bonding: support custom interface IDs
[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_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   i32 retval = ntohl (mp->retval);
1913
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_bond_create_reply_t_handler_json
1927   (vl_api_bond_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 static void
1944 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1945 {
1946   vat_main_t *vam = &vat_main;
1947   i32 retval = ntohl (mp->retval);
1948
1949   if (vam->async_mode)
1950     {
1951       vam->async_errors += (retval < 0);
1952     }
1953   else
1954     {
1955       vam->retval = retval;
1956       vam->result_ready = 1;
1957     }
1958 }
1959
1960 static void vl_api_bond_delete_reply_t_handler_json
1961   (vl_api_bond_delete_reply_t * mp)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   vat_json_node_t node;
1965
1966   vat_json_init_object (&node);
1967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1968
1969   vat_json_print (vam->ofp, &node);
1970   vat_json_free (&node);
1971
1972   vam->retval = ntohl (mp->retval);
1973   vam->result_ready = 1;
1974 }
1975
1976 static void
1977 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   i32 retval = ntohl (mp->retval);
1981
1982   if (vam->async_mode)
1983     {
1984       vam->async_errors += (retval < 0);
1985     }
1986   else
1987     {
1988       vam->retval = retval;
1989       vam->result_ready = 1;
1990     }
1991 }
1992
1993 static void vl_api_bond_enslave_reply_t_handler_json
1994   (vl_api_bond_enslave_reply_t * mp)
1995 {
1996   vat_main_t *vam = &vat_main;
1997   vat_json_node_t node;
1998
1999   vat_json_init_object (&node);
2000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2001
2002   vat_json_print (vam->ofp, &node);
2003   vat_json_free (&node);
2004
2005   vam->retval = ntohl (mp->retval);
2006   vam->result_ready = 1;
2007 }
2008
2009 static void
2010 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2011                                           mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014   i32 retval = ntohl (mp->retval);
2015
2016   if (vam->async_mode)
2017     {
2018       vam->async_errors += (retval < 0);
2019     }
2020   else
2021     {
2022       vam->retval = retval;
2023       vam->result_ready = 1;
2024     }
2025 }
2026
2027 static void vl_api_bond_detach_slave_reply_t_handler_json
2028   (vl_api_bond_detach_slave_reply_t * mp)
2029 {
2030   vat_main_t *vam = &vat_main;
2031   vat_json_node_t node;
2032
2033   vat_json_init_object (&node);
2034   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2035
2036   vat_json_print (vam->ofp, &node);
2037   vat_json_free (&node);
2038
2039   vam->retval = ntohl (mp->retval);
2040   vam->result_ready = 1;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2052          ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", mp->mode);
2073   vat_json_object_add_uint (node, "load_balance", mp->lb);
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-12d %d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2110 }
2111
2112 static void vl_api_sw_interface_slave_details_t_handler_json
2113   (vl_api_sw_interface_slave_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t *node = NULL;
2117
2118   if (VAT_JSON_ARRAY != vam->json_tree.type)
2119     {
2120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2121       vat_json_init_array (&vam->json_tree);
2122     }
2123   node = vat_json_array_add (&vam->json_tree);
2124
2125   vat_json_init_object (node);
2126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2127   vat_json_object_add_string_copy (node, "interface_name",
2128                                    mp->interface_name);
2129   vat_json_object_add_uint (node, "passive", mp->is_passive);
2130   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2131 }
2132
2133 static int
2134 api_sw_interface_slave_dump (vat_main_t * vam)
2135 {
2136   unformat_input_t *i = vam->input;
2137   vl_api_sw_interface_slave_dump_t *mp;
2138   vl_api_control_ping_t *mp_ping;
2139   u32 sw_if_index = ~0;
2140   u8 sw_if_index_set = 0;
2141   int ret;
2142
2143   /* Parse args required to build the message */
2144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145     {
2146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147         sw_if_index_set = 1;
2148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2149         sw_if_index_set = 1;
2150       else
2151         break;
2152     }
2153
2154   if (sw_if_index_set == 0)
2155     {
2156       errmsg ("missing vpp interface name. ");
2157       return -99;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-25s %-12s %-12s %s",
2162          "slave interface name", "sw_if_index", "passive", "long_timeout");
2163
2164   /* Get list of bond interfaces */
2165   M (SW_INTERFACE_SLAVE_DUMP, mp);
2166   mp->sw_if_index = ntohl (sw_if_index);
2167   S (mp);
2168
2169   /* Use a control ping for synchronization */
2170   MPING (CONTROL_PING, mp_ping);
2171   S (mp_ping);
2172
2173   W (ret);
2174   return ret;
2175 }
2176
2177 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2178   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2179 {
2180   vat_main_t *vam = &vat_main;
2181   i32 retval = ntohl (mp->retval);
2182   if (vam->async_mode)
2183     {
2184       vam->async_errors += (retval < 0);
2185     }
2186   else
2187     {
2188       vam->retval = retval;
2189       vam->sw_if_index = ntohl (mp->sw_if_index);
2190       vam->result_ready = 1;
2191     }
2192   vam->regenerate_interface_table = 1;
2193 }
2194
2195 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2196   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t node;
2200
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2204                             ntohl (mp->sw_if_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2214   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   i32 retval = ntohl (mp->retval);
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->sw_if_index = ntohl (mp->sw_if_index);
2226       vam->result_ready = 1;
2227     }
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vat_json_node_t node;
2235
2236   vat_json_init_object (&node);
2237   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2238   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2248   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   i32 retval = ntohl (mp->retval);
2252   if (vam->async_mode)
2253     {
2254       vam->async_errors += (retval < 0);
2255     }
2256   else
2257     {
2258       vam->retval = retval;
2259       vam->result_ready = 1;
2260     }
2261 }
2262
2263 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2264   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   vat_json_node_t node;
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_uint (&node, "fwd_entry_index",
2272                             clib_net_to_host_u32 (mp->fwd_entry_index));
2273
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 u8 *
2282 format_lisp_transport_protocol (u8 * s, va_list * args)
2283 {
2284   u32 proto = va_arg (*args, u32);
2285
2286   switch (proto)
2287     {
2288     case 1:
2289       return format (s, "udp");
2290     case 2:
2291       return format (s, "api");
2292     default:
2293       return 0;
2294     }
2295   return 0;
2296 }
2297
2298 static void vl_api_one_get_transport_protocol_reply_t_handler
2299   (vl_api_one_get_transport_protocol_reply_t * mp)
2300 {
2301   vat_main_t *vam = &vat_main;
2302   i32 retval = ntohl (mp->retval);
2303   if (vam->async_mode)
2304     {
2305       vam->async_errors += (retval < 0);
2306     }
2307   else
2308     {
2309       u32 proto = mp->protocol;
2310       print (vam->ofp, "Transport protocol: %U",
2311              format_lisp_transport_protocol, proto);
2312       vam->retval = retval;
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2318   (vl_api_one_get_transport_protocol_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322   u8 *s;
2323
2324   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2325   vec_add1 (s, 0);
2326
2327   vat_json_init_object (&node);
2328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2329   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2330
2331   vec_free (s);
2332   vat_json_print (vam->ofp, &node);
2333   vat_json_free (&node);
2334
2335   vam->retval = ntohl (mp->retval);
2336   vam->result_ready = 1;
2337 }
2338
2339 static void vl_api_one_add_del_locator_set_reply_t_handler
2340   (vl_api_one_add_del_locator_set_reply_t * mp)
2341 {
2342   vat_main_t *vam = &vat_main;
2343   i32 retval = ntohl (mp->retval);
2344   if (vam->async_mode)
2345     {
2346       vam->async_errors += (retval < 0);
2347     }
2348   else
2349     {
2350       vam->retval = retval;
2351       vam->result_ready = 1;
2352     }
2353 }
2354
2355 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2356   (vl_api_one_add_del_locator_set_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   vat_json_node_t node;
2360
2361   vat_json_init_object (&node);
2362   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2363   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2364
2365   vat_json_print (vam->ofp, &node);
2366   vat_json_free (&node);
2367
2368   vam->retval = ntohl (mp->retval);
2369   vam->result_ready = 1;
2370 }
2371
2372 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2373   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   i32 retval = ntohl (mp->retval);
2377   if (vam->async_mode)
2378     {
2379       vam->async_errors += (retval < 0);
2380     }
2381   else
2382     {
2383       vam->retval = retval;
2384       vam->sw_if_index = ntohl (mp->sw_if_index);
2385       vam->result_ready = 1;
2386     }
2387   vam->regenerate_interface_table = 1;
2388 }
2389
2390 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2391   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   vat_json_node_t node;
2395
2396   vat_json_init_object (&node);
2397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2398   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2399
2400   vat_json_print (vam->ofp, &node);
2401   vat_json_free (&node);
2402
2403   vam->retval = ntohl (mp->retval);
2404   vam->result_ready = 1;
2405 }
2406
2407 static void vl_api_vxlan_offload_rx_reply_t_handler
2408   (vl_api_vxlan_offload_rx_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   i32 retval = ntohl (mp->retval);
2412   if (vam->async_mode)
2413     {
2414       vam->async_errors += (retval < 0);
2415     }
2416   else
2417     {
2418       vam->retval = retval;
2419       vam->result_ready = 1;
2420     }
2421 }
2422
2423 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2424   (vl_api_vxlan_offload_rx_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   vat_json_node_t node;
2428
2429   vat_json_init_object (&node);
2430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2431
2432   vat_json_print (vam->ofp, &node);
2433   vat_json_free (&node);
2434
2435   vam->retval = ntohl (mp->retval);
2436   vam->result_ready = 1;
2437 }
2438
2439 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2440   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   i32 retval = ntohl (mp->retval);
2444   if (vam->async_mode)
2445     {
2446       vam->async_errors += (retval < 0);
2447     }
2448   else
2449     {
2450       vam->retval = retval;
2451       vam->sw_if_index = ntohl (mp->sw_if_index);
2452       vam->result_ready = 1;
2453     }
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t node;
2461
2462   vat_json_init_object (&node);
2463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2465
2466   vat_json_print (vam->ofp, &node);
2467   vat_json_free (&node);
2468
2469   vam->retval = ntohl (mp->retval);
2470   vam->result_ready = 1;
2471 }
2472
2473 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2474   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   i32 retval = ntohl (mp->retval);
2478   if (vam->async_mode)
2479     {
2480       vam->async_errors += (retval < 0);
2481     }
2482   else
2483     {
2484       vam->retval = retval;
2485       vam->sw_if_index = ntohl (mp->sw_if_index);
2486       vam->result_ready = 1;
2487     }
2488   vam->regenerate_interface_table = 1;
2489 }
2490
2491 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2492   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   vat_json_node_t node;
2496
2497   vat_json_init_object (&node);
2498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2499   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_gre_add_del_tunnel_reply_t_handler
2509   (vl_api_gre_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_gre_add_del_tunnel_reply_t_handler_json
2526   (vl_api_gre_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_create_vhost_user_if_reply_t_handler
2543   (vl_api_create_vhost_user_if_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_create_vhost_user_if_reply_t_handler_json
2561   (vl_api_create_vhost_user_if_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_dns_resolve_name_reply_t_handler
2578   (vl_api_dns_resolve_name_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->result_ready = 1;
2590
2591       if (retval == 0)
2592         {
2593           if (mp->ip4_set)
2594             clib_warning ("ip4 address %U", format_ip4_address,
2595                           (ip4_address_t *) mp->ip4_address);
2596           if (mp->ip6_set)
2597             clib_warning ("ip6 address %U", format_ip6_address,
2598                           (ip6_address_t *) mp->ip6_address);
2599         }
2600       else
2601         clib_warning ("retval %d", retval);
2602     }
2603 }
2604
2605 static void vl_api_dns_resolve_name_reply_t_handler_json
2606   (vl_api_dns_resolve_name_reply_t * mp)
2607 {
2608   clib_warning ("not implemented");
2609 }
2610
2611 static void vl_api_dns_resolve_ip_reply_t_handler
2612   (vl_api_dns_resolve_ip_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->result_ready = 1;
2624
2625       if (retval == 0)
2626         {
2627           clib_warning ("canonical name %s", mp->name);
2628         }
2629       else
2630         clib_warning ("retval %d", retval);
2631     }
2632 }
2633
2634 static void vl_api_dns_resolve_ip_reply_t_handler_json
2635   (vl_api_dns_resolve_ip_reply_t * mp)
2636 {
2637   clib_warning ("not implemented");
2638 }
2639
2640
2641 static void vl_api_ip_address_details_t_handler
2642   (vl_api_ip_address_details_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   static ip_address_details_t empty_ip_address_details = { {0} };
2646   ip_address_details_t *address = NULL;
2647   ip_details_t *current_ip_details = NULL;
2648   ip_details_t *details = NULL;
2649
2650   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2651
2652   if (!details || vam->current_sw_if_index >= vec_len (details)
2653       || !details[vam->current_sw_if_index].present)
2654     {
2655       errmsg ("ip address details arrived but not stored");
2656       errmsg ("ip_dump should be called first");
2657       return;
2658     }
2659
2660   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2661
2662 #define addresses (current_ip_details->addr)
2663
2664   vec_validate_init_empty (addresses, vec_len (addresses),
2665                            empty_ip_address_details);
2666
2667   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2668
2669   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2670   address->prefix_length = mp->prefix_length;
2671 #undef addresses
2672 }
2673
2674 static void vl_api_ip_address_details_t_handler_json
2675   (vl_api_ip_address_details_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   vat_json_node_t *node = NULL;
2679   struct in6_addr ip6;
2680   struct in_addr ip4;
2681
2682   if (VAT_JSON_ARRAY != vam->json_tree.type)
2683     {
2684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2685       vat_json_init_array (&vam->json_tree);
2686     }
2687   node = vat_json_array_add (&vam->json_tree);
2688
2689   vat_json_init_object (node);
2690   if (vam->is_ipv6)
2691     {
2692       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2693       vat_json_object_add_ip6 (node, "ip", ip6);
2694     }
2695   else
2696     {
2697       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2698       vat_json_object_add_ip4 (node, "ip", ip4);
2699     }
2700   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2701 }
2702
2703 static void
2704 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   static ip_details_t empty_ip_details = { 0 };
2708   ip_details_t *ip = NULL;
2709   u32 sw_if_index = ~0;
2710
2711   sw_if_index = ntohl (mp->sw_if_index);
2712
2713   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2714                            sw_if_index, empty_ip_details);
2715
2716   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2717                          sw_if_index);
2718
2719   ip->present = 1;
2720 }
2721
2722 static void
2723 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2724 {
2725   vat_main_t *vam = &vat_main;
2726
2727   if (VAT_JSON_ARRAY != vam->json_tree.type)
2728     {
2729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2730       vat_json_init_array (&vam->json_tree);
2731     }
2732   vat_json_array_add_uint (&vam->json_tree,
2733                            clib_net_to_host_u32 (mp->sw_if_index));
2734 }
2735
2736 static void
2737 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2738 {
2739   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2740           "router_addr %U host_mac %U",
2741           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2742           mp->lease.hostname,
2743           format_ip4_address, &mp->lease.host_address,
2744           format_ip4_address, &mp->lease.router_address,
2745           format_ethernet_address, mp->lease.host_mac);
2746 }
2747
2748 static void vl_api_dhcp_compl_event_t_handler_json
2749   (vl_api_dhcp_compl_event_t * mp)
2750 {
2751   /* JSON output not supported */
2752 }
2753
2754 static void vl_api_get_first_msg_id_reply_t_handler
2755   (vl_api_get_first_msg_id_reply_t * mp)
2756 {
2757   vat_main_t *vam = &vat_main;
2758   i32 retval = ntohl (mp->retval);
2759
2760   if (vam->async_mode)
2761     {
2762       vam->async_errors += (retval < 0);
2763     }
2764   else
2765     {
2766       vam->retval = retval;
2767       vam->result_ready = 1;
2768     }
2769   if (retval >= 0)
2770     {
2771       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2772     }
2773 }
2774
2775 static void vl_api_get_first_msg_id_reply_t_handler_json
2776   (vl_api_get_first_msg_id_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780
2781   vat_json_init_object (&node);
2782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2783   vat_json_object_add_uint (&node, "first_msg_id",
2784                             (uint) ntohs (mp->first_msg_id));
2785
2786   vat_json_print (vam->ofp, &node);
2787   vat_json_free (&node);
2788
2789   vam->retval = ntohl (mp->retval);
2790   vam->result_ready = 1;
2791 }
2792
2793 static void vl_api_get_node_graph_reply_t_handler
2794   (vl_api_get_node_graph_reply_t * mp)
2795 {
2796   vat_main_t *vam = &vat_main;
2797   api_main_t *am = &api_main;
2798   i32 retval = ntohl (mp->retval);
2799   u8 *pvt_copy, *reply;
2800   void *oldheap;
2801   vlib_node_t *node;
2802   int i;
2803
2804   if (vam->async_mode)
2805     {
2806       vam->async_errors += (retval < 0);
2807     }
2808   else
2809     {
2810       vam->retval = retval;
2811       vam->result_ready = 1;
2812     }
2813
2814   /* "Should never happen..." */
2815   if (retval != 0)
2816     return;
2817
2818   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2819   pvt_copy = vec_dup (reply);
2820
2821   /* Toss the shared-memory original... */
2822   pthread_mutex_lock (&am->vlib_rp->mutex);
2823   oldheap = svm_push_data_heap (am->vlib_rp);
2824
2825   vec_free (reply);
2826
2827   svm_pop_heap (oldheap);
2828   pthread_mutex_unlock (&am->vlib_rp->mutex);
2829
2830   if (vam->graph_nodes)
2831     {
2832       hash_free (vam->graph_node_index_by_name);
2833
2834       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2835         {
2836           node = vam->graph_nodes[0][i];
2837           vec_free (node->name);
2838           vec_free (node->next_nodes);
2839           vec_free (node);
2840         }
2841       vec_free (vam->graph_nodes[0]);
2842       vec_free (vam->graph_nodes);
2843     }
2844
2845   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2846   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2847   vec_free (pvt_copy);
2848
2849   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2850     {
2851       node = vam->graph_nodes[0][i];
2852       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2853     }
2854 }
2855
2856 static void vl_api_get_node_graph_reply_t_handler_json
2857   (vl_api_get_node_graph_reply_t * mp)
2858 {
2859   vat_main_t *vam = &vat_main;
2860   api_main_t *am = &api_main;
2861   void *oldheap;
2862   vat_json_node_t node;
2863   u8 *reply;
2864
2865   /* $$$$ make this real? */
2866   vat_json_init_object (&node);
2867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2868   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2869
2870   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2871
2872   /* Toss the shared-memory original... */
2873   pthread_mutex_lock (&am->vlib_rp->mutex);
2874   oldheap = svm_push_data_heap (am->vlib_rp);
2875
2876   vec_free (reply);
2877
2878   svm_pop_heap (oldheap);
2879   pthread_mutex_unlock (&am->vlib_rp->mutex);
2880
2881   vat_json_print (vam->ofp, &node);
2882   vat_json_free (&node);
2883
2884   vam->retval = ntohl (mp->retval);
2885   vam->result_ready = 1;
2886 }
2887
2888 static void
2889 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2890 {
2891   vat_main_t *vam = &vat_main;
2892   u8 *s = 0;
2893
2894   if (mp->local)
2895     {
2896       s = format (s, "%=16d%=16d%=16d",
2897                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2898     }
2899   else
2900     {
2901       s = format (s, "%=16U%=16d%=16d",
2902                   mp->is_ipv6 ? format_ip6_address :
2903                   format_ip4_address,
2904                   mp->ip_address, mp->priority, mp->weight);
2905     }
2906
2907   print (vam->ofp, "%v", s);
2908   vec_free (s);
2909 }
2910
2911 static void
2912 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node = NULL;
2916   struct in6_addr ip6;
2917   struct in_addr ip4;
2918
2919   if (VAT_JSON_ARRAY != vam->json_tree.type)
2920     {
2921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2922       vat_json_init_array (&vam->json_tree);
2923     }
2924   node = vat_json_array_add (&vam->json_tree);
2925   vat_json_init_object (node);
2926
2927   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2928   vat_json_object_add_uint (node, "priority", mp->priority);
2929   vat_json_object_add_uint (node, "weight", mp->weight);
2930
2931   if (mp->local)
2932     vat_json_object_add_uint (node, "sw_if_index",
2933                               clib_net_to_host_u32 (mp->sw_if_index));
2934   else
2935     {
2936       if (mp->is_ipv6)
2937         {
2938           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2939           vat_json_object_add_ip6 (node, "address", ip6);
2940         }
2941       else
2942         {
2943           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2944           vat_json_object_add_ip4 (node, "address", ip4);
2945         }
2946     }
2947 }
2948
2949 static void
2950 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2951                                           mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   u8 *ls_name = 0;
2955
2956   ls_name = format (0, "%s", mp->ls_name);
2957
2958   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2959          ls_name);
2960   vec_free (ls_name);
2961 }
2962
2963 static void
2964   vl_api_one_locator_set_details_t_handler_json
2965   (vl_api_one_locator_set_details_t * mp)
2966 {
2967   vat_main_t *vam = &vat_main;
2968   vat_json_node_t *node = 0;
2969   u8 *ls_name = 0;
2970
2971   ls_name = format (0, "%s", mp->ls_name);
2972   vec_add1 (ls_name, 0);
2973
2974   if (VAT_JSON_ARRAY != vam->json_tree.type)
2975     {
2976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2977       vat_json_init_array (&vam->json_tree);
2978     }
2979   node = vat_json_array_add (&vam->json_tree);
2980
2981   vat_json_init_object (node);
2982   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2983   vat_json_object_add_uint (node, "ls_index",
2984                             clib_net_to_host_u32 (mp->ls_index));
2985   vec_free (ls_name);
2986 }
2987
2988 typedef struct
2989 {
2990   u32 spi;
2991   u8 si;
2992 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2993
2994 uword
2995 unformat_nsh_address (unformat_input_t * input, va_list * args)
2996 {
2997   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2998   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2999 }
3000
3001 u8 *
3002 format_nsh_address_vat (u8 * s, va_list * args)
3003 {
3004   nsh_t *a = va_arg (*args, nsh_t *);
3005   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3006 }
3007
3008 static u8 *
3009 format_lisp_flat_eid (u8 * s, va_list * args)
3010 {
3011   u32 type = va_arg (*args, u32);
3012   u8 *eid = va_arg (*args, u8 *);
3013   u32 eid_len = va_arg (*args, u32);
3014
3015   switch (type)
3016     {
3017     case 0:
3018       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3019     case 1:
3020       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3021     case 2:
3022       return format (s, "%U", format_ethernet_address, eid);
3023     case 3:
3024       return format (s, "%U", format_nsh_address_vat, eid);
3025     }
3026   return 0;
3027 }
3028
3029 static u8 *
3030 format_lisp_eid_vat (u8 * s, va_list * args)
3031 {
3032   u32 type = va_arg (*args, u32);
3033   u8 *eid = va_arg (*args, u8 *);
3034   u32 eid_len = va_arg (*args, u32);
3035   u8 *seid = va_arg (*args, u8 *);
3036   u32 seid_len = va_arg (*args, u32);
3037   u32 is_src_dst = va_arg (*args, u32);
3038
3039   if (is_src_dst)
3040     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3041
3042   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3043
3044   return s;
3045 }
3046
3047 static void
3048 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   u8 *s = 0, *eid = 0;
3052
3053   if (~0 == mp->locator_set_index)
3054     s = format (0, "action: %d", mp->action);
3055   else
3056     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3057
3058   eid = format (0, "%U", format_lisp_eid_vat,
3059                 mp->eid_type,
3060                 mp->eid,
3061                 mp->eid_prefix_len,
3062                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3063   vec_add1 (eid, 0);
3064
3065   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3066          clib_net_to_host_u32 (mp->vni),
3067          eid,
3068          mp->is_local ? "local" : "remote",
3069          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3070          clib_net_to_host_u16 (mp->key_id), mp->key);
3071
3072   vec_free (s);
3073   vec_free (eid);
3074 }
3075
3076 static void
3077 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3078                                              * mp)
3079 {
3080   vat_main_t *vam = &vat_main;
3081   vat_json_node_t *node = 0;
3082   u8 *eid = 0;
3083
3084   if (VAT_JSON_ARRAY != vam->json_tree.type)
3085     {
3086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3087       vat_json_init_array (&vam->json_tree);
3088     }
3089   node = vat_json_array_add (&vam->json_tree);
3090
3091   vat_json_init_object (node);
3092   if (~0 == mp->locator_set_index)
3093     vat_json_object_add_uint (node, "action", mp->action);
3094   else
3095     vat_json_object_add_uint (node, "locator_set_index",
3096                               clib_net_to_host_u32 (mp->locator_set_index));
3097
3098   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3099   if (mp->eid_type == 3)
3100     {
3101       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3102       vat_json_init_object (nsh_json);
3103       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3104       vat_json_object_add_uint (nsh_json, "spi",
3105                                 clib_net_to_host_u32 (nsh->spi));
3106       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3107     }
3108   else
3109     {
3110       eid = format (0, "%U", format_lisp_eid_vat,
3111                     mp->eid_type,
3112                     mp->eid,
3113                     mp->eid_prefix_len,
3114                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3115       vec_add1 (eid, 0);
3116       vat_json_object_add_string_copy (node, "eid", eid);
3117       vec_free (eid);
3118     }
3119   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3120   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3121   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3122
3123   if (mp->key_id)
3124     {
3125       vat_json_object_add_uint (node, "key_id",
3126                                 clib_net_to_host_u16 (mp->key_id));
3127       vat_json_object_add_string_copy (node, "key", mp->key);
3128     }
3129 }
3130
3131 static void
3132 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3133 {
3134   vat_main_t *vam = &vat_main;
3135   u8 *seid = 0, *deid = 0;
3136   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3137
3138   deid = format (0, "%U", format_lisp_eid_vat,
3139                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3140
3141   seid = format (0, "%U", format_lisp_eid_vat,
3142                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3143
3144   vec_add1 (deid, 0);
3145   vec_add1 (seid, 0);
3146
3147   if (mp->is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152
3153   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3154          clib_net_to_host_u32 (mp->vni),
3155          seid, deid,
3156          format_ip_address_fcn, mp->lloc,
3157          format_ip_address_fcn, mp->rloc,
3158          clib_net_to_host_u32 (mp->pkt_count),
3159          clib_net_to_host_u32 (mp->bytes));
3160
3161   vec_free (deid);
3162   vec_free (seid);
3163 }
3164
3165 static void
3166 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3167 {
3168   struct in6_addr ip6;
3169   struct in_addr ip4;
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t *node = 0;
3172   u8 *deid = 0, *seid = 0;
3173
3174   if (VAT_JSON_ARRAY != vam->json_tree.type)
3175     {
3176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3177       vat_json_init_array (&vam->json_tree);
3178     }
3179   node = vat_json_array_add (&vam->json_tree);
3180
3181   vat_json_init_object (node);
3182   deid = format (0, "%U", format_lisp_eid_vat,
3183                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3184
3185   seid = format (0, "%U", format_lisp_eid_vat,
3186                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3187
3188   vec_add1 (deid, 0);
3189   vec_add1 (seid, 0);
3190
3191   vat_json_object_add_string_copy (node, "seid", seid);
3192   vat_json_object_add_string_copy (node, "deid", deid);
3193   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3194
3195   if (mp->is_ip4)
3196     {
3197       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3198       vat_json_object_add_ip4 (node, "lloc", ip4);
3199       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3200       vat_json_object_add_ip4 (node, "rloc", ip4);
3201     }
3202   else
3203     {
3204       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3205       vat_json_object_add_ip6 (node, "lloc", ip6);
3206       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3207       vat_json_object_add_ip6 (node, "rloc", ip6);
3208     }
3209   vat_json_object_add_uint (node, "pkt_count",
3210                             clib_net_to_host_u32 (mp->pkt_count));
3211   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3212
3213   vec_free (deid);
3214   vec_free (seid);
3215 }
3216
3217 static void
3218   vl_api_one_eid_table_map_details_t_handler
3219   (vl_api_one_eid_table_map_details_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222
3223   u8 *line = format (0, "%=10d%=10d",
3224                      clib_net_to_host_u32 (mp->vni),
3225                      clib_net_to_host_u32 (mp->dp_table));
3226   print (vam->ofp, "%v", line);
3227   vec_free (line);
3228 }
3229
3230 static void
3231   vl_api_one_eid_table_map_details_t_handler_json
3232   (vl_api_one_eid_table_map_details_t * mp)
3233 {
3234   vat_main_t *vam = &vat_main;
3235   vat_json_node_t *node = NULL;
3236
3237   if (VAT_JSON_ARRAY != vam->json_tree.type)
3238     {
3239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3240       vat_json_init_array (&vam->json_tree);
3241     }
3242   node = vat_json_array_add (&vam->json_tree);
3243   vat_json_init_object (node);
3244   vat_json_object_add_uint (node, "dp_table",
3245                             clib_net_to_host_u32 (mp->dp_table));
3246   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3247 }
3248
3249 static void
3250   vl_api_one_eid_table_vni_details_t_handler
3251   (vl_api_one_eid_table_vni_details_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254
3255   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3256   print (vam->ofp, "%v", line);
3257   vec_free (line);
3258 }
3259
3260 static void
3261   vl_api_one_eid_table_vni_details_t_handler_json
3262   (vl_api_one_eid_table_vni_details_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   vat_json_node_t *node = NULL;
3266
3267   if (VAT_JSON_ARRAY != vam->json_tree.type)
3268     {
3269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3270       vat_json_init_array (&vam->json_tree);
3271     }
3272   node = vat_json_array_add (&vam->json_tree);
3273   vat_json_init_object (node);
3274   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3275 }
3276
3277 static void
3278   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3279   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3285   print (vam->ofp, "fallback threshold value: %d", mp->value);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289 }
3290
3291 static void
3292   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3293   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t _node, *node = &_node;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3300   vat_json_init_object (node);
3301   vat_json_object_add_uint (node, "value", mp->value);
3302
3303   vat_json_print (vam->ofp, node);
3304   vat_json_free (node);
3305
3306   vam->retval = retval;
3307   vam->result_ready = 1;
3308 }
3309
3310 static void
3311   vl_api_show_one_map_register_state_reply_t_handler
3312   (vl_api_show_one_map_register_state_reply_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315   int retval = clib_net_to_host_u32 (mp->retval);
3316
3317   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3318
3319   vam->retval = retval;
3320   vam->result_ready = 1;
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_state_reply_t_handler_json
3325   (vl_api_show_one_map_register_state_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   vat_json_node_t _node, *node = &_node;
3329   int retval = clib_net_to_host_u32 (mp->retval);
3330
3331   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3332
3333   vat_json_init_object (node);
3334   vat_json_object_add_string_copy (node, "state", s);
3335
3336   vat_json_print (vam->ofp, node);
3337   vat_json_free (node);
3338
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341   vec_free (s);
3342 }
3343
3344 static void
3345   vl_api_show_one_rloc_probe_state_reply_t_handler
3346   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3347 {
3348   vat_main_t *vam = &vat_main;
3349   int retval = clib_net_to_host_u32 (mp->retval);
3350
3351   if (retval)
3352     goto end;
3353
3354   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3355 end:
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3362   (vl_api_show_one_rloc_probe_state_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   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3369   vat_json_init_object (node);
3370   vat_json_object_add_string_copy (node, "state", s);
3371
3372   vat_json_print (vam->ofp, node);
3373   vat_json_free (node);
3374
3375   vam->retval = retval;
3376   vam->result_ready = 1;
3377   vec_free (s);
3378 }
3379
3380 static void
3381   vl_api_show_one_stats_enable_disable_reply_t_handler
3382   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385   int retval = clib_net_to_host_u32 (mp->retval);
3386
3387   if (retval)
3388     goto end;
3389
3390   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3391 end:
3392   vam->retval = retval;
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3398   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   vat_json_node_t _node, *node = &_node;
3402   int retval = clib_net_to_host_u32 (mp->retval);
3403
3404   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3405   vat_json_init_object (node);
3406   vat_json_object_add_string_copy (node, "state", s);
3407
3408   vat_json_print (vam->ofp, node);
3409   vat_json_free (node);
3410
3411   vam->retval = retval;
3412   vam->result_ready = 1;
3413   vec_free (s);
3414 }
3415
3416 static void
3417 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3418 {
3419   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3420   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3421   e->vni = clib_net_to_host_u32 (e->vni);
3422 }
3423
3424 static void
3425   gpe_fwd_entries_get_reply_t_net_to_host
3426   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3427 {
3428   u32 i;
3429
3430   mp->count = clib_net_to_host_u32 (mp->count);
3431   for (i = 0; i < mp->count; i++)
3432     {
3433       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3434     }
3435 }
3436
3437 static u8 *
3438 format_gpe_encap_mode (u8 * s, va_list * args)
3439 {
3440   u32 mode = va_arg (*args, u32);
3441
3442   switch (mode)
3443     {
3444     case 0:
3445       return format (s, "lisp");
3446     case 1:
3447       return format (s, "vxlan");
3448     }
3449   return 0;
3450 }
3451
3452 static void
3453   vl_api_gpe_get_encap_mode_reply_t_handler
3454   (vl_api_gpe_get_encap_mode_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457
3458   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3459   vam->retval = ntohl (mp->retval);
3460   vam->result_ready = 1;
3461 }
3462
3463 static void
3464   vl_api_gpe_get_encap_mode_reply_t_handler_json
3465   (vl_api_gpe_get_encap_mode_reply_t * mp)
3466 {
3467   vat_main_t *vam = &vat_main;
3468   vat_json_node_t node;
3469
3470   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3471   vec_add1 (encap_mode, 0);
3472
3473   vat_json_init_object (&node);
3474   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3475
3476   vec_free (encap_mode);
3477   vat_json_print (vam->ofp, &node);
3478   vat_json_free (&node);
3479
3480   vam->retval = ntohl (mp->retval);
3481   vam->result_ready = 1;
3482 }
3483
3484 static void
3485   vl_api_gpe_fwd_entry_path_details_t_handler
3486   (vl_api_gpe_fwd_entry_path_details_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3490
3491   if (mp->lcl_loc.is_ip4)
3492     format_ip_address_fcn = format_ip4_address;
3493   else
3494     format_ip_address_fcn = format_ip6_address;
3495
3496   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3497          format_ip_address_fcn, &mp->lcl_loc,
3498          format_ip_address_fcn, &mp->rmt_loc);
3499 }
3500
3501 static void
3502 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3503 {
3504   struct in6_addr ip6;
3505   struct in_addr ip4;
3506
3507   if (loc->is_ip4)
3508     {
3509       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3510       vat_json_object_add_ip4 (n, "address", ip4);
3511     }
3512   else
3513     {
3514       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3515       vat_json_object_add_ip6 (n, "address", ip6);
3516     }
3517   vat_json_object_add_uint (n, "weight", loc->weight);
3518 }
3519
3520 static void
3521   vl_api_gpe_fwd_entry_path_details_t_handler_json
3522   (vl_api_gpe_fwd_entry_path_details_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   vat_json_node_t *node = NULL;
3526   vat_json_node_t *loc_node;
3527
3528   if (VAT_JSON_ARRAY != vam->json_tree.type)
3529     {
3530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3531       vat_json_init_array (&vam->json_tree);
3532     }
3533   node = vat_json_array_add (&vam->json_tree);
3534   vat_json_init_object (node);
3535
3536   loc_node = vat_json_object_add (node, "local_locator");
3537   vat_json_init_object (loc_node);
3538   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3539
3540   loc_node = vat_json_object_add (node, "remote_locator");
3541   vat_json_init_object (loc_node);
3542   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3543 }
3544
3545 static void
3546   vl_api_gpe_fwd_entries_get_reply_t_handler
3547   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u32 i;
3551   int retval = clib_net_to_host_u32 (mp->retval);
3552   vl_api_gpe_fwd_entry_t *e;
3553
3554   if (retval)
3555     goto end;
3556
3557   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3558
3559   for (i = 0; i < mp->count; i++)
3560     {
3561       e = &mp->entries[i];
3562       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3563              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3564              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3565     }
3566
3567 end:
3568   vam->retval = retval;
3569   vam->result_ready = 1;
3570 }
3571
3572 static void
3573   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3574   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3575 {
3576   u8 *s = 0;
3577   vat_main_t *vam = &vat_main;
3578   vat_json_node_t *e = 0, root;
3579   u32 i;
3580   int retval = clib_net_to_host_u32 (mp->retval);
3581   vl_api_gpe_fwd_entry_t *fwd;
3582
3583   if (retval)
3584     goto end;
3585
3586   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3587   vat_json_init_array (&root);
3588
3589   for (i = 0; i < mp->count; i++)
3590     {
3591       e = vat_json_array_add (&root);
3592       fwd = &mp->entries[i];
3593
3594       vat_json_init_object (e);
3595       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3596       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3597       vat_json_object_add_int (e, "vni", fwd->vni);
3598       vat_json_object_add_int (e, "action", fwd->action);
3599
3600       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3601                   fwd->leid_prefix_len);
3602       vec_add1 (s, 0);
3603       vat_json_object_add_string_copy (e, "leid", s);
3604       vec_free (s);
3605
3606       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3607                   fwd->reid_prefix_len);
3608       vec_add1 (s, 0);
3609       vat_json_object_add_string_copy (e, "reid", s);
3610       vec_free (s);
3611     }
3612
3613   vat_json_print (vam->ofp, &root);
3614   vat_json_free (&root);
3615
3616 end:
3617   vam->retval = retval;
3618   vam->result_ready = 1;
3619 }
3620
3621 static void
3622   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3623   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3624 {
3625   vat_main_t *vam = &vat_main;
3626   u32 i, n;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628   vl_api_gpe_native_fwd_rpath_t *r;
3629
3630   if (retval)
3631     goto end;
3632
3633   n = clib_net_to_host_u32 (mp->count);
3634
3635   for (i = 0; i < n; i++)
3636     {
3637       r = &mp->entries[i];
3638       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3639              clib_net_to_host_u32 (r->fib_index),
3640              clib_net_to_host_u32 (r->nh_sw_if_index),
3641              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3642     }
3643
3644 end:
3645   vam->retval = retval;
3646   vam->result_ready = 1;
3647 }
3648
3649 static void
3650   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3651   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3652 {
3653   vat_main_t *vam = &vat_main;
3654   vat_json_node_t root, *e;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657   vl_api_gpe_native_fwd_rpath_t *r;
3658   u8 *s;
3659
3660   if (retval)
3661     goto end;
3662
3663   n = clib_net_to_host_u32 (mp->count);
3664   vat_json_init_array (&root);
3665
3666   for (i = 0; i < n; i++)
3667     {
3668       e = vat_json_array_add (&root);
3669       vat_json_init_object (e);
3670       r = &mp->entries[i];
3671       s =
3672         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3673                 r->nh_addr);
3674       vec_add1 (s, 0);
3675       vat_json_object_add_string_copy (e, "ip4", s);
3676       vec_free (s);
3677
3678       vat_json_object_add_uint (e, "fib_index",
3679                                 clib_net_to_host_u32 (r->fib_index));
3680       vat_json_object_add_uint (e, "nh_sw_if_index",
3681                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3682     }
3683
3684   vat_json_print (vam->ofp, &root);
3685   vat_json_free (&root);
3686
3687 end:
3688   vam->retval = retval;
3689   vam->result_ready = 1;
3690 }
3691
3692 static void
3693   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3694   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3695 {
3696   vat_main_t *vam = &vat_main;
3697   u32 i, n;
3698   int retval = clib_net_to_host_u32 (mp->retval);
3699
3700   if (retval)
3701     goto end;
3702
3703   n = clib_net_to_host_u32 (mp->count);
3704
3705   for (i = 0; i < n; i++)
3706     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3707
3708 end:
3709   vam->retval = retval;
3710   vam->result_ready = 1;
3711 }
3712
3713 static void
3714   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3715   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3716 {
3717   vat_main_t *vam = &vat_main;
3718   vat_json_node_t root;
3719   u32 i, n;
3720   int retval = clib_net_to_host_u32 (mp->retval);
3721
3722   if (retval)
3723     goto end;
3724
3725   n = clib_net_to_host_u32 (mp->count);
3726   vat_json_init_array (&root);
3727
3728   for (i = 0; i < n; i++)
3729     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3730
3731   vat_json_print (vam->ofp, &root);
3732   vat_json_free (&root);
3733
3734 end:
3735   vam->retval = retval;
3736   vam->result_ready = 1;
3737 }
3738
3739 static void
3740   vl_api_one_ndp_entries_get_reply_t_handler
3741   (vl_api_one_ndp_entries_get_reply_t * mp)
3742 {
3743   vat_main_t *vam = &vat_main;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746
3747   if (retval)
3748     goto end;
3749
3750   n = clib_net_to_host_u32 (mp->count);
3751
3752   for (i = 0; i < n; i++)
3753     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3754            format_ethernet_address, mp->entries[i].mac);
3755
3756 end:
3757   vam->retval = retval;
3758   vam->result_ready = 1;
3759 }
3760
3761 static void
3762   vl_api_one_ndp_entries_get_reply_t_handler_json
3763   (vl_api_one_ndp_entries_get_reply_t * mp)
3764 {
3765   u8 *s = 0;
3766   vat_main_t *vam = &vat_main;
3767   vat_json_node_t *e = 0, root;
3768   u32 i, n;
3769   int retval = clib_net_to_host_u32 (mp->retval);
3770   vl_api_one_ndp_entry_t *arp_entry;
3771
3772   if (retval)
3773     goto end;
3774
3775   n = clib_net_to_host_u32 (mp->count);
3776   vat_json_init_array (&root);
3777
3778   for (i = 0; i < n; i++)
3779     {
3780       e = vat_json_array_add (&root);
3781       arp_entry = &mp->entries[i];
3782
3783       vat_json_init_object (e);
3784       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3785       vec_add1 (s, 0);
3786
3787       vat_json_object_add_string_copy (e, "mac", s);
3788       vec_free (s);
3789
3790       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3791       vec_add1 (s, 0);
3792       vat_json_object_add_string_copy (e, "ip6", s);
3793       vec_free (s);
3794     }
3795
3796   vat_json_print (vam->ofp, &root);
3797   vat_json_free (&root);
3798
3799 end:
3800   vam->retval = retval;
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_one_l2_arp_entries_get_reply_t_handler
3806   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   u32 i, n;
3810   int retval = clib_net_to_host_u32 (mp->retval);
3811
3812   if (retval)
3813     goto end;
3814
3815   n = clib_net_to_host_u32 (mp->count);
3816
3817   for (i = 0; i < n; i++)
3818     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3819            format_ethernet_address, mp->entries[i].mac);
3820
3821 end:
3822   vam->retval = retval;
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3828   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3829 {
3830   u8 *s = 0;
3831   vat_main_t *vam = &vat_main;
3832   vat_json_node_t *e = 0, root;
3833   u32 i, n;
3834   int retval = clib_net_to_host_u32 (mp->retval);
3835   vl_api_one_l2_arp_entry_t *arp_entry;
3836
3837   if (retval)
3838     goto end;
3839
3840   n = clib_net_to_host_u32 (mp->count);
3841   vat_json_init_array (&root);
3842
3843   for (i = 0; i < n; i++)
3844     {
3845       e = vat_json_array_add (&root);
3846       arp_entry = &mp->entries[i];
3847
3848       vat_json_init_object (e);
3849       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3850       vec_add1 (s, 0);
3851
3852       vat_json_object_add_string_copy (e, "mac", s);
3853       vec_free (s);
3854
3855       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3856       vec_add1 (s, 0);
3857       vat_json_object_add_string_copy (e, "ip4", s);
3858       vec_free (s);
3859     }
3860
3861   vat_json_print (vam->ofp, &root);
3862   vat_json_free (&root);
3863
3864 end:
3865   vam->retval = retval;
3866   vam->result_ready = 1;
3867 }
3868
3869 static void
3870 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   u32 i, n;
3874   int retval = clib_net_to_host_u32 (mp->retval);
3875
3876   if (retval)
3877     goto end;
3878
3879   n = clib_net_to_host_u32 (mp->count);
3880
3881   for (i = 0; i < n; i++)
3882     {
3883       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3884     }
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_ndp_bd_get_reply_t_handler_json
3893   (vl_api_one_ndp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   vat_json_node_t root;
3897   u32 i, n;
3898   int retval = clib_net_to_host_u32 (mp->retval);
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904   vat_json_init_array (&root);
3905
3906   for (i = 0; i < n; i++)
3907     {
3908       vat_json_array_add_uint (&root,
3909                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3910     }
3911
3912   vat_json_print (vam->ofp, &root);
3913   vat_json_free (&root);
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_l2_arp_bd_get_reply_t_handler
3922   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   u32 i, n;
3926   int retval = clib_net_to_host_u32 (mp->retval);
3927
3928   if (retval)
3929     goto end;
3930
3931   n = clib_net_to_host_u32 (mp->count);
3932
3933   for (i = 0; i < n; i++)
3934     {
3935       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3936     }
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3945   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   vat_json_node_t root;
3949   u32 i, n;
3950   int retval = clib_net_to_host_u32 (mp->retval);
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956   vat_json_init_array (&root);
3957
3958   for (i = 0; i < n; i++)
3959     {
3960       vat_json_array_add_uint (&root,
3961                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3962     }
3963
3964   vat_json_print (vam->ofp, &root);
3965   vat_json_free (&root);
3966
3967 end:
3968   vam->retval = retval;
3969   vam->result_ready = 1;
3970 }
3971
3972 static void
3973   vl_api_one_adjacencies_get_reply_t_handler
3974   (vl_api_one_adjacencies_get_reply_t * mp)
3975 {
3976   vat_main_t *vam = &vat_main;
3977   u32 i, n;
3978   int retval = clib_net_to_host_u32 (mp->retval);
3979   vl_api_one_adjacency_t *a;
3980
3981   if (retval)
3982     goto end;
3983
3984   n = clib_net_to_host_u32 (mp->count);
3985
3986   for (i = 0; i < n; i++)
3987     {
3988       a = &mp->adjacencies[i];
3989       print (vam->ofp, "%U %40U",
3990              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3991              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3992     }
3993
3994 end:
3995   vam->retval = retval;
3996   vam->result_ready = 1;
3997 }
3998
3999 static void
4000   vl_api_one_adjacencies_get_reply_t_handler_json
4001   (vl_api_one_adjacencies_get_reply_t * mp)
4002 {
4003   u8 *s = 0;
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t *e = 0, root;
4006   u32 i, n;
4007   int retval = clib_net_to_host_u32 (mp->retval);
4008   vl_api_one_adjacency_t *a;
4009
4010   if (retval)
4011     goto end;
4012
4013   n = clib_net_to_host_u32 (mp->count);
4014   vat_json_init_array (&root);
4015
4016   for (i = 0; i < n; i++)
4017     {
4018       e = vat_json_array_add (&root);
4019       a = &mp->adjacencies[i];
4020
4021       vat_json_init_object (e);
4022       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4023                   a->leid_prefix_len);
4024       vec_add1 (s, 0);
4025       vat_json_object_add_string_copy (e, "leid", s);
4026       vec_free (s);
4027
4028       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4029                   a->reid_prefix_len);
4030       vec_add1 (s, 0);
4031       vat_json_object_add_string_copy (e, "reid", s);
4032       vec_free (s);
4033     }
4034
4035   vat_json_print (vam->ofp, &root);
4036   vat_json_free (&root);
4037
4038 end:
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4045 {
4046   vat_main_t *vam = &vat_main;
4047
4048   print (vam->ofp, "%=20U",
4049          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4050          mp->ip_address);
4051 }
4052
4053 static void
4054   vl_api_one_map_server_details_t_handler_json
4055   (vl_api_one_map_server_details_t * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058   vat_json_node_t *node = NULL;
4059   struct in6_addr ip6;
4060   struct in_addr ip4;
4061
4062   if (VAT_JSON_ARRAY != vam->json_tree.type)
4063     {
4064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4065       vat_json_init_array (&vam->json_tree);
4066     }
4067   node = vat_json_array_add (&vam->json_tree);
4068
4069   vat_json_init_object (node);
4070   if (mp->is_ipv6)
4071     {
4072       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4073       vat_json_object_add_ip6 (node, "map-server", ip6);
4074     }
4075   else
4076     {
4077       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4078       vat_json_object_add_ip4 (node, "map-server", ip4);
4079     }
4080 }
4081
4082 static void
4083 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4084                                            * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087
4088   print (vam->ofp, "%=20U",
4089          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4090          mp->ip_address);
4091 }
4092
4093 static void
4094   vl_api_one_map_resolver_details_t_handler_json
4095   (vl_api_one_map_resolver_details_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098   vat_json_node_t *node = NULL;
4099   struct in6_addr ip6;
4100   struct in_addr ip4;
4101
4102   if (VAT_JSON_ARRAY != vam->json_tree.type)
4103     {
4104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4105       vat_json_init_array (&vam->json_tree);
4106     }
4107   node = vat_json_array_add (&vam->json_tree);
4108
4109   vat_json_init_object (node);
4110   if (mp->is_ipv6)
4111     {
4112       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4113       vat_json_object_add_ip6 (node, "map resolver", ip6);
4114     }
4115   else
4116     {
4117       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4118       vat_json_object_add_ip4 (node, "map resolver", ip4);
4119     }
4120 }
4121
4122 static void
4123 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4124 {
4125   vat_main_t *vam = &vat_main;
4126   i32 retval = ntohl (mp->retval);
4127
4128   if (0 <= retval)
4129     {
4130       print (vam->ofp, "feature: %s\ngpe: %s",
4131              mp->feature_status ? "enabled" : "disabled",
4132              mp->gpe_status ? "enabled" : "disabled");
4133     }
4134
4135   vam->retval = retval;
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_show_one_status_reply_t_handler_json
4141   (vl_api_show_one_status_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t node;
4145   u8 *gpe_status = NULL;
4146   u8 *feature_status = NULL;
4147
4148   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4149   feature_status = format (0, "%s",
4150                            mp->feature_status ? "enabled" : "disabled");
4151   vec_add1 (gpe_status, 0);
4152   vec_add1 (feature_status, 0);
4153
4154   vat_json_init_object (&node);
4155   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4156   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4157
4158   vec_free (gpe_status);
4159   vec_free (feature_status);
4160
4161   vat_json_print (vam->ofp, &node);
4162   vat_json_free (&node);
4163
4164   vam->retval = ntohl (mp->retval);
4165   vam->result_ready = 1;
4166 }
4167
4168 static void
4169   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4170   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   i32 retval = ntohl (mp->retval);
4174
4175   if (retval >= 0)
4176     {
4177       print (vam->ofp, "%=20s", mp->locator_set_name);
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4186   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t *node = NULL;
4190
4191   if (VAT_JSON_ARRAY != vam->json_tree.type)
4192     {
4193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4194       vat_json_init_array (&vam->json_tree);
4195     }
4196   node = vat_json_array_add (&vam->json_tree);
4197
4198   vat_json_init_object (node);
4199   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4200
4201   vat_json_print (vam->ofp, node);
4202   vat_json_free (node);
4203
4204   vam->retval = ntohl (mp->retval);
4205   vam->result_ready = 1;
4206 }
4207
4208 static u8 *
4209 format_lisp_map_request_mode (u8 * s, va_list * args)
4210 {
4211   u32 mode = va_arg (*args, u32);
4212
4213   switch (mode)
4214     {
4215     case 0:
4216       return format (0, "dst-only");
4217     case 1:
4218       return format (0, "src-dst");
4219     }
4220   return 0;
4221 }
4222
4223 static void
4224   vl_api_show_one_map_request_mode_reply_t_handler
4225   (vl_api_show_one_map_request_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   i32 retval = ntohl (mp->retval);
4229
4230   if (0 <= retval)
4231     {
4232       u32 mode = mp->mode;
4233       print (vam->ofp, "map_request_mode: %U",
4234              format_lisp_map_request_mode, mode);
4235     }
4236
4237   vam->retval = retval;
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_show_one_map_request_mode_reply_t_handler_json
4243   (vl_api_show_one_map_request_mode_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   vat_json_node_t node;
4247   u8 *s = 0;
4248   u32 mode;
4249
4250   mode = mp->mode;
4251   s = format (0, "%U", format_lisp_map_request_mode, mode);
4252   vec_add1 (s, 0);
4253
4254   vat_json_init_object (&node);
4255   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4256   vat_json_print (vam->ofp, &node);
4257   vat_json_free (&node);
4258
4259   vec_free (s);
4260   vam->retval = ntohl (mp->retval);
4261   vam->result_ready = 1;
4262 }
4263
4264 static void
4265   vl_api_one_show_xtr_mode_reply_t_handler
4266   (vl_api_one_show_xtr_mode_reply_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   i32 retval = ntohl (mp->retval);
4270
4271   if (0 <= retval)
4272     {
4273       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4274     }
4275
4276   vam->retval = retval;
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_one_show_xtr_mode_reply_t_handler_json
4282   (vl_api_one_show_xtr_mode_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286   u8 *status = 0;
4287
4288   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293
4294   vec_free (status);
4295
4296   vat_json_print (vam->ofp, &node);
4297   vat_json_free (&node);
4298
4299   vam->retval = ntohl (mp->retval);
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_one_show_pitr_mode_reply_t_handler
4305   (vl_api_one_show_pitr_mode_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   i32 retval = ntohl (mp->retval);
4309
4310   if (0 <= retval)
4311     {
4312       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_one_show_pitr_mode_reply_t_handler_json
4321   (vl_api_one_show_pitr_mode_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "status", status);
4332
4333   vec_free (status);
4334
4335   vat_json_print (vam->ofp, &node);
4336   vat_json_free (&node);
4337
4338   vam->retval = ntohl (mp->retval);
4339   vam->result_ready = 1;
4340 }
4341
4342 static void
4343   vl_api_one_show_petr_mode_reply_t_handler
4344   (vl_api_one_show_petr_mode_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   i32 retval = ntohl (mp->retval);
4348
4349   if (0 <= retval)
4350     {
4351       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4352     }
4353
4354   vam->retval = retval;
4355   vam->result_ready = 1;
4356 }
4357
4358 static void
4359   vl_api_one_show_petr_mode_reply_t_handler_json
4360   (vl_api_one_show_petr_mode_reply_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   vat_json_node_t node;
4364   u8 *status = 0;
4365
4366   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4367   vec_add1 (status, 0);
4368
4369   vat_json_init_object (&node);
4370   vat_json_object_add_string_copy (&node, "status", status);
4371
4372   vec_free (status);
4373
4374   vat_json_print (vam->ofp, &node);
4375   vat_json_free (&node);
4376
4377   vam->retval = ntohl (mp->retval);
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_use_petr_reply_t_handler
4383   (vl_api_show_one_use_petr_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   i32 retval = ntohl (mp->retval);
4387
4388   if (0 <= retval)
4389     {
4390       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4391       if (mp->status)
4392         {
4393           print (vam->ofp, "Proxy-ETR address; %U",
4394                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4395                  mp->address);
4396         }
4397     }
4398
4399   vam->retval = retval;
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_show_one_use_petr_reply_t_handler_json
4405   (vl_api_show_one_use_petr_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   vat_json_node_t node;
4409   u8 *status = 0;
4410   struct in_addr ip4;
4411   struct in6_addr ip6;
4412
4413   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4414   vec_add1 (status, 0);
4415
4416   vat_json_init_object (&node);
4417   vat_json_object_add_string_copy (&node, "status", status);
4418   if (mp->status)
4419     {
4420       if (mp->is_ip4)
4421         {
4422           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4423           vat_json_object_add_ip6 (&node, "address", ip6);
4424         }
4425       else
4426         {
4427           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4428           vat_json_object_add_ip4 (&node, "address", ip4);
4429         }
4430     }
4431
4432   vec_free (status);
4433
4434   vat_json_print (vam->ofp, &node);
4435   vat_json_free (&node);
4436
4437   vam->retval = ntohl (mp->retval);
4438   vam->result_ready = 1;
4439 }
4440
4441 static void
4442   vl_api_show_one_nsh_mapping_reply_t_handler
4443   (vl_api_show_one_nsh_mapping_reply_t * mp)
4444 {
4445   vat_main_t *vam = &vat_main;
4446   i32 retval = ntohl (mp->retval);
4447
4448   if (0 <= retval)
4449     {
4450       print (vam->ofp, "%-20s%-16s",
4451              mp->is_set ? "set" : "not-set",
4452              mp->is_set ? (char *) mp->locator_set_name : "");
4453     }
4454
4455   vam->retval = retval;
4456   vam->result_ready = 1;
4457 }
4458
4459 static void
4460   vl_api_show_one_nsh_mapping_reply_t_handler_json
4461   (vl_api_show_one_nsh_mapping_reply_t * mp)
4462 {
4463   vat_main_t *vam = &vat_main;
4464   vat_json_node_t node;
4465   u8 *status = 0;
4466
4467   status = format (0, "%s", mp->is_set ? "yes" : "no");
4468   vec_add1 (status, 0);
4469
4470   vat_json_init_object (&node);
4471   vat_json_object_add_string_copy (&node, "is_set", status);
4472   if (mp->is_set)
4473     {
4474       vat_json_object_add_string_copy (&node, "locator_set",
4475                                        mp->locator_set_name);
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_map_register_ttl_reply_t_handler
4489   (vl_api_show_one_map_register_ttl_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4495
4496   if (0 <= retval)
4497     {
4498       print (vam->ofp, "ttl: %u", mp->ttl);
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_map_register_ttl_reply_t_handler_json
4507   (vl_api_show_one_map_register_ttl_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511
4512   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4513   vat_json_init_object (&node);
4514   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4515
4516   vat_json_print (vam->ofp, &node);
4517   vat_json_free (&node);
4518
4519   vam->retval = ntohl (mp->retval);
4520   vam->result_ready = 1;
4521 }
4522
4523 static void
4524 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4525 {
4526   vat_main_t *vam = &vat_main;
4527   i32 retval = ntohl (mp->retval);
4528
4529   if (0 <= retval)
4530     {
4531       print (vam->ofp, "%-20s%-16s",
4532              mp->status ? "enabled" : "disabled",
4533              mp->status ? (char *) mp->locator_set_name : "");
4534     }
4535
4536   vam->retval = retval;
4537   vam->result_ready = 1;
4538 }
4539
4540 static void
4541 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4542 {
4543   vat_main_t *vam = &vat_main;
4544   vat_json_node_t node;
4545   u8 *status = 0;
4546
4547   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4548   vec_add1 (status, 0);
4549
4550   vat_json_init_object (&node);
4551   vat_json_object_add_string_copy (&node, "status", status);
4552   if (mp->status)
4553     {
4554       vat_json_object_add_string_copy (&node, "locator_set",
4555                                        mp->locator_set_name);
4556     }
4557
4558   vec_free (status);
4559
4560   vat_json_print (vam->ofp, &node);
4561   vat_json_free (&node);
4562
4563   vam->retval = ntohl (mp->retval);
4564   vam->result_ready = 1;
4565 }
4566
4567 static u8 *
4568 format_policer_type (u8 * s, va_list * va)
4569 {
4570   u32 i = va_arg (*va, u32);
4571
4572   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4573     s = format (s, "1r2c");
4574   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4575     s = format (s, "1r3c");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4577     s = format (s, "2r3c-2698");
4578   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4579     s = format (s, "2r3c-4115");
4580   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4581     s = format (s, "2r3c-mef5cf1");
4582   else
4583     s = format (s, "ILLEGAL");
4584   return s;
4585 }
4586
4587 static u8 *
4588 format_policer_rate_type (u8 * s, va_list * va)
4589 {
4590   u32 i = va_arg (*va, u32);
4591
4592   if (i == SSE2_QOS_RATE_KBPS)
4593     s = format (s, "kbps");
4594   else if (i == SSE2_QOS_RATE_PPS)
4595     s = format (s, "pps");
4596   else
4597     s = format (s, "ILLEGAL");
4598   return s;
4599 }
4600
4601 static u8 *
4602 format_policer_round_type (u8 * s, va_list * va)
4603 {
4604   u32 i = va_arg (*va, u32);
4605
4606   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4607     s = format (s, "closest");
4608   else if (i == SSE2_QOS_ROUND_TO_UP)
4609     s = format (s, "up");
4610   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4611     s = format (s, "down");
4612   else
4613     s = format (s, "ILLEGAL");
4614   return s;
4615 }
4616
4617 static u8 *
4618 format_policer_action_type (u8 * s, va_list * va)
4619 {
4620   u32 i = va_arg (*va, u32);
4621
4622   if (i == SSE2_QOS_ACTION_DROP)
4623     s = format (s, "drop");
4624   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4625     s = format (s, "transmit");
4626   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4627     s = format (s, "mark-and-transmit");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_dscp (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637   char *t = 0;
4638
4639   switch (i)
4640     {
4641 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4642       foreach_vnet_dscp
4643 #undef _
4644     default:
4645       return format (s, "ILLEGAL");
4646     }
4647   s = format (s, "%s", t);
4648   return s;
4649 }
4650
4651 static void
4652 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4656
4657   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4658     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4659   else
4660     conform_dscp_str = format (0, "");
4661
4662   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4663     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4664   else
4665     exceed_dscp_str = format (0, "");
4666
4667   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4668     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4669   else
4670     violate_dscp_str = format (0, "");
4671
4672   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4673          "rate type %U, round type %U, %s rate, %s color-aware, "
4674          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4675          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4676          "conform action %U%s, exceed action %U%s, violate action %U%s",
4677          mp->name,
4678          format_policer_type, mp->type,
4679          ntohl (mp->cir),
4680          ntohl (mp->eir),
4681          clib_net_to_host_u64 (mp->cb),
4682          clib_net_to_host_u64 (mp->eb),
4683          format_policer_rate_type, mp->rate_type,
4684          format_policer_round_type, mp->round_type,
4685          mp->single_rate ? "single" : "dual",
4686          mp->color_aware ? "is" : "not",
4687          ntohl (mp->cir_tokens_per_period),
4688          ntohl (mp->pir_tokens_per_period),
4689          ntohl (mp->scale),
4690          ntohl (mp->current_limit),
4691          ntohl (mp->current_bucket),
4692          ntohl (mp->extended_limit),
4693          ntohl (mp->extended_bucket),
4694          clib_net_to_host_u64 (mp->last_update_time),
4695          format_policer_action_type, mp->conform_action_type,
4696          conform_dscp_str,
4697          format_policer_action_type, mp->exceed_action_type,
4698          exceed_dscp_str,
4699          format_policer_action_type, mp->violate_action_type,
4700          violate_dscp_str);
4701
4702   vec_free (conform_dscp_str);
4703   vec_free (exceed_dscp_str);
4704   vec_free (violate_dscp_str);
4705 }
4706
4707 static void vl_api_policer_details_t_handler_json
4708   (vl_api_policer_details_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   vat_json_node_t *node;
4712   u8 *rate_type_str, *round_type_str, *type_str;
4713   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4714
4715   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4716   round_type_str =
4717     format (0, "%U", format_policer_round_type, mp->round_type);
4718   type_str = format (0, "%U", format_policer_type, mp->type);
4719   conform_action_str = format (0, "%U", format_policer_action_type,
4720                                mp->conform_action_type);
4721   exceed_action_str = format (0, "%U", format_policer_action_type,
4722                               mp->exceed_action_type);
4723   violate_action_str = format (0, "%U", format_policer_action_type,
4724                                mp->violate_action_type);
4725
4726   if (VAT_JSON_ARRAY != vam->json_tree.type)
4727     {
4728       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4729       vat_json_init_array (&vam->json_tree);
4730     }
4731   node = vat_json_array_add (&vam->json_tree);
4732
4733   vat_json_init_object (node);
4734   vat_json_object_add_string_copy (node, "name", mp->name);
4735   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4736   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4737   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4738   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4739   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4740   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4741   vat_json_object_add_string_copy (node, "type", type_str);
4742   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4743   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4744   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4745   vat_json_object_add_uint (node, "cir_tokens_per_period",
4746                             ntohl (mp->cir_tokens_per_period));
4747   vat_json_object_add_uint (node, "eir_tokens_per_period",
4748                             ntohl (mp->pir_tokens_per_period));
4749   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4750   vat_json_object_add_uint (node, "current_bucket",
4751                             ntohl (mp->current_bucket));
4752   vat_json_object_add_uint (node, "extended_limit",
4753                             ntohl (mp->extended_limit));
4754   vat_json_object_add_uint (node, "extended_bucket",
4755                             ntohl (mp->extended_bucket));
4756   vat_json_object_add_uint (node, "last_update_time",
4757                             ntohl (mp->last_update_time));
4758   vat_json_object_add_string_copy (node, "conform_action",
4759                                    conform_action_str);
4760   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4761     {
4762       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4763       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4764       vec_free (dscp_str);
4765     }
4766   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4767   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4768     {
4769       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4770       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4771       vec_free (dscp_str);
4772     }
4773   vat_json_object_add_string_copy (node, "violate_action",
4774                                    violate_action_str);
4775   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4776     {
4777       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4778       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4779       vec_free (dscp_str);
4780     }
4781
4782   vec_free (rate_type_str);
4783   vec_free (round_type_str);
4784   vec_free (type_str);
4785   vec_free (conform_action_str);
4786   vec_free (exceed_action_str);
4787   vec_free (violate_action_str);
4788 }
4789
4790 static void
4791 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4792                                            mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   int i, count = ntohl (mp->count);
4796
4797   if (count > 0)
4798     print (vam->ofp, "classify table ids (%d) : ", count);
4799   for (i = 0; i < count; i++)
4800     {
4801       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4802       print (vam->ofp, (i < count - 1) ? "," : "");
4803     }
4804   vam->retval = ntohl (mp->retval);
4805   vam->result_ready = 1;
4806 }
4807
4808 static void
4809   vl_api_classify_table_ids_reply_t_handler_json
4810   (vl_api_classify_table_ids_reply_t * mp)
4811 {
4812   vat_main_t *vam = &vat_main;
4813   int i, count = ntohl (mp->count);
4814
4815   if (count > 0)
4816     {
4817       vat_json_node_t node;
4818
4819       vat_json_init_object (&node);
4820       for (i = 0; i < count; i++)
4821         {
4822           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4823         }
4824       vat_json_print (vam->ofp, &node);
4825       vat_json_free (&node);
4826     }
4827   vam->retval = ntohl (mp->retval);
4828   vam->result_ready = 1;
4829 }
4830
4831 static void
4832   vl_api_classify_table_by_interface_reply_t_handler
4833   (vl_api_classify_table_by_interface_reply_t * mp)
4834 {
4835   vat_main_t *vam = &vat_main;
4836   u32 table_id;
4837
4838   table_id = ntohl (mp->l2_table_id);
4839   if (table_id != ~0)
4840     print (vam->ofp, "l2 table id : %d", table_id);
4841   else
4842     print (vam->ofp, "l2 table id : No input ACL tables configured");
4843   table_id = ntohl (mp->ip4_table_id);
4844   if (table_id != ~0)
4845     print (vam->ofp, "ip4 table id : %d", table_id);
4846   else
4847     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4848   table_id = ntohl (mp->ip6_table_id);
4849   if (table_id != ~0)
4850     print (vam->ofp, "ip6 table id : %d", table_id);
4851   else
4852     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4853   vam->retval = ntohl (mp->retval);
4854   vam->result_ready = 1;
4855 }
4856
4857 static void
4858   vl_api_classify_table_by_interface_reply_t_handler_json
4859   (vl_api_classify_table_by_interface_reply_t * mp)
4860 {
4861   vat_main_t *vam = &vat_main;
4862   vat_json_node_t node;
4863
4864   vat_json_init_object (&node);
4865
4866   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4867   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4868   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4869
4870   vat_json_print (vam->ofp, &node);
4871   vat_json_free (&node);
4872
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void vl_api_policer_add_del_reply_t_handler
4878   (vl_api_policer_add_del_reply_t * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   i32 retval = ntohl (mp->retval);
4882   if (vam->async_mode)
4883     {
4884       vam->async_errors += (retval < 0);
4885     }
4886   else
4887     {
4888       vam->retval = retval;
4889       vam->result_ready = 1;
4890       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4891         /*
4892          * Note: this is just barely thread-safe, depends on
4893          * the main thread spinning waiting for an answer...
4894          */
4895         errmsg ("policer index %d", ntohl (mp->policer_index));
4896     }
4897 }
4898
4899 static void vl_api_policer_add_del_reply_t_handler_json
4900   (vl_api_policer_add_del_reply_t * mp)
4901 {
4902   vat_main_t *vam = &vat_main;
4903   vat_json_node_t node;
4904
4905   vat_json_init_object (&node);
4906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4907   vat_json_object_add_uint (&node, "policer_index",
4908                             ntohl (mp->policer_index));
4909
4910   vat_json_print (vam->ofp, &node);
4911   vat_json_free (&node);
4912
4913   vam->retval = ntohl (mp->retval);
4914   vam->result_ready = 1;
4915 }
4916
4917 /* Format hex dump. */
4918 u8 *
4919 format_hex_bytes (u8 * s, va_list * va)
4920 {
4921   u8 *bytes = va_arg (*va, u8 *);
4922   int n_bytes = va_arg (*va, int);
4923   uword i;
4924
4925   /* Print short or long form depending on byte count. */
4926   uword short_form = n_bytes <= 32;
4927   u32 indent = format_get_indent (s);
4928
4929   if (n_bytes == 0)
4930     return s;
4931
4932   for (i = 0; i < n_bytes; i++)
4933     {
4934       if (!short_form && (i % 32) == 0)
4935         s = format (s, "%08x: ", i);
4936       s = format (s, "%02x", bytes[i]);
4937       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4938         s = format (s, "\n%U", format_white_space, indent);
4939     }
4940
4941   return s;
4942 }
4943
4944 static void
4945 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4946                                             * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   i32 retval = ntohl (mp->retval);
4950   if (retval == 0)
4951     {
4952       print (vam->ofp, "classify table info :");
4953       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4954              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4955              ntohl (mp->miss_next_index));
4956       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4957              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4958              ntohl (mp->match_n_vectors));
4959       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4960              ntohl (mp->mask_length));
4961     }
4962   vam->retval = retval;
4963   vam->result_ready = 1;
4964 }
4965
4966 static void
4967   vl_api_classify_table_info_reply_t_handler_json
4968   (vl_api_classify_table_info_reply_t * mp)
4969 {
4970   vat_main_t *vam = &vat_main;
4971   vat_json_node_t node;
4972
4973   i32 retval = ntohl (mp->retval);
4974   if (retval == 0)
4975     {
4976       vat_json_init_object (&node);
4977
4978       vat_json_object_add_int (&node, "sessions",
4979                                ntohl (mp->active_sessions));
4980       vat_json_object_add_int (&node, "nexttbl",
4981                                ntohl (mp->next_table_index));
4982       vat_json_object_add_int (&node, "nextnode",
4983                                ntohl (mp->miss_next_index));
4984       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4985       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4986       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4987       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4988                       ntohl (mp->mask_length), 0);
4989       vat_json_object_add_string_copy (&node, "mask", s);
4990
4991       vat_json_print (vam->ofp, &node);
4992       vat_json_free (&node);
4993     }
4994   vam->retval = ntohl (mp->retval);
4995   vam->result_ready = 1;
4996 }
4997
4998 static void
4999 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5000                                            mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5005          ntohl (mp->hit_next_index), ntohl (mp->advance),
5006          ntohl (mp->opaque_index));
5007   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5008          ntohl (mp->match_length));
5009 }
5010
5011 static void
5012   vl_api_classify_session_details_t_handler_json
5013   (vl_api_classify_session_details_t * mp)
5014 {
5015   vat_main_t *vam = &vat_main;
5016   vat_json_node_t *node = NULL;
5017
5018   if (VAT_JSON_ARRAY != vam->json_tree.type)
5019     {
5020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5021       vat_json_init_array (&vam->json_tree);
5022     }
5023   node = vat_json_array_add (&vam->json_tree);
5024
5025   vat_json_init_object (node);
5026   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5027   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5028   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5029   u8 *s =
5030     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5031             0);
5032   vat_json_object_add_string_copy (node, "match", s);
5033 }
5034
5035 static void vl_api_pg_create_interface_reply_t_handler
5036   (vl_api_pg_create_interface_reply_t * mp)
5037 {
5038   vat_main_t *vam = &vat_main;
5039
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void vl_api_pg_create_interface_reply_t_handler_json
5045   (vl_api_pg_create_interface_reply_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   vat_json_node_t node;
5049
5050   i32 retval = ntohl (mp->retval);
5051   if (retval == 0)
5052     {
5053       vat_json_init_object (&node);
5054
5055       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5056
5057       vat_json_print (vam->ofp, &node);
5058       vat_json_free (&node);
5059     }
5060   vam->retval = ntohl (mp->retval);
5061   vam->result_ready = 1;
5062 }
5063
5064 static void vl_api_policer_classify_details_t_handler
5065   (vl_api_policer_classify_details_t * mp)
5066 {
5067   vat_main_t *vam = &vat_main;
5068
5069   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5070          ntohl (mp->table_index));
5071 }
5072
5073 static void vl_api_policer_classify_details_t_handler_json
5074   (vl_api_policer_classify_details_t * mp)
5075 {
5076   vat_main_t *vam = &vat_main;
5077   vat_json_node_t *node;
5078
5079   if (VAT_JSON_ARRAY != vam->json_tree.type)
5080     {
5081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5082       vat_json_init_array (&vam->json_tree);
5083     }
5084   node = vat_json_array_add (&vam->json_tree);
5085
5086   vat_json_init_object (node);
5087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5088   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5089 }
5090
5091 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5092   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5093 {
5094   vat_main_t *vam = &vat_main;
5095   i32 retval = ntohl (mp->retval);
5096   if (vam->async_mode)
5097     {
5098       vam->async_errors += (retval < 0);
5099     }
5100   else
5101     {
5102       vam->retval = retval;
5103       vam->sw_if_index = ntohl (mp->sw_if_index);
5104       vam->result_ready = 1;
5105     }
5106   vam->regenerate_interface_table = 1;
5107 }
5108
5109 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5110   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   vat_json_node_t node;
5114
5115   vat_json_init_object (&node);
5116   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5117   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5118
5119   vat_json_print (vam->ofp, &node);
5120   vat_json_free (&node);
5121
5122   vam->retval = ntohl (mp->retval);
5123   vam->result_ready = 1;
5124 }
5125
5126 static void vl_api_flow_classify_details_t_handler
5127   (vl_api_flow_classify_details_t * mp)
5128 {
5129   vat_main_t *vam = &vat_main;
5130
5131   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5132          ntohl (mp->table_index));
5133 }
5134
5135 static void vl_api_flow_classify_details_t_handler_json
5136   (vl_api_flow_classify_details_t * mp)
5137 {
5138   vat_main_t *vam = &vat_main;
5139   vat_json_node_t *node;
5140
5141   if (VAT_JSON_ARRAY != vam->json_tree.type)
5142     {
5143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5144       vat_json_init_array (&vam->json_tree);
5145     }
5146   node = vat_json_array_add (&vam->json_tree);
5147
5148   vat_json_init_object (node);
5149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5150   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5151 }
5152
5153 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5154 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5155 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5156 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5157 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5158 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5159 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5160 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5161 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5162 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5163
5164 /*
5165  * Generate boilerplate reply handlers, which
5166  * dig the return value out of the xxx_reply_t API message,
5167  * stick it into vam->retval, and set vam->result_ready
5168  *
5169  * Could also do this by pointing N message decode slots at
5170  * a single function, but that could break in subtle ways.
5171  */
5172
5173 #define foreach_standard_reply_retval_handler           \
5174 _(sw_interface_set_flags_reply)                         \
5175 _(sw_interface_add_del_address_reply)                   \
5176 _(sw_interface_set_rx_mode_reply)                       \
5177 _(sw_interface_set_rx_placement_reply)                  \
5178 _(sw_interface_set_table_reply)                         \
5179 _(sw_interface_set_mpls_enable_reply)                   \
5180 _(sw_interface_set_vpath_reply)                         \
5181 _(sw_interface_set_vxlan_bypass_reply)                  \
5182 _(sw_interface_set_geneve_bypass_reply)                 \
5183 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5184 _(sw_interface_set_l2_bridge_reply)                     \
5185 _(bridge_domain_add_del_reply)                          \
5186 _(sw_interface_set_l2_xconnect_reply)                   \
5187 _(l2fib_add_del_reply)                                  \
5188 _(l2fib_flush_int_reply)                                \
5189 _(l2fib_flush_bd_reply)                                 \
5190 _(ip_add_del_route_reply)                               \
5191 _(ip_table_add_del_reply)                               \
5192 _(ip_mroute_add_del_reply)                              \
5193 _(mpls_route_add_del_reply)                             \
5194 _(mpls_table_add_del_reply)                             \
5195 _(mpls_ip_bind_unbind_reply)                            \
5196 _(bier_route_add_del_reply)                             \
5197 _(bier_table_add_del_reply)                             \
5198 _(proxy_arp_add_del_reply)                              \
5199 _(proxy_arp_intfc_enable_disable_reply)                 \
5200 _(sw_interface_set_unnumbered_reply)                    \
5201 _(ip_neighbor_add_del_reply)                            \
5202 _(oam_add_del_reply)                                    \
5203 _(reset_fib_reply)                                      \
5204 _(dhcp_proxy_config_reply)                              \
5205 _(dhcp_proxy_set_vss_reply)                             \
5206 _(dhcp_client_config_reply)                             \
5207 _(set_ip_flow_hash_reply)                               \
5208 _(sw_interface_ip6_enable_disable_reply)                \
5209 _(ip6nd_proxy_add_del_reply)                            \
5210 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5211 _(sw_interface_ip6nd_ra_config_reply)                   \
5212 _(set_arp_neighbor_limit_reply)                         \
5213 _(l2_patch_add_del_reply)                               \
5214 _(sr_mpls_policy_add_reply)                             \
5215 _(sr_mpls_policy_mod_reply)                             \
5216 _(sr_mpls_policy_del_reply)                             \
5217 _(sr_policy_add_reply)                                  \
5218 _(sr_policy_mod_reply)                                  \
5219 _(sr_policy_del_reply)                                  \
5220 _(sr_localsid_add_del_reply)                            \
5221 _(sr_steering_add_del_reply)                            \
5222 _(classify_add_del_session_reply)                       \
5223 _(classify_set_interface_ip_table_reply)                \
5224 _(classify_set_interface_l2_tables_reply)               \
5225 _(l2tpv3_set_tunnel_cookies_reply)                      \
5226 _(l2tpv3_interface_enable_disable_reply)                \
5227 _(l2tpv3_set_lookup_key_reply)                          \
5228 _(l2_fib_clear_table_reply)                             \
5229 _(l2_interface_efp_filter_reply)                        \
5230 _(l2_interface_vlan_tag_rewrite_reply)                  \
5231 _(modify_vhost_user_if_reply)                           \
5232 _(delete_vhost_user_if_reply)                           \
5233 _(ip_probe_neighbor_reply)                              \
5234 _(ip_scan_neighbor_enable_disable_reply)                \
5235 _(want_ip4_arp_events_reply)                            \
5236 _(want_ip6_nd_events_reply)                             \
5237 _(want_l2_macs_events_reply)                            \
5238 _(input_acl_set_interface_reply)                        \
5239 _(ipsec_spd_add_del_reply)                              \
5240 _(ipsec_interface_add_del_spd_reply)                    \
5241 _(ipsec_spd_add_del_entry_reply)                        \
5242 _(ipsec_sad_add_del_entry_reply)                        \
5243 _(ipsec_sa_set_key_reply)                               \
5244 _(ipsec_tunnel_if_add_del_reply)                        \
5245 _(ipsec_tunnel_if_set_key_reply)                        \
5246 _(ipsec_tunnel_if_set_sa_reply)                         \
5247 _(ikev2_profile_add_del_reply)                          \
5248 _(ikev2_profile_set_auth_reply)                         \
5249 _(ikev2_profile_set_id_reply)                           \
5250 _(ikev2_profile_set_ts_reply)                           \
5251 _(ikev2_set_local_key_reply)                            \
5252 _(ikev2_set_responder_reply)                            \
5253 _(ikev2_set_ike_transforms_reply)                       \
5254 _(ikev2_set_esp_transforms_reply)                       \
5255 _(ikev2_set_sa_lifetime_reply)                          \
5256 _(ikev2_initiate_sa_init_reply)                         \
5257 _(ikev2_initiate_del_ike_sa_reply)                      \
5258 _(ikev2_initiate_del_child_sa_reply)                    \
5259 _(ikev2_initiate_rekey_child_sa_reply)                  \
5260 _(delete_loopback_reply)                                \
5261 _(bd_ip_mac_add_del_reply)                              \
5262 _(bd_ip_mac_flush_reply)                                \
5263 _(want_interface_events_reply)                          \
5264 _(cop_interface_enable_disable_reply)                   \
5265 _(cop_whitelist_enable_disable_reply)                   \
5266 _(sw_interface_clear_stats_reply)                       \
5267 _(ioam_enable_reply)                                    \
5268 _(ioam_disable_reply)                                   \
5269 _(one_add_del_locator_reply)                            \
5270 _(one_add_del_local_eid_reply)                          \
5271 _(one_add_del_remote_mapping_reply)                     \
5272 _(one_add_del_adjacency_reply)                          \
5273 _(one_add_del_map_resolver_reply)                       \
5274 _(one_add_del_map_server_reply)                         \
5275 _(one_enable_disable_reply)                             \
5276 _(one_rloc_probe_enable_disable_reply)                  \
5277 _(one_map_register_enable_disable_reply)                \
5278 _(one_map_register_set_ttl_reply)                       \
5279 _(one_set_transport_protocol_reply)                     \
5280 _(one_map_register_fallback_threshold_reply)            \
5281 _(one_pitr_set_locator_set_reply)                       \
5282 _(one_map_request_mode_reply)                           \
5283 _(one_add_del_map_request_itr_rlocs_reply)              \
5284 _(one_eid_table_add_del_map_reply)                      \
5285 _(one_use_petr_reply)                                   \
5286 _(one_stats_enable_disable_reply)                       \
5287 _(one_add_del_l2_arp_entry_reply)                       \
5288 _(one_add_del_ndp_entry_reply)                          \
5289 _(one_stats_flush_reply)                                \
5290 _(one_enable_disable_xtr_mode_reply)                    \
5291 _(one_enable_disable_pitr_mode_reply)                   \
5292 _(one_enable_disable_petr_mode_reply)                   \
5293 _(gpe_enable_disable_reply)                             \
5294 _(gpe_set_encap_mode_reply)                             \
5295 _(gpe_add_del_iface_reply)                              \
5296 _(gpe_add_del_native_fwd_rpath_reply)                   \
5297 _(af_packet_delete_reply)                               \
5298 _(policer_classify_set_interface_reply)                 \
5299 _(netmap_create_reply)                                  \
5300 _(netmap_delete_reply)                                  \
5301 _(set_ipfix_exporter_reply)                             \
5302 _(set_ipfix_classify_stream_reply)                      \
5303 _(ipfix_classify_table_add_del_reply)                   \
5304 _(flow_classify_set_interface_reply)                    \
5305 _(sw_interface_span_enable_disable_reply)               \
5306 _(pg_capture_reply)                                     \
5307 _(pg_enable_disable_reply)                              \
5308 _(ip_source_and_port_range_check_add_del_reply)         \
5309 _(ip_source_and_port_range_check_interface_add_del_reply)\
5310 _(delete_subif_reply)                                   \
5311 _(l2_interface_pbb_tag_rewrite_reply)                   \
5312 _(set_punt_reply)                                       \
5313 _(feature_enable_disable_reply)                         \
5314 _(sw_interface_tag_add_del_reply)                       \
5315 _(hw_interface_set_mtu_reply)                           \
5316 _(p2p_ethernet_add_reply)                               \
5317 _(p2p_ethernet_del_reply)                               \
5318 _(lldp_config_reply)                                    \
5319 _(sw_interface_set_lldp_reply)                          \
5320 _(tcp_configure_src_addresses_reply)                    \
5321 _(dns_enable_disable_reply)                             \
5322 _(dns_name_server_add_del_reply)                        \
5323 _(session_rule_add_del_reply)                           \
5324 _(ip_container_proxy_add_del_reply)                     \
5325 _(output_acl_set_interface_reply)                       \
5326 _(qos_record_enable_disable_reply)
5327
5328 #define _(n)                                    \
5329     static void vl_api_##n##_t_handler          \
5330     (vl_api_##n##_t * mp)                       \
5331     {                                           \
5332         vat_main_t * vam = &vat_main;           \
5333         i32 retval = ntohl(mp->retval);         \
5334         if (vam->async_mode) {                  \
5335             vam->async_errors += (retval < 0);  \
5336         } else {                                \
5337             vam->retval = retval;               \
5338             vam->result_ready = 1;              \
5339         }                                       \
5340     }
5341 foreach_standard_reply_retval_handler;
5342 #undef _
5343
5344 #define _(n)                                    \
5345     static void vl_api_##n##_t_handler_json     \
5346     (vl_api_##n##_t * mp)                       \
5347     {                                           \
5348         vat_main_t * vam = &vat_main;           \
5349         vat_json_node_t node;                   \
5350         vat_json_init_object(&node);            \
5351         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5352         vat_json_print(vam->ofp, &node);        \
5353         vam->retval = ntohl(mp->retval);        \
5354         vam->result_ready = 1;                  \
5355     }
5356 foreach_standard_reply_retval_handler;
5357 #undef _
5358
5359 /*
5360  * Table of message reply handlers, must include boilerplate handlers
5361  * we just generated
5362  */
5363
5364 #define foreach_vpe_api_reply_msg                                       \
5365 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5366 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5367 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5368 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5369 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5370 _(CLI_REPLY, cli_reply)                                                 \
5371 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5372 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5373   sw_interface_add_del_address_reply)                                   \
5374 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5375 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5376 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5377 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5378 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5379 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5380 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5381 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5382 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5383 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5384   sw_interface_set_l2_xconnect_reply)                                   \
5385 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5386   sw_interface_set_l2_bridge_reply)                                     \
5387 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5388 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5389 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5390 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5391 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5392 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5393 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5394 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5395 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5396 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5397 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5398 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5399 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5400 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5401 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5402 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5403 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5404 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5405 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5406 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5407 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5408 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5409 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5410 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5411 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5412 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5413 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5414 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5415 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5416 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5417 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5418   proxy_arp_intfc_enable_disable_reply)                                 \
5419 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5420 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5421   sw_interface_set_unnumbered_reply)                                    \
5422 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5423 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5424 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5425 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5426 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5427 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5428 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5429 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5430 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5431 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5432 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5433   sw_interface_ip6_enable_disable_reply)                                \
5434 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5435 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5436 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5437   sw_interface_ip6nd_ra_prefix_reply)                                   \
5438 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5439   sw_interface_ip6nd_ra_config_reply)                                   \
5440 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5441 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5442 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5443 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5444 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5445 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5446 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5447 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5448 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5449 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5450 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5451 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5452 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5453 classify_set_interface_ip_table_reply)                                  \
5454 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5455   classify_set_interface_l2_tables_reply)                               \
5456 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5457 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5458 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5459 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5460 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5461   l2tpv3_interface_enable_disable_reply)                                \
5462 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5463 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5464 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5465 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5466 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5467 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5468 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5469 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5470 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5471 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5472 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5473 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5474 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5475 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5476 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5477 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5478 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5479 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5480 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5481 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5482 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5483 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5484 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5485 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5486 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5487 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5488 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5489 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5490 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5491 _(L2_MACS_EVENT, l2_macs_event)                                         \
5492 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5493 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5494 _(IP_DETAILS, ip_details)                                               \
5495 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5496 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5497 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5498 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5499 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5500 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5501 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5502 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5503 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5504 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5505 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5506 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5507 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5508 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5509 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5510 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5511 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5512 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5513 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5514 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5515 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5516 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5517 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5518 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5519 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5520 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5521 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5522 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5523 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5524 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5525 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5526 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5527 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5528 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5529 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5530 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5531 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5532 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5533 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5534 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5535 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5536 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5537 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5538 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5539   one_map_register_enable_disable_reply)                                \
5540 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5541 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5542 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5543 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5544   one_map_register_fallback_threshold_reply)                            \
5545 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5546   one_rloc_probe_enable_disable_reply)                                  \
5547 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5548 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5549 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5550 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5551 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5552 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5553 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5554 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5555 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5556 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5557 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5558 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5559 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5560 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5561 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5562 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5563   show_one_stats_enable_disable_reply)                                  \
5564 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5565 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5566 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5567 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5568 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5569 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5570 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5571 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5572   one_enable_disable_pitr_mode_reply)                                   \
5573 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5574   one_enable_disable_petr_mode_reply)                                   \
5575 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5576 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5577 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5578 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5579 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5580 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5581 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5582 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5583 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5584 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5585 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5586 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5587   gpe_add_del_native_fwd_rpath_reply)                                   \
5588 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5589   gpe_fwd_entry_path_details)                                           \
5590 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5591 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5592   one_add_del_map_request_itr_rlocs_reply)                              \
5593 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5594   one_get_map_request_itr_rlocs_reply)                                  \
5595 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5596 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5597 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5598 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5599 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5600 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5601   show_one_map_register_state_reply)                                    \
5602 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5603 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5604   show_one_map_register_fallback_threshold_reply)                       \
5605 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5606 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5607 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5608 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5609 _(POLICER_DETAILS, policer_details)                                     \
5610 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5611 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5612 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5613 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5614 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5615 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5616 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5617 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5618 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5619 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5620 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5621 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5622 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5623 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5624 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5625 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5626 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5627 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5628 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5629 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5630 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5631 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5632 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5633 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5634 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5635  ip_source_and_port_range_check_add_del_reply)                          \
5636 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5637  ip_source_and_port_range_check_interface_add_del_reply)                \
5638 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5639 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5640 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5641 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5642 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5643 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5644 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5645 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5646 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5647 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5648 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5649 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5650 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5651 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5652 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5653 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5654 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5655 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5656 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5657 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5658 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5659 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5660 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5661 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5662 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5663 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5664 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5665 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5666
5667 #define foreach_standalone_reply_msg                                    \
5668 _(SW_INTERFACE_EVENT, sw_interface_event)
5669
5670 typedef struct
5671 {
5672   u8 *name;
5673   u32 value;
5674 } name_sort_t;
5675
5676 #define STR_VTR_OP_CASE(op)     \
5677     case L2_VTR_ ## op:         \
5678         return "" # op;
5679
5680 static const char *
5681 str_vtr_op (u32 vtr_op)
5682 {
5683   switch (vtr_op)
5684     {
5685       STR_VTR_OP_CASE (DISABLED);
5686       STR_VTR_OP_CASE (PUSH_1);
5687       STR_VTR_OP_CASE (PUSH_2);
5688       STR_VTR_OP_CASE (POP_1);
5689       STR_VTR_OP_CASE (POP_2);
5690       STR_VTR_OP_CASE (TRANSLATE_1_1);
5691       STR_VTR_OP_CASE (TRANSLATE_1_2);
5692       STR_VTR_OP_CASE (TRANSLATE_2_1);
5693       STR_VTR_OP_CASE (TRANSLATE_2_2);
5694     }
5695
5696   return "UNKNOWN";
5697 }
5698
5699 static int
5700 dump_sub_interface_table (vat_main_t * vam)
5701 {
5702   const sw_interface_subif_t *sub = NULL;
5703
5704   if (vam->json_output)
5705     {
5706       clib_warning
5707         ("JSON output supported only for VPE API calls and dump_stats_table");
5708       return -99;
5709     }
5710
5711   print (vam->ofp,
5712          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5713          "Interface", "sw_if_index",
5714          "sub id", "dot1ad", "tags", "outer id",
5715          "inner id", "exact", "default", "outer any", "inner any");
5716
5717   vec_foreach (sub, vam->sw_if_subif_table)
5718   {
5719     print (vam->ofp,
5720            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5721            sub->interface_name,
5722            sub->sw_if_index,
5723            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5724            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5725            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5726            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5727     if (sub->vtr_op != L2_VTR_DISABLED)
5728       {
5729         print (vam->ofp,
5730                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5731                "tag1: %d tag2: %d ]",
5732                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5733                sub->vtr_tag1, sub->vtr_tag2);
5734       }
5735   }
5736
5737   return 0;
5738 }
5739
5740 static int
5741 name_sort_cmp (void *a1, void *a2)
5742 {
5743   name_sort_t *n1 = a1;
5744   name_sort_t *n2 = a2;
5745
5746   return strcmp ((char *) n1->name, (char *) n2->name);
5747 }
5748
5749 static int
5750 dump_interface_table (vat_main_t * vam)
5751 {
5752   hash_pair_t *p;
5753   name_sort_t *nses = 0, *ns;
5754
5755   if (vam->json_output)
5756     {
5757       clib_warning
5758         ("JSON output supported only for VPE API calls and dump_stats_table");
5759       return -99;
5760     }
5761
5762   /* *INDENT-OFF* */
5763   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5764   ({
5765     vec_add2 (nses, ns, 1);
5766     ns->name = (u8 *)(p->key);
5767     ns->value = (u32) p->value[0];
5768   }));
5769   /* *INDENT-ON* */
5770
5771   vec_sort_with_function (nses, name_sort_cmp);
5772
5773   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5774   vec_foreach (ns, nses)
5775   {
5776     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5777   }
5778   vec_free (nses);
5779   return 0;
5780 }
5781
5782 static int
5783 dump_ip_table (vat_main_t * vam, int is_ipv6)
5784 {
5785   const ip_details_t *det = NULL;
5786   const ip_address_details_t *address = NULL;
5787   u32 i = ~0;
5788
5789   print (vam->ofp, "%-12s", "sw_if_index");
5790
5791   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5792   {
5793     i++;
5794     if (!det->present)
5795       {
5796         continue;
5797       }
5798     print (vam->ofp, "%-12d", i);
5799     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5800     if (!det->addr)
5801       {
5802         continue;
5803       }
5804     vec_foreach (address, det->addr)
5805     {
5806       print (vam->ofp,
5807              "            %-30U%-13d",
5808              is_ipv6 ? format_ip6_address : format_ip4_address,
5809              address->ip, address->prefix_length);
5810     }
5811   }
5812
5813   return 0;
5814 }
5815
5816 static int
5817 dump_ipv4_table (vat_main_t * vam)
5818 {
5819   if (vam->json_output)
5820     {
5821       clib_warning
5822         ("JSON output supported only for VPE API calls and dump_stats_table");
5823       return -99;
5824     }
5825
5826   return dump_ip_table (vam, 0);
5827 }
5828
5829 static int
5830 dump_ipv6_table (vat_main_t * vam)
5831 {
5832   if (vam->json_output)
5833     {
5834       clib_warning
5835         ("JSON output supported only for VPE API calls and dump_stats_table");
5836       return -99;
5837     }
5838
5839   return dump_ip_table (vam, 1);
5840 }
5841
5842 /*
5843  * Pass CLI buffers directly in the CLI_INBAND API message,
5844  * instead of an additional shared memory area.
5845  */
5846 static int
5847 exec_inband (vat_main_t * vam)
5848 {
5849   vl_api_cli_inband_t *mp;
5850   unformat_input_t *i = vam->input;
5851   int ret;
5852
5853   if (vec_len (i->buffer) == 0)
5854     return -1;
5855
5856   if (vam->exec_mode == 0 && unformat (i, "mode"))
5857     {
5858       vam->exec_mode = 1;
5859       return 0;
5860     }
5861   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5862     {
5863       vam->exec_mode = 0;
5864       return 0;
5865     }
5866
5867   /*
5868    * In order for the CLI command to work, it
5869    * must be a vector ending in \n, not a C-string ending
5870    * in \n\0.
5871    */
5872   u32 len = vec_len (vam->input->buffer);
5873   M2 (CLI_INBAND, mp, len);
5874   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5875
5876   S (mp);
5877   W (ret);
5878   /* json responses may or may not include a useful reply... */
5879   if (vec_len (vam->cmd_reply))
5880     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5881   return ret;
5882 }
5883
5884 int
5885 exec (vat_main_t * vam)
5886 {
5887   return exec_inband (vam);
5888 }
5889
5890 static int
5891 api_create_loopback (vat_main_t * vam)
5892 {
5893   unformat_input_t *i = vam->input;
5894   vl_api_create_loopback_t *mp;
5895   vl_api_create_loopback_instance_t *mp_lbi;
5896   u8 mac_address[6];
5897   u8 mac_set = 0;
5898   u8 is_specified = 0;
5899   u32 user_instance = 0;
5900   int ret;
5901
5902   clib_memset (mac_address, 0, sizeof (mac_address));
5903
5904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5905     {
5906       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5907         mac_set = 1;
5908       if (unformat (i, "instance %d", &user_instance))
5909         is_specified = 1;
5910       else
5911         break;
5912     }
5913
5914   if (is_specified)
5915     {
5916       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5917       mp_lbi->is_specified = is_specified;
5918       if (is_specified)
5919         mp_lbi->user_instance = htonl (user_instance);
5920       if (mac_set)
5921         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5922       S (mp_lbi);
5923     }
5924   else
5925     {
5926       /* Construct the API message */
5927       M (CREATE_LOOPBACK, mp);
5928       if (mac_set)
5929         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5930       S (mp);
5931     }
5932
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_delete_loopback (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_delete_loopback_t *mp;
5942   u32 sw_if_index = ~0;
5943   int ret;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "sw_if_index %d", &sw_if_index))
5948         ;
5949       else
5950         break;
5951     }
5952
5953   if (sw_if_index == ~0)
5954     {
5955       errmsg ("missing sw_if_index");
5956       return -99;
5957     }
5958
5959   /* Construct the API message */
5960   M (DELETE_LOOPBACK, mp);
5961   mp->sw_if_index = ntohl (sw_if_index);
5962
5963   S (mp);
5964   W (ret);
5965   return ret;
5966 }
5967
5968 static int
5969 api_want_interface_events (vat_main_t * vam)
5970 {
5971   unformat_input_t *i = vam->input;
5972   vl_api_want_interface_events_t *mp;
5973   int enable = -1;
5974   int ret;
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "enable"))
5979         enable = 1;
5980       else if (unformat (i, "disable"))
5981         enable = 0;
5982       else
5983         break;
5984     }
5985
5986   if (enable == -1)
5987     {
5988       errmsg ("missing enable|disable");
5989       return -99;
5990     }
5991
5992   M (WANT_INTERFACE_EVENTS, mp);
5993   mp->enable_disable = enable;
5994
5995   vam->interface_event_display = enable;
5996
5997   S (mp);
5998   W (ret);
5999   return ret;
6000 }
6001
6002
6003 /* Note: non-static, called once to set up the initial intfc table */
6004 int
6005 api_sw_interface_dump (vat_main_t * vam)
6006 {
6007   vl_api_sw_interface_dump_t *mp;
6008   vl_api_control_ping_t *mp_ping;
6009   hash_pair_t *p;
6010   name_sort_t *nses = 0, *ns;
6011   sw_interface_subif_t *sub = NULL;
6012   int ret;
6013
6014   /* Toss the old name table */
6015   /* *INDENT-OFF* */
6016   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6017   ({
6018     vec_add2 (nses, ns, 1);
6019     ns->name = (u8 *)(p->key);
6020     ns->value = (u32) p->value[0];
6021   }));
6022   /* *INDENT-ON* */
6023
6024   hash_free (vam->sw_if_index_by_interface_name);
6025
6026   vec_foreach (ns, nses) vec_free (ns->name);
6027
6028   vec_free (nses);
6029
6030   vec_foreach (sub, vam->sw_if_subif_table)
6031   {
6032     vec_free (sub->interface_name);
6033   }
6034   vec_free (vam->sw_if_subif_table);
6035
6036   /* recreate the interface name hash table */
6037   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6038
6039   /*
6040    * Ask for all interface names. Otherwise, the epic catalog of
6041    * name filters becomes ridiculously long, and vat ends up needing
6042    * to be taught about new interface types.
6043    */
6044   M (SW_INTERFACE_DUMP, mp);
6045   S (mp);
6046
6047   /* Use a control ping for synchronization */
6048   MPING (CONTROL_PING, mp_ping);
6049   S (mp_ping);
6050
6051   W (ret);
6052   return ret;
6053 }
6054
6055 static int
6056 api_sw_interface_set_flags (vat_main_t * vam)
6057 {
6058   unformat_input_t *i = vam->input;
6059   vl_api_sw_interface_set_flags_t *mp;
6060   u32 sw_if_index;
6061   u8 sw_if_index_set = 0;
6062   u8 admin_up = 0;
6063   int ret;
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "admin-up"))
6069         admin_up = 1;
6070       else if (unformat (i, "admin-down"))
6071         admin_up = 0;
6072       else
6073         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6074         sw_if_index_set = 1;
6075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6076         sw_if_index_set = 1;
6077       else
6078         break;
6079     }
6080
6081   if (sw_if_index_set == 0)
6082     {
6083       errmsg ("missing interface name or sw_if_index");
6084       return -99;
6085     }
6086
6087   /* Construct the API message */
6088   M (SW_INTERFACE_SET_FLAGS, mp);
6089   mp->sw_if_index = ntohl (sw_if_index);
6090   mp->admin_up_down = admin_up;
6091
6092   /* send it... */
6093   S (mp);
6094
6095   /* Wait for a reply, return the good/bad news... */
6096   W (ret);
6097   return ret;
6098 }
6099
6100 static int
6101 api_sw_interface_set_rx_mode (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_sw_interface_set_rx_mode_t *mp;
6105   u32 sw_if_index;
6106   u8 sw_if_index_set = 0;
6107   int ret;
6108   u8 queue_id_valid = 0;
6109   u32 queue_id;
6110   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "queue %d", &queue_id))
6116         queue_id_valid = 1;
6117       else if (unformat (i, "polling"))
6118         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6119       else if (unformat (i, "interrupt"))
6120         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6121       else if (unformat (i, "adaptive"))
6122         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6123       else
6124         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6125         sw_if_index_set = 1;
6126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         sw_if_index_set = 1;
6128       else
6129         break;
6130     }
6131
6132   if (sw_if_index_set == 0)
6133     {
6134       errmsg ("missing interface name or sw_if_index");
6135       return -99;
6136     }
6137   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6138     {
6139       errmsg ("missing rx-mode");
6140       return -99;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_SET_RX_MODE, mp);
6145   mp->sw_if_index = ntohl (sw_if_index);
6146   mp->mode = mode;
6147   mp->queue_id_valid = queue_id_valid;
6148   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6149
6150   /* send it... */
6151   S (mp);
6152
6153   /* Wait for a reply, return the good/bad news... */
6154   W (ret);
6155   return ret;
6156 }
6157
6158 static int
6159 api_sw_interface_set_rx_placement (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_set_rx_placement_t *mp;
6163   u32 sw_if_index;
6164   u8 sw_if_index_set = 0;
6165   int ret;
6166   u8 is_main = 0;
6167   u32 queue_id, thread_index;
6168
6169   /* Parse args required to build the message */
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "queue %d", &queue_id))
6173         ;
6174       else if (unformat (i, "main"))
6175         is_main = 1;
6176       else if (unformat (i, "worker %d", &thread_index))
6177         ;
6178       else
6179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6182         sw_if_index_set = 1;
6183       else
6184         break;
6185     }
6186
6187   if (sw_if_index_set == 0)
6188     {
6189       errmsg ("missing interface name or sw_if_index");
6190       return -99;
6191     }
6192
6193   if (is_main)
6194     thread_index = 0;
6195   /* Construct the API message */
6196   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6197   mp->sw_if_index = ntohl (sw_if_index);
6198   mp->worker_id = ntohl (thread_index);
6199   mp->queue_id = ntohl (queue_id);
6200   mp->is_main = is_main;
6201
6202   /* send it... */
6203   S (mp);
6204   /* Wait for a reply, return the good/bad news... */
6205   W (ret);
6206   return ret;
6207 }
6208
6209 static void vl_api_sw_interface_rx_placement_details_t_handler
6210   (vl_api_sw_interface_rx_placement_details_t * mp)
6211 {
6212   vat_main_t *vam = &vat_main;
6213   u32 worker_id = ntohl (mp->worker_id);
6214
6215   print (vam->ofp,
6216          "\n%-11d %-11s %-6d %-5d %-9s",
6217          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6218          worker_id, ntohl (mp->queue_id),
6219          (mp->mode ==
6220           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6221 }
6222
6223 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6224   (vl_api_sw_interface_rx_placement_details_t * mp)
6225 {
6226   vat_main_t *vam = &vat_main;
6227   vat_json_node_t *node = NULL;
6228
6229   if (VAT_JSON_ARRAY != vam->json_tree.type)
6230     {
6231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6232       vat_json_init_array (&vam->json_tree);
6233     }
6234   node = vat_json_array_add (&vam->json_tree);
6235
6236   vat_json_init_object (node);
6237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6238   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6239   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6240   vat_json_object_add_uint (node, "mode", mp->mode);
6241 }
6242
6243 static int
6244 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6245 {
6246   unformat_input_t *i = vam->input;
6247   vl_api_sw_interface_rx_placement_dump_t *mp;
6248   vl_api_control_ping_t *mp_ping;
6249   int ret;
6250   u32 sw_if_index;
6251   u8 sw_if_index_set = 0;
6252
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set++;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set++;
6259       else
6260         break;
6261     }
6262
6263   print (vam->ofp,
6264          "\n%-11s %-11s %-6s %-5s %-4s",
6265          "sw_if_index", "main/worker", "thread", "queue", "mode");
6266
6267   /* Dump Interface rx placement */
6268   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6269
6270   if (sw_if_index_set)
6271     mp->sw_if_index = htonl (sw_if_index);
6272   else
6273     mp->sw_if_index = ~0;
6274
6275   S (mp);
6276
6277   /* Use a control ping for synchronization */
6278   MPING (CONTROL_PING, mp_ping);
6279   S (mp_ping);
6280
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static int
6286 api_sw_interface_clear_stats (vat_main_t * vam)
6287 {
6288   unformat_input_t *i = vam->input;
6289   vl_api_sw_interface_clear_stats_t *mp;
6290   u32 sw_if_index;
6291   u8 sw_if_index_set = 0;
6292   int ret;
6293
6294   /* Parse args required to build the message */
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else
6302         break;
6303     }
6304
6305   /* Construct the API message */
6306   M (SW_INTERFACE_CLEAR_STATS, mp);
6307
6308   if (sw_if_index_set == 1)
6309     mp->sw_if_index = ntohl (sw_if_index);
6310   else
6311     mp->sw_if_index = ~0;
6312
6313   /* send it... */
6314   S (mp);
6315
6316   /* Wait for a reply, return the good/bad news... */
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_sw_interface_add_del_address (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_add_del_address_t *mp;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u8 is_add = 1, del_all = 0;
6329   u32 address_length = 0;
6330   u8 v4_address_set = 0;
6331   u8 v6_address_set = 0;
6332   ip4_address_t v4address;
6333   ip6_address_t v6address;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "del-all"))
6340         del_all = 1;
6341       else if (unformat (i, "del"))
6342         is_add = 0;
6343       else
6344         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "%U/%d",
6349                          unformat_ip4_address, &v4address, &address_length))
6350         v4_address_set = 1;
6351       else if (unformat (i, "%U/%d",
6352                          unformat_ip6_address, &v6address, &address_length))
6353         v6_address_set = 1;
6354       else
6355         break;
6356     }
6357
6358   if (sw_if_index_set == 0)
6359     {
6360       errmsg ("missing interface name or sw_if_index");
6361       return -99;
6362     }
6363   if (v4_address_set && v6_address_set)
6364     {
6365       errmsg ("both v4 and v6 addresses set");
6366       return -99;
6367     }
6368   if (!v4_address_set && !v6_address_set && !del_all)
6369     {
6370       errmsg ("no addresses set");
6371       return -99;
6372     }
6373
6374   /* Construct the API message */
6375   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6376
6377   mp->sw_if_index = ntohl (sw_if_index);
6378   mp->is_add = is_add;
6379   mp->del_all = del_all;
6380   if (v6_address_set)
6381     {
6382       mp->is_ipv6 = 1;
6383       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6384     }
6385   else
6386     {
6387       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6388     }
6389   mp->address_length = address_length;
6390
6391   /* send it... */
6392   S (mp);
6393
6394   /* Wait for a reply, return good/bad news  */
6395   W (ret);
6396   return ret;
6397 }
6398
6399 static int
6400 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_sw_interface_set_mpls_enable_t *mp;
6404   u32 sw_if_index;
6405   u8 sw_if_index_set = 0;
6406   u8 enable = 1;
6407   int ret;
6408
6409   /* Parse args required to build the message */
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "disable"))
6417         enable = 0;
6418       else if (unformat (i, "dis"))
6419         enable = 0;
6420       else
6421         break;
6422     }
6423
6424   if (sw_if_index_set == 0)
6425     {
6426       errmsg ("missing interface name or sw_if_index");
6427       return -99;
6428     }
6429
6430   /* Construct the API message */
6431   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6432
6433   mp->sw_if_index = ntohl (sw_if_index);
6434   mp->enable = enable;
6435
6436   /* send it... */
6437   S (mp);
6438
6439   /* Wait for a reply... */
6440   W (ret);
6441   return ret;
6442 }
6443
6444 static int
6445 api_sw_interface_set_table (vat_main_t * vam)
6446 {
6447   unformat_input_t *i = vam->input;
6448   vl_api_sw_interface_set_table_t *mp;
6449   u32 sw_if_index, vrf_id = 0;
6450   u8 sw_if_index_set = 0;
6451   u8 is_ipv6 = 0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "vrf %d", &vrf_id))
6462         ;
6463       else if (unformat (i, "ipv6"))
6464         is_ipv6 = 1;
6465       else
6466         break;
6467     }
6468
6469   if (sw_if_index_set == 0)
6470     {
6471       errmsg ("missing interface name or sw_if_index");
6472       return -99;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_SET_TABLE, mp);
6477
6478   mp->sw_if_index = ntohl (sw_if_index);
6479   mp->is_ipv6 = is_ipv6;
6480   mp->vrf_id = ntohl (vrf_id);
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static void vl_api_sw_interface_get_table_reply_t_handler
6491   (vl_api_sw_interface_get_table_reply_t * mp)
6492 {
6493   vat_main_t *vam = &vat_main;
6494
6495   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6496
6497   vam->retval = ntohl (mp->retval);
6498   vam->result_ready = 1;
6499
6500 }
6501
6502 static void vl_api_sw_interface_get_table_reply_t_handler_json
6503   (vl_api_sw_interface_get_table_reply_t * mp)
6504 {
6505   vat_main_t *vam = &vat_main;
6506   vat_json_node_t node;
6507
6508   vat_json_init_object (&node);
6509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6510   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6511
6512   vat_json_print (vam->ofp, &node);
6513   vat_json_free (&node);
6514
6515   vam->retval = ntohl (mp->retval);
6516   vam->result_ready = 1;
6517 }
6518
6519 static int
6520 api_sw_interface_get_table (vat_main_t * vam)
6521 {
6522   unformat_input_t *i = vam->input;
6523   vl_api_sw_interface_get_table_t *mp;
6524   u32 sw_if_index;
6525   u8 sw_if_index_set = 0;
6526   u8 is_ipv6 = 0;
6527   int ret;
6528
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
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   M (SW_INTERFACE_GET_TABLE, mp);
6548   mp->sw_if_index = htonl (sw_if_index);
6549   mp->is_ipv6 = is_ipv6;
6550
6551   S (mp);
6552   W (ret);
6553   return ret;
6554 }
6555
6556 static int
6557 api_sw_interface_set_vpath (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_sw_interface_set_vpath_t *mp;
6561   u32 sw_if_index = 0;
6562   u8 sw_if_index_set = 0;
6563   u8 is_enable = 0;
6564   int ret;
6565
6566   /* Parse args required to build the message */
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6570         sw_if_index_set = 1;
6571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6572         sw_if_index_set = 1;
6573       else if (unformat (i, "enable"))
6574         is_enable = 1;
6575       else if (unformat (i, "disable"))
6576         is_enable = 0;
6577       else
6578         break;
6579     }
6580
6581   if (sw_if_index_set == 0)
6582     {
6583       errmsg ("missing interface name or sw_if_index");
6584       return -99;
6585     }
6586
6587   /* Construct the API message */
6588   M (SW_INTERFACE_SET_VPATH, mp);
6589
6590   mp->sw_if_index = ntohl (sw_if_index);
6591   mp->enable = is_enable;
6592
6593   /* send it... */
6594   S (mp);
6595
6596   /* Wait for a reply... */
6597   W (ret);
6598   return ret;
6599 }
6600
6601 static int
6602 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6606   u32 sw_if_index = 0;
6607   u8 sw_if_index_set = 0;
6608   u8 is_enable = 1;
6609   u8 is_ipv6 = 0;
6610   int ret;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "enable"))
6620         is_enable = 1;
6621       else if (unformat (i, "disable"))
6622         is_enable = 0;
6623       else if (unformat (i, "ip4"))
6624         is_ipv6 = 0;
6625       else if (unformat (i, "ip6"))
6626         is_ipv6 = 1;
6627       else
6628         break;
6629     }
6630
6631   if (sw_if_index_set == 0)
6632     {
6633       errmsg ("missing interface name or sw_if_index");
6634       return -99;
6635     }
6636
6637   /* Construct the API message */
6638   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6639
6640   mp->sw_if_index = ntohl (sw_if_index);
6641   mp->enable = is_enable;
6642   mp->is_ipv6 = is_ipv6;
6643
6644   /* send it... */
6645   S (mp);
6646
6647   /* Wait for a reply... */
6648   W (ret);
6649   return ret;
6650 }
6651
6652 static int
6653 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6654 {
6655   unformat_input_t *i = vam->input;
6656   vl_api_sw_interface_set_geneve_bypass_t *mp;
6657   u32 sw_if_index = 0;
6658   u8 sw_if_index_set = 0;
6659   u8 is_enable = 1;
6660   u8 is_ipv6 = 0;
6661   int ret;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "enable"))
6671         is_enable = 1;
6672       else if (unformat (i, "disable"))
6673         is_enable = 0;
6674       else if (unformat (i, "ip4"))
6675         is_ipv6 = 0;
6676       else if (unformat (i, "ip6"))
6677         is_ipv6 = 1;
6678       else
6679         break;
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index");
6685       return -99;
6686     }
6687
6688   /* Construct the API message */
6689   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6690
6691   mp->sw_if_index = ntohl (sw_if_index);
6692   mp->enable = is_enable;
6693   mp->is_ipv6 = is_ipv6;
6694
6695   /* send it... */
6696   S (mp);
6697
6698   /* Wait for a reply... */
6699   W (ret);
6700   return ret;
6701 }
6702
6703 static int
6704 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6705 {
6706   unformat_input_t *i = vam->input;
6707   vl_api_sw_interface_set_l2_xconnect_t *mp;
6708   u32 rx_sw_if_index;
6709   u8 rx_sw_if_index_set = 0;
6710   u32 tx_sw_if_index;
6711   u8 tx_sw_if_index_set = 0;
6712   u8 enable = 1;
6713   int ret;
6714
6715   /* Parse args required to build the message */
6716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6717     {
6718       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6719         rx_sw_if_index_set = 1;
6720       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6721         tx_sw_if_index_set = 1;
6722       else if (unformat (i, "rx"))
6723         {
6724           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725             {
6726               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6727                             &rx_sw_if_index))
6728                 rx_sw_if_index_set = 1;
6729             }
6730           else
6731             break;
6732         }
6733       else if (unformat (i, "tx"))
6734         {
6735           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736             {
6737               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6738                             &tx_sw_if_index))
6739                 tx_sw_if_index_set = 1;
6740             }
6741           else
6742             break;
6743         }
6744       else if (unformat (i, "enable"))
6745         enable = 1;
6746       else if (unformat (i, "disable"))
6747         enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (rx_sw_if_index_set == 0)
6753     {
6754       errmsg ("missing rx interface name or rx_sw_if_index");
6755       return -99;
6756     }
6757
6758   if (enable && (tx_sw_if_index_set == 0))
6759     {
6760       errmsg ("missing tx interface name or tx_sw_if_index");
6761       return -99;
6762     }
6763
6764   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6765
6766   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6767   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6768   mp->enable = enable;
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_set_l2_bridge_t *mp;
6780   vl_api_l2_port_type_t port_type;
6781   u32 rx_sw_if_index;
6782   u8 rx_sw_if_index_set = 0;
6783   u32 bd_id;
6784   u8 bd_id_set = 0;
6785   u32 shg = 0;
6786   u8 enable = 1;
6787   int ret;
6788
6789   port_type = L2_API_PORT_TYPE_NORMAL;
6790
6791   /* Parse args required to build the message */
6792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6793     {
6794       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6795         rx_sw_if_index_set = 1;
6796       else if (unformat (i, "bd_id %d", &bd_id))
6797         bd_id_set = 1;
6798       else
6799         if (unformat
6800             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6801         rx_sw_if_index_set = 1;
6802       else if (unformat (i, "shg %d", &shg))
6803         ;
6804       else if (unformat (i, "bvi"))
6805         port_type = L2_API_PORT_TYPE_BVI;
6806       else if (unformat (i, "uu-fwd"))
6807         port_type = L2_API_PORT_TYPE_UU_FWD;
6808       else if (unformat (i, "enable"))
6809         enable = 1;
6810       else if (unformat (i, "disable"))
6811         enable = 0;
6812       else
6813         break;
6814     }
6815
6816   if (rx_sw_if_index_set == 0)
6817     {
6818       errmsg ("missing rx interface name or sw_if_index");
6819       return -99;
6820     }
6821
6822   if (enable && (bd_id_set == 0))
6823     {
6824       errmsg ("missing bridge domain");
6825       return -99;
6826     }
6827
6828   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6829
6830   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6831   mp->bd_id = ntohl (bd_id);
6832   mp->shg = (u8) shg;
6833   mp->port_type = ntohl (port_type);
6834   mp->enable = enable;
6835
6836   S (mp);
6837   W (ret);
6838   return ret;
6839 }
6840
6841 static int
6842 api_bridge_domain_dump (vat_main_t * vam)
6843 {
6844   unformat_input_t *i = vam->input;
6845   vl_api_bridge_domain_dump_t *mp;
6846   vl_api_control_ping_t *mp_ping;
6847   u32 bd_id = ~0;
6848   int ret;
6849
6850   /* Parse args required to build the message */
6851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6852     {
6853       if (unformat (i, "bd_id %d", &bd_id))
6854         ;
6855       else
6856         break;
6857     }
6858
6859   M (BRIDGE_DOMAIN_DUMP, mp);
6860   mp->bd_id = ntohl (bd_id);
6861   S (mp);
6862
6863   /* Use a control ping for synchronization */
6864   MPING (CONTROL_PING, mp_ping);
6865   S (mp_ping);
6866
6867   W (ret);
6868   return ret;
6869 }
6870
6871 static int
6872 api_bridge_domain_add_del (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_bridge_domain_add_del_t *mp;
6876   u32 bd_id = ~0;
6877   u8 is_add = 1;
6878   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6879   u8 *bd_tag = NULL;
6880   u32 mac_age = 0;
6881   int ret;
6882
6883   /* Parse args required to build the message */
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "bd_id %d", &bd_id))
6887         ;
6888       else if (unformat (i, "flood %d", &flood))
6889         ;
6890       else if (unformat (i, "uu-flood %d", &uu_flood))
6891         ;
6892       else if (unformat (i, "forward %d", &forward))
6893         ;
6894       else if (unformat (i, "learn %d", &learn))
6895         ;
6896       else if (unformat (i, "arp-term %d", &arp_term))
6897         ;
6898       else if (unformat (i, "mac-age %d", &mac_age))
6899         ;
6900       else if (unformat (i, "bd-tag %s", &bd_tag))
6901         ;
6902       else if (unformat (i, "del"))
6903         {
6904           is_add = 0;
6905           flood = uu_flood = forward = learn = 0;
6906         }
6907       else
6908         break;
6909     }
6910
6911   if (bd_id == ~0)
6912     {
6913       errmsg ("missing bridge domain");
6914       ret = -99;
6915       goto done;
6916     }
6917
6918   if (mac_age > 255)
6919     {
6920       errmsg ("mac age must be less than 256 ");
6921       ret = -99;
6922       goto done;
6923     }
6924
6925   if ((bd_tag) && (vec_len (bd_tag) > 63))
6926     {
6927       errmsg ("bd-tag cannot be longer than 63");
6928       ret = -99;
6929       goto done;
6930     }
6931
6932   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6933
6934   mp->bd_id = ntohl (bd_id);
6935   mp->flood = flood;
6936   mp->uu_flood = uu_flood;
6937   mp->forward = forward;
6938   mp->learn = learn;
6939   mp->arp_term = arp_term;
6940   mp->is_add = is_add;
6941   mp->mac_age = (u8) mac_age;
6942   if (bd_tag)
6943     {
6944       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6945       mp->bd_tag[vec_len (bd_tag)] = 0;
6946     }
6947   S (mp);
6948   W (ret);
6949
6950 done:
6951   vec_free (bd_tag);
6952   return ret;
6953 }
6954
6955 static int
6956 api_l2fib_flush_bd (vat_main_t * vam)
6957 {
6958   unformat_input_t *i = vam->input;
6959   vl_api_l2fib_flush_bd_t *mp;
6960   u32 bd_id = ~0;
6961   int ret;
6962
6963   /* Parse args required to build the message */
6964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6965     {
6966       if (unformat (i, "bd_id %d", &bd_id));
6967       else
6968         break;
6969     }
6970
6971   if (bd_id == ~0)
6972     {
6973       errmsg ("missing bridge domain");
6974       return -99;
6975     }
6976
6977   M (L2FIB_FLUSH_BD, mp);
6978
6979   mp->bd_id = htonl (bd_id);
6980
6981   S (mp);
6982   W (ret);
6983   return ret;
6984 }
6985
6986 static int
6987 api_l2fib_flush_int (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_l2fib_flush_int_t *mp;
6991   u32 sw_if_index = ~0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index));
6998       else
6999         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7000       else
7001         break;
7002     }
7003
7004   if (sw_if_index == ~0)
7005     {
7006       errmsg ("missing interface name or sw_if_index");
7007       return -99;
7008     }
7009
7010   M (L2FIB_FLUSH_INT, mp);
7011
7012   mp->sw_if_index = ntohl (sw_if_index);
7013
7014   S (mp);
7015   W (ret);
7016   return ret;
7017 }
7018
7019 static int
7020 api_l2fib_add_del (vat_main_t * vam)
7021 {
7022   unformat_input_t *i = vam->input;
7023   vl_api_l2fib_add_del_t *mp;
7024   f64 timeout;
7025   u8 mac[6] = { 0 };
7026   u8 mac_set = 0;
7027   u32 bd_id;
7028   u8 bd_id_set = 0;
7029   u32 sw_if_index = 0;
7030   u8 sw_if_index_set = 0;
7031   u8 is_add = 1;
7032   u8 static_mac = 0;
7033   u8 filter_mac = 0;
7034   u8 bvi_mac = 0;
7035   int count = 1;
7036   f64 before = 0;
7037   int j;
7038
7039   /* Parse args required to build the message */
7040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041     {
7042       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7043         mac_set = 1;
7044       else if (unformat (i, "bd_id %d", &bd_id))
7045         bd_id_set = 1;
7046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7047         sw_if_index_set = 1;
7048       else if (unformat (i, "sw_if"))
7049         {
7050           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051             {
7052               if (unformat
7053                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7054                 sw_if_index_set = 1;
7055             }
7056           else
7057             break;
7058         }
7059       else if (unformat (i, "static"))
7060         static_mac = 1;
7061       else if (unformat (i, "filter"))
7062         {
7063           filter_mac = 1;
7064           static_mac = 1;
7065         }
7066       else if (unformat (i, "bvi"))
7067         {
7068           bvi_mac = 1;
7069           static_mac = 1;
7070         }
7071       else if (unformat (i, "del"))
7072         is_add = 0;
7073       else if (unformat (i, "count %d", &count))
7074         ;
7075       else
7076         break;
7077     }
7078
7079   if (mac_set == 0)
7080     {
7081       errmsg ("missing mac address");
7082       return -99;
7083     }
7084
7085   if (bd_id_set == 0)
7086     {
7087       errmsg ("missing bridge domain");
7088       return -99;
7089     }
7090
7091   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7092     {
7093       errmsg ("missing interface name or sw_if_index");
7094       return -99;
7095     }
7096
7097   if (count > 1)
7098     {
7099       /* Turn on async mode */
7100       vam->async_mode = 1;
7101       vam->async_errors = 0;
7102       before = vat_time_now (vam);
7103     }
7104
7105   for (j = 0; j < count; j++)
7106     {
7107       M (L2FIB_ADD_DEL, mp);
7108
7109       clib_memcpy (mp->mac, mac, 6);
7110       mp->bd_id = ntohl (bd_id);
7111       mp->is_add = is_add;
7112       mp->sw_if_index = ntohl (sw_if_index);
7113
7114       if (is_add)
7115         {
7116           mp->static_mac = static_mac;
7117           mp->filter_mac = filter_mac;
7118           mp->bvi_mac = bvi_mac;
7119         }
7120       increment_mac_address (mac);
7121       /* send it... */
7122       S (mp);
7123     }
7124
7125   if (count > 1)
7126     {
7127       vl_api_control_ping_t *mp_ping;
7128       f64 after;
7129
7130       /* Shut off async mode */
7131       vam->async_mode = 0;
7132
7133       MPING (CONTROL_PING, mp_ping);
7134       S (mp_ping);
7135
7136       timeout = vat_time_now (vam) + 1.0;
7137       while (vat_time_now (vam) < timeout)
7138         if (vam->result_ready == 1)
7139           goto out;
7140       vam->retval = -99;
7141
7142     out:
7143       if (vam->retval == -99)
7144         errmsg ("timeout");
7145
7146       if (vam->async_errors > 0)
7147         {
7148           errmsg ("%d asynchronous errors", vam->async_errors);
7149           vam->retval = -98;
7150         }
7151       vam->async_errors = 0;
7152       after = vat_time_now (vam);
7153
7154       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7155              count, after - before, count / (after - before));
7156     }
7157   else
7158     {
7159       int ret;
7160
7161       /* Wait for a reply... */
7162       W (ret);
7163       return ret;
7164     }
7165   /* Return the good/bad news */
7166   return (vam->retval);
7167 }
7168
7169 static int
7170 api_bridge_domain_set_mac_age (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_bridge_domain_set_mac_age_t *mp;
7174   u32 bd_id = ~0;
7175   u32 mac_age = 0;
7176   int ret;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "bd_id %d", &bd_id));
7182       else if (unformat (i, "mac-age %d", &mac_age));
7183       else
7184         break;
7185     }
7186
7187   if (bd_id == ~0)
7188     {
7189       errmsg ("missing bridge domain");
7190       return -99;
7191     }
7192
7193   if (mac_age > 255)
7194     {
7195       errmsg ("mac age must be less than 256 ");
7196       return -99;
7197     }
7198
7199   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7200
7201   mp->bd_id = htonl (bd_id);
7202   mp->mac_age = (u8) mac_age;
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_l2_flags (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_l2_flags_t *mp;
7214   u32 sw_if_index;
7215   u32 flags = 0;
7216   u8 sw_if_index_set = 0;
7217   u8 is_set = 0;
7218   int ret;
7219
7220   /* Parse args required to build the message */
7221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222     {
7223       if (unformat (i, "sw_if_index %d", &sw_if_index))
7224         sw_if_index_set = 1;
7225       else if (unformat (i, "sw_if"))
7226         {
7227           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228             {
7229               if (unformat
7230                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7231                 sw_if_index_set = 1;
7232             }
7233           else
7234             break;
7235         }
7236       else if (unformat (i, "learn"))
7237         flags |= L2_LEARN;
7238       else if (unformat (i, "forward"))
7239         flags |= L2_FWD;
7240       else if (unformat (i, "flood"))
7241         flags |= L2_FLOOD;
7242       else if (unformat (i, "uu-flood"))
7243         flags |= L2_UU_FLOOD;
7244       else if (unformat (i, "arp-term"))
7245         flags |= L2_ARP_TERM;
7246       else if (unformat (i, "off"))
7247         is_set = 0;
7248       else if (unformat (i, "disable"))
7249         is_set = 0;
7250       else
7251         break;
7252     }
7253
7254   if (sw_if_index_set == 0)
7255     {
7256       errmsg ("missing interface name or sw_if_index");
7257       return -99;
7258     }
7259
7260   M (L2_FLAGS, mp);
7261
7262   mp->sw_if_index = ntohl (sw_if_index);
7263   mp->feature_bitmap = ntohl (flags);
7264   mp->is_set = is_set;
7265
7266   S (mp);
7267   W (ret);
7268   return ret;
7269 }
7270
7271 static int
7272 api_bridge_flags (vat_main_t * vam)
7273 {
7274   unformat_input_t *i = vam->input;
7275   vl_api_bridge_flags_t *mp;
7276   u32 bd_id;
7277   u8 bd_id_set = 0;
7278   u8 is_set = 1;
7279   bd_flags_t flags = 0;
7280   int ret;
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         bd_id_set = 1;
7287       else if (unformat (i, "learn"))
7288         flags |= BRIDGE_API_FLAG_LEARN;
7289       else if (unformat (i, "forward"))
7290         flags |= BRIDGE_API_FLAG_FWD;
7291       else if (unformat (i, "flood"))
7292         flags |= BRIDGE_API_FLAG_FLOOD;
7293       else if (unformat (i, "uu-flood"))
7294         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7295       else if (unformat (i, "arp-term"))
7296         flags |= BRIDGE_API_FLAG_ARP_TERM;
7297       else if (unformat (i, "off"))
7298         is_set = 0;
7299       else if (unformat (i, "disable"))
7300         is_set = 0;
7301       else
7302         break;
7303     }
7304
7305   if (bd_id_set == 0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310
7311   M (BRIDGE_FLAGS, mp);
7312
7313   mp->bd_id = ntohl (bd_id);
7314   mp->flags = ntohl (flags);
7315   mp->is_set = is_set;
7316
7317   S (mp);
7318   W (ret);
7319   return ret;
7320 }
7321
7322 static int
7323 api_bd_ip_mac_add_del (vat_main_t * vam)
7324 {
7325   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7326   vl_api_mac_address_t mac = { 0 };
7327   unformat_input_t *i = vam->input;
7328   vl_api_bd_ip_mac_add_del_t *mp;
7329   ip46_type_t type;
7330   u32 bd_id;
7331   u8 is_ipv6 = 0;
7332   u8 is_add = 1;
7333   u8 bd_id_set = 0;
7334   u8 ip_set = 0;
7335   u8 mac_set = 0;
7336   u8 macaddr[6];
7337   int ret;
7338
7339
7340   /* Parse args required to build the message */
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7348         {
7349           ip_set++;
7350         }
7351       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7352         {
7353           mac_set++;
7354         }
7355       else if (unformat (i, "del"))
7356         is_add = 0;
7357       else
7358         break;
7359     }
7360
7361   if (bd_id_set == 0)
7362     {
7363       errmsg ("missing bridge domain");
7364       return -99;
7365     }
7366   else if (ip_set == 0)
7367     {
7368       errmsg ("missing IP address");
7369       return -99;
7370     }
7371   else if (mac_set == 0)
7372     {
7373       errmsg ("missing MAC address");
7374       return -99;
7375     }
7376
7377   M (BD_IP_MAC_ADD_DEL, mp);
7378
7379   mp->bd_id = ntohl (bd_id);
7380   mp->is_add = is_add;
7381
7382   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7383   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7384
7385   S (mp);
7386   W (ret);
7387   return ret;
7388 }
7389
7390 static int
7391 api_bd_ip_mac_flush (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_bd_ip_mac_flush_t *mp;
7395   u32 bd_id;
7396   u8 bd_id_set = 0;
7397   int ret;
7398
7399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7400     {
7401       if (unformat (i, "bd_id %d", &bd_id))
7402         {
7403           bd_id_set++;
7404         }
7405       else
7406         break;
7407     }
7408
7409   if (bd_id_set == 0)
7410     {
7411       errmsg ("missing bridge domain");
7412       return -99;
7413     }
7414
7415   M (BD_IP_MAC_FLUSH, mp);
7416
7417   mp->bd_id = ntohl (bd_id);
7418
7419   S (mp);
7420   W (ret);
7421   return ret;
7422 }
7423
7424 static void vl_api_bd_ip_mac_details_t_handler
7425   (vl_api_bd_ip_mac_details_t * mp)
7426 {
7427   vat_main_t *vam = &vat_main;
7428   u8 *ip = 0;
7429
7430   if (!mp->is_ipv6)
7431     ip =
7432       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7433   else
7434     ip =
7435       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7436
7437   print (vam->ofp,
7438          "\n%-5d %-7s %-20U %-30s",
7439          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7440          format_ethernet_address, mp->mac_address, ip);
7441
7442   vec_free (ip);
7443 }
7444
7445 static void vl_api_bd_ip_mac_details_t_handler_json
7446   (vl_api_bd_ip_mac_details_t * mp)
7447 {
7448   vat_main_t *vam = &vat_main;
7449   vat_json_node_t *node = NULL;
7450
7451   if (VAT_JSON_ARRAY != vam->json_tree.type)
7452     {
7453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7454       vat_json_init_array (&vam->json_tree);
7455     }
7456   node = vat_json_array_add (&vam->json_tree);
7457
7458   vat_json_init_object (node);
7459   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7460   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7461   vat_json_object_add_string_copy (node, "mac_address",
7462                                    format (0, "%U", format_ethernet_address,
7463                                            &mp->mac_address));
7464   u8 *ip = 0;
7465
7466   if (!mp->is_ipv6)
7467     ip =
7468       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7469   else
7470     ip =
7471       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7472   vat_json_object_add_string_copy (node, "ip_address", ip);
7473   vec_free (ip);
7474 }
7475
7476 static int
7477 api_bd_ip_mac_dump (vat_main_t * vam)
7478 {
7479   unformat_input_t *i = vam->input;
7480   vl_api_bd_ip_mac_dump_t *mp;
7481   vl_api_control_ping_t *mp_ping;
7482   int ret;
7483   u32 bd_id;
7484   u8 bd_id_set = 0;
7485
7486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7487     {
7488       if (unformat (i, "bd_id %d", &bd_id))
7489         {
7490           bd_id_set++;
7491         }
7492       else
7493         break;
7494     }
7495
7496   print (vam->ofp,
7497          "\n%-5s %-7s %-20s %-30s",
7498          "bd_id", "is_ipv6", "mac_address", "ip_address");
7499
7500   /* Dump Bridge Domain Ip to Mac entries */
7501   M (BD_IP_MAC_DUMP, mp);
7502
7503   if (bd_id_set)
7504     mp->bd_id = htonl (bd_id);
7505   else
7506     mp->bd_id = ~0;
7507
7508   S (mp);
7509
7510   /* Use a control ping for synchronization */
7511   MPING (CONTROL_PING, mp_ping);
7512   S (mp_ping);
7513
7514   W (ret);
7515   return ret;
7516 }
7517
7518 static int
7519 api_tap_connect (vat_main_t * vam)
7520 {
7521   unformat_input_t *i = vam->input;
7522   vl_api_tap_connect_t *mp;
7523   u8 mac_address[6];
7524   u8 random_mac = 1;
7525   u8 name_set = 0;
7526   u8 *tap_name;
7527   u8 *tag = 0;
7528   ip4_address_t ip4_address;
7529   u32 ip4_mask_width;
7530   int ip4_address_set = 0;
7531   ip6_address_t ip6_address;
7532   u32 ip6_mask_width;
7533   int ip6_address_set = 0;
7534   int ret;
7535
7536   clib_memset (mac_address, 0, sizeof (mac_address));
7537
7538   /* Parse args required to build the message */
7539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7540     {
7541       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7542         {
7543           random_mac = 0;
7544         }
7545       else if (unformat (i, "random-mac"))
7546         random_mac = 1;
7547       else if (unformat (i, "tapname %s", &tap_name))
7548         name_set = 1;
7549       else if (unformat (i, "tag %s", &tag))
7550         ;
7551       else if (unformat (i, "address %U/%d",
7552                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7553         ip4_address_set = 1;
7554       else if (unformat (i, "address %U/%d",
7555                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7556         ip6_address_set = 1;
7557       else
7558         break;
7559     }
7560
7561   if (name_set == 0)
7562     {
7563       errmsg ("missing tap name");
7564       return -99;
7565     }
7566   if (vec_len (tap_name) > 63)
7567     {
7568       errmsg ("tap name too long");
7569       return -99;
7570     }
7571   vec_add1 (tap_name, 0);
7572
7573   if (vec_len (tag) > 63)
7574     {
7575       errmsg ("tag too long");
7576       return -99;
7577     }
7578
7579   /* Construct the API message */
7580   M (TAP_CONNECT, mp);
7581
7582   mp->use_random_mac = random_mac;
7583   clib_memcpy (mp->mac_address, mac_address, 6);
7584   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7585   if (tag)
7586     clib_memcpy (mp->tag, tag, vec_len (tag));
7587
7588   if (ip4_address_set)
7589     {
7590       mp->ip4_address_set = 1;
7591       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7592       mp->ip4_mask_width = ip4_mask_width;
7593     }
7594   if (ip6_address_set)
7595     {
7596       mp->ip6_address_set = 1;
7597       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7598       mp->ip6_mask_width = ip6_mask_width;
7599     }
7600
7601   vec_free (tap_name);
7602   vec_free (tag);
7603
7604   /* send it... */
7605   S (mp);
7606
7607   /* Wait for a reply... */
7608   W (ret);
7609   return ret;
7610 }
7611
7612 static int
7613 api_tap_modify (vat_main_t * vam)
7614 {
7615   unformat_input_t *i = vam->input;
7616   vl_api_tap_modify_t *mp;
7617   u8 mac_address[6];
7618   u8 random_mac = 1;
7619   u8 name_set = 0;
7620   u8 *tap_name;
7621   u32 sw_if_index = ~0;
7622   u8 sw_if_index_set = 0;
7623   int ret;
7624
7625   clib_memset (mac_address, 0, sizeof (mac_address));
7626
7627   /* Parse args required to build the message */
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7631         sw_if_index_set = 1;
7632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7633         sw_if_index_set = 1;
7634       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7635         {
7636           random_mac = 0;
7637         }
7638       else if (unformat (i, "random-mac"))
7639         random_mac = 1;
7640       else if (unformat (i, "tapname %s", &tap_name))
7641         name_set = 1;
7642       else
7643         break;
7644     }
7645
7646   if (sw_if_index_set == 0)
7647     {
7648       errmsg ("missing vpp interface name");
7649       return -99;
7650     }
7651   if (name_set == 0)
7652     {
7653       errmsg ("missing tap name");
7654       return -99;
7655     }
7656   if (vec_len (tap_name) > 63)
7657     {
7658       errmsg ("tap name too long");
7659     }
7660   vec_add1 (tap_name, 0);
7661
7662   /* Construct the API message */
7663   M (TAP_MODIFY, mp);
7664
7665   mp->use_random_mac = random_mac;
7666   mp->sw_if_index = ntohl (sw_if_index);
7667   clib_memcpy (mp->mac_address, mac_address, 6);
7668   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7669   vec_free (tap_name);
7670
7671   /* send it... */
7672   S (mp);
7673
7674   /* Wait for a reply... */
7675   W (ret);
7676   return ret;
7677 }
7678
7679 static int
7680 api_tap_delete (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_tap_delete_t *mp;
7684   u32 sw_if_index = ~0;
7685   u8 sw_if_index_set = 0;
7686   int ret;
7687
7688   /* Parse args required to build the message */
7689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7690     {
7691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7692         sw_if_index_set = 1;
7693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7694         sw_if_index_set = 1;
7695       else
7696         break;
7697     }
7698
7699   if (sw_if_index_set == 0)
7700     {
7701       errmsg ("missing vpp interface name");
7702       return -99;
7703     }
7704
7705   /* Construct the API message */
7706   M (TAP_DELETE, mp);
7707
7708   mp->sw_if_index = ntohl (sw_if_index);
7709
7710   /* send it... */
7711   S (mp);
7712
7713   /* Wait for a reply... */
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_tap_create_v2 (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_tap_create_v2_t *mp;
7723   u8 mac_address[6];
7724   u8 random_mac = 1;
7725   u32 id = ~0;
7726   u8 *host_if_name = 0;
7727   u8 *host_ns = 0;
7728   u8 host_mac_addr[6];
7729   u8 host_mac_addr_set = 0;
7730   u8 *host_bridge = 0;
7731   ip4_address_t host_ip4_addr;
7732   ip4_address_t host_ip4_gw;
7733   u8 host_ip4_gw_set = 0;
7734   u32 host_ip4_prefix_len = 0;
7735   ip6_address_t host_ip6_addr;
7736   ip6_address_t host_ip6_gw;
7737   u8 host_ip6_gw_set = 0;
7738   u32 host_ip6_prefix_len = 0;
7739   int ret;
7740   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7741
7742   clib_memset (mac_address, 0, sizeof (mac_address));
7743
7744   /* Parse args required to build the message */
7745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7746     {
7747       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7748         {
7749           random_mac = 0;
7750         }
7751       else if (unformat (i, "id %u", &id))
7752         ;
7753       else if (unformat (i, "host-if-name %s", &host_if_name))
7754         ;
7755       else if (unformat (i, "host-ns %s", &host_ns))
7756         ;
7757       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7758                          host_mac_addr))
7759         host_mac_addr_set = 1;
7760       else if (unformat (i, "host-bridge %s", &host_bridge))
7761         ;
7762       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7763                          &host_ip4_addr, &host_ip4_prefix_len))
7764         ;
7765       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7766                          &host_ip6_addr, &host_ip6_prefix_len))
7767         ;
7768       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7769                          &host_ip4_gw))
7770         host_ip4_gw_set = 1;
7771       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7772                          &host_ip6_gw))
7773         host_ip6_gw_set = 1;
7774       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7775         ;
7776       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7777         ;
7778       else
7779         break;
7780     }
7781
7782   if (vec_len (host_if_name) > 63)
7783     {
7784       errmsg ("tap name too long. ");
7785       return -99;
7786     }
7787   if (vec_len (host_ns) > 63)
7788     {
7789       errmsg ("host name space too long. ");
7790       return -99;
7791     }
7792   if (vec_len (host_bridge) > 63)
7793     {
7794       errmsg ("host bridge name too long. ");
7795       return -99;
7796     }
7797   if (host_ip4_prefix_len > 32)
7798     {
7799       errmsg ("host ip4 prefix length not valid. ");
7800       return -99;
7801     }
7802   if (host_ip6_prefix_len > 128)
7803     {
7804       errmsg ("host ip6 prefix length not valid. ");
7805       return -99;
7806     }
7807   if (!is_pow2 (rx_ring_sz))
7808     {
7809       errmsg ("rx ring size must be power of 2. ");
7810       return -99;
7811     }
7812   if (rx_ring_sz > 32768)
7813     {
7814       errmsg ("rx ring size must be 32768 or lower. ");
7815       return -99;
7816     }
7817   if (!is_pow2 (tx_ring_sz))
7818     {
7819       errmsg ("tx ring size must be power of 2. ");
7820       return -99;
7821     }
7822   if (tx_ring_sz > 32768)
7823     {
7824       errmsg ("tx ring size must be 32768 or lower. ");
7825       return -99;
7826     }
7827
7828   /* Construct the API message */
7829   M (TAP_CREATE_V2, mp);
7830
7831   mp->use_random_mac = random_mac;
7832
7833   mp->id = ntohl (id);
7834   mp->host_namespace_set = host_ns != 0;
7835   mp->host_bridge_set = host_bridge != 0;
7836   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7837   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7838   mp->rx_ring_sz = ntohs (rx_ring_sz);
7839   mp->tx_ring_sz = ntohs (tx_ring_sz);
7840
7841   if (random_mac == 0)
7842     clib_memcpy (mp->mac_address, mac_address, 6);
7843   if (host_mac_addr_set)
7844     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7845   if (host_if_name)
7846     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7847   if (host_ns)
7848     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7849   if (host_bridge)
7850     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7851   if (host_ip4_prefix_len)
7852     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7853   if (host_ip6_prefix_len)
7854     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7855   if (host_ip4_gw_set)
7856     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7857   if (host_ip6_gw_set)
7858     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7859
7860   vec_free (host_ns);
7861   vec_free (host_if_name);
7862   vec_free (host_bridge);
7863
7864   /* send it... */
7865   S (mp);
7866
7867   /* Wait for a reply... */
7868   W (ret);
7869   return ret;
7870 }
7871
7872 static int
7873 api_tap_delete_v2 (vat_main_t * vam)
7874 {
7875   unformat_input_t *i = vam->input;
7876   vl_api_tap_delete_v2_t *mp;
7877   u32 sw_if_index = ~0;
7878   u8 sw_if_index_set = 0;
7879   int ret;
7880
7881   /* Parse args required to build the message */
7882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7883     {
7884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7885         sw_if_index_set = 1;
7886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7887         sw_if_index_set = 1;
7888       else
7889         break;
7890     }
7891
7892   if (sw_if_index_set == 0)
7893     {
7894       errmsg ("missing vpp interface name. ");
7895       return -99;
7896     }
7897
7898   /* Construct the API message */
7899   M (TAP_DELETE_V2, mp);
7900
7901   mp->sw_if_index = ntohl (sw_if_index);
7902
7903   /* send it... */
7904   S (mp);
7905
7906   /* Wait for a reply... */
7907   W (ret);
7908   return ret;
7909 }
7910
7911 static int
7912 api_bond_create (vat_main_t * vam)
7913 {
7914   unformat_input_t *i = vam->input;
7915   vl_api_bond_create_t *mp;
7916   u8 mac_address[6];
7917   u8 custom_mac = 0;
7918   int ret;
7919   u8 mode;
7920   u8 lb;
7921   u8 mode_is_set = 0;
7922   u32 id = ~0;
7923
7924   clib_memset (mac_address, 0, sizeof (mac_address));
7925   lb = BOND_LB_L2;
7926
7927   /* Parse args required to build the message */
7928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7931         mode_is_set = 1;
7932       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7933                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7934         ;
7935       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7936                          mac_address))
7937         custom_mac = 1;
7938       else if (unformat (i, "id %u", &id))
7939         ;
7940       else
7941         break;
7942     }
7943
7944   if (mode_is_set == 0)
7945     {
7946       errmsg ("Missing bond mode. ");
7947       return -99;
7948     }
7949
7950   /* Construct the API message */
7951   M (BOND_CREATE, mp);
7952
7953   mp->use_custom_mac = custom_mac;
7954
7955   mp->mode = mode;
7956   mp->lb = lb;
7957   mp->id = htonl (id);
7958
7959   if (custom_mac)
7960     clib_memcpy (mp->mac_address, mac_address, 6);
7961
7962   /* send it... */
7963   S (mp);
7964
7965   /* Wait for a reply... */
7966   W (ret);
7967   return ret;
7968 }
7969
7970 static int
7971 api_bond_delete (vat_main_t * vam)
7972 {
7973   unformat_input_t *i = vam->input;
7974   vl_api_bond_delete_t *mp;
7975   u32 sw_if_index = ~0;
7976   u8 sw_if_index_set = 0;
7977   int ret;
7978
7979   /* Parse args required to build the message */
7980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7981     {
7982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7983         sw_if_index_set = 1;
7984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7985         sw_if_index_set = 1;
7986       else
7987         break;
7988     }
7989
7990   if (sw_if_index_set == 0)
7991     {
7992       errmsg ("missing vpp interface name. ");
7993       return -99;
7994     }
7995
7996   /* Construct the API message */
7997   M (BOND_DELETE, mp);
7998
7999   mp->sw_if_index = ntohl (sw_if_index);
8000
8001   /* send it... */
8002   S (mp);
8003
8004   /* Wait for a reply... */
8005   W (ret);
8006   return ret;
8007 }
8008
8009 static int
8010 api_bond_enslave (vat_main_t * vam)
8011 {
8012   unformat_input_t *i = vam->input;
8013   vl_api_bond_enslave_t *mp;
8014   u32 bond_sw_if_index;
8015   int ret;
8016   u8 is_passive;
8017   u8 is_long_timeout;
8018   u32 bond_sw_if_index_is_set = 0;
8019   u32 sw_if_index;
8020   u8 sw_if_index_is_set = 0;
8021
8022   /* Parse args required to build the message */
8023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8024     {
8025       if (unformat (i, "sw_if_index %d", &sw_if_index))
8026         sw_if_index_is_set = 1;
8027       else if (unformat (i, "bond %u", &bond_sw_if_index))
8028         bond_sw_if_index_is_set = 1;
8029       else if (unformat (i, "passive %d", &is_passive))
8030         ;
8031       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8032         ;
8033       else
8034         break;
8035     }
8036
8037   if (bond_sw_if_index_is_set == 0)
8038     {
8039       errmsg ("Missing bond sw_if_index. ");
8040       return -99;
8041     }
8042   if (sw_if_index_is_set == 0)
8043     {
8044       errmsg ("Missing slave sw_if_index. ");
8045       return -99;
8046     }
8047
8048   /* Construct the API message */
8049   M (BOND_ENSLAVE, mp);
8050
8051   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8052   mp->sw_if_index = ntohl (sw_if_index);
8053   mp->is_long_timeout = is_long_timeout;
8054   mp->is_passive = is_passive;
8055
8056   /* send it... */
8057   S (mp);
8058
8059   /* Wait for a reply... */
8060   W (ret);
8061   return ret;
8062 }
8063
8064 static int
8065 api_bond_detach_slave (vat_main_t * vam)
8066 {
8067   unformat_input_t *i = vam->input;
8068   vl_api_bond_detach_slave_t *mp;
8069   u32 sw_if_index = ~0;
8070   u8 sw_if_index_set = 0;
8071   int ret;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8077         sw_if_index_set = 1;
8078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8079         sw_if_index_set = 1;
8080       else
8081         break;
8082     }
8083
8084   if (sw_if_index_set == 0)
8085     {
8086       errmsg ("missing vpp interface name. ");
8087       return -99;
8088     }
8089
8090   /* Construct the API message */
8091   M (BOND_DETACH_SLAVE, mp);
8092
8093   mp->sw_if_index = ntohl (sw_if_index);
8094
8095   /* send it... */
8096   S (mp);
8097
8098   /* Wait for a reply... */
8099   W (ret);
8100   return ret;
8101 }
8102
8103 static int
8104 api_ip_table_add_del (vat_main_t * vam)
8105 {
8106   unformat_input_t *i = vam->input;
8107   vl_api_ip_table_add_del_t *mp;
8108   u32 table_id = ~0;
8109   u8 is_ipv6 = 0;
8110   u8 is_add = 1;
8111   int ret = 0;
8112
8113   /* Parse args required to build the message */
8114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8115     {
8116       if (unformat (i, "ipv6"))
8117         is_ipv6 = 1;
8118       else if (unformat (i, "del"))
8119         is_add = 0;
8120       else if (unformat (i, "add"))
8121         is_add = 1;
8122       else if (unformat (i, "table %d", &table_id))
8123         ;
8124       else
8125         {
8126           clib_warning ("parse error '%U'", format_unformat_error, i);
8127           return -99;
8128         }
8129     }
8130
8131   if (~0 == table_id)
8132     {
8133       errmsg ("missing table-ID");
8134       return -99;
8135     }
8136
8137   /* Construct the API message */
8138   M (IP_TABLE_ADD_DEL, mp);
8139
8140   mp->table_id = ntohl (table_id);
8141   mp->is_ipv6 = is_ipv6;
8142   mp->is_add = is_add;
8143
8144   /* send it... */
8145   S (mp);
8146
8147   /* Wait for a reply... */
8148   W (ret);
8149
8150   return ret;
8151 }
8152
8153 static int
8154 api_ip_add_del_route (vat_main_t * vam)
8155 {
8156   unformat_input_t *i = vam->input;
8157   vl_api_ip_add_del_route_t *mp;
8158   u32 sw_if_index = ~0, vrf_id = 0;
8159   u8 is_ipv6 = 0;
8160   u8 is_local = 0, is_drop = 0;
8161   u8 is_unreach = 0, is_prohibit = 0;
8162   u8 is_add = 1;
8163   u32 next_hop_weight = 1;
8164   u8 is_multipath = 0;
8165   u8 address_set = 0;
8166   u8 address_length_set = 0;
8167   u32 next_hop_table_id = 0;
8168   u32 resolve_attempts = 0;
8169   u32 dst_address_length = 0;
8170   u8 next_hop_set = 0;
8171   ip4_address_t v4_dst_address, v4_next_hop_address;
8172   ip6_address_t v6_dst_address, v6_next_hop_address;
8173   int count = 1;
8174   int j;
8175   f64 before = 0;
8176   u32 random_add_del = 0;
8177   u32 *random_vector = 0;
8178   uword *random_hash;
8179   u32 random_seed = 0xdeaddabe;
8180   u32 classify_table_index = ~0;
8181   u8 is_classify = 0;
8182   u8 resolve_host = 0, resolve_attached = 0;
8183   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8184   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8185   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8186
8187   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8188   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8189   /* Parse args required to build the message */
8190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8191     {
8192       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8193         ;
8194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8195         ;
8196       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8197         {
8198           address_set = 1;
8199           is_ipv6 = 0;
8200         }
8201       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8202         {
8203           address_set = 1;
8204           is_ipv6 = 1;
8205         }
8206       else if (unformat (i, "/%d", &dst_address_length))
8207         {
8208           address_length_set = 1;
8209         }
8210
8211       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8212                                          &v4_next_hop_address))
8213         {
8214           next_hop_set = 1;
8215         }
8216       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8217                                          &v6_next_hop_address))
8218         {
8219           next_hop_set = 1;
8220         }
8221       else
8222         if (unformat
8223             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8224         {
8225           next_hop_set = 1;
8226         }
8227       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8228         {
8229           next_hop_set = 1;
8230         }
8231       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8232         ;
8233       else if (unformat (i, "weight %d", &next_hop_weight))
8234         ;
8235       else if (unformat (i, "drop"))
8236         {
8237           is_drop = 1;
8238         }
8239       else if (unformat (i, "null-send-unreach"))
8240         {
8241           is_unreach = 1;
8242         }
8243       else if (unformat (i, "null-send-prohibit"))
8244         {
8245           is_prohibit = 1;
8246         }
8247       else if (unformat (i, "local"))
8248         {
8249           is_local = 1;
8250         }
8251       else if (unformat (i, "classify %d", &classify_table_index))
8252         {
8253           is_classify = 1;
8254         }
8255       else if (unformat (i, "del"))
8256         is_add = 0;
8257       else if (unformat (i, "add"))
8258         is_add = 1;
8259       else if (unformat (i, "resolve-via-host"))
8260         resolve_host = 1;
8261       else if (unformat (i, "resolve-via-attached"))
8262         resolve_attached = 1;
8263       else if (unformat (i, "multipath"))
8264         is_multipath = 1;
8265       else if (unformat (i, "vrf %d", &vrf_id))
8266         ;
8267       else if (unformat (i, "count %d", &count))
8268         ;
8269       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8270         ;
8271       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8272         ;
8273       else if (unformat (i, "out-label %d", &next_hop_out_label))
8274         {
8275           vl_api_fib_mpls_label_t fib_label = {
8276             .label = ntohl (next_hop_out_label),
8277             .ttl = 64,
8278             .exp = 0,
8279           };
8280           vec_add1 (next_hop_out_label_stack, fib_label);
8281         }
8282       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8283         ;
8284       else if (unformat (i, "random"))
8285         random_add_del = 1;
8286       else if (unformat (i, "seed %d", &random_seed))
8287         ;
8288       else
8289         {
8290           clib_warning ("parse error '%U'", format_unformat_error, i);
8291           return -99;
8292         }
8293     }
8294
8295   if (!next_hop_set && !is_drop && !is_local &&
8296       !is_classify && !is_unreach && !is_prohibit &&
8297       MPLS_LABEL_INVALID == next_hop_via_label)
8298     {
8299       errmsg
8300         ("next hop / local / drop / unreach / prohibit / classify not set");
8301       return -99;
8302     }
8303
8304   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8305     {
8306       errmsg ("next hop and next-hop via label set");
8307       return -99;
8308     }
8309   if (address_set == 0)
8310     {
8311       errmsg ("missing addresses");
8312       return -99;
8313     }
8314
8315   if (address_length_set == 0)
8316     {
8317       errmsg ("missing address length");
8318       return -99;
8319     }
8320
8321   /* Generate a pile of unique, random routes */
8322   if (random_add_del)
8323     {
8324       u32 this_random_address;
8325       random_hash = hash_create (count, sizeof (uword));
8326
8327       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8328       for (j = 0; j <= count; j++)
8329         {
8330           do
8331             {
8332               this_random_address = random_u32 (&random_seed);
8333               this_random_address =
8334                 clib_host_to_net_u32 (this_random_address);
8335             }
8336           while (hash_get (random_hash, this_random_address));
8337           vec_add1 (random_vector, this_random_address);
8338           hash_set (random_hash, this_random_address, 1);
8339         }
8340       hash_free (random_hash);
8341       v4_dst_address.as_u32 = random_vector[0];
8342     }
8343
8344   if (count > 1)
8345     {
8346       /* Turn on async mode */
8347       vam->async_mode = 1;
8348       vam->async_errors = 0;
8349       before = vat_time_now (vam);
8350     }
8351
8352   for (j = 0; j < count; j++)
8353     {
8354       /* Construct the API message */
8355       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8356           vec_len (next_hop_out_label_stack));
8357
8358       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8359       mp->table_id = ntohl (vrf_id);
8360
8361       mp->is_add = is_add;
8362       mp->is_drop = is_drop;
8363       mp->is_unreach = is_unreach;
8364       mp->is_prohibit = is_prohibit;
8365       mp->is_ipv6 = is_ipv6;
8366       mp->is_local = is_local;
8367       mp->is_classify = is_classify;
8368       mp->is_multipath = is_multipath;
8369       mp->is_resolve_host = resolve_host;
8370       mp->is_resolve_attached = resolve_attached;
8371       mp->next_hop_weight = next_hop_weight;
8372       mp->next_hop_preference = 0;
8373       mp->dst_address_length = dst_address_length;
8374       mp->next_hop_table_id = ntohl (next_hop_table_id);
8375       mp->classify_table_index = ntohl (classify_table_index);
8376       mp->next_hop_via_label = ntohl (next_hop_via_label);
8377       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8378       if (0 != mp->next_hop_n_out_labels)
8379         {
8380           memcpy (mp->next_hop_out_label_stack,
8381                   next_hop_out_label_stack,
8382                   (vec_len (next_hop_out_label_stack) *
8383                    sizeof (vl_api_fib_mpls_label_t)));
8384           vec_free (next_hop_out_label_stack);
8385         }
8386
8387       if (is_ipv6)
8388         {
8389           clib_memcpy (mp->dst_address, &v6_dst_address,
8390                        sizeof (v6_dst_address));
8391           if (next_hop_set)
8392             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8393                          sizeof (v6_next_hop_address));
8394           increment_v6_address (&v6_dst_address);
8395         }
8396       else
8397         {
8398           clib_memcpy (mp->dst_address, &v4_dst_address,
8399                        sizeof (v4_dst_address));
8400           if (next_hop_set)
8401             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8402                          sizeof (v4_next_hop_address));
8403           if (random_add_del)
8404             v4_dst_address.as_u32 = random_vector[j + 1];
8405           else
8406             increment_v4_address (&v4_dst_address);
8407         }
8408       /* send it... */
8409       S (mp);
8410       /* If we receive SIGTERM, stop now... */
8411       if (vam->do_exit)
8412         break;
8413     }
8414
8415   /* When testing multiple add/del ops, use a control-ping to sync */
8416   if (count > 1)
8417     {
8418       vl_api_control_ping_t *mp_ping;
8419       f64 after;
8420       f64 timeout;
8421
8422       /* Shut off async mode */
8423       vam->async_mode = 0;
8424
8425       MPING (CONTROL_PING, mp_ping);
8426       S (mp_ping);
8427
8428       timeout = vat_time_now (vam) + 1.0;
8429       while (vat_time_now (vam) < timeout)
8430         if (vam->result_ready == 1)
8431           goto out;
8432       vam->retval = -99;
8433
8434     out:
8435       if (vam->retval == -99)
8436         errmsg ("timeout");
8437
8438       if (vam->async_errors > 0)
8439         {
8440           errmsg ("%d asynchronous errors", vam->async_errors);
8441           vam->retval = -98;
8442         }
8443       vam->async_errors = 0;
8444       after = vat_time_now (vam);
8445
8446       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8447       if (j > 0)
8448         count = j;
8449
8450       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8451              count, after - before, count / (after - before));
8452     }
8453   else
8454     {
8455       int ret;
8456
8457       /* Wait for a reply... */
8458       W (ret);
8459       return ret;
8460     }
8461
8462   /* Return the good/bad news */
8463   return (vam->retval);
8464 }
8465
8466 static int
8467 api_ip_mroute_add_del (vat_main_t * vam)
8468 {
8469   unformat_input_t *i = vam->input;
8470   vl_api_ip_mroute_add_del_t *mp;
8471   u32 sw_if_index = ~0, vrf_id = 0;
8472   u8 is_ipv6 = 0;
8473   u8 is_local = 0;
8474   u8 is_add = 1;
8475   u8 address_set = 0;
8476   u32 grp_address_length = 0;
8477   ip4_address_t v4_grp_address, v4_src_address;
8478   ip6_address_t v6_grp_address, v6_src_address;
8479   mfib_itf_flags_t iflags = 0;
8480   mfib_entry_flags_t eflags = 0;
8481   int ret;
8482
8483   /* Parse args required to build the message */
8484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8485     {
8486       if (unformat (i, "sw_if_index %d", &sw_if_index))
8487         ;
8488       else if (unformat (i, "%U %U",
8489                          unformat_ip4_address, &v4_src_address,
8490                          unformat_ip4_address, &v4_grp_address))
8491         {
8492           grp_address_length = 64;
8493           address_set = 1;
8494           is_ipv6 = 0;
8495         }
8496       else if (unformat (i, "%U %U",
8497                          unformat_ip6_address, &v6_src_address,
8498                          unformat_ip6_address, &v6_grp_address))
8499         {
8500           grp_address_length = 256;
8501           address_set = 1;
8502           is_ipv6 = 1;
8503         }
8504       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8505         {
8506           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8507           grp_address_length = 32;
8508           address_set = 1;
8509           is_ipv6 = 0;
8510         }
8511       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8512         {
8513           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8514           grp_address_length = 128;
8515           address_set = 1;
8516           is_ipv6 = 1;
8517         }
8518       else if (unformat (i, "/%d", &grp_address_length))
8519         ;
8520       else if (unformat (i, "local"))
8521         {
8522           is_local = 1;
8523         }
8524       else if (unformat (i, "del"))
8525         is_add = 0;
8526       else if (unformat (i, "add"))
8527         is_add = 1;
8528       else if (unformat (i, "vrf %d", &vrf_id))
8529         ;
8530       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8531         ;
8532       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8533         ;
8534       else
8535         {
8536           clib_warning ("parse error '%U'", format_unformat_error, i);
8537           return -99;
8538         }
8539     }
8540
8541   if (address_set == 0)
8542     {
8543       errmsg ("missing addresses\n");
8544       return -99;
8545     }
8546
8547   /* Construct the API message */
8548   M (IP_MROUTE_ADD_DEL, mp);
8549
8550   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8551   mp->table_id = ntohl (vrf_id);
8552
8553   mp->is_add = is_add;
8554   mp->is_ipv6 = is_ipv6;
8555   mp->is_local = is_local;
8556   mp->itf_flags = ntohl (iflags);
8557   mp->entry_flags = ntohl (eflags);
8558   mp->grp_address_length = grp_address_length;
8559   mp->grp_address_length = ntohs (mp->grp_address_length);
8560
8561   if (is_ipv6)
8562     {
8563       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8564       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8565     }
8566   else
8567     {
8568       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8569       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8570
8571     }
8572
8573   /* send it... */
8574   S (mp);
8575   /* Wait for a reply... */
8576   W (ret);
8577   return ret;
8578 }
8579
8580 static int
8581 api_mpls_table_add_del (vat_main_t * vam)
8582 {
8583   unformat_input_t *i = vam->input;
8584   vl_api_mpls_table_add_del_t *mp;
8585   u32 table_id = ~0;
8586   u8 is_add = 1;
8587   int ret = 0;
8588
8589   /* Parse args required to build the message */
8590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8591     {
8592       if (unformat (i, "table %d", &table_id))
8593         ;
8594       else if (unformat (i, "del"))
8595         is_add = 0;
8596       else if (unformat (i, "add"))
8597         is_add = 1;
8598       else
8599         {
8600           clib_warning ("parse error '%U'", format_unformat_error, i);
8601           return -99;
8602         }
8603     }
8604
8605   if (~0 == table_id)
8606     {
8607       errmsg ("missing table-ID");
8608       return -99;
8609     }
8610
8611   /* Construct the API message */
8612   M (MPLS_TABLE_ADD_DEL, mp);
8613
8614   mp->mt_table_id = ntohl (table_id);
8615   mp->mt_is_add = is_add;
8616
8617   /* send it... */
8618   S (mp);
8619
8620   /* Wait for a reply... */
8621   W (ret);
8622
8623   return ret;
8624 }
8625
8626 static int
8627 api_mpls_route_add_del (vat_main_t * vam)
8628 {
8629   unformat_input_t *i = vam->input;
8630   vl_api_mpls_route_add_del_t *mp;
8631   u32 sw_if_index = ~0, table_id = 0;
8632   u8 is_add = 1;
8633   u32 next_hop_weight = 1;
8634   u8 is_multipath = 0;
8635   u32 next_hop_table_id = 0;
8636   u8 next_hop_set = 0;
8637   ip4_address_t v4_next_hop_address = {
8638     .as_u32 = 0,
8639   };
8640   ip6_address_t v6_next_hop_address = { {0} };
8641   int count = 1;
8642   int j;
8643   f64 before = 0;
8644   u32 classify_table_index = ~0;
8645   u8 is_classify = 0;
8646   u8 resolve_host = 0, resolve_attached = 0;
8647   u8 is_interface_rx = 0;
8648   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8649   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8650   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8651   mpls_label_t local_label = MPLS_LABEL_INVALID;
8652   u8 is_eos = 0;
8653   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8654
8655   /* Parse args required to build the message */
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8659         ;
8660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8661         ;
8662       else if (unformat (i, "%d", &local_label))
8663         ;
8664       else if (unformat (i, "eos"))
8665         is_eos = 1;
8666       else if (unformat (i, "non-eos"))
8667         is_eos = 0;
8668       else if (unformat (i, "via %U", unformat_ip4_address,
8669                          &v4_next_hop_address))
8670         {
8671           next_hop_set = 1;
8672           next_hop_proto = DPO_PROTO_IP4;
8673         }
8674       else if (unformat (i, "via %U", unformat_ip6_address,
8675                          &v6_next_hop_address))
8676         {
8677           next_hop_set = 1;
8678           next_hop_proto = DPO_PROTO_IP6;
8679         }
8680       else if (unformat (i, "weight %d", &next_hop_weight))
8681         ;
8682       else if (unformat (i, "classify %d", &classify_table_index))
8683         {
8684           is_classify = 1;
8685         }
8686       else if (unformat (i, "del"))
8687         is_add = 0;
8688       else if (unformat (i, "add"))
8689         is_add = 1;
8690       else if (unformat (i, "resolve-via-host"))
8691         resolve_host = 1;
8692       else if (unformat (i, "resolve-via-attached"))
8693         resolve_attached = 1;
8694       else if (unformat (i, "multipath"))
8695         is_multipath = 1;
8696       else if (unformat (i, "count %d", &count))
8697         ;
8698       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8699         {
8700           next_hop_set = 1;
8701           next_hop_proto = DPO_PROTO_IP4;
8702         }
8703       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8704         {
8705           next_hop_set = 1;
8706           next_hop_proto = DPO_PROTO_IP6;
8707         }
8708       else
8709         if (unformat
8710             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8711              &sw_if_index))
8712         {
8713           next_hop_set = 1;
8714           next_hop_proto = DPO_PROTO_ETHERNET;
8715           is_interface_rx = 1;
8716         }
8717       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8718         {
8719           next_hop_set = 1;
8720           next_hop_proto = DPO_PROTO_ETHERNET;
8721           is_interface_rx = 1;
8722         }
8723       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8724         next_hop_set = 1;
8725       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8726         next_hop_set = 1;
8727       else if (unformat (i, "out-label %d", &next_hop_out_label))
8728         {
8729           vl_api_fib_mpls_label_t fib_label = {
8730             .label = ntohl (next_hop_out_label),
8731             .ttl = 64,
8732             .exp = 0,
8733           };
8734           vec_add1 (next_hop_out_label_stack, fib_label);
8735         }
8736       else
8737         {
8738           clib_warning ("parse error '%U'", format_unformat_error, i);
8739           return -99;
8740         }
8741     }
8742
8743   if (!next_hop_set && !is_classify)
8744     {
8745       errmsg ("next hop / classify not set");
8746       return -99;
8747     }
8748
8749   if (MPLS_LABEL_INVALID == local_label)
8750     {
8751       errmsg ("missing label");
8752       return -99;
8753     }
8754
8755   if (count > 1)
8756     {
8757       /* Turn on async mode */
8758       vam->async_mode = 1;
8759       vam->async_errors = 0;
8760       before = vat_time_now (vam);
8761     }
8762
8763   for (j = 0; j < count; j++)
8764     {
8765       /* Construct the API message */
8766       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8767           vec_len (next_hop_out_label_stack));
8768
8769       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8770       mp->mr_table_id = ntohl (table_id);
8771
8772       mp->mr_is_add = is_add;
8773       mp->mr_next_hop_proto = next_hop_proto;
8774       mp->mr_is_classify = is_classify;
8775       mp->mr_is_multipath = is_multipath;
8776       mp->mr_is_resolve_host = resolve_host;
8777       mp->mr_is_resolve_attached = resolve_attached;
8778       mp->mr_is_interface_rx = is_interface_rx;
8779       mp->mr_next_hop_weight = next_hop_weight;
8780       mp->mr_next_hop_preference = 0;
8781       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8782       mp->mr_classify_table_index = ntohl (classify_table_index);
8783       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8784       mp->mr_label = ntohl (local_label);
8785       mp->mr_eos = is_eos;
8786
8787       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8788       if (0 != mp->mr_next_hop_n_out_labels)
8789         {
8790           memcpy (mp->mr_next_hop_out_label_stack,
8791                   next_hop_out_label_stack,
8792                   vec_len (next_hop_out_label_stack) *
8793                   sizeof (vl_api_fib_mpls_label_t));
8794           vec_free (next_hop_out_label_stack);
8795         }
8796
8797       if (next_hop_set)
8798         {
8799           if (DPO_PROTO_IP4 == next_hop_proto)
8800             {
8801               clib_memcpy (mp->mr_next_hop,
8802                            &v4_next_hop_address,
8803                            sizeof (v4_next_hop_address));
8804             }
8805           else if (DPO_PROTO_IP6 == next_hop_proto)
8806
8807             {
8808               clib_memcpy (mp->mr_next_hop,
8809                            &v6_next_hop_address,
8810                            sizeof (v6_next_hop_address));
8811             }
8812         }
8813       local_label++;
8814
8815       /* send it... */
8816       S (mp);
8817       /* If we receive SIGTERM, stop now... */
8818       if (vam->do_exit)
8819         break;
8820     }
8821
8822   /* When testing multiple add/del ops, use a control-ping to sync */
8823   if (count > 1)
8824     {
8825       vl_api_control_ping_t *mp_ping;
8826       f64 after;
8827       f64 timeout;
8828
8829       /* Shut off async mode */
8830       vam->async_mode = 0;
8831
8832       MPING (CONTROL_PING, mp_ping);
8833       S (mp_ping);
8834
8835       timeout = vat_time_now (vam) + 1.0;
8836       while (vat_time_now (vam) < timeout)
8837         if (vam->result_ready == 1)
8838           goto out;
8839       vam->retval = -99;
8840
8841     out:
8842       if (vam->retval == -99)
8843         errmsg ("timeout");
8844
8845       if (vam->async_errors > 0)
8846         {
8847           errmsg ("%d asynchronous errors", vam->async_errors);
8848           vam->retval = -98;
8849         }
8850       vam->async_errors = 0;
8851       after = vat_time_now (vam);
8852
8853       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8854       if (j > 0)
8855         count = j;
8856
8857       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8858              count, after - before, count / (after - before));
8859     }
8860   else
8861     {
8862       int ret;
8863
8864       /* Wait for a reply... */
8865       W (ret);
8866       return ret;
8867     }
8868
8869   /* Return the good/bad news */
8870   return (vam->retval);
8871 }
8872
8873 static int
8874 api_mpls_ip_bind_unbind (vat_main_t * vam)
8875 {
8876   unformat_input_t *i = vam->input;
8877   vl_api_mpls_ip_bind_unbind_t *mp;
8878   u32 ip_table_id = 0;
8879   u8 is_bind = 1;
8880   u8 is_ip4 = 1;
8881   ip4_address_t v4_address;
8882   ip6_address_t v6_address;
8883   u32 address_length;
8884   u8 address_set = 0;
8885   mpls_label_t local_label = MPLS_LABEL_INVALID;
8886   int ret;
8887
8888   /* Parse args required to build the message */
8889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8890     {
8891       if (unformat (i, "%U/%d", unformat_ip4_address,
8892                     &v4_address, &address_length))
8893         {
8894           is_ip4 = 1;
8895           address_set = 1;
8896         }
8897       else if (unformat (i, "%U/%d", unformat_ip6_address,
8898                          &v6_address, &address_length))
8899         {
8900           is_ip4 = 0;
8901           address_set = 1;
8902         }
8903       else if (unformat (i, "%d", &local_label))
8904         ;
8905       else if (unformat (i, "table-id %d", &ip_table_id))
8906         ;
8907       else if (unformat (i, "unbind"))
8908         is_bind = 0;
8909       else if (unformat (i, "bind"))
8910         is_bind = 1;
8911       else
8912         {
8913           clib_warning ("parse error '%U'", format_unformat_error, i);
8914           return -99;
8915         }
8916     }
8917
8918   if (!address_set)
8919     {
8920       errmsg ("IP address not set");
8921       return -99;
8922     }
8923
8924   if (MPLS_LABEL_INVALID == local_label)
8925     {
8926       errmsg ("missing label");
8927       return -99;
8928     }
8929
8930   /* Construct the API message */
8931   M (MPLS_IP_BIND_UNBIND, mp);
8932
8933   mp->mb_is_bind = is_bind;
8934   mp->mb_is_ip4 = is_ip4;
8935   mp->mb_ip_table_id = ntohl (ip_table_id);
8936   mp->mb_mpls_table_id = 0;
8937   mp->mb_label = ntohl (local_label);
8938   mp->mb_address_length = address_length;
8939
8940   if (is_ip4)
8941     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8942   else
8943     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8944
8945   /* send it... */
8946   S (mp);
8947
8948   /* Wait for a reply... */
8949   W (ret);
8950   return ret;
8951 }
8952
8953 static int
8954 api_sr_mpls_policy_add (vat_main_t * vam)
8955 {
8956   unformat_input_t *i = vam->input;
8957   vl_api_sr_mpls_policy_add_t *mp;
8958   u32 bsid = 0;
8959   u32 weight = 1;
8960   u8 type = 0;
8961   u8 n_segments = 0;
8962   u32 sid;
8963   u32 *segments = NULL;
8964   int ret;
8965
8966   /* Parse args required to build the message */
8967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (i, "bsid %d", &bsid))
8970         ;
8971       else if (unformat (i, "weight %d", &weight))
8972         ;
8973       else if (unformat (i, "spray"))
8974         type = 1;
8975       else if (unformat (i, "next %d", &sid))
8976         {
8977           n_segments += 1;
8978           vec_add1 (segments, htonl (sid));
8979         }
8980       else
8981         {
8982           clib_warning ("parse error '%U'", format_unformat_error, i);
8983           return -99;
8984         }
8985     }
8986
8987   if (bsid == 0)
8988     {
8989       errmsg ("bsid not set");
8990       return -99;
8991     }
8992
8993   if (n_segments == 0)
8994     {
8995       errmsg ("no sid in segment stack");
8996       return -99;
8997     }
8998
8999   /* Construct the API message */
9000   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9001
9002   mp->bsid = htonl (bsid);
9003   mp->weight = htonl (weight);
9004   mp->type = type;
9005   mp->n_segments = n_segments;
9006   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9007   vec_free (segments);
9008
9009   /* send it... */
9010   S (mp);
9011
9012   /* Wait for a reply... */
9013   W (ret);
9014   return ret;
9015 }
9016
9017 static int
9018 api_sr_mpls_policy_del (vat_main_t * vam)
9019 {
9020   unformat_input_t *i = vam->input;
9021   vl_api_sr_mpls_policy_del_t *mp;
9022   u32 bsid = 0;
9023   int ret;
9024
9025   /* Parse args required to build the message */
9026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9027     {
9028       if (unformat (i, "bsid %d", &bsid))
9029         ;
9030       else
9031         {
9032           clib_warning ("parse error '%U'", format_unformat_error, i);
9033           return -99;
9034         }
9035     }
9036
9037   if (bsid == 0)
9038     {
9039       errmsg ("bsid not set");
9040       return -99;
9041     }
9042
9043   /* Construct the API message */
9044   M (SR_MPLS_POLICY_DEL, mp);
9045
9046   mp->bsid = htonl (bsid);
9047
9048   /* send it... */
9049   S (mp);
9050
9051   /* Wait for a reply... */
9052   W (ret);
9053   return ret;
9054 }
9055
9056 static int
9057 api_bier_table_add_del (vat_main_t * vam)
9058 {
9059   unformat_input_t *i = vam->input;
9060   vl_api_bier_table_add_del_t *mp;
9061   u8 is_add = 1;
9062   u32 set = 0, sub_domain = 0, hdr_len = 3;
9063   mpls_label_t local_label = MPLS_LABEL_INVALID;
9064   int ret;
9065
9066   /* Parse args required to build the message */
9067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (i, "sub-domain %d", &sub_domain))
9070         ;
9071       else if (unformat (i, "set %d", &set))
9072         ;
9073       else if (unformat (i, "label %d", &local_label))
9074         ;
9075       else if (unformat (i, "hdr-len %d", &hdr_len))
9076         ;
9077       else if (unformat (i, "add"))
9078         is_add = 1;
9079       else if (unformat (i, "del"))
9080         is_add = 0;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   if (MPLS_LABEL_INVALID == local_label)
9089     {
9090       errmsg ("missing label\n");
9091       return -99;
9092     }
9093
9094   /* Construct the API message */
9095   M (BIER_TABLE_ADD_DEL, mp);
9096
9097   mp->bt_is_add = is_add;
9098   mp->bt_label = ntohl (local_label);
9099   mp->bt_tbl_id.bt_set = set;
9100   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9101   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9102
9103   /* send it... */
9104   S (mp);
9105
9106   /* Wait for a reply... */
9107   W (ret);
9108
9109   return (ret);
9110 }
9111
9112 static int
9113 api_bier_route_add_del (vat_main_t * vam)
9114 {
9115   unformat_input_t *i = vam->input;
9116   vl_api_bier_route_add_del_t *mp;
9117   u8 is_add = 1;
9118   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9119   ip4_address_t v4_next_hop_address;
9120   ip6_address_t v6_next_hop_address;
9121   u8 next_hop_set = 0;
9122   u8 next_hop_proto_is_ip4 = 1;
9123   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9124   int ret;
9125
9126   /* Parse args required to build the message */
9127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9128     {
9129       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9130         {
9131           next_hop_proto_is_ip4 = 1;
9132           next_hop_set = 1;
9133         }
9134       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9135         {
9136           next_hop_proto_is_ip4 = 0;
9137           next_hop_set = 1;
9138         }
9139       if (unformat (i, "sub-domain %d", &sub_domain))
9140         ;
9141       else if (unformat (i, "set %d", &set))
9142         ;
9143       else if (unformat (i, "hdr-len %d", &hdr_len))
9144         ;
9145       else if (unformat (i, "bp %d", &bp))
9146         ;
9147       else if (unformat (i, "add"))
9148         is_add = 1;
9149       else if (unformat (i, "del"))
9150         is_add = 0;
9151       else if (unformat (i, "out-label %d", &next_hop_out_label))
9152         ;
9153       else
9154         {
9155           clib_warning ("parse error '%U'", format_unformat_error, i);
9156           return -99;
9157         }
9158     }
9159
9160   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9161     {
9162       errmsg ("next hop / label set\n");
9163       return -99;
9164     }
9165   if (0 == bp)
9166     {
9167       errmsg ("bit=position not set\n");
9168       return -99;
9169     }
9170
9171   /* Construct the API message */
9172   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9173
9174   mp->br_is_add = is_add;
9175   mp->br_tbl_id.bt_set = set;
9176   mp->br_tbl_id.bt_sub_domain = sub_domain;
9177   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9178   mp->br_bp = ntohs (bp);
9179   mp->br_n_paths = 1;
9180   mp->br_paths[0].n_labels = 1;
9181   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9182   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9183
9184   if (next_hop_proto_is_ip4)
9185     {
9186       clib_memcpy (mp->br_paths[0].next_hop,
9187                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9188     }
9189   else
9190     {
9191       clib_memcpy (mp->br_paths[0].next_hop,
9192                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9193     }
9194
9195   /* send it... */
9196   S (mp);
9197
9198   /* Wait for a reply... */
9199   W (ret);
9200
9201   return (ret);
9202 }
9203
9204 static int
9205 api_proxy_arp_add_del (vat_main_t * vam)
9206 {
9207   unformat_input_t *i = vam->input;
9208   vl_api_proxy_arp_add_del_t *mp;
9209   u32 vrf_id = 0;
9210   u8 is_add = 1;
9211   ip4_address_t lo, hi;
9212   u8 range_set = 0;
9213   int ret;
9214
9215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9216     {
9217       if (unformat (i, "vrf %d", &vrf_id))
9218         ;
9219       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9220                          unformat_ip4_address, &hi))
9221         range_set = 1;
9222       else if (unformat (i, "del"))
9223         is_add = 0;
9224       else
9225         {
9226           clib_warning ("parse error '%U'", format_unformat_error, i);
9227           return -99;
9228         }
9229     }
9230
9231   if (range_set == 0)
9232     {
9233       errmsg ("address range not set");
9234       return -99;
9235     }
9236
9237   M (PROXY_ARP_ADD_DEL, mp);
9238
9239   mp->proxy.vrf_id = ntohl (vrf_id);
9240   mp->is_add = is_add;
9241   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9242   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9243
9244   S (mp);
9245   W (ret);
9246   return ret;
9247 }
9248
9249 static int
9250 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9251 {
9252   unformat_input_t *i = vam->input;
9253   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9254   u32 sw_if_index;
9255   u8 enable = 1;
9256   u8 sw_if_index_set = 0;
9257   int ret;
9258
9259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9260     {
9261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9262         sw_if_index_set = 1;
9263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9264         sw_if_index_set = 1;
9265       else if (unformat (i, "enable"))
9266         enable = 1;
9267       else if (unformat (i, "disable"))
9268         enable = 0;
9269       else
9270         {
9271           clib_warning ("parse error '%U'", format_unformat_error, i);
9272           return -99;
9273         }
9274     }
9275
9276   if (sw_if_index_set == 0)
9277     {
9278       errmsg ("missing interface name or sw_if_index");
9279       return -99;
9280     }
9281
9282   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9283
9284   mp->sw_if_index = ntohl (sw_if_index);
9285   mp->enable_disable = enable;
9286
9287   S (mp);
9288   W (ret);
9289   return ret;
9290 }
9291
9292 static int
9293 api_mpls_tunnel_add_del (vat_main_t * vam)
9294 {
9295   unformat_input_t *i = vam->input;
9296   vl_api_mpls_tunnel_add_del_t *mp;
9297
9298   u8 is_add = 1;
9299   u8 l2_only = 0;
9300   u32 sw_if_index = ~0;
9301   u32 next_hop_sw_if_index = ~0;
9302   u32 next_hop_proto_is_ip4 = 1;
9303
9304   u32 next_hop_table_id = 0;
9305   ip4_address_t v4_next_hop_address = {
9306     .as_u32 = 0,
9307   };
9308   ip6_address_t v6_next_hop_address = { {0} };
9309   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9310   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9311   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9312   int ret;
9313
9314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9315     {
9316       if (unformat (i, "add"))
9317         is_add = 1;
9318       else
9319         if (unformat
9320             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9321         is_add = 0;
9322       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9323         is_add = 0;
9324       else if (unformat (i, "via %U",
9325                          unformat_ip4_address, &v4_next_hop_address))
9326         {
9327           next_hop_proto_is_ip4 = 1;
9328         }
9329       else if (unformat (i, "via %U",
9330                          unformat_ip6_address, &v6_next_hop_address))
9331         {
9332           next_hop_proto_is_ip4 = 0;
9333         }
9334       else if (unformat (i, "via-label %d", &next_hop_via_label))
9335         ;
9336       else
9337         if (unformat
9338             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9339         ;
9340       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9341         ;
9342       else if (unformat (i, "l2-only"))
9343         l2_only = 1;
9344       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9345         ;
9346       else if (unformat (i, "out-label %d", &next_hop_out_label))
9347         {
9348           vl_api_fib_mpls_label_t fib_label = {
9349             .label = ntohl (next_hop_out_label),
9350             .ttl = 64,
9351             .exp = 0,
9352           };
9353           vec_add1 (next_hop_out_label_stack, fib_label);
9354         }
9355       else
9356         {
9357           clib_warning ("parse error '%U'", format_unformat_error, i);
9358           return -99;
9359         }
9360     }
9361
9362   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9363       vec_len (next_hop_out_label_stack));
9364
9365   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9366   mp->mt_sw_if_index = ntohl (sw_if_index);
9367   mp->mt_is_add = is_add;
9368   mp->mt_l2_only = l2_only;
9369   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9370   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9371   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9372   mp->mt_next_hop_weight = 1;
9373   mp->mt_next_hop_preference = 0;
9374
9375   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9376
9377   if (0 != mp->mt_next_hop_n_out_labels)
9378     {
9379       clib_memcpy (mp->mt_next_hop_out_label_stack,
9380                    next_hop_out_label_stack,
9381                    (vec_len (next_hop_out_label_stack) *
9382                     sizeof (vl_api_fib_mpls_label_t)));
9383       vec_free (next_hop_out_label_stack);
9384     }
9385
9386   if (next_hop_proto_is_ip4)
9387     {
9388       clib_memcpy (mp->mt_next_hop,
9389                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9390     }
9391   else
9392     {
9393       clib_memcpy (mp->mt_next_hop,
9394                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9395     }
9396
9397   S (mp);
9398   W (ret);
9399   return ret;
9400 }
9401
9402 static int
9403 api_sw_interface_set_unnumbered (vat_main_t * vam)
9404 {
9405   unformat_input_t *i = vam->input;
9406   vl_api_sw_interface_set_unnumbered_t *mp;
9407   u32 sw_if_index;
9408   u32 unnum_sw_index = ~0;
9409   u8 is_add = 1;
9410   u8 sw_if_index_set = 0;
9411   int ret;
9412
9413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9416         sw_if_index_set = 1;
9417       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9418         sw_if_index_set = 1;
9419       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9420         ;
9421       else if (unformat (i, "del"))
9422         is_add = 0;
9423       else
9424         {
9425           clib_warning ("parse error '%U'", format_unformat_error, i);
9426           return -99;
9427         }
9428     }
9429
9430   if (sw_if_index_set == 0)
9431     {
9432       errmsg ("missing interface name or sw_if_index");
9433       return -99;
9434     }
9435
9436   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9437
9438   mp->sw_if_index = ntohl (sw_if_index);
9439   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9440   mp->is_add = is_add;
9441
9442   S (mp);
9443   W (ret);
9444   return ret;
9445 }
9446
9447 static int
9448 api_ip_neighbor_add_del (vat_main_t * vam)
9449 {
9450   unformat_input_t *i = vam->input;
9451   vl_api_ip_neighbor_add_del_t *mp;
9452   u32 sw_if_index;
9453   u8 sw_if_index_set = 0;
9454   u8 is_add = 1;
9455   u8 is_static = 0;
9456   u8 is_no_fib_entry = 0;
9457   u8 mac_address[6];
9458   u8 mac_set = 0;
9459   u8 v4_address_set = 0;
9460   u8 v6_address_set = 0;
9461   ip4_address_t v4address;
9462   ip6_address_t v6address;
9463   int ret;
9464
9465   clib_memset (mac_address, 0, sizeof (mac_address));
9466
9467   /* Parse args required to build the message */
9468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9469     {
9470       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9471         {
9472           mac_set = 1;
9473         }
9474       else if (unformat (i, "del"))
9475         is_add = 0;
9476       else
9477         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9478         sw_if_index_set = 1;
9479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9480         sw_if_index_set = 1;
9481       else if (unformat (i, "is_static"))
9482         is_static = 1;
9483       else if (unformat (i, "no-fib-entry"))
9484         is_no_fib_entry = 1;
9485       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9486         v4_address_set = 1;
9487       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9488         v6_address_set = 1;
9489       else
9490         {
9491           clib_warning ("parse error '%U'", format_unformat_error, i);
9492           return -99;
9493         }
9494     }
9495
9496   if (sw_if_index_set == 0)
9497     {
9498       errmsg ("missing interface name or sw_if_index");
9499       return -99;
9500     }
9501   if (v4_address_set && v6_address_set)
9502     {
9503       errmsg ("both v4 and v6 addresses set");
9504       return -99;
9505     }
9506   if (!v4_address_set && !v6_address_set)
9507     {
9508       errmsg ("no address set");
9509       return -99;
9510     }
9511
9512   /* Construct the API message */
9513   M (IP_NEIGHBOR_ADD_DEL, mp);
9514
9515   mp->sw_if_index = ntohl (sw_if_index);
9516   mp->is_add = is_add;
9517   mp->is_static = is_static;
9518   mp->is_no_adj_fib = is_no_fib_entry;
9519   if (mac_set)
9520     clib_memcpy (mp->mac_address, mac_address, 6);
9521   if (v6_address_set)
9522     {
9523       mp->is_ipv6 = 1;
9524       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9525     }
9526   else
9527     {
9528       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9529       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9530     }
9531
9532   /* send it... */
9533   S (mp);
9534
9535   /* Wait for a reply, return good/bad news  */
9536   W (ret);
9537   return ret;
9538 }
9539
9540 static int
9541 api_create_vlan_subif (vat_main_t * vam)
9542 {
9543   unformat_input_t *i = vam->input;
9544   vl_api_create_vlan_subif_t *mp;
9545   u32 sw_if_index;
9546   u8 sw_if_index_set = 0;
9547   u32 vlan_id;
9548   u8 vlan_id_set = 0;
9549   int ret;
9550
9551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (i, "sw_if_index %d", &sw_if_index))
9554         sw_if_index_set = 1;
9555       else
9556         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "vlan %d", &vlan_id))
9559         vlan_id_set = 1;
9560       else
9561         {
9562           clib_warning ("parse error '%U'", format_unformat_error, i);
9563           return -99;
9564         }
9565     }
9566
9567   if (sw_if_index_set == 0)
9568     {
9569       errmsg ("missing interface name or sw_if_index");
9570       return -99;
9571     }
9572
9573   if (vlan_id_set == 0)
9574     {
9575       errmsg ("missing vlan_id");
9576       return -99;
9577     }
9578   M (CREATE_VLAN_SUBIF, mp);
9579
9580   mp->sw_if_index = ntohl (sw_if_index);
9581   mp->vlan_id = ntohl (vlan_id);
9582
9583   S (mp);
9584   W (ret);
9585   return ret;
9586 }
9587
9588 #define foreach_create_subif_bit                \
9589 _(no_tags)                                      \
9590 _(one_tag)                                      \
9591 _(two_tags)                                     \
9592 _(dot1ad)                                       \
9593 _(exact_match)                                  \
9594 _(default_sub)                                  \
9595 _(outer_vlan_id_any)                            \
9596 _(inner_vlan_id_any)
9597
9598 static int
9599 api_create_subif (vat_main_t * vam)
9600 {
9601   unformat_input_t *i = vam->input;
9602   vl_api_create_subif_t *mp;
9603   u32 sw_if_index;
9604   u8 sw_if_index_set = 0;
9605   u32 sub_id;
9606   u8 sub_id_set = 0;
9607   u32 no_tags = 0;
9608   u32 one_tag = 0;
9609   u32 two_tags = 0;
9610   u32 dot1ad = 0;
9611   u32 exact_match = 0;
9612   u32 default_sub = 0;
9613   u32 outer_vlan_id_any = 0;
9614   u32 inner_vlan_id_any = 0;
9615   u32 tmp;
9616   u16 outer_vlan_id = 0;
9617   u16 inner_vlan_id = 0;
9618   int ret;
9619
9620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9621     {
9622       if (unformat (i, "sw_if_index %d", &sw_if_index))
9623         sw_if_index_set = 1;
9624       else
9625         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9626         sw_if_index_set = 1;
9627       else if (unformat (i, "sub_id %d", &sub_id))
9628         sub_id_set = 1;
9629       else if (unformat (i, "outer_vlan_id %d", &tmp))
9630         outer_vlan_id = tmp;
9631       else if (unformat (i, "inner_vlan_id %d", &tmp))
9632         inner_vlan_id = tmp;
9633
9634 #define _(a) else if (unformat (i, #a)) a = 1 ;
9635       foreach_create_subif_bit
9636 #undef _
9637         else
9638         {
9639           clib_warning ("parse error '%U'", format_unformat_error, i);
9640           return -99;
9641         }
9642     }
9643
9644   if (sw_if_index_set == 0)
9645     {
9646       errmsg ("missing interface name or sw_if_index");
9647       return -99;
9648     }
9649
9650   if (sub_id_set == 0)
9651     {
9652       errmsg ("missing sub_id");
9653       return -99;
9654     }
9655   M (CREATE_SUBIF, mp);
9656
9657   mp->sw_if_index = ntohl (sw_if_index);
9658   mp->sub_id = ntohl (sub_id);
9659
9660 #define _(a) mp->a = a;
9661   foreach_create_subif_bit;
9662 #undef _
9663
9664   mp->outer_vlan_id = ntohs (outer_vlan_id);
9665   mp->inner_vlan_id = ntohs (inner_vlan_id);
9666
9667   S (mp);
9668   W (ret);
9669   return ret;
9670 }
9671
9672 static int
9673 api_oam_add_del (vat_main_t * vam)
9674 {
9675   unformat_input_t *i = vam->input;
9676   vl_api_oam_add_del_t *mp;
9677   u32 vrf_id = 0;
9678   u8 is_add = 1;
9679   ip4_address_t src, dst;
9680   u8 src_set = 0;
9681   u8 dst_set = 0;
9682   int ret;
9683
9684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9685     {
9686       if (unformat (i, "vrf %d", &vrf_id))
9687         ;
9688       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9689         src_set = 1;
9690       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9691         dst_set = 1;
9692       else if (unformat (i, "del"))
9693         is_add = 0;
9694       else
9695         {
9696           clib_warning ("parse error '%U'", format_unformat_error, i);
9697           return -99;
9698         }
9699     }
9700
9701   if (src_set == 0)
9702     {
9703       errmsg ("missing src addr");
9704       return -99;
9705     }
9706
9707   if (dst_set == 0)
9708     {
9709       errmsg ("missing dst addr");
9710       return -99;
9711     }
9712
9713   M (OAM_ADD_DEL, mp);
9714
9715   mp->vrf_id = ntohl (vrf_id);
9716   mp->is_add = is_add;
9717   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9718   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9719
9720   S (mp);
9721   W (ret);
9722   return ret;
9723 }
9724
9725 static int
9726 api_reset_fib (vat_main_t * vam)
9727 {
9728   unformat_input_t *i = vam->input;
9729   vl_api_reset_fib_t *mp;
9730   u32 vrf_id = 0;
9731   u8 is_ipv6 = 0;
9732   u8 vrf_id_set = 0;
9733
9734   int ret;
9735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9736     {
9737       if (unformat (i, "vrf %d", &vrf_id))
9738         vrf_id_set = 1;
9739       else if (unformat (i, "ipv6"))
9740         is_ipv6 = 1;
9741       else
9742         {
9743           clib_warning ("parse error '%U'", format_unformat_error, i);
9744           return -99;
9745         }
9746     }
9747
9748   if (vrf_id_set == 0)
9749     {
9750       errmsg ("missing vrf id");
9751       return -99;
9752     }
9753
9754   M (RESET_FIB, mp);
9755
9756   mp->vrf_id = ntohl (vrf_id);
9757   mp->is_ipv6 = is_ipv6;
9758
9759   S (mp);
9760   W (ret);
9761   return ret;
9762 }
9763
9764 static int
9765 api_dhcp_proxy_config (vat_main_t * vam)
9766 {
9767   unformat_input_t *i = vam->input;
9768   vl_api_dhcp_proxy_config_t *mp;
9769   u32 rx_vrf_id = 0;
9770   u32 server_vrf_id = 0;
9771   u8 is_add = 1;
9772   u8 v4_address_set = 0;
9773   u8 v6_address_set = 0;
9774   ip4_address_t v4address;
9775   ip6_address_t v6address;
9776   u8 v4_src_address_set = 0;
9777   u8 v6_src_address_set = 0;
9778   ip4_address_t v4srcaddress;
9779   ip6_address_t v6srcaddress;
9780   int ret;
9781
9782   /* Parse args required to build the message */
9783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9784     {
9785       if (unformat (i, "del"))
9786         is_add = 0;
9787       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9788         ;
9789       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9790         ;
9791       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9792         v4_address_set = 1;
9793       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9794         v6_address_set = 1;
9795       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9796         v4_src_address_set = 1;
9797       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9798         v6_src_address_set = 1;
9799       else
9800         break;
9801     }
9802
9803   if (v4_address_set && v6_address_set)
9804     {
9805       errmsg ("both v4 and v6 server addresses set");
9806       return -99;
9807     }
9808   if (!v4_address_set && !v6_address_set)
9809     {
9810       errmsg ("no server addresses set");
9811       return -99;
9812     }
9813
9814   if (v4_src_address_set && v6_src_address_set)
9815     {
9816       errmsg ("both v4 and v6  src addresses set");
9817       return -99;
9818     }
9819   if (!v4_src_address_set && !v6_src_address_set)
9820     {
9821       errmsg ("no src addresses set");
9822       return -99;
9823     }
9824
9825   if (!(v4_src_address_set && v4_address_set) &&
9826       !(v6_src_address_set && v6_address_set))
9827     {
9828       errmsg ("no matching server and src addresses set");
9829       return -99;
9830     }
9831
9832   /* Construct the API message */
9833   M (DHCP_PROXY_CONFIG, mp);
9834
9835   mp->is_add = is_add;
9836   mp->rx_vrf_id = ntohl (rx_vrf_id);
9837   mp->server_vrf_id = ntohl (server_vrf_id);
9838   if (v6_address_set)
9839     {
9840       mp->is_ipv6 = 1;
9841       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9842       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9843     }
9844   else
9845     {
9846       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9847       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9848     }
9849
9850   /* send it... */
9851   S (mp);
9852
9853   /* Wait for a reply, return good/bad news  */
9854   W (ret);
9855   return ret;
9856 }
9857
9858 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9859 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9860
9861 static void
9862 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9863 {
9864   vat_main_t *vam = &vat_main;
9865   u32 i, count = mp->count;
9866   vl_api_dhcp_server_t *s;
9867
9868   if (mp->is_ipv6)
9869     print (vam->ofp,
9870            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9871            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9872            ntohl (mp->rx_vrf_id),
9873            format_ip6_address, mp->dhcp_src_address,
9874            mp->vss_type, mp->vss_vpn_ascii_id,
9875            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9876   else
9877     print (vam->ofp,
9878            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9879            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9880            ntohl (mp->rx_vrf_id),
9881            format_ip4_address, mp->dhcp_src_address,
9882            mp->vss_type, mp->vss_vpn_ascii_id,
9883            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9884
9885   for (i = 0; i < count; i++)
9886     {
9887       s = &mp->servers[i];
9888
9889       if (mp->is_ipv6)
9890         print (vam->ofp,
9891                " Server Table-ID %d, Server Address %U",
9892                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9893       else
9894         print (vam->ofp,
9895                " Server Table-ID %d, Server Address %U",
9896                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9897     }
9898 }
9899
9900 static void vl_api_dhcp_proxy_details_t_handler_json
9901   (vl_api_dhcp_proxy_details_t * mp)
9902 {
9903   vat_main_t *vam = &vat_main;
9904   vat_json_node_t *node = NULL;
9905   u32 i, count = mp->count;
9906   struct in_addr ip4;
9907   struct in6_addr ip6;
9908   vl_api_dhcp_server_t *s;
9909
9910   if (VAT_JSON_ARRAY != vam->json_tree.type)
9911     {
9912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9913       vat_json_init_array (&vam->json_tree);
9914     }
9915   node = vat_json_array_add (&vam->json_tree);
9916
9917   vat_json_init_object (node);
9918   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9919   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9920                              sizeof (mp->vss_type));
9921   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9922                                    mp->vss_vpn_ascii_id);
9923   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9924   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9925
9926   if (mp->is_ipv6)
9927     {
9928       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9929       vat_json_object_add_ip6 (node, "src_address", ip6);
9930     }
9931   else
9932     {
9933       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9934       vat_json_object_add_ip4 (node, "src_address", ip4);
9935     }
9936
9937   for (i = 0; i < count; i++)
9938     {
9939       s = &mp->servers[i];
9940
9941       vat_json_object_add_uint (node, "server-table-id",
9942                                 ntohl (s->server_vrf_id));
9943
9944       if (mp->is_ipv6)
9945         {
9946           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9947           vat_json_object_add_ip4 (node, "src_address", ip4);
9948         }
9949       else
9950         {
9951           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9952           vat_json_object_add_ip6 (node, "server_address", ip6);
9953         }
9954     }
9955 }
9956
9957 static int
9958 api_dhcp_proxy_dump (vat_main_t * vam)
9959 {
9960   unformat_input_t *i = vam->input;
9961   vl_api_control_ping_t *mp_ping;
9962   vl_api_dhcp_proxy_dump_t *mp;
9963   u8 is_ipv6 = 0;
9964   int ret;
9965
9966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9967     {
9968       if (unformat (i, "ipv6"))
9969         is_ipv6 = 1;
9970       else
9971         {
9972           clib_warning ("parse error '%U'", format_unformat_error, i);
9973           return -99;
9974         }
9975     }
9976
9977   M (DHCP_PROXY_DUMP, mp);
9978
9979   mp->is_ip6 = is_ipv6;
9980   S (mp);
9981
9982   /* Use a control ping for synchronization */
9983   MPING (CONTROL_PING, mp_ping);
9984   S (mp_ping);
9985
9986   W (ret);
9987   return ret;
9988 }
9989
9990 static int
9991 api_dhcp_proxy_set_vss (vat_main_t * vam)
9992 {
9993   unformat_input_t *i = vam->input;
9994   vl_api_dhcp_proxy_set_vss_t *mp;
9995   u8 is_ipv6 = 0;
9996   u8 is_add = 1;
9997   u32 tbl_id = ~0;
9998   u8 vss_type = VSS_TYPE_DEFAULT;
9999   u8 *vpn_ascii_id = 0;
10000   u32 oui = 0;
10001   u32 fib_id = 0;
10002   int ret;
10003
10004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10005     {
10006       if (unformat (i, "tbl_id %d", &tbl_id))
10007         ;
10008       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10009         vss_type = VSS_TYPE_ASCII;
10010       else if (unformat (i, "fib_id %d", &fib_id))
10011         vss_type = VSS_TYPE_VPN_ID;
10012       else if (unformat (i, "oui %d", &oui))
10013         vss_type = VSS_TYPE_VPN_ID;
10014       else if (unformat (i, "ipv6"))
10015         is_ipv6 = 1;
10016       else if (unformat (i, "del"))
10017         is_add = 0;
10018       else
10019         break;
10020     }
10021
10022   if (tbl_id == ~0)
10023     {
10024       errmsg ("missing tbl_id ");
10025       vec_free (vpn_ascii_id);
10026       return -99;
10027     }
10028
10029   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10030     {
10031       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10032       vec_free (vpn_ascii_id);
10033       return -99;
10034     }
10035
10036   M (DHCP_PROXY_SET_VSS, mp);
10037   mp->tbl_id = ntohl (tbl_id);
10038   mp->vss_type = vss_type;
10039   if (vpn_ascii_id)
10040     {
10041       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10042       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10043     }
10044   mp->vpn_index = ntohl (fib_id);
10045   mp->oui = ntohl (oui);
10046   mp->is_ipv6 = is_ipv6;
10047   mp->is_add = is_add;
10048
10049   S (mp);
10050   W (ret);
10051
10052   vec_free (vpn_ascii_id);
10053   return ret;
10054 }
10055
10056 static int
10057 api_dhcp_client_config (vat_main_t * vam)
10058 {
10059   unformat_input_t *i = vam->input;
10060   vl_api_dhcp_client_config_t *mp;
10061   u32 sw_if_index;
10062   u8 sw_if_index_set = 0;
10063   u8 is_add = 1;
10064   u8 *hostname = 0;
10065   u8 disable_event = 0;
10066   int ret;
10067
10068   /* Parse args required to build the message */
10069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10070     {
10071       if (unformat (i, "del"))
10072         is_add = 0;
10073       else
10074         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10075         sw_if_index_set = 1;
10076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "hostname %s", &hostname))
10079         ;
10080       else if (unformat (i, "disable_event"))
10081         disable_event = 1;
10082       else
10083         break;
10084     }
10085
10086   if (sw_if_index_set == 0)
10087     {
10088       errmsg ("missing interface name or sw_if_index");
10089       return -99;
10090     }
10091
10092   if (vec_len (hostname) > 63)
10093     {
10094       errmsg ("hostname too long");
10095     }
10096   vec_add1 (hostname, 0);
10097
10098   /* Construct the API message */
10099   M (DHCP_CLIENT_CONFIG, mp);
10100
10101   mp->is_add = is_add;
10102   mp->client.sw_if_index = htonl (sw_if_index);
10103   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10104   vec_free (hostname);
10105   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10106   mp->client.pid = htonl (getpid ());
10107
10108   /* send it... */
10109   S (mp);
10110
10111   /* Wait for a reply, return good/bad news  */
10112   W (ret);
10113   return ret;
10114 }
10115
10116 static int
10117 api_set_ip_flow_hash (vat_main_t * vam)
10118 {
10119   unformat_input_t *i = vam->input;
10120   vl_api_set_ip_flow_hash_t *mp;
10121   u32 vrf_id = 0;
10122   u8 is_ipv6 = 0;
10123   u8 vrf_id_set = 0;
10124   u8 src = 0;
10125   u8 dst = 0;
10126   u8 sport = 0;
10127   u8 dport = 0;
10128   u8 proto = 0;
10129   u8 reverse = 0;
10130   int ret;
10131
10132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10133     {
10134       if (unformat (i, "vrf %d", &vrf_id))
10135         vrf_id_set = 1;
10136       else if (unformat (i, "ipv6"))
10137         is_ipv6 = 1;
10138       else if (unformat (i, "src"))
10139         src = 1;
10140       else if (unformat (i, "dst"))
10141         dst = 1;
10142       else if (unformat (i, "sport"))
10143         sport = 1;
10144       else if (unformat (i, "dport"))
10145         dport = 1;
10146       else if (unformat (i, "proto"))
10147         proto = 1;
10148       else if (unformat (i, "reverse"))
10149         reverse = 1;
10150
10151       else
10152         {
10153           clib_warning ("parse error '%U'", format_unformat_error, i);
10154           return -99;
10155         }
10156     }
10157
10158   if (vrf_id_set == 0)
10159     {
10160       errmsg ("missing vrf id");
10161       return -99;
10162     }
10163
10164   M (SET_IP_FLOW_HASH, mp);
10165   mp->src = src;
10166   mp->dst = dst;
10167   mp->sport = sport;
10168   mp->dport = dport;
10169   mp->proto = proto;
10170   mp->reverse = reverse;
10171   mp->vrf_id = ntohl (vrf_id);
10172   mp->is_ipv6 = is_ipv6;
10173
10174   S (mp);
10175   W (ret);
10176   return ret;
10177 }
10178
10179 static int
10180 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10181 {
10182   unformat_input_t *i = vam->input;
10183   vl_api_sw_interface_ip6_enable_disable_t *mp;
10184   u32 sw_if_index;
10185   u8 sw_if_index_set = 0;
10186   u8 enable = 0;
10187   int ret;
10188
10189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10190     {
10191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10192         sw_if_index_set = 1;
10193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10194         sw_if_index_set = 1;
10195       else if (unformat (i, "enable"))
10196         enable = 1;
10197       else if (unformat (i, "disable"))
10198         enable = 0;
10199       else
10200         {
10201           clib_warning ("parse error '%U'", format_unformat_error, i);
10202           return -99;
10203         }
10204     }
10205
10206   if (sw_if_index_set == 0)
10207     {
10208       errmsg ("missing interface name or sw_if_index");
10209       return -99;
10210     }
10211
10212   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10213
10214   mp->sw_if_index = ntohl (sw_if_index);
10215   mp->enable = enable;
10216
10217   S (mp);
10218   W (ret);
10219   return ret;
10220 }
10221
10222 static int
10223 api_ip6nd_proxy_add_del (vat_main_t * vam)
10224 {
10225   unformat_input_t *i = vam->input;
10226   vl_api_ip6nd_proxy_add_del_t *mp;
10227   u32 sw_if_index = ~0;
10228   u8 v6_address_set = 0;
10229   ip6_address_t v6address;
10230   u8 is_del = 0;
10231   int ret;
10232
10233   /* Parse args required to build the message */
10234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10235     {
10236       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10237         ;
10238       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10239         ;
10240       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10241         v6_address_set = 1;
10242       if (unformat (i, "del"))
10243         is_del = 1;
10244       else
10245         {
10246           clib_warning ("parse error '%U'", format_unformat_error, i);
10247           return -99;
10248         }
10249     }
10250
10251   if (sw_if_index == ~0)
10252     {
10253       errmsg ("missing interface name or sw_if_index");
10254       return -99;
10255     }
10256   if (!v6_address_set)
10257     {
10258       errmsg ("no address set");
10259       return -99;
10260     }
10261
10262   /* Construct the API message */
10263   M (IP6ND_PROXY_ADD_DEL, mp);
10264
10265   mp->is_del = is_del;
10266   mp->sw_if_index = ntohl (sw_if_index);
10267   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10268
10269   /* send it... */
10270   S (mp);
10271
10272   /* Wait for a reply, return good/bad news  */
10273   W (ret);
10274   return ret;
10275 }
10276
10277 static int
10278 api_ip6nd_proxy_dump (vat_main_t * vam)
10279 {
10280   vl_api_ip6nd_proxy_dump_t *mp;
10281   vl_api_control_ping_t *mp_ping;
10282   int ret;
10283
10284   M (IP6ND_PROXY_DUMP, mp);
10285
10286   S (mp);
10287
10288   /* Use a control ping for synchronization */
10289   MPING (CONTROL_PING, mp_ping);
10290   S (mp_ping);
10291
10292   W (ret);
10293   return ret;
10294 }
10295
10296 static void vl_api_ip6nd_proxy_details_t_handler
10297   (vl_api_ip6nd_proxy_details_t * mp)
10298 {
10299   vat_main_t *vam = &vat_main;
10300
10301   print (vam->ofp, "host %U sw_if_index %d",
10302          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10303 }
10304
10305 static void vl_api_ip6nd_proxy_details_t_handler_json
10306   (vl_api_ip6nd_proxy_details_t * mp)
10307 {
10308   vat_main_t *vam = &vat_main;
10309   struct in6_addr ip6;
10310   vat_json_node_t *node = NULL;
10311
10312   if (VAT_JSON_ARRAY != vam->json_tree.type)
10313     {
10314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10315       vat_json_init_array (&vam->json_tree);
10316     }
10317   node = vat_json_array_add (&vam->json_tree);
10318
10319   vat_json_init_object (node);
10320   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10321
10322   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10323   vat_json_object_add_ip6 (node, "host", ip6);
10324 }
10325
10326 static int
10327 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10328 {
10329   unformat_input_t *i = vam->input;
10330   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10331   u32 sw_if_index;
10332   u8 sw_if_index_set = 0;
10333   u32 address_length = 0;
10334   u8 v6_address_set = 0;
10335   ip6_address_t v6address;
10336   u8 use_default = 0;
10337   u8 no_advertise = 0;
10338   u8 off_link = 0;
10339   u8 no_autoconfig = 0;
10340   u8 no_onlink = 0;
10341   u8 is_no = 0;
10342   u32 val_lifetime = 0;
10343   u32 pref_lifetime = 0;
10344   int ret;
10345
10346   /* Parse args required to build the message */
10347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10348     {
10349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10350         sw_if_index_set = 1;
10351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10352         sw_if_index_set = 1;
10353       else if (unformat (i, "%U/%d",
10354                          unformat_ip6_address, &v6address, &address_length))
10355         v6_address_set = 1;
10356       else if (unformat (i, "val_life %d", &val_lifetime))
10357         ;
10358       else if (unformat (i, "pref_life %d", &pref_lifetime))
10359         ;
10360       else if (unformat (i, "def"))
10361         use_default = 1;
10362       else if (unformat (i, "noadv"))
10363         no_advertise = 1;
10364       else if (unformat (i, "offl"))
10365         off_link = 1;
10366       else if (unformat (i, "noauto"))
10367         no_autoconfig = 1;
10368       else if (unformat (i, "nolink"))
10369         no_onlink = 1;
10370       else if (unformat (i, "isno"))
10371         is_no = 1;
10372       else
10373         {
10374           clib_warning ("parse error '%U'", format_unformat_error, i);
10375           return -99;
10376         }
10377     }
10378
10379   if (sw_if_index_set == 0)
10380     {
10381       errmsg ("missing interface name or sw_if_index");
10382       return -99;
10383     }
10384   if (!v6_address_set)
10385     {
10386       errmsg ("no address set");
10387       return -99;
10388     }
10389
10390   /* Construct the API message */
10391   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10392
10393   mp->sw_if_index = ntohl (sw_if_index);
10394   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10395   mp->address_length = address_length;
10396   mp->use_default = use_default;
10397   mp->no_advertise = no_advertise;
10398   mp->off_link = off_link;
10399   mp->no_autoconfig = no_autoconfig;
10400   mp->no_onlink = no_onlink;
10401   mp->is_no = is_no;
10402   mp->val_lifetime = ntohl (val_lifetime);
10403   mp->pref_lifetime = ntohl (pref_lifetime);
10404
10405   /* send it... */
10406   S (mp);
10407
10408   /* Wait for a reply, return good/bad news  */
10409   W (ret);
10410   return ret;
10411 }
10412
10413 static int
10414 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10415 {
10416   unformat_input_t *i = vam->input;
10417   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10418   u32 sw_if_index;
10419   u8 sw_if_index_set = 0;
10420   u8 suppress = 0;
10421   u8 managed = 0;
10422   u8 other = 0;
10423   u8 ll_option = 0;
10424   u8 send_unicast = 0;
10425   u8 cease = 0;
10426   u8 is_no = 0;
10427   u8 default_router = 0;
10428   u32 max_interval = 0;
10429   u32 min_interval = 0;
10430   u32 lifetime = 0;
10431   u32 initial_count = 0;
10432   u32 initial_interval = 0;
10433   int ret;
10434
10435
10436   /* Parse args required to build the message */
10437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10438     {
10439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10440         sw_if_index_set = 1;
10441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10442         sw_if_index_set = 1;
10443       else if (unformat (i, "maxint %d", &max_interval))
10444         ;
10445       else if (unformat (i, "minint %d", &min_interval))
10446         ;
10447       else if (unformat (i, "life %d", &lifetime))
10448         ;
10449       else if (unformat (i, "count %d", &initial_count))
10450         ;
10451       else if (unformat (i, "interval %d", &initial_interval))
10452         ;
10453       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10454         suppress = 1;
10455       else if (unformat (i, "managed"))
10456         managed = 1;
10457       else if (unformat (i, "other"))
10458         other = 1;
10459       else if (unformat (i, "ll"))
10460         ll_option = 1;
10461       else if (unformat (i, "send"))
10462         send_unicast = 1;
10463       else if (unformat (i, "cease"))
10464         cease = 1;
10465       else if (unformat (i, "isno"))
10466         is_no = 1;
10467       else if (unformat (i, "def"))
10468         default_router = 1;
10469       else
10470         {
10471           clib_warning ("parse error '%U'", format_unformat_error, i);
10472           return -99;
10473         }
10474     }
10475
10476   if (sw_if_index_set == 0)
10477     {
10478       errmsg ("missing interface name or sw_if_index");
10479       return -99;
10480     }
10481
10482   /* Construct the API message */
10483   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10484
10485   mp->sw_if_index = ntohl (sw_if_index);
10486   mp->max_interval = ntohl (max_interval);
10487   mp->min_interval = ntohl (min_interval);
10488   mp->lifetime = ntohl (lifetime);
10489   mp->initial_count = ntohl (initial_count);
10490   mp->initial_interval = ntohl (initial_interval);
10491   mp->suppress = suppress;
10492   mp->managed = managed;
10493   mp->other = other;
10494   mp->ll_option = ll_option;
10495   mp->send_unicast = send_unicast;
10496   mp->cease = cease;
10497   mp->is_no = is_no;
10498   mp->default_router = default_router;
10499
10500   /* send it... */
10501   S (mp);
10502
10503   /* Wait for a reply, return good/bad news  */
10504   W (ret);
10505   return ret;
10506 }
10507
10508 static int
10509 api_set_arp_neighbor_limit (vat_main_t * vam)
10510 {
10511   unformat_input_t *i = vam->input;
10512   vl_api_set_arp_neighbor_limit_t *mp;
10513   u32 arp_nbr_limit;
10514   u8 limit_set = 0;
10515   u8 is_ipv6 = 0;
10516   int ret;
10517
10518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10519     {
10520       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10521         limit_set = 1;
10522       else if (unformat (i, "ipv6"))
10523         is_ipv6 = 1;
10524       else
10525         {
10526           clib_warning ("parse error '%U'", format_unformat_error, i);
10527           return -99;
10528         }
10529     }
10530
10531   if (limit_set == 0)
10532     {
10533       errmsg ("missing limit value");
10534       return -99;
10535     }
10536
10537   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10538
10539   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10540   mp->is_ipv6 = is_ipv6;
10541
10542   S (mp);
10543   W (ret);
10544   return ret;
10545 }
10546
10547 static int
10548 api_l2_patch_add_del (vat_main_t * vam)
10549 {
10550   unformat_input_t *i = vam->input;
10551   vl_api_l2_patch_add_del_t *mp;
10552   u32 rx_sw_if_index;
10553   u8 rx_sw_if_index_set = 0;
10554   u32 tx_sw_if_index;
10555   u8 tx_sw_if_index_set = 0;
10556   u8 is_add = 1;
10557   int ret;
10558
10559   /* Parse args required to build the message */
10560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10563         rx_sw_if_index_set = 1;
10564       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10565         tx_sw_if_index_set = 1;
10566       else if (unformat (i, "rx"))
10567         {
10568           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10569             {
10570               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10571                             &rx_sw_if_index))
10572                 rx_sw_if_index_set = 1;
10573             }
10574           else
10575             break;
10576         }
10577       else if (unformat (i, "tx"))
10578         {
10579           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10580             {
10581               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10582                             &tx_sw_if_index))
10583                 tx_sw_if_index_set = 1;
10584             }
10585           else
10586             break;
10587         }
10588       else if (unformat (i, "del"))
10589         is_add = 0;
10590       else
10591         break;
10592     }
10593
10594   if (rx_sw_if_index_set == 0)
10595     {
10596       errmsg ("missing rx interface name or rx_sw_if_index");
10597       return -99;
10598     }
10599
10600   if (tx_sw_if_index_set == 0)
10601     {
10602       errmsg ("missing tx interface name or tx_sw_if_index");
10603       return -99;
10604     }
10605
10606   M (L2_PATCH_ADD_DEL, mp);
10607
10608   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10609   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10610   mp->is_add = is_add;
10611
10612   S (mp);
10613   W (ret);
10614   return ret;
10615 }
10616
10617 u8 is_del;
10618 u8 localsid_addr[16];
10619 u8 end_psp;
10620 u8 behavior;
10621 u32 sw_if_index;
10622 u32 vlan_index;
10623 u32 fib_table;
10624 u8 nh_addr[16];
10625
10626 static int
10627 api_sr_localsid_add_del (vat_main_t * vam)
10628 {
10629   unformat_input_t *i = vam->input;
10630   vl_api_sr_localsid_add_del_t *mp;
10631
10632   u8 is_del;
10633   ip6_address_t localsid;
10634   u8 end_psp = 0;
10635   u8 behavior = ~0;
10636   u32 sw_if_index;
10637   u32 fib_table = ~(u32) 0;
10638   ip6_address_t nh_addr6;
10639   ip4_address_t nh_addr4;
10640   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10641   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10642
10643   bool nexthop_set = 0;
10644
10645   int ret;
10646
10647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10648     {
10649       if (unformat (i, "del"))
10650         is_del = 1;
10651       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10652       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10653         nexthop_set = 1;
10654       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10655         nexthop_set = 1;
10656       else if (unformat (i, "behavior %u", &behavior));
10657       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10658       else if (unformat (i, "fib-table %u", &fib_table));
10659       else if (unformat (i, "end.psp %u", &behavior));
10660       else
10661         break;
10662     }
10663
10664   M (SR_LOCALSID_ADD_DEL, mp);
10665
10666   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10667   if (nexthop_set)
10668     {
10669       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10670       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10671     }
10672   mp->behavior = behavior;
10673   mp->sw_if_index = ntohl (sw_if_index);
10674   mp->fib_table = ntohl (fib_table);
10675   mp->end_psp = end_psp;
10676   mp->is_del = is_del;
10677
10678   S (mp);
10679   W (ret);
10680   return ret;
10681 }
10682
10683 static int
10684 api_ioam_enable (vat_main_t * vam)
10685 {
10686   unformat_input_t *input = vam->input;
10687   vl_api_ioam_enable_t *mp;
10688   u32 id = 0;
10689   int has_trace_option = 0;
10690   int has_pot_option = 0;
10691   int has_seqno_option = 0;
10692   int has_analyse_option = 0;
10693   int ret;
10694
10695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10696     {
10697       if (unformat (input, "trace"))
10698         has_trace_option = 1;
10699       else if (unformat (input, "pot"))
10700         has_pot_option = 1;
10701       else if (unformat (input, "seqno"))
10702         has_seqno_option = 1;
10703       else if (unformat (input, "analyse"))
10704         has_analyse_option = 1;
10705       else
10706         break;
10707     }
10708   M (IOAM_ENABLE, mp);
10709   mp->id = htons (id);
10710   mp->seqno = has_seqno_option;
10711   mp->analyse = has_analyse_option;
10712   mp->pot_enable = has_pot_option;
10713   mp->trace_enable = has_trace_option;
10714
10715   S (mp);
10716   W (ret);
10717   return ret;
10718 }
10719
10720
10721 static int
10722 api_ioam_disable (vat_main_t * vam)
10723 {
10724   vl_api_ioam_disable_t *mp;
10725   int ret;
10726
10727   M (IOAM_DISABLE, mp);
10728   S (mp);
10729   W (ret);
10730   return ret;
10731 }
10732
10733 #define foreach_tcp_proto_field                 \
10734 _(src_port)                                     \
10735 _(dst_port)
10736
10737 #define foreach_udp_proto_field                 \
10738 _(src_port)                                     \
10739 _(dst_port)
10740
10741 #define foreach_ip4_proto_field                 \
10742 _(src_address)                                  \
10743 _(dst_address)                                  \
10744 _(tos)                                          \
10745 _(length)                                       \
10746 _(fragment_id)                                  \
10747 _(ttl)                                          \
10748 _(protocol)                                     \
10749 _(checksum)
10750
10751 typedef struct
10752 {
10753   u16 src_port, dst_port;
10754 } tcpudp_header_t;
10755
10756 #if VPP_API_TEST_BUILTIN == 0
10757 uword
10758 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10759 {
10760   u8 **maskp = va_arg (*args, u8 **);
10761   u8 *mask = 0;
10762   u8 found_something = 0;
10763   tcp_header_t *tcp;
10764
10765 #define _(a) u8 a=0;
10766   foreach_tcp_proto_field;
10767 #undef _
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (0);
10772 #define _(a) else if (unformat (input, #a)) a=1;
10773       foreach_tcp_proto_field
10774 #undef _
10775         else
10776         break;
10777     }
10778
10779 #define _(a) found_something += a;
10780   foreach_tcp_proto_field;
10781 #undef _
10782
10783   if (found_something == 0)
10784     return 0;
10785
10786   vec_validate (mask, sizeof (*tcp) - 1);
10787
10788   tcp = (tcp_header_t *) mask;
10789
10790 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10791   foreach_tcp_proto_field;
10792 #undef _
10793
10794   *maskp = mask;
10795   return 1;
10796 }
10797
10798 uword
10799 unformat_udp_mask (unformat_input_t * input, va_list * args)
10800 {
10801   u8 **maskp = va_arg (*args, u8 **);
10802   u8 *mask = 0;
10803   u8 found_something = 0;
10804   udp_header_t *udp;
10805
10806 #define _(a) u8 a=0;
10807   foreach_udp_proto_field;
10808 #undef _
10809
10810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (0);
10813 #define _(a) else if (unformat (input, #a)) a=1;
10814       foreach_udp_proto_field
10815 #undef _
10816         else
10817         break;
10818     }
10819
10820 #define _(a) found_something += a;
10821   foreach_udp_proto_field;
10822 #undef _
10823
10824   if (found_something == 0)
10825     return 0;
10826
10827   vec_validate (mask, sizeof (*udp) - 1);
10828
10829   udp = (udp_header_t *) mask;
10830
10831 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10832   foreach_udp_proto_field;
10833 #undef _
10834
10835   *maskp = mask;
10836   return 1;
10837 }
10838
10839 uword
10840 unformat_l4_mask (unformat_input_t * input, va_list * args)
10841 {
10842   u8 **maskp = va_arg (*args, u8 **);
10843   u16 src_port = 0, dst_port = 0;
10844   tcpudp_header_t *tcpudp;
10845
10846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10847     {
10848       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10849         return 1;
10850       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10851         return 1;
10852       else if (unformat (input, "src_port"))
10853         src_port = 0xFFFF;
10854       else if (unformat (input, "dst_port"))
10855         dst_port = 0xFFFF;
10856       else
10857         return 0;
10858     }
10859
10860   if (!src_port && !dst_port)
10861     return 0;
10862
10863   u8 *mask = 0;
10864   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10865
10866   tcpudp = (tcpudp_header_t *) mask;
10867   tcpudp->src_port = src_port;
10868   tcpudp->dst_port = dst_port;
10869
10870   *maskp = mask;
10871
10872   return 1;
10873 }
10874
10875 uword
10876 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10877 {
10878   u8 **maskp = va_arg (*args, u8 **);
10879   u8 *mask = 0;
10880   u8 found_something = 0;
10881   ip4_header_t *ip;
10882
10883 #define _(a) u8 a=0;
10884   foreach_ip4_proto_field;
10885 #undef _
10886   u8 version = 0;
10887   u8 hdr_length = 0;
10888
10889
10890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10891     {
10892       if (unformat (input, "version"))
10893         version = 1;
10894       else if (unformat (input, "hdr_length"))
10895         hdr_length = 1;
10896       else if (unformat (input, "src"))
10897         src_address = 1;
10898       else if (unformat (input, "dst"))
10899         dst_address = 1;
10900       else if (unformat (input, "proto"))
10901         protocol = 1;
10902
10903 #define _(a) else if (unformat (input, #a)) a=1;
10904       foreach_ip4_proto_field
10905 #undef _
10906         else
10907         break;
10908     }
10909
10910 #define _(a) found_something += a;
10911   foreach_ip4_proto_field;
10912 #undef _
10913
10914   if (found_something == 0)
10915     return 0;
10916
10917   vec_validate (mask, sizeof (*ip) - 1);
10918
10919   ip = (ip4_header_t *) mask;
10920
10921 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10922   foreach_ip4_proto_field;
10923 #undef _
10924
10925   ip->ip_version_and_header_length = 0;
10926
10927   if (version)
10928     ip->ip_version_and_header_length |= 0xF0;
10929
10930   if (hdr_length)
10931     ip->ip_version_and_header_length |= 0x0F;
10932
10933   *maskp = mask;
10934   return 1;
10935 }
10936
10937 #define foreach_ip6_proto_field                 \
10938 _(src_address)                                  \
10939 _(dst_address)                                  \
10940 _(payload_length)                               \
10941 _(hop_limit)                                    \
10942 _(protocol)
10943
10944 uword
10945 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10946 {
10947   u8 **maskp = va_arg (*args, u8 **);
10948   u8 *mask = 0;
10949   u8 found_something = 0;
10950   ip6_header_t *ip;
10951   u32 ip_version_traffic_class_and_flow_label;
10952
10953 #define _(a) u8 a=0;
10954   foreach_ip6_proto_field;
10955 #undef _
10956   u8 version = 0;
10957   u8 traffic_class = 0;
10958   u8 flow_label = 0;
10959
10960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (input, "version"))
10963         version = 1;
10964       else if (unformat (input, "traffic-class"))
10965         traffic_class = 1;
10966       else if (unformat (input, "flow-label"))
10967         flow_label = 1;
10968       else if (unformat (input, "src"))
10969         src_address = 1;
10970       else if (unformat (input, "dst"))
10971         dst_address = 1;
10972       else if (unformat (input, "proto"))
10973         protocol = 1;
10974
10975 #define _(a) else if (unformat (input, #a)) a=1;
10976       foreach_ip6_proto_field
10977 #undef _
10978         else
10979         break;
10980     }
10981
10982 #define _(a) found_something += a;
10983   foreach_ip6_proto_field;
10984 #undef _
10985
10986   if (found_something == 0)
10987     return 0;
10988
10989   vec_validate (mask, sizeof (*ip) - 1);
10990
10991   ip = (ip6_header_t *) mask;
10992
10993 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10994   foreach_ip6_proto_field;
10995 #undef _
10996
10997   ip_version_traffic_class_and_flow_label = 0;
10998
10999   if (version)
11000     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11001
11002   if (traffic_class)
11003     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11004
11005   if (flow_label)
11006     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11007
11008   ip->ip_version_traffic_class_and_flow_label =
11009     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11010
11011   *maskp = mask;
11012   return 1;
11013 }
11014
11015 uword
11016 unformat_l3_mask (unformat_input_t * input, va_list * args)
11017 {
11018   u8 **maskp = va_arg (*args, u8 **);
11019
11020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11021     {
11022       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11023         return 1;
11024       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11025         return 1;
11026       else
11027         break;
11028     }
11029   return 0;
11030 }
11031
11032 uword
11033 unformat_l2_mask (unformat_input_t * input, va_list * args)
11034 {
11035   u8 **maskp = va_arg (*args, u8 **);
11036   u8 *mask = 0;
11037   u8 src = 0;
11038   u8 dst = 0;
11039   u8 proto = 0;
11040   u8 tag1 = 0;
11041   u8 tag2 = 0;
11042   u8 ignore_tag1 = 0;
11043   u8 ignore_tag2 = 0;
11044   u8 cos1 = 0;
11045   u8 cos2 = 0;
11046   u8 dot1q = 0;
11047   u8 dot1ad = 0;
11048   int len = 14;
11049
11050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11051     {
11052       if (unformat (input, "src"))
11053         src = 1;
11054       else if (unformat (input, "dst"))
11055         dst = 1;
11056       else if (unformat (input, "proto"))
11057         proto = 1;
11058       else if (unformat (input, "tag1"))
11059         tag1 = 1;
11060       else if (unformat (input, "tag2"))
11061         tag2 = 1;
11062       else if (unformat (input, "ignore-tag1"))
11063         ignore_tag1 = 1;
11064       else if (unformat (input, "ignore-tag2"))
11065         ignore_tag2 = 1;
11066       else if (unformat (input, "cos1"))
11067         cos1 = 1;
11068       else if (unformat (input, "cos2"))
11069         cos2 = 1;
11070       else if (unformat (input, "dot1q"))
11071         dot1q = 1;
11072       else if (unformat (input, "dot1ad"))
11073         dot1ad = 1;
11074       else
11075         break;
11076     }
11077   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11078        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11079     return 0;
11080
11081   if (tag1 || ignore_tag1 || cos1 || dot1q)
11082     len = 18;
11083   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11084     len = 22;
11085
11086   vec_validate (mask, len - 1);
11087
11088   if (dst)
11089     clib_memset (mask, 0xff, 6);
11090
11091   if (src)
11092     clib_memset (mask + 6, 0xff, 6);
11093
11094   if (tag2 || dot1ad)
11095     {
11096       /* inner vlan tag */
11097       if (tag2)
11098         {
11099           mask[19] = 0xff;
11100           mask[18] = 0x0f;
11101         }
11102       if (cos2)
11103         mask[18] |= 0xe0;
11104       if (proto)
11105         mask[21] = mask[20] = 0xff;
11106       if (tag1)
11107         {
11108           mask[15] = 0xff;
11109           mask[14] = 0x0f;
11110         }
11111       if (cos1)
11112         mask[14] |= 0xe0;
11113       *maskp = mask;
11114       return 1;
11115     }
11116   if (tag1 | dot1q)
11117     {
11118       if (tag1)
11119         {
11120           mask[15] = 0xff;
11121           mask[14] = 0x0f;
11122         }
11123       if (cos1)
11124         mask[14] |= 0xe0;
11125       if (proto)
11126         mask[16] = mask[17] = 0xff;
11127
11128       *maskp = mask;
11129       return 1;
11130     }
11131   if (cos2)
11132     mask[18] |= 0xe0;
11133   if (cos1)
11134     mask[14] |= 0xe0;
11135   if (proto)
11136     mask[12] = mask[13] = 0xff;
11137
11138   *maskp = mask;
11139   return 1;
11140 }
11141
11142 uword
11143 unformat_classify_mask (unformat_input_t * input, va_list * args)
11144 {
11145   u8 **maskp = va_arg (*args, u8 **);
11146   u32 *skipp = va_arg (*args, u32 *);
11147   u32 *matchp = va_arg (*args, u32 *);
11148   u32 match;
11149   u8 *mask = 0;
11150   u8 *l2 = 0;
11151   u8 *l3 = 0;
11152   u8 *l4 = 0;
11153   int i;
11154
11155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11156     {
11157       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11158         ;
11159       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11160         ;
11161       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11162         ;
11163       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11164         ;
11165       else
11166         break;
11167     }
11168
11169   if (l4 && !l3)
11170     {
11171       vec_free (mask);
11172       vec_free (l2);
11173       vec_free (l4);
11174       return 0;
11175     }
11176
11177   if (mask || l2 || l3 || l4)
11178     {
11179       if (l2 || l3 || l4)
11180         {
11181           /* "With a free Ethernet header in every package" */
11182           if (l2 == 0)
11183             vec_validate (l2, 13);
11184           mask = l2;
11185           if (vec_len (l3))
11186             {
11187               vec_append (mask, l3);
11188               vec_free (l3);
11189             }
11190           if (vec_len (l4))
11191             {
11192               vec_append (mask, l4);
11193               vec_free (l4);
11194             }
11195         }
11196
11197       /* Scan forward looking for the first significant mask octet */
11198       for (i = 0; i < vec_len (mask); i++)
11199         if (mask[i])
11200           break;
11201
11202       /* compute (skip, match) params */
11203       *skipp = i / sizeof (u32x4);
11204       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11205
11206       /* Pad mask to an even multiple of the vector size */
11207       while (vec_len (mask) % sizeof (u32x4))
11208         vec_add1 (mask, 0);
11209
11210       match = vec_len (mask) / sizeof (u32x4);
11211
11212       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11213         {
11214           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11215           if (*tmp || *(tmp + 1))
11216             break;
11217           match--;
11218         }
11219       if (match == 0)
11220         clib_warning ("BUG: match 0");
11221
11222       _vec_len (mask) = match * sizeof (u32x4);
11223
11224       *matchp = match;
11225       *maskp = mask;
11226
11227       return 1;
11228     }
11229
11230   return 0;
11231 }
11232 #endif /* VPP_API_TEST_BUILTIN */
11233
11234 #define foreach_l2_next                         \
11235 _(drop, DROP)                                   \
11236 _(ethernet, ETHERNET_INPUT)                     \
11237 _(ip4, IP4_INPUT)                               \
11238 _(ip6, IP6_INPUT)
11239
11240 uword
11241 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11242 {
11243   u32 *miss_next_indexp = va_arg (*args, u32 *);
11244   u32 next_index = 0;
11245   u32 tmp;
11246
11247 #define _(n,N) \
11248   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11249   foreach_l2_next;
11250 #undef _
11251
11252   if (unformat (input, "%d", &tmp))
11253     {
11254       next_index = tmp;
11255       goto out;
11256     }
11257
11258   return 0;
11259
11260 out:
11261   *miss_next_indexp = next_index;
11262   return 1;
11263 }
11264
11265 #define foreach_ip_next                         \
11266 _(drop, DROP)                                   \
11267 _(local, LOCAL)                                 \
11268 _(rewrite, REWRITE)
11269
11270 uword
11271 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11272 {
11273   u32 *miss_next_indexp = va_arg (*args, u32 *);
11274   u32 next_index = 0;
11275   u32 tmp;
11276
11277 #define _(n,N) \
11278   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11279   foreach_ip_next;
11280 #undef _
11281
11282   if (unformat (input, "%d", &tmp))
11283     {
11284       next_index = tmp;
11285       goto out;
11286     }
11287
11288   return 0;
11289
11290 out:
11291   *miss_next_indexp = next_index;
11292   return 1;
11293 }
11294
11295 #define foreach_acl_next                        \
11296 _(deny, DENY)
11297
11298 uword
11299 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11300 {
11301   u32 *miss_next_indexp = va_arg (*args, u32 *);
11302   u32 next_index = 0;
11303   u32 tmp;
11304
11305 #define _(n,N) \
11306   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11307   foreach_acl_next;
11308 #undef _
11309
11310   if (unformat (input, "permit"))
11311     {
11312       next_index = ~0;
11313       goto out;
11314     }
11315   else if (unformat (input, "%d", &tmp))
11316     {
11317       next_index = tmp;
11318       goto out;
11319     }
11320
11321   return 0;
11322
11323 out:
11324   *miss_next_indexp = next_index;
11325   return 1;
11326 }
11327
11328 uword
11329 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11330 {
11331   u32 *r = va_arg (*args, u32 *);
11332
11333   if (unformat (input, "conform-color"))
11334     *r = POLICE_CONFORM;
11335   else if (unformat (input, "exceed-color"))
11336     *r = POLICE_EXCEED;
11337   else
11338     return 0;
11339
11340   return 1;
11341 }
11342
11343 static int
11344 api_classify_add_del_table (vat_main_t * vam)
11345 {
11346   unformat_input_t *i = vam->input;
11347   vl_api_classify_add_del_table_t *mp;
11348
11349   u32 nbuckets = 2;
11350   u32 skip = ~0;
11351   u32 match = ~0;
11352   int is_add = 1;
11353   int del_chain = 0;
11354   u32 table_index = ~0;
11355   u32 next_table_index = ~0;
11356   u32 miss_next_index = ~0;
11357   u32 memory_size = 32 << 20;
11358   u8 *mask = 0;
11359   u32 current_data_flag = 0;
11360   int current_data_offset = 0;
11361   int ret;
11362
11363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11364     {
11365       if (unformat (i, "del"))
11366         is_add = 0;
11367       else if (unformat (i, "del-chain"))
11368         {
11369           is_add = 0;
11370           del_chain = 1;
11371         }
11372       else if (unformat (i, "buckets %d", &nbuckets))
11373         ;
11374       else if (unformat (i, "memory_size %d", &memory_size))
11375         ;
11376       else if (unformat (i, "skip %d", &skip))
11377         ;
11378       else if (unformat (i, "match %d", &match))
11379         ;
11380       else if (unformat (i, "table %d", &table_index))
11381         ;
11382       else if (unformat (i, "mask %U", unformat_classify_mask,
11383                          &mask, &skip, &match))
11384         ;
11385       else if (unformat (i, "next-table %d", &next_table_index))
11386         ;
11387       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11388                          &miss_next_index))
11389         ;
11390       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11391                          &miss_next_index))
11392         ;
11393       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11394                          &miss_next_index))
11395         ;
11396       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11397         ;
11398       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11399         ;
11400       else
11401         break;
11402     }
11403
11404   if (is_add && mask == 0)
11405     {
11406       errmsg ("Mask required");
11407       return -99;
11408     }
11409
11410   if (is_add && skip == ~0)
11411     {
11412       errmsg ("skip count required");
11413       return -99;
11414     }
11415
11416   if (is_add && match == ~0)
11417     {
11418       errmsg ("match count required");
11419       return -99;
11420     }
11421
11422   if (!is_add && table_index == ~0)
11423     {
11424       errmsg ("table index required for delete");
11425       return -99;
11426     }
11427
11428   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11429
11430   mp->is_add = is_add;
11431   mp->del_chain = del_chain;
11432   mp->table_index = ntohl (table_index);
11433   mp->nbuckets = ntohl (nbuckets);
11434   mp->memory_size = ntohl (memory_size);
11435   mp->skip_n_vectors = ntohl (skip);
11436   mp->match_n_vectors = ntohl (match);
11437   mp->next_table_index = ntohl (next_table_index);
11438   mp->miss_next_index = ntohl (miss_next_index);
11439   mp->current_data_flag = ntohl (current_data_flag);
11440   mp->current_data_offset = ntohl (current_data_offset);
11441   mp->mask_len = ntohl (vec_len (mask));
11442   clib_memcpy (mp->mask, mask, vec_len (mask));
11443
11444   vec_free (mask);
11445
11446   S (mp);
11447   W (ret);
11448   return ret;
11449 }
11450
11451 #if VPP_API_TEST_BUILTIN == 0
11452 uword
11453 unformat_l4_match (unformat_input_t * input, va_list * args)
11454 {
11455   u8 **matchp = va_arg (*args, u8 **);
11456
11457   u8 *proto_header = 0;
11458   int src_port = 0;
11459   int dst_port = 0;
11460
11461   tcpudp_header_t h;
11462
11463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11464     {
11465       if (unformat (input, "src_port %d", &src_port))
11466         ;
11467       else if (unformat (input, "dst_port %d", &dst_port))
11468         ;
11469       else
11470         return 0;
11471     }
11472
11473   h.src_port = clib_host_to_net_u16 (src_port);
11474   h.dst_port = clib_host_to_net_u16 (dst_port);
11475   vec_validate (proto_header, sizeof (h) - 1);
11476   memcpy (proto_header, &h, sizeof (h));
11477
11478   *matchp = proto_header;
11479
11480   return 1;
11481 }
11482
11483 uword
11484 unformat_ip4_match (unformat_input_t * input, va_list * args)
11485 {
11486   u8 **matchp = va_arg (*args, u8 **);
11487   u8 *match = 0;
11488   ip4_header_t *ip;
11489   int version = 0;
11490   u32 version_val;
11491   int hdr_length = 0;
11492   u32 hdr_length_val;
11493   int src = 0, dst = 0;
11494   ip4_address_t src_val, dst_val;
11495   int proto = 0;
11496   u32 proto_val;
11497   int tos = 0;
11498   u32 tos_val;
11499   int length = 0;
11500   u32 length_val;
11501   int fragment_id = 0;
11502   u32 fragment_id_val;
11503   int ttl = 0;
11504   int ttl_val;
11505   int checksum = 0;
11506   u32 checksum_val;
11507
11508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11509     {
11510       if (unformat (input, "version %d", &version_val))
11511         version = 1;
11512       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11513         hdr_length = 1;
11514       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11515         src = 1;
11516       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11517         dst = 1;
11518       else if (unformat (input, "proto %d", &proto_val))
11519         proto = 1;
11520       else if (unformat (input, "tos %d", &tos_val))
11521         tos = 1;
11522       else if (unformat (input, "length %d", &length_val))
11523         length = 1;
11524       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11525         fragment_id = 1;
11526       else if (unformat (input, "ttl %d", &ttl_val))
11527         ttl = 1;
11528       else if (unformat (input, "checksum %d", &checksum_val))
11529         checksum = 1;
11530       else
11531         break;
11532     }
11533
11534   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11535       + ttl + checksum == 0)
11536     return 0;
11537
11538   /*
11539    * Aligned because we use the real comparison functions
11540    */
11541   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11542
11543   ip = (ip4_header_t *) match;
11544
11545   /* These are realistically matched in practice */
11546   if (src)
11547     ip->src_address.as_u32 = src_val.as_u32;
11548
11549   if (dst)
11550     ip->dst_address.as_u32 = dst_val.as_u32;
11551
11552   if (proto)
11553     ip->protocol = proto_val;
11554
11555
11556   /* These are not, but they're included for completeness */
11557   if (version)
11558     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11559
11560   if (hdr_length)
11561     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11562
11563   if (tos)
11564     ip->tos = tos_val;
11565
11566   if (length)
11567     ip->length = clib_host_to_net_u16 (length_val);
11568
11569   if (ttl)
11570     ip->ttl = ttl_val;
11571
11572   if (checksum)
11573     ip->checksum = clib_host_to_net_u16 (checksum_val);
11574
11575   *matchp = match;
11576   return 1;
11577 }
11578
11579 uword
11580 unformat_ip6_match (unformat_input_t * input, va_list * args)
11581 {
11582   u8 **matchp = va_arg (*args, u8 **);
11583   u8 *match = 0;
11584   ip6_header_t *ip;
11585   int version = 0;
11586   u32 version_val;
11587   u8 traffic_class = 0;
11588   u32 traffic_class_val = 0;
11589   u8 flow_label = 0;
11590   u8 flow_label_val;
11591   int src = 0, dst = 0;
11592   ip6_address_t src_val, dst_val;
11593   int proto = 0;
11594   u32 proto_val;
11595   int payload_length = 0;
11596   u32 payload_length_val;
11597   int hop_limit = 0;
11598   int hop_limit_val;
11599   u32 ip_version_traffic_class_and_flow_label;
11600
11601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11602     {
11603       if (unformat (input, "version %d", &version_val))
11604         version = 1;
11605       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11606         traffic_class = 1;
11607       else if (unformat (input, "flow_label %d", &flow_label_val))
11608         flow_label = 1;
11609       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11610         src = 1;
11611       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11612         dst = 1;
11613       else if (unformat (input, "proto %d", &proto_val))
11614         proto = 1;
11615       else if (unformat (input, "payload_length %d", &payload_length_val))
11616         payload_length = 1;
11617       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11618         hop_limit = 1;
11619       else
11620         break;
11621     }
11622
11623   if (version + traffic_class + flow_label + src + dst + proto +
11624       payload_length + hop_limit == 0)
11625     return 0;
11626
11627   /*
11628    * Aligned because we use the real comparison functions
11629    */
11630   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11631
11632   ip = (ip6_header_t *) match;
11633
11634   if (src)
11635     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11636
11637   if (dst)
11638     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11639
11640   if (proto)
11641     ip->protocol = proto_val;
11642
11643   ip_version_traffic_class_and_flow_label = 0;
11644
11645   if (version)
11646     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11647
11648   if (traffic_class)
11649     ip_version_traffic_class_and_flow_label |=
11650       (traffic_class_val & 0xFF) << 20;
11651
11652   if (flow_label)
11653     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11654
11655   ip->ip_version_traffic_class_and_flow_label =
11656     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11657
11658   if (payload_length)
11659     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11660
11661   if (hop_limit)
11662     ip->hop_limit = hop_limit_val;
11663
11664   *matchp = match;
11665   return 1;
11666 }
11667
11668 uword
11669 unformat_l3_match (unformat_input_t * input, va_list * args)
11670 {
11671   u8 **matchp = va_arg (*args, u8 **);
11672
11673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11674     {
11675       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11676         return 1;
11677       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11678         return 1;
11679       else
11680         break;
11681     }
11682   return 0;
11683 }
11684
11685 uword
11686 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11687 {
11688   u8 *tagp = va_arg (*args, u8 *);
11689   u32 tag;
11690
11691   if (unformat (input, "%d", &tag))
11692     {
11693       tagp[0] = (tag >> 8) & 0x0F;
11694       tagp[1] = tag & 0xFF;
11695       return 1;
11696     }
11697
11698   return 0;
11699 }
11700
11701 uword
11702 unformat_l2_match (unformat_input_t * input, va_list * args)
11703 {
11704   u8 **matchp = va_arg (*args, u8 **);
11705   u8 *match = 0;
11706   u8 src = 0;
11707   u8 src_val[6];
11708   u8 dst = 0;
11709   u8 dst_val[6];
11710   u8 proto = 0;
11711   u16 proto_val;
11712   u8 tag1 = 0;
11713   u8 tag1_val[2];
11714   u8 tag2 = 0;
11715   u8 tag2_val[2];
11716   int len = 14;
11717   u8 ignore_tag1 = 0;
11718   u8 ignore_tag2 = 0;
11719   u8 cos1 = 0;
11720   u8 cos2 = 0;
11721   u32 cos1_val = 0;
11722   u32 cos2_val = 0;
11723
11724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11725     {
11726       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11727         src = 1;
11728       else
11729         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11730         dst = 1;
11731       else if (unformat (input, "proto %U",
11732                          unformat_ethernet_type_host_byte_order, &proto_val))
11733         proto = 1;
11734       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11735         tag1 = 1;
11736       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11737         tag2 = 1;
11738       else if (unformat (input, "ignore-tag1"))
11739         ignore_tag1 = 1;
11740       else if (unformat (input, "ignore-tag2"))
11741         ignore_tag2 = 1;
11742       else if (unformat (input, "cos1 %d", &cos1_val))
11743         cos1 = 1;
11744       else if (unformat (input, "cos2 %d", &cos2_val))
11745         cos2 = 1;
11746       else
11747         break;
11748     }
11749   if ((src + dst + proto + tag1 + tag2 +
11750        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11751     return 0;
11752
11753   if (tag1 || ignore_tag1 || cos1)
11754     len = 18;
11755   if (tag2 || ignore_tag2 || cos2)
11756     len = 22;
11757
11758   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11759
11760   if (dst)
11761     clib_memcpy (match, dst_val, 6);
11762
11763   if (src)
11764     clib_memcpy (match + 6, src_val, 6);
11765
11766   if (tag2)
11767     {
11768       /* inner vlan tag */
11769       match[19] = tag2_val[1];
11770       match[18] = tag2_val[0];
11771       if (cos2)
11772         match[18] |= (cos2_val & 0x7) << 5;
11773       if (proto)
11774         {
11775           match[21] = proto_val & 0xff;
11776           match[20] = proto_val >> 8;
11777         }
11778       if (tag1)
11779         {
11780           match[15] = tag1_val[1];
11781           match[14] = tag1_val[0];
11782         }
11783       if (cos1)
11784         match[14] |= (cos1_val & 0x7) << 5;
11785       *matchp = match;
11786       return 1;
11787     }
11788   if (tag1)
11789     {
11790       match[15] = tag1_val[1];
11791       match[14] = tag1_val[0];
11792       if (proto)
11793         {
11794           match[17] = proto_val & 0xff;
11795           match[16] = proto_val >> 8;
11796         }
11797       if (cos1)
11798         match[14] |= (cos1_val & 0x7) << 5;
11799
11800       *matchp = match;
11801       return 1;
11802     }
11803   if (cos2)
11804     match[18] |= (cos2_val & 0x7) << 5;
11805   if (cos1)
11806     match[14] |= (cos1_val & 0x7) << 5;
11807   if (proto)
11808     {
11809       match[13] = proto_val & 0xff;
11810       match[12] = proto_val >> 8;
11811     }
11812
11813   *matchp = match;
11814   return 1;
11815 }
11816
11817 uword
11818 unformat_qos_source (unformat_input_t * input, va_list * args)
11819 {
11820   int *qs = va_arg (*args, int *);
11821
11822   if (unformat (input, "ip"))
11823     *qs = QOS_SOURCE_IP;
11824   else if (unformat (input, "mpls"))
11825     *qs = QOS_SOURCE_MPLS;
11826   else if (unformat (input, "ext"))
11827     *qs = QOS_SOURCE_EXT;
11828   else if (unformat (input, "vlan"))
11829     *qs = QOS_SOURCE_VLAN;
11830   else
11831     return 0;
11832
11833   return 1;
11834 }
11835 #endif
11836
11837 uword
11838 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11839 {
11840   u8 **matchp = va_arg (*args, u8 **);
11841   u32 skip_n_vectors = va_arg (*args, u32);
11842   u32 match_n_vectors = va_arg (*args, u32);
11843
11844   u8 *match = 0;
11845   u8 *l2 = 0;
11846   u8 *l3 = 0;
11847   u8 *l4 = 0;
11848
11849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11850     {
11851       if (unformat (input, "hex %U", unformat_hex_string, &match))
11852         ;
11853       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11854         ;
11855       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11856         ;
11857       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11858         ;
11859       else
11860         break;
11861     }
11862
11863   if (l4 && !l3)
11864     {
11865       vec_free (match);
11866       vec_free (l2);
11867       vec_free (l4);
11868       return 0;
11869     }
11870
11871   if (match || l2 || l3 || l4)
11872     {
11873       if (l2 || l3 || l4)
11874         {
11875           /* "Win a free Ethernet header in every packet" */
11876           if (l2 == 0)
11877             vec_validate_aligned (l2, 13, sizeof (u32x4));
11878           match = l2;
11879           if (vec_len (l3))
11880             {
11881               vec_append_aligned (match, l3, sizeof (u32x4));
11882               vec_free (l3);
11883             }
11884           if (vec_len (l4))
11885             {
11886               vec_append_aligned (match, l4, sizeof (u32x4));
11887               vec_free (l4);
11888             }
11889         }
11890
11891       /* Make sure the vector is big enough even if key is all 0's */
11892       vec_validate_aligned
11893         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11894          sizeof (u32x4));
11895
11896       /* Set size, include skipped vectors */
11897       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11898
11899       *matchp = match;
11900
11901       return 1;
11902     }
11903
11904   return 0;
11905 }
11906
11907 static int
11908 api_classify_add_del_session (vat_main_t * vam)
11909 {
11910   unformat_input_t *i = vam->input;
11911   vl_api_classify_add_del_session_t *mp;
11912   int is_add = 1;
11913   u32 table_index = ~0;
11914   u32 hit_next_index = ~0;
11915   u32 opaque_index = ~0;
11916   u8 *match = 0;
11917   i32 advance = 0;
11918   u32 skip_n_vectors = 0;
11919   u32 match_n_vectors = 0;
11920   u32 action = 0;
11921   u32 metadata = 0;
11922   int ret;
11923
11924   /*
11925    * Warning: you have to supply skip_n and match_n
11926    * because the API client cant simply look at the classify
11927    * table object.
11928    */
11929
11930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11931     {
11932       if (unformat (i, "del"))
11933         is_add = 0;
11934       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11935                          &hit_next_index))
11936         ;
11937       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11938                          &hit_next_index))
11939         ;
11940       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11941                          &hit_next_index))
11942         ;
11943       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11944         ;
11945       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11946         ;
11947       else if (unformat (i, "opaque-index %d", &opaque_index))
11948         ;
11949       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11950         ;
11951       else if (unformat (i, "match_n %d", &match_n_vectors))
11952         ;
11953       else if (unformat (i, "match %U", api_unformat_classify_match,
11954                          &match, skip_n_vectors, match_n_vectors))
11955         ;
11956       else if (unformat (i, "advance %d", &advance))
11957         ;
11958       else if (unformat (i, "table-index %d", &table_index))
11959         ;
11960       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11961         action = 1;
11962       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11963         action = 2;
11964       else if (unformat (i, "action %d", &action))
11965         ;
11966       else if (unformat (i, "metadata %d", &metadata))
11967         ;
11968       else
11969         break;
11970     }
11971
11972   if (table_index == ~0)
11973     {
11974       errmsg ("Table index required");
11975       return -99;
11976     }
11977
11978   if (is_add && match == 0)
11979     {
11980       errmsg ("Match value required");
11981       return -99;
11982     }
11983
11984   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11985
11986   mp->is_add = is_add;
11987   mp->table_index = ntohl (table_index);
11988   mp->hit_next_index = ntohl (hit_next_index);
11989   mp->opaque_index = ntohl (opaque_index);
11990   mp->advance = ntohl (advance);
11991   mp->action = action;
11992   mp->metadata = ntohl (metadata);
11993   mp->match_len = ntohl (vec_len (match));
11994   clib_memcpy (mp->match, match, vec_len (match));
11995   vec_free (match);
11996
11997   S (mp);
11998   W (ret);
11999   return ret;
12000 }
12001
12002 static int
12003 api_classify_set_interface_ip_table (vat_main_t * vam)
12004 {
12005   unformat_input_t *i = vam->input;
12006   vl_api_classify_set_interface_ip_table_t *mp;
12007   u32 sw_if_index;
12008   int sw_if_index_set;
12009   u32 table_index = ~0;
12010   u8 is_ipv6 = 0;
12011   int ret;
12012
12013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12014     {
12015       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12016         sw_if_index_set = 1;
12017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12018         sw_if_index_set = 1;
12019       else if (unformat (i, "table %d", &table_index))
12020         ;
12021       else
12022         {
12023           clib_warning ("parse error '%U'", format_unformat_error, i);
12024           return -99;
12025         }
12026     }
12027
12028   if (sw_if_index_set == 0)
12029     {
12030       errmsg ("missing interface name or sw_if_index");
12031       return -99;
12032     }
12033
12034
12035   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12036
12037   mp->sw_if_index = ntohl (sw_if_index);
12038   mp->table_index = ntohl (table_index);
12039   mp->is_ipv6 = is_ipv6;
12040
12041   S (mp);
12042   W (ret);
12043   return ret;
12044 }
12045
12046 static int
12047 api_classify_set_interface_l2_tables (vat_main_t * vam)
12048 {
12049   unformat_input_t *i = vam->input;
12050   vl_api_classify_set_interface_l2_tables_t *mp;
12051   u32 sw_if_index;
12052   int sw_if_index_set;
12053   u32 ip4_table_index = ~0;
12054   u32 ip6_table_index = ~0;
12055   u32 other_table_index = ~0;
12056   u32 is_input = 1;
12057   int ret;
12058
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12062         sw_if_index_set = 1;
12063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12064         sw_if_index_set = 1;
12065       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12066         ;
12067       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12068         ;
12069       else if (unformat (i, "other-table %d", &other_table_index))
12070         ;
12071       else if (unformat (i, "is-input %d", &is_input))
12072         ;
12073       else
12074         {
12075           clib_warning ("parse error '%U'", format_unformat_error, i);
12076           return -99;
12077         }
12078     }
12079
12080   if (sw_if_index_set == 0)
12081     {
12082       errmsg ("missing interface name or sw_if_index");
12083       return -99;
12084     }
12085
12086
12087   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12088
12089   mp->sw_if_index = ntohl (sw_if_index);
12090   mp->ip4_table_index = ntohl (ip4_table_index);
12091   mp->ip6_table_index = ntohl (ip6_table_index);
12092   mp->other_table_index = ntohl (other_table_index);
12093   mp->is_input = (u8) is_input;
12094
12095   S (mp);
12096   W (ret);
12097   return ret;
12098 }
12099
12100 static int
12101 api_set_ipfix_exporter (vat_main_t * vam)
12102 {
12103   unformat_input_t *i = vam->input;
12104   vl_api_set_ipfix_exporter_t *mp;
12105   ip4_address_t collector_address;
12106   u8 collector_address_set = 0;
12107   u32 collector_port = ~0;
12108   ip4_address_t src_address;
12109   u8 src_address_set = 0;
12110   u32 vrf_id = ~0;
12111   u32 path_mtu = ~0;
12112   u32 template_interval = ~0;
12113   u8 udp_checksum = 0;
12114   int ret;
12115
12116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12117     {
12118       if (unformat (i, "collector_address %U", unformat_ip4_address,
12119                     &collector_address))
12120         collector_address_set = 1;
12121       else if (unformat (i, "collector_port %d", &collector_port))
12122         ;
12123       else if (unformat (i, "src_address %U", unformat_ip4_address,
12124                          &src_address))
12125         src_address_set = 1;
12126       else if (unformat (i, "vrf_id %d", &vrf_id))
12127         ;
12128       else if (unformat (i, "path_mtu %d", &path_mtu))
12129         ;
12130       else if (unformat (i, "template_interval %d", &template_interval))
12131         ;
12132       else if (unformat (i, "udp_checksum"))
12133         udp_checksum = 1;
12134       else
12135         break;
12136     }
12137
12138   if (collector_address_set == 0)
12139     {
12140       errmsg ("collector_address required");
12141       return -99;
12142     }
12143
12144   if (src_address_set == 0)
12145     {
12146       errmsg ("src_address required");
12147       return -99;
12148     }
12149
12150   M (SET_IPFIX_EXPORTER, mp);
12151
12152   memcpy (mp->collector_address, collector_address.data,
12153           sizeof (collector_address.data));
12154   mp->collector_port = htons ((u16) collector_port);
12155   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12156   mp->vrf_id = htonl (vrf_id);
12157   mp->path_mtu = htonl (path_mtu);
12158   mp->template_interval = htonl (template_interval);
12159   mp->udp_checksum = udp_checksum;
12160
12161   S (mp);
12162   W (ret);
12163   return ret;
12164 }
12165
12166 static int
12167 api_set_ipfix_classify_stream (vat_main_t * vam)
12168 {
12169   unformat_input_t *i = vam->input;
12170   vl_api_set_ipfix_classify_stream_t *mp;
12171   u32 domain_id = 0;
12172   u32 src_port = UDP_DST_PORT_ipfix;
12173   int ret;
12174
12175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12176     {
12177       if (unformat (i, "domain %d", &domain_id))
12178         ;
12179       else if (unformat (i, "src_port %d", &src_port))
12180         ;
12181       else
12182         {
12183           errmsg ("unknown input `%U'", format_unformat_error, i);
12184           return -99;
12185         }
12186     }
12187
12188   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12189
12190   mp->domain_id = htonl (domain_id);
12191   mp->src_port = htons ((u16) src_port);
12192
12193   S (mp);
12194   W (ret);
12195   return ret;
12196 }
12197
12198 static int
12199 api_ipfix_classify_table_add_del (vat_main_t * vam)
12200 {
12201   unformat_input_t *i = vam->input;
12202   vl_api_ipfix_classify_table_add_del_t *mp;
12203   int is_add = -1;
12204   u32 classify_table_index = ~0;
12205   u8 ip_version = 0;
12206   u8 transport_protocol = 255;
12207   int ret;
12208
12209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12210     {
12211       if (unformat (i, "add"))
12212         is_add = 1;
12213       else if (unformat (i, "del"))
12214         is_add = 0;
12215       else if (unformat (i, "table %d", &classify_table_index))
12216         ;
12217       else if (unformat (i, "ip4"))
12218         ip_version = 4;
12219       else if (unformat (i, "ip6"))
12220         ip_version = 6;
12221       else if (unformat (i, "tcp"))
12222         transport_protocol = 6;
12223       else if (unformat (i, "udp"))
12224         transport_protocol = 17;
12225       else
12226         {
12227           errmsg ("unknown input `%U'", format_unformat_error, i);
12228           return -99;
12229         }
12230     }
12231
12232   if (is_add == -1)
12233     {
12234       errmsg ("expecting: add|del");
12235       return -99;
12236     }
12237   if (classify_table_index == ~0)
12238     {
12239       errmsg ("classifier table not specified");
12240       return -99;
12241     }
12242   if (ip_version == 0)
12243     {
12244       errmsg ("IP version not specified");
12245       return -99;
12246     }
12247
12248   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12249
12250   mp->is_add = is_add;
12251   mp->table_id = htonl (classify_table_index);
12252   mp->ip_version = ip_version;
12253   mp->transport_protocol = transport_protocol;
12254
12255   S (mp);
12256   W (ret);
12257   return ret;
12258 }
12259
12260 static int
12261 api_get_node_index (vat_main_t * vam)
12262 {
12263   unformat_input_t *i = vam->input;
12264   vl_api_get_node_index_t *mp;
12265   u8 *name = 0;
12266   int ret;
12267
12268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12269     {
12270       if (unformat (i, "node %s", &name))
12271         ;
12272       else
12273         break;
12274     }
12275   if (name == 0)
12276     {
12277       errmsg ("node name required");
12278       return -99;
12279     }
12280   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12281     {
12282       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12283       return -99;
12284     }
12285
12286   M (GET_NODE_INDEX, mp);
12287   clib_memcpy (mp->node_name, name, vec_len (name));
12288   vec_free (name);
12289
12290   S (mp);
12291   W (ret);
12292   return ret;
12293 }
12294
12295 static int
12296 api_get_next_index (vat_main_t * vam)
12297 {
12298   unformat_input_t *i = vam->input;
12299   vl_api_get_next_index_t *mp;
12300   u8 *node_name = 0, *next_node_name = 0;
12301   int ret;
12302
12303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (i, "node-name %s", &node_name))
12306         ;
12307       else if (unformat (i, "next-node-name %s", &next_node_name))
12308         break;
12309     }
12310
12311   if (node_name == 0)
12312     {
12313       errmsg ("node name required");
12314       return -99;
12315     }
12316   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12317     {
12318       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12319       return -99;
12320     }
12321
12322   if (next_node_name == 0)
12323     {
12324       errmsg ("next node name required");
12325       return -99;
12326     }
12327   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12328     {
12329       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12330       return -99;
12331     }
12332
12333   M (GET_NEXT_INDEX, mp);
12334   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12335   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12336   vec_free (node_name);
12337   vec_free (next_node_name);
12338
12339   S (mp);
12340   W (ret);
12341   return ret;
12342 }
12343
12344 static int
12345 api_add_node_next (vat_main_t * vam)
12346 {
12347   unformat_input_t *i = vam->input;
12348   vl_api_add_node_next_t *mp;
12349   u8 *name = 0;
12350   u8 *next = 0;
12351   int ret;
12352
12353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12354     {
12355       if (unformat (i, "node %s", &name))
12356         ;
12357       else if (unformat (i, "next %s", &next))
12358         ;
12359       else
12360         break;
12361     }
12362   if (name == 0)
12363     {
12364       errmsg ("node name required");
12365       return -99;
12366     }
12367   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12368     {
12369       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12370       return -99;
12371     }
12372   if (next == 0)
12373     {
12374       errmsg ("next node required");
12375       return -99;
12376     }
12377   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12378     {
12379       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12380       return -99;
12381     }
12382
12383   M (ADD_NODE_NEXT, mp);
12384   clib_memcpy (mp->node_name, name, vec_len (name));
12385   clib_memcpy (mp->next_name, next, vec_len (next));
12386   vec_free (name);
12387   vec_free (next);
12388
12389   S (mp);
12390   W (ret);
12391   return ret;
12392 }
12393
12394 static int
12395 api_l2tpv3_create_tunnel (vat_main_t * vam)
12396 {
12397   unformat_input_t *i = vam->input;
12398   ip6_address_t client_address, our_address;
12399   int client_address_set = 0;
12400   int our_address_set = 0;
12401   u32 local_session_id = 0;
12402   u32 remote_session_id = 0;
12403   u64 local_cookie = 0;
12404   u64 remote_cookie = 0;
12405   u8 l2_sublayer_present = 0;
12406   vl_api_l2tpv3_create_tunnel_t *mp;
12407   int ret;
12408
12409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12410     {
12411       if (unformat (i, "client_address %U", unformat_ip6_address,
12412                     &client_address))
12413         client_address_set = 1;
12414       else if (unformat (i, "our_address %U", unformat_ip6_address,
12415                          &our_address))
12416         our_address_set = 1;
12417       else if (unformat (i, "local_session_id %d", &local_session_id))
12418         ;
12419       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12420         ;
12421       else if (unformat (i, "local_cookie %lld", &local_cookie))
12422         ;
12423       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12424         ;
12425       else if (unformat (i, "l2-sublayer-present"))
12426         l2_sublayer_present = 1;
12427       else
12428         break;
12429     }
12430
12431   if (client_address_set == 0)
12432     {
12433       errmsg ("client_address required");
12434       return -99;
12435     }
12436
12437   if (our_address_set == 0)
12438     {
12439       errmsg ("our_address required");
12440       return -99;
12441     }
12442
12443   M (L2TPV3_CREATE_TUNNEL, mp);
12444
12445   clib_memcpy (mp->client_address, client_address.as_u8,
12446                sizeof (mp->client_address));
12447
12448   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12449
12450   mp->local_session_id = ntohl (local_session_id);
12451   mp->remote_session_id = ntohl (remote_session_id);
12452   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12453   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12454   mp->l2_sublayer_present = l2_sublayer_present;
12455   mp->is_ipv6 = 1;
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static int
12463 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12464 {
12465   unformat_input_t *i = vam->input;
12466   u32 sw_if_index;
12467   u8 sw_if_index_set = 0;
12468   u64 new_local_cookie = 0;
12469   u64 new_remote_cookie = 0;
12470   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12471   int ret;
12472
12473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12476         sw_if_index_set = 1;
12477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12478         sw_if_index_set = 1;
12479       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12480         ;
12481       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12482         ;
12483       else
12484         break;
12485     }
12486
12487   if (sw_if_index_set == 0)
12488     {
12489       errmsg ("missing interface name or sw_if_index");
12490       return -99;
12491     }
12492
12493   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12494
12495   mp->sw_if_index = ntohl (sw_if_index);
12496   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12497   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12498
12499   S (mp);
12500   W (ret);
12501   return ret;
12502 }
12503
12504 static int
12505 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12506 {
12507   unformat_input_t *i = vam->input;
12508   vl_api_l2tpv3_interface_enable_disable_t *mp;
12509   u32 sw_if_index;
12510   u8 sw_if_index_set = 0;
12511   u8 enable_disable = 1;
12512   int ret;
12513
12514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12515     {
12516       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12517         sw_if_index_set = 1;
12518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12519         sw_if_index_set = 1;
12520       else if (unformat (i, "enable"))
12521         enable_disable = 1;
12522       else if (unformat (i, "disable"))
12523         enable_disable = 0;
12524       else
12525         break;
12526     }
12527
12528   if (sw_if_index_set == 0)
12529     {
12530       errmsg ("missing interface name or sw_if_index");
12531       return -99;
12532     }
12533
12534   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12535
12536   mp->sw_if_index = ntohl (sw_if_index);
12537   mp->enable_disable = enable_disable;
12538
12539   S (mp);
12540   W (ret);
12541   return ret;
12542 }
12543
12544 static int
12545 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12546 {
12547   unformat_input_t *i = vam->input;
12548   vl_api_l2tpv3_set_lookup_key_t *mp;
12549   u8 key = ~0;
12550   int ret;
12551
12552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (i, "lookup_v6_src"))
12555         key = L2T_LOOKUP_SRC_ADDRESS;
12556       else if (unformat (i, "lookup_v6_dst"))
12557         key = L2T_LOOKUP_DST_ADDRESS;
12558       else if (unformat (i, "lookup_session_id"))
12559         key = L2T_LOOKUP_SESSION_ID;
12560       else
12561         break;
12562     }
12563
12564   if (key == (u8) ~ 0)
12565     {
12566       errmsg ("l2tp session lookup key unset");
12567       return -99;
12568     }
12569
12570   M (L2TPV3_SET_LOOKUP_KEY, mp);
12571
12572   mp->key = key;
12573
12574   S (mp);
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12580   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12581 {
12582   vat_main_t *vam = &vat_main;
12583
12584   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12585          format_ip6_address, mp->our_address,
12586          format_ip6_address, mp->client_address,
12587          clib_net_to_host_u32 (mp->sw_if_index));
12588
12589   print (vam->ofp,
12590          "   local cookies %016llx %016llx remote cookie %016llx",
12591          clib_net_to_host_u64 (mp->local_cookie[0]),
12592          clib_net_to_host_u64 (mp->local_cookie[1]),
12593          clib_net_to_host_u64 (mp->remote_cookie));
12594
12595   print (vam->ofp, "   local session-id %d remote session-id %d",
12596          clib_net_to_host_u32 (mp->local_session_id),
12597          clib_net_to_host_u32 (mp->remote_session_id));
12598
12599   print (vam->ofp, "   l2 specific sublayer %s\n",
12600          mp->l2_sublayer_present ? "preset" : "absent");
12601
12602 }
12603
12604 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12605   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12606 {
12607   vat_main_t *vam = &vat_main;
12608   vat_json_node_t *node = NULL;
12609   struct in6_addr addr;
12610
12611   if (VAT_JSON_ARRAY != vam->json_tree.type)
12612     {
12613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12614       vat_json_init_array (&vam->json_tree);
12615     }
12616   node = vat_json_array_add (&vam->json_tree);
12617
12618   vat_json_init_object (node);
12619
12620   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12621   vat_json_object_add_ip6 (node, "our_address", addr);
12622   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12623   vat_json_object_add_ip6 (node, "client_address", addr);
12624
12625   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12626   vat_json_init_array (lc);
12627   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12628   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12629   vat_json_object_add_uint (node, "remote_cookie",
12630                             clib_net_to_host_u64 (mp->remote_cookie));
12631
12632   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12633   vat_json_object_add_uint (node, "local_session_id",
12634                             clib_net_to_host_u32 (mp->local_session_id));
12635   vat_json_object_add_uint (node, "remote_session_id",
12636                             clib_net_to_host_u32 (mp->remote_session_id));
12637   vat_json_object_add_string_copy (node, "l2_sublayer",
12638                                    mp->l2_sublayer_present ? (u8 *) "present"
12639                                    : (u8 *) "absent");
12640 }
12641
12642 static int
12643 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12644 {
12645   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12646   vl_api_control_ping_t *mp_ping;
12647   int ret;
12648
12649   /* Get list of l2tpv3-tunnel interfaces */
12650   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12651   S (mp);
12652
12653   /* Use a control ping for synchronization */
12654   MPING (CONTROL_PING, mp_ping);
12655   S (mp_ping);
12656
12657   W (ret);
12658   return ret;
12659 }
12660
12661
12662 static void vl_api_sw_interface_tap_details_t_handler
12663   (vl_api_sw_interface_tap_details_t * mp)
12664 {
12665   vat_main_t *vam = &vat_main;
12666
12667   print (vam->ofp, "%-16s %d",
12668          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12669 }
12670
12671 static void vl_api_sw_interface_tap_details_t_handler_json
12672   (vl_api_sw_interface_tap_details_t * mp)
12673 {
12674   vat_main_t *vam = &vat_main;
12675   vat_json_node_t *node = NULL;
12676
12677   if (VAT_JSON_ARRAY != vam->json_tree.type)
12678     {
12679       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12680       vat_json_init_array (&vam->json_tree);
12681     }
12682   node = vat_json_array_add (&vam->json_tree);
12683
12684   vat_json_init_object (node);
12685   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12686   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12687 }
12688
12689 static int
12690 api_sw_interface_tap_dump (vat_main_t * vam)
12691 {
12692   vl_api_sw_interface_tap_dump_t *mp;
12693   vl_api_control_ping_t *mp_ping;
12694   int ret;
12695
12696   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12697   /* Get list of tap interfaces */
12698   M (SW_INTERFACE_TAP_DUMP, mp);
12699   S (mp);
12700
12701   /* Use a control ping for synchronization */
12702   MPING (CONTROL_PING, mp_ping);
12703   S (mp_ping);
12704
12705   W (ret);
12706   return ret;
12707 }
12708
12709 static void vl_api_sw_interface_tap_v2_details_t_handler
12710   (vl_api_sw_interface_tap_v2_details_t * mp)
12711 {
12712   vat_main_t *vam = &vat_main;
12713
12714   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12715                     mp->host_ip4_prefix_len);
12716   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12717                     mp->host_ip6_prefix_len);
12718
12719   print (vam->ofp,
12720          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12721          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12722          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12723          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12724          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12725
12726   vec_free (ip4);
12727   vec_free (ip6);
12728 }
12729
12730 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12731   (vl_api_sw_interface_tap_v2_details_t * mp)
12732 {
12733   vat_main_t *vam = &vat_main;
12734   vat_json_node_t *node = NULL;
12735
12736   if (VAT_JSON_ARRAY != vam->json_tree.type)
12737     {
12738       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12739       vat_json_init_array (&vam->json_tree);
12740     }
12741   node = vat_json_array_add (&vam->json_tree);
12742
12743   vat_json_init_object (node);
12744   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12745   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12746   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12747   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12748   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12749   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12750   vat_json_object_add_string_copy (node, "host_mac_addr",
12751                                    format (0, "%U", format_ethernet_address,
12752                                            &mp->host_mac_addr));
12753   vat_json_object_add_string_copy (node, "host_namespace",
12754                                    mp->host_namespace);
12755   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12756   vat_json_object_add_string_copy (node, "host_ip4_addr",
12757                                    format (0, "%U/%d", format_ip4_address,
12758                                            mp->host_ip4_addr,
12759                                            mp->host_ip4_prefix_len));
12760   vat_json_object_add_string_copy (node, "host_ip6_addr",
12761                                    format (0, "%U/%d", format_ip6_address,
12762                                            mp->host_ip6_addr,
12763                                            mp->host_ip6_prefix_len));
12764
12765 }
12766
12767 static int
12768 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12769 {
12770   vl_api_sw_interface_tap_v2_dump_t *mp;
12771   vl_api_control_ping_t *mp_ping;
12772   int ret;
12773
12774   print (vam->ofp,
12775          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12776          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12777          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12778          "host_ip6_addr");
12779
12780   /* Get list of tap interfaces */
12781   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12782   S (mp);
12783
12784   /* Use a control ping for synchronization */
12785   MPING (CONTROL_PING, mp_ping);
12786   S (mp_ping);
12787
12788   W (ret);
12789   return ret;
12790 }
12791
12792 static int
12793 api_vxlan_offload_rx (vat_main_t * vam)
12794 {
12795   unformat_input_t *line_input = vam->input;
12796   vl_api_vxlan_offload_rx_t *mp;
12797   u32 hw_if_index = ~0, rx_if_index = ~0;
12798   u8 is_add = 1;
12799   int ret;
12800
12801   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12802     {
12803       if (unformat (line_input, "del"))
12804         is_add = 0;
12805       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12806                          &hw_if_index))
12807         ;
12808       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12809         ;
12810       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12811                          &rx_if_index))
12812         ;
12813       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12814         ;
12815       else
12816         {
12817           errmsg ("parse error '%U'", format_unformat_error, line_input);
12818           return -99;
12819         }
12820     }
12821
12822   if (hw_if_index == ~0)
12823     {
12824       errmsg ("no hw interface");
12825       return -99;
12826     }
12827
12828   if (rx_if_index == ~0)
12829     {
12830       errmsg ("no rx tunnel");
12831       return -99;
12832     }
12833
12834   M (VXLAN_OFFLOAD_RX, mp);
12835
12836   mp->hw_if_index = ntohl (hw_if_index);
12837   mp->sw_if_index = ntohl (rx_if_index);
12838   mp->enable = is_add;
12839
12840   S (mp);
12841   W (ret);
12842   return ret;
12843 }
12844
12845 static uword unformat_vxlan_decap_next
12846   (unformat_input_t * input, va_list * args)
12847 {
12848   u32 *result = va_arg (*args, u32 *);
12849   u32 tmp;
12850
12851   if (unformat (input, "l2"))
12852     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12853   else if (unformat (input, "%d", &tmp))
12854     *result = tmp;
12855   else
12856     return 0;
12857   return 1;
12858 }
12859
12860 static int
12861 api_vxlan_add_del_tunnel (vat_main_t * vam)
12862 {
12863   unformat_input_t *line_input = vam->input;
12864   vl_api_vxlan_add_del_tunnel_t *mp;
12865   ip46_address_t src, dst;
12866   u8 is_add = 1;
12867   u8 ipv4_set = 0, ipv6_set = 0;
12868   u8 src_set = 0;
12869   u8 dst_set = 0;
12870   u8 grp_set = 0;
12871   u32 instance = ~0;
12872   u32 mcast_sw_if_index = ~0;
12873   u32 encap_vrf_id = 0;
12874   u32 decap_next_index = ~0;
12875   u32 vni = 0;
12876   int ret;
12877
12878   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12879   clib_memset (&src, 0, sizeof src);
12880   clib_memset (&dst, 0, sizeof dst);
12881
12882   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (line_input, "del"))
12885         is_add = 0;
12886       else if (unformat (line_input, "instance %d", &instance))
12887         ;
12888       else
12889         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12890         {
12891           ipv4_set = 1;
12892           src_set = 1;
12893         }
12894       else
12895         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12896         {
12897           ipv4_set = 1;
12898           dst_set = 1;
12899         }
12900       else
12901         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12902         {
12903           ipv6_set = 1;
12904           src_set = 1;
12905         }
12906       else
12907         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12908         {
12909           ipv6_set = 1;
12910           dst_set = 1;
12911         }
12912       else if (unformat (line_input, "group %U %U",
12913                          unformat_ip4_address, &dst.ip4,
12914                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12915         {
12916           grp_set = dst_set = 1;
12917           ipv4_set = 1;
12918         }
12919       else if (unformat (line_input, "group %U",
12920                          unformat_ip4_address, &dst.ip4))
12921         {
12922           grp_set = dst_set = 1;
12923           ipv4_set = 1;
12924         }
12925       else if (unformat (line_input, "group %U %U",
12926                          unformat_ip6_address, &dst.ip6,
12927                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12928         {
12929           grp_set = dst_set = 1;
12930           ipv6_set = 1;
12931         }
12932       else if (unformat (line_input, "group %U",
12933                          unformat_ip6_address, &dst.ip6))
12934         {
12935           grp_set = dst_set = 1;
12936           ipv6_set = 1;
12937         }
12938       else
12939         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12940         ;
12941       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12942         ;
12943       else if (unformat (line_input, "decap-next %U",
12944                          unformat_vxlan_decap_next, &decap_next_index))
12945         ;
12946       else if (unformat (line_input, "vni %d", &vni))
12947         ;
12948       else
12949         {
12950           errmsg ("parse error '%U'", format_unformat_error, line_input);
12951           return -99;
12952         }
12953     }
12954
12955   if (src_set == 0)
12956     {
12957       errmsg ("tunnel src address not specified");
12958       return -99;
12959     }
12960   if (dst_set == 0)
12961     {
12962       errmsg ("tunnel dst address not specified");
12963       return -99;
12964     }
12965
12966   if (grp_set && !ip46_address_is_multicast (&dst))
12967     {
12968       errmsg ("tunnel group address not multicast");
12969       return -99;
12970     }
12971   if (grp_set && mcast_sw_if_index == ~0)
12972     {
12973       errmsg ("tunnel nonexistent multicast device");
12974       return -99;
12975     }
12976   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12977     {
12978       errmsg ("tunnel dst address must be unicast");
12979       return -99;
12980     }
12981
12982
12983   if (ipv4_set && ipv6_set)
12984     {
12985       errmsg ("both IPv4 and IPv6 addresses specified");
12986       return -99;
12987     }
12988
12989   if ((vni == 0) || (vni >> 24))
12990     {
12991       errmsg ("vni not specified or out of range");
12992       return -99;
12993     }
12994
12995   M (VXLAN_ADD_DEL_TUNNEL, mp);
12996
12997   if (ipv6_set)
12998     {
12999       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13000       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13001     }
13002   else
13003     {
13004       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13005       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13006     }
13007
13008   mp->instance = htonl (instance);
13009   mp->encap_vrf_id = ntohl (encap_vrf_id);
13010   mp->decap_next_index = ntohl (decap_next_index);
13011   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13012   mp->vni = ntohl (vni);
13013   mp->is_add = is_add;
13014   mp->is_ipv6 = ipv6_set;
13015
13016   S (mp);
13017   W (ret);
13018   return ret;
13019 }
13020
13021 static void vl_api_vxlan_tunnel_details_t_handler
13022   (vl_api_vxlan_tunnel_details_t * mp)
13023 {
13024   vat_main_t *vam = &vat_main;
13025   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13026   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13027
13028   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13029          ntohl (mp->sw_if_index),
13030          ntohl (mp->instance),
13031          format_ip46_address, &src, IP46_TYPE_ANY,
13032          format_ip46_address, &dst, IP46_TYPE_ANY,
13033          ntohl (mp->encap_vrf_id),
13034          ntohl (mp->decap_next_index), ntohl (mp->vni),
13035          ntohl (mp->mcast_sw_if_index));
13036 }
13037
13038 static void vl_api_vxlan_tunnel_details_t_handler_json
13039   (vl_api_vxlan_tunnel_details_t * mp)
13040 {
13041   vat_main_t *vam = &vat_main;
13042   vat_json_node_t *node = NULL;
13043
13044   if (VAT_JSON_ARRAY != vam->json_tree.type)
13045     {
13046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13047       vat_json_init_array (&vam->json_tree);
13048     }
13049   node = vat_json_array_add (&vam->json_tree);
13050
13051   vat_json_init_object (node);
13052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13053
13054   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13055
13056   if (mp->is_ipv6)
13057     {
13058       struct in6_addr ip6;
13059
13060       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13061       vat_json_object_add_ip6 (node, "src_address", ip6);
13062       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13063       vat_json_object_add_ip6 (node, "dst_address", ip6);
13064     }
13065   else
13066     {
13067       struct in_addr ip4;
13068
13069       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13070       vat_json_object_add_ip4 (node, "src_address", ip4);
13071       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13072       vat_json_object_add_ip4 (node, "dst_address", ip4);
13073     }
13074   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13075   vat_json_object_add_uint (node, "decap_next_index",
13076                             ntohl (mp->decap_next_index));
13077   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13078   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13079   vat_json_object_add_uint (node, "mcast_sw_if_index",
13080                             ntohl (mp->mcast_sw_if_index));
13081 }
13082
13083 static int
13084 api_vxlan_tunnel_dump (vat_main_t * vam)
13085 {
13086   unformat_input_t *i = vam->input;
13087   vl_api_vxlan_tunnel_dump_t *mp;
13088   vl_api_control_ping_t *mp_ping;
13089   u32 sw_if_index;
13090   u8 sw_if_index_set = 0;
13091   int ret;
13092
13093   /* Parse args required to build the message */
13094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13095     {
13096       if (unformat (i, "sw_if_index %d", &sw_if_index))
13097         sw_if_index_set = 1;
13098       else
13099         break;
13100     }
13101
13102   if (sw_if_index_set == 0)
13103     {
13104       sw_if_index = ~0;
13105     }
13106
13107   if (!vam->json_output)
13108     {
13109       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13110              "sw_if_index", "instance", "src_address", "dst_address",
13111              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13112     }
13113
13114   /* Get list of vxlan-tunnel interfaces */
13115   M (VXLAN_TUNNEL_DUMP, mp);
13116
13117   mp->sw_if_index = htonl (sw_if_index);
13118
13119   S (mp);
13120
13121   /* Use a control ping for synchronization */
13122   MPING (CONTROL_PING, mp_ping);
13123   S (mp_ping);
13124
13125   W (ret);
13126   return ret;
13127 }
13128
13129 static uword unformat_geneve_decap_next
13130   (unformat_input_t * input, va_list * args)
13131 {
13132   u32 *result = va_arg (*args, u32 *);
13133   u32 tmp;
13134
13135   if (unformat (input, "l2"))
13136     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13137   else if (unformat (input, "%d", &tmp))
13138     *result = tmp;
13139   else
13140     return 0;
13141   return 1;
13142 }
13143
13144 static int
13145 api_geneve_add_del_tunnel (vat_main_t * vam)
13146 {
13147   unformat_input_t *line_input = vam->input;
13148   vl_api_geneve_add_del_tunnel_t *mp;
13149   ip46_address_t src, dst;
13150   u8 is_add = 1;
13151   u8 ipv4_set = 0, ipv6_set = 0;
13152   u8 src_set = 0;
13153   u8 dst_set = 0;
13154   u8 grp_set = 0;
13155   u32 mcast_sw_if_index = ~0;
13156   u32 encap_vrf_id = 0;
13157   u32 decap_next_index = ~0;
13158   u32 vni = 0;
13159   int ret;
13160
13161   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13162   clib_memset (&src, 0, sizeof src);
13163   clib_memset (&dst, 0, sizeof dst);
13164
13165   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13166     {
13167       if (unformat (line_input, "del"))
13168         is_add = 0;
13169       else
13170         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13171         {
13172           ipv4_set = 1;
13173           src_set = 1;
13174         }
13175       else
13176         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13177         {
13178           ipv4_set = 1;
13179           dst_set = 1;
13180         }
13181       else
13182         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13183         {
13184           ipv6_set = 1;
13185           src_set = 1;
13186         }
13187       else
13188         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13189         {
13190           ipv6_set = 1;
13191           dst_set = 1;
13192         }
13193       else if (unformat (line_input, "group %U %U",
13194                          unformat_ip4_address, &dst.ip4,
13195                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13196         {
13197           grp_set = dst_set = 1;
13198           ipv4_set = 1;
13199         }
13200       else if (unformat (line_input, "group %U",
13201                          unformat_ip4_address, &dst.ip4))
13202         {
13203           grp_set = dst_set = 1;
13204           ipv4_set = 1;
13205         }
13206       else if (unformat (line_input, "group %U %U",
13207                          unformat_ip6_address, &dst.ip6,
13208                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13209         {
13210           grp_set = dst_set = 1;
13211           ipv6_set = 1;
13212         }
13213       else if (unformat (line_input, "group %U",
13214                          unformat_ip6_address, &dst.ip6))
13215         {
13216           grp_set = dst_set = 1;
13217           ipv6_set = 1;
13218         }
13219       else
13220         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13221         ;
13222       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13223         ;
13224       else if (unformat (line_input, "decap-next %U",
13225                          unformat_geneve_decap_next, &decap_next_index))
13226         ;
13227       else if (unformat (line_input, "vni %d", &vni))
13228         ;
13229       else
13230         {
13231           errmsg ("parse error '%U'", format_unformat_error, line_input);
13232           return -99;
13233         }
13234     }
13235
13236   if (src_set == 0)
13237     {
13238       errmsg ("tunnel src address not specified");
13239       return -99;
13240     }
13241   if (dst_set == 0)
13242     {
13243       errmsg ("tunnel dst address not specified");
13244       return -99;
13245     }
13246
13247   if (grp_set && !ip46_address_is_multicast (&dst))
13248     {
13249       errmsg ("tunnel group address not multicast");
13250       return -99;
13251     }
13252   if (grp_set && mcast_sw_if_index == ~0)
13253     {
13254       errmsg ("tunnel nonexistent multicast device");
13255       return -99;
13256     }
13257   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13258     {
13259       errmsg ("tunnel dst address must be unicast");
13260       return -99;
13261     }
13262
13263
13264   if (ipv4_set && ipv6_set)
13265     {
13266       errmsg ("both IPv4 and IPv6 addresses specified");
13267       return -99;
13268     }
13269
13270   if ((vni == 0) || (vni >> 24))
13271     {
13272       errmsg ("vni not specified or out of range");
13273       return -99;
13274     }
13275
13276   M (GENEVE_ADD_DEL_TUNNEL, mp);
13277
13278   if (ipv6_set)
13279     {
13280       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13281       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13282     }
13283   else
13284     {
13285       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13286       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13287     }
13288   mp->encap_vrf_id = ntohl (encap_vrf_id);
13289   mp->decap_next_index = ntohl (decap_next_index);
13290   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13291   mp->vni = ntohl (vni);
13292   mp->is_add = is_add;
13293   mp->is_ipv6 = ipv6_set;
13294
13295   S (mp);
13296   W (ret);
13297   return ret;
13298 }
13299
13300 static void vl_api_geneve_tunnel_details_t_handler
13301   (vl_api_geneve_tunnel_details_t * mp)
13302 {
13303   vat_main_t *vam = &vat_main;
13304   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13305   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13306
13307   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13308          ntohl (mp->sw_if_index),
13309          format_ip46_address, &src, IP46_TYPE_ANY,
13310          format_ip46_address, &dst, IP46_TYPE_ANY,
13311          ntohl (mp->encap_vrf_id),
13312          ntohl (mp->decap_next_index), ntohl (mp->vni),
13313          ntohl (mp->mcast_sw_if_index));
13314 }
13315
13316 static void vl_api_geneve_tunnel_details_t_handler_json
13317   (vl_api_geneve_tunnel_details_t * mp)
13318 {
13319   vat_main_t *vam = &vat_main;
13320   vat_json_node_t *node = NULL;
13321
13322   if (VAT_JSON_ARRAY != vam->json_tree.type)
13323     {
13324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13325       vat_json_init_array (&vam->json_tree);
13326     }
13327   node = vat_json_array_add (&vam->json_tree);
13328
13329   vat_json_init_object (node);
13330   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13331   if (mp->is_ipv6)
13332     {
13333       struct in6_addr ip6;
13334
13335       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13336       vat_json_object_add_ip6 (node, "src_address", ip6);
13337       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13338       vat_json_object_add_ip6 (node, "dst_address", ip6);
13339     }
13340   else
13341     {
13342       struct in_addr ip4;
13343
13344       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13345       vat_json_object_add_ip4 (node, "src_address", ip4);
13346       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13347       vat_json_object_add_ip4 (node, "dst_address", ip4);
13348     }
13349   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13350   vat_json_object_add_uint (node, "decap_next_index",
13351                             ntohl (mp->decap_next_index));
13352   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13353   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13354   vat_json_object_add_uint (node, "mcast_sw_if_index",
13355                             ntohl (mp->mcast_sw_if_index));
13356 }
13357
13358 static int
13359 api_geneve_tunnel_dump (vat_main_t * vam)
13360 {
13361   unformat_input_t *i = vam->input;
13362   vl_api_geneve_tunnel_dump_t *mp;
13363   vl_api_control_ping_t *mp_ping;
13364   u32 sw_if_index;
13365   u8 sw_if_index_set = 0;
13366   int ret;
13367
13368   /* Parse args required to build the message */
13369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (i, "sw_if_index %d", &sw_if_index))
13372         sw_if_index_set = 1;
13373       else
13374         break;
13375     }
13376
13377   if (sw_if_index_set == 0)
13378     {
13379       sw_if_index = ~0;
13380     }
13381
13382   if (!vam->json_output)
13383     {
13384       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13385              "sw_if_index", "local_address", "remote_address",
13386              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13387     }
13388
13389   /* Get list of geneve-tunnel interfaces */
13390   M (GENEVE_TUNNEL_DUMP, mp);
13391
13392   mp->sw_if_index = htonl (sw_if_index);
13393
13394   S (mp);
13395
13396   /* Use a control ping for synchronization */
13397   M (CONTROL_PING, mp_ping);
13398   S (mp_ping);
13399
13400   W (ret);
13401   return ret;
13402 }
13403
13404 static int
13405 api_gre_add_del_tunnel (vat_main_t * vam)
13406 {
13407   unformat_input_t *line_input = vam->input;
13408   vl_api_gre_add_del_tunnel_t *mp;
13409   ip4_address_t src4, dst4;
13410   ip6_address_t src6, dst6;
13411   u8 is_add = 1;
13412   u8 ipv4_set = 0;
13413   u8 ipv6_set = 0;
13414   u8 t_type = GRE_TUNNEL_TYPE_L3;
13415   u8 src_set = 0;
13416   u8 dst_set = 0;
13417   u32 outer_fib_id = 0;
13418   u32 session_id = 0;
13419   u32 instance = ~0;
13420   int ret;
13421
13422   clib_memset (&src4, 0, sizeof src4);
13423   clib_memset (&dst4, 0, sizeof dst4);
13424   clib_memset (&src6, 0, sizeof src6);
13425   clib_memset (&dst6, 0, sizeof dst6);
13426
13427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13428     {
13429       if (unformat (line_input, "del"))
13430         is_add = 0;
13431       else if (unformat (line_input, "instance %d", &instance))
13432         ;
13433       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13434         {
13435           src_set = 1;
13436           ipv4_set = 1;
13437         }
13438       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13439         {
13440           dst_set = 1;
13441           ipv4_set = 1;
13442         }
13443       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13444         {
13445           src_set = 1;
13446           ipv6_set = 1;
13447         }
13448       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13449         {
13450           dst_set = 1;
13451           ipv6_set = 1;
13452         }
13453       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13454         ;
13455       else if (unformat (line_input, "teb"))
13456         t_type = GRE_TUNNEL_TYPE_TEB;
13457       else if (unformat (line_input, "erspan %d", &session_id))
13458         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13459       else
13460         {
13461           errmsg ("parse error '%U'", format_unformat_error, line_input);
13462           return -99;
13463         }
13464     }
13465
13466   if (src_set == 0)
13467     {
13468       errmsg ("tunnel src address not specified");
13469       return -99;
13470     }
13471   if (dst_set == 0)
13472     {
13473       errmsg ("tunnel dst address not specified");
13474       return -99;
13475     }
13476   if (ipv4_set && ipv6_set)
13477     {
13478       errmsg ("both IPv4 and IPv6 addresses specified");
13479       return -99;
13480     }
13481
13482
13483   M (GRE_ADD_DEL_TUNNEL, mp);
13484
13485   if (ipv4_set)
13486     {
13487       clib_memcpy (&mp->src_address, &src4, 4);
13488       clib_memcpy (&mp->dst_address, &dst4, 4);
13489     }
13490   else
13491     {
13492       clib_memcpy (&mp->src_address, &src6, 16);
13493       clib_memcpy (&mp->dst_address, &dst6, 16);
13494     }
13495   mp->instance = htonl (instance);
13496   mp->outer_fib_id = htonl (outer_fib_id);
13497   mp->is_add = is_add;
13498   mp->session_id = htons ((u16) session_id);
13499   mp->tunnel_type = t_type;
13500   mp->is_ipv6 = ipv6_set;
13501
13502   S (mp);
13503   W (ret);
13504   return ret;
13505 }
13506
13507 static void vl_api_gre_tunnel_details_t_handler
13508   (vl_api_gre_tunnel_details_t * mp)
13509 {
13510   vat_main_t *vam = &vat_main;
13511   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13512   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13513
13514   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13515          ntohl (mp->sw_if_index),
13516          ntohl (mp->instance),
13517          format_ip46_address, &src, IP46_TYPE_ANY,
13518          format_ip46_address, &dst, IP46_TYPE_ANY,
13519          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13520 }
13521
13522 static void vl_api_gre_tunnel_details_t_handler_json
13523   (vl_api_gre_tunnel_details_t * mp)
13524 {
13525   vat_main_t *vam = &vat_main;
13526   vat_json_node_t *node = NULL;
13527   struct in_addr ip4;
13528   struct in6_addr ip6;
13529
13530   if (VAT_JSON_ARRAY != vam->json_tree.type)
13531     {
13532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13533       vat_json_init_array (&vam->json_tree);
13534     }
13535   node = vat_json_array_add (&vam->json_tree);
13536
13537   vat_json_init_object (node);
13538   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13539   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13540   if (!mp->is_ipv6)
13541     {
13542       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13543       vat_json_object_add_ip4 (node, "src_address", ip4);
13544       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13545       vat_json_object_add_ip4 (node, "dst_address", ip4);
13546     }
13547   else
13548     {
13549       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13550       vat_json_object_add_ip6 (node, "src_address", ip6);
13551       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13552       vat_json_object_add_ip6 (node, "dst_address", ip6);
13553     }
13554   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13555   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13556   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13557   vat_json_object_add_uint (node, "session_id", mp->session_id);
13558 }
13559
13560 static int
13561 api_gre_tunnel_dump (vat_main_t * vam)
13562 {
13563   unformat_input_t *i = vam->input;
13564   vl_api_gre_tunnel_dump_t *mp;
13565   vl_api_control_ping_t *mp_ping;
13566   u32 sw_if_index;
13567   u8 sw_if_index_set = 0;
13568   int ret;
13569
13570   /* Parse args required to build the message */
13571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13572     {
13573       if (unformat (i, "sw_if_index %d", &sw_if_index))
13574         sw_if_index_set = 1;
13575       else
13576         break;
13577     }
13578
13579   if (sw_if_index_set == 0)
13580     {
13581       sw_if_index = ~0;
13582     }
13583
13584   if (!vam->json_output)
13585     {
13586       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13587              "sw_if_index", "instance", "src_address", "dst_address",
13588              "tunnel_type", "outer_fib_id", "session_id");
13589     }
13590
13591   /* Get list of gre-tunnel interfaces */
13592   M (GRE_TUNNEL_DUMP, mp);
13593
13594   mp->sw_if_index = htonl (sw_if_index);
13595
13596   S (mp);
13597
13598   /* Use a control ping for synchronization */
13599   MPING (CONTROL_PING, mp_ping);
13600   S (mp_ping);
13601
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_l2_fib_clear_table (vat_main_t * vam)
13608 {
13609 //  unformat_input_t * i = vam->input;
13610   vl_api_l2_fib_clear_table_t *mp;
13611   int ret;
13612
13613   M (L2_FIB_CLEAR_TABLE, mp);
13614
13615   S (mp);
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_l2_interface_efp_filter (vat_main_t * vam)
13622 {
13623   unformat_input_t *i = vam->input;
13624   vl_api_l2_interface_efp_filter_t *mp;
13625   u32 sw_if_index;
13626   u8 enable = 1;
13627   u8 sw_if_index_set = 0;
13628   int ret;
13629
13630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13631     {
13632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13633         sw_if_index_set = 1;
13634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13635         sw_if_index_set = 1;
13636       else if (unformat (i, "enable"))
13637         enable = 1;
13638       else if (unformat (i, "disable"))
13639         enable = 0;
13640       else
13641         {
13642           clib_warning ("parse error '%U'", format_unformat_error, i);
13643           return -99;
13644         }
13645     }
13646
13647   if (sw_if_index_set == 0)
13648     {
13649       errmsg ("missing sw_if_index");
13650       return -99;
13651     }
13652
13653   M (L2_INTERFACE_EFP_FILTER, mp);
13654
13655   mp->sw_if_index = ntohl (sw_if_index);
13656   mp->enable_disable = enable;
13657
13658   S (mp);
13659   W (ret);
13660   return ret;
13661 }
13662
13663 #define foreach_vtr_op                          \
13664 _("disable",  L2_VTR_DISABLED)                  \
13665 _("push-1",  L2_VTR_PUSH_1)                     \
13666 _("push-2",  L2_VTR_PUSH_2)                     \
13667 _("pop-1",  L2_VTR_POP_1)                       \
13668 _("pop-2",  L2_VTR_POP_2)                       \
13669 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13670 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13671 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13672 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13673
13674 static int
13675 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13676 {
13677   unformat_input_t *i = vam->input;
13678   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13679   u32 sw_if_index;
13680   u8 sw_if_index_set = 0;
13681   u8 vtr_op_set = 0;
13682   u32 vtr_op = 0;
13683   u32 push_dot1q = 1;
13684   u32 tag1 = ~0;
13685   u32 tag2 = ~0;
13686   int ret;
13687
13688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13689     {
13690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13691         sw_if_index_set = 1;
13692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13693         sw_if_index_set = 1;
13694       else if (unformat (i, "vtr_op %d", &vtr_op))
13695         vtr_op_set = 1;
13696 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13697       foreach_vtr_op
13698 #undef _
13699         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13700         ;
13701       else if (unformat (i, "tag1 %d", &tag1))
13702         ;
13703       else if (unformat (i, "tag2 %d", &tag2))
13704         ;
13705       else
13706         {
13707           clib_warning ("parse error '%U'", format_unformat_error, i);
13708           return -99;
13709         }
13710     }
13711
13712   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13713     {
13714       errmsg ("missing vtr operation or sw_if_index");
13715       return -99;
13716     }
13717
13718   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13719   mp->sw_if_index = ntohl (sw_if_index);
13720   mp->vtr_op = ntohl (vtr_op);
13721   mp->push_dot1q = ntohl (push_dot1q);
13722   mp->tag1 = ntohl (tag1);
13723   mp->tag2 = ntohl (tag2);
13724
13725   S (mp);
13726   W (ret);
13727   return ret;
13728 }
13729
13730 static int
13731 api_create_vhost_user_if (vat_main_t * vam)
13732 {
13733   unformat_input_t *i = vam->input;
13734   vl_api_create_vhost_user_if_t *mp;
13735   u8 *file_name;
13736   u8 is_server = 0;
13737   u8 file_name_set = 0;
13738   u32 custom_dev_instance = ~0;
13739   u8 hwaddr[6];
13740   u8 use_custom_mac = 0;
13741   u8 disable_mrg_rxbuf = 0;
13742   u8 disable_indirect_desc = 0;
13743   u8 *tag = 0;
13744   int ret;
13745
13746   /* Shut up coverity */
13747   clib_memset (hwaddr, 0, sizeof (hwaddr));
13748
13749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13750     {
13751       if (unformat (i, "socket %s", &file_name))
13752         {
13753           file_name_set = 1;
13754         }
13755       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13756         ;
13757       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13758         use_custom_mac = 1;
13759       else if (unformat (i, "server"))
13760         is_server = 1;
13761       else if (unformat (i, "disable_mrg_rxbuf"))
13762         disable_mrg_rxbuf = 1;
13763       else if (unformat (i, "disable_indirect_desc"))
13764         disable_indirect_desc = 1;
13765       else if (unformat (i, "tag %s", &tag))
13766         ;
13767       else
13768         break;
13769     }
13770
13771   if (file_name_set == 0)
13772     {
13773       errmsg ("missing socket file name");
13774       return -99;
13775     }
13776
13777   if (vec_len (file_name) > 255)
13778     {
13779       errmsg ("socket file name too long");
13780       return -99;
13781     }
13782   vec_add1 (file_name, 0);
13783
13784   M (CREATE_VHOST_USER_IF, mp);
13785
13786   mp->is_server = is_server;
13787   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13788   mp->disable_indirect_desc = disable_indirect_desc;
13789   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13790   vec_free (file_name);
13791   if (custom_dev_instance != ~0)
13792     {
13793       mp->renumber = 1;
13794       mp->custom_dev_instance = ntohl (custom_dev_instance);
13795     }
13796
13797   mp->use_custom_mac = use_custom_mac;
13798   clib_memcpy (mp->mac_address, hwaddr, 6);
13799   if (tag)
13800     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13801   vec_free (tag);
13802
13803   S (mp);
13804   W (ret);
13805   return ret;
13806 }
13807
13808 static int
13809 api_modify_vhost_user_if (vat_main_t * vam)
13810 {
13811   unformat_input_t *i = vam->input;
13812   vl_api_modify_vhost_user_if_t *mp;
13813   u8 *file_name;
13814   u8 is_server = 0;
13815   u8 file_name_set = 0;
13816   u32 custom_dev_instance = ~0;
13817   u8 sw_if_index_set = 0;
13818   u32 sw_if_index = (u32) ~ 0;
13819   int ret;
13820
13821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13822     {
13823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13824         sw_if_index_set = 1;
13825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13826         sw_if_index_set = 1;
13827       else if (unformat (i, "socket %s", &file_name))
13828         {
13829           file_name_set = 1;
13830         }
13831       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13832         ;
13833       else if (unformat (i, "server"))
13834         is_server = 1;
13835       else
13836         break;
13837     }
13838
13839   if (sw_if_index_set == 0)
13840     {
13841       errmsg ("missing sw_if_index or interface name");
13842       return -99;
13843     }
13844
13845   if (file_name_set == 0)
13846     {
13847       errmsg ("missing socket file name");
13848       return -99;
13849     }
13850
13851   if (vec_len (file_name) > 255)
13852     {
13853       errmsg ("socket file name too long");
13854       return -99;
13855     }
13856   vec_add1 (file_name, 0);
13857
13858   M (MODIFY_VHOST_USER_IF, mp);
13859
13860   mp->sw_if_index = ntohl (sw_if_index);
13861   mp->is_server = is_server;
13862   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13863   vec_free (file_name);
13864   if (custom_dev_instance != ~0)
13865     {
13866       mp->renumber = 1;
13867       mp->custom_dev_instance = ntohl (custom_dev_instance);
13868     }
13869
13870   S (mp);
13871   W (ret);
13872   return ret;
13873 }
13874
13875 static int
13876 api_delete_vhost_user_if (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_delete_vhost_user_if_t *mp;
13880   u32 sw_if_index = ~0;
13881   u8 sw_if_index_set = 0;
13882   int ret;
13883
13884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13887         sw_if_index_set = 1;
13888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13889         sw_if_index_set = 1;
13890       else
13891         break;
13892     }
13893
13894   if (sw_if_index_set == 0)
13895     {
13896       errmsg ("missing sw_if_index or interface name");
13897       return -99;
13898     }
13899
13900
13901   M (DELETE_VHOST_USER_IF, mp);
13902
13903   mp->sw_if_index = ntohl (sw_if_index);
13904
13905   S (mp);
13906   W (ret);
13907   return ret;
13908 }
13909
13910 static void vl_api_sw_interface_vhost_user_details_t_handler
13911   (vl_api_sw_interface_vhost_user_details_t * mp)
13912 {
13913   vat_main_t *vam = &vat_main;
13914
13915   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13916          (char *) mp->interface_name,
13917          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13918          clib_net_to_host_u64 (mp->features), mp->is_server,
13919          ntohl (mp->num_regions), (char *) mp->sock_filename);
13920   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13921 }
13922
13923 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13924   (vl_api_sw_interface_vhost_user_details_t * mp)
13925 {
13926   vat_main_t *vam = &vat_main;
13927   vat_json_node_t *node = NULL;
13928
13929   if (VAT_JSON_ARRAY != vam->json_tree.type)
13930     {
13931       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13932       vat_json_init_array (&vam->json_tree);
13933     }
13934   node = vat_json_array_add (&vam->json_tree);
13935
13936   vat_json_init_object (node);
13937   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13938   vat_json_object_add_string_copy (node, "interface_name",
13939                                    mp->interface_name);
13940   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13941                             ntohl (mp->virtio_net_hdr_sz));
13942   vat_json_object_add_uint (node, "features",
13943                             clib_net_to_host_u64 (mp->features));
13944   vat_json_object_add_uint (node, "is_server", mp->is_server);
13945   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13946   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13947   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13948 }
13949
13950 static int
13951 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13952 {
13953   vl_api_sw_interface_vhost_user_dump_t *mp;
13954   vl_api_control_ping_t *mp_ping;
13955   int ret;
13956   print (vam->ofp,
13957          "Interface name            idx hdr_sz features server regions filename");
13958
13959   /* Get list of vhost-user interfaces */
13960   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13961   S (mp);
13962
13963   /* Use a control ping for synchronization */
13964   MPING (CONTROL_PING, mp_ping);
13965   S (mp_ping);
13966
13967   W (ret);
13968   return ret;
13969 }
13970
13971 static int
13972 api_show_version (vat_main_t * vam)
13973 {
13974   vl_api_show_version_t *mp;
13975   int ret;
13976
13977   M (SHOW_VERSION, mp);
13978
13979   S (mp);
13980   W (ret);
13981   return ret;
13982 }
13983
13984
13985 static int
13986 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13987 {
13988   unformat_input_t *line_input = vam->input;
13989   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13990   ip4_address_t local4, remote4;
13991   ip6_address_t local6, remote6;
13992   u8 is_add = 1;
13993   u8 ipv4_set = 0, ipv6_set = 0;
13994   u8 local_set = 0;
13995   u8 remote_set = 0;
13996   u8 grp_set = 0;
13997   u32 mcast_sw_if_index = ~0;
13998   u32 encap_vrf_id = 0;
13999   u32 decap_vrf_id = 0;
14000   u8 protocol = ~0;
14001   u32 vni;
14002   u8 vni_set = 0;
14003   int ret;
14004
14005   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14006   clib_memset (&local4, 0, sizeof local4);
14007   clib_memset (&remote4, 0, sizeof remote4);
14008   clib_memset (&local6, 0, sizeof local6);
14009   clib_memset (&remote6, 0, sizeof remote6);
14010
14011   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14012     {
14013       if (unformat (line_input, "del"))
14014         is_add = 0;
14015       else if (unformat (line_input, "local %U",
14016                          unformat_ip4_address, &local4))
14017         {
14018           local_set = 1;
14019           ipv4_set = 1;
14020         }
14021       else if (unformat (line_input, "remote %U",
14022                          unformat_ip4_address, &remote4))
14023         {
14024           remote_set = 1;
14025           ipv4_set = 1;
14026         }
14027       else if (unformat (line_input, "local %U",
14028                          unformat_ip6_address, &local6))
14029         {
14030           local_set = 1;
14031           ipv6_set = 1;
14032         }
14033       else if (unformat (line_input, "remote %U",
14034                          unformat_ip6_address, &remote6))
14035         {
14036           remote_set = 1;
14037           ipv6_set = 1;
14038         }
14039       else if (unformat (line_input, "group %U %U",
14040                          unformat_ip4_address, &remote4,
14041                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14042         {
14043           grp_set = remote_set = 1;
14044           ipv4_set = 1;
14045         }
14046       else if (unformat (line_input, "group %U",
14047                          unformat_ip4_address, &remote4))
14048         {
14049           grp_set = remote_set = 1;
14050           ipv4_set = 1;
14051         }
14052       else if (unformat (line_input, "group %U %U",
14053                          unformat_ip6_address, &remote6,
14054                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14055         {
14056           grp_set = remote_set = 1;
14057           ipv6_set = 1;
14058         }
14059       else if (unformat (line_input, "group %U",
14060                          unformat_ip6_address, &remote6))
14061         {
14062           grp_set = remote_set = 1;
14063           ipv6_set = 1;
14064         }
14065       else
14066         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14067         ;
14068       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14069         ;
14070       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14071         ;
14072       else if (unformat (line_input, "vni %d", &vni))
14073         vni_set = 1;
14074       else if (unformat (line_input, "next-ip4"))
14075         protocol = 1;
14076       else if (unformat (line_input, "next-ip6"))
14077         protocol = 2;
14078       else if (unformat (line_input, "next-ethernet"))
14079         protocol = 3;
14080       else if (unformat (line_input, "next-nsh"))
14081         protocol = 4;
14082       else
14083         {
14084           errmsg ("parse error '%U'", format_unformat_error, line_input);
14085           return -99;
14086         }
14087     }
14088
14089   if (local_set == 0)
14090     {
14091       errmsg ("tunnel local address not specified");
14092       return -99;
14093     }
14094   if (remote_set == 0)
14095     {
14096       errmsg ("tunnel remote address not specified");
14097       return -99;
14098     }
14099   if (grp_set && mcast_sw_if_index == ~0)
14100     {
14101       errmsg ("tunnel nonexistent multicast device");
14102       return -99;
14103     }
14104   if (ipv4_set && ipv6_set)
14105     {
14106       errmsg ("both IPv4 and IPv6 addresses specified");
14107       return -99;
14108     }
14109
14110   if (vni_set == 0)
14111     {
14112       errmsg ("vni not specified");
14113       return -99;
14114     }
14115
14116   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14117
14118
14119   if (ipv6_set)
14120     {
14121       clib_memcpy (&mp->local, &local6, sizeof (local6));
14122       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14123     }
14124   else
14125     {
14126       clib_memcpy (&mp->local, &local4, sizeof (local4));
14127       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14128     }
14129
14130   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14131   mp->encap_vrf_id = ntohl (encap_vrf_id);
14132   mp->decap_vrf_id = ntohl (decap_vrf_id);
14133   mp->protocol = protocol;
14134   mp->vni = ntohl (vni);
14135   mp->is_add = is_add;
14136   mp->is_ipv6 = ipv6_set;
14137
14138   S (mp);
14139   W (ret);
14140   return ret;
14141 }
14142
14143 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14144   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14145 {
14146   vat_main_t *vam = &vat_main;
14147   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14148   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14149
14150   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14151          ntohl (mp->sw_if_index),
14152          format_ip46_address, &local, IP46_TYPE_ANY,
14153          format_ip46_address, &remote, IP46_TYPE_ANY,
14154          ntohl (mp->vni), mp->protocol,
14155          ntohl (mp->mcast_sw_if_index),
14156          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14157 }
14158
14159
14160 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14161   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14162 {
14163   vat_main_t *vam = &vat_main;
14164   vat_json_node_t *node = NULL;
14165   struct in_addr ip4;
14166   struct in6_addr ip6;
14167
14168   if (VAT_JSON_ARRAY != vam->json_tree.type)
14169     {
14170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14171       vat_json_init_array (&vam->json_tree);
14172     }
14173   node = vat_json_array_add (&vam->json_tree);
14174
14175   vat_json_init_object (node);
14176   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14177   if (mp->is_ipv6)
14178     {
14179       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14180       vat_json_object_add_ip6 (node, "local", ip6);
14181       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14182       vat_json_object_add_ip6 (node, "remote", ip6);
14183     }
14184   else
14185     {
14186       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14187       vat_json_object_add_ip4 (node, "local", ip4);
14188       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14189       vat_json_object_add_ip4 (node, "remote", ip4);
14190     }
14191   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14192   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14193   vat_json_object_add_uint (node, "mcast_sw_if_index",
14194                             ntohl (mp->mcast_sw_if_index));
14195   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14196   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14197   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14198 }
14199
14200 static int
14201 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14202 {
14203   unformat_input_t *i = vam->input;
14204   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14205   vl_api_control_ping_t *mp_ping;
14206   u32 sw_if_index;
14207   u8 sw_if_index_set = 0;
14208   int ret;
14209
14210   /* Parse args required to build the message */
14211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (i, "sw_if_index %d", &sw_if_index))
14214         sw_if_index_set = 1;
14215       else
14216         break;
14217     }
14218
14219   if (sw_if_index_set == 0)
14220     {
14221       sw_if_index = ~0;
14222     }
14223
14224   if (!vam->json_output)
14225     {
14226       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14227              "sw_if_index", "local", "remote", "vni",
14228              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14229     }
14230
14231   /* Get list of vxlan-tunnel interfaces */
14232   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14233
14234   mp->sw_if_index = htonl (sw_if_index);
14235
14236   S (mp);
14237
14238   /* Use a control ping for synchronization */
14239   MPING (CONTROL_PING, mp_ping);
14240   S (mp_ping);
14241
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static void vl_api_l2_fib_table_details_t_handler
14247   (vl_api_l2_fib_table_details_t * mp)
14248 {
14249   vat_main_t *vam = &vat_main;
14250
14251   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14252          "       %d       %d     %d",
14253          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14254          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14255          mp->bvi_mac);
14256 }
14257
14258 static void vl_api_l2_fib_table_details_t_handler_json
14259   (vl_api_l2_fib_table_details_t * mp)
14260 {
14261   vat_main_t *vam = &vat_main;
14262   vat_json_node_t *node = NULL;
14263
14264   if (VAT_JSON_ARRAY != vam->json_tree.type)
14265     {
14266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14267       vat_json_init_array (&vam->json_tree);
14268     }
14269   node = vat_json_array_add (&vam->json_tree);
14270
14271   vat_json_init_object (node);
14272   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14273   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14275   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14276   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14277   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14278 }
14279
14280 static int
14281 api_l2_fib_table_dump (vat_main_t * vam)
14282 {
14283   unformat_input_t *i = vam->input;
14284   vl_api_l2_fib_table_dump_t *mp;
14285   vl_api_control_ping_t *mp_ping;
14286   u32 bd_id;
14287   u8 bd_id_set = 0;
14288   int ret;
14289
14290   /* Parse args required to build the message */
14291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14292     {
14293       if (unformat (i, "bd_id %d", &bd_id))
14294         bd_id_set = 1;
14295       else
14296         break;
14297     }
14298
14299   if (bd_id_set == 0)
14300     {
14301       errmsg ("missing bridge domain");
14302       return -99;
14303     }
14304
14305   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14306
14307   /* Get list of l2 fib entries */
14308   M (L2_FIB_TABLE_DUMP, mp);
14309
14310   mp->bd_id = ntohl (bd_id);
14311   S (mp);
14312
14313   /* Use a control ping for synchronization */
14314   MPING (CONTROL_PING, mp_ping);
14315   S (mp_ping);
14316
14317   W (ret);
14318   return ret;
14319 }
14320
14321
14322 static int
14323 api_interface_name_renumber (vat_main_t * vam)
14324 {
14325   unformat_input_t *line_input = vam->input;
14326   vl_api_interface_name_renumber_t *mp;
14327   u32 sw_if_index = ~0;
14328   u32 new_show_dev_instance = ~0;
14329   int ret;
14330
14331   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14332     {
14333       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14334                     &sw_if_index))
14335         ;
14336       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14337         ;
14338       else if (unformat (line_input, "new_show_dev_instance %d",
14339                          &new_show_dev_instance))
14340         ;
14341       else
14342         break;
14343     }
14344
14345   if (sw_if_index == ~0)
14346     {
14347       errmsg ("missing interface name or sw_if_index");
14348       return -99;
14349     }
14350
14351   if (new_show_dev_instance == ~0)
14352     {
14353       errmsg ("missing new_show_dev_instance");
14354       return -99;
14355     }
14356
14357   M (INTERFACE_NAME_RENUMBER, mp);
14358
14359   mp->sw_if_index = ntohl (sw_if_index);
14360   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14361
14362   S (mp);
14363   W (ret);
14364   return ret;
14365 }
14366
14367 static int
14368 api_ip_probe_neighbor (vat_main_t * vam)
14369 {
14370   unformat_input_t *i = vam->input;
14371   vl_api_ip_probe_neighbor_t *mp;
14372   u8 int_set = 0;
14373   u8 adr_set = 0;
14374   u8 is_ipv6 = 0;
14375   u8 dst_adr[16];
14376   u32 sw_if_index;
14377   int ret;
14378
14379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14380     {
14381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14382         int_set = 1;
14383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14384         int_set = 1;
14385       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14386         adr_set = 1;
14387       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14388         {
14389           adr_set = 1;
14390           is_ipv6 = 1;
14391         }
14392       else
14393         break;
14394     }
14395
14396   if (int_set == 0)
14397     {
14398       errmsg ("missing interface");
14399       return -99;
14400     }
14401
14402   if (adr_set == 0)
14403     {
14404       errmsg ("missing addresses");
14405       return -99;
14406     }
14407
14408   M (IP_PROBE_NEIGHBOR, mp);
14409
14410   mp->sw_if_index = ntohl (sw_if_index);
14411   mp->is_ipv6 = is_ipv6;
14412   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14413
14414   S (mp);
14415   W (ret);
14416   return ret;
14417 }
14418
14419 static int
14420 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14421 {
14422   unformat_input_t *i = vam->input;
14423   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14424   u8 mode = IP_SCAN_V46_NEIGHBORS;
14425   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14426   int ret;
14427
14428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14429     {
14430       if (unformat (i, "ip4"))
14431         mode = IP_SCAN_V4_NEIGHBORS;
14432       else if (unformat (i, "ip6"))
14433         mode = IP_SCAN_V6_NEIGHBORS;
14434       if (unformat (i, "both"))
14435         mode = IP_SCAN_V46_NEIGHBORS;
14436       else if (unformat (i, "disable"))
14437         mode = IP_SCAN_DISABLED;
14438       else if (unformat (i, "interval %d", &interval))
14439         ;
14440       else if (unformat (i, "max-time %d", &time))
14441         ;
14442       else if (unformat (i, "max-update %d", &update))
14443         ;
14444       else if (unformat (i, "delay %d", &delay))
14445         ;
14446       else if (unformat (i, "stale %d", &stale))
14447         ;
14448       else
14449         break;
14450     }
14451
14452   if (interval > 255)
14453     {
14454       errmsg ("interval cannot exceed 255 minutes.");
14455       return -99;
14456     }
14457   if (time > 255)
14458     {
14459       errmsg ("max-time cannot exceed 255 usec.");
14460       return -99;
14461     }
14462   if (update > 255)
14463     {
14464       errmsg ("max-update cannot exceed 255.");
14465       return -99;
14466     }
14467   if (delay > 255)
14468     {
14469       errmsg ("delay cannot exceed 255 msec.");
14470       return -99;
14471     }
14472   if (stale > 255)
14473     {
14474       errmsg ("stale cannot exceed 255 minutes.");
14475       return -99;
14476     }
14477
14478   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14479   mp->mode = mode;
14480   mp->scan_interval = interval;
14481   mp->max_proc_time = time;
14482   mp->max_update = update;
14483   mp->scan_int_delay = delay;
14484   mp->stale_threshold = stale;
14485
14486   S (mp);
14487   W (ret);
14488   return ret;
14489 }
14490
14491 static int
14492 api_want_ip4_arp_events (vat_main_t * vam)
14493 {
14494   unformat_input_t *line_input = vam->input;
14495   vl_api_want_ip4_arp_events_t *mp;
14496   ip4_address_t address;
14497   int address_set = 0;
14498   u32 enable_disable = 1;
14499   int ret;
14500
14501   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14502     {
14503       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14504         address_set = 1;
14505       else if (unformat (line_input, "del"))
14506         enable_disable = 0;
14507       else
14508         break;
14509     }
14510
14511   if (address_set == 0)
14512     {
14513       errmsg ("missing addresses");
14514       return -99;
14515     }
14516
14517   M (WANT_IP4_ARP_EVENTS, mp);
14518   mp->enable_disable = enable_disable;
14519   mp->pid = htonl (getpid ());
14520   mp->address = address.as_u32;
14521
14522   S (mp);
14523   W (ret);
14524   return ret;
14525 }
14526
14527 static int
14528 api_want_ip6_nd_events (vat_main_t * vam)
14529 {
14530   unformat_input_t *line_input = vam->input;
14531   vl_api_want_ip6_nd_events_t *mp;
14532   ip6_address_t address;
14533   int address_set = 0;
14534   u32 enable_disable = 1;
14535   int ret;
14536
14537   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14538     {
14539       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14540         address_set = 1;
14541       else if (unformat (line_input, "del"))
14542         enable_disable = 0;
14543       else
14544         break;
14545     }
14546
14547   if (address_set == 0)
14548     {
14549       errmsg ("missing addresses");
14550       return -99;
14551     }
14552
14553   M (WANT_IP6_ND_EVENTS, mp);
14554   mp->enable_disable = enable_disable;
14555   mp->pid = htonl (getpid ());
14556   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14557
14558   S (mp);
14559   W (ret);
14560   return ret;
14561 }
14562
14563 static int
14564 api_want_l2_macs_events (vat_main_t * vam)
14565 {
14566   unformat_input_t *line_input = vam->input;
14567   vl_api_want_l2_macs_events_t *mp;
14568   u8 enable_disable = 1;
14569   u32 scan_delay = 0;
14570   u32 max_macs_in_event = 0;
14571   u32 learn_limit = 0;
14572   int ret;
14573
14574   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14575     {
14576       if (unformat (line_input, "learn-limit %d", &learn_limit))
14577         ;
14578       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14579         ;
14580       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14581         ;
14582       else if (unformat (line_input, "disable"))
14583         enable_disable = 0;
14584       else
14585         break;
14586     }
14587
14588   M (WANT_L2_MACS_EVENTS, mp);
14589   mp->enable_disable = enable_disable;
14590   mp->pid = htonl (getpid ());
14591   mp->learn_limit = htonl (learn_limit);
14592   mp->scan_delay = (u8) scan_delay;
14593   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14594   S (mp);
14595   W (ret);
14596   return ret;
14597 }
14598
14599 static int
14600 api_input_acl_set_interface (vat_main_t * vam)
14601 {
14602   unformat_input_t *i = vam->input;
14603   vl_api_input_acl_set_interface_t *mp;
14604   u32 sw_if_index;
14605   int sw_if_index_set;
14606   u32 ip4_table_index = ~0;
14607   u32 ip6_table_index = ~0;
14608   u32 l2_table_index = ~0;
14609   u8 is_add = 1;
14610   int ret;
14611
14612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14615         sw_if_index_set = 1;
14616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14617         sw_if_index_set = 1;
14618       else if (unformat (i, "del"))
14619         is_add = 0;
14620       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14621         ;
14622       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14623         ;
14624       else if (unformat (i, "l2-table %d", &l2_table_index))
14625         ;
14626       else
14627         {
14628           clib_warning ("parse error '%U'", format_unformat_error, i);
14629           return -99;
14630         }
14631     }
14632
14633   if (sw_if_index_set == 0)
14634     {
14635       errmsg ("missing interface name or sw_if_index");
14636       return -99;
14637     }
14638
14639   M (INPUT_ACL_SET_INTERFACE, mp);
14640
14641   mp->sw_if_index = ntohl (sw_if_index);
14642   mp->ip4_table_index = ntohl (ip4_table_index);
14643   mp->ip6_table_index = ntohl (ip6_table_index);
14644   mp->l2_table_index = ntohl (l2_table_index);
14645   mp->is_add = is_add;
14646
14647   S (mp);
14648   W (ret);
14649   return ret;
14650 }
14651
14652 static int
14653 api_output_acl_set_interface (vat_main_t * vam)
14654 {
14655   unformat_input_t *i = vam->input;
14656   vl_api_output_acl_set_interface_t *mp;
14657   u32 sw_if_index;
14658   int sw_if_index_set;
14659   u32 ip4_table_index = ~0;
14660   u32 ip6_table_index = ~0;
14661   u32 l2_table_index = ~0;
14662   u8 is_add = 1;
14663   int ret;
14664
14665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14666     {
14667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14668         sw_if_index_set = 1;
14669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14670         sw_if_index_set = 1;
14671       else if (unformat (i, "del"))
14672         is_add = 0;
14673       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14674         ;
14675       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14676         ;
14677       else if (unformat (i, "l2-table %d", &l2_table_index))
14678         ;
14679       else
14680         {
14681           clib_warning ("parse error '%U'", format_unformat_error, i);
14682           return -99;
14683         }
14684     }
14685
14686   if (sw_if_index_set == 0)
14687     {
14688       errmsg ("missing interface name or sw_if_index");
14689       return -99;
14690     }
14691
14692   M (OUTPUT_ACL_SET_INTERFACE, mp);
14693
14694   mp->sw_if_index = ntohl (sw_if_index);
14695   mp->ip4_table_index = ntohl (ip4_table_index);
14696   mp->ip6_table_index = ntohl (ip6_table_index);
14697   mp->l2_table_index = ntohl (l2_table_index);
14698   mp->is_add = is_add;
14699
14700   S (mp);
14701   W (ret);
14702   return ret;
14703 }
14704
14705 static int
14706 api_ip_address_dump (vat_main_t * vam)
14707 {
14708   unformat_input_t *i = vam->input;
14709   vl_api_ip_address_dump_t *mp;
14710   vl_api_control_ping_t *mp_ping;
14711   u32 sw_if_index = ~0;
14712   u8 sw_if_index_set = 0;
14713   u8 ipv4_set = 0;
14714   u8 ipv6_set = 0;
14715   int ret;
14716
14717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14718     {
14719       if (unformat (i, "sw_if_index %d", &sw_if_index))
14720         sw_if_index_set = 1;
14721       else
14722         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14723         sw_if_index_set = 1;
14724       else if (unformat (i, "ipv4"))
14725         ipv4_set = 1;
14726       else if (unformat (i, "ipv6"))
14727         ipv6_set = 1;
14728       else
14729         break;
14730     }
14731
14732   if (ipv4_set && ipv6_set)
14733     {
14734       errmsg ("ipv4 and ipv6 flags cannot be both set");
14735       return -99;
14736     }
14737
14738   if ((!ipv4_set) && (!ipv6_set))
14739     {
14740       errmsg ("no ipv4 nor ipv6 flag set");
14741       return -99;
14742     }
14743
14744   if (sw_if_index_set == 0)
14745     {
14746       errmsg ("missing interface name or sw_if_index");
14747       return -99;
14748     }
14749
14750   vam->current_sw_if_index = sw_if_index;
14751   vam->is_ipv6 = ipv6_set;
14752
14753   M (IP_ADDRESS_DUMP, mp);
14754   mp->sw_if_index = ntohl (sw_if_index);
14755   mp->is_ipv6 = ipv6_set;
14756   S (mp);
14757
14758   /* Use a control ping for synchronization */
14759   MPING (CONTROL_PING, mp_ping);
14760   S (mp_ping);
14761
14762   W (ret);
14763   return ret;
14764 }
14765
14766 static int
14767 api_ip_dump (vat_main_t * vam)
14768 {
14769   vl_api_ip_dump_t *mp;
14770   vl_api_control_ping_t *mp_ping;
14771   unformat_input_t *in = vam->input;
14772   int ipv4_set = 0;
14773   int ipv6_set = 0;
14774   int is_ipv6;
14775   int i;
14776   int ret;
14777
14778   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14779     {
14780       if (unformat (in, "ipv4"))
14781         ipv4_set = 1;
14782       else if (unformat (in, "ipv6"))
14783         ipv6_set = 1;
14784       else
14785         break;
14786     }
14787
14788   if (ipv4_set && ipv6_set)
14789     {
14790       errmsg ("ipv4 and ipv6 flags cannot be both set");
14791       return -99;
14792     }
14793
14794   if ((!ipv4_set) && (!ipv6_set))
14795     {
14796       errmsg ("no ipv4 nor ipv6 flag set");
14797       return -99;
14798     }
14799
14800   is_ipv6 = ipv6_set;
14801   vam->is_ipv6 = is_ipv6;
14802
14803   /* free old data */
14804   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14805     {
14806       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14807     }
14808   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14809
14810   M (IP_DUMP, mp);
14811   mp->is_ipv6 = ipv6_set;
14812   S (mp);
14813
14814   /* Use a control ping for synchronization */
14815   MPING (CONTROL_PING, mp_ping);
14816   S (mp_ping);
14817
14818   W (ret);
14819   return ret;
14820 }
14821
14822 static int
14823 api_ipsec_spd_add_del (vat_main_t * vam)
14824 {
14825   unformat_input_t *i = vam->input;
14826   vl_api_ipsec_spd_add_del_t *mp;
14827   u32 spd_id = ~0;
14828   u8 is_add = 1;
14829   int ret;
14830
14831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14832     {
14833       if (unformat (i, "spd_id %d", &spd_id))
14834         ;
14835       else if (unformat (i, "del"))
14836         is_add = 0;
14837       else
14838         {
14839           clib_warning ("parse error '%U'", format_unformat_error, i);
14840           return -99;
14841         }
14842     }
14843   if (spd_id == ~0)
14844     {
14845       errmsg ("spd_id must be set");
14846       return -99;
14847     }
14848
14849   M (IPSEC_SPD_ADD_DEL, mp);
14850
14851   mp->spd_id = ntohl (spd_id);
14852   mp->is_add = is_add;
14853
14854   S (mp);
14855   W (ret);
14856   return ret;
14857 }
14858
14859 static int
14860 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14861 {
14862   unformat_input_t *i = vam->input;
14863   vl_api_ipsec_interface_add_del_spd_t *mp;
14864   u32 sw_if_index;
14865   u8 sw_if_index_set = 0;
14866   u32 spd_id = (u32) ~ 0;
14867   u8 is_add = 1;
14868   int ret;
14869
14870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14871     {
14872       if (unformat (i, "del"))
14873         is_add = 0;
14874       else if (unformat (i, "spd_id %d", &spd_id))
14875         ;
14876       else
14877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14878         sw_if_index_set = 1;
14879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14880         sw_if_index_set = 1;
14881       else
14882         {
14883           clib_warning ("parse error '%U'", format_unformat_error, i);
14884           return -99;
14885         }
14886
14887     }
14888
14889   if (spd_id == (u32) ~ 0)
14890     {
14891       errmsg ("spd_id must be set");
14892       return -99;
14893     }
14894
14895   if (sw_if_index_set == 0)
14896     {
14897       errmsg ("missing interface name or sw_if_index");
14898       return -99;
14899     }
14900
14901   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14902
14903   mp->spd_id = ntohl (spd_id);
14904   mp->sw_if_index = ntohl (sw_if_index);
14905   mp->is_add = is_add;
14906
14907   S (mp);
14908   W (ret);
14909   return ret;
14910 }
14911
14912 static int
14913 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14914 {
14915   unformat_input_t *i = vam->input;
14916   vl_api_ipsec_spd_add_del_entry_t *mp;
14917   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14918   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14919   i32 priority = 0;
14920   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14921   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14922   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14923   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14924   int ret;
14925
14926   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14927   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14928   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14929   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14930   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14931   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14932
14933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14934     {
14935       if (unformat (i, "del"))
14936         is_add = 0;
14937       if (unformat (i, "outbound"))
14938         is_outbound = 1;
14939       if (unformat (i, "inbound"))
14940         is_outbound = 0;
14941       else if (unformat (i, "spd_id %d", &spd_id))
14942         ;
14943       else if (unformat (i, "sa_id %d", &sa_id))
14944         ;
14945       else if (unformat (i, "priority %d", &priority))
14946         ;
14947       else if (unformat (i, "protocol %d", &protocol))
14948         ;
14949       else if (unformat (i, "lport_start %d", &lport_start))
14950         ;
14951       else if (unformat (i, "lport_stop %d", &lport_stop))
14952         ;
14953       else if (unformat (i, "rport_start %d", &rport_start))
14954         ;
14955       else if (unformat (i, "rport_stop %d", &rport_stop))
14956         ;
14957       else
14958         if (unformat
14959             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14960         {
14961           is_ipv6 = 0;
14962           is_ip_any = 0;
14963         }
14964       else
14965         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14966         {
14967           is_ipv6 = 0;
14968           is_ip_any = 0;
14969         }
14970       else
14971         if (unformat
14972             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14973         {
14974           is_ipv6 = 0;
14975           is_ip_any = 0;
14976         }
14977       else
14978         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14979         {
14980           is_ipv6 = 0;
14981           is_ip_any = 0;
14982         }
14983       else
14984         if (unformat
14985             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14986         {
14987           is_ipv6 = 1;
14988           is_ip_any = 0;
14989         }
14990       else
14991         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14992         {
14993           is_ipv6 = 1;
14994           is_ip_any = 0;
14995         }
14996       else
14997         if (unformat
14998             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14999         {
15000           is_ipv6 = 1;
15001           is_ip_any = 0;
15002         }
15003       else
15004         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15005         {
15006           is_ipv6 = 1;
15007           is_ip_any = 0;
15008         }
15009       else
15010         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15011         {
15012           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15013             {
15014               clib_warning ("unsupported action: 'resolve'");
15015               return -99;
15016             }
15017         }
15018       else
15019         {
15020           clib_warning ("parse error '%U'", format_unformat_error, i);
15021           return -99;
15022         }
15023
15024     }
15025
15026   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15027
15028   mp->spd_id = ntohl (spd_id);
15029   mp->priority = ntohl (priority);
15030   mp->is_outbound = is_outbound;
15031
15032   mp->is_ipv6 = is_ipv6;
15033   if (is_ipv6 || is_ip_any)
15034     {
15035       clib_memcpy (mp->remote_address_start, &raddr6_start,
15036                    sizeof (ip6_address_t));
15037       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15038                    sizeof (ip6_address_t));
15039       clib_memcpy (mp->local_address_start, &laddr6_start,
15040                    sizeof (ip6_address_t));
15041       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15042                    sizeof (ip6_address_t));
15043     }
15044   else
15045     {
15046       clib_memcpy (mp->remote_address_start, &raddr4_start,
15047                    sizeof (ip4_address_t));
15048       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15049                    sizeof (ip4_address_t));
15050       clib_memcpy (mp->local_address_start, &laddr4_start,
15051                    sizeof (ip4_address_t));
15052       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15053                    sizeof (ip4_address_t));
15054     }
15055   mp->protocol = (u8) protocol;
15056   mp->local_port_start = ntohs ((u16) lport_start);
15057   mp->local_port_stop = ntohs ((u16) lport_stop);
15058   mp->remote_port_start = ntohs ((u16) rport_start);
15059   mp->remote_port_stop = ntohs ((u16) rport_stop);
15060   mp->policy = (u8) policy;
15061   mp->sa_id = ntohl (sa_id);
15062   mp->is_add = is_add;
15063   mp->is_ip_any = is_ip_any;
15064   S (mp);
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15071 {
15072   unformat_input_t *i = vam->input;
15073   vl_api_ipsec_sad_add_del_entry_t *mp;
15074   u32 sad_id = 0, spi = 0;
15075   u8 *ck = 0, *ik = 0;
15076   u8 is_add = 1;
15077
15078   u8 protocol = IPSEC_PROTOCOL_AH;
15079   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15080   u32 crypto_alg = 0, integ_alg = 0;
15081   ip4_address_t tun_src4;
15082   ip4_address_t tun_dst4;
15083   ip6_address_t tun_src6;
15084   ip6_address_t tun_dst6;
15085   int ret;
15086
15087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (i, "del"))
15090         is_add = 0;
15091       else if (unformat (i, "sad_id %d", &sad_id))
15092         ;
15093       else if (unformat (i, "spi %d", &spi))
15094         ;
15095       else if (unformat (i, "esp"))
15096         protocol = IPSEC_PROTOCOL_ESP;
15097       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15098         {
15099           is_tunnel = 1;
15100           is_tunnel_ipv6 = 0;
15101         }
15102       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15103         {
15104           is_tunnel = 1;
15105           is_tunnel_ipv6 = 0;
15106         }
15107       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15108         {
15109           is_tunnel = 1;
15110           is_tunnel_ipv6 = 1;
15111         }
15112       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15113         {
15114           is_tunnel = 1;
15115           is_tunnel_ipv6 = 1;
15116         }
15117       else
15118         if (unformat
15119             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15120         {
15121           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15122             {
15123               clib_warning ("unsupported crypto-alg: '%U'",
15124                             format_ipsec_crypto_alg, crypto_alg);
15125               return -99;
15126             }
15127         }
15128       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15129         ;
15130       else
15131         if (unformat
15132             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15133         {
15134           if (integ_alg >= IPSEC_INTEG_N_ALG)
15135             {
15136               clib_warning ("unsupported integ-alg: '%U'",
15137                             format_ipsec_integ_alg, integ_alg);
15138               return -99;
15139             }
15140         }
15141       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15142         ;
15143       else
15144         {
15145           clib_warning ("parse error '%U'", format_unformat_error, i);
15146           return -99;
15147         }
15148
15149     }
15150
15151   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15152
15153   mp->sad_id = ntohl (sad_id);
15154   mp->is_add = is_add;
15155   mp->protocol = protocol;
15156   mp->spi = ntohl (spi);
15157   mp->is_tunnel = is_tunnel;
15158   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15159   mp->crypto_algorithm = crypto_alg;
15160   mp->integrity_algorithm = integ_alg;
15161   mp->crypto_key_length = vec_len (ck);
15162   mp->integrity_key_length = vec_len (ik);
15163
15164   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15165     mp->crypto_key_length = sizeof (mp->crypto_key);
15166
15167   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15168     mp->integrity_key_length = sizeof (mp->integrity_key);
15169
15170   if (ck)
15171     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15172   if (ik)
15173     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15174
15175   if (is_tunnel)
15176     {
15177       if (is_tunnel_ipv6)
15178         {
15179           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15180                        sizeof (ip6_address_t));
15181           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15182                        sizeof (ip6_address_t));
15183         }
15184       else
15185         {
15186           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15187                        sizeof (ip4_address_t));
15188           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15189                        sizeof (ip4_address_t));
15190         }
15191     }
15192
15193   S (mp);
15194   W (ret);
15195   return ret;
15196 }
15197
15198 static int
15199 api_ipsec_sa_set_key (vat_main_t * vam)
15200 {
15201   unformat_input_t *i = vam->input;
15202   vl_api_ipsec_sa_set_key_t *mp;
15203   u32 sa_id;
15204   u8 *ck = 0, *ik = 0;
15205   int ret;
15206
15207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15208     {
15209       if (unformat (i, "sa_id %d", &sa_id))
15210         ;
15211       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15212         ;
15213       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15214         ;
15215       else
15216         {
15217           clib_warning ("parse error '%U'", format_unformat_error, i);
15218           return -99;
15219         }
15220     }
15221
15222   M (IPSEC_SA_SET_KEY, mp);
15223
15224   mp->sa_id = ntohl (sa_id);
15225   mp->crypto_key_length = vec_len (ck);
15226   mp->integrity_key_length = vec_len (ik);
15227
15228   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15229     mp->crypto_key_length = sizeof (mp->crypto_key);
15230
15231   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15232     mp->integrity_key_length = sizeof (mp->integrity_key);
15233
15234   if (ck)
15235     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15236   if (ik)
15237     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15238
15239   S (mp);
15240   W (ret);
15241   return ret;
15242 }
15243
15244 static int
15245 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15246 {
15247   unformat_input_t *i = vam->input;
15248   vl_api_ipsec_tunnel_if_add_del_t *mp;
15249   u32 local_spi = 0, remote_spi = 0;
15250   u32 crypto_alg = 0, integ_alg = 0;
15251   u8 *lck = NULL, *rck = NULL;
15252   u8 *lik = NULL, *rik = NULL;
15253   ip4_address_t local_ip = { {0} };
15254   ip4_address_t remote_ip = { {0} };
15255   u8 is_add = 1;
15256   u8 esn = 0;
15257   u8 anti_replay = 0;
15258   u8 renumber = 0;
15259   u32 instance = ~0;
15260   int ret;
15261
15262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15263     {
15264       if (unformat (i, "del"))
15265         is_add = 0;
15266       else if (unformat (i, "esn"))
15267         esn = 1;
15268       else if (unformat (i, "anti_replay"))
15269         anti_replay = 1;
15270       else if (unformat (i, "local_spi %d", &local_spi))
15271         ;
15272       else if (unformat (i, "remote_spi %d", &remote_spi))
15273         ;
15274       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15275         ;
15276       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15277         ;
15278       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15279         ;
15280       else
15281         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15282         ;
15283       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15284         ;
15285       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15286         ;
15287       else
15288         if (unformat
15289             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15290         {
15291           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15292             {
15293               errmsg ("unsupported crypto-alg: '%U'\n",
15294                       format_ipsec_crypto_alg, crypto_alg);
15295               return -99;
15296             }
15297         }
15298       else
15299         if (unformat
15300             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15301         {
15302           if (integ_alg >= IPSEC_INTEG_N_ALG)
15303             {
15304               errmsg ("unsupported integ-alg: '%U'\n",
15305                       format_ipsec_integ_alg, integ_alg);
15306               return -99;
15307             }
15308         }
15309       else if (unformat (i, "instance %u", &instance))
15310         renumber = 1;
15311       else
15312         {
15313           errmsg ("parse error '%U'\n", format_unformat_error, i);
15314           return -99;
15315         }
15316     }
15317
15318   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15319
15320   mp->is_add = is_add;
15321   mp->esn = esn;
15322   mp->anti_replay = anti_replay;
15323
15324   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15325   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15326
15327   mp->local_spi = htonl (local_spi);
15328   mp->remote_spi = htonl (remote_spi);
15329   mp->crypto_alg = (u8) crypto_alg;
15330
15331   mp->local_crypto_key_len = 0;
15332   if (lck)
15333     {
15334       mp->local_crypto_key_len = vec_len (lck);
15335       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15336         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15337       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15338     }
15339
15340   mp->remote_crypto_key_len = 0;
15341   if (rck)
15342     {
15343       mp->remote_crypto_key_len = vec_len (rck);
15344       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15345         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15346       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15347     }
15348
15349   mp->integ_alg = (u8) integ_alg;
15350
15351   mp->local_integ_key_len = 0;
15352   if (lik)
15353     {
15354       mp->local_integ_key_len = vec_len (lik);
15355       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15356         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15357       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15358     }
15359
15360   mp->remote_integ_key_len = 0;
15361   if (rik)
15362     {
15363       mp->remote_integ_key_len = vec_len (rik);
15364       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15365         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15366       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15367     }
15368
15369   if (renumber)
15370     {
15371       mp->renumber = renumber;
15372       mp->show_instance = ntohl (instance);
15373     }
15374
15375   S (mp);
15376   W (ret);
15377   return ret;
15378 }
15379
15380 static void
15381 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15382 {
15383   vat_main_t *vam = &vat_main;
15384
15385   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15386          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15387          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15388          "tunnel_src_addr %U tunnel_dst_addr %U "
15389          "salt %u seq_outbound %lu last_seq_inbound %lu "
15390          "replay_window %lu total_data_size %lu\n",
15391          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15392          mp->protocol,
15393          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15394          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15395          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15396          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15397          mp->tunnel_src_addr,
15398          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15399          mp->tunnel_dst_addr,
15400          ntohl (mp->salt),
15401          clib_net_to_host_u64 (mp->seq_outbound),
15402          clib_net_to_host_u64 (mp->last_seq_inbound),
15403          clib_net_to_host_u64 (mp->replay_window),
15404          clib_net_to_host_u64 (mp->total_data_size));
15405 }
15406
15407 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15408 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15409
15410 static void vl_api_ipsec_sa_details_t_handler_json
15411   (vl_api_ipsec_sa_details_t * mp)
15412 {
15413   vat_main_t *vam = &vat_main;
15414   vat_json_node_t *node = NULL;
15415   struct in_addr src_ip4, dst_ip4;
15416   struct in6_addr src_ip6, dst_ip6;
15417
15418   if (VAT_JSON_ARRAY != vam->json_tree.type)
15419     {
15420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15421       vat_json_init_array (&vam->json_tree);
15422     }
15423   node = vat_json_array_add (&vam->json_tree);
15424
15425   vat_json_init_object (node);
15426   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15427   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15428   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15429   vat_json_object_add_uint (node, "proto", mp->protocol);
15430   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15431   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15432   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15433   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15434   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15435   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15436   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15437                              mp->crypto_key_len);
15438   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15439                              mp->integ_key_len);
15440   if (mp->is_tunnel_ip6)
15441     {
15442       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15443       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15444       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15445       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15446     }
15447   else
15448     {
15449       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15450       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15451       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15452       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15453     }
15454   vat_json_object_add_uint (node, "replay_window",
15455                             clib_net_to_host_u64 (mp->replay_window));
15456   vat_json_object_add_uint (node, "total_data_size",
15457                             clib_net_to_host_u64 (mp->total_data_size));
15458
15459 }
15460
15461 static int
15462 api_ipsec_sa_dump (vat_main_t * vam)
15463 {
15464   unformat_input_t *i = vam->input;
15465   vl_api_ipsec_sa_dump_t *mp;
15466   vl_api_control_ping_t *mp_ping;
15467   u32 sa_id = ~0;
15468   int ret;
15469
15470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (i, "sa_id %d", &sa_id))
15473         ;
15474       else
15475         {
15476           clib_warning ("parse error '%U'", format_unformat_error, i);
15477           return -99;
15478         }
15479     }
15480
15481   M (IPSEC_SA_DUMP, mp);
15482
15483   mp->sa_id = ntohl (sa_id);
15484
15485   S (mp);
15486
15487   /* Use a control ping for synchronization */
15488   M (CONTROL_PING, mp_ping);
15489   S (mp_ping);
15490
15491   W (ret);
15492   return ret;
15493 }
15494
15495 static int
15496 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15497 {
15498   unformat_input_t *i = vam->input;
15499   vl_api_ipsec_tunnel_if_set_key_t *mp;
15500   u32 sw_if_index = ~0;
15501   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15502   u8 *key = 0;
15503   u32 alg = ~0;
15504   int ret;
15505
15506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15507     {
15508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15509         ;
15510       else
15511         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15512         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15513       else
15514         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15515         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15516       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15517         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15518       else
15519         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15520         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15521       else if (unformat (i, "%U", unformat_hex_string, &key))
15522         ;
15523       else
15524         {
15525           clib_warning ("parse error '%U'", format_unformat_error, i);
15526           return -99;
15527         }
15528     }
15529
15530   if (sw_if_index == ~0)
15531     {
15532       errmsg ("interface must be specified");
15533       return -99;
15534     }
15535
15536   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15537     {
15538       errmsg ("key type must be specified");
15539       return -99;
15540     }
15541
15542   if (alg == ~0)
15543     {
15544       errmsg ("algorithm must be specified");
15545       return -99;
15546     }
15547
15548   if (vec_len (key) == 0)
15549     {
15550       errmsg ("key must be specified");
15551       return -99;
15552     }
15553
15554   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15555
15556   mp->sw_if_index = htonl (sw_if_index);
15557   mp->alg = alg;
15558   mp->key_type = key_type;
15559   mp->key_len = vec_len (key);
15560   clib_memcpy (mp->key, key, vec_len (key));
15561
15562   S (mp);
15563   W (ret);
15564
15565   return ret;
15566 }
15567
15568 static int
15569 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15570 {
15571   unformat_input_t *i = vam->input;
15572   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15573   u32 sw_if_index = ~0;
15574   u32 sa_id = ~0;
15575   u8 is_outbound = (u8) ~ 0;
15576   int ret;
15577
15578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15579     {
15580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15581         ;
15582       else if (unformat (i, "sa_id %d", &sa_id))
15583         ;
15584       else if (unformat (i, "outbound"))
15585         is_outbound = 1;
15586       else if (unformat (i, "inbound"))
15587         is_outbound = 0;
15588       else
15589         {
15590           clib_warning ("parse error '%U'", format_unformat_error, i);
15591           return -99;
15592         }
15593     }
15594
15595   if (sw_if_index == ~0)
15596     {
15597       errmsg ("interface must be specified");
15598       return -99;
15599     }
15600
15601   if (sa_id == ~0)
15602     {
15603       errmsg ("SA ID must be specified");
15604       return -99;
15605     }
15606
15607   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15608
15609   mp->sw_if_index = htonl (sw_if_index);
15610   mp->sa_id = htonl (sa_id);
15611   mp->is_outbound = is_outbound;
15612
15613   S (mp);
15614   W (ret);
15615
15616   return ret;
15617 }
15618
15619 static int
15620 api_ikev2_profile_add_del (vat_main_t * vam)
15621 {
15622   unformat_input_t *i = vam->input;
15623   vl_api_ikev2_profile_add_del_t *mp;
15624   u8 is_add = 1;
15625   u8 *name = 0;
15626   int ret;
15627
15628   const char *valid_chars = "a-zA-Z0-9_";
15629
15630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15631     {
15632       if (unformat (i, "del"))
15633         is_add = 0;
15634       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15635         vec_add1 (name, 0);
15636       else
15637         {
15638           errmsg ("parse error '%U'", format_unformat_error, i);
15639           return -99;
15640         }
15641     }
15642
15643   if (!vec_len (name))
15644     {
15645       errmsg ("profile name must be specified");
15646       return -99;
15647     }
15648
15649   if (vec_len (name) > 64)
15650     {
15651       errmsg ("profile name too long");
15652       return -99;
15653     }
15654
15655   M (IKEV2_PROFILE_ADD_DEL, mp);
15656
15657   clib_memcpy (mp->name, name, vec_len (name));
15658   mp->is_add = is_add;
15659   vec_free (name);
15660
15661   S (mp);
15662   W (ret);
15663   return ret;
15664 }
15665
15666 static int
15667 api_ikev2_profile_set_auth (vat_main_t * vam)
15668 {
15669   unformat_input_t *i = vam->input;
15670   vl_api_ikev2_profile_set_auth_t *mp;
15671   u8 *name = 0;
15672   u8 *data = 0;
15673   u32 auth_method = 0;
15674   u8 is_hex = 0;
15675   int ret;
15676
15677   const char *valid_chars = "a-zA-Z0-9_";
15678
15679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15680     {
15681       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15682         vec_add1 (name, 0);
15683       else if (unformat (i, "auth_method %U",
15684                          unformat_ikev2_auth_method, &auth_method))
15685         ;
15686       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15687         is_hex = 1;
15688       else if (unformat (i, "auth_data %v", &data))
15689         ;
15690       else
15691         {
15692           errmsg ("parse error '%U'", format_unformat_error, i);
15693           return -99;
15694         }
15695     }
15696
15697   if (!vec_len (name))
15698     {
15699       errmsg ("profile name must be specified");
15700       return -99;
15701     }
15702
15703   if (vec_len (name) > 64)
15704     {
15705       errmsg ("profile name too long");
15706       return -99;
15707     }
15708
15709   if (!vec_len (data))
15710     {
15711       errmsg ("auth_data must be specified");
15712       return -99;
15713     }
15714
15715   if (!auth_method)
15716     {
15717       errmsg ("auth_method must be specified");
15718       return -99;
15719     }
15720
15721   M (IKEV2_PROFILE_SET_AUTH, mp);
15722
15723   mp->is_hex = is_hex;
15724   mp->auth_method = (u8) auth_method;
15725   mp->data_len = vec_len (data);
15726   clib_memcpy (mp->name, name, vec_len (name));
15727   clib_memcpy (mp->data, data, vec_len (data));
15728   vec_free (name);
15729   vec_free (data);
15730
15731   S (mp);
15732   W (ret);
15733   return ret;
15734 }
15735
15736 static int
15737 api_ikev2_profile_set_id (vat_main_t * vam)
15738 {
15739   unformat_input_t *i = vam->input;
15740   vl_api_ikev2_profile_set_id_t *mp;
15741   u8 *name = 0;
15742   u8 *data = 0;
15743   u8 is_local = 0;
15744   u32 id_type = 0;
15745   ip4_address_t ip4;
15746   int ret;
15747
15748   const char *valid_chars = "a-zA-Z0-9_";
15749
15750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15751     {
15752       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15753         vec_add1 (name, 0);
15754       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15755         ;
15756       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15757         {
15758           data = vec_new (u8, 4);
15759           clib_memcpy (data, ip4.as_u8, 4);
15760         }
15761       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15762         ;
15763       else if (unformat (i, "id_data %v", &data))
15764         ;
15765       else if (unformat (i, "local"))
15766         is_local = 1;
15767       else if (unformat (i, "remote"))
15768         is_local = 0;
15769       else
15770         {
15771           errmsg ("parse error '%U'", format_unformat_error, i);
15772           return -99;
15773         }
15774     }
15775
15776   if (!vec_len (name))
15777     {
15778       errmsg ("profile name must be specified");
15779       return -99;
15780     }
15781
15782   if (vec_len (name) > 64)
15783     {
15784       errmsg ("profile name too long");
15785       return -99;
15786     }
15787
15788   if (!vec_len (data))
15789     {
15790       errmsg ("id_data must be specified");
15791       return -99;
15792     }
15793
15794   if (!id_type)
15795     {
15796       errmsg ("id_type must be specified");
15797       return -99;
15798     }
15799
15800   M (IKEV2_PROFILE_SET_ID, mp);
15801
15802   mp->is_local = is_local;
15803   mp->id_type = (u8) id_type;
15804   mp->data_len = vec_len (data);
15805   clib_memcpy (mp->name, name, vec_len (name));
15806   clib_memcpy (mp->data, data, vec_len (data));
15807   vec_free (name);
15808   vec_free (data);
15809
15810   S (mp);
15811   W (ret);
15812   return ret;
15813 }
15814
15815 static int
15816 api_ikev2_profile_set_ts (vat_main_t * vam)
15817 {
15818   unformat_input_t *i = vam->input;
15819   vl_api_ikev2_profile_set_ts_t *mp;
15820   u8 *name = 0;
15821   u8 is_local = 0;
15822   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15823   ip4_address_t start_addr, end_addr;
15824
15825   const char *valid_chars = "a-zA-Z0-9_";
15826   int ret;
15827
15828   start_addr.as_u32 = 0;
15829   end_addr.as_u32 = (u32) ~ 0;
15830
15831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15832     {
15833       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15834         vec_add1 (name, 0);
15835       else if (unformat (i, "protocol %d", &proto))
15836         ;
15837       else if (unformat (i, "start_port %d", &start_port))
15838         ;
15839       else if (unformat (i, "end_port %d", &end_port))
15840         ;
15841       else
15842         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15843         ;
15844       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15845         ;
15846       else if (unformat (i, "local"))
15847         is_local = 1;
15848       else if (unformat (i, "remote"))
15849         is_local = 0;
15850       else
15851         {
15852           errmsg ("parse error '%U'", format_unformat_error, i);
15853           return -99;
15854         }
15855     }
15856
15857   if (!vec_len (name))
15858     {
15859       errmsg ("profile name must be specified");
15860       return -99;
15861     }
15862
15863   if (vec_len (name) > 64)
15864     {
15865       errmsg ("profile name too long");
15866       return -99;
15867     }
15868
15869   M (IKEV2_PROFILE_SET_TS, mp);
15870
15871   mp->is_local = is_local;
15872   mp->proto = (u8) proto;
15873   mp->start_port = (u16) start_port;
15874   mp->end_port = (u16) end_port;
15875   mp->start_addr = start_addr.as_u32;
15876   mp->end_addr = end_addr.as_u32;
15877   clib_memcpy (mp->name, name, vec_len (name));
15878   vec_free (name);
15879
15880   S (mp);
15881   W (ret);
15882   return ret;
15883 }
15884
15885 static int
15886 api_ikev2_set_local_key (vat_main_t * vam)
15887 {
15888   unformat_input_t *i = vam->input;
15889   vl_api_ikev2_set_local_key_t *mp;
15890   u8 *file = 0;
15891   int ret;
15892
15893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15894     {
15895       if (unformat (i, "file %v", &file))
15896         vec_add1 (file, 0);
15897       else
15898         {
15899           errmsg ("parse error '%U'", format_unformat_error, i);
15900           return -99;
15901         }
15902     }
15903
15904   if (!vec_len (file))
15905     {
15906       errmsg ("RSA key file must be specified");
15907       return -99;
15908     }
15909
15910   if (vec_len (file) > 256)
15911     {
15912       errmsg ("file name too long");
15913       return -99;
15914     }
15915
15916   M (IKEV2_SET_LOCAL_KEY, mp);
15917
15918   clib_memcpy (mp->key_file, file, vec_len (file));
15919   vec_free (file);
15920
15921   S (mp);
15922   W (ret);
15923   return ret;
15924 }
15925
15926 static int
15927 api_ikev2_set_responder (vat_main_t * vam)
15928 {
15929   unformat_input_t *i = vam->input;
15930   vl_api_ikev2_set_responder_t *mp;
15931   int ret;
15932   u8 *name = 0;
15933   u32 sw_if_index = ~0;
15934   ip4_address_t address;
15935
15936   const char *valid_chars = "a-zA-Z0-9_";
15937
15938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15939     {
15940       if (unformat
15941           (i, "%U interface %d address %U", unformat_token, valid_chars,
15942            &name, &sw_if_index, unformat_ip4_address, &address))
15943         vec_add1 (name, 0);
15944       else
15945         {
15946           errmsg ("parse error '%U'", format_unformat_error, i);
15947           return -99;
15948         }
15949     }
15950
15951   if (!vec_len (name))
15952     {
15953       errmsg ("profile name must be specified");
15954       return -99;
15955     }
15956
15957   if (vec_len (name) > 64)
15958     {
15959       errmsg ("profile name too long");
15960       return -99;
15961     }
15962
15963   M (IKEV2_SET_RESPONDER, mp);
15964
15965   clib_memcpy (mp->name, name, vec_len (name));
15966   vec_free (name);
15967
15968   mp->sw_if_index = sw_if_index;
15969   clib_memcpy (mp->address, &address, sizeof (address));
15970
15971   S (mp);
15972   W (ret);
15973   return ret;
15974 }
15975
15976 static int
15977 api_ikev2_set_ike_transforms (vat_main_t * vam)
15978 {
15979   unformat_input_t *i = vam->input;
15980   vl_api_ikev2_set_ike_transforms_t *mp;
15981   int ret;
15982   u8 *name = 0;
15983   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15984
15985   const char *valid_chars = "a-zA-Z0-9_";
15986
15987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15988     {
15989       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15990                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15991         vec_add1 (name, 0);
15992       else
15993         {
15994           errmsg ("parse error '%U'", format_unformat_error, i);
15995           return -99;
15996         }
15997     }
15998
15999   if (!vec_len (name))
16000     {
16001       errmsg ("profile name must be specified");
16002       return -99;
16003     }
16004
16005   if (vec_len (name) > 64)
16006     {
16007       errmsg ("profile name too long");
16008       return -99;
16009     }
16010
16011   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16012
16013   clib_memcpy (mp->name, name, vec_len (name));
16014   vec_free (name);
16015   mp->crypto_alg = crypto_alg;
16016   mp->crypto_key_size = crypto_key_size;
16017   mp->integ_alg = integ_alg;
16018   mp->dh_group = dh_group;
16019
16020   S (mp);
16021   W (ret);
16022   return ret;
16023 }
16024
16025
16026 static int
16027 api_ikev2_set_esp_transforms (vat_main_t * vam)
16028 {
16029   unformat_input_t *i = vam->input;
16030   vl_api_ikev2_set_esp_transforms_t *mp;
16031   int ret;
16032   u8 *name = 0;
16033   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16034
16035   const char *valid_chars = "a-zA-Z0-9_";
16036
16037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16038     {
16039       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16040                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16041         vec_add1 (name, 0);
16042       else
16043         {
16044           errmsg ("parse error '%U'", format_unformat_error, i);
16045           return -99;
16046         }
16047     }
16048
16049   if (!vec_len (name))
16050     {
16051       errmsg ("profile name must be specified");
16052       return -99;
16053     }
16054
16055   if (vec_len (name) > 64)
16056     {
16057       errmsg ("profile name too long");
16058       return -99;
16059     }
16060
16061   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16062
16063   clib_memcpy (mp->name, name, vec_len (name));
16064   vec_free (name);
16065   mp->crypto_alg = crypto_alg;
16066   mp->crypto_key_size = crypto_key_size;
16067   mp->integ_alg = integ_alg;
16068   mp->dh_group = dh_group;
16069
16070   S (mp);
16071   W (ret);
16072   return ret;
16073 }
16074
16075 static int
16076 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16077 {
16078   unformat_input_t *i = vam->input;
16079   vl_api_ikev2_set_sa_lifetime_t *mp;
16080   int ret;
16081   u8 *name = 0;
16082   u64 lifetime, lifetime_maxdata;
16083   u32 lifetime_jitter, handover;
16084
16085   const char *valid_chars = "a-zA-Z0-9_";
16086
16087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16090                     &lifetime, &lifetime_jitter, &handover,
16091                     &lifetime_maxdata))
16092         vec_add1 (name, 0);
16093       else
16094         {
16095           errmsg ("parse error '%U'", format_unformat_error, i);
16096           return -99;
16097         }
16098     }
16099
16100   if (!vec_len (name))
16101     {
16102       errmsg ("profile name must be specified");
16103       return -99;
16104     }
16105
16106   if (vec_len (name) > 64)
16107     {
16108       errmsg ("profile name too long");
16109       return -99;
16110     }
16111
16112   M (IKEV2_SET_SA_LIFETIME, mp);
16113
16114   clib_memcpy (mp->name, name, vec_len (name));
16115   vec_free (name);
16116   mp->lifetime = lifetime;
16117   mp->lifetime_jitter = lifetime_jitter;
16118   mp->handover = handover;
16119   mp->lifetime_maxdata = lifetime_maxdata;
16120
16121   S (mp);
16122   W (ret);
16123   return ret;
16124 }
16125
16126 static int
16127 api_ikev2_initiate_sa_init (vat_main_t * vam)
16128 {
16129   unformat_input_t *i = vam->input;
16130   vl_api_ikev2_initiate_sa_init_t *mp;
16131   int ret;
16132   u8 *name = 0;
16133
16134   const char *valid_chars = "a-zA-Z0-9_";
16135
16136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16137     {
16138       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16139         vec_add1 (name, 0);
16140       else
16141         {
16142           errmsg ("parse error '%U'", format_unformat_error, i);
16143           return -99;
16144         }
16145     }
16146
16147   if (!vec_len (name))
16148     {
16149       errmsg ("profile name must be specified");
16150       return -99;
16151     }
16152
16153   if (vec_len (name) > 64)
16154     {
16155       errmsg ("profile name too long");
16156       return -99;
16157     }
16158
16159   M (IKEV2_INITIATE_SA_INIT, mp);
16160
16161   clib_memcpy (mp->name, name, vec_len (name));
16162   vec_free (name);
16163
16164   S (mp);
16165   W (ret);
16166   return ret;
16167 }
16168
16169 static int
16170 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16171 {
16172   unformat_input_t *i = vam->input;
16173   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16174   int ret;
16175   u64 ispi;
16176
16177
16178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16179     {
16180       if (unformat (i, "%lx", &ispi))
16181         ;
16182       else
16183         {
16184           errmsg ("parse error '%U'", format_unformat_error, i);
16185           return -99;
16186         }
16187     }
16188
16189   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16190
16191   mp->ispi = ispi;
16192
16193   S (mp);
16194   W (ret);
16195   return ret;
16196 }
16197
16198 static int
16199 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16200 {
16201   unformat_input_t *i = vam->input;
16202   vl_api_ikev2_initiate_del_child_sa_t *mp;
16203   int ret;
16204   u32 ispi;
16205
16206
16207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (i, "%x", &ispi))
16210         ;
16211       else
16212         {
16213           errmsg ("parse error '%U'", format_unformat_error, i);
16214           return -99;
16215         }
16216     }
16217
16218   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16219
16220   mp->ispi = ispi;
16221
16222   S (mp);
16223   W (ret);
16224   return ret;
16225 }
16226
16227 static int
16228 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16229 {
16230   unformat_input_t *i = vam->input;
16231   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16232   int ret;
16233   u32 ispi;
16234
16235
16236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16237     {
16238       if (unformat (i, "%x", &ispi))
16239         ;
16240       else
16241         {
16242           errmsg ("parse error '%U'", format_unformat_error, i);
16243           return -99;
16244         }
16245     }
16246
16247   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16248
16249   mp->ispi = ispi;
16250
16251   S (mp);
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_get_first_msg_id (vat_main_t * vam)
16258 {
16259   vl_api_get_first_msg_id_t *mp;
16260   unformat_input_t *i = vam->input;
16261   u8 *name;
16262   u8 name_set = 0;
16263   int ret;
16264
16265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16266     {
16267       if (unformat (i, "client %s", &name))
16268         name_set = 1;
16269       else
16270         break;
16271     }
16272
16273   if (name_set == 0)
16274     {
16275       errmsg ("missing client name");
16276       return -99;
16277     }
16278   vec_add1 (name, 0);
16279
16280   if (vec_len (name) > 63)
16281     {
16282       errmsg ("client name too long");
16283       return -99;
16284     }
16285
16286   M (GET_FIRST_MSG_ID, mp);
16287   clib_memcpy (mp->name, name, vec_len (name));
16288   S (mp);
16289   W (ret);
16290   return ret;
16291 }
16292
16293 static int
16294 api_cop_interface_enable_disable (vat_main_t * vam)
16295 {
16296   unformat_input_t *line_input = vam->input;
16297   vl_api_cop_interface_enable_disable_t *mp;
16298   u32 sw_if_index = ~0;
16299   u8 enable_disable = 1;
16300   int ret;
16301
16302   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16303     {
16304       if (unformat (line_input, "disable"))
16305         enable_disable = 0;
16306       if (unformat (line_input, "enable"))
16307         enable_disable = 1;
16308       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16309                          vam, &sw_if_index))
16310         ;
16311       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16312         ;
16313       else
16314         break;
16315     }
16316
16317   if (sw_if_index == ~0)
16318     {
16319       errmsg ("missing interface name or sw_if_index");
16320       return -99;
16321     }
16322
16323   /* Construct the API message */
16324   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16325   mp->sw_if_index = ntohl (sw_if_index);
16326   mp->enable_disable = enable_disable;
16327
16328   /* send it... */
16329   S (mp);
16330   /* Wait for the reply */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_cop_whitelist_enable_disable (vat_main_t * vam)
16337 {
16338   unformat_input_t *line_input = vam->input;
16339   vl_api_cop_whitelist_enable_disable_t *mp;
16340   u32 sw_if_index = ~0;
16341   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16342   u32 fib_id = 0;
16343   int ret;
16344
16345   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16346     {
16347       if (unformat (line_input, "ip4"))
16348         ip4 = 1;
16349       else if (unformat (line_input, "ip6"))
16350         ip6 = 1;
16351       else if (unformat (line_input, "default"))
16352         default_cop = 1;
16353       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16354                          vam, &sw_if_index))
16355         ;
16356       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16357         ;
16358       else if (unformat (line_input, "fib-id %d", &fib_id))
16359         ;
16360       else
16361         break;
16362     }
16363
16364   if (sw_if_index == ~0)
16365     {
16366       errmsg ("missing interface name or sw_if_index");
16367       return -99;
16368     }
16369
16370   /* Construct the API message */
16371   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16372   mp->sw_if_index = ntohl (sw_if_index);
16373   mp->fib_id = ntohl (fib_id);
16374   mp->ip4 = ip4;
16375   mp->ip6 = ip6;
16376   mp->default_cop = default_cop;
16377
16378   /* send it... */
16379   S (mp);
16380   /* Wait for the reply */
16381   W (ret);
16382   return ret;
16383 }
16384
16385 static int
16386 api_get_node_graph (vat_main_t * vam)
16387 {
16388   vl_api_get_node_graph_t *mp;
16389   int ret;
16390
16391   M (GET_NODE_GRAPH, mp);
16392
16393   /* send it... */
16394   S (mp);
16395   /* Wait for the reply */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 /* *INDENT-OFF* */
16401 /** Used for parsing LISP eids */
16402 typedef CLIB_PACKED(struct{
16403   u8 addr[16];   /**< eid address */
16404   u32 len;       /**< prefix length if IP */
16405   u8 type;      /**< type of eid */
16406 }) lisp_eid_vat_t;
16407 /* *INDENT-ON* */
16408
16409 static uword
16410 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16411 {
16412   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16413
16414   clib_memset (a, 0, sizeof (a[0]));
16415
16416   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16417     {
16418       a->type = 0;              /* ipv4 type */
16419     }
16420   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16421     {
16422       a->type = 1;              /* ipv6 type */
16423     }
16424   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16425     {
16426       a->type = 2;              /* mac type */
16427     }
16428   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16429     {
16430       a->type = 3;              /* NSH type */
16431       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16432       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16433     }
16434   else
16435     {
16436       return 0;
16437     }
16438
16439   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16440     {
16441       return 0;
16442     }
16443
16444   return 1;
16445 }
16446
16447 static int
16448 lisp_eid_size_vat (u8 type)
16449 {
16450   switch (type)
16451     {
16452     case 0:
16453       return 4;
16454     case 1:
16455       return 16;
16456     case 2:
16457       return 6;
16458     case 3:
16459       return 5;
16460     }
16461   return 0;
16462 }
16463
16464 static void
16465 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16466 {
16467   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16468 }
16469
16470 static int
16471 api_one_add_del_locator_set (vat_main_t * vam)
16472 {
16473   unformat_input_t *input = vam->input;
16474   vl_api_one_add_del_locator_set_t *mp;
16475   u8 is_add = 1;
16476   u8 *locator_set_name = NULL;
16477   u8 locator_set_name_set = 0;
16478   vl_api_local_locator_t locator, *locators = 0;
16479   u32 sw_if_index, priority, weight;
16480   u32 data_len = 0;
16481
16482   int ret;
16483   /* Parse args required to build the message */
16484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (input, "del"))
16487         {
16488           is_add = 0;
16489         }
16490       else if (unformat (input, "locator-set %s", &locator_set_name))
16491         {
16492           locator_set_name_set = 1;
16493         }
16494       else if (unformat (input, "sw_if_index %u p %u w %u",
16495                          &sw_if_index, &priority, &weight))
16496         {
16497           locator.sw_if_index = htonl (sw_if_index);
16498           locator.priority = priority;
16499           locator.weight = weight;
16500           vec_add1 (locators, locator);
16501         }
16502       else
16503         if (unformat
16504             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16505              &sw_if_index, &priority, &weight))
16506         {
16507           locator.sw_if_index = htonl (sw_if_index);
16508           locator.priority = priority;
16509           locator.weight = weight;
16510           vec_add1 (locators, locator);
16511         }
16512       else
16513         break;
16514     }
16515
16516   if (locator_set_name_set == 0)
16517     {
16518       errmsg ("missing locator-set name");
16519       vec_free (locators);
16520       return -99;
16521     }
16522
16523   if (vec_len (locator_set_name) > 64)
16524     {
16525       errmsg ("locator-set name too long");
16526       vec_free (locator_set_name);
16527       vec_free (locators);
16528       return -99;
16529     }
16530   vec_add1 (locator_set_name, 0);
16531
16532   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16533
16534   /* Construct the API message */
16535   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16536
16537   mp->is_add = is_add;
16538   clib_memcpy (mp->locator_set_name, locator_set_name,
16539                vec_len (locator_set_name));
16540   vec_free (locator_set_name);
16541
16542   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16543   if (locators)
16544     clib_memcpy (mp->locators, locators, data_len);
16545   vec_free (locators);
16546
16547   /* send it... */
16548   S (mp);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16556
16557 static int
16558 api_one_add_del_locator (vat_main_t * vam)
16559 {
16560   unformat_input_t *input = vam->input;
16561   vl_api_one_add_del_locator_t *mp;
16562   u32 tmp_if_index = ~0;
16563   u32 sw_if_index = ~0;
16564   u8 sw_if_index_set = 0;
16565   u8 sw_if_index_if_name_set = 0;
16566   u32 priority = ~0;
16567   u8 priority_set = 0;
16568   u32 weight = ~0;
16569   u8 weight_set = 0;
16570   u8 is_add = 1;
16571   u8 *locator_set_name = NULL;
16572   u8 locator_set_name_set = 0;
16573   int ret;
16574
16575   /* Parse args required to build the message */
16576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16577     {
16578       if (unformat (input, "del"))
16579         {
16580           is_add = 0;
16581         }
16582       else if (unformat (input, "locator-set %s", &locator_set_name))
16583         {
16584           locator_set_name_set = 1;
16585         }
16586       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16587                          &tmp_if_index))
16588         {
16589           sw_if_index_if_name_set = 1;
16590           sw_if_index = tmp_if_index;
16591         }
16592       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16593         {
16594           sw_if_index_set = 1;
16595           sw_if_index = tmp_if_index;
16596         }
16597       else if (unformat (input, "p %d", &priority))
16598         {
16599           priority_set = 1;
16600         }
16601       else if (unformat (input, "w %d", &weight))
16602         {
16603           weight_set = 1;
16604         }
16605       else
16606         break;
16607     }
16608
16609   if (locator_set_name_set == 0)
16610     {
16611       errmsg ("missing locator-set name");
16612       return -99;
16613     }
16614
16615   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16616     {
16617       errmsg ("missing sw_if_index");
16618       vec_free (locator_set_name);
16619       return -99;
16620     }
16621
16622   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16623     {
16624       errmsg ("cannot use both params interface name and sw_if_index");
16625       vec_free (locator_set_name);
16626       return -99;
16627     }
16628
16629   if (priority_set == 0)
16630     {
16631       errmsg ("missing locator-set priority");
16632       vec_free (locator_set_name);
16633       return -99;
16634     }
16635
16636   if (weight_set == 0)
16637     {
16638       errmsg ("missing locator-set weight");
16639       vec_free (locator_set_name);
16640       return -99;
16641     }
16642
16643   if (vec_len (locator_set_name) > 64)
16644     {
16645       errmsg ("locator-set name too long");
16646       vec_free (locator_set_name);
16647       return -99;
16648     }
16649   vec_add1 (locator_set_name, 0);
16650
16651   /* Construct the API message */
16652   M (ONE_ADD_DEL_LOCATOR, mp);
16653
16654   mp->is_add = is_add;
16655   mp->sw_if_index = ntohl (sw_if_index);
16656   mp->priority = priority;
16657   mp->weight = weight;
16658   clib_memcpy (mp->locator_set_name, locator_set_name,
16659                vec_len (locator_set_name));
16660   vec_free (locator_set_name);
16661
16662   /* send it... */
16663   S (mp);
16664
16665   /* Wait for a reply... */
16666   W (ret);
16667   return ret;
16668 }
16669
16670 #define api_lisp_add_del_locator api_one_add_del_locator
16671
16672 uword
16673 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16674 {
16675   u32 *key_id = va_arg (*args, u32 *);
16676   u8 *s = 0;
16677
16678   if (unformat (input, "%s", &s))
16679     {
16680       if (!strcmp ((char *) s, "sha1"))
16681         key_id[0] = HMAC_SHA_1_96;
16682       else if (!strcmp ((char *) s, "sha256"))
16683         key_id[0] = HMAC_SHA_256_128;
16684       else
16685         {
16686           clib_warning ("invalid key_id: '%s'", s);
16687           key_id[0] = HMAC_NO_KEY;
16688         }
16689     }
16690   else
16691     return 0;
16692
16693   vec_free (s);
16694   return 1;
16695 }
16696
16697 static int
16698 api_one_add_del_local_eid (vat_main_t * vam)
16699 {
16700   unformat_input_t *input = vam->input;
16701   vl_api_one_add_del_local_eid_t *mp;
16702   u8 is_add = 1;
16703   u8 eid_set = 0;
16704   lisp_eid_vat_t _eid, *eid = &_eid;
16705   u8 *locator_set_name = 0;
16706   u8 locator_set_name_set = 0;
16707   u32 vni = 0;
16708   u16 key_id = 0;
16709   u8 *key = 0;
16710   int ret;
16711
16712   /* Parse args required to build the message */
16713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16714     {
16715       if (unformat (input, "del"))
16716         {
16717           is_add = 0;
16718         }
16719       else if (unformat (input, "vni %d", &vni))
16720         {
16721           ;
16722         }
16723       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16724         {
16725           eid_set = 1;
16726         }
16727       else if (unformat (input, "locator-set %s", &locator_set_name))
16728         {
16729           locator_set_name_set = 1;
16730         }
16731       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16732         ;
16733       else if (unformat (input, "secret-key %_%v%_", &key))
16734         ;
16735       else
16736         break;
16737     }
16738
16739   if (locator_set_name_set == 0)
16740     {
16741       errmsg ("missing locator-set name");
16742       return -99;
16743     }
16744
16745   if (0 == eid_set)
16746     {
16747       errmsg ("EID address not set!");
16748       vec_free (locator_set_name);
16749       return -99;
16750     }
16751
16752   if (key && (0 == key_id))
16753     {
16754       errmsg ("invalid key_id!");
16755       return -99;
16756     }
16757
16758   if (vec_len (key) > 64)
16759     {
16760       errmsg ("key too long");
16761       vec_free (key);
16762       return -99;
16763     }
16764
16765   if (vec_len (locator_set_name) > 64)
16766     {
16767       errmsg ("locator-set name too long");
16768       vec_free (locator_set_name);
16769       return -99;
16770     }
16771   vec_add1 (locator_set_name, 0);
16772
16773   /* Construct the API message */
16774   M (ONE_ADD_DEL_LOCAL_EID, mp);
16775
16776   mp->is_add = is_add;
16777   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16778   mp->eid_type = eid->type;
16779   mp->prefix_len = eid->len;
16780   mp->vni = clib_host_to_net_u32 (vni);
16781   mp->key_id = clib_host_to_net_u16 (key_id);
16782   clib_memcpy (mp->locator_set_name, locator_set_name,
16783                vec_len (locator_set_name));
16784   clib_memcpy (mp->key, key, vec_len (key));
16785
16786   vec_free (locator_set_name);
16787   vec_free (key);
16788
16789   /* send it... */
16790   S (mp);
16791
16792   /* Wait for a reply... */
16793   W (ret);
16794   return ret;
16795 }
16796
16797 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16798
16799 static int
16800 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16801 {
16802   u32 dp_table = 0, vni = 0;;
16803   unformat_input_t *input = vam->input;
16804   vl_api_gpe_add_del_fwd_entry_t *mp;
16805   u8 is_add = 1;
16806   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16807   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16808   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16809   u32 action = ~0, w;
16810   ip4_address_t rmt_rloc4, lcl_rloc4;
16811   ip6_address_t rmt_rloc6, lcl_rloc6;
16812   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16813   int ret;
16814
16815   clib_memset (&rloc, 0, sizeof (rloc));
16816
16817   /* Parse args required to build the message */
16818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16819     {
16820       if (unformat (input, "del"))
16821         is_add = 0;
16822       else if (unformat (input, "add"))
16823         is_add = 1;
16824       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16825         {
16826           rmt_eid_set = 1;
16827         }
16828       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16829         {
16830           lcl_eid_set = 1;
16831         }
16832       else if (unformat (input, "vrf %d", &dp_table))
16833         ;
16834       else if (unformat (input, "bd %d", &dp_table))
16835         ;
16836       else if (unformat (input, "vni %d", &vni))
16837         ;
16838       else if (unformat (input, "w %d", &w))
16839         {
16840           if (!curr_rloc)
16841             {
16842               errmsg ("No RLOC configured for setting priority/weight!");
16843               return -99;
16844             }
16845           curr_rloc->weight = w;
16846         }
16847       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16848                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16849         {
16850           rloc.is_ip4 = 1;
16851
16852           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16853           rloc.weight = 0;
16854           vec_add1 (lcl_locs, rloc);
16855
16856           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16857           vec_add1 (rmt_locs, rloc);
16858           /* weight saved in rmt loc */
16859           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16860         }
16861       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16862                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16863         {
16864           rloc.is_ip4 = 0;
16865           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16866           rloc.weight = 0;
16867           vec_add1 (lcl_locs, rloc);
16868
16869           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16870           vec_add1 (rmt_locs, rloc);
16871           /* weight saved in rmt loc */
16872           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16873         }
16874       else if (unformat (input, "action %d", &action))
16875         {
16876           ;
16877         }
16878       else
16879         {
16880           clib_warning ("parse error '%U'", format_unformat_error, input);
16881           return -99;
16882         }
16883     }
16884
16885   if (!rmt_eid_set)
16886     {
16887       errmsg ("remote eid addresses not set");
16888       return -99;
16889     }
16890
16891   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16892     {
16893       errmsg ("eid types don't match");
16894       return -99;
16895     }
16896
16897   if (0 == rmt_locs && (u32) ~ 0 == action)
16898     {
16899       errmsg ("action not set for negative mapping");
16900       return -99;
16901     }
16902
16903   /* Construct the API message */
16904   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16905       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16906
16907   mp->is_add = is_add;
16908   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16909   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16910   mp->eid_type = rmt_eid->type;
16911   mp->dp_table = clib_host_to_net_u32 (dp_table);
16912   mp->vni = clib_host_to_net_u32 (vni);
16913   mp->rmt_len = rmt_eid->len;
16914   mp->lcl_len = lcl_eid->len;
16915   mp->action = action;
16916
16917   if (0 != rmt_locs && 0 != lcl_locs)
16918     {
16919       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16920       clib_memcpy (mp->locs, lcl_locs,
16921                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16922
16923       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16924       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16925                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16926     }
16927   vec_free (lcl_locs);
16928   vec_free (rmt_locs);
16929
16930   /* send it... */
16931   S (mp);
16932
16933   /* Wait for a reply... */
16934   W (ret);
16935   return ret;
16936 }
16937
16938 static int
16939 api_one_add_del_map_server (vat_main_t * vam)
16940 {
16941   unformat_input_t *input = vam->input;
16942   vl_api_one_add_del_map_server_t *mp;
16943   u8 is_add = 1;
16944   u8 ipv4_set = 0;
16945   u8 ipv6_set = 0;
16946   ip4_address_t ipv4;
16947   ip6_address_t ipv6;
16948   int ret;
16949
16950   /* Parse args required to build the message */
16951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16952     {
16953       if (unformat (input, "del"))
16954         {
16955           is_add = 0;
16956         }
16957       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16958         {
16959           ipv4_set = 1;
16960         }
16961       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16962         {
16963           ipv6_set = 1;
16964         }
16965       else
16966         break;
16967     }
16968
16969   if (ipv4_set && ipv6_set)
16970     {
16971       errmsg ("both eid v4 and v6 addresses set");
16972       return -99;
16973     }
16974
16975   if (!ipv4_set && !ipv6_set)
16976     {
16977       errmsg ("eid addresses not set");
16978       return -99;
16979     }
16980
16981   /* Construct the API message */
16982   M (ONE_ADD_DEL_MAP_SERVER, mp);
16983
16984   mp->is_add = is_add;
16985   if (ipv6_set)
16986     {
16987       mp->is_ipv6 = 1;
16988       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16989     }
16990   else
16991     {
16992       mp->is_ipv6 = 0;
16993       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16994     }
16995
16996   /* send it... */
16997   S (mp);
16998
16999   /* Wait for a reply... */
17000   W (ret);
17001   return ret;
17002 }
17003
17004 #define api_lisp_add_del_map_server api_one_add_del_map_server
17005
17006 static int
17007 api_one_add_del_map_resolver (vat_main_t * vam)
17008 {
17009   unformat_input_t *input = vam->input;
17010   vl_api_one_add_del_map_resolver_t *mp;
17011   u8 is_add = 1;
17012   u8 ipv4_set = 0;
17013   u8 ipv6_set = 0;
17014   ip4_address_t ipv4;
17015   ip6_address_t ipv6;
17016   int ret;
17017
17018   /* Parse args required to build the message */
17019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17020     {
17021       if (unformat (input, "del"))
17022         {
17023           is_add = 0;
17024         }
17025       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17026         {
17027           ipv4_set = 1;
17028         }
17029       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17030         {
17031           ipv6_set = 1;
17032         }
17033       else
17034         break;
17035     }
17036
17037   if (ipv4_set && ipv6_set)
17038     {
17039       errmsg ("both eid v4 and v6 addresses set");
17040       return -99;
17041     }
17042
17043   if (!ipv4_set && !ipv6_set)
17044     {
17045       errmsg ("eid addresses not set");
17046       return -99;
17047     }
17048
17049   /* Construct the API message */
17050   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17051
17052   mp->is_add = is_add;
17053   if (ipv6_set)
17054     {
17055       mp->is_ipv6 = 1;
17056       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17057     }
17058   else
17059     {
17060       mp->is_ipv6 = 0;
17061       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17062     }
17063
17064   /* send it... */
17065   S (mp);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17073
17074 static int
17075 api_lisp_gpe_enable_disable (vat_main_t * vam)
17076 {
17077   unformat_input_t *input = vam->input;
17078   vl_api_gpe_enable_disable_t *mp;
17079   u8 is_set = 0;
17080   u8 is_en = 1;
17081   int ret;
17082
17083   /* Parse args required to build the message */
17084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17085     {
17086       if (unformat (input, "enable"))
17087         {
17088           is_set = 1;
17089           is_en = 1;
17090         }
17091       else if (unformat (input, "disable"))
17092         {
17093           is_set = 1;
17094           is_en = 0;
17095         }
17096       else
17097         break;
17098     }
17099
17100   if (is_set == 0)
17101     {
17102       errmsg ("Value not set");
17103       return -99;
17104     }
17105
17106   /* Construct the API message */
17107   M (GPE_ENABLE_DISABLE, mp);
17108
17109   mp->is_en = is_en;
17110
17111   /* send it... */
17112   S (mp);
17113
17114   /* Wait for a reply... */
17115   W (ret);
17116   return ret;
17117 }
17118
17119 static int
17120 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17121 {
17122   unformat_input_t *input = vam->input;
17123   vl_api_one_rloc_probe_enable_disable_t *mp;
17124   u8 is_set = 0;
17125   u8 is_en = 0;
17126   int ret;
17127
17128   /* Parse args required to build the message */
17129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17130     {
17131       if (unformat (input, "enable"))
17132         {
17133           is_set = 1;
17134           is_en = 1;
17135         }
17136       else if (unformat (input, "disable"))
17137         is_set = 1;
17138       else
17139         break;
17140     }
17141
17142   if (!is_set)
17143     {
17144       errmsg ("Value not set");
17145       return -99;
17146     }
17147
17148   /* Construct the API message */
17149   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17150
17151   mp->is_enabled = is_en;
17152
17153   /* send it... */
17154   S (mp);
17155
17156   /* Wait for a reply... */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17162
17163 static int
17164 api_one_map_register_enable_disable (vat_main_t * vam)
17165 {
17166   unformat_input_t *input = vam->input;
17167   vl_api_one_map_register_enable_disable_t *mp;
17168   u8 is_set = 0;
17169   u8 is_en = 0;
17170   int ret;
17171
17172   /* Parse args required to build the message */
17173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17174     {
17175       if (unformat (input, "enable"))
17176         {
17177           is_set = 1;
17178           is_en = 1;
17179         }
17180       else if (unformat (input, "disable"))
17181         is_set = 1;
17182       else
17183         break;
17184     }
17185
17186   if (!is_set)
17187     {
17188       errmsg ("Value not set");
17189       return -99;
17190     }
17191
17192   /* Construct the API message */
17193   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17194
17195   mp->is_enabled = is_en;
17196
17197   /* send it... */
17198   S (mp);
17199
17200   /* Wait for a reply... */
17201   W (ret);
17202   return ret;
17203 }
17204
17205 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17206
17207 static int
17208 api_one_enable_disable (vat_main_t * vam)
17209 {
17210   unformat_input_t *input = vam->input;
17211   vl_api_one_enable_disable_t *mp;
17212   u8 is_set = 0;
17213   u8 is_en = 0;
17214   int ret;
17215
17216   /* Parse args required to build the message */
17217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17218     {
17219       if (unformat (input, "enable"))
17220         {
17221           is_set = 1;
17222           is_en = 1;
17223         }
17224       else if (unformat (input, "disable"))
17225         {
17226           is_set = 1;
17227         }
17228       else
17229         break;
17230     }
17231
17232   if (!is_set)
17233     {
17234       errmsg ("Value not set");
17235       return -99;
17236     }
17237
17238   /* Construct the API message */
17239   M (ONE_ENABLE_DISABLE, mp);
17240
17241   mp->is_en = is_en;
17242
17243   /* send it... */
17244   S (mp);
17245
17246   /* Wait for a reply... */
17247   W (ret);
17248   return ret;
17249 }
17250
17251 #define api_lisp_enable_disable api_one_enable_disable
17252
17253 static int
17254 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17255 {
17256   unformat_input_t *input = vam->input;
17257   vl_api_one_enable_disable_xtr_mode_t *mp;
17258   u8 is_set = 0;
17259   u8 is_en = 0;
17260   int ret;
17261
17262   /* Parse args required to build the message */
17263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17264     {
17265       if (unformat (input, "enable"))
17266         {
17267           is_set = 1;
17268           is_en = 1;
17269         }
17270       else if (unformat (input, "disable"))
17271         {
17272           is_set = 1;
17273         }
17274       else
17275         break;
17276     }
17277
17278   if (!is_set)
17279     {
17280       errmsg ("Value not set");
17281       return -99;
17282     }
17283
17284   /* Construct the API message */
17285   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17286
17287   mp->is_en = is_en;
17288
17289   /* send it... */
17290   S (mp);
17291
17292   /* Wait for a reply... */
17293   W (ret);
17294   return ret;
17295 }
17296
17297 static int
17298 api_one_show_xtr_mode (vat_main_t * vam)
17299 {
17300   vl_api_one_show_xtr_mode_t *mp;
17301   int ret;
17302
17303   /* Construct the API message */
17304   M (ONE_SHOW_XTR_MODE, mp);
17305
17306   /* send it... */
17307   S (mp);
17308
17309   /* Wait for a reply... */
17310   W (ret);
17311   return ret;
17312 }
17313
17314 static int
17315 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17316 {
17317   unformat_input_t *input = vam->input;
17318   vl_api_one_enable_disable_pitr_mode_t *mp;
17319   u8 is_set = 0;
17320   u8 is_en = 0;
17321   int ret;
17322
17323   /* Parse args required to build the message */
17324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (input, "enable"))
17327         {
17328           is_set = 1;
17329           is_en = 1;
17330         }
17331       else if (unformat (input, "disable"))
17332         {
17333           is_set = 1;
17334         }
17335       else
17336         break;
17337     }
17338
17339   if (!is_set)
17340     {
17341       errmsg ("Value not set");
17342       return -99;
17343     }
17344
17345   /* Construct the API message */
17346   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17347
17348   mp->is_en = is_en;
17349
17350   /* send it... */
17351   S (mp);
17352
17353   /* Wait for a reply... */
17354   W (ret);
17355   return ret;
17356 }
17357
17358 static int
17359 api_one_show_pitr_mode (vat_main_t * vam)
17360 {
17361   vl_api_one_show_pitr_mode_t *mp;
17362   int ret;
17363
17364   /* Construct the API message */
17365   M (ONE_SHOW_PITR_MODE, mp);
17366
17367   /* send it... */
17368   S (mp);
17369
17370   /* Wait for a reply... */
17371   W (ret);
17372   return ret;
17373 }
17374
17375 static int
17376 api_one_enable_disable_petr_mode (vat_main_t * vam)
17377 {
17378   unformat_input_t *input = vam->input;
17379   vl_api_one_enable_disable_petr_mode_t *mp;
17380   u8 is_set = 0;
17381   u8 is_en = 0;
17382   int ret;
17383
17384   /* Parse args required to build the message */
17385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17386     {
17387       if (unformat (input, "enable"))
17388         {
17389           is_set = 1;
17390           is_en = 1;
17391         }
17392       else if (unformat (input, "disable"))
17393         {
17394           is_set = 1;
17395         }
17396       else
17397         break;
17398     }
17399
17400   if (!is_set)
17401     {
17402       errmsg ("Value not set");
17403       return -99;
17404     }
17405
17406   /* Construct the API message */
17407   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17408
17409   mp->is_en = is_en;
17410
17411   /* send it... */
17412   S (mp);
17413
17414   /* Wait for a reply... */
17415   W (ret);
17416   return ret;
17417 }
17418
17419 static int
17420 api_one_show_petr_mode (vat_main_t * vam)
17421 {
17422   vl_api_one_show_petr_mode_t *mp;
17423   int ret;
17424
17425   /* Construct the API message */
17426   M (ONE_SHOW_PETR_MODE, mp);
17427
17428   /* send it... */
17429   S (mp);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_show_one_map_register_state (vat_main_t * vam)
17438 {
17439   vl_api_show_one_map_register_state_t *mp;
17440   int ret;
17441
17442   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17443
17444   /* send */
17445   S (mp);
17446
17447   /* wait for reply */
17448   W (ret);
17449   return ret;
17450 }
17451
17452 #define api_show_lisp_map_register_state api_show_one_map_register_state
17453
17454 static int
17455 api_show_one_rloc_probe_state (vat_main_t * vam)
17456 {
17457   vl_api_show_one_rloc_probe_state_t *mp;
17458   int ret;
17459
17460   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17461
17462   /* send */
17463   S (mp);
17464
17465   /* wait for reply */
17466   W (ret);
17467   return ret;
17468 }
17469
17470 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17471
17472 static int
17473 api_one_add_del_ndp_entry (vat_main_t * vam)
17474 {
17475   vl_api_one_add_del_ndp_entry_t *mp;
17476   unformat_input_t *input = vam->input;
17477   u8 is_add = 1;
17478   u8 mac_set = 0;
17479   u8 bd_set = 0;
17480   u8 ip_set = 0;
17481   u8 mac[6] = { 0, };
17482   u8 ip6[16] = { 0, };
17483   u32 bd = ~0;
17484   int ret;
17485
17486   /* Parse args required to build the message */
17487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17488     {
17489       if (unformat (input, "del"))
17490         is_add = 0;
17491       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17492         mac_set = 1;
17493       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17494         ip_set = 1;
17495       else if (unformat (input, "bd %d", &bd))
17496         bd_set = 1;
17497       else
17498         {
17499           errmsg ("parse error '%U'", format_unformat_error, input);
17500           return -99;
17501         }
17502     }
17503
17504   if (!bd_set || !ip_set || (!mac_set && is_add))
17505     {
17506       errmsg ("Missing BD, IP or MAC!");
17507       return -99;
17508     }
17509
17510   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17511   mp->is_add = is_add;
17512   clib_memcpy (mp->mac, mac, 6);
17513   mp->bd = clib_host_to_net_u32 (bd);
17514   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17515
17516   /* send */
17517   S (mp);
17518
17519   /* wait for reply */
17520   W (ret);
17521   return ret;
17522 }
17523
17524 static int
17525 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17526 {
17527   vl_api_one_add_del_l2_arp_entry_t *mp;
17528   unformat_input_t *input = vam->input;
17529   u8 is_add = 1;
17530   u8 mac_set = 0;
17531   u8 bd_set = 0;
17532   u8 ip_set = 0;
17533   u8 mac[6] = { 0, };
17534   u32 ip4 = 0, bd = ~0;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "del"))
17541         is_add = 0;
17542       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17543         mac_set = 1;
17544       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17545         ip_set = 1;
17546       else if (unformat (input, "bd %d", &bd))
17547         bd_set = 1;
17548       else
17549         {
17550           errmsg ("parse error '%U'", format_unformat_error, input);
17551           return -99;
17552         }
17553     }
17554
17555   if (!bd_set || !ip_set || (!mac_set && is_add))
17556     {
17557       errmsg ("Missing BD, IP or MAC!");
17558       return -99;
17559     }
17560
17561   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17562   mp->is_add = is_add;
17563   clib_memcpy (mp->mac, mac, 6);
17564   mp->bd = clib_host_to_net_u32 (bd);
17565   mp->ip4 = ip4;
17566
17567   /* send */
17568   S (mp);
17569
17570   /* wait for reply */
17571   W (ret);
17572   return ret;
17573 }
17574
17575 static int
17576 api_one_ndp_bd_get (vat_main_t * vam)
17577 {
17578   vl_api_one_ndp_bd_get_t *mp;
17579   int ret;
17580
17581   M (ONE_NDP_BD_GET, mp);
17582
17583   /* send */
17584   S (mp);
17585
17586   /* wait for reply */
17587   W (ret);
17588   return ret;
17589 }
17590
17591 static int
17592 api_one_ndp_entries_get (vat_main_t * vam)
17593 {
17594   vl_api_one_ndp_entries_get_t *mp;
17595   unformat_input_t *input = vam->input;
17596   u8 bd_set = 0;
17597   u32 bd = ~0;
17598   int ret;
17599
17600   /* Parse args required to build the message */
17601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17602     {
17603       if (unformat (input, "bd %d", &bd))
17604         bd_set = 1;
17605       else
17606         {
17607           errmsg ("parse error '%U'", format_unformat_error, input);
17608           return -99;
17609         }
17610     }
17611
17612   if (!bd_set)
17613     {
17614       errmsg ("Expected bridge domain!");
17615       return -99;
17616     }
17617
17618   M (ONE_NDP_ENTRIES_GET, mp);
17619   mp->bd = clib_host_to_net_u32 (bd);
17620
17621   /* send */
17622   S (mp);
17623
17624   /* wait for reply */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 static int
17630 api_one_l2_arp_bd_get (vat_main_t * vam)
17631 {
17632   vl_api_one_l2_arp_bd_get_t *mp;
17633   int ret;
17634
17635   M (ONE_L2_ARP_BD_GET, mp);
17636
17637   /* send */
17638   S (mp);
17639
17640   /* wait for reply */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 static int
17646 api_one_l2_arp_entries_get (vat_main_t * vam)
17647 {
17648   vl_api_one_l2_arp_entries_get_t *mp;
17649   unformat_input_t *input = vam->input;
17650   u8 bd_set = 0;
17651   u32 bd = ~0;
17652   int ret;
17653
17654   /* Parse args required to build the message */
17655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17656     {
17657       if (unformat (input, "bd %d", &bd))
17658         bd_set = 1;
17659       else
17660         {
17661           errmsg ("parse error '%U'", format_unformat_error, input);
17662           return -99;
17663         }
17664     }
17665
17666   if (!bd_set)
17667     {
17668       errmsg ("Expected bridge domain!");
17669       return -99;
17670     }
17671
17672   M (ONE_L2_ARP_ENTRIES_GET, mp);
17673   mp->bd = clib_host_to_net_u32 (bd);
17674
17675   /* send */
17676   S (mp);
17677
17678   /* wait for reply */
17679   W (ret);
17680   return ret;
17681 }
17682
17683 static int
17684 api_one_stats_enable_disable (vat_main_t * vam)
17685 {
17686   vl_api_one_stats_enable_disable_t *mp;
17687   unformat_input_t *input = vam->input;
17688   u8 is_set = 0;
17689   u8 is_en = 0;
17690   int ret;
17691
17692   /* Parse args required to build the message */
17693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17694     {
17695       if (unformat (input, "enable"))
17696         {
17697           is_set = 1;
17698           is_en = 1;
17699         }
17700       else if (unformat (input, "disable"))
17701         {
17702           is_set = 1;
17703         }
17704       else
17705         break;
17706     }
17707
17708   if (!is_set)
17709     {
17710       errmsg ("Value not set");
17711       return -99;
17712     }
17713
17714   M (ONE_STATS_ENABLE_DISABLE, mp);
17715   mp->is_en = is_en;
17716
17717   /* send */
17718   S (mp);
17719
17720   /* wait for reply */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 static int
17726 api_show_one_stats_enable_disable (vat_main_t * vam)
17727 {
17728   vl_api_show_one_stats_enable_disable_t *mp;
17729   int ret;
17730
17731   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17732
17733   /* send */
17734   S (mp);
17735
17736   /* wait for reply */
17737   W (ret);
17738   return ret;
17739 }
17740
17741 static int
17742 api_show_one_map_request_mode (vat_main_t * vam)
17743 {
17744   vl_api_show_one_map_request_mode_t *mp;
17745   int ret;
17746
17747   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17748
17749   /* send */
17750   S (mp);
17751
17752   /* wait for reply */
17753   W (ret);
17754   return ret;
17755 }
17756
17757 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17758
17759 static int
17760 api_one_map_request_mode (vat_main_t * vam)
17761 {
17762   unformat_input_t *input = vam->input;
17763   vl_api_one_map_request_mode_t *mp;
17764   u8 mode = 0;
17765   int ret;
17766
17767   /* Parse args required to build the message */
17768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17769     {
17770       if (unformat (input, "dst-only"))
17771         mode = 0;
17772       else if (unformat (input, "src-dst"))
17773         mode = 1;
17774       else
17775         {
17776           errmsg ("parse error '%U'", format_unformat_error, input);
17777           return -99;
17778         }
17779     }
17780
17781   M (ONE_MAP_REQUEST_MODE, mp);
17782
17783   mp->mode = mode;
17784
17785   /* send */
17786   S (mp);
17787
17788   /* wait for reply */
17789   W (ret);
17790   return ret;
17791 }
17792
17793 #define api_lisp_map_request_mode api_one_map_request_mode
17794
17795 /**
17796  * Enable/disable ONE proxy ITR.
17797  *
17798  * @param vam vpp API test context
17799  * @return return code
17800  */
17801 static int
17802 api_one_pitr_set_locator_set (vat_main_t * vam)
17803 {
17804   u8 ls_name_set = 0;
17805   unformat_input_t *input = vam->input;
17806   vl_api_one_pitr_set_locator_set_t *mp;
17807   u8 is_add = 1;
17808   u8 *ls_name = 0;
17809   int ret;
17810
17811   /* Parse args required to build the message */
17812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17813     {
17814       if (unformat (input, "del"))
17815         is_add = 0;
17816       else if (unformat (input, "locator-set %s", &ls_name))
17817         ls_name_set = 1;
17818       else
17819         {
17820           errmsg ("parse error '%U'", format_unformat_error, input);
17821           return -99;
17822         }
17823     }
17824
17825   if (!ls_name_set)
17826     {
17827       errmsg ("locator-set name not set!");
17828       return -99;
17829     }
17830
17831   M (ONE_PITR_SET_LOCATOR_SET, mp);
17832
17833   mp->is_add = is_add;
17834   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17835   vec_free (ls_name);
17836
17837   /* send */
17838   S (mp);
17839
17840   /* wait for reply */
17841   W (ret);
17842   return ret;
17843 }
17844
17845 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17846
17847 static int
17848 api_one_nsh_set_locator_set (vat_main_t * vam)
17849 {
17850   u8 ls_name_set = 0;
17851   unformat_input_t *input = vam->input;
17852   vl_api_one_nsh_set_locator_set_t *mp;
17853   u8 is_add = 1;
17854   u8 *ls_name = 0;
17855   int ret;
17856
17857   /* Parse args required to build the message */
17858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17859     {
17860       if (unformat (input, "del"))
17861         is_add = 0;
17862       else if (unformat (input, "ls %s", &ls_name))
17863         ls_name_set = 1;
17864       else
17865         {
17866           errmsg ("parse error '%U'", format_unformat_error, input);
17867           return -99;
17868         }
17869     }
17870
17871   if (!ls_name_set && is_add)
17872     {
17873       errmsg ("locator-set name not set!");
17874       return -99;
17875     }
17876
17877   M (ONE_NSH_SET_LOCATOR_SET, mp);
17878
17879   mp->is_add = is_add;
17880   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17881   vec_free (ls_name);
17882
17883   /* send */
17884   S (mp);
17885
17886   /* wait for reply */
17887   W (ret);
17888   return ret;
17889 }
17890
17891 static int
17892 api_show_one_pitr (vat_main_t * vam)
17893 {
17894   vl_api_show_one_pitr_t *mp;
17895   int ret;
17896
17897   if (!vam->json_output)
17898     {
17899       print (vam->ofp, "%=20s", "lisp status:");
17900     }
17901
17902   M (SHOW_ONE_PITR, mp);
17903   /* send it... */
17904   S (mp);
17905
17906   /* Wait for a reply... */
17907   W (ret);
17908   return ret;
17909 }
17910
17911 #define api_show_lisp_pitr api_show_one_pitr
17912
17913 static int
17914 api_one_use_petr (vat_main_t * vam)
17915 {
17916   unformat_input_t *input = vam->input;
17917   vl_api_one_use_petr_t *mp;
17918   u8 is_add = 0;
17919   ip_address_t ip;
17920   int ret;
17921
17922   clib_memset (&ip, 0, sizeof (ip));
17923
17924   /* Parse args required to build the message */
17925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17926     {
17927       if (unformat (input, "disable"))
17928         is_add = 0;
17929       else
17930         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17931         {
17932           is_add = 1;
17933           ip_addr_version (&ip) = IP4;
17934         }
17935       else
17936         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17937         {
17938           is_add = 1;
17939           ip_addr_version (&ip) = IP6;
17940         }
17941       else
17942         {
17943           errmsg ("parse error '%U'", format_unformat_error, input);
17944           return -99;
17945         }
17946     }
17947
17948   M (ONE_USE_PETR, mp);
17949
17950   mp->is_add = is_add;
17951   if (is_add)
17952     {
17953       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17954       if (mp->is_ip4)
17955         clib_memcpy (mp->address, &ip, 4);
17956       else
17957         clib_memcpy (mp->address, &ip, 16);
17958     }
17959
17960   /* send */
17961   S (mp);
17962
17963   /* wait for reply */
17964   W (ret);
17965   return ret;
17966 }
17967
17968 #define api_lisp_use_petr api_one_use_petr
17969
17970 static int
17971 api_show_one_nsh_mapping (vat_main_t * vam)
17972 {
17973   vl_api_show_one_use_petr_t *mp;
17974   int ret;
17975
17976   if (!vam->json_output)
17977     {
17978       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17979     }
17980
17981   M (SHOW_ONE_NSH_MAPPING, mp);
17982   /* send it... */
17983   S (mp);
17984
17985   /* Wait for a reply... */
17986   W (ret);
17987   return ret;
17988 }
17989
17990 static int
17991 api_show_one_use_petr (vat_main_t * vam)
17992 {
17993   vl_api_show_one_use_petr_t *mp;
17994   int ret;
17995
17996   if (!vam->json_output)
17997     {
17998       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17999     }
18000
18001   M (SHOW_ONE_USE_PETR, mp);
18002   /* send it... */
18003   S (mp);
18004
18005   /* Wait for a reply... */
18006   W (ret);
18007   return ret;
18008 }
18009
18010 #define api_show_lisp_use_petr api_show_one_use_petr
18011
18012 /**
18013  * Add/delete mapping between vni and vrf
18014  */
18015 static int
18016 api_one_eid_table_add_del_map (vat_main_t * vam)
18017 {
18018   unformat_input_t *input = vam->input;
18019   vl_api_one_eid_table_add_del_map_t *mp;
18020   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18021   u32 vni, vrf, bd_index;
18022   int ret;
18023
18024   /* Parse args required to build the message */
18025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18026     {
18027       if (unformat (input, "del"))
18028         is_add = 0;
18029       else if (unformat (input, "vrf %d", &vrf))
18030         vrf_set = 1;
18031       else if (unformat (input, "bd_index %d", &bd_index))
18032         bd_index_set = 1;
18033       else if (unformat (input, "vni %d", &vni))
18034         vni_set = 1;
18035       else
18036         break;
18037     }
18038
18039   if (!vni_set || (!vrf_set && !bd_index_set))
18040     {
18041       errmsg ("missing arguments!");
18042       return -99;
18043     }
18044
18045   if (vrf_set && bd_index_set)
18046     {
18047       errmsg ("error: both vrf and bd entered!");
18048       return -99;
18049     }
18050
18051   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18052
18053   mp->is_add = is_add;
18054   mp->vni = htonl (vni);
18055   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18056   mp->is_l2 = bd_index_set;
18057
18058   /* send */
18059   S (mp);
18060
18061   /* wait for reply */
18062   W (ret);
18063   return ret;
18064 }
18065
18066 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18067
18068 uword
18069 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18070 {
18071   u32 *action = va_arg (*args, u32 *);
18072   u8 *s = 0;
18073
18074   if (unformat (input, "%s", &s))
18075     {
18076       if (!strcmp ((char *) s, "no-action"))
18077         action[0] = 0;
18078       else if (!strcmp ((char *) s, "natively-forward"))
18079         action[0] = 1;
18080       else if (!strcmp ((char *) s, "send-map-request"))
18081         action[0] = 2;
18082       else if (!strcmp ((char *) s, "drop"))
18083         action[0] = 3;
18084       else
18085         {
18086           clib_warning ("invalid action: '%s'", s);
18087           action[0] = 3;
18088         }
18089     }
18090   else
18091     return 0;
18092
18093   vec_free (s);
18094   return 1;
18095 }
18096
18097 /**
18098  * Add/del remote mapping to/from ONE control plane
18099  *
18100  * @param vam vpp API test context
18101  * @return return code
18102  */
18103 static int
18104 api_one_add_del_remote_mapping (vat_main_t * vam)
18105 {
18106   unformat_input_t *input = vam->input;
18107   vl_api_one_add_del_remote_mapping_t *mp;
18108   u32 vni = 0;
18109   lisp_eid_vat_t _eid, *eid = &_eid;
18110   lisp_eid_vat_t _seid, *seid = &_seid;
18111   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18112   u32 action = ~0, p, w, data_len;
18113   ip4_address_t rloc4;
18114   ip6_address_t rloc6;
18115   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18116   int ret;
18117
18118   clib_memset (&rloc, 0, sizeof (rloc));
18119
18120   /* Parse args required to build the message */
18121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (input, "del-all"))
18124         {
18125           del_all = 1;
18126         }
18127       else if (unformat (input, "del"))
18128         {
18129           is_add = 0;
18130         }
18131       else if (unformat (input, "add"))
18132         {
18133           is_add = 1;
18134         }
18135       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18136         {
18137           eid_set = 1;
18138         }
18139       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18140         {
18141           seid_set = 1;
18142         }
18143       else if (unformat (input, "vni %d", &vni))
18144         {
18145           ;
18146         }
18147       else if (unformat (input, "p %d w %d", &p, &w))
18148         {
18149           if (!curr_rloc)
18150             {
18151               errmsg ("No RLOC configured for setting priority/weight!");
18152               return -99;
18153             }
18154           curr_rloc->priority = p;
18155           curr_rloc->weight = w;
18156         }
18157       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18158         {
18159           rloc.is_ip4 = 1;
18160           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18161           vec_add1 (rlocs, rloc);
18162           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18163         }
18164       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18165         {
18166           rloc.is_ip4 = 0;
18167           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18168           vec_add1 (rlocs, rloc);
18169           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18170         }
18171       else if (unformat (input, "action %U",
18172                          unformat_negative_mapping_action, &action))
18173         {
18174           ;
18175         }
18176       else
18177         {
18178           clib_warning ("parse error '%U'", format_unformat_error, input);
18179           return -99;
18180         }
18181     }
18182
18183   if (0 == eid_set)
18184     {
18185       errmsg ("missing params!");
18186       return -99;
18187     }
18188
18189   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18190     {
18191       errmsg ("no action set for negative map-reply!");
18192       return -99;
18193     }
18194
18195   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18196
18197   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18198   mp->is_add = is_add;
18199   mp->vni = htonl (vni);
18200   mp->action = (u8) action;
18201   mp->is_src_dst = seid_set;
18202   mp->eid_len = eid->len;
18203   mp->seid_len = seid->len;
18204   mp->del_all = del_all;
18205   mp->eid_type = eid->type;
18206   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18207   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18208
18209   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18210   clib_memcpy (mp->rlocs, rlocs, data_len);
18211   vec_free (rlocs);
18212
18213   /* send it... */
18214   S (mp);
18215
18216   /* Wait for a reply... */
18217   W (ret);
18218   return ret;
18219 }
18220
18221 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18222
18223 /**
18224  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18225  * forwarding entries in data-plane accordingly.
18226  *
18227  * @param vam vpp API test context
18228  * @return return code
18229  */
18230 static int
18231 api_one_add_del_adjacency (vat_main_t * vam)
18232 {
18233   unformat_input_t *input = vam->input;
18234   vl_api_one_add_del_adjacency_t *mp;
18235   u32 vni = 0;
18236   ip4_address_t leid4, reid4;
18237   ip6_address_t leid6, reid6;
18238   u8 reid_mac[6] = { 0 };
18239   u8 leid_mac[6] = { 0 };
18240   u8 reid_type, leid_type;
18241   u32 leid_len = 0, reid_len = 0, len;
18242   u8 is_add = 1;
18243   int ret;
18244
18245   leid_type = reid_type = (u8) ~ 0;
18246
18247   /* Parse args required to build the message */
18248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18249     {
18250       if (unformat (input, "del"))
18251         {
18252           is_add = 0;
18253         }
18254       else if (unformat (input, "add"))
18255         {
18256           is_add = 1;
18257         }
18258       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18259                          &reid4, &len))
18260         {
18261           reid_type = 0;        /* ipv4 */
18262           reid_len = len;
18263         }
18264       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18265                          &reid6, &len))
18266         {
18267           reid_type = 1;        /* ipv6 */
18268           reid_len = len;
18269         }
18270       else if (unformat (input, "reid %U", unformat_ethernet_address,
18271                          reid_mac))
18272         {
18273           reid_type = 2;        /* mac */
18274         }
18275       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18276                          &leid4, &len))
18277         {
18278           leid_type = 0;        /* ipv4 */
18279           leid_len = len;
18280         }
18281       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18282                          &leid6, &len))
18283         {
18284           leid_type = 1;        /* ipv6 */
18285           leid_len = len;
18286         }
18287       else if (unformat (input, "leid %U", unformat_ethernet_address,
18288                          leid_mac))
18289         {
18290           leid_type = 2;        /* mac */
18291         }
18292       else if (unformat (input, "vni %d", &vni))
18293         {
18294           ;
18295         }
18296       else
18297         {
18298           errmsg ("parse error '%U'", format_unformat_error, input);
18299           return -99;
18300         }
18301     }
18302
18303   if ((u8) ~ 0 == reid_type)
18304     {
18305       errmsg ("missing params!");
18306       return -99;
18307     }
18308
18309   if (leid_type != reid_type)
18310     {
18311       errmsg ("remote and local EIDs are of different types!");
18312       return -99;
18313     }
18314
18315   M (ONE_ADD_DEL_ADJACENCY, mp);
18316   mp->is_add = is_add;
18317   mp->vni = htonl (vni);
18318   mp->leid_len = leid_len;
18319   mp->reid_len = reid_len;
18320   mp->eid_type = reid_type;
18321
18322   switch (mp->eid_type)
18323     {
18324     case 0:
18325       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18326       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18327       break;
18328     case 1:
18329       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18330       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18331       break;
18332     case 2:
18333       clib_memcpy (mp->leid, leid_mac, 6);
18334       clib_memcpy (mp->reid, reid_mac, 6);
18335       break;
18336     default:
18337       errmsg ("unknown EID type %d!", mp->eid_type);
18338       return 0;
18339     }
18340
18341   /* send it... */
18342   S (mp);
18343
18344   /* Wait for a reply... */
18345   W (ret);
18346   return ret;
18347 }
18348
18349 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18350
18351 uword
18352 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18353 {
18354   u32 *mode = va_arg (*args, u32 *);
18355
18356   if (unformat (input, "lisp"))
18357     *mode = 0;
18358   else if (unformat (input, "vxlan"))
18359     *mode = 1;
18360   else
18361     return 0;
18362
18363   return 1;
18364 }
18365
18366 static int
18367 api_gpe_get_encap_mode (vat_main_t * vam)
18368 {
18369   vl_api_gpe_get_encap_mode_t *mp;
18370   int ret;
18371
18372   /* Construct the API message */
18373   M (GPE_GET_ENCAP_MODE, mp);
18374
18375   /* send it... */
18376   S (mp);
18377
18378   /* Wait for a reply... */
18379   W (ret);
18380   return ret;
18381 }
18382
18383 static int
18384 api_gpe_set_encap_mode (vat_main_t * vam)
18385 {
18386   unformat_input_t *input = vam->input;
18387   vl_api_gpe_set_encap_mode_t *mp;
18388   int ret;
18389   u32 mode = 0;
18390
18391   /* Parse args required to build the message */
18392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18393     {
18394       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18395         ;
18396       else
18397         break;
18398     }
18399
18400   /* Construct the API message */
18401   M (GPE_SET_ENCAP_MODE, mp);
18402
18403   mp->mode = mode;
18404
18405   /* send it... */
18406   S (mp);
18407
18408   /* Wait for a reply... */
18409   W (ret);
18410   return ret;
18411 }
18412
18413 static int
18414 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18415 {
18416   unformat_input_t *input = vam->input;
18417   vl_api_gpe_add_del_iface_t *mp;
18418   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18419   u32 dp_table = 0, vni = 0;
18420   int ret;
18421
18422   /* Parse args required to build the message */
18423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18424     {
18425       if (unformat (input, "up"))
18426         {
18427           action_set = 1;
18428           is_add = 1;
18429         }
18430       else if (unformat (input, "down"))
18431         {
18432           action_set = 1;
18433           is_add = 0;
18434         }
18435       else if (unformat (input, "table_id %d", &dp_table))
18436         {
18437           dp_table_set = 1;
18438         }
18439       else if (unformat (input, "bd_id %d", &dp_table))
18440         {
18441           dp_table_set = 1;
18442           is_l2 = 1;
18443         }
18444       else if (unformat (input, "vni %d", &vni))
18445         {
18446           vni_set = 1;
18447         }
18448       else
18449         break;
18450     }
18451
18452   if (action_set == 0)
18453     {
18454       errmsg ("Action not set");
18455       return -99;
18456     }
18457   if (dp_table_set == 0 || vni_set == 0)
18458     {
18459       errmsg ("vni and dp_table must be set");
18460       return -99;
18461     }
18462
18463   /* Construct the API message */
18464   M (GPE_ADD_DEL_IFACE, mp);
18465
18466   mp->is_add = is_add;
18467   mp->dp_table = clib_host_to_net_u32 (dp_table);
18468   mp->is_l2 = is_l2;
18469   mp->vni = clib_host_to_net_u32 (vni);
18470
18471   /* send it... */
18472   S (mp);
18473
18474   /* Wait for a reply... */
18475   W (ret);
18476   return ret;
18477 }
18478
18479 static int
18480 api_one_map_register_fallback_threshold (vat_main_t * vam)
18481 {
18482   unformat_input_t *input = vam->input;
18483   vl_api_one_map_register_fallback_threshold_t *mp;
18484   u32 value = 0;
18485   u8 is_set = 0;
18486   int ret;
18487
18488   /* Parse args required to build the message */
18489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18490     {
18491       if (unformat (input, "%u", &value))
18492         is_set = 1;
18493       else
18494         {
18495           clib_warning ("parse error '%U'", format_unformat_error, input);
18496           return -99;
18497         }
18498     }
18499
18500   if (!is_set)
18501     {
18502       errmsg ("fallback threshold value is missing!");
18503       return -99;
18504     }
18505
18506   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18507   mp->value = clib_host_to_net_u32 (value);
18508
18509   /* send it... */
18510   S (mp);
18511
18512   /* Wait for a reply... */
18513   W (ret);
18514   return ret;
18515 }
18516
18517 static int
18518 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18519 {
18520   vl_api_show_one_map_register_fallback_threshold_t *mp;
18521   int ret;
18522
18523   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18524
18525   /* send it... */
18526   S (mp);
18527
18528   /* Wait for a reply... */
18529   W (ret);
18530   return ret;
18531 }
18532
18533 uword
18534 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18535 {
18536   u32 *proto = va_arg (*args, u32 *);
18537
18538   if (unformat (input, "udp"))
18539     *proto = 1;
18540   else if (unformat (input, "api"))
18541     *proto = 2;
18542   else
18543     return 0;
18544
18545   return 1;
18546 }
18547
18548 static int
18549 api_one_set_transport_protocol (vat_main_t * vam)
18550 {
18551   unformat_input_t *input = vam->input;
18552   vl_api_one_set_transport_protocol_t *mp;
18553   u8 is_set = 0;
18554   u32 protocol = 0;
18555   int ret;
18556
18557   /* Parse args required to build the message */
18558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18559     {
18560       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18561         is_set = 1;
18562       else
18563         {
18564           clib_warning ("parse error '%U'", format_unformat_error, input);
18565           return -99;
18566         }
18567     }
18568
18569   if (!is_set)
18570     {
18571       errmsg ("Transport protocol missing!");
18572       return -99;
18573     }
18574
18575   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18576   mp->protocol = (u8) protocol;
18577
18578   /* send it... */
18579   S (mp);
18580
18581   /* Wait for a reply... */
18582   W (ret);
18583   return ret;
18584 }
18585
18586 static int
18587 api_one_get_transport_protocol (vat_main_t * vam)
18588 {
18589   vl_api_one_get_transport_protocol_t *mp;
18590   int ret;
18591
18592   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18593
18594   /* send it... */
18595   S (mp);
18596
18597   /* Wait for a reply... */
18598   W (ret);
18599   return ret;
18600 }
18601
18602 static int
18603 api_one_map_register_set_ttl (vat_main_t * vam)
18604 {
18605   unformat_input_t *input = vam->input;
18606   vl_api_one_map_register_set_ttl_t *mp;
18607   u32 ttl = 0;
18608   u8 is_set = 0;
18609   int ret;
18610
18611   /* Parse args required to build the message */
18612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18613     {
18614       if (unformat (input, "%u", &ttl))
18615         is_set = 1;
18616       else
18617         {
18618           clib_warning ("parse error '%U'", format_unformat_error, input);
18619           return -99;
18620         }
18621     }
18622
18623   if (!is_set)
18624     {
18625       errmsg ("TTL value missing!");
18626       return -99;
18627     }
18628
18629   M (ONE_MAP_REGISTER_SET_TTL, mp);
18630   mp->ttl = clib_host_to_net_u32 (ttl);
18631
18632   /* send it... */
18633   S (mp);
18634
18635   /* Wait for a reply... */
18636   W (ret);
18637   return ret;
18638 }
18639
18640 static int
18641 api_show_one_map_register_ttl (vat_main_t * vam)
18642 {
18643   vl_api_show_one_map_register_ttl_t *mp;
18644   int ret;
18645
18646   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18647
18648   /* send it... */
18649   S (mp);
18650
18651   /* Wait for a reply... */
18652   W (ret);
18653   return ret;
18654 }
18655
18656 /**
18657  * Add/del map request itr rlocs from ONE control plane and updates
18658  *
18659  * @param vam vpp API test context
18660  * @return return code
18661  */
18662 static int
18663 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18664 {
18665   unformat_input_t *input = vam->input;
18666   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18667   u8 *locator_set_name = 0;
18668   u8 locator_set_name_set = 0;
18669   u8 is_add = 1;
18670   int ret;
18671
18672   /* Parse args required to build the message */
18673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18674     {
18675       if (unformat (input, "del"))
18676         {
18677           is_add = 0;
18678         }
18679       else if (unformat (input, "%_%v%_", &locator_set_name))
18680         {
18681           locator_set_name_set = 1;
18682         }
18683       else
18684         {
18685           clib_warning ("parse error '%U'", format_unformat_error, input);
18686           return -99;
18687         }
18688     }
18689
18690   if (is_add && !locator_set_name_set)
18691     {
18692       errmsg ("itr-rloc is not set!");
18693       return -99;
18694     }
18695
18696   if (is_add && vec_len (locator_set_name) > 64)
18697     {
18698       errmsg ("itr-rloc locator-set name too long");
18699       vec_free (locator_set_name);
18700       return -99;
18701     }
18702
18703   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18704   mp->is_add = is_add;
18705   if (is_add)
18706     {
18707       clib_memcpy (mp->locator_set_name, locator_set_name,
18708                    vec_len (locator_set_name));
18709     }
18710   else
18711     {
18712       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18713     }
18714   vec_free (locator_set_name);
18715
18716   /* send it... */
18717   S (mp);
18718
18719   /* Wait for a reply... */
18720   W (ret);
18721   return ret;
18722 }
18723
18724 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18725
18726 static int
18727 api_one_locator_dump (vat_main_t * vam)
18728 {
18729   unformat_input_t *input = vam->input;
18730   vl_api_one_locator_dump_t *mp;
18731   vl_api_control_ping_t *mp_ping;
18732   u8 is_index_set = 0, is_name_set = 0;
18733   u8 *ls_name = 0;
18734   u32 ls_index = ~0;
18735   int ret;
18736
18737   /* Parse args required to build the message */
18738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18739     {
18740       if (unformat (input, "ls_name %_%v%_", &ls_name))
18741         {
18742           is_name_set = 1;
18743         }
18744       else if (unformat (input, "ls_index %d", &ls_index))
18745         {
18746           is_index_set = 1;
18747         }
18748       else
18749         {
18750           errmsg ("parse error '%U'", format_unformat_error, input);
18751           return -99;
18752         }
18753     }
18754
18755   if (!is_index_set && !is_name_set)
18756     {
18757       errmsg ("error: expected one of index or name!");
18758       return -99;
18759     }
18760
18761   if (is_index_set && is_name_set)
18762     {
18763       errmsg ("error: only one param expected!");
18764       return -99;
18765     }
18766
18767   if (vec_len (ls_name) > 62)
18768     {
18769       errmsg ("error: locator set name too long!");
18770       return -99;
18771     }
18772
18773   if (!vam->json_output)
18774     {
18775       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18776     }
18777
18778   M (ONE_LOCATOR_DUMP, mp);
18779   mp->is_index_set = is_index_set;
18780
18781   if (is_index_set)
18782     mp->ls_index = clib_host_to_net_u32 (ls_index);
18783   else
18784     {
18785       vec_add1 (ls_name, 0);
18786       strncpy ((char *) mp->ls_name, (char *) ls_name,
18787                sizeof (mp->ls_name) - 1);
18788     }
18789
18790   /* send it... */
18791   S (mp);
18792
18793   /* Use a control ping for synchronization */
18794   MPING (CONTROL_PING, mp_ping);
18795   S (mp_ping);
18796
18797   /* Wait for a reply... */
18798   W (ret);
18799   return ret;
18800 }
18801
18802 #define api_lisp_locator_dump api_one_locator_dump
18803
18804 static int
18805 api_one_locator_set_dump (vat_main_t * vam)
18806 {
18807   vl_api_one_locator_set_dump_t *mp;
18808   vl_api_control_ping_t *mp_ping;
18809   unformat_input_t *input = vam->input;
18810   u8 filter = 0;
18811   int ret;
18812
18813   /* Parse args required to build the message */
18814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18815     {
18816       if (unformat (input, "local"))
18817         {
18818           filter = 1;
18819         }
18820       else if (unformat (input, "remote"))
18821         {
18822           filter = 2;
18823         }
18824       else
18825         {
18826           errmsg ("parse error '%U'", format_unformat_error, input);
18827           return -99;
18828         }
18829     }
18830
18831   if (!vam->json_output)
18832     {
18833       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18834     }
18835
18836   M (ONE_LOCATOR_SET_DUMP, mp);
18837
18838   mp->filter = filter;
18839
18840   /* send it... */
18841   S (mp);
18842
18843   /* Use a control ping for synchronization */
18844   MPING (CONTROL_PING, mp_ping);
18845   S (mp_ping);
18846
18847   /* Wait for a reply... */
18848   W (ret);
18849   return ret;
18850 }
18851
18852 #define api_lisp_locator_set_dump api_one_locator_set_dump
18853
18854 static int
18855 api_one_eid_table_map_dump (vat_main_t * vam)
18856 {
18857   u8 is_l2 = 0;
18858   u8 mode_set = 0;
18859   unformat_input_t *input = vam->input;
18860   vl_api_one_eid_table_map_dump_t *mp;
18861   vl_api_control_ping_t *mp_ping;
18862   int ret;
18863
18864   /* Parse args required to build the message */
18865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18866     {
18867       if (unformat (input, "l2"))
18868         {
18869           is_l2 = 1;
18870           mode_set = 1;
18871         }
18872       else if (unformat (input, "l3"))
18873         {
18874           is_l2 = 0;
18875           mode_set = 1;
18876         }
18877       else
18878         {
18879           errmsg ("parse error '%U'", format_unformat_error, input);
18880           return -99;
18881         }
18882     }
18883
18884   if (!mode_set)
18885     {
18886       errmsg ("expected one of 'l2' or 'l3' parameter!");
18887       return -99;
18888     }
18889
18890   if (!vam->json_output)
18891     {
18892       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18893     }
18894
18895   M (ONE_EID_TABLE_MAP_DUMP, mp);
18896   mp->is_l2 = is_l2;
18897
18898   /* send it... */
18899   S (mp);
18900
18901   /* Use a control ping for synchronization */
18902   MPING (CONTROL_PING, mp_ping);
18903   S (mp_ping);
18904
18905   /* Wait for a reply... */
18906   W (ret);
18907   return ret;
18908 }
18909
18910 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18911
18912 static int
18913 api_one_eid_table_vni_dump (vat_main_t * vam)
18914 {
18915   vl_api_one_eid_table_vni_dump_t *mp;
18916   vl_api_control_ping_t *mp_ping;
18917   int ret;
18918
18919   if (!vam->json_output)
18920     {
18921       print (vam->ofp, "VNI");
18922     }
18923
18924   M (ONE_EID_TABLE_VNI_DUMP, mp);
18925
18926   /* send it... */
18927   S (mp);
18928
18929   /* Use a control ping for synchronization */
18930   MPING (CONTROL_PING, mp_ping);
18931   S (mp_ping);
18932
18933   /* Wait for a reply... */
18934   W (ret);
18935   return ret;
18936 }
18937
18938 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18939
18940 static int
18941 api_one_eid_table_dump (vat_main_t * vam)
18942 {
18943   unformat_input_t *i = vam->input;
18944   vl_api_one_eid_table_dump_t *mp;
18945   vl_api_control_ping_t *mp_ping;
18946   struct in_addr ip4;
18947   struct in6_addr ip6;
18948   u8 mac[6];
18949   u8 eid_type = ~0, eid_set = 0;
18950   u32 prefix_length = ~0, t, vni = 0;
18951   u8 filter = 0;
18952   int ret;
18953   lisp_nsh_api_t nsh;
18954
18955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18956     {
18957       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18958         {
18959           eid_set = 1;
18960           eid_type = 0;
18961           prefix_length = t;
18962         }
18963       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18964         {
18965           eid_set = 1;
18966           eid_type = 1;
18967           prefix_length = t;
18968         }
18969       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18970         {
18971           eid_set = 1;
18972           eid_type = 2;
18973         }
18974       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18975         {
18976           eid_set = 1;
18977           eid_type = 3;
18978         }
18979       else if (unformat (i, "vni %d", &t))
18980         {
18981           vni = t;
18982         }
18983       else if (unformat (i, "local"))
18984         {
18985           filter = 1;
18986         }
18987       else if (unformat (i, "remote"))
18988         {
18989           filter = 2;
18990         }
18991       else
18992         {
18993           errmsg ("parse error '%U'", format_unformat_error, i);
18994           return -99;
18995         }
18996     }
18997
18998   if (!vam->json_output)
18999     {
19000       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19001              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19002     }
19003
19004   M (ONE_EID_TABLE_DUMP, mp);
19005
19006   mp->filter = filter;
19007   if (eid_set)
19008     {
19009       mp->eid_set = 1;
19010       mp->vni = htonl (vni);
19011       mp->eid_type = eid_type;
19012       switch (eid_type)
19013         {
19014         case 0:
19015           mp->prefix_length = prefix_length;
19016           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19017           break;
19018         case 1:
19019           mp->prefix_length = prefix_length;
19020           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19021           break;
19022         case 2:
19023           clib_memcpy (mp->eid, mac, sizeof (mac));
19024           break;
19025         case 3:
19026           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19027           break;
19028         default:
19029           errmsg ("unknown EID type %d!", eid_type);
19030           return -99;
19031         }
19032     }
19033
19034   /* send it... */
19035   S (mp);
19036
19037   /* Use a control ping for synchronization */
19038   MPING (CONTROL_PING, mp_ping);
19039   S (mp_ping);
19040
19041   /* Wait for a reply... */
19042   W (ret);
19043   return ret;
19044 }
19045
19046 #define api_lisp_eid_table_dump api_one_eid_table_dump
19047
19048 static int
19049 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19050 {
19051   unformat_input_t *i = vam->input;
19052   vl_api_gpe_fwd_entries_get_t *mp;
19053   u8 vni_set = 0;
19054   u32 vni = ~0;
19055   int ret;
19056
19057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19058     {
19059       if (unformat (i, "vni %d", &vni))
19060         {
19061           vni_set = 1;
19062         }
19063       else
19064         {
19065           errmsg ("parse error '%U'", format_unformat_error, i);
19066           return -99;
19067         }
19068     }
19069
19070   if (!vni_set)
19071     {
19072       errmsg ("vni not set!");
19073       return -99;
19074     }
19075
19076   if (!vam->json_output)
19077     {
19078       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19079              "leid", "reid");
19080     }
19081
19082   M (GPE_FWD_ENTRIES_GET, mp);
19083   mp->vni = clib_host_to_net_u32 (vni);
19084
19085   /* send it... */
19086   S (mp);
19087
19088   /* Wait for a reply... */
19089   W (ret);
19090   return ret;
19091 }
19092
19093 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19094 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19095 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19096 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19097 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19098 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19099 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19100 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19101
19102 static int
19103 api_one_adjacencies_get (vat_main_t * vam)
19104 {
19105   unformat_input_t *i = vam->input;
19106   vl_api_one_adjacencies_get_t *mp;
19107   u8 vni_set = 0;
19108   u32 vni = ~0;
19109   int ret;
19110
19111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19112     {
19113       if (unformat (i, "vni %d", &vni))
19114         {
19115           vni_set = 1;
19116         }
19117       else
19118         {
19119           errmsg ("parse error '%U'", format_unformat_error, i);
19120           return -99;
19121         }
19122     }
19123
19124   if (!vni_set)
19125     {
19126       errmsg ("vni not set!");
19127       return -99;
19128     }
19129
19130   if (!vam->json_output)
19131     {
19132       print (vam->ofp, "%s %40s", "leid", "reid");
19133     }
19134
19135   M (ONE_ADJACENCIES_GET, mp);
19136   mp->vni = clib_host_to_net_u32 (vni);
19137
19138   /* send it... */
19139   S (mp);
19140
19141   /* Wait for a reply... */
19142   W (ret);
19143   return ret;
19144 }
19145
19146 #define api_lisp_adjacencies_get api_one_adjacencies_get
19147
19148 static int
19149 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19150 {
19151   unformat_input_t *i = vam->input;
19152   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19153   int ret;
19154   u8 ip_family_set = 0, is_ip4 = 1;
19155
19156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19157     {
19158       if (unformat (i, "ip4"))
19159         {
19160           ip_family_set = 1;
19161           is_ip4 = 1;
19162         }
19163       else if (unformat (i, "ip6"))
19164         {
19165           ip_family_set = 1;
19166           is_ip4 = 0;
19167         }
19168       else
19169         {
19170           errmsg ("parse error '%U'", format_unformat_error, i);
19171           return -99;
19172         }
19173     }
19174
19175   if (!ip_family_set)
19176     {
19177       errmsg ("ip family not set!");
19178       return -99;
19179     }
19180
19181   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19182   mp->is_ip4 = is_ip4;
19183
19184   /* send it... */
19185   S (mp);
19186
19187   /* Wait for a reply... */
19188   W (ret);
19189   return ret;
19190 }
19191
19192 static int
19193 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19194 {
19195   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19196   int ret;
19197
19198   if (!vam->json_output)
19199     {
19200       print (vam->ofp, "VNIs");
19201     }
19202
19203   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19204
19205   /* send it... */
19206   S (mp);
19207
19208   /* Wait for a reply... */
19209   W (ret);
19210   return ret;
19211 }
19212
19213 static int
19214 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19215 {
19216   unformat_input_t *i = vam->input;
19217   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19218   int ret = 0;
19219   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19220   struct in_addr ip4;
19221   struct in6_addr ip6;
19222   u32 table_id = 0, nh_sw_if_index = ~0;
19223
19224   clib_memset (&ip4, 0, sizeof (ip4));
19225   clib_memset (&ip6, 0, sizeof (ip6));
19226
19227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19228     {
19229       if (unformat (i, "del"))
19230         is_add = 0;
19231       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19232                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19233         {
19234           ip_set = 1;
19235           is_ip4 = 1;
19236         }
19237       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19238                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19239         {
19240           ip_set = 1;
19241           is_ip4 = 0;
19242         }
19243       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19244         {
19245           ip_set = 1;
19246           is_ip4 = 1;
19247           nh_sw_if_index = ~0;
19248         }
19249       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19250         {
19251           ip_set = 1;
19252           is_ip4 = 0;
19253           nh_sw_if_index = ~0;
19254         }
19255       else if (unformat (i, "table %d", &table_id))
19256         ;
19257       else
19258         {
19259           errmsg ("parse error '%U'", format_unformat_error, i);
19260           return -99;
19261         }
19262     }
19263
19264   if (!ip_set)
19265     {
19266       errmsg ("nh addr not set!");
19267       return -99;
19268     }
19269
19270   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19271   mp->is_add = is_add;
19272   mp->table_id = clib_host_to_net_u32 (table_id);
19273   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19274   mp->is_ip4 = is_ip4;
19275   if (is_ip4)
19276     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19277   else
19278     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19279
19280   /* send it... */
19281   S (mp);
19282
19283   /* Wait for a reply... */
19284   W (ret);
19285   return ret;
19286 }
19287
19288 static int
19289 api_one_map_server_dump (vat_main_t * vam)
19290 {
19291   vl_api_one_map_server_dump_t *mp;
19292   vl_api_control_ping_t *mp_ping;
19293   int ret;
19294
19295   if (!vam->json_output)
19296     {
19297       print (vam->ofp, "%=20s", "Map server");
19298     }
19299
19300   M (ONE_MAP_SERVER_DUMP, mp);
19301   /* send it... */
19302   S (mp);
19303
19304   /* Use a control ping for synchronization */
19305   MPING (CONTROL_PING, mp_ping);
19306   S (mp_ping);
19307
19308   /* Wait for a reply... */
19309   W (ret);
19310   return ret;
19311 }
19312
19313 #define api_lisp_map_server_dump api_one_map_server_dump
19314
19315 static int
19316 api_one_map_resolver_dump (vat_main_t * vam)
19317 {
19318   vl_api_one_map_resolver_dump_t *mp;
19319   vl_api_control_ping_t *mp_ping;
19320   int ret;
19321
19322   if (!vam->json_output)
19323     {
19324       print (vam->ofp, "%=20s", "Map resolver");
19325     }
19326
19327   M (ONE_MAP_RESOLVER_DUMP, mp);
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_map_resolver_dump api_one_map_resolver_dump
19341
19342 static int
19343 api_one_stats_flush (vat_main_t * vam)
19344 {
19345   vl_api_one_stats_flush_t *mp;
19346   int ret = 0;
19347
19348   M (ONE_STATS_FLUSH, mp);
19349   S (mp);
19350   W (ret);
19351   return ret;
19352 }
19353
19354 static int
19355 api_one_stats_dump (vat_main_t * vam)
19356 {
19357   vl_api_one_stats_dump_t *mp;
19358   vl_api_control_ping_t *mp_ping;
19359   int ret;
19360
19361   M (ONE_STATS_DUMP, mp);
19362   /* send it... */
19363   S (mp);
19364
19365   /* Use a control ping for synchronization */
19366   MPING (CONTROL_PING, mp_ping);
19367   S (mp_ping);
19368
19369   /* Wait for a reply... */
19370   W (ret);
19371   return ret;
19372 }
19373
19374 static int
19375 api_show_one_status (vat_main_t * vam)
19376 {
19377   vl_api_show_one_status_t *mp;
19378   int ret;
19379
19380   if (!vam->json_output)
19381     {
19382       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19383     }
19384
19385   M (SHOW_ONE_STATUS, mp);
19386   /* send it... */
19387   S (mp);
19388   /* Wait for a reply... */
19389   W (ret);
19390   return ret;
19391 }
19392
19393 #define api_show_lisp_status api_show_one_status
19394
19395 static int
19396 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19397 {
19398   vl_api_gpe_fwd_entry_path_dump_t *mp;
19399   vl_api_control_ping_t *mp_ping;
19400   unformat_input_t *i = vam->input;
19401   u32 fwd_entry_index = ~0;
19402   int ret;
19403
19404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (i, "index %d", &fwd_entry_index))
19407         ;
19408       else
19409         break;
19410     }
19411
19412   if (~0 == fwd_entry_index)
19413     {
19414       errmsg ("no index specified!");
19415       return -99;
19416     }
19417
19418   if (!vam->json_output)
19419     {
19420       print (vam->ofp, "first line");
19421     }
19422
19423   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19424
19425   /* send it... */
19426   S (mp);
19427   /* Use a control ping for synchronization */
19428   MPING (CONTROL_PING, mp_ping);
19429   S (mp_ping);
19430
19431   /* Wait for a reply... */
19432   W (ret);
19433   return ret;
19434 }
19435
19436 static int
19437 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19438 {
19439   vl_api_one_get_map_request_itr_rlocs_t *mp;
19440   int ret;
19441
19442   if (!vam->json_output)
19443     {
19444       print (vam->ofp, "%=20s", "itr-rlocs:");
19445     }
19446
19447   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19448   /* send it... */
19449   S (mp);
19450   /* Wait for a reply... */
19451   W (ret);
19452   return ret;
19453 }
19454
19455 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19456
19457 static int
19458 api_af_packet_create (vat_main_t * vam)
19459 {
19460   unformat_input_t *i = vam->input;
19461   vl_api_af_packet_create_t *mp;
19462   u8 *host_if_name = 0;
19463   u8 hw_addr[6];
19464   u8 random_hw_addr = 1;
19465   int ret;
19466
19467   clib_memset (hw_addr, 0, sizeof (hw_addr));
19468
19469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19470     {
19471       if (unformat (i, "name %s", &host_if_name))
19472         vec_add1 (host_if_name, 0);
19473       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19474         random_hw_addr = 0;
19475       else
19476         break;
19477     }
19478
19479   if (!vec_len (host_if_name))
19480     {
19481       errmsg ("host-interface name must be specified");
19482       return -99;
19483     }
19484
19485   if (vec_len (host_if_name) > 64)
19486     {
19487       errmsg ("host-interface name too long");
19488       return -99;
19489     }
19490
19491   M (AF_PACKET_CREATE, mp);
19492
19493   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19494   clib_memcpy (mp->hw_addr, hw_addr, 6);
19495   mp->use_random_hw_addr = random_hw_addr;
19496   vec_free (host_if_name);
19497
19498   S (mp);
19499
19500   /* *INDENT-OFF* */
19501   W2 (ret,
19502       ({
19503         if (ret == 0)
19504           fprintf (vam->ofp ? vam->ofp : stderr,
19505                    " new sw_if_index = %d\n", vam->sw_if_index);
19506       }));
19507   /* *INDENT-ON* */
19508   return ret;
19509 }
19510
19511 static int
19512 api_af_packet_delete (vat_main_t * vam)
19513 {
19514   unformat_input_t *i = vam->input;
19515   vl_api_af_packet_delete_t *mp;
19516   u8 *host_if_name = 0;
19517   int ret;
19518
19519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19520     {
19521       if (unformat (i, "name %s", &host_if_name))
19522         vec_add1 (host_if_name, 0);
19523       else
19524         break;
19525     }
19526
19527   if (!vec_len (host_if_name))
19528     {
19529       errmsg ("host-interface name must be specified");
19530       return -99;
19531     }
19532
19533   if (vec_len (host_if_name) > 64)
19534     {
19535       errmsg ("host-interface name too long");
19536       return -99;
19537     }
19538
19539   M (AF_PACKET_DELETE, mp);
19540
19541   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19542   vec_free (host_if_name);
19543
19544   S (mp);
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static void vl_api_af_packet_details_t_handler
19550   (vl_api_af_packet_details_t * mp)
19551 {
19552   vat_main_t *vam = &vat_main;
19553
19554   print (vam->ofp, "%-16s %d",
19555          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19556 }
19557
19558 static void vl_api_af_packet_details_t_handler_json
19559   (vl_api_af_packet_details_t * mp)
19560 {
19561   vat_main_t *vam = &vat_main;
19562   vat_json_node_t *node = NULL;
19563
19564   if (VAT_JSON_ARRAY != vam->json_tree.type)
19565     {
19566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19567       vat_json_init_array (&vam->json_tree);
19568     }
19569   node = vat_json_array_add (&vam->json_tree);
19570
19571   vat_json_init_object (node);
19572   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19573   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19574 }
19575
19576 static int
19577 api_af_packet_dump (vat_main_t * vam)
19578 {
19579   vl_api_af_packet_dump_t *mp;
19580   vl_api_control_ping_t *mp_ping;
19581   int ret;
19582
19583   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19584   /* Get list of tap interfaces */
19585   M (AF_PACKET_DUMP, mp);
19586   S (mp);
19587
19588   /* Use a control ping for synchronization */
19589   MPING (CONTROL_PING, mp_ping);
19590   S (mp_ping);
19591
19592   W (ret);
19593   return ret;
19594 }
19595
19596 static int
19597 api_policer_add_del (vat_main_t * vam)
19598 {
19599   unformat_input_t *i = vam->input;
19600   vl_api_policer_add_del_t *mp;
19601   u8 is_add = 1;
19602   u8 *name = 0;
19603   u32 cir = 0;
19604   u32 eir = 0;
19605   u64 cb = 0;
19606   u64 eb = 0;
19607   u8 rate_type = 0;
19608   u8 round_type = 0;
19609   u8 type = 0;
19610   u8 color_aware = 0;
19611   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19612   int ret;
19613
19614   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19615   conform_action.dscp = 0;
19616   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19617   exceed_action.dscp = 0;
19618   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19619   violate_action.dscp = 0;
19620
19621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19622     {
19623       if (unformat (i, "del"))
19624         is_add = 0;
19625       else if (unformat (i, "name %s", &name))
19626         vec_add1 (name, 0);
19627       else if (unformat (i, "cir %u", &cir))
19628         ;
19629       else if (unformat (i, "eir %u", &eir))
19630         ;
19631       else if (unformat (i, "cb %u", &cb))
19632         ;
19633       else if (unformat (i, "eb %u", &eb))
19634         ;
19635       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19636                          &rate_type))
19637         ;
19638       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19639                          &round_type))
19640         ;
19641       else if (unformat (i, "type %U", unformat_policer_type, &type))
19642         ;
19643       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19644                          &conform_action))
19645         ;
19646       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19647                          &exceed_action))
19648         ;
19649       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19650                          &violate_action))
19651         ;
19652       else if (unformat (i, "color-aware"))
19653         color_aware = 1;
19654       else
19655         break;
19656     }
19657
19658   if (!vec_len (name))
19659     {
19660       errmsg ("policer name must be specified");
19661       return -99;
19662     }
19663
19664   if (vec_len (name) > 64)
19665     {
19666       errmsg ("policer name too long");
19667       return -99;
19668     }
19669
19670   M (POLICER_ADD_DEL, mp);
19671
19672   clib_memcpy (mp->name, name, vec_len (name));
19673   vec_free (name);
19674   mp->is_add = is_add;
19675   mp->cir = ntohl (cir);
19676   mp->eir = ntohl (eir);
19677   mp->cb = clib_net_to_host_u64 (cb);
19678   mp->eb = clib_net_to_host_u64 (eb);
19679   mp->rate_type = rate_type;
19680   mp->round_type = round_type;
19681   mp->type = type;
19682   mp->conform_action_type = conform_action.action_type;
19683   mp->conform_dscp = conform_action.dscp;
19684   mp->exceed_action_type = exceed_action.action_type;
19685   mp->exceed_dscp = exceed_action.dscp;
19686   mp->violate_action_type = violate_action.action_type;
19687   mp->violate_dscp = violate_action.dscp;
19688   mp->color_aware = color_aware;
19689
19690   S (mp);
19691   W (ret);
19692   return ret;
19693 }
19694
19695 static int
19696 api_policer_dump (vat_main_t * vam)
19697 {
19698   unformat_input_t *i = vam->input;
19699   vl_api_policer_dump_t *mp;
19700   vl_api_control_ping_t *mp_ping;
19701   u8 *match_name = 0;
19702   u8 match_name_valid = 0;
19703   int ret;
19704
19705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19706     {
19707       if (unformat (i, "name %s", &match_name))
19708         {
19709           vec_add1 (match_name, 0);
19710           match_name_valid = 1;
19711         }
19712       else
19713         break;
19714     }
19715
19716   M (POLICER_DUMP, mp);
19717   mp->match_name_valid = match_name_valid;
19718   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19719   vec_free (match_name);
19720   /* send it... */
19721   S (mp);
19722
19723   /* Use a control ping for synchronization */
19724   MPING (CONTROL_PING, mp_ping);
19725   S (mp_ping);
19726
19727   /* Wait for a reply... */
19728   W (ret);
19729   return ret;
19730 }
19731
19732 static int
19733 api_policer_classify_set_interface (vat_main_t * vam)
19734 {
19735   unformat_input_t *i = vam->input;
19736   vl_api_policer_classify_set_interface_t *mp;
19737   u32 sw_if_index;
19738   int sw_if_index_set;
19739   u32 ip4_table_index = ~0;
19740   u32 ip6_table_index = ~0;
19741   u32 l2_table_index = ~0;
19742   u8 is_add = 1;
19743   int ret;
19744
19745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19746     {
19747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19748         sw_if_index_set = 1;
19749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19750         sw_if_index_set = 1;
19751       else if (unformat (i, "del"))
19752         is_add = 0;
19753       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19754         ;
19755       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19756         ;
19757       else if (unformat (i, "l2-table %d", &l2_table_index))
19758         ;
19759       else
19760         {
19761           clib_warning ("parse error '%U'", format_unformat_error, i);
19762           return -99;
19763         }
19764     }
19765
19766   if (sw_if_index_set == 0)
19767     {
19768       errmsg ("missing interface name or sw_if_index");
19769       return -99;
19770     }
19771
19772   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19773
19774   mp->sw_if_index = ntohl (sw_if_index);
19775   mp->ip4_table_index = ntohl (ip4_table_index);
19776   mp->ip6_table_index = ntohl (ip6_table_index);
19777   mp->l2_table_index = ntohl (l2_table_index);
19778   mp->is_add = is_add;
19779
19780   S (mp);
19781   W (ret);
19782   return ret;
19783 }
19784
19785 static int
19786 api_policer_classify_dump (vat_main_t * vam)
19787 {
19788   unformat_input_t *i = vam->input;
19789   vl_api_policer_classify_dump_t *mp;
19790   vl_api_control_ping_t *mp_ping;
19791   u8 type = POLICER_CLASSIFY_N_TABLES;
19792   int ret;
19793
19794   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19795     ;
19796   else
19797     {
19798       errmsg ("classify table type must be specified");
19799       return -99;
19800     }
19801
19802   if (!vam->json_output)
19803     {
19804       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19805     }
19806
19807   M (POLICER_CLASSIFY_DUMP, mp);
19808   mp->type = type;
19809   /* send it... */
19810   S (mp);
19811
19812   /* Use a control ping for synchronization */
19813   MPING (CONTROL_PING, mp_ping);
19814   S (mp_ping);
19815
19816   /* Wait for a reply... */
19817   W (ret);
19818   return ret;
19819 }
19820
19821 static int
19822 api_netmap_create (vat_main_t * vam)
19823 {
19824   unformat_input_t *i = vam->input;
19825   vl_api_netmap_create_t *mp;
19826   u8 *if_name = 0;
19827   u8 hw_addr[6];
19828   u8 random_hw_addr = 1;
19829   u8 is_pipe = 0;
19830   u8 is_master = 0;
19831   int ret;
19832
19833   clib_memset (hw_addr, 0, sizeof (hw_addr));
19834
19835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19836     {
19837       if (unformat (i, "name %s", &if_name))
19838         vec_add1 (if_name, 0);
19839       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19840         random_hw_addr = 0;
19841       else if (unformat (i, "pipe"))
19842         is_pipe = 1;
19843       else if (unformat (i, "master"))
19844         is_master = 1;
19845       else if (unformat (i, "slave"))
19846         is_master = 0;
19847       else
19848         break;
19849     }
19850
19851   if (!vec_len (if_name))
19852     {
19853       errmsg ("interface name must be specified");
19854       return -99;
19855     }
19856
19857   if (vec_len (if_name) > 64)
19858     {
19859       errmsg ("interface name too long");
19860       return -99;
19861     }
19862
19863   M (NETMAP_CREATE, mp);
19864
19865   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19866   clib_memcpy (mp->hw_addr, hw_addr, 6);
19867   mp->use_random_hw_addr = random_hw_addr;
19868   mp->is_pipe = is_pipe;
19869   mp->is_master = is_master;
19870   vec_free (if_name);
19871
19872   S (mp);
19873   W (ret);
19874   return ret;
19875 }
19876
19877 static int
19878 api_netmap_delete (vat_main_t * vam)
19879 {
19880   unformat_input_t *i = vam->input;
19881   vl_api_netmap_delete_t *mp;
19882   u8 *if_name = 0;
19883   int ret;
19884
19885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19886     {
19887       if (unformat (i, "name %s", &if_name))
19888         vec_add1 (if_name, 0);
19889       else
19890         break;
19891     }
19892
19893   if (!vec_len (if_name))
19894     {
19895       errmsg ("interface name must be specified");
19896       return -99;
19897     }
19898
19899   if (vec_len (if_name) > 64)
19900     {
19901       errmsg ("interface name too long");
19902       return -99;
19903     }
19904
19905   M (NETMAP_DELETE, mp);
19906
19907   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19908   vec_free (if_name);
19909
19910   S (mp);
19911   W (ret);
19912   return ret;
19913 }
19914
19915 static void
19916 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19917 {
19918   if (fp->afi == IP46_TYPE_IP6)
19919     print (vam->ofp,
19920            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19921            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19922            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19923            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19924            format_ip6_address, fp->next_hop);
19925   else if (fp->afi == IP46_TYPE_IP4)
19926     print (vam->ofp,
19927            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19928            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19929            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19930            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19931            format_ip4_address, fp->next_hop);
19932 }
19933
19934 static void
19935 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19936                                  vl_api_fib_path_t * fp)
19937 {
19938   struct in_addr ip4;
19939   struct in6_addr ip6;
19940
19941   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19942   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19943   vat_json_object_add_uint (node, "is_local", fp->is_local);
19944   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19945   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19946   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19947   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19948   if (fp->afi == IP46_TYPE_IP4)
19949     {
19950       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19951       vat_json_object_add_ip4 (node, "next_hop", ip4);
19952     }
19953   else if (fp->afi == IP46_TYPE_IP6)
19954     {
19955       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19956       vat_json_object_add_ip6 (node, "next_hop", ip6);
19957     }
19958 }
19959
19960 static void
19961 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19962 {
19963   vat_main_t *vam = &vat_main;
19964   int count = ntohl (mp->mt_count);
19965   vl_api_fib_path_t *fp;
19966   i32 i;
19967
19968   print (vam->ofp, "[%d]: sw_if_index %d via:",
19969          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19970   fp = mp->mt_paths;
19971   for (i = 0; i < count; i++)
19972     {
19973       vl_api_mpls_fib_path_print (vam, fp);
19974       fp++;
19975     }
19976
19977   print (vam->ofp, "");
19978 }
19979
19980 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19981 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19982
19983 static void
19984 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19985 {
19986   vat_main_t *vam = &vat_main;
19987   vat_json_node_t *node = NULL;
19988   int count = ntohl (mp->mt_count);
19989   vl_api_fib_path_t *fp;
19990   i32 i;
19991
19992   if (VAT_JSON_ARRAY != vam->json_tree.type)
19993     {
19994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19995       vat_json_init_array (&vam->json_tree);
19996     }
19997   node = vat_json_array_add (&vam->json_tree);
19998
19999   vat_json_init_object (node);
20000   vat_json_object_add_uint (node, "tunnel_index",
20001                             ntohl (mp->mt_tunnel_index));
20002   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20003
20004   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20005
20006   fp = mp->mt_paths;
20007   for (i = 0; i < count; i++)
20008     {
20009       vl_api_mpls_fib_path_json_print (node, fp);
20010       fp++;
20011     }
20012 }
20013
20014 static int
20015 api_mpls_tunnel_dump (vat_main_t * vam)
20016 {
20017   vl_api_mpls_tunnel_dump_t *mp;
20018   vl_api_control_ping_t *mp_ping;
20019   u32 sw_if_index = ~0;
20020   int ret;
20021
20022   /* Parse args required to build the message */
20023   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20024     {
20025       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20026         ;
20027     }
20028
20029   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20030
20031   M (MPLS_TUNNEL_DUMP, mp);
20032   mp->sw_if_index = htonl (sw_if_index);
20033   S (mp);
20034
20035   /* Use a control ping for synchronization */
20036   MPING (CONTROL_PING, mp_ping);
20037   S (mp_ping);
20038
20039   W (ret);
20040   return ret;
20041 }
20042
20043 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20044 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20045
20046
20047 static void
20048 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20049 {
20050   vat_main_t *vam = &vat_main;
20051   int count = ntohl (mp->count);
20052   vl_api_fib_path_t *fp;
20053   int i;
20054
20055   print (vam->ofp,
20056          "table-id %d, label %u, ess_bit %u",
20057          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20058   fp = mp->path;
20059   for (i = 0; i < count; i++)
20060     {
20061       vl_api_mpls_fib_path_print (vam, fp);
20062       fp++;
20063     }
20064 }
20065
20066 static void vl_api_mpls_fib_details_t_handler_json
20067   (vl_api_mpls_fib_details_t * mp)
20068 {
20069   vat_main_t *vam = &vat_main;
20070   int count = ntohl (mp->count);
20071   vat_json_node_t *node = NULL;
20072   vl_api_fib_path_t *fp;
20073   int i;
20074
20075   if (VAT_JSON_ARRAY != vam->json_tree.type)
20076     {
20077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20078       vat_json_init_array (&vam->json_tree);
20079     }
20080   node = vat_json_array_add (&vam->json_tree);
20081
20082   vat_json_init_object (node);
20083   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20084   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20085   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20086   vat_json_object_add_uint (node, "path_count", count);
20087   fp = mp->path;
20088   for (i = 0; i < count; i++)
20089     {
20090       vl_api_mpls_fib_path_json_print (node, fp);
20091       fp++;
20092     }
20093 }
20094
20095 static int
20096 api_mpls_fib_dump (vat_main_t * vam)
20097 {
20098   vl_api_mpls_fib_dump_t *mp;
20099   vl_api_control_ping_t *mp_ping;
20100   int ret;
20101
20102   M (MPLS_FIB_DUMP, mp);
20103   S (mp);
20104
20105   /* Use a control ping for synchronization */
20106   MPING (CONTROL_PING, mp_ping);
20107   S (mp_ping);
20108
20109   W (ret);
20110   return ret;
20111 }
20112
20113 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20114 #define vl_api_ip_fib_details_t_print vl_noop_handler
20115
20116 static void
20117 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20118 {
20119   vat_main_t *vam = &vat_main;
20120   int count = ntohl (mp->count);
20121   vl_api_fib_path_t *fp;
20122   int i;
20123
20124   print (vam->ofp,
20125          "table-id %d, prefix %U/%d stats-index %d",
20126          ntohl (mp->table_id), format_ip4_address, mp->address,
20127          mp->address_length, ntohl (mp->stats_index));
20128   fp = mp->path;
20129   for (i = 0; i < count; i++)
20130     {
20131       if (fp->afi == IP46_TYPE_IP6)
20132         print (vam->ofp,
20133                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20134                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20135                "next_hop_table %d",
20136                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20137                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20138                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20139       else if (fp->afi == IP46_TYPE_IP4)
20140         print (vam->ofp,
20141                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20142                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20143                "next_hop_table %d",
20144                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20145                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20146                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20147       fp++;
20148     }
20149 }
20150
20151 static void vl_api_ip_fib_details_t_handler_json
20152   (vl_api_ip_fib_details_t * mp)
20153 {
20154   vat_main_t *vam = &vat_main;
20155   int count = ntohl (mp->count);
20156   vat_json_node_t *node = NULL;
20157   struct in_addr ip4;
20158   struct in6_addr ip6;
20159   vl_api_fib_path_t *fp;
20160   int i;
20161
20162   if (VAT_JSON_ARRAY != vam->json_tree.type)
20163     {
20164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20165       vat_json_init_array (&vam->json_tree);
20166     }
20167   node = vat_json_array_add (&vam->json_tree);
20168
20169   vat_json_init_object (node);
20170   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20171   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20172   vat_json_object_add_ip4 (node, "prefix", ip4);
20173   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20174   vat_json_object_add_uint (node, "path_count", count);
20175   fp = mp->path;
20176   for (i = 0; i < count; i++)
20177     {
20178       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20179       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20180       vat_json_object_add_uint (node, "is_local", fp->is_local);
20181       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20182       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20183       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20184       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20185       if (fp->afi == IP46_TYPE_IP4)
20186         {
20187           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20188           vat_json_object_add_ip4 (node, "next_hop", ip4);
20189         }
20190       else if (fp->afi == IP46_TYPE_IP6)
20191         {
20192           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20193           vat_json_object_add_ip6 (node, "next_hop", ip6);
20194         }
20195     }
20196 }
20197
20198 static int
20199 api_ip_fib_dump (vat_main_t * vam)
20200 {
20201   vl_api_ip_fib_dump_t *mp;
20202   vl_api_control_ping_t *mp_ping;
20203   int ret;
20204
20205   M (IP_FIB_DUMP, mp);
20206   S (mp);
20207
20208   /* Use a control ping for synchronization */
20209   MPING (CONTROL_PING, mp_ping);
20210   S (mp_ping);
20211
20212   W (ret);
20213   return ret;
20214 }
20215
20216 static int
20217 api_ip_mfib_dump (vat_main_t * vam)
20218 {
20219   vl_api_ip_mfib_dump_t *mp;
20220   vl_api_control_ping_t *mp_ping;
20221   int ret;
20222
20223   M (IP_MFIB_DUMP, mp);
20224   S (mp);
20225
20226   /* Use a control ping for synchronization */
20227   MPING (CONTROL_PING, mp_ping);
20228   S (mp_ping);
20229
20230   W (ret);
20231   return ret;
20232 }
20233
20234 static void vl_api_ip_neighbor_details_t_handler
20235   (vl_api_ip_neighbor_details_t * mp)
20236 {
20237   vat_main_t *vam = &vat_main;
20238
20239   print (vam->ofp, "%c %U %U",
20240          (mp->is_static) ? 'S' : 'D',
20241          format_ethernet_address, &mp->mac_address,
20242          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20243          &mp->ip_address);
20244 }
20245
20246 static void vl_api_ip_neighbor_details_t_handler_json
20247   (vl_api_ip_neighbor_details_t * mp)
20248 {
20249
20250   vat_main_t *vam = &vat_main;
20251   vat_json_node_t *node;
20252   struct in_addr ip4;
20253   struct in6_addr ip6;
20254
20255   if (VAT_JSON_ARRAY != vam->json_tree.type)
20256     {
20257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20258       vat_json_init_array (&vam->json_tree);
20259     }
20260   node = vat_json_array_add (&vam->json_tree);
20261
20262   vat_json_init_object (node);
20263   vat_json_object_add_string_copy (node, "flag",
20264                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20265                                    "dynamic");
20266
20267   vat_json_object_add_string_copy (node, "link_layer",
20268                                    format (0, "%U", format_ethernet_address,
20269                                            &mp->mac_address));
20270
20271   if (mp->is_ipv6)
20272     {
20273       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20274       vat_json_object_add_ip6 (node, "ip_address", ip6);
20275     }
20276   else
20277     {
20278       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20279       vat_json_object_add_ip4 (node, "ip_address", ip4);
20280     }
20281 }
20282
20283 static int
20284 api_ip_neighbor_dump (vat_main_t * vam)
20285 {
20286   unformat_input_t *i = vam->input;
20287   vl_api_ip_neighbor_dump_t *mp;
20288   vl_api_control_ping_t *mp_ping;
20289   u8 is_ipv6 = 0;
20290   u32 sw_if_index = ~0;
20291   int ret;
20292
20293   /* Parse args required to build the message */
20294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20295     {
20296       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20297         ;
20298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20299         ;
20300       else if (unformat (i, "ip6"))
20301         is_ipv6 = 1;
20302       else
20303         break;
20304     }
20305
20306   if (sw_if_index == ~0)
20307     {
20308       errmsg ("missing interface name or sw_if_index");
20309       return -99;
20310     }
20311
20312   M (IP_NEIGHBOR_DUMP, mp);
20313   mp->is_ipv6 = (u8) is_ipv6;
20314   mp->sw_if_index = ntohl (sw_if_index);
20315   S (mp);
20316
20317   /* Use a control ping for synchronization */
20318   MPING (CONTROL_PING, mp_ping);
20319   S (mp_ping);
20320
20321   W (ret);
20322   return ret;
20323 }
20324
20325 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20326 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20327
20328 static void
20329 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20330 {
20331   vat_main_t *vam = &vat_main;
20332   int count = ntohl (mp->count);
20333   vl_api_fib_path_t *fp;
20334   int i;
20335
20336   print (vam->ofp,
20337          "table-id %d, prefix %U/%d stats-index %d",
20338          ntohl (mp->table_id), format_ip6_address, mp->address,
20339          mp->address_length, ntohl (mp->stats_index));
20340   fp = mp->path;
20341   for (i = 0; i < count; i++)
20342     {
20343       if (fp->afi == IP46_TYPE_IP6)
20344         print (vam->ofp,
20345                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20346                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20347                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20348                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20349                format_ip6_address, fp->next_hop);
20350       else if (fp->afi == IP46_TYPE_IP4)
20351         print (vam->ofp,
20352                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20353                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20354                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20355                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20356                format_ip4_address, fp->next_hop);
20357       fp++;
20358     }
20359 }
20360
20361 static void vl_api_ip6_fib_details_t_handler_json
20362   (vl_api_ip6_fib_details_t * mp)
20363 {
20364   vat_main_t *vam = &vat_main;
20365   int count = ntohl (mp->count);
20366   vat_json_node_t *node = NULL;
20367   struct in_addr ip4;
20368   struct in6_addr ip6;
20369   vl_api_fib_path_t *fp;
20370   int i;
20371
20372   if (VAT_JSON_ARRAY != vam->json_tree.type)
20373     {
20374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20375       vat_json_init_array (&vam->json_tree);
20376     }
20377   node = vat_json_array_add (&vam->json_tree);
20378
20379   vat_json_init_object (node);
20380   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20381   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20382   vat_json_object_add_ip6 (node, "prefix", ip6);
20383   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20384   vat_json_object_add_uint (node, "path_count", count);
20385   fp = mp->path;
20386   for (i = 0; i < count; i++)
20387     {
20388       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20389       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20390       vat_json_object_add_uint (node, "is_local", fp->is_local);
20391       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20392       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20393       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20394       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20395       if (fp->afi == IP46_TYPE_IP4)
20396         {
20397           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20398           vat_json_object_add_ip4 (node, "next_hop", ip4);
20399         }
20400       else if (fp->afi == IP46_TYPE_IP6)
20401         {
20402           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20403           vat_json_object_add_ip6 (node, "next_hop", ip6);
20404         }
20405     }
20406 }
20407
20408 static int
20409 api_ip6_fib_dump (vat_main_t * vam)
20410 {
20411   vl_api_ip6_fib_dump_t *mp;
20412   vl_api_control_ping_t *mp_ping;
20413   int ret;
20414
20415   M (IP6_FIB_DUMP, mp);
20416   S (mp);
20417
20418   /* Use a control ping for synchronization */
20419   MPING (CONTROL_PING, mp_ping);
20420   S (mp_ping);
20421
20422   W (ret);
20423   return ret;
20424 }
20425
20426 static int
20427 api_ip6_mfib_dump (vat_main_t * vam)
20428 {
20429   vl_api_ip6_mfib_dump_t *mp;
20430   vl_api_control_ping_t *mp_ping;
20431   int ret;
20432
20433   M (IP6_MFIB_DUMP, mp);
20434   S (mp);
20435
20436   /* Use a control ping for synchronization */
20437   MPING (CONTROL_PING, mp_ping);
20438   S (mp_ping);
20439
20440   W (ret);
20441   return ret;
20442 }
20443
20444 int
20445 api_classify_table_ids (vat_main_t * vam)
20446 {
20447   vl_api_classify_table_ids_t *mp;
20448   int ret;
20449
20450   /* Construct the API message */
20451   M (CLASSIFY_TABLE_IDS, mp);
20452   mp->context = 0;
20453
20454   S (mp);
20455   W (ret);
20456   return ret;
20457 }
20458
20459 int
20460 api_classify_table_by_interface (vat_main_t * vam)
20461 {
20462   unformat_input_t *input = vam->input;
20463   vl_api_classify_table_by_interface_t *mp;
20464
20465   u32 sw_if_index = ~0;
20466   int ret;
20467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20468     {
20469       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20470         ;
20471       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20472         ;
20473       else
20474         break;
20475     }
20476   if (sw_if_index == ~0)
20477     {
20478       errmsg ("missing interface name or sw_if_index");
20479       return -99;
20480     }
20481
20482   /* Construct the API message */
20483   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20484   mp->context = 0;
20485   mp->sw_if_index = ntohl (sw_if_index);
20486
20487   S (mp);
20488   W (ret);
20489   return ret;
20490 }
20491
20492 int
20493 api_classify_table_info (vat_main_t * vam)
20494 {
20495   unformat_input_t *input = vam->input;
20496   vl_api_classify_table_info_t *mp;
20497
20498   u32 table_id = ~0;
20499   int ret;
20500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20501     {
20502       if (unformat (input, "table_id %d", &table_id))
20503         ;
20504       else
20505         break;
20506     }
20507   if (table_id == ~0)
20508     {
20509       errmsg ("missing table id");
20510       return -99;
20511     }
20512
20513   /* Construct the API message */
20514   M (CLASSIFY_TABLE_INFO, mp);
20515   mp->context = 0;
20516   mp->table_id = ntohl (table_id);
20517
20518   S (mp);
20519   W (ret);
20520   return ret;
20521 }
20522
20523 int
20524 api_classify_session_dump (vat_main_t * vam)
20525 {
20526   unformat_input_t *input = vam->input;
20527   vl_api_classify_session_dump_t *mp;
20528   vl_api_control_ping_t *mp_ping;
20529
20530   u32 table_id = ~0;
20531   int ret;
20532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20533     {
20534       if (unformat (input, "table_id %d", &table_id))
20535         ;
20536       else
20537         break;
20538     }
20539   if (table_id == ~0)
20540     {
20541       errmsg ("missing table id");
20542       return -99;
20543     }
20544
20545   /* Construct the API message */
20546   M (CLASSIFY_SESSION_DUMP, mp);
20547   mp->context = 0;
20548   mp->table_id = ntohl (table_id);
20549   S (mp);
20550
20551   /* Use a control ping for synchronization */
20552   MPING (CONTROL_PING, mp_ping);
20553   S (mp_ping);
20554
20555   W (ret);
20556   return ret;
20557 }
20558
20559 static void
20560 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20561 {
20562   vat_main_t *vam = &vat_main;
20563
20564   print (vam->ofp, "collector_address %U, collector_port %d, "
20565          "src_address %U, vrf_id %d, path_mtu %u, "
20566          "template_interval %u, udp_checksum %d",
20567          format_ip4_address, mp->collector_address,
20568          ntohs (mp->collector_port),
20569          format_ip4_address, mp->src_address,
20570          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20571          ntohl (mp->template_interval), mp->udp_checksum);
20572
20573   vam->retval = 0;
20574   vam->result_ready = 1;
20575 }
20576
20577 static void
20578   vl_api_ipfix_exporter_details_t_handler_json
20579   (vl_api_ipfix_exporter_details_t * mp)
20580 {
20581   vat_main_t *vam = &vat_main;
20582   vat_json_node_t node;
20583   struct in_addr collector_address;
20584   struct in_addr src_address;
20585
20586   vat_json_init_object (&node);
20587   clib_memcpy (&collector_address, &mp->collector_address,
20588                sizeof (collector_address));
20589   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20590   vat_json_object_add_uint (&node, "collector_port",
20591                             ntohs (mp->collector_port));
20592   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20593   vat_json_object_add_ip4 (&node, "src_address", src_address);
20594   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20595   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20596   vat_json_object_add_uint (&node, "template_interval",
20597                             ntohl (mp->template_interval));
20598   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20599
20600   vat_json_print (vam->ofp, &node);
20601   vat_json_free (&node);
20602   vam->retval = 0;
20603   vam->result_ready = 1;
20604 }
20605
20606 int
20607 api_ipfix_exporter_dump (vat_main_t * vam)
20608 {
20609   vl_api_ipfix_exporter_dump_t *mp;
20610   int ret;
20611
20612   /* Construct the API message */
20613   M (IPFIX_EXPORTER_DUMP, mp);
20614   mp->context = 0;
20615
20616   S (mp);
20617   W (ret);
20618   return ret;
20619 }
20620
20621 static int
20622 api_ipfix_classify_stream_dump (vat_main_t * vam)
20623 {
20624   vl_api_ipfix_classify_stream_dump_t *mp;
20625   int ret;
20626
20627   /* Construct the API message */
20628   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20629   mp->context = 0;
20630
20631   S (mp);
20632   W (ret);
20633   return ret;
20634   /* NOTREACHED */
20635   return 0;
20636 }
20637
20638 static void
20639   vl_api_ipfix_classify_stream_details_t_handler
20640   (vl_api_ipfix_classify_stream_details_t * mp)
20641 {
20642   vat_main_t *vam = &vat_main;
20643   print (vam->ofp, "domain_id %d, src_port %d",
20644          ntohl (mp->domain_id), ntohs (mp->src_port));
20645   vam->retval = 0;
20646   vam->result_ready = 1;
20647 }
20648
20649 static void
20650   vl_api_ipfix_classify_stream_details_t_handler_json
20651   (vl_api_ipfix_classify_stream_details_t * mp)
20652 {
20653   vat_main_t *vam = &vat_main;
20654   vat_json_node_t node;
20655
20656   vat_json_init_object (&node);
20657   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20658   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20659
20660   vat_json_print (vam->ofp, &node);
20661   vat_json_free (&node);
20662   vam->retval = 0;
20663   vam->result_ready = 1;
20664 }
20665
20666 static int
20667 api_ipfix_classify_table_dump (vat_main_t * vam)
20668 {
20669   vl_api_ipfix_classify_table_dump_t *mp;
20670   vl_api_control_ping_t *mp_ping;
20671   int ret;
20672
20673   if (!vam->json_output)
20674     {
20675       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20676              "transport_protocol");
20677     }
20678
20679   /* Construct the API message */
20680   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20681
20682   /* send it... */
20683   S (mp);
20684
20685   /* Use a control ping for synchronization */
20686   MPING (CONTROL_PING, mp_ping);
20687   S (mp_ping);
20688
20689   W (ret);
20690   return ret;
20691 }
20692
20693 static void
20694   vl_api_ipfix_classify_table_details_t_handler
20695   (vl_api_ipfix_classify_table_details_t * mp)
20696 {
20697   vat_main_t *vam = &vat_main;
20698   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20699          mp->transport_protocol);
20700 }
20701
20702 static void
20703   vl_api_ipfix_classify_table_details_t_handler_json
20704   (vl_api_ipfix_classify_table_details_t * mp)
20705 {
20706   vat_json_node_t *node = NULL;
20707   vat_main_t *vam = &vat_main;
20708
20709   if (VAT_JSON_ARRAY != vam->json_tree.type)
20710     {
20711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20712       vat_json_init_array (&vam->json_tree);
20713     }
20714
20715   node = vat_json_array_add (&vam->json_tree);
20716   vat_json_init_object (node);
20717
20718   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20719   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20720   vat_json_object_add_uint (node, "transport_protocol",
20721                             mp->transport_protocol);
20722 }
20723
20724 static int
20725 api_sw_interface_span_enable_disable (vat_main_t * vam)
20726 {
20727   unformat_input_t *i = vam->input;
20728   vl_api_sw_interface_span_enable_disable_t *mp;
20729   u32 src_sw_if_index = ~0;
20730   u32 dst_sw_if_index = ~0;
20731   u8 state = 3;
20732   int ret;
20733   u8 is_l2 = 0;
20734
20735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20736     {
20737       if (unformat
20738           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20739         ;
20740       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20741         ;
20742       else
20743         if (unformat
20744             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20745         ;
20746       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20747         ;
20748       else if (unformat (i, "disable"))
20749         state = 0;
20750       else if (unformat (i, "rx"))
20751         state = 1;
20752       else if (unformat (i, "tx"))
20753         state = 2;
20754       else if (unformat (i, "both"))
20755         state = 3;
20756       else if (unformat (i, "l2"))
20757         is_l2 = 1;
20758       else
20759         break;
20760     }
20761
20762   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20763
20764   mp->sw_if_index_from = htonl (src_sw_if_index);
20765   mp->sw_if_index_to = htonl (dst_sw_if_index);
20766   mp->state = state;
20767   mp->is_l2 = is_l2;
20768
20769   S (mp);
20770   W (ret);
20771   return ret;
20772 }
20773
20774 static void
20775 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20776                                             * mp)
20777 {
20778   vat_main_t *vam = &vat_main;
20779   u8 *sw_if_from_name = 0;
20780   u8 *sw_if_to_name = 0;
20781   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20782   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20783   char *states[] = { "none", "rx", "tx", "both" };
20784   hash_pair_t *p;
20785
20786   /* *INDENT-OFF* */
20787   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20788   ({
20789     if ((u32) p->value[0] == sw_if_index_from)
20790       {
20791         sw_if_from_name = (u8 *)(p->key);
20792         if (sw_if_to_name)
20793           break;
20794       }
20795     if ((u32) p->value[0] == sw_if_index_to)
20796       {
20797         sw_if_to_name = (u8 *)(p->key);
20798         if (sw_if_from_name)
20799           break;
20800       }
20801   }));
20802   /* *INDENT-ON* */
20803   print (vam->ofp, "%20s => %20s (%s) %s",
20804          sw_if_from_name, sw_if_to_name, states[mp->state],
20805          mp->is_l2 ? "l2" : "device");
20806 }
20807
20808 static void
20809   vl_api_sw_interface_span_details_t_handler_json
20810   (vl_api_sw_interface_span_details_t * mp)
20811 {
20812   vat_main_t *vam = &vat_main;
20813   vat_json_node_t *node = NULL;
20814   u8 *sw_if_from_name = 0;
20815   u8 *sw_if_to_name = 0;
20816   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20817   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20818   hash_pair_t *p;
20819
20820   /* *INDENT-OFF* */
20821   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20822   ({
20823     if ((u32) p->value[0] == sw_if_index_from)
20824       {
20825         sw_if_from_name = (u8 *)(p->key);
20826         if (sw_if_to_name)
20827           break;
20828       }
20829     if ((u32) p->value[0] == sw_if_index_to)
20830       {
20831         sw_if_to_name = (u8 *)(p->key);
20832         if (sw_if_from_name)
20833           break;
20834       }
20835   }));
20836   /* *INDENT-ON* */
20837
20838   if (VAT_JSON_ARRAY != vam->json_tree.type)
20839     {
20840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20841       vat_json_init_array (&vam->json_tree);
20842     }
20843   node = vat_json_array_add (&vam->json_tree);
20844
20845   vat_json_init_object (node);
20846   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20847   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20848   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20849   if (0 != sw_if_to_name)
20850     {
20851       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20852     }
20853   vat_json_object_add_uint (node, "state", mp->state);
20854   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20855 }
20856
20857 static int
20858 api_sw_interface_span_dump (vat_main_t * vam)
20859 {
20860   unformat_input_t *input = vam->input;
20861   vl_api_sw_interface_span_dump_t *mp;
20862   vl_api_control_ping_t *mp_ping;
20863   u8 is_l2 = 0;
20864   int ret;
20865
20866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20867     {
20868       if (unformat (input, "l2"))
20869         is_l2 = 1;
20870       else
20871         break;
20872     }
20873
20874   M (SW_INTERFACE_SPAN_DUMP, mp);
20875   mp->is_l2 = is_l2;
20876   S (mp);
20877
20878   /* Use a control ping for synchronization */
20879   MPING (CONTROL_PING, mp_ping);
20880   S (mp_ping);
20881
20882   W (ret);
20883   return ret;
20884 }
20885
20886 int
20887 api_pg_create_interface (vat_main_t * vam)
20888 {
20889   unformat_input_t *input = vam->input;
20890   vl_api_pg_create_interface_t *mp;
20891
20892   u32 if_id = ~0;
20893   int ret;
20894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20895     {
20896       if (unformat (input, "if_id %d", &if_id))
20897         ;
20898       else
20899         break;
20900     }
20901   if (if_id == ~0)
20902     {
20903       errmsg ("missing pg interface index");
20904       return -99;
20905     }
20906
20907   /* Construct the API message */
20908   M (PG_CREATE_INTERFACE, mp);
20909   mp->context = 0;
20910   mp->interface_id = ntohl (if_id);
20911
20912   S (mp);
20913   W (ret);
20914   return ret;
20915 }
20916
20917 int
20918 api_pg_capture (vat_main_t * vam)
20919 {
20920   unformat_input_t *input = vam->input;
20921   vl_api_pg_capture_t *mp;
20922
20923   u32 if_id = ~0;
20924   u8 enable = 1;
20925   u32 count = 1;
20926   u8 pcap_file_set = 0;
20927   u8 *pcap_file = 0;
20928   int ret;
20929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20930     {
20931       if (unformat (input, "if_id %d", &if_id))
20932         ;
20933       else if (unformat (input, "pcap %s", &pcap_file))
20934         pcap_file_set = 1;
20935       else if (unformat (input, "count %d", &count))
20936         ;
20937       else if (unformat (input, "disable"))
20938         enable = 0;
20939       else
20940         break;
20941     }
20942   if (if_id == ~0)
20943     {
20944       errmsg ("missing pg interface index");
20945       return -99;
20946     }
20947   if (pcap_file_set > 0)
20948     {
20949       if (vec_len (pcap_file) > 255)
20950         {
20951           errmsg ("pcap file name is too long");
20952           return -99;
20953         }
20954     }
20955
20956   u32 name_len = vec_len (pcap_file);
20957   /* Construct the API message */
20958   M (PG_CAPTURE, mp);
20959   mp->context = 0;
20960   mp->interface_id = ntohl (if_id);
20961   mp->is_enabled = enable;
20962   mp->count = ntohl (count);
20963   mp->pcap_name_length = ntohl (name_len);
20964   if (pcap_file_set != 0)
20965     {
20966       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20967     }
20968   vec_free (pcap_file);
20969
20970   S (mp);
20971   W (ret);
20972   return ret;
20973 }
20974
20975 int
20976 api_pg_enable_disable (vat_main_t * vam)
20977 {
20978   unformat_input_t *input = vam->input;
20979   vl_api_pg_enable_disable_t *mp;
20980
20981   u8 enable = 1;
20982   u8 stream_name_set = 0;
20983   u8 *stream_name = 0;
20984   int ret;
20985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20986     {
20987       if (unformat (input, "stream %s", &stream_name))
20988         stream_name_set = 1;
20989       else if (unformat (input, "disable"))
20990         enable = 0;
20991       else
20992         break;
20993     }
20994
20995   if (stream_name_set > 0)
20996     {
20997       if (vec_len (stream_name) > 255)
20998         {
20999           errmsg ("stream name too long");
21000           return -99;
21001         }
21002     }
21003
21004   u32 name_len = vec_len (stream_name);
21005   /* Construct the API message */
21006   M (PG_ENABLE_DISABLE, mp);
21007   mp->context = 0;
21008   mp->is_enabled = enable;
21009   if (stream_name_set != 0)
21010     {
21011       mp->stream_name_length = ntohl (name_len);
21012       clib_memcpy (mp->stream_name, stream_name, name_len);
21013     }
21014   vec_free (stream_name);
21015
21016   S (mp);
21017   W (ret);
21018   return ret;
21019 }
21020
21021 int
21022 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21023 {
21024   unformat_input_t *input = vam->input;
21025   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21026
21027   u16 *low_ports = 0;
21028   u16 *high_ports = 0;
21029   u16 this_low;
21030   u16 this_hi;
21031   ip4_address_t ip4_addr;
21032   ip6_address_t ip6_addr;
21033   u32 length;
21034   u32 tmp, tmp2;
21035   u8 prefix_set = 0;
21036   u32 vrf_id = ~0;
21037   u8 is_add = 1;
21038   u8 is_ipv6 = 0;
21039   int ret;
21040
21041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21042     {
21043       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21044         {
21045           prefix_set = 1;
21046         }
21047       else
21048         if (unformat
21049             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21050         {
21051           prefix_set = 1;
21052           is_ipv6 = 1;
21053         }
21054       else if (unformat (input, "vrf %d", &vrf_id))
21055         ;
21056       else if (unformat (input, "del"))
21057         is_add = 0;
21058       else if (unformat (input, "port %d", &tmp))
21059         {
21060           if (tmp == 0 || tmp > 65535)
21061             {
21062               errmsg ("port %d out of range", tmp);
21063               return -99;
21064             }
21065           this_low = tmp;
21066           this_hi = this_low + 1;
21067           vec_add1 (low_ports, this_low);
21068           vec_add1 (high_ports, this_hi);
21069         }
21070       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21071         {
21072           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21073             {
21074               errmsg ("incorrect range parameters");
21075               return -99;
21076             }
21077           this_low = tmp;
21078           /* Note: in debug CLI +1 is added to high before
21079              passing to real fn that does "the work"
21080              (ip_source_and_port_range_check_add_del).
21081              This fn is a wrapper around the binary API fn a
21082              control plane will call, which expects this increment
21083              to have occurred. Hence letting the binary API control
21084              plane fn do the increment for consistency between VAT
21085              and other control planes.
21086            */
21087           this_hi = tmp2;
21088           vec_add1 (low_ports, this_low);
21089           vec_add1 (high_ports, this_hi);
21090         }
21091       else
21092         break;
21093     }
21094
21095   if (prefix_set == 0)
21096     {
21097       errmsg ("<address>/<mask> not specified");
21098       return -99;
21099     }
21100
21101   if (vrf_id == ~0)
21102     {
21103       errmsg ("VRF ID required, not specified");
21104       return -99;
21105     }
21106
21107   if (vrf_id == 0)
21108     {
21109       errmsg
21110         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21111       return -99;
21112     }
21113
21114   if (vec_len (low_ports) == 0)
21115     {
21116       errmsg ("At least one port or port range required");
21117       return -99;
21118     }
21119
21120   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21121
21122   mp->is_add = is_add;
21123
21124   if (is_ipv6)
21125     {
21126       mp->is_ipv6 = 1;
21127       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21128     }
21129   else
21130     {
21131       mp->is_ipv6 = 0;
21132       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21133     }
21134
21135   mp->mask_length = length;
21136   mp->number_of_ranges = vec_len (low_ports);
21137
21138   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21139   vec_free (low_ports);
21140
21141   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21142   vec_free (high_ports);
21143
21144   mp->vrf_id = ntohl (vrf_id);
21145
21146   S (mp);
21147   W (ret);
21148   return ret;
21149 }
21150
21151 int
21152 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21153 {
21154   unformat_input_t *input = vam->input;
21155   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21156   u32 sw_if_index = ~0;
21157   int vrf_set = 0;
21158   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21159   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21160   u8 is_add = 1;
21161   int ret;
21162
21163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21164     {
21165       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21166         ;
21167       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21168         ;
21169       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21170         vrf_set = 1;
21171       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21172         vrf_set = 1;
21173       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21174         vrf_set = 1;
21175       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21176         vrf_set = 1;
21177       else if (unformat (input, "del"))
21178         is_add = 0;
21179       else
21180         break;
21181     }
21182
21183   if (sw_if_index == ~0)
21184     {
21185       errmsg ("Interface required but not specified");
21186       return -99;
21187     }
21188
21189   if (vrf_set == 0)
21190     {
21191       errmsg ("VRF ID required but not specified");
21192       return -99;
21193     }
21194
21195   if (tcp_out_vrf_id == 0
21196       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21197     {
21198       errmsg
21199         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21200       return -99;
21201     }
21202
21203   /* Construct the API message */
21204   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21205
21206   mp->sw_if_index = ntohl (sw_if_index);
21207   mp->is_add = is_add;
21208   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21209   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21210   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21211   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21212
21213   /* send it... */
21214   S (mp);
21215
21216   /* Wait for a reply... */
21217   W (ret);
21218   return ret;
21219 }
21220
21221 static int
21222 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21223 {
21224   unformat_input_t *i = vam->input;
21225   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21226   u32 local_sa_id = 0;
21227   u32 remote_sa_id = 0;
21228   ip4_address_t src_address;
21229   ip4_address_t dst_address;
21230   u8 is_add = 1;
21231   int ret;
21232
21233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21234     {
21235       if (unformat (i, "local_sa %d", &local_sa_id))
21236         ;
21237       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21238         ;
21239       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21240         ;
21241       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21242         ;
21243       else if (unformat (i, "del"))
21244         is_add = 0;
21245       else
21246         {
21247           clib_warning ("parse error '%U'", format_unformat_error, i);
21248           return -99;
21249         }
21250     }
21251
21252   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21253
21254   mp->local_sa_id = ntohl (local_sa_id);
21255   mp->remote_sa_id = ntohl (remote_sa_id);
21256   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21257   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21258   mp->is_add = is_add;
21259
21260   S (mp);
21261   W (ret);
21262   return ret;
21263 }
21264
21265 static int
21266 api_set_punt (vat_main_t * vam)
21267 {
21268   unformat_input_t *i = vam->input;
21269   vl_api_set_punt_t *mp;
21270   u32 ipv = ~0;
21271   u32 protocol = ~0;
21272   u32 port = ~0;
21273   int is_add = 1;
21274   int ret;
21275
21276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21277     {
21278       if (unformat (i, "ip %d", &ipv))
21279         ;
21280       else if (unformat (i, "protocol %d", &protocol))
21281         ;
21282       else if (unformat (i, "port %d", &port))
21283         ;
21284       else if (unformat (i, "del"))
21285         is_add = 0;
21286       else
21287         {
21288           clib_warning ("parse error '%U'", format_unformat_error, i);
21289           return -99;
21290         }
21291     }
21292
21293   M (SET_PUNT, mp);
21294
21295   mp->is_add = (u8) is_add;
21296   mp->punt.ipv = (u8) ipv;
21297   mp->punt.l4_protocol = (u8) protocol;
21298   mp->punt.l4_port = htons ((u16) port);
21299
21300   S (mp);
21301   W (ret);
21302   return ret;
21303 }
21304
21305 static void vl_api_ipsec_gre_tunnel_details_t_handler
21306   (vl_api_ipsec_gre_tunnel_details_t * mp)
21307 {
21308   vat_main_t *vam = &vat_main;
21309
21310   print (vam->ofp, "%11d%15U%15U%14d%14d",
21311          ntohl (mp->sw_if_index),
21312          format_ip4_address, &mp->src_address,
21313          format_ip4_address, &mp->dst_address,
21314          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21315 }
21316
21317 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21318   (vl_api_ipsec_gre_tunnel_details_t * mp)
21319 {
21320   vat_main_t *vam = &vat_main;
21321   vat_json_node_t *node = NULL;
21322   struct in_addr ip4;
21323
21324   if (VAT_JSON_ARRAY != vam->json_tree.type)
21325     {
21326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21327       vat_json_init_array (&vam->json_tree);
21328     }
21329   node = vat_json_array_add (&vam->json_tree);
21330
21331   vat_json_init_object (node);
21332   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21333   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21334   vat_json_object_add_ip4 (node, "src_address", ip4);
21335   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21336   vat_json_object_add_ip4 (node, "dst_address", ip4);
21337   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21338   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21339 }
21340
21341 static int
21342 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21343 {
21344   unformat_input_t *i = vam->input;
21345   vl_api_ipsec_gre_tunnel_dump_t *mp;
21346   vl_api_control_ping_t *mp_ping;
21347   u32 sw_if_index;
21348   u8 sw_if_index_set = 0;
21349   int ret;
21350
21351   /* Parse args required to build the message */
21352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21353     {
21354       if (unformat (i, "sw_if_index %d", &sw_if_index))
21355         sw_if_index_set = 1;
21356       else
21357         break;
21358     }
21359
21360   if (sw_if_index_set == 0)
21361     {
21362       sw_if_index = ~0;
21363     }
21364
21365   if (!vam->json_output)
21366     {
21367       print (vam->ofp, "%11s%15s%15s%14s%14s",
21368              "sw_if_index", "src_address", "dst_address",
21369              "local_sa_id", "remote_sa_id");
21370     }
21371
21372   /* Get list of gre-tunnel interfaces */
21373   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21374
21375   mp->sw_if_index = htonl (sw_if_index);
21376
21377   S (mp);
21378
21379   /* Use a control ping for synchronization */
21380   MPING (CONTROL_PING, mp_ping);
21381   S (mp_ping);
21382
21383   W (ret);
21384   return ret;
21385 }
21386
21387 static int
21388 api_delete_subif (vat_main_t * vam)
21389 {
21390   unformat_input_t *i = vam->input;
21391   vl_api_delete_subif_t *mp;
21392   u32 sw_if_index = ~0;
21393   int ret;
21394
21395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21396     {
21397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21398         ;
21399       if (unformat (i, "sw_if_index %d", &sw_if_index))
21400         ;
21401       else
21402         break;
21403     }
21404
21405   if (sw_if_index == ~0)
21406     {
21407       errmsg ("missing sw_if_index");
21408       return -99;
21409     }
21410
21411   /* Construct the API message */
21412   M (DELETE_SUBIF, mp);
21413   mp->sw_if_index = ntohl (sw_if_index);
21414
21415   S (mp);
21416   W (ret);
21417   return ret;
21418 }
21419
21420 #define foreach_pbb_vtr_op      \
21421 _("disable",  L2_VTR_DISABLED)  \
21422 _("pop",  L2_VTR_POP_2)         \
21423 _("push",  L2_VTR_PUSH_2)
21424
21425 static int
21426 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21427 {
21428   unformat_input_t *i = vam->input;
21429   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21430   u32 sw_if_index = ~0, vtr_op = ~0;
21431   u16 outer_tag = ~0;
21432   u8 dmac[6], smac[6];
21433   u8 dmac_set = 0, smac_set = 0;
21434   u16 vlanid = 0;
21435   u32 sid = ~0;
21436   u32 tmp;
21437   int ret;
21438
21439   /* Shut up coverity */
21440   clib_memset (dmac, 0, sizeof (dmac));
21441   clib_memset (smac, 0, sizeof (smac));
21442
21443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21444     {
21445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21446         ;
21447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21448         ;
21449       else if (unformat (i, "vtr_op %d", &vtr_op))
21450         ;
21451 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21452       foreach_pbb_vtr_op
21453 #undef _
21454         else if (unformat (i, "translate_pbb_stag"))
21455         {
21456           if (unformat (i, "%d", &tmp))
21457             {
21458               vtr_op = L2_VTR_TRANSLATE_2_1;
21459               outer_tag = tmp;
21460             }
21461           else
21462             {
21463               errmsg
21464                 ("translate_pbb_stag operation requires outer tag definition");
21465               return -99;
21466             }
21467         }
21468       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21469         dmac_set++;
21470       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21471         smac_set++;
21472       else if (unformat (i, "sid %d", &sid))
21473         ;
21474       else if (unformat (i, "vlanid %d", &tmp))
21475         vlanid = tmp;
21476       else
21477         {
21478           clib_warning ("parse error '%U'", format_unformat_error, i);
21479           return -99;
21480         }
21481     }
21482
21483   if ((sw_if_index == ~0) || (vtr_op == ~0))
21484     {
21485       errmsg ("missing sw_if_index or vtr operation");
21486       return -99;
21487     }
21488   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21489       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21490     {
21491       errmsg
21492         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21493       return -99;
21494     }
21495
21496   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21497   mp->sw_if_index = ntohl (sw_if_index);
21498   mp->vtr_op = ntohl (vtr_op);
21499   mp->outer_tag = ntohs (outer_tag);
21500   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21501   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21502   mp->b_vlanid = ntohs (vlanid);
21503   mp->i_sid = ntohl (sid);
21504
21505   S (mp);
21506   W (ret);
21507   return ret;
21508 }
21509
21510 static int
21511 api_flow_classify_set_interface (vat_main_t * vam)
21512 {
21513   unformat_input_t *i = vam->input;
21514   vl_api_flow_classify_set_interface_t *mp;
21515   u32 sw_if_index;
21516   int sw_if_index_set;
21517   u32 ip4_table_index = ~0;
21518   u32 ip6_table_index = ~0;
21519   u8 is_add = 1;
21520   int ret;
21521
21522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21523     {
21524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21525         sw_if_index_set = 1;
21526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21527         sw_if_index_set = 1;
21528       else if (unformat (i, "del"))
21529         is_add = 0;
21530       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21531         ;
21532       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21533         ;
21534       else
21535         {
21536           clib_warning ("parse error '%U'", format_unformat_error, i);
21537           return -99;
21538         }
21539     }
21540
21541   if (sw_if_index_set == 0)
21542     {
21543       errmsg ("missing interface name or sw_if_index");
21544       return -99;
21545     }
21546
21547   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21548
21549   mp->sw_if_index = ntohl (sw_if_index);
21550   mp->ip4_table_index = ntohl (ip4_table_index);
21551   mp->ip6_table_index = ntohl (ip6_table_index);
21552   mp->is_add = is_add;
21553
21554   S (mp);
21555   W (ret);
21556   return ret;
21557 }
21558
21559 static int
21560 api_flow_classify_dump (vat_main_t * vam)
21561 {
21562   unformat_input_t *i = vam->input;
21563   vl_api_flow_classify_dump_t *mp;
21564   vl_api_control_ping_t *mp_ping;
21565   u8 type = FLOW_CLASSIFY_N_TABLES;
21566   int ret;
21567
21568   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21569     ;
21570   else
21571     {
21572       errmsg ("classify table type must be specified");
21573       return -99;
21574     }
21575
21576   if (!vam->json_output)
21577     {
21578       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21579     }
21580
21581   M (FLOW_CLASSIFY_DUMP, mp);
21582   mp->type = type;
21583   /* send it... */
21584   S (mp);
21585
21586   /* Use a control ping for synchronization */
21587   MPING (CONTROL_PING, mp_ping);
21588   S (mp_ping);
21589
21590   /* Wait for a reply... */
21591   W (ret);
21592   return ret;
21593 }
21594
21595 static int
21596 api_feature_enable_disable (vat_main_t * vam)
21597 {
21598   unformat_input_t *i = vam->input;
21599   vl_api_feature_enable_disable_t *mp;
21600   u8 *arc_name = 0;
21601   u8 *feature_name = 0;
21602   u32 sw_if_index = ~0;
21603   u8 enable = 1;
21604   int ret;
21605
21606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21607     {
21608       if (unformat (i, "arc_name %s", &arc_name))
21609         ;
21610       else if (unformat (i, "feature_name %s", &feature_name))
21611         ;
21612       else
21613         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21614         ;
21615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21616         ;
21617       else if (unformat (i, "disable"))
21618         enable = 0;
21619       else
21620         break;
21621     }
21622
21623   if (arc_name == 0)
21624     {
21625       errmsg ("missing arc name");
21626       return -99;
21627     }
21628   if (vec_len (arc_name) > 63)
21629     {
21630       errmsg ("arc name too long");
21631     }
21632
21633   if (feature_name == 0)
21634     {
21635       errmsg ("missing feature name");
21636       return -99;
21637     }
21638   if (vec_len (feature_name) > 63)
21639     {
21640       errmsg ("feature name too long");
21641     }
21642
21643   if (sw_if_index == ~0)
21644     {
21645       errmsg ("missing interface name or sw_if_index");
21646       return -99;
21647     }
21648
21649   /* Construct the API message */
21650   M (FEATURE_ENABLE_DISABLE, mp);
21651   mp->sw_if_index = ntohl (sw_if_index);
21652   mp->enable = enable;
21653   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21654   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21655   vec_free (arc_name);
21656   vec_free (feature_name);
21657
21658   S (mp);
21659   W (ret);
21660   return ret;
21661 }
21662
21663 static int
21664 api_sw_interface_tag_add_del (vat_main_t * vam)
21665 {
21666   unformat_input_t *i = vam->input;
21667   vl_api_sw_interface_tag_add_del_t *mp;
21668   u32 sw_if_index = ~0;
21669   u8 *tag = 0;
21670   u8 enable = 1;
21671   int ret;
21672
21673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21674     {
21675       if (unformat (i, "tag %s", &tag))
21676         ;
21677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21678         ;
21679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21680         ;
21681       else if (unformat (i, "del"))
21682         enable = 0;
21683       else
21684         break;
21685     }
21686
21687   if (sw_if_index == ~0)
21688     {
21689       errmsg ("missing interface name or sw_if_index");
21690       return -99;
21691     }
21692
21693   if (enable && (tag == 0))
21694     {
21695       errmsg ("no tag specified");
21696       return -99;
21697     }
21698
21699   /* Construct the API message */
21700   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21701   mp->sw_if_index = ntohl (sw_if_index);
21702   mp->is_add = enable;
21703   if (enable)
21704     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21705   vec_free (tag);
21706
21707   S (mp);
21708   W (ret);
21709   return ret;
21710 }
21711
21712 static void vl_api_l2_xconnect_details_t_handler
21713   (vl_api_l2_xconnect_details_t * mp)
21714 {
21715   vat_main_t *vam = &vat_main;
21716
21717   print (vam->ofp, "%15d%15d",
21718          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21719 }
21720
21721 static void vl_api_l2_xconnect_details_t_handler_json
21722   (vl_api_l2_xconnect_details_t * mp)
21723 {
21724   vat_main_t *vam = &vat_main;
21725   vat_json_node_t *node = NULL;
21726
21727   if (VAT_JSON_ARRAY != vam->json_tree.type)
21728     {
21729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21730       vat_json_init_array (&vam->json_tree);
21731     }
21732   node = vat_json_array_add (&vam->json_tree);
21733
21734   vat_json_init_object (node);
21735   vat_json_object_add_uint (node, "rx_sw_if_index",
21736                             ntohl (mp->rx_sw_if_index));
21737   vat_json_object_add_uint (node, "tx_sw_if_index",
21738                             ntohl (mp->tx_sw_if_index));
21739 }
21740
21741 static int
21742 api_l2_xconnect_dump (vat_main_t * vam)
21743 {
21744   vl_api_l2_xconnect_dump_t *mp;
21745   vl_api_control_ping_t *mp_ping;
21746   int ret;
21747
21748   if (!vam->json_output)
21749     {
21750       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21751     }
21752
21753   M (L2_XCONNECT_DUMP, mp);
21754
21755   S (mp);
21756
21757   /* Use a control ping for synchronization */
21758   MPING (CONTROL_PING, mp_ping);
21759   S (mp_ping);
21760
21761   W (ret);
21762   return ret;
21763 }
21764
21765 static int
21766 api_hw_interface_set_mtu (vat_main_t * vam)
21767 {
21768   unformat_input_t *i = vam->input;
21769   vl_api_hw_interface_set_mtu_t *mp;
21770   u32 sw_if_index = ~0;
21771   u32 mtu = 0;
21772   int ret;
21773
21774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21775     {
21776       if (unformat (i, "mtu %d", &mtu))
21777         ;
21778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21779         ;
21780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21781         ;
21782       else
21783         break;
21784     }
21785
21786   if (sw_if_index == ~0)
21787     {
21788       errmsg ("missing interface name or sw_if_index");
21789       return -99;
21790     }
21791
21792   if (mtu == 0)
21793     {
21794       errmsg ("no mtu specified");
21795       return -99;
21796     }
21797
21798   /* Construct the API message */
21799   M (HW_INTERFACE_SET_MTU, mp);
21800   mp->sw_if_index = ntohl (sw_if_index);
21801   mp->mtu = ntohs ((u16) mtu);
21802
21803   S (mp);
21804   W (ret);
21805   return ret;
21806 }
21807
21808 static int
21809 api_p2p_ethernet_add (vat_main_t * vam)
21810 {
21811   unformat_input_t *i = vam->input;
21812   vl_api_p2p_ethernet_add_t *mp;
21813   u32 parent_if_index = ~0;
21814   u32 sub_id = ~0;
21815   u8 remote_mac[6];
21816   u8 mac_set = 0;
21817   int ret;
21818
21819   clib_memset (remote_mac, 0, sizeof (remote_mac));
21820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21821     {
21822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21823         ;
21824       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21825         ;
21826       else
21827         if (unformat
21828             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21829         mac_set++;
21830       else if (unformat (i, "sub_id %d", &sub_id))
21831         ;
21832       else
21833         {
21834           clib_warning ("parse error '%U'", format_unformat_error, i);
21835           return -99;
21836         }
21837     }
21838
21839   if (parent_if_index == ~0)
21840     {
21841       errmsg ("missing interface name or sw_if_index");
21842       return -99;
21843     }
21844   if (mac_set == 0)
21845     {
21846       errmsg ("missing remote mac address");
21847       return -99;
21848     }
21849   if (sub_id == ~0)
21850     {
21851       errmsg ("missing sub-interface id");
21852       return -99;
21853     }
21854
21855   M (P2P_ETHERNET_ADD, mp);
21856   mp->parent_if_index = ntohl (parent_if_index);
21857   mp->subif_id = ntohl (sub_id);
21858   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21859
21860   S (mp);
21861   W (ret);
21862   return ret;
21863 }
21864
21865 static int
21866 api_p2p_ethernet_del (vat_main_t * vam)
21867 {
21868   unformat_input_t *i = vam->input;
21869   vl_api_p2p_ethernet_del_t *mp;
21870   u32 parent_if_index = ~0;
21871   u8 remote_mac[6];
21872   u8 mac_set = 0;
21873   int ret;
21874
21875   clib_memset (remote_mac, 0, sizeof (remote_mac));
21876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21877     {
21878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21879         ;
21880       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21881         ;
21882       else
21883         if (unformat
21884             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21885         mac_set++;
21886       else
21887         {
21888           clib_warning ("parse error '%U'", format_unformat_error, i);
21889           return -99;
21890         }
21891     }
21892
21893   if (parent_if_index == ~0)
21894     {
21895       errmsg ("missing interface name or sw_if_index");
21896       return -99;
21897     }
21898   if (mac_set == 0)
21899     {
21900       errmsg ("missing remote mac address");
21901       return -99;
21902     }
21903
21904   M (P2P_ETHERNET_DEL, mp);
21905   mp->parent_if_index = ntohl (parent_if_index);
21906   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21907
21908   S (mp);
21909   W (ret);
21910   return ret;
21911 }
21912
21913 static int
21914 api_lldp_config (vat_main_t * vam)
21915 {
21916   unformat_input_t *i = vam->input;
21917   vl_api_lldp_config_t *mp;
21918   int tx_hold = 0;
21919   int tx_interval = 0;
21920   u8 *sys_name = NULL;
21921   int ret;
21922
21923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21924     {
21925       if (unformat (i, "system-name %s", &sys_name))
21926         ;
21927       else if (unformat (i, "tx-hold %d", &tx_hold))
21928         ;
21929       else if (unformat (i, "tx-interval %d", &tx_interval))
21930         ;
21931       else
21932         {
21933           clib_warning ("parse error '%U'", format_unformat_error, i);
21934           return -99;
21935         }
21936     }
21937
21938   vec_add1 (sys_name, 0);
21939
21940   M (LLDP_CONFIG, mp);
21941   mp->tx_hold = htonl (tx_hold);
21942   mp->tx_interval = htonl (tx_interval);
21943   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21944   vec_free (sys_name);
21945
21946   S (mp);
21947   W (ret);
21948   return ret;
21949 }
21950
21951 static int
21952 api_sw_interface_set_lldp (vat_main_t * vam)
21953 {
21954   unformat_input_t *i = vam->input;
21955   vl_api_sw_interface_set_lldp_t *mp;
21956   u32 sw_if_index = ~0;
21957   u32 enable = 1;
21958   u8 *port_desc = NULL, *mgmt_oid = NULL;
21959   ip4_address_t ip4_addr;
21960   ip6_address_t ip6_addr;
21961   int ret;
21962
21963   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21964   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21965
21966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21967     {
21968       if (unformat (i, "disable"))
21969         enable = 0;
21970       else
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, "port-desc %s", &port_desc))
21976         ;
21977       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21978         ;
21979       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21980         ;
21981       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21982         ;
21983       else
21984         break;
21985     }
21986
21987   if (sw_if_index == ~0)
21988     {
21989       errmsg ("missing interface name or sw_if_index");
21990       return -99;
21991     }
21992
21993   /* Construct the API message */
21994   vec_add1 (port_desc, 0);
21995   vec_add1 (mgmt_oid, 0);
21996   M (SW_INTERFACE_SET_LLDP, mp);
21997   mp->sw_if_index = ntohl (sw_if_index);
21998   mp->enable = enable;
21999   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22000   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22001   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22002   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22003   vec_free (port_desc);
22004   vec_free (mgmt_oid);
22005
22006   S (mp);
22007   W (ret);
22008   return ret;
22009 }
22010
22011 static int
22012 api_tcp_configure_src_addresses (vat_main_t * vam)
22013 {
22014   vl_api_tcp_configure_src_addresses_t *mp;
22015   unformat_input_t *i = vam->input;
22016   ip4_address_t v4first, v4last;
22017   ip6_address_t v6first, v6last;
22018   u8 range_set = 0;
22019   u32 vrf_id = 0;
22020   int ret;
22021
22022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22023     {
22024       if (unformat (i, "%U - %U",
22025                     unformat_ip4_address, &v4first,
22026                     unformat_ip4_address, &v4last))
22027         {
22028           if (range_set)
22029             {
22030               errmsg ("one range per message (range already set)");
22031               return -99;
22032             }
22033           range_set = 1;
22034         }
22035       else if (unformat (i, "%U - %U",
22036                          unformat_ip6_address, &v6first,
22037                          unformat_ip6_address, &v6last))
22038         {
22039           if (range_set)
22040             {
22041               errmsg ("one range per message (range already set)");
22042               return -99;
22043             }
22044           range_set = 2;
22045         }
22046       else if (unformat (i, "vrf %d", &vrf_id))
22047         ;
22048       else
22049         break;
22050     }
22051
22052   if (range_set == 0)
22053     {
22054       errmsg ("address range not set");
22055       return -99;
22056     }
22057
22058   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22059   mp->vrf_id = ntohl (vrf_id);
22060   /* ipv6? */
22061   if (range_set == 2)
22062     {
22063       mp->is_ipv6 = 1;
22064       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22065       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22066     }
22067   else
22068     {
22069       mp->is_ipv6 = 0;
22070       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22071       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22072     }
22073   S (mp);
22074   W (ret);
22075   return ret;
22076 }
22077
22078 static void vl_api_app_namespace_add_del_reply_t_handler
22079   (vl_api_app_namespace_add_del_reply_t * mp)
22080 {
22081   vat_main_t *vam = &vat_main;
22082   i32 retval = ntohl (mp->retval);
22083   if (vam->async_mode)
22084     {
22085       vam->async_errors += (retval < 0);
22086     }
22087   else
22088     {
22089       vam->retval = retval;
22090       if (retval == 0)
22091         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22092       vam->result_ready = 1;
22093     }
22094 }
22095
22096 static void vl_api_app_namespace_add_del_reply_t_handler_json
22097   (vl_api_app_namespace_add_del_reply_t * mp)
22098 {
22099   vat_main_t *vam = &vat_main;
22100   vat_json_node_t node;
22101
22102   vat_json_init_object (&node);
22103   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22104   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22105
22106   vat_json_print (vam->ofp, &node);
22107   vat_json_free (&node);
22108
22109   vam->retval = ntohl (mp->retval);
22110   vam->result_ready = 1;
22111 }
22112
22113 static int
22114 api_app_namespace_add_del (vat_main_t * vam)
22115 {
22116   vl_api_app_namespace_add_del_t *mp;
22117   unformat_input_t *i = vam->input;
22118   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22119   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22120   u64 secret;
22121   int ret;
22122
22123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22124     {
22125       if (unformat (i, "id %_%v%_", &ns_id))
22126         ;
22127       else if (unformat (i, "secret %lu", &secret))
22128         secret_set = 1;
22129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22130         sw_if_index_set = 1;
22131       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22132         ;
22133       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22134         ;
22135       else
22136         break;
22137     }
22138   if (!ns_id || !secret_set || !sw_if_index_set)
22139     {
22140       errmsg ("namespace id, secret and sw_if_index must be set");
22141       return -99;
22142     }
22143   if (vec_len (ns_id) > 64)
22144     {
22145       errmsg ("namespace id too long");
22146       return -99;
22147     }
22148   M (APP_NAMESPACE_ADD_DEL, mp);
22149
22150   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22151   mp->namespace_id_len = vec_len (ns_id);
22152   mp->secret = clib_host_to_net_u64 (secret);
22153   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22154   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22155   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22156   vec_free (ns_id);
22157   S (mp);
22158   W (ret);
22159   return ret;
22160 }
22161
22162 static int
22163 api_sock_init_shm (vat_main_t * vam)
22164 {
22165 #if VPP_API_TEST_BUILTIN == 0
22166   unformat_input_t *i = vam->input;
22167   vl_api_shm_elem_config_t *config = 0;
22168   u64 size = 64 << 20;
22169   int rv;
22170
22171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22172     {
22173       if (unformat (i, "size %U", unformat_memory_size, &size))
22174         ;
22175       else
22176         break;
22177     }
22178
22179   /*
22180    * Canned custom ring allocator config.
22181    * Should probably parse all of this
22182    */
22183   vec_validate (config, 6);
22184   config[0].type = VL_API_VLIB_RING;
22185   config[0].size = 256;
22186   config[0].count = 32;
22187
22188   config[1].type = VL_API_VLIB_RING;
22189   config[1].size = 1024;
22190   config[1].count = 16;
22191
22192   config[2].type = VL_API_VLIB_RING;
22193   config[2].size = 4096;
22194   config[2].count = 2;
22195
22196   config[3].type = VL_API_CLIENT_RING;
22197   config[3].size = 256;
22198   config[3].count = 32;
22199
22200   config[4].type = VL_API_CLIENT_RING;
22201   config[4].size = 1024;
22202   config[4].count = 16;
22203
22204   config[5].type = VL_API_CLIENT_RING;
22205   config[5].size = 4096;
22206   config[5].count = 2;
22207
22208   config[6].type = VL_API_QUEUE;
22209   config[6].count = 128;
22210   config[6].size = sizeof (uword);
22211
22212   rv = vl_socket_client_init_shm (config);
22213   if (!rv)
22214     vam->client_index_invalid = 1;
22215   return rv;
22216 #else
22217   return -99;
22218 #endif
22219 }
22220
22221 static int
22222 api_dns_enable_disable (vat_main_t * vam)
22223 {
22224   unformat_input_t *line_input = vam->input;
22225   vl_api_dns_enable_disable_t *mp;
22226   u8 enable_disable = 1;
22227   int ret;
22228
22229   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22230     {
22231       if (unformat (line_input, "disable"))
22232         enable_disable = 0;
22233       if (unformat (line_input, "enable"))
22234         enable_disable = 1;
22235       else
22236         break;
22237     }
22238
22239   /* Construct the API message */
22240   M (DNS_ENABLE_DISABLE, mp);
22241   mp->enable = enable_disable;
22242
22243   /* send it... */
22244   S (mp);
22245   /* Wait for the reply */
22246   W (ret);
22247   return ret;
22248 }
22249
22250 static int
22251 api_dns_resolve_name (vat_main_t * vam)
22252 {
22253   unformat_input_t *line_input = vam->input;
22254   vl_api_dns_resolve_name_t *mp;
22255   u8 *name = 0;
22256   int ret;
22257
22258   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22259     {
22260       if (unformat (line_input, "%s", &name))
22261         ;
22262       else
22263         break;
22264     }
22265
22266   if (vec_len (name) > 127)
22267     {
22268       errmsg ("name too long");
22269       return -99;
22270     }
22271
22272   /* Construct the API message */
22273   M (DNS_RESOLVE_NAME, mp);
22274   memcpy (mp->name, name, vec_len (name));
22275   vec_free (name);
22276
22277   /* send it... */
22278   S (mp);
22279   /* Wait for the reply */
22280   W (ret);
22281   return ret;
22282 }
22283
22284 static int
22285 api_dns_resolve_ip (vat_main_t * vam)
22286 {
22287   unformat_input_t *line_input = vam->input;
22288   vl_api_dns_resolve_ip_t *mp;
22289   int is_ip6 = -1;
22290   ip4_address_t addr4;
22291   ip6_address_t addr6;
22292   int ret;
22293
22294   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22295     {
22296       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22297         is_ip6 = 1;
22298       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22299         is_ip6 = 0;
22300       else
22301         break;
22302     }
22303
22304   if (is_ip6 == -1)
22305     {
22306       errmsg ("missing address");
22307       return -99;
22308     }
22309
22310   /* Construct the API message */
22311   M (DNS_RESOLVE_IP, mp);
22312   mp->is_ip6 = is_ip6;
22313   if (is_ip6)
22314     memcpy (mp->address, &addr6, sizeof (addr6));
22315   else
22316     memcpy (mp->address, &addr4, sizeof (addr4));
22317
22318   /* send it... */
22319   S (mp);
22320   /* Wait for the reply */
22321   W (ret);
22322   return ret;
22323 }
22324
22325 static int
22326 api_dns_name_server_add_del (vat_main_t * vam)
22327 {
22328   unformat_input_t *i = vam->input;
22329   vl_api_dns_name_server_add_del_t *mp;
22330   u8 is_add = 1;
22331   ip6_address_t ip6_server;
22332   ip4_address_t ip4_server;
22333   int ip6_set = 0;
22334   int ip4_set = 0;
22335   int ret = 0;
22336
22337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22338     {
22339       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22340         ip6_set = 1;
22341       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22342         ip4_set = 1;
22343       else if (unformat (i, "del"))
22344         is_add = 0;
22345       else
22346         {
22347           clib_warning ("parse error '%U'", format_unformat_error, i);
22348           return -99;
22349         }
22350     }
22351
22352   if (ip4_set && ip6_set)
22353     {
22354       errmsg ("Only one server address allowed per message");
22355       return -99;
22356     }
22357   if ((ip4_set + ip6_set) == 0)
22358     {
22359       errmsg ("Server address required");
22360       return -99;
22361     }
22362
22363   /* Construct the API message */
22364   M (DNS_NAME_SERVER_ADD_DEL, mp);
22365
22366   if (ip6_set)
22367     {
22368       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22369       mp->is_ip6 = 1;
22370     }
22371   else
22372     {
22373       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22374       mp->is_ip6 = 0;
22375     }
22376
22377   mp->is_add = is_add;
22378
22379   /* send it... */
22380   S (mp);
22381
22382   /* Wait for a reply, return good/bad news  */
22383   W (ret);
22384   return ret;
22385 }
22386
22387 static void
22388 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22389 {
22390   vat_main_t *vam = &vat_main;
22391
22392   if (mp->is_ip4)
22393     {
22394       print (vam->ofp,
22395              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22396              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22397              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22398              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22399              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22400              clib_net_to_host_u32 (mp->action_index), mp->tag);
22401     }
22402   else
22403     {
22404       print (vam->ofp,
22405              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22406              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22407              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22408              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22409              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22410              clib_net_to_host_u32 (mp->action_index), mp->tag);
22411     }
22412 }
22413
22414 static void
22415 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22416                                              mp)
22417 {
22418   vat_main_t *vam = &vat_main;
22419   vat_json_node_t *node = NULL;
22420   struct in6_addr ip6;
22421   struct in_addr ip4;
22422
22423   if (VAT_JSON_ARRAY != vam->json_tree.type)
22424     {
22425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22426       vat_json_init_array (&vam->json_tree);
22427     }
22428   node = vat_json_array_add (&vam->json_tree);
22429   vat_json_init_object (node);
22430
22431   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22432   vat_json_object_add_uint (node, "appns_index",
22433                             clib_net_to_host_u32 (mp->appns_index));
22434   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22435   vat_json_object_add_uint (node, "scope", mp->scope);
22436   vat_json_object_add_uint (node, "action_index",
22437                             clib_net_to_host_u32 (mp->action_index));
22438   vat_json_object_add_uint (node, "lcl_port",
22439                             clib_net_to_host_u16 (mp->lcl_port));
22440   vat_json_object_add_uint (node, "rmt_port",
22441                             clib_net_to_host_u16 (mp->rmt_port));
22442   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22443   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22444   vat_json_object_add_string_copy (node, "tag", mp->tag);
22445   if (mp->is_ip4)
22446     {
22447       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22448       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22449       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22450       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22451     }
22452   else
22453     {
22454       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22455       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22456       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22457       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22458     }
22459 }
22460
22461 static int
22462 api_session_rule_add_del (vat_main_t * vam)
22463 {
22464   vl_api_session_rule_add_del_t *mp;
22465   unformat_input_t *i = vam->input;
22466   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22467   u32 appns_index = 0, scope = 0;
22468   ip4_address_t lcl_ip4, rmt_ip4;
22469   ip6_address_t lcl_ip6, rmt_ip6;
22470   u8 is_ip4 = 1, conn_set = 0;
22471   u8 is_add = 1, *tag = 0;
22472   int ret;
22473
22474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22475     {
22476       if (unformat (i, "del"))
22477         is_add = 0;
22478       else if (unformat (i, "add"))
22479         ;
22480       else if (unformat (i, "proto tcp"))
22481         proto = 0;
22482       else if (unformat (i, "proto udp"))
22483         proto = 1;
22484       else if (unformat (i, "appns %d", &appns_index))
22485         ;
22486       else if (unformat (i, "scope %d", &scope))
22487         ;
22488       else if (unformat (i, "tag %_%v%_", &tag))
22489         ;
22490       else
22491         if (unformat
22492             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22493              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22494              &rmt_port))
22495         {
22496           is_ip4 = 1;
22497           conn_set = 1;
22498         }
22499       else
22500         if (unformat
22501             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22502              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22503              &rmt_port))
22504         {
22505           is_ip4 = 0;
22506           conn_set = 1;
22507         }
22508       else if (unformat (i, "action %d", &action))
22509         ;
22510       else
22511         break;
22512     }
22513   if (proto == ~0 || !conn_set || action == ~0)
22514     {
22515       errmsg ("transport proto, connection and action must be set");
22516       return -99;
22517     }
22518
22519   if (scope > 3)
22520     {
22521       errmsg ("scope should be 0-3");
22522       return -99;
22523     }
22524
22525   M (SESSION_RULE_ADD_DEL, mp);
22526
22527   mp->is_ip4 = is_ip4;
22528   mp->transport_proto = proto;
22529   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22530   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22531   mp->lcl_plen = lcl_plen;
22532   mp->rmt_plen = rmt_plen;
22533   mp->action_index = clib_host_to_net_u32 (action);
22534   mp->appns_index = clib_host_to_net_u32 (appns_index);
22535   mp->scope = scope;
22536   mp->is_add = is_add;
22537   if (is_ip4)
22538     {
22539       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22540       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22541     }
22542   else
22543     {
22544       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22545       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22546     }
22547   if (tag)
22548     {
22549       clib_memcpy (mp->tag, tag, vec_len (tag));
22550       vec_free (tag);
22551     }
22552
22553   S (mp);
22554   W (ret);
22555   return ret;
22556 }
22557
22558 static int
22559 api_session_rules_dump (vat_main_t * vam)
22560 {
22561   vl_api_session_rules_dump_t *mp;
22562   vl_api_control_ping_t *mp_ping;
22563   int ret;
22564
22565   if (!vam->json_output)
22566     {
22567       print (vam->ofp, "%=20s", "Session Rules");
22568     }
22569
22570   M (SESSION_RULES_DUMP, mp);
22571   /* send it... */
22572   S (mp);
22573
22574   /* Use a control ping for synchronization */
22575   MPING (CONTROL_PING, mp_ping);
22576   S (mp_ping);
22577
22578   /* Wait for a reply... */
22579   W (ret);
22580   return ret;
22581 }
22582
22583 static int
22584 api_ip_container_proxy_add_del (vat_main_t * vam)
22585 {
22586   vl_api_ip_container_proxy_add_del_t *mp;
22587   unformat_input_t *i = vam->input;
22588   u32 plen = ~0, sw_if_index = ~0;
22589   ip4_address_t ip4;
22590   ip6_address_t ip6;
22591   u8 is_ip4 = 1;
22592   u8 is_add = 1;
22593   int ret;
22594
22595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22596     {
22597       if (unformat (i, "del"))
22598         is_add = 0;
22599       else if (unformat (i, "add"))
22600         ;
22601       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22602         {
22603           is_ip4 = 1;
22604           plen = 32;
22605         }
22606       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22607         {
22608           is_ip4 = 0;
22609           plen = 128;
22610         }
22611       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22612         ;
22613       else
22614         break;
22615     }
22616   if (sw_if_index == ~0 || plen == ~0)
22617     {
22618       errmsg ("address and sw_if_index must be set");
22619       return -99;
22620     }
22621
22622   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22623
22624   mp->is_ip4 = is_ip4;
22625   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22626   mp->plen = plen;
22627   mp->is_add = is_add;
22628   if (is_ip4)
22629     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22630   else
22631     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22632
22633   S (mp);
22634   W (ret);
22635   return ret;
22636 }
22637
22638 static int
22639 api_qos_record_enable_disable (vat_main_t * vam)
22640 {
22641   unformat_input_t *i = vam->input;
22642   vl_api_qos_record_enable_disable_t *mp;
22643   u32 sw_if_index, qs = 0xff;
22644   u8 sw_if_index_set = 0;
22645   u8 enable = 1;
22646   int ret;
22647
22648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22649     {
22650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22651         sw_if_index_set = 1;
22652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22653         sw_if_index_set = 1;
22654       else if (unformat (i, "%U", unformat_qos_source, &qs))
22655         ;
22656       else if (unformat (i, "disable"))
22657         enable = 0;
22658       else
22659         {
22660           clib_warning ("parse error '%U'", format_unformat_error, i);
22661           return -99;
22662         }
22663     }
22664
22665   if (sw_if_index_set == 0)
22666     {
22667       errmsg ("missing interface name or sw_if_index");
22668       return -99;
22669     }
22670   if (qs == 0xff)
22671     {
22672       errmsg ("input location must be specified");
22673       return -99;
22674     }
22675
22676   M (QOS_RECORD_ENABLE_DISABLE, mp);
22677
22678   mp->sw_if_index = ntohl (sw_if_index);
22679   mp->input_source = qs;
22680   mp->enable = enable;
22681
22682   S (mp);
22683   W (ret);
22684   return ret;
22685 }
22686
22687
22688 static int
22689 q_or_quit (vat_main_t * vam)
22690 {
22691 #if VPP_API_TEST_BUILTIN == 0
22692   longjmp (vam->jump_buf, 1);
22693 #endif
22694   return 0;                     /* not so much */
22695 }
22696
22697 static int
22698 q (vat_main_t * vam)
22699 {
22700   return q_or_quit (vam);
22701 }
22702
22703 static int
22704 quit (vat_main_t * vam)
22705 {
22706   return q_or_quit (vam);
22707 }
22708
22709 static int
22710 comment (vat_main_t * vam)
22711 {
22712   return 0;
22713 }
22714
22715 static int
22716 statseg (vat_main_t * vam)
22717 {
22718   ssvm_private_t *ssvmp = &vam->stat_segment;
22719   ssvm_shared_header_t *shared_header = ssvmp->sh;
22720   vlib_counter_t **counters;
22721   u64 thread0_index1_packets;
22722   u64 thread0_index1_bytes;
22723   f64 vector_rate, input_rate;
22724   uword *p;
22725
22726   uword *counter_vector_by_name;
22727   if (vam->stat_segment_lockp == 0)
22728     {
22729       errmsg ("Stat segment not mapped...");
22730       return -99;
22731     }
22732
22733   /* look up "/if/rx for sw_if_index 1 as a test */
22734
22735   clib_spinlock_lock (vam->stat_segment_lockp);
22736
22737   counter_vector_by_name = (uword *) shared_header->opaque[1];
22738
22739   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22740   if (p == 0)
22741     {
22742       clib_spinlock_unlock (vam->stat_segment_lockp);
22743       errmsg ("/if/tx not found?");
22744       return -99;
22745     }
22746
22747   /* Fish per-thread vector of combined counters from shared memory */
22748   counters = (vlib_counter_t **) p[0];
22749
22750   if (vec_len (counters[0]) < 2)
22751     {
22752       clib_spinlock_unlock (vam->stat_segment_lockp);
22753       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22754       return -99;
22755     }
22756
22757   /* Read thread 0 sw_if_index 1 counter */
22758   thread0_index1_packets = counters[0][1].packets;
22759   thread0_index1_bytes = counters[0][1].bytes;
22760
22761   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22762   if (p == 0)
22763     {
22764       clib_spinlock_unlock (vam->stat_segment_lockp);
22765       errmsg ("vector_rate not found?");
22766       return -99;
22767     }
22768
22769   vector_rate = *(f64 *) (p[0]);
22770   p = hash_get_mem (counter_vector_by_name, "input_rate");
22771   if (p == 0)
22772     {
22773       clib_spinlock_unlock (vam->stat_segment_lockp);
22774       errmsg ("input_rate not found?");
22775       return -99;
22776     }
22777   input_rate = *(f64 *) (p[0]);
22778
22779   clib_spinlock_unlock (vam->stat_segment_lockp);
22780
22781   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22782          vector_rate, input_rate);
22783   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22784          thread0_index1_packets, thread0_index1_bytes);
22785
22786   return 0;
22787 }
22788
22789 static int
22790 cmd_cmp (void *a1, void *a2)
22791 {
22792   u8 **c1 = a1;
22793   u8 **c2 = a2;
22794
22795   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22796 }
22797
22798 static int
22799 help (vat_main_t * vam)
22800 {
22801   u8 **cmds = 0;
22802   u8 *name = 0;
22803   hash_pair_t *p;
22804   unformat_input_t *i = vam->input;
22805   int j;
22806
22807   if (unformat (i, "%s", &name))
22808     {
22809       uword *hs;
22810
22811       vec_add1 (name, 0);
22812
22813       hs = hash_get_mem (vam->help_by_name, name);
22814       if (hs)
22815         print (vam->ofp, "usage: %s %s", name, hs[0]);
22816       else
22817         print (vam->ofp, "No such msg / command '%s'", name);
22818       vec_free (name);
22819       return 0;
22820     }
22821
22822   print (vam->ofp, "Help is available for the following:");
22823
22824     /* *INDENT-OFF* */
22825     hash_foreach_pair (p, vam->function_by_name,
22826     ({
22827       vec_add1 (cmds, (u8 *)(p->key));
22828     }));
22829     /* *INDENT-ON* */
22830
22831   vec_sort_with_function (cmds, cmd_cmp);
22832
22833   for (j = 0; j < vec_len (cmds); j++)
22834     print (vam->ofp, "%s", cmds[j]);
22835
22836   vec_free (cmds);
22837   return 0;
22838 }
22839
22840 static int
22841 set (vat_main_t * vam)
22842 {
22843   u8 *name = 0, *value = 0;
22844   unformat_input_t *i = vam->input;
22845
22846   if (unformat (i, "%s", &name))
22847     {
22848       /* The input buffer is a vector, not a string. */
22849       value = vec_dup (i->buffer);
22850       vec_delete (value, i->index, 0);
22851       /* Almost certainly has a trailing newline */
22852       if (value[vec_len (value) - 1] == '\n')
22853         value[vec_len (value) - 1] = 0;
22854       /* Make sure it's a proper string, one way or the other */
22855       vec_add1 (value, 0);
22856       (void) clib_macro_set_value (&vam->macro_main,
22857                                    (char *) name, (char *) value);
22858     }
22859   else
22860     errmsg ("usage: set <name> <value>");
22861
22862   vec_free (name);
22863   vec_free (value);
22864   return 0;
22865 }
22866
22867 static int
22868 unset (vat_main_t * vam)
22869 {
22870   u8 *name = 0;
22871
22872   if (unformat (vam->input, "%s", &name))
22873     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22874       errmsg ("unset: %s wasn't set", name);
22875   vec_free (name);
22876   return 0;
22877 }
22878
22879 typedef struct
22880 {
22881   u8 *name;
22882   u8 *value;
22883 } macro_sort_t;
22884
22885
22886 static int
22887 macro_sort_cmp (void *a1, void *a2)
22888 {
22889   macro_sort_t *s1 = a1;
22890   macro_sort_t *s2 = a2;
22891
22892   return strcmp ((char *) (s1->name), (char *) (s2->name));
22893 }
22894
22895 static int
22896 dump_macro_table (vat_main_t * vam)
22897 {
22898   macro_sort_t *sort_me = 0, *sm;
22899   int i;
22900   hash_pair_t *p;
22901
22902     /* *INDENT-OFF* */
22903     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22904     ({
22905       vec_add2 (sort_me, sm, 1);
22906       sm->name = (u8 *)(p->key);
22907       sm->value = (u8 *) (p->value[0]);
22908     }));
22909     /* *INDENT-ON* */
22910
22911   vec_sort_with_function (sort_me, macro_sort_cmp);
22912
22913   if (vec_len (sort_me))
22914     print (vam->ofp, "%-15s%s", "Name", "Value");
22915   else
22916     print (vam->ofp, "The macro table is empty...");
22917
22918   for (i = 0; i < vec_len (sort_me); i++)
22919     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22920   return 0;
22921 }
22922
22923 static int
22924 dump_node_table (vat_main_t * vam)
22925 {
22926   int i, j;
22927   vlib_node_t *node, *next_node;
22928
22929   if (vec_len (vam->graph_nodes) == 0)
22930     {
22931       print (vam->ofp, "Node table empty, issue get_node_graph...");
22932       return 0;
22933     }
22934
22935   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22936     {
22937       node = vam->graph_nodes[0][i];
22938       print (vam->ofp, "[%d] %s", i, node->name);
22939       for (j = 0; j < vec_len (node->next_nodes); j++)
22940         {
22941           if (node->next_nodes[j] != ~0)
22942             {
22943               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22944               print (vam->ofp, "  [%d] %s", j, next_node->name);
22945             }
22946         }
22947     }
22948   return 0;
22949 }
22950
22951 static int
22952 value_sort_cmp (void *a1, void *a2)
22953 {
22954   name_sort_t *n1 = a1;
22955   name_sort_t *n2 = a2;
22956
22957   if (n1->value < n2->value)
22958     return -1;
22959   if (n1->value > n2->value)
22960     return 1;
22961   return 0;
22962 }
22963
22964
22965 static int
22966 dump_msg_api_table (vat_main_t * vam)
22967 {
22968   api_main_t *am = &api_main;
22969   name_sort_t *nses = 0, *ns;
22970   hash_pair_t *hp;
22971   int i;
22972
22973   /* *INDENT-OFF* */
22974   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22975   ({
22976     vec_add2 (nses, ns, 1);
22977     ns->name = (u8 *)(hp->key);
22978     ns->value = (u32) hp->value[0];
22979   }));
22980   /* *INDENT-ON* */
22981
22982   vec_sort_with_function (nses, value_sort_cmp);
22983
22984   for (i = 0; i < vec_len (nses); i++)
22985     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22986   vec_free (nses);
22987   return 0;
22988 }
22989
22990 static int
22991 get_msg_id (vat_main_t * vam)
22992 {
22993   u8 *name_and_crc;
22994   u32 message_index;
22995
22996   if (unformat (vam->input, "%s", &name_and_crc))
22997     {
22998       message_index = vl_msg_api_get_msg_index (name_and_crc);
22999       if (message_index == ~0)
23000         {
23001           print (vam->ofp, " '%s' not found", name_and_crc);
23002           return 0;
23003         }
23004       print (vam->ofp, " '%s' has message index %d",
23005              name_and_crc, message_index);
23006       return 0;
23007     }
23008   errmsg ("name_and_crc required...");
23009   return 0;
23010 }
23011
23012 static int
23013 search_node_table (vat_main_t * vam)
23014 {
23015   unformat_input_t *line_input = vam->input;
23016   u8 *node_to_find;
23017   int j;
23018   vlib_node_t *node, *next_node;
23019   uword *p;
23020
23021   if (vam->graph_node_index_by_name == 0)
23022     {
23023       print (vam->ofp, "Node table empty, issue get_node_graph...");
23024       return 0;
23025     }
23026
23027   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23028     {
23029       if (unformat (line_input, "%s", &node_to_find))
23030         {
23031           vec_add1 (node_to_find, 0);
23032           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23033           if (p == 0)
23034             {
23035               print (vam->ofp, "%s not found...", node_to_find);
23036               goto out;
23037             }
23038           node = vam->graph_nodes[0][p[0]];
23039           print (vam->ofp, "[%d] %s", p[0], node->name);
23040           for (j = 0; j < vec_len (node->next_nodes); j++)
23041             {
23042               if (node->next_nodes[j] != ~0)
23043                 {
23044                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23045                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23046                 }
23047             }
23048         }
23049
23050       else
23051         {
23052           clib_warning ("parse error '%U'", format_unformat_error,
23053                         line_input);
23054           return -99;
23055         }
23056
23057     out:
23058       vec_free (node_to_find);
23059
23060     }
23061
23062   return 0;
23063 }
23064
23065
23066 static int
23067 script (vat_main_t * vam)
23068 {
23069 #if (VPP_API_TEST_BUILTIN==0)
23070   u8 *s = 0;
23071   char *save_current_file;
23072   unformat_input_t save_input;
23073   jmp_buf save_jump_buf;
23074   u32 save_line_number;
23075
23076   FILE *new_fp, *save_ifp;
23077
23078   if (unformat (vam->input, "%s", &s))
23079     {
23080       new_fp = fopen ((char *) s, "r");
23081       if (new_fp == 0)
23082         {
23083           errmsg ("Couldn't open script file %s", s);
23084           vec_free (s);
23085           return -99;
23086         }
23087     }
23088   else
23089     {
23090       errmsg ("Missing script name");
23091       return -99;
23092     }
23093
23094   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23095   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23096   save_ifp = vam->ifp;
23097   save_line_number = vam->input_line_number;
23098   save_current_file = (char *) vam->current_file;
23099
23100   vam->input_line_number = 0;
23101   vam->ifp = new_fp;
23102   vam->current_file = s;
23103   do_one_file (vam);
23104
23105   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23106   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23107   vam->ifp = save_ifp;
23108   vam->input_line_number = save_line_number;
23109   vam->current_file = (u8 *) save_current_file;
23110   vec_free (s);
23111
23112   return 0;
23113 #else
23114   clib_warning ("use the exec command...");
23115   return -99;
23116 #endif
23117 }
23118
23119 static int
23120 echo (vat_main_t * vam)
23121 {
23122   print (vam->ofp, "%v", vam->input->buffer);
23123   return 0;
23124 }
23125
23126 /* List of API message constructors, CLI names map to api_xxx */
23127 #define foreach_vpe_api_msg                                             \
23128 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23129 _(sw_interface_dump,"")                                                 \
23130 _(sw_interface_set_flags,                                               \
23131   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23132 _(sw_interface_add_del_address,                                         \
23133   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23134 _(sw_interface_set_rx_mode,                                             \
23135   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23136 _(sw_interface_set_rx_placement,                                        \
23137   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23138 _(sw_interface_rx_placement_dump,                                       \
23139   "[<intfc> | sw_if_index <id>]")                                         \
23140 _(sw_interface_set_table,                                               \
23141   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23142 _(sw_interface_set_mpls_enable,                                         \
23143   "<intfc> | sw_if_index [disable | dis]")                              \
23144 _(sw_interface_set_vpath,                                               \
23145   "<intfc> | sw_if_index <id> enable | disable")                        \
23146 _(sw_interface_set_vxlan_bypass,                                        \
23147   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23148 _(sw_interface_set_geneve_bypass,                                       \
23149   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23150 _(sw_interface_set_l2_xconnect,                                         \
23151   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23152   "enable | disable")                                                   \
23153 _(sw_interface_set_l2_bridge,                                           \
23154   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23155   "[shg <split-horizon-group>] [bvi]\n"                                 \
23156   "enable | disable")                                                   \
23157 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23158 _(bridge_domain_add_del,                                                \
23159   "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") \
23160 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23161 _(l2fib_add_del,                                                        \
23162   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23163 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23164 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23165 _(l2_flags,                                                             \
23166   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23167 _(bridge_flags,                                                         \
23168   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23169 _(tap_connect,                                                          \
23170   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23171 _(tap_modify,                                                           \
23172   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23173 _(tap_delete,                                                           \
23174   "<vpp-if-name> | sw_if_index <id>")                                   \
23175 _(sw_interface_tap_dump, "")                                            \
23176 _(tap_create_v2,                                                        \
23177   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23178 _(tap_delete_v2,                                                        \
23179   "<vpp-if-name> | sw_if_index <id>")                                   \
23180 _(sw_interface_tap_v2_dump, "")                                         \
23181 _(bond_create,                                                          \
23182   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23183   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
23184   "[id <if-id>]")                                                       \
23185 _(bond_delete,                                                          \
23186   "<vpp-if-name> | sw_if_index <id>")                                   \
23187 _(bond_enslave,                                                         \
23188   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23189 _(bond_detach_slave,                                                    \
23190   "sw_if_index <n>")                                                    \
23191 _(sw_interface_bond_dump, "")                                           \
23192 _(sw_interface_slave_dump,                                              \
23193   "<vpp-if-name> | sw_if_index <id>")                                   \
23194 _(ip_table_add_del,                                                     \
23195   "table <n> [ipv6] [add | del]\n")                                     \
23196 _(ip_add_del_route,                                                     \
23197   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23198   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23199   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23200   "[multipath] [count <n>] [del]")                                      \
23201 _(ip_mroute_add_del,                                                    \
23202   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23203   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23204 _(mpls_table_add_del,                                                   \
23205   "table <n> [add | del]\n")                                            \
23206 _(mpls_route_add_del,                                                   \
23207   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23208   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23209   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23210   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23211   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23212   "[count <n>] [del]")                                                  \
23213 _(mpls_ip_bind_unbind,                                                  \
23214   "<label> <addr/len>")                                                 \
23215 _(mpls_tunnel_add_del,                                                  \
23216   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23217   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23218   "[l2-only]  [out-label <n>]")                                         \
23219 _(sr_mpls_policy_add,                                                   \
23220   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23221 _(sr_mpls_policy_del,                                                   \
23222   "bsid <id>")                                                          \
23223 _(bier_table_add_del,                                                   \
23224   "<label> <sub-domain> <set> <bsl> [del]")                             \
23225 _(bier_route_add_del,                                                   \
23226   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23227   "[<intfc> | sw_if_index <id>]"                                        \
23228   "[weight <n>] [del] [multipath]")                                     \
23229 _(proxy_arp_add_del,                                                    \
23230   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23231 _(proxy_arp_intfc_enable_disable,                                       \
23232   "<intfc> | sw_if_index <id> enable | disable")                        \
23233 _(sw_interface_set_unnumbered,                                          \
23234   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23235 _(ip_neighbor_add_del,                                                  \
23236   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23237   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23238 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23239 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23240   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23241   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23242   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23243 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23244 _(reset_fib, "vrf <n> [ipv6]")                                          \
23245 _(dhcp_proxy_config,                                                    \
23246   "svr <v46-address> src <v46-address>\n"                               \
23247    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23248 _(dhcp_proxy_set_vss,                                                   \
23249   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23250 _(dhcp_proxy_dump, "ip6")                                               \
23251 _(dhcp_client_config,                                                   \
23252   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23253 _(set_ip_flow_hash,                                                     \
23254   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23255 _(sw_interface_ip6_enable_disable,                                      \
23256   "<intfc> | sw_if_index <id> enable | disable")                        \
23257 _(ip6nd_proxy_add_del,                                                  \
23258   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23259 _(ip6nd_proxy_dump, "")                                                 \
23260 _(sw_interface_ip6nd_ra_prefix,                                         \
23261   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23262   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23263   "[nolink] [isno]")                                                    \
23264 _(sw_interface_ip6nd_ra_config,                                         \
23265   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23266   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23267   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23268 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23269 _(l2_patch_add_del,                                                     \
23270   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23271   "enable | disable")                                                   \
23272 _(sr_localsid_add_del,                                                  \
23273   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23274   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23275 _(classify_add_del_table,                                               \
23276   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23277   " [del] [del-chain] mask <mask-value>\n"                              \
23278   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23279   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23280 _(classify_add_del_session,                                             \
23281   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23282   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23283   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23284   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23285 _(classify_set_interface_ip_table,                                      \
23286   "<intfc> | sw_if_index <nn> table <nn>")                              \
23287 _(classify_set_interface_l2_tables,                                     \
23288   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23289   "  [other-table <nn>]")                                               \
23290 _(get_node_index, "node <node-name")                                    \
23291 _(add_node_next, "node <node-name> next <next-node-name>")              \
23292 _(l2tpv3_create_tunnel,                                                 \
23293   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23294   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23295   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23296 _(l2tpv3_set_tunnel_cookies,                                            \
23297   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23298   "[new_remote_cookie <nn>]\n")                                         \
23299 _(l2tpv3_interface_enable_disable,                                      \
23300   "<intfc> | sw_if_index <nn> enable | disable")                        \
23301 _(l2tpv3_set_lookup_key,                                                \
23302   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23303 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23304 _(vxlan_offload_rx,                                                     \
23305   "hw { <interface name> | hw_if_index <nn>} "                          \
23306   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23307 _(vxlan_add_del_tunnel,                                                 \
23308   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23309   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23310   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23311 _(geneve_add_del_tunnel,                                                \
23312   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23313   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23314   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23315 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23316 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23317 _(gre_add_del_tunnel,                                                   \
23318   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23319   "[teb | erspan <session-id>] [del]")                                  \
23320 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23321 _(l2_fib_clear_table, "")                                               \
23322 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23323 _(l2_interface_vlan_tag_rewrite,                                        \
23324   "<intfc> | sw_if_index <nn> \n"                                       \
23325   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23326   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23327 _(create_vhost_user_if,                                                 \
23328         "socket <filename> [server] [renumber <dev_instance>] "         \
23329         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23330         "[mac <mac_address>]")                                          \
23331 _(modify_vhost_user_if,                                                 \
23332         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23333         "[server] [renumber <dev_instance>]")                           \
23334 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23335 _(sw_interface_vhost_user_dump, "")                                     \
23336 _(show_version, "")                                                     \
23337 _(show_threads, "")                                                     \
23338 _(vxlan_gpe_add_del_tunnel,                                             \
23339   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23340   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23341   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23342   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23343 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23344 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23345 _(interface_name_renumber,                                              \
23346   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23347 _(input_acl_set_interface,                                              \
23348   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23349   "  [l2-table <nn>] [del]")                                            \
23350 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23351 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23352   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23353 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23354 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23355 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23356 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23357 _(ip_dump, "ipv4 | ipv6")                                               \
23358 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23359 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23360   "  spid_id <n> ")                                                     \
23361 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23362   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23363   "  integ_alg <alg> integ_key <hex>")                                  \
23364 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23365   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23366   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23367   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23368 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23369 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23370   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23371   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23372   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23373   "  [instance <n>]")     \
23374 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23375 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23376   "  <alg> <hex>\n")                                                    \
23377 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23378 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23379 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23380   "(auth_data 0x<data> | auth_data <data>)")                            \
23381 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23382   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23383 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23384   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23385   "(local|remote)")                                                     \
23386 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23387 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23388 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23389 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23390 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23391 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23392 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23393 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23394 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23395 _(delete_loopback,"sw_if_index <nn>")                                   \
23396 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23397 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23398 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23399 _(want_interface_events,  "enable|disable")                             \
23400 _(get_first_msg_id, "client <name>")                                    \
23401 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23402 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23403   "fib-id <nn> [ip4][ip6][default]")                                    \
23404 _(get_node_graph, " ")                                                  \
23405 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23406 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23407 _(ioam_disable, "")                                                     \
23408 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23409                             " sw_if_index <sw_if_index> p <priority> "  \
23410                             "w <weight>] [del]")                        \
23411 _(one_add_del_locator, "locator-set <locator_name> "                    \
23412                         "iface <intf> | sw_if_index <sw_if_index> "     \
23413                         "p <priority> w <weight> [del]")                \
23414 _(one_add_del_local_eid,"vni <vni> eid "                                \
23415                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23416                          "locator-set <locator_name> [del]"             \
23417                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23418 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23419 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23420 _(one_enable_disable, "enable|disable")                                 \
23421 _(one_map_register_enable_disable, "enable|disable")                    \
23422 _(one_map_register_fallback_threshold, "<value>")                       \
23423 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23424 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23425                                "[seid <seid>] "                         \
23426                                "rloc <locator> p <prio> "               \
23427                                "w <weight> [rloc <loc> ... ] "          \
23428                                "action <action> [del-all]")             \
23429 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23430                           "<local-eid>")                                \
23431 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23432 _(one_use_petr, "ip-address> | disable")                                \
23433 _(one_map_request_mode, "src-dst|dst-only")                             \
23434 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23435 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23436 _(one_locator_set_dump, "[local | remote]")                             \
23437 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23438 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23439                        "[local] | [remote]")                            \
23440 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23441 _(one_ndp_bd_get, "")                                                   \
23442 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23443 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23444 _(one_l2_arp_bd_get, "")                                                \
23445 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23446 _(one_stats_enable_disable, "enable|disable")                           \
23447 _(show_one_stats_enable_disable, "")                                    \
23448 _(one_eid_table_vni_dump, "")                                           \
23449 _(one_eid_table_map_dump, "l2|l3")                                      \
23450 _(one_map_resolver_dump, "")                                            \
23451 _(one_map_server_dump, "")                                              \
23452 _(one_adjacencies_get, "vni <vni>")                                     \
23453 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23454 _(show_one_rloc_probe_state, "")                                        \
23455 _(show_one_map_register_state, "")                                      \
23456 _(show_one_status, "")                                                  \
23457 _(one_stats_dump, "")                                                   \
23458 _(one_stats_flush, "")                                                  \
23459 _(one_get_map_request_itr_rlocs, "")                                    \
23460 _(one_map_register_set_ttl, "<ttl>")                                    \
23461 _(one_set_transport_protocol, "udp|api")                                \
23462 _(one_get_transport_protocol, "")                                       \
23463 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23464 _(one_show_xtr_mode, "")                                                \
23465 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23466 _(one_show_pitr_mode, "")                                               \
23467 _(one_enable_disable_petr_mode, "enable|disable")                       \
23468 _(one_show_petr_mode, "")                                               \
23469 _(show_one_nsh_mapping, "")                                             \
23470 _(show_one_pitr, "")                                                    \
23471 _(show_one_use_petr, "")                                                \
23472 _(show_one_map_request_mode, "")                                        \
23473 _(show_one_map_register_ttl, "")                                        \
23474 _(show_one_map_register_fallback_threshold, "")                         \
23475 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23476                             " sw_if_index <sw_if_index> p <priority> "  \
23477                             "w <weight>] [del]")                        \
23478 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23479                         "iface <intf> | sw_if_index <sw_if_index> "     \
23480                         "p <priority> w <weight> [del]")                \
23481 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23482                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23483                          "locator-set <locator_name> [del]"             \
23484                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23485 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23486 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23487 _(lisp_enable_disable, "enable|disable")                                \
23488 _(lisp_map_register_enable_disable, "enable|disable")                   \
23489 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23490 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23491                                "[seid <seid>] "                         \
23492                                "rloc <locator> p <prio> "               \
23493                                "w <weight> [rloc <loc> ... ] "          \
23494                                "action <action> [del-all]")             \
23495 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23496                           "<local-eid>")                                \
23497 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23498 _(lisp_use_petr, "<ip-address> | disable")                              \
23499 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23500 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23501 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23502 _(lisp_locator_set_dump, "[local | remote]")                            \
23503 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23504 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23505                        "[local] | [remote]")                            \
23506 _(lisp_eid_table_vni_dump, "")                                          \
23507 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23508 _(lisp_map_resolver_dump, "")                                           \
23509 _(lisp_map_server_dump, "")                                             \
23510 _(lisp_adjacencies_get, "vni <vni>")                                    \
23511 _(gpe_fwd_entry_vnis_get, "")                                           \
23512 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23513 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23514                                 "[table <table-id>]")                   \
23515 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23516 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23517 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23518 _(gpe_get_encap_mode, "")                                               \
23519 _(lisp_gpe_add_del_iface, "up|down")                                    \
23520 _(lisp_gpe_enable_disable, "enable|disable")                            \
23521 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23522   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23523 _(show_lisp_rloc_probe_state, "")                                       \
23524 _(show_lisp_map_register_state, "")                                     \
23525 _(show_lisp_status, "")                                                 \
23526 _(lisp_get_map_request_itr_rlocs, "")                                   \
23527 _(show_lisp_pitr, "")                                                   \
23528 _(show_lisp_use_petr, "")                                               \
23529 _(show_lisp_map_request_mode, "")                                       \
23530 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23531 _(af_packet_delete, "name <host interface name>")                       \
23532 _(af_packet_dump, "")                                                   \
23533 _(policer_add_del, "name <policer name> <params> [del]")                \
23534 _(policer_dump, "[name <policer name>]")                                \
23535 _(policer_classify_set_interface,                                       \
23536   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23537   "  [l2-table <nn>] [del]")                                            \
23538 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23539 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23540     "[master|slave]")                                                   \
23541 _(netmap_delete, "name <interface name>")                               \
23542 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23543 _(mpls_fib_dump, "")                                                    \
23544 _(classify_table_ids, "")                                               \
23545 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23546 _(classify_table_info, "table_id <nn>")                                 \
23547 _(classify_session_dump, "table_id <nn>")                               \
23548 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23549     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23550     "[template_interval <nn>] [udp_checksum]")                          \
23551 _(ipfix_exporter_dump, "")                                              \
23552 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23553 _(ipfix_classify_stream_dump, "")                                       \
23554 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23555 _(ipfix_classify_table_dump, "")                                        \
23556 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23557 _(sw_interface_span_dump, "[l2]")                                           \
23558 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23559 _(pg_create_interface, "if_id <nn>")                                    \
23560 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23561 _(pg_enable_disable, "[stream <id>] disable")                           \
23562 _(ip_source_and_port_range_check_add_del,                               \
23563   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23564 _(ip_source_and_port_range_check_interface_add_del,                     \
23565   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23566   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23567 _(ipsec_gre_add_del_tunnel,                                             \
23568   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23569 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23570 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23571 _(l2_interface_pbb_tag_rewrite,                                         \
23572   "<intfc> | sw_if_index <nn> \n"                                       \
23573   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23574   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23575 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23576 _(flow_classify_set_interface,                                          \
23577   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23578 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23579 _(ip_fib_dump, "")                                                      \
23580 _(ip_mfib_dump, "")                                                     \
23581 _(ip6_fib_dump, "")                                                     \
23582 _(ip6_mfib_dump, "")                                                    \
23583 _(feature_enable_disable, "arc_name <arc_name> "                        \
23584   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23585 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23586 "[disable]")                                                            \
23587 _(l2_xconnect_dump, "")                                                 \
23588 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23589 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23590 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23591 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23592 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23593 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23594 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23595   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23596 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23597 _(sock_init_shm, "size <nnn>")                                          \
23598 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23599 _(dns_enable_disable, "[enable][disable]")                              \
23600 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23601 _(dns_resolve_name, "<hostname>")                                       \
23602 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23603 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23604 _(dns_resolve_name, "<hostname>")                                       \
23605 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23606   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23607 _(session_rules_dump, "")                                               \
23608 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23609 _(output_acl_set_interface,                                             \
23610   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23611   "  [l2-table <nn>] [del]")                                            \
23612 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23613
23614 /* List of command functions, CLI names map directly to functions */
23615 #define foreach_cli_function                                    \
23616 _(comment, "usage: comment <ignore-rest-of-line>")              \
23617 _(dump_interface_table, "usage: dump_interface_table")          \
23618 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23619 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23620 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23621 _(dump_macro_table, "usage: dump_macro_table ")                 \
23622 _(dump_node_table, "usage: dump_node_table")                    \
23623 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23624 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23625 _(echo, "usage: echo <message>")                                \
23626 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23627 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23628 _(help, "usage: help")                                          \
23629 _(q, "usage: quit")                                             \
23630 _(quit, "usage: quit")                                          \
23631 _(search_node_table, "usage: search_node_table <name>...")      \
23632 _(set, "usage: set <variable-name> <value>")                    \
23633 _(script, "usage: script <file-name>")                          \
23634 _(statseg, "usage: statseg");                                   \
23635 _(unset, "usage: unset <variable-name>")
23636
23637 #define _(N,n)                                  \
23638     static void vl_api_##n##_t_handler_uni      \
23639     (vl_api_##n##_t * mp)                       \
23640     {                                           \
23641         vat_main_t * vam = &vat_main;           \
23642         if (vam->json_output) {                 \
23643             vl_api_##n##_t_handler_json(mp);    \
23644         } else {                                \
23645             vl_api_##n##_t_handler(mp);         \
23646         }                                       \
23647     }
23648 foreach_vpe_api_reply_msg;
23649 #if VPP_API_TEST_BUILTIN == 0
23650 foreach_standalone_reply_msg;
23651 #endif
23652 #undef _
23653
23654 void
23655 vat_api_hookup (vat_main_t * vam)
23656 {
23657 #define _(N,n)                                                  \
23658     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23659                            vl_api_##n##_t_handler_uni,          \
23660                            vl_noop_handler,                     \
23661                            vl_api_##n##_t_endian,               \
23662                            vl_api_##n##_t_print,                \
23663                            sizeof(vl_api_##n##_t), 1);
23664   foreach_vpe_api_reply_msg;
23665 #if VPP_API_TEST_BUILTIN == 0
23666   foreach_standalone_reply_msg;
23667 #endif
23668 #undef _
23669
23670 #if (VPP_API_TEST_BUILTIN==0)
23671   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23672
23673   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23674
23675   vam->function_by_name = hash_create_string (0, sizeof (uword));
23676
23677   vam->help_by_name = hash_create_string (0, sizeof (uword));
23678 #endif
23679
23680   /* API messages we can send */
23681 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23682   foreach_vpe_api_msg;
23683 #undef _
23684
23685   /* Help strings */
23686 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23687   foreach_vpe_api_msg;
23688 #undef _
23689
23690   /* CLI functions */
23691 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23692   foreach_cli_function;
23693 #undef _
23694
23695   /* Help strings */
23696 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23697   foreach_cli_function;
23698 #undef _
23699 }
23700
23701 #if VPP_API_TEST_BUILTIN
23702 static clib_error_t *
23703 vat_api_hookup_shim (vlib_main_t * vm)
23704 {
23705   vat_api_hookup (&vat_main);
23706   return 0;
23707 }
23708
23709 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23710 #endif
23711
23712 /*
23713  * fd.io coding-style-patch-verification: ON
23714  *
23715  * Local Variables:
23716  * eval: (c-set-style "gnu")
23717  * End:
23718  */