bapi/vat: fix socket transport for vat
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 u32
86 vl (void *p)
87 {
88   return vec_len (p);
89 }
90
91 int
92 vat_socket_connect (vat_main_t * vam)
93 {
94   int rv;
95   vam->socket_client_main = &socket_client_main;
96   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
97                                       "vpp_api_test",
98                                       0 /* default socket rx, tx buffer */ )))
99     return rv;
100   /* vpp expects the client index in network order */
101   vam->my_client_index = htonl (socket_client_main.client_index);
102   return 0;
103 }
104 #else /* vpp built-in case, we don't do sockets... */
105 int
106 vat_socket_connect (vat_main_t * vam)
107 {
108   return 0;
109 }
110
111 int
112 vl_socket_client_read (int wait)
113 {
114   return -1;
115 };
116
117 int
118 vl_socket_client_write ()
119 {
120   return -1;
121 };
122
123 void *
124 vl_socket_client_msg_alloc (int nbytes)
125 {
126   return 0;
127 }
128 #endif
129
130
131 f64
132 vat_time_now (vat_main_t * vam)
133 {
134 #if VPP_API_TEST_BUILTIN
135   return vlib_time_now (vam->vlib_main);
136 #else
137   return clib_time_now (&vam->clib_time);
138 #endif
139 }
140
141 void
142 errmsg (char *fmt, ...)
143 {
144   vat_main_t *vam = &vat_main;
145   va_list va;
146   u8 *s;
147
148   va_start (va, fmt);
149   s = va_format (0, fmt, &va);
150   va_end (va);
151
152   vec_add1 (s, 0);
153
154 #if VPP_API_TEST_BUILTIN
155   vlib_cli_output (vam->vlib_main, (char *) s);
156 #else
157   {
158     if (vam->ifp != stdin)
159       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
160                vam->input_line_number);
161     fformat (vam->ofp, (char *) s);
162     fflush (vam->ofp);
163   }
164 #endif
165
166   vec_free (s);
167 }
168
169 #if VPP_API_TEST_BUILTIN == 0
170 static uword
171 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
172 {
173   vat_main_t *vam = va_arg (*args, vat_main_t *);
174   u32 *result = va_arg (*args, u32 *);
175   u8 *if_name;
176   uword *p;
177
178   if (!unformat (input, "%s", &if_name))
179     return 0;
180
181   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
182   if (p == 0)
183     return 0;
184   *result = p[0];
185   return 1;
186 }
187
188 static uword
189 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
190 {
191   return 0;
192 }
193
194 /* Parse an IP4 address %d.%d.%d.%d. */
195 uword
196 unformat_ip4_address (unformat_input_t * input, va_list * args)
197 {
198   u8 *result = va_arg (*args, u8 *);
199   unsigned a[4];
200
201   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
202     return 0;
203
204   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
205     return 0;
206
207   result[0] = a[0];
208   result[1] = a[1];
209   result[2] = a[2];
210   result[3] = a[3];
211
212   return 1;
213 }
214
215 uword
216 unformat_ethernet_address (unformat_input_t * input, va_list * args)
217 {
218   u8 *result = va_arg (*args, u8 *);
219   u32 i, a[6];
220
221   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
222                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
223     return 0;
224
225   /* Check range. */
226   for (i = 0; i < 6; i++)
227     if (a[i] >= (1 << 8))
228       return 0;
229
230   for (i = 0; i < 6; i++)
231     result[i] = a[i];
232
233   return 1;
234 }
235
236 /* Returns ethernet type as an int in host byte order. */
237 uword
238 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
239                                         va_list * args)
240 {
241   u16 *result = va_arg (*args, u16 *);
242   int type;
243
244   /* Numeric type. */
245   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
246     {
247       if (type >= (1 << 16))
248         return 0;
249       *result = type;
250       return 1;
251     }
252   return 0;
253 }
254
255 /* Parse an IP6 address. */
256 uword
257 unformat_ip6_address (unformat_input_t * input, va_list * args)
258 {
259   ip6_address_t *result = va_arg (*args, ip6_address_t *);
260   u16 hex_quads[8];
261   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
262   uword c, n_colon, double_colon_index;
263
264   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
265   double_colon_index = ARRAY_LEN (hex_quads);
266   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
267     {
268       hex_digit = 16;
269       if (c >= '0' && c <= '9')
270         hex_digit = c - '0';
271       else if (c >= 'a' && c <= 'f')
272         hex_digit = c + 10 - 'a';
273       else if (c >= 'A' && c <= 'F')
274         hex_digit = c + 10 - 'A';
275       else if (c == ':' && n_colon < 2)
276         n_colon++;
277       else
278         {
279           unformat_put_input (input);
280           break;
281         }
282
283       /* Too many hex quads. */
284       if (n_hex_quads >= ARRAY_LEN (hex_quads))
285         return 0;
286
287       if (hex_digit < 16)
288         {
289           hex_quad = (hex_quad << 4) | hex_digit;
290
291           /* Hex quad must fit in 16 bits. */
292           if (n_hex_digits >= 4)
293             return 0;
294
295           n_colon = 0;
296           n_hex_digits++;
297         }
298
299       /* Save position of :: */
300       if (n_colon == 2)
301         {
302           /* More than one :: ? */
303           if (double_colon_index < ARRAY_LEN (hex_quads))
304             return 0;
305           double_colon_index = n_hex_quads;
306         }
307
308       if (n_colon > 0 && n_hex_digits > 0)
309         {
310           hex_quads[n_hex_quads++] = hex_quad;
311           hex_quad = 0;
312           n_hex_digits = 0;
313         }
314     }
315
316   if (n_hex_digits > 0)
317     hex_quads[n_hex_quads++] = hex_quad;
318
319   {
320     word i;
321
322     /* Expand :: to appropriate number of zero hex quads. */
323     if (double_colon_index < ARRAY_LEN (hex_quads))
324       {
325         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
326
327         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
328           hex_quads[n_zero + i] = hex_quads[i];
329
330         for (i = 0; i < n_zero; i++)
331           hex_quads[double_colon_index + i] = 0;
332
333         n_hex_quads = ARRAY_LEN (hex_quads);
334       }
335
336     /* Too few hex quads given. */
337     if (n_hex_quads < ARRAY_LEN (hex_quads))
338       return 0;
339
340     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
341       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
342
343     return 1;
344   }
345 }
346
347 uword
348 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
354   foreach_ipsec_policy_action
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 uword
362 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
363 {
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
368   foreach_ipsec_crypto_alg
369 #undef _
370     else
371     return 0;
372   return 1;
373 }
374
375 u8 *
376 format_ipsec_crypto_alg (u8 * s, va_list * args)
377 {
378   u32 i = va_arg (*args, u32);
379   u8 *t = 0;
380
381   switch (i)
382     {
383 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
384       foreach_ipsec_crypto_alg
385 #undef _
386     default:
387       return format (s, "unknown");
388     }
389   return format (s, "%s", t);
390 }
391
392 uword
393 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
394 {
395   u32 *r = va_arg (*args, u32 *);
396
397   if (0);
398 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
399   foreach_ipsec_integ_alg
400 #undef _
401     else
402     return 0;
403   return 1;
404 }
405
406 u8 *
407 format_ipsec_integ_alg (u8 * s, va_list * args)
408 {
409   u32 i = va_arg (*args, u32);
410   u8 *t = 0;
411
412   switch (i)
413     {
414 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
415       foreach_ipsec_integ_alg
416 #undef _
417     default:
418       return format (s, "unknown");
419     }
420   return format (s, "%s", t);
421 }
422
423 uword
424 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
430   foreach_ikev2_auth_method
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436
437 uword
438 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
439 {
440   u32 *r = va_arg (*args, u32 *);
441
442   if (0);
443 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
444   foreach_ikev2_id_type
445 #undef _
446     else
447     return 0;
448   return 1;
449 }
450 #else /* VPP_API_TEST_BUILTIN == 1 */
451 static uword
452 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
453 {
454   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
455   vnet_main_t *vnm = vnet_get_main ();
456   u32 *result = va_arg (*args, u32 *);
457
458   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
459 }
460
461 static uword
462 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
463 {
464   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
465   vnet_main_t *vnm = vnet_get_main ();
466   u32 *result = va_arg (*args, u32 *);
467
468   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
469 }
470
471 #endif /* VPP_API_TEST_BUILTIN */
472
473 static uword
474 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
475 {
476   u8 *r = va_arg (*args, u8 *);
477
478   if (unformat (input, "kbps"))
479     *r = SSE2_QOS_RATE_KBPS;
480   else if (unformat (input, "pps"))
481     *r = SSE2_QOS_RATE_PPS;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_round_type (unformat_input_t * input, va_list * args)
489 {
490   u8 *r = va_arg (*args, u8 *);
491
492   if (unformat (input, "closest"))
493     *r = SSE2_QOS_ROUND_TO_CLOSEST;
494   else if (unformat (input, "up"))
495     *r = SSE2_QOS_ROUND_TO_UP;
496   else if (unformat (input, "down"))
497     *r = SSE2_QOS_ROUND_TO_DOWN;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_type (unformat_input_t * input, va_list * args)
505 {
506   u8 *r = va_arg (*args, u8 *);
507
508   if (unformat (input, "1r2c"))
509     *r = SSE2_QOS_POLICER_TYPE_1R2C;
510   else if (unformat (input, "1r3c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
512   else if (unformat (input, "2r3c-2698"))
513     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
514   else if (unformat (input, "2r3c-4115"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
516   else if (unformat (input, "2r3c-mef5cf1"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
518   else
519     return 0;
520   return 1;
521 }
522
523 static uword
524 unformat_dscp (unformat_input_t * input, va_list * va)
525 {
526   u8 *r = va_arg (*va, u8 *);
527
528   if (0);
529 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
530   foreach_vnet_dscp
531 #undef _
532     else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_action_type (unformat_input_t * input, va_list * va)
539 {
540   sse2_qos_pol_action_params_st *a
541     = va_arg (*va, sse2_qos_pol_action_params_st *);
542
543   if (unformat (input, "drop"))
544     a->action_type = SSE2_QOS_ACTION_DROP;
545   else if (unformat (input, "transmit"))
546     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
547   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
548     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
549   else
550     return 0;
551   return 1;
552 }
553
554 static uword
555 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
556 {
557   u32 *r = va_arg (*va, u32 *);
558   u32 tid;
559
560   if (unformat (input, "ip4"))
561     tid = POLICER_CLASSIFY_TABLE_IP4;
562   else if (unformat (input, "ip6"))
563     tid = POLICER_CLASSIFY_TABLE_IP6;
564   else if (unformat (input, "l2"))
565     tid = POLICER_CLASSIFY_TABLE_L2;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 static uword
574 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
575 {
576   u32 *r = va_arg (*va, u32 *);
577   u32 tid;
578
579   if (unformat (input, "ip4"))
580     tid = FLOW_CLASSIFY_TABLE_IP4;
581   else if (unformat (input, "ip6"))
582     tid = FLOW_CLASSIFY_TABLE_IP6;
583   else
584     return 0;
585
586   *r = tid;
587   return 1;
588 }
589
590 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
591 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
592 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
593 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
594
595 #if (VPP_API_TEST_BUILTIN==0)
596 uword
597 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
598 {
599   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
600   mfib_itf_attribute_t attr;
601
602   old = *iflags;
603   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
604   {
605     if (unformat (input, mfib_itf_flag_long_names[attr]))
606       *iflags |= (1 << attr);
607   }
608   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_itf_flag_names[attr]))
611       *iflags |= (1 << attr);
612   }
613
614   return (old == *iflags ? 0 : 1);
615 }
616
617 uword
618 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
619 {
620   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
621   mfib_entry_attribute_t attr;
622
623   old = *eflags;
624   FOR_EACH_MFIB_ATTRIBUTE (attr)
625   {
626     if (unformat (input, mfib_flag_long_names[attr]))
627       *eflags |= (1 << attr);
628   }
629   FOR_EACH_MFIB_ATTRIBUTE (attr)
630   {
631     if (unformat (input, mfib_flag_names[attr]))
632       *eflags |= (1 << attr);
633   }
634
635   return (old == *eflags ? 0 : 1);
636 }
637
638 u8 *
639 format_ip4_address (u8 * s, va_list * args)
640 {
641   u8 *a = va_arg (*args, u8 *);
642   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
643 }
644
645 u8 *
646 format_ip6_address (u8 * s, va_list * args)
647 {
648   ip6_address_t *a = va_arg (*args, ip6_address_t *);
649   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
650
651   i_max_n_zero = ARRAY_LEN (a->as_u16);
652   max_n_zeros = 0;
653   i_first_zero = i_max_n_zero;
654   n_zeros = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       u32 is_zero = a->as_u16[i] == 0;
658       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
659         {
660           i_first_zero = i;
661           n_zeros = 0;
662         }
663       n_zeros += is_zero;
664       if ((!is_zero && n_zeros > max_n_zeros)
665           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
666         {
667           i_max_n_zero = i_first_zero;
668           max_n_zeros = n_zeros;
669           i_first_zero = ARRAY_LEN (a->as_u16);
670           n_zeros = 0;
671         }
672     }
673
674   last_double_colon = 0;
675   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
676     {
677       if (i == i_max_n_zero && max_n_zeros > 1)
678         {
679           s = format (s, "::");
680           i += max_n_zeros - 1;
681           last_double_colon = 1;
682         }
683       else
684         {
685           s = format (s, "%s%x",
686                       (last_double_colon || i == 0) ? "" : ":",
687                       clib_net_to_host_u16 (a->as_u16[i]));
688           last_double_colon = 0;
689         }
690     }
691
692   return s;
693 }
694
695 /* Format an IP46 address. */
696 u8 *
697 format_ip46_address (u8 * s, va_list * args)
698 {
699   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
700   ip46_type_t type = va_arg (*args, ip46_type_t);
701   int is_ip4 = 1;
702
703   switch (type)
704     {
705     case IP46_TYPE_ANY:
706       is_ip4 = ip46_address_is_ip4 (ip46);
707       break;
708     case IP46_TYPE_IP4:
709       is_ip4 = 1;
710       break;
711     case IP46_TYPE_IP6:
712       is_ip4 = 0;
713       break;
714     }
715
716   return is_ip4 ?
717     format (s, "%U", format_ip4_address, &ip46->ip4) :
718     format (s, "%U", format_ip6_address, &ip46->ip6);
719 }
720
721 u8 *
722 format_ethernet_address (u8 * s, va_list * args)
723 {
724   u8 *a = va_arg (*args, u8 *);
725
726   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
727                  a[0], a[1], a[2], a[3], a[4], a[5]);
728 }
729 #endif
730
731 static void
732 increment_v4_address (ip4_address_t * a)
733 {
734   u32 v;
735
736   v = ntohl (a->as_u32) + 1;
737   a->as_u32 = ntohl (v);
738 }
739
740 static void
741 increment_v6_address (ip6_address_t * a)
742 {
743   u64 v0, v1;
744
745   v0 = clib_net_to_host_u64 (a->as_u64[0]);
746   v1 = clib_net_to_host_u64 (a->as_u64[1]);
747
748   v1 += 1;
749   if (v1 == 0)
750     v0 += 1;
751   a->as_u64[0] = clib_net_to_host_u64 (v0);
752   a->as_u64[1] = clib_net_to_host_u64 (v1);
753 }
754
755 static void
756 increment_mac_address (u8 * mac)
757 {
758   u64 tmp = *((u64 *) mac);
759   tmp = clib_net_to_host_u64 (tmp);
760   tmp += 1 << 16;               /* skip unused (least significant) octets */
761   tmp = clib_host_to_net_u64 (tmp);
762
763   clib_memcpy (mac, &tmp, 6);
764 }
765
766 static void vl_api_create_loopback_reply_t_handler
767   (vl_api_create_loopback_reply_t * mp)
768 {
769   vat_main_t *vam = &vat_main;
770   i32 retval = ntohl (mp->retval);
771
772   vam->retval = retval;
773   vam->regenerate_interface_table = 1;
774   vam->sw_if_index = ntohl (mp->sw_if_index);
775   vam->result_ready = 1;
776 }
777
778 static void vl_api_create_loopback_reply_t_handler_json
779   (vl_api_create_loopback_reply_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t node;
783
784   vat_json_init_object (&node);
785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
787
788   vat_json_print (vam->ofp, &node);
789   vat_json_free (&node);
790   vam->retval = ntohl (mp->retval);
791   vam->result_ready = 1;
792 }
793
794 static void vl_api_create_loopback_instance_reply_t_handler
795   (vl_api_create_loopback_instance_reply_t * mp)
796 {
797   vat_main_t *vam = &vat_main;
798   i32 retval = ntohl (mp->retval);
799
800   vam->retval = retval;
801   vam->regenerate_interface_table = 1;
802   vam->sw_if_index = ntohl (mp->sw_if_index);
803   vam->result_ready = 1;
804 }
805
806 static void vl_api_create_loopback_instance_reply_t_handler_json
807   (vl_api_create_loopback_instance_reply_t * mp)
808 {
809   vat_main_t *vam = &vat_main;
810   vat_json_node_t node;
811
812   vat_json_init_object (&node);
813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
814   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
815
816   vat_json_print (vam->ofp, &node);
817   vat_json_free (&node);
818   vam->retval = ntohl (mp->retval);
819   vam->result_ready = 1;
820 }
821
822 static void vl_api_af_packet_create_reply_t_handler
823   (vl_api_af_packet_create_reply_t * mp)
824 {
825   vat_main_t *vam = &vat_main;
826   i32 retval = ntohl (mp->retval);
827
828   vam->retval = retval;
829   vam->regenerate_interface_table = 1;
830   vam->sw_if_index = ntohl (mp->sw_if_index);
831   vam->result_ready = 1;
832 }
833
834 static void vl_api_af_packet_create_reply_t_handler_json
835   (vl_api_af_packet_create_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   vat_json_node_t node;
839
840   vat_json_init_object (&node);
841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
842   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
843
844   vat_json_print (vam->ofp, &node);
845   vat_json_free (&node);
846
847   vam->retval = ntohl (mp->retval);
848   vam->result_ready = 1;
849 }
850
851 static void vl_api_create_vlan_subif_reply_t_handler
852   (vl_api_create_vlan_subif_reply_t * mp)
853 {
854   vat_main_t *vam = &vat_main;
855   i32 retval = ntohl (mp->retval);
856
857   vam->retval = retval;
858   vam->regenerate_interface_table = 1;
859   vam->sw_if_index = ntohl (mp->sw_if_index);
860   vam->result_ready = 1;
861 }
862
863 static void vl_api_create_vlan_subif_reply_t_handler_json
864   (vl_api_create_vlan_subif_reply_t * mp)
865 {
866   vat_main_t *vam = &vat_main;
867   vat_json_node_t node;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
872
873   vat_json_print (vam->ofp, &node);
874   vat_json_free (&node);
875
876   vam->retval = ntohl (mp->retval);
877   vam->result_ready = 1;
878 }
879
880 static void vl_api_create_subif_reply_t_handler
881   (vl_api_create_subif_reply_t * mp)
882 {
883   vat_main_t *vam = &vat_main;
884   i32 retval = ntohl (mp->retval);
885
886   vam->retval = retval;
887   vam->regenerate_interface_table = 1;
888   vam->sw_if_index = ntohl (mp->sw_if_index);
889   vam->result_ready = 1;
890 }
891
892 static void vl_api_create_subif_reply_t_handler_json
893   (vl_api_create_subif_reply_t * mp)
894 {
895   vat_main_t *vam = &vat_main;
896   vat_json_node_t node;
897
898   vat_json_init_object (&node);
899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 static void vl_api_interface_name_renumber_reply_t_handler
910   (vl_api_interface_name_renumber_reply_t * mp)
911 {
912   vat_main_t *vam = &vat_main;
913   i32 retval = ntohl (mp->retval);
914
915   vam->retval = retval;
916   vam->regenerate_interface_table = 1;
917   vam->result_ready = 1;
918 }
919
920 static void vl_api_interface_name_renumber_reply_t_handler_json
921   (vl_api_interface_name_renumber_reply_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   vat_json_node_t node;
925
926   vat_json_init_object (&node);
927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
928
929   vat_json_print (vam->ofp, &node);
930   vat_json_free (&node);
931
932   vam->retval = ntohl (mp->retval);
933   vam->result_ready = 1;
934 }
935
936 /*
937  * Special-case: build the interface table, maintain
938  * the next loopback sw_if_index vbl.
939  */
940 static void vl_api_sw_interface_details_t_handler
941   (vl_api_sw_interface_details_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   u8 *s = format (0, "%s%c", mp->interface_name, 0);
945
946   hash_set_mem (vam->sw_if_index_by_interface_name, s,
947                 ntohl (mp->sw_if_index));
948
949   /* In sub interface case, fill the sub interface table entry */
950   if (mp->sw_if_index != mp->sup_sw_if_index)
951     {
952       sw_interface_subif_t *sub = NULL;
953
954       vec_add2 (vam->sw_if_subif_table, sub, 1);
955
956       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
957       strncpy ((char *) sub->interface_name, (char *) s,
958                vec_len (sub->interface_name));
959       sub->sw_if_index = ntohl (mp->sw_if_index);
960       sub->sub_id = ntohl (mp->sub_id);
961
962       sub->sub_dot1ad = mp->sub_dot1ad;
963       sub->sub_number_of_tags = mp->sub_number_of_tags;
964       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
965       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
966       sub->sub_exact_match = mp->sub_exact_match;
967       sub->sub_default = mp->sub_default;
968       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
969       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
970
971       /* vlan tag rewrite */
972       sub->vtr_op = ntohl (mp->vtr_op);
973       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
974       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
975       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
976     }
977 }
978
979 static void vl_api_sw_interface_details_t_handler_json
980   (vl_api_sw_interface_details_t * mp)
981 {
982   vat_main_t *vam = &vat_main;
983   vat_json_node_t *node = NULL;
984
985   if (VAT_JSON_ARRAY != vam->json_tree.type)
986     {
987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
988       vat_json_init_array (&vam->json_tree);
989     }
990   node = vat_json_array_add (&vam->json_tree);
991
992   vat_json_init_object (node);
993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
994   vat_json_object_add_uint (node, "sup_sw_if_index",
995                             ntohl (mp->sup_sw_if_index));
996   vat_json_object_add_uint (node, "l2_address_length",
997                             ntohl (mp->l2_address_length));
998   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
999                              sizeof (mp->l2_address));
1000   vat_json_object_add_string_copy (node, "interface_name",
1001                                    mp->interface_name);
1002   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1003   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1004   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1005   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1006   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1007   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1008   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1009   vat_json_object_add_uint (node, "sub_number_of_tags",
1010                             mp->sub_number_of_tags);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1012                             ntohs (mp->sub_outer_vlan_id));
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1014                             ntohs (mp->sub_inner_vlan_id));
1015   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1016   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1017   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1018                             mp->sub_outer_vlan_id_any);
1019   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1020                             mp->sub_inner_vlan_id_any);
1021   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1022   vat_json_object_add_uint (node, "vtr_push_dot1q",
1023                             ntohl (mp->vtr_push_dot1q));
1024   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1025   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1026   if (mp->sub_dot1ah)
1027     {
1028       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1029                                        format (0, "%U",
1030                                                format_ethernet_address,
1031                                                &mp->b_dmac));
1032       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1033                                        format (0, "%U",
1034                                                format_ethernet_address,
1035                                                &mp->b_smac));
1036       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1037       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1038     }
1039 }
1040
1041 #if VPP_API_TEST_BUILTIN == 0
1042 static void vl_api_sw_interface_event_t_handler
1043   (vl_api_sw_interface_event_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   if (vam->interface_event_display)
1047     errmsg ("interface flags: sw_if_index %d %s %s",
1048             ntohl (mp->sw_if_index),
1049             mp->admin_up_down ? "admin-up" : "admin-down",
1050             mp->link_up_down ? "link-up" : "link-down");
1051 }
1052 #endif
1053
1054 static void vl_api_sw_interface_event_t_handler_json
1055   (vl_api_sw_interface_event_t * mp)
1056 {
1057   /* JSON output not supported */
1058 }
1059
1060 static void
1061 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   i32 retval = ntohl (mp->retval);
1065
1066   vam->retval = retval;
1067   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vam->result_ready = 1;
1069 }
1070
1071 static void
1072 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1073 {
1074   vat_main_t *vam = &vat_main;
1075   vat_json_node_t node;
1076   api_main_t *am = &api_main;
1077   void *oldheap;
1078   u8 *reply;
1079
1080   vat_json_init_object (&node);
1081   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1082   vat_json_object_add_uint (&node, "reply_in_shmem",
1083                             ntohl (mp->reply_in_shmem));
1084   /* Toss the shared-memory original... */
1085   pthread_mutex_lock (&am->vlib_rp->mutex);
1086   oldheap = svm_push_data_heap (am->vlib_rp);
1087
1088   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1089   vec_free (reply);
1090
1091   svm_pop_heap (oldheap);
1092   pthread_mutex_unlock (&am->vlib_rp->mutex);
1093
1094   vat_json_print (vam->ofp, &node);
1095   vat_json_free (&node);
1096
1097   vam->retval = ntohl (mp->retval);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   i32 retval = ntohl (mp->retval);
1106   u32 length = vl_api_string_len (&mp->reply);
1107
1108   vec_reset_length (vam->cmd_reply);
1109
1110   vam->retval = retval;
1111   if (retval == 0)
1112     {
1113       vec_validate (vam->cmd_reply, length);
1114       clib_memcpy ((char *) (vam->cmd_reply),
1115                    vl_api_from_api_string (&mp->reply), length);
1116       vam->cmd_reply[length] = 0;
1117     }
1118   vam->result_ready = 1;
1119 }
1120
1121 static void
1122 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   vat_json_node_t node;
1126
1127   vec_reset_length (vam->cmd_reply);
1128
1129   vat_json_init_object (&node);
1130   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1131   vat_json_object_add_string_copy (&node, "reply",
1132                                    vl_api_from_api_string (&mp->reply));
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       char *s;
1304       char *p = (char *) &mp->program;
1305
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        program: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("        version: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("     build date: %s\n", s);
1320       free (s);
1321
1322       p +=
1323         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1324       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1325       errmsg ("build directory: %s\n", s);
1326       free (s);
1327     }
1328   vam->retval = retval;
1329   vam->result_ready = 1;
1330 }
1331
1332 static void vl_api_show_version_reply_t_handler_json
1333   (vl_api_show_version_reply_t * mp)
1334 {
1335   vat_main_t *vam = &vat_main;
1336   vat_json_node_t node;
1337
1338   vat_json_init_object (&node);
1339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1340   char *p = (char *) &mp->program;
1341   vat_json_object_add_string_copy (&node, "program",
1342                                    vl_api_from_api_string ((vl_api_string_t *)
1343                                                            p));
1344   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1345   vat_json_object_add_string_copy (&node, "version",
1346                                    vl_api_from_api_string ((vl_api_string_t *)
1347                                                            p));
1348   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1349   vat_json_object_add_string_copy (&node, "build_date",
1350                                    vl_api_from_api_string ((vl_api_string_t *)
1351                                                            p));
1352   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1353   vat_json_object_add_string_copy (&node, "build_directory",
1354                                    vl_api_from_api_string ((vl_api_string_t *)
1355                                                            p));
1356
1357   vat_json_print (vam->ofp, &node);
1358   vat_json_free (&node);
1359
1360   vam->retval = ntohl (mp->retval);
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_threads_reply_t_handler
1365   (vl_api_show_threads_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   i32 retval = ntohl (mp->retval);
1369   int i, count = 0;
1370
1371   if (retval >= 0)
1372     count = ntohl (mp->count);
1373
1374   for (i = 0; i < count; i++)
1375     print (vam->ofp,
1376            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1377            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1378            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1379            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1380            ntohl (mp->thread_data[i].cpu_socket));
1381
1382   vam->retval = retval;
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler_json
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391   vl_api_thread_data_t *td;
1392   i32 retval = ntohl (mp->retval);
1393   int i, count = 0;
1394
1395   if (retval >= 0)
1396     count = ntohl (mp->count);
1397
1398   vat_json_init_object (&node);
1399   vat_json_object_add_int (&node, "retval", retval);
1400   vat_json_object_add_uint (&node, "count", count);
1401
1402   for (i = 0; i < count; i++)
1403     {
1404       td = &mp->thread_data[i];
1405       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1406       vat_json_object_add_string_copy (&node, "name", td->name);
1407       vat_json_object_add_string_copy (&node, "type", td->type);
1408       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1409       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1410       vat_json_object_add_int (&node, "core", ntohl (td->id));
1411       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1412     }
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static int
1422 api_show_threads (vat_main_t * vam)
1423 {
1424   vl_api_show_threads_t *mp;
1425   int ret;
1426
1427   print (vam->ofp,
1428          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1429          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1430
1431   M (SHOW_THREADS, mp);
1432
1433   S (mp);
1434   W (ret);
1435   return ret;
1436 }
1437
1438 static void
1439 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1440 {
1441   u32 sw_if_index = ntohl (mp->sw_if_index);
1442   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1443           mp->mac_ip ? "mac/ip binding" : "address resolution",
1444           ntohl (mp->pid), format_ip4_address, &mp->address,
1445           format_ethernet_address, mp->new_mac, sw_if_index);
1446 }
1447
1448 static void
1449 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1450 {
1451   /* JSON output not supported */
1452 }
1453
1454 static void
1455 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1456 {
1457   u32 sw_if_index = ntohl (mp->sw_if_index);
1458   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1459           mp->mac_ip ? "mac/ip binding" : "address resolution",
1460           ntohl (mp->pid), format_ip6_address, mp->address,
1461           format_ethernet_address, mp->new_mac, sw_if_index);
1462 }
1463
1464 static void
1465 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1466 {
1467   /* JSON output not supported */
1468 }
1469
1470 static void
1471 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1472 {
1473   u32 n_macs = ntohl (mp->n_macs);
1474   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1475           ntohl (mp->pid), mp->client_index, n_macs);
1476   int i;
1477   for (i = 0; i < n_macs; i++)
1478     {
1479       vl_api_mac_entry_t *mac = &mp->mac[i];
1480       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1481               i + 1, ntohl (mac->sw_if_index),
1482               format_ethernet_address, mac->mac_addr, mac->action);
1483       if (i == 1000)
1484         break;
1485     }
1486 }
1487
1488 static void
1489 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1490 {
1491   /* JSON output not supported */
1492 }
1493
1494 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1495 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1496
1497 /*
1498  * Special-case: build the bridge domain table, maintain
1499  * the next bd id vbl.
1500  */
1501 static void vl_api_bridge_domain_details_t_handler
1502   (vl_api_bridge_domain_details_t * mp)
1503 {
1504   vat_main_t *vam = &vat_main;
1505   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1506   int i;
1507
1508   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1509          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1510
1511   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1512          ntohl (mp->bd_id), mp->learn, mp->forward,
1513          mp->flood, ntohl (mp->bvi_sw_if_index),
1514          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1515
1516   if (n_sw_ifs)
1517     {
1518       vl_api_bridge_domain_sw_if_t *sw_ifs;
1519       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1520              "Interface Name");
1521
1522       sw_ifs = mp->sw_if_details;
1523       for (i = 0; i < n_sw_ifs; i++)
1524         {
1525           u8 *sw_if_name = 0;
1526           u32 sw_if_index;
1527           hash_pair_t *p;
1528
1529           sw_if_index = ntohl (sw_ifs->sw_if_index);
1530
1531           /* *INDENT-OFF* */
1532           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1533                              ({
1534                                if ((u32) p->value[0] == sw_if_index)
1535                                  {
1536                                    sw_if_name = (u8 *)(p->key);
1537                                    break;
1538                                  }
1539                              }));
1540           /* *INDENT-ON* */
1541           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1542                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1543                  "sw_if_index not found!");
1544
1545           sw_ifs++;
1546         }
1547     }
1548 }
1549
1550 static void vl_api_bridge_domain_details_t_handler_json
1551   (vl_api_bridge_domain_details_t * mp)
1552 {
1553   vat_main_t *vam = &vat_main;
1554   vat_json_node_t *node, *array = NULL;
1555   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1556
1557   if (VAT_JSON_ARRAY != vam->json_tree.type)
1558     {
1559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1560       vat_json_init_array (&vam->json_tree);
1561     }
1562   node = vat_json_array_add (&vam->json_tree);
1563
1564   vat_json_init_object (node);
1565   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1566   vat_json_object_add_uint (node, "flood", mp->flood);
1567   vat_json_object_add_uint (node, "forward", mp->forward);
1568   vat_json_object_add_uint (node, "learn", mp->learn);
1569   vat_json_object_add_uint (node, "bvi_sw_if_index",
1570                             ntohl (mp->bvi_sw_if_index));
1571   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1572   array = vat_json_object_add (node, "sw_if");
1573   vat_json_init_array (array);
1574
1575
1576
1577   if (n_sw_ifs)
1578     {
1579       vl_api_bridge_domain_sw_if_t *sw_ifs;
1580       int i;
1581
1582       sw_ifs = mp->sw_if_details;
1583       for (i = 0; i < n_sw_ifs; i++)
1584         {
1585           node = vat_json_array_add (array);
1586           vat_json_init_object (node);
1587           vat_json_object_add_uint (node, "sw_if_index",
1588                                     ntohl (sw_ifs->sw_if_index));
1589           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1590           sw_ifs++;
1591         }
1592     }
1593 }
1594
1595 static void vl_api_control_ping_reply_t_handler
1596   (vl_api_control_ping_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->result_ready = 1;
1608     }
1609   if (vam->socket_client_main)
1610     vam->socket_client_main->control_pings_outstanding--;
1611 }
1612
1613 static void vl_api_control_ping_reply_t_handler_json
1614   (vl_api_control_ping_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618
1619   if (VAT_JSON_NONE != vam->json_tree.type)
1620     {
1621       vat_json_print (vam->ofp, &vam->json_tree);
1622       vat_json_free (&vam->json_tree);
1623       vam->json_tree.type = VAT_JSON_NONE;
1624     }
1625   else
1626     {
1627       /* just print [] */
1628       vat_json_init_array (&vam->json_tree);
1629       vat_json_print (vam->ofp, &vam->json_tree);
1630       vam->json_tree.type = VAT_JSON_NONE;
1631     }
1632
1633   vam->retval = retval;
1634   vam->result_ready = 1;
1635 }
1636
1637 static void
1638   vl_api_bridge_domain_set_mac_age_reply_t_handler
1639   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1640 {
1641   vat_main_t *vam = &vat_main;
1642   i32 retval = ntohl (mp->retval);
1643   if (vam->async_mode)
1644     {
1645       vam->async_errors += (retval < 0);
1646     }
1647   else
1648     {
1649       vam->retval = retval;
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1655   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662
1663   vat_json_print (vam->ofp, &node);
1664   vat_json_free (&node);
1665
1666   vam->retval = ntohl (mp->retval);
1667   vam->result_ready = 1;
1668 }
1669
1670 static void
1671 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   i32 retval = ntohl (mp->retval);
1675   if (vam->async_mode)
1676     {
1677       vam->async_errors += (retval < 0);
1678     }
1679   else
1680     {
1681       vam->retval = retval;
1682       vam->result_ready = 1;
1683     }
1684 }
1685
1686 static void vl_api_l2_flags_reply_t_handler_json
1687   (vl_api_l2_flags_reply_t * mp)
1688 {
1689   vat_main_t *vam = &vat_main;
1690   vat_json_node_t node;
1691
1692   vat_json_init_object (&node);
1693   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1694   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1695                             ntohl (mp->resulting_feature_bitmap));
1696
1697   vat_json_print (vam->ofp, &node);
1698   vat_json_free (&node);
1699
1700   vam->retval = ntohl (mp->retval);
1701   vam->result_ready = 1;
1702 }
1703
1704 static void vl_api_bridge_flags_reply_t_handler
1705   (vl_api_bridge_flags_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   i32 retval = ntohl (mp->retval);
1709   if (vam->async_mode)
1710     {
1711       vam->async_errors += (retval < 0);
1712     }
1713   else
1714     {
1715       vam->retval = retval;
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_bridge_flags_reply_t_handler_json
1721   (vl_api_bridge_flags_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1729                             ntohl (mp->resulting_feature_bitmap));
1730
1731   vat_json_print (vam->ofp, &node);
1732   vat_json_free (&node);
1733
1734   vam->retval = ntohl (mp->retval);
1735   vam->result_ready = 1;
1736 }
1737
1738 static void vl_api_tap_connect_reply_t_handler
1739   (vl_api_tap_connect_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   i32 retval = ntohl (mp->retval);
1743   if (vam->async_mode)
1744     {
1745       vam->async_errors += (retval < 0);
1746     }
1747   else
1748     {
1749       vam->retval = retval;
1750       vam->sw_if_index = ntohl (mp->sw_if_index);
1751       vam->result_ready = 1;
1752     }
1753
1754 }
1755
1756 static void vl_api_tap_connect_reply_t_handler_json
1757   (vl_api_tap_connect_reply_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   vat_json_node_t node;
1761
1762   vat_json_init_object (&node);
1763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1765
1766   vat_json_print (vam->ofp, &node);
1767   vat_json_free (&node);
1768
1769   vam->retval = ntohl (mp->retval);
1770   vam->result_ready = 1;
1771
1772 }
1773
1774 static void
1775 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1776 {
1777   vat_main_t *vam = &vat_main;
1778   i32 retval = ntohl (mp->retval);
1779   if (vam->async_mode)
1780     {
1781       vam->async_errors += (retval < 0);
1782     }
1783   else
1784     {
1785       vam->retval = retval;
1786       vam->sw_if_index = ntohl (mp->sw_if_index);
1787       vam->result_ready = 1;
1788     }
1789 }
1790
1791 static void vl_api_tap_modify_reply_t_handler_json
1792   (vl_api_tap_modify_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   vat_json_node_t node;
1796
1797   vat_json_init_object (&node);
1798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1799   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1800
1801   vat_json_print (vam->ofp, &node);
1802   vat_json_free (&node);
1803
1804   vam->retval = ntohl (mp->retval);
1805   vam->result_ready = 1;
1806 }
1807
1808 static void
1809 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   i32 retval = ntohl (mp->retval);
1813   if (vam->async_mode)
1814     {
1815       vam->async_errors += (retval < 0);
1816     }
1817   else
1818     {
1819       vam->retval = retval;
1820       vam->result_ready = 1;
1821     }
1822 }
1823
1824 static void vl_api_tap_delete_reply_t_handler_json
1825   (vl_api_tap_delete_reply_t * mp)
1826 {
1827   vat_main_t *vam = &vat_main;
1828   vat_json_node_t node;
1829
1830   vat_json_init_object (&node);
1831   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1832
1833   vat_json_print (vam->ofp, &node);
1834   vat_json_free (&node);
1835
1836   vam->retval = ntohl (mp->retval);
1837   vam->result_ready = 1;
1838 }
1839
1840 static void
1841 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845   if (vam->async_mode)
1846     {
1847       vam->async_errors += (retval < 0);
1848     }
1849   else
1850     {
1851       vam->retval = retval;
1852       vam->sw_if_index = ntohl (mp->sw_if_index);
1853       vam->result_ready = 1;
1854     }
1855
1856 }
1857
1858 static void vl_api_tap_create_v2_reply_t_handler_json
1859   (vl_api_tap_create_v2_reply_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   vat_json_node_t node;
1863
1864   vat_json_init_object (&node);
1865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1867
1868   vat_json_print (vam->ofp, &node);
1869   vat_json_free (&node);
1870
1871   vam->retval = ntohl (mp->retval);
1872   vam->result_ready = 1;
1873
1874 }
1875
1876 static void
1877 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_tap_delete_v2_reply_t_handler_json
1893   (vl_api_tap_delete_v2_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_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 _(want_interface_events_reply)                          \
5263 _(cop_interface_enable_disable_reply)                   \
5264 _(cop_whitelist_enable_disable_reply)                   \
5265 _(sw_interface_clear_stats_reply)                       \
5266 _(ioam_enable_reply)                                    \
5267 _(ioam_disable_reply)                                   \
5268 _(one_add_del_locator_reply)                            \
5269 _(one_add_del_local_eid_reply)                          \
5270 _(one_add_del_remote_mapping_reply)                     \
5271 _(one_add_del_adjacency_reply)                          \
5272 _(one_add_del_map_resolver_reply)                       \
5273 _(one_add_del_map_server_reply)                         \
5274 _(one_enable_disable_reply)                             \
5275 _(one_rloc_probe_enable_disable_reply)                  \
5276 _(one_map_register_enable_disable_reply)                \
5277 _(one_map_register_set_ttl_reply)                       \
5278 _(one_set_transport_protocol_reply)                     \
5279 _(one_map_register_fallback_threshold_reply)            \
5280 _(one_pitr_set_locator_set_reply)                       \
5281 _(one_map_request_mode_reply)                           \
5282 _(one_add_del_map_request_itr_rlocs_reply)              \
5283 _(one_eid_table_add_del_map_reply)                      \
5284 _(one_use_petr_reply)                                   \
5285 _(one_stats_enable_disable_reply)                       \
5286 _(one_add_del_l2_arp_entry_reply)                       \
5287 _(one_add_del_ndp_entry_reply)                          \
5288 _(one_stats_flush_reply)                                \
5289 _(one_enable_disable_xtr_mode_reply)                    \
5290 _(one_enable_disable_pitr_mode_reply)                   \
5291 _(one_enable_disable_petr_mode_reply)                   \
5292 _(gpe_enable_disable_reply)                             \
5293 _(gpe_set_encap_mode_reply)                             \
5294 _(gpe_add_del_iface_reply)                              \
5295 _(gpe_add_del_native_fwd_rpath_reply)                   \
5296 _(af_packet_delete_reply)                               \
5297 _(policer_classify_set_interface_reply)                 \
5298 _(netmap_create_reply)                                  \
5299 _(netmap_delete_reply)                                  \
5300 _(set_ipfix_exporter_reply)                             \
5301 _(set_ipfix_classify_stream_reply)                      \
5302 _(ipfix_classify_table_add_del_reply)                   \
5303 _(flow_classify_set_interface_reply)                    \
5304 _(sw_interface_span_enable_disable_reply)               \
5305 _(pg_capture_reply)                                     \
5306 _(pg_enable_disable_reply)                              \
5307 _(ip_source_and_port_range_check_add_del_reply)         \
5308 _(ip_source_and_port_range_check_interface_add_del_reply)\
5309 _(delete_subif_reply)                                   \
5310 _(l2_interface_pbb_tag_rewrite_reply)                   \
5311 _(set_punt_reply)                                       \
5312 _(feature_enable_disable_reply)                         \
5313 _(sw_interface_tag_add_del_reply)                       \
5314 _(hw_interface_set_mtu_reply)                           \
5315 _(p2p_ethernet_add_reply)                               \
5316 _(p2p_ethernet_del_reply)                               \
5317 _(lldp_config_reply)                                    \
5318 _(sw_interface_set_lldp_reply)                          \
5319 _(tcp_configure_src_addresses_reply)                    \
5320 _(dns_enable_disable_reply)                             \
5321 _(dns_name_server_add_del_reply)                        \
5322 _(session_rule_add_del_reply)                           \
5323 _(ip_container_proxy_add_del_reply)                     \
5324 _(output_acl_set_interface_reply)                       \
5325 _(qos_record_enable_disable_reply)
5326
5327 #define _(n)                                    \
5328     static void vl_api_##n##_t_handler          \
5329     (vl_api_##n##_t * mp)                       \
5330     {                                           \
5331         vat_main_t * vam = &vat_main;           \
5332         i32 retval = ntohl(mp->retval);         \
5333         if (vam->async_mode) {                  \
5334             vam->async_errors += (retval < 0);  \
5335         } else {                                \
5336             vam->retval = retval;               \
5337             vam->result_ready = 1;              \
5338         }                                       \
5339     }
5340 foreach_standard_reply_retval_handler;
5341 #undef _
5342
5343 #define _(n)                                    \
5344     static void vl_api_##n##_t_handler_json     \
5345     (vl_api_##n##_t * mp)                       \
5346     {                                           \
5347         vat_main_t * vam = &vat_main;           \
5348         vat_json_node_t node;                   \
5349         vat_json_init_object(&node);            \
5350         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5351         vat_json_print(vam->ofp, &node);        \
5352         vam->retval = ntohl(mp->retval);        \
5353         vam->result_ready = 1;                  \
5354     }
5355 foreach_standard_reply_retval_handler;
5356 #undef _
5357
5358 /*
5359  * Table of message reply handlers, must include boilerplate handlers
5360  * we just generated
5361  */
5362
5363 #define foreach_vpe_api_reply_msg                                       \
5364 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5365 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5366 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5367 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5368 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5369 _(CLI_REPLY, cli_reply)                                                 \
5370 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5371 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5372   sw_interface_add_del_address_reply)                                   \
5373 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5374 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5375 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5376 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5377 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5378 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5379 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5380 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5381 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5382 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5383   sw_interface_set_l2_xconnect_reply)                                   \
5384 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5385   sw_interface_set_l2_bridge_reply)                                     \
5386 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5387 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5388 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5389 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5390 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5391 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5392 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5393 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5394 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5395 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5396 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5397 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5398 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5399 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5400 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5401 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5402 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5403 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5404 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5405 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5406 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5407 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5408 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5409 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5410 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5411 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5412 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5413 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5414 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5415 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5416 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5417   proxy_arp_intfc_enable_disable_reply)                                 \
5418 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5419 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5420   sw_interface_set_unnumbered_reply)                                    \
5421 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5422 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5423 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5424 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5425 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5426 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5427 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5428 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5429 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5430 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5431 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5432   sw_interface_ip6_enable_disable_reply)                                \
5433 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5434 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5435 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5436   sw_interface_ip6nd_ra_prefix_reply)                                   \
5437 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5438   sw_interface_ip6nd_ra_config_reply)                                   \
5439 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5440 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5441 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5442 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5443 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5444 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5445 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5446 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5447 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5448 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5449 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5450 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5451 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5452 classify_set_interface_ip_table_reply)                                  \
5453 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5454   classify_set_interface_l2_tables_reply)                               \
5455 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5456 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5457 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5458 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5459 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5460   l2tpv3_interface_enable_disable_reply)                                \
5461 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5462 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5463 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5464 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5465 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5466 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5467 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5468 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5469 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5470 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5471 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5472 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5473 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5474 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5475 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5476 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5477 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5478 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5479 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5480 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5481 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5482 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5483 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5484 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5485 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5486 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5487 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5488 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5489 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5490 _(L2_MACS_EVENT, l2_macs_event)                                         \
5491 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5492 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5493 _(IP_DETAILS, ip_details)                                               \
5494 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5495 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5496 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5497 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5498 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5499 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5500 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5501 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5502 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5503 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5504 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5505 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5506 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5507 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5508 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5509 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5510 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5511 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5512 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5513 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5514 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5515 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5516 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5517 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5518 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5519 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5520 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5521 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5522 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5523 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5524 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5525 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5526 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5527 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5528 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5529 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5530 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5531 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5532 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5533 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5534 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5535 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5536 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5537   one_map_register_enable_disable_reply)                                \
5538 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5539 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5540 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5541 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5542   one_map_register_fallback_threshold_reply)                            \
5543 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5544   one_rloc_probe_enable_disable_reply)                                  \
5545 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5546 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5547 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5548 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5549 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5550 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5551 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5552 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5553 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5554 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5555 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5556 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5557 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5558 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5559 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5560 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5561   show_one_stats_enable_disable_reply)                                  \
5562 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5563 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5564 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5565 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5566 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5567 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5568 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5569 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5570   one_enable_disable_pitr_mode_reply)                                   \
5571 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5572   one_enable_disable_petr_mode_reply)                                   \
5573 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5574 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5575 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5576 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5577 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5578 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5579 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5580 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5581 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5582 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5583 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5584 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5585   gpe_add_del_native_fwd_rpath_reply)                                   \
5586 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5587   gpe_fwd_entry_path_details)                                           \
5588 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5589 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5590   one_add_del_map_request_itr_rlocs_reply)                              \
5591 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5592   one_get_map_request_itr_rlocs_reply)                                  \
5593 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5594 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5595 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5596 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5597 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5598 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5599   show_one_map_register_state_reply)                                    \
5600 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5601 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5602   show_one_map_register_fallback_threshold_reply)                       \
5603 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5604 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5605 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5606 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5607 _(POLICER_DETAILS, policer_details)                                     \
5608 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5609 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5610 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5611 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5612 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5613 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5614 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5615 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5616 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5617 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5618 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5619 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5620 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5621 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5622 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5623 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5624 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5625 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5626 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5627 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5628 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5629 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5630 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5631 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5632 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5633  ip_source_and_port_range_check_add_del_reply)                          \
5634 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5635  ip_source_and_port_range_check_interface_add_del_reply)                \
5636 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5637 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5638 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5639 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5640 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5641 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5642 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5643 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5644 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5645 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5646 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5647 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5648 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5649 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5650 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5651 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5652 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5653 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5654 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5655 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5656 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5657 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5658 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5659 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5660 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5661 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5662 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5663 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5664
5665 #define foreach_standalone_reply_msg                                    \
5666 _(SW_INTERFACE_EVENT, sw_interface_event)
5667
5668 typedef struct
5669 {
5670   u8 *name;
5671   u32 value;
5672 } name_sort_t;
5673
5674 #define STR_VTR_OP_CASE(op)     \
5675     case L2_VTR_ ## op:         \
5676         return "" # op;
5677
5678 static const char *
5679 str_vtr_op (u32 vtr_op)
5680 {
5681   switch (vtr_op)
5682     {
5683       STR_VTR_OP_CASE (DISABLED);
5684       STR_VTR_OP_CASE (PUSH_1);
5685       STR_VTR_OP_CASE (PUSH_2);
5686       STR_VTR_OP_CASE (POP_1);
5687       STR_VTR_OP_CASE (POP_2);
5688       STR_VTR_OP_CASE (TRANSLATE_1_1);
5689       STR_VTR_OP_CASE (TRANSLATE_1_2);
5690       STR_VTR_OP_CASE (TRANSLATE_2_1);
5691       STR_VTR_OP_CASE (TRANSLATE_2_2);
5692     }
5693
5694   return "UNKNOWN";
5695 }
5696
5697 static int
5698 dump_sub_interface_table (vat_main_t * vam)
5699 {
5700   const sw_interface_subif_t *sub = NULL;
5701
5702   if (vam->json_output)
5703     {
5704       clib_warning
5705         ("JSON output supported only for VPE API calls and dump_stats_table");
5706       return -99;
5707     }
5708
5709   print (vam->ofp,
5710          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5711          "Interface", "sw_if_index",
5712          "sub id", "dot1ad", "tags", "outer id",
5713          "inner id", "exact", "default", "outer any", "inner any");
5714
5715   vec_foreach (sub, vam->sw_if_subif_table)
5716   {
5717     print (vam->ofp,
5718            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5719            sub->interface_name,
5720            sub->sw_if_index,
5721            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5722            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5723            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5724            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5725     if (sub->vtr_op != L2_VTR_DISABLED)
5726       {
5727         print (vam->ofp,
5728                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5729                "tag1: %d tag2: %d ]",
5730                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5731                sub->vtr_tag1, sub->vtr_tag2);
5732       }
5733   }
5734
5735   return 0;
5736 }
5737
5738 static int
5739 name_sort_cmp (void *a1, void *a2)
5740 {
5741   name_sort_t *n1 = a1;
5742   name_sort_t *n2 = a2;
5743
5744   return strcmp ((char *) n1->name, (char *) n2->name);
5745 }
5746
5747 static int
5748 dump_interface_table (vat_main_t * vam)
5749 {
5750   hash_pair_t *p;
5751   name_sort_t *nses = 0, *ns;
5752
5753   if (vam->json_output)
5754     {
5755       clib_warning
5756         ("JSON output supported only for VPE API calls and dump_stats_table");
5757       return -99;
5758     }
5759
5760   /* *INDENT-OFF* */
5761   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5762   ({
5763     vec_add2 (nses, ns, 1);
5764     ns->name = (u8 *)(p->key);
5765     ns->value = (u32) p->value[0];
5766   }));
5767   /* *INDENT-ON* */
5768
5769   vec_sort_with_function (nses, name_sort_cmp);
5770
5771   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5772   vec_foreach (ns, nses)
5773   {
5774     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5775   }
5776   vec_free (nses);
5777   return 0;
5778 }
5779
5780 static int
5781 dump_ip_table (vat_main_t * vam, int is_ipv6)
5782 {
5783   const ip_details_t *det = NULL;
5784   const ip_address_details_t *address = NULL;
5785   u32 i = ~0;
5786
5787   print (vam->ofp, "%-12s", "sw_if_index");
5788
5789   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5790   {
5791     i++;
5792     if (!det->present)
5793       {
5794         continue;
5795       }
5796     print (vam->ofp, "%-12d", i);
5797     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5798     if (!det->addr)
5799       {
5800         continue;
5801       }
5802     vec_foreach (address, det->addr)
5803     {
5804       print (vam->ofp,
5805              "            %-30U%-13d",
5806              is_ipv6 ? format_ip6_address : format_ip4_address,
5807              address->ip, address->prefix_length);
5808     }
5809   }
5810
5811   return 0;
5812 }
5813
5814 static int
5815 dump_ipv4_table (vat_main_t * vam)
5816 {
5817   if (vam->json_output)
5818     {
5819       clib_warning
5820         ("JSON output supported only for VPE API calls and dump_stats_table");
5821       return -99;
5822     }
5823
5824   return dump_ip_table (vam, 0);
5825 }
5826
5827 static int
5828 dump_ipv6_table (vat_main_t * vam)
5829 {
5830   if (vam->json_output)
5831     {
5832       clib_warning
5833         ("JSON output supported only for VPE API calls and dump_stats_table");
5834       return -99;
5835     }
5836
5837   return dump_ip_table (vam, 1);
5838 }
5839
5840 /*
5841  * Pass CLI buffers directly in the CLI_INBAND API message,
5842  * instead of an additional shared memory area.
5843  */
5844 static int
5845 exec_inband (vat_main_t * vam)
5846 {
5847   vl_api_cli_inband_t *mp;
5848   unformat_input_t *i = vam->input;
5849   int ret;
5850
5851   if (vec_len (i->buffer) == 0)
5852     return -1;
5853
5854   if (vam->exec_mode == 0 && unformat (i, "mode"))
5855     {
5856       vam->exec_mode = 1;
5857       return 0;
5858     }
5859   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5860     {
5861       vam->exec_mode = 0;
5862       return 0;
5863     }
5864
5865   /*
5866    * In order for the CLI command to work, it
5867    * must be a vector ending in \n, not a C-string ending
5868    * in \n\0.
5869    */
5870   u32 len = vec_len (vam->input->buffer);
5871   M2 (CLI_INBAND, mp, len);
5872   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5873
5874   S (mp);
5875   W (ret);
5876   /* json responses may or may not include a useful reply... */
5877   if (vec_len (vam->cmd_reply))
5878     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5879   return ret;
5880 }
5881
5882 int
5883 exec (vat_main_t * vam)
5884 {
5885   return exec_inband (vam);
5886 }
5887
5888 static int
5889 api_create_loopback (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_create_loopback_t *mp;
5893   vl_api_create_loopback_instance_t *mp_lbi;
5894   u8 mac_address[6];
5895   u8 mac_set = 0;
5896   u8 is_specified = 0;
5897   u32 user_instance = 0;
5898   int ret;
5899
5900   clib_memset (mac_address, 0, sizeof (mac_address));
5901
5902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5903     {
5904       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5905         mac_set = 1;
5906       if (unformat (i, "instance %d", &user_instance))
5907         is_specified = 1;
5908       else
5909         break;
5910     }
5911
5912   if (is_specified)
5913     {
5914       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5915       mp_lbi->is_specified = is_specified;
5916       if (is_specified)
5917         mp_lbi->user_instance = htonl (user_instance);
5918       if (mac_set)
5919         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5920       S (mp_lbi);
5921     }
5922   else
5923     {
5924       /* Construct the API message */
5925       M (CREATE_LOOPBACK, mp);
5926       if (mac_set)
5927         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5928       S (mp);
5929     }
5930
5931   W (ret);
5932   return ret;
5933 }
5934
5935 static int
5936 api_delete_loopback (vat_main_t * vam)
5937 {
5938   unformat_input_t *i = vam->input;
5939   vl_api_delete_loopback_t *mp;
5940   u32 sw_if_index = ~0;
5941   int ret;
5942
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "sw_if_index %d", &sw_if_index))
5946         ;
5947       else
5948         break;
5949     }
5950
5951   if (sw_if_index == ~0)
5952     {
5953       errmsg ("missing sw_if_index");
5954       return -99;
5955     }
5956
5957   /* Construct the API message */
5958   M (DELETE_LOOPBACK, mp);
5959   mp->sw_if_index = ntohl (sw_if_index);
5960
5961   S (mp);
5962   W (ret);
5963   return ret;
5964 }
5965
5966 static int
5967 api_want_interface_events (vat_main_t * vam)
5968 {
5969   unformat_input_t *i = vam->input;
5970   vl_api_want_interface_events_t *mp;
5971   int enable = -1;
5972   int ret;
5973
5974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5975     {
5976       if (unformat (i, "enable"))
5977         enable = 1;
5978       else if (unformat (i, "disable"))
5979         enable = 0;
5980       else
5981         break;
5982     }
5983
5984   if (enable == -1)
5985     {
5986       errmsg ("missing enable|disable");
5987       return -99;
5988     }
5989
5990   M (WANT_INTERFACE_EVENTS, mp);
5991   mp->enable_disable = enable;
5992
5993   vam->interface_event_display = enable;
5994
5995   S (mp);
5996   W (ret);
5997   return ret;
5998 }
5999
6000
6001 /* Note: non-static, called once to set up the initial intfc table */
6002 int
6003 api_sw_interface_dump (vat_main_t * vam)
6004 {
6005   vl_api_sw_interface_dump_t *mp;
6006   vl_api_control_ping_t *mp_ping;
6007   hash_pair_t *p;
6008   name_sort_t *nses = 0, *ns;
6009   sw_interface_subif_t *sub = NULL;
6010   int ret;
6011
6012   /* Toss the old name table */
6013   /* *INDENT-OFF* */
6014   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6015   ({
6016     vec_add2 (nses, ns, 1);
6017     ns->name = (u8 *)(p->key);
6018     ns->value = (u32) p->value[0];
6019   }));
6020   /* *INDENT-ON* */
6021
6022   hash_free (vam->sw_if_index_by_interface_name);
6023
6024   vec_foreach (ns, nses) vec_free (ns->name);
6025
6026   vec_free (nses);
6027
6028   vec_foreach (sub, vam->sw_if_subif_table)
6029   {
6030     vec_free (sub->interface_name);
6031   }
6032   vec_free (vam->sw_if_subif_table);
6033
6034   /* recreate the interface name hash table */
6035   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6036
6037   /*
6038    * Ask for all interface names. Otherwise, the epic catalog of
6039    * name filters becomes ridiculously long, and vat ends up needing
6040    * to be taught about new interface types.
6041    */
6042   M (SW_INTERFACE_DUMP, mp);
6043   S (mp);
6044
6045   /* Use a control ping for synchronization */
6046   MPING (CONTROL_PING, mp_ping);
6047   S (mp_ping);
6048
6049   W (ret);
6050   return ret;
6051 }
6052
6053 static int
6054 api_sw_interface_set_flags (vat_main_t * vam)
6055 {
6056   unformat_input_t *i = vam->input;
6057   vl_api_sw_interface_set_flags_t *mp;
6058   u32 sw_if_index;
6059   u8 sw_if_index_set = 0;
6060   u8 admin_up = 0;
6061   int ret;
6062
6063   /* Parse args required to build the message */
6064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6065     {
6066       if (unformat (i, "admin-up"))
6067         admin_up = 1;
6068       else if (unformat (i, "admin-down"))
6069         admin_up = 0;
6070       else
6071         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6072         sw_if_index_set = 1;
6073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6074         sw_if_index_set = 1;
6075       else
6076         break;
6077     }
6078
6079   if (sw_if_index_set == 0)
6080     {
6081       errmsg ("missing interface name or sw_if_index");
6082       return -99;
6083     }
6084
6085   /* Construct the API message */
6086   M (SW_INTERFACE_SET_FLAGS, mp);
6087   mp->sw_if_index = ntohl (sw_if_index);
6088   mp->admin_up_down = admin_up;
6089
6090   /* send it... */
6091   S (mp);
6092
6093   /* Wait for a reply, return the good/bad news... */
6094   W (ret);
6095   return ret;
6096 }
6097
6098 static int
6099 api_sw_interface_set_rx_mode (vat_main_t * vam)
6100 {
6101   unformat_input_t *i = vam->input;
6102   vl_api_sw_interface_set_rx_mode_t *mp;
6103   u32 sw_if_index;
6104   u8 sw_if_index_set = 0;
6105   int ret;
6106   u8 queue_id_valid = 0;
6107   u32 queue_id;
6108   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6109
6110   /* Parse args required to build the message */
6111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6112     {
6113       if (unformat (i, "queue %d", &queue_id))
6114         queue_id_valid = 1;
6115       else if (unformat (i, "polling"))
6116         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6117       else if (unformat (i, "interrupt"))
6118         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6119       else if (unformat (i, "adaptive"))
6120         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6121       else
6122         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6123         sw_if_index_set = 1;
6124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         sw_if_index_set = 1;
6126       else
6127         break;
6128     }
6129
6130   if (sw_if_index_set == 0)
6131     {
6132       errmsg ("missing interface name or sw_if_index");
6133       return -99;
6134     }
6135   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6136     {
6137       errmsg ("missing rx-mode");
6138       return -99;
6139     }
6140
6141   /* Construct the API message */
6142   M (SW_INTERFACE_SET_RX_MODE, mp);
6143   mp->sw_if_index = ntohl (sw_if_index);
6144   mp->mode = mode;
6145   mp->queue_id_valid = queue_id_valid;
6146   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6147
6148   /* send it... */
6149   S (mp);
6150
6151   /* Wait for a reply, return the good/bad news... */
6152   W (ret);
6153   return ret;
6154 }
6155
6156 static int
6157 api_sw_interface_set_rx_placement (vat_main_t * vam)
6158 {
6159   unformat_input_t *i = vam->input;
6160   vl_api_sw_interface_set_rx_placement_t *mp;
6161   u32 sw_if_index;
6162   u8 sw_if_index_set = 0;
6163   int ret;
6164   u8 is_main = 0;
6165   u32 queue_id, thread_index;
6166
6167   /* Parse args required to build the message */
6168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6169     {
6170       if (unformat (i, "queue %d", &queue_id))
6171         ;
6172       else if (unformat (i, "main"))
6173         is_main = 1;
6174       else if (unformat (i, "worker %d", &thread_index))
6175         ;
6176       else
6177         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6178         sw_if_index_set = 1;
6179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6180         sw_if_index_set = 1;
6181       else
6182         break;
6183     }
6184
6185   if (sw_if_index_set == 0)
6186     {
6187       errmsg ("missing interface name or sw_if_index");
6188       return -99;
6189     }
6190
6191   if (is_main)
6192     thread_index = 0;
6193   /* Construct the API message */
6194   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6195   mp->sw_if_index = ntohl (sw_if_index);
6196   mp->worker_id = ntohl (thread_index);
6197   mp->queue_id = ntohl (queue_id);
6198   mp->is_main = is_main;
6199
6200   /* send it... */
6201   S (mp);
6202   /* Wait for a reply, return the good/bad news... */
6203   W (ret);
6204   return ret;
6205 }
6206
6207 static void vl_api_sw_interface_rx_placement_details_t_handler
6208   (vl_api_sw_interface_rx_placement_details_t * mp)
6209 {
6210   vat_main_t *vam = &vat_main;
6211   u32 worker_id = ntohl (mp->worker_id);
6212
6213   print (vam->ofp,
6214          "\n%-11d %-11s %-6d %-5d %-9s",
6215          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6216          worker_id, ntohl (mp->queue_id),
6217          (mp->mode ==
6218           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6219 }
6220
6221 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6222   (vl_api_sw_interface_rx_placement_details_t * mp)
6223 {
6224   vat_main_t *vam = &vat_main;
6225   vat_json_node_t *node = NULL;
6226
6227   if (VAT_JSON_ARRAY != vam->json_tree.type)
6228     {
6229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6230       vat_json_init_array (&vam->json_tree);
6231     }
6232   node = vat_json_array_add (&vam->json_tree);
6233
6234   vat_json_init_object (node);
6235   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6236   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6237   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6238   vat_json_object_add_uint (node, "mode", mp->mode);
6239 }
6240
6241 static int
6242 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6243 {
6244   unformat_input_t *i = vam->input;
6245   vl_api_sw_interface_rx_placement_dump_t *mp;
6246   vl_api_control_ping_t *mp_ping;
6247   int ret;
6248   u32 sw_if_index;
6249   u8 sw_if_index_set = 0;
6250
6251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6252     {
6253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6254         sw_if_index_set++;
6255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6256         sw_if_index_set++;
6257       else
6258         break;
6259     }
6260
6261   print (vam->ofp,
6262          "\n%-11s %-11s %-6s %-5s %-4s",
6263          "sw_if_index", "main/worker", "thread", "queue", "mode");
6264
6265   /* Dump Interface rx placement */
6266   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6267
6268   if (sw_if_index_set)
6269     mp->sw_if_index = htonl (sw_if_index);
6270   else
6271     mp->sw_if_index = ~0;
6272
6273   S (mp);
6274
6275   /* Use a control ping for synchronization */
6276   MPING (CONTROL_PING, mp_ping);
6277   S (mp_ping);
6278
6279   W (ret);
6280   return ret;
6281 }
6282
6283 static int
6284 api_sw_interface_clear_stats (vat_main_t * vam)
6285 {
6286   unformat_input_t *i = vam->input;
6287   vl_api_sw_interface_clear_stats_t *mp;
6288   u32 sw_if_index;
6289   u8 sw_if_index_set = 0;
6290   int ret;
6291
6292   /* Parse args required to build the message */
6293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6294     {
6295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6296         sw_if_index_set = 1;
6297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6298         sw_if_index_set = 1;
6299       else
6300         break;
6301     }
6302
6303   /* Construct the API message */
6304   M (SW_INTERFACE_CLEAR_STATS, mp);
6305
6306   if (sw_if_index_set == 1)
6307     mp->sw_if_index = ntohl (sw_if_index);
6308   else
6309     mp->sw_if_index = ~0;
6310
6311   /* send it... */
6312   S (mp);
6313
6314   /* Wait for a reply, return the good/bad news... */
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static int
6320 api_sw_interface_add_del_address (vat_main_t * vam)
6321 {
6322   unformat_input_t *i = vam->input;
6323   vl_api_sw_interface_add_del_address_t *mp;
6324   u32 sw_if_index;
6325   u8 sw_if_index_set = 0;
6326   u8 is_add = 1, del_all = 0;
6327   u32 address_length = 0;
6328   u8 v4_address_set = 0;
6329   u8 v6_address_set = 0;
6330   ip4_address_t v4address;
6331   ip6_address_t v6address;
6332   int ret;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "del-all"))
6338         del_all = 1;
6339       else if (unformat (i, "del"))
6340         is_add = 0;
6341       else
6342         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6343         sw_if_index_set = 1;
6344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "%U/%d",
6347                          unformat_ip4_address, &v4address, &address_length))
6348         v4_address_set = 1;
6349       else if (unformat (i, "%U/%d",
6350                          unformat_ip6_address, &v6address, &address_length))
6351         v6_address_set = 1;
6352       else
6353         break;
6354     }
6355
6356   if (sw_if_index_set == 0)
6357     {
6358       errmsg ("missing interface name or sw_if_index");
6359       return -99;
6360     }
6361   if (v4_address_set && v6_address_set)
6362     {
6363       errmsg ("both v4 and v6 addresses set");
6364       return -99;
6365     }
6366   if (!v4_address_set && !v6_address_set && !del_all)
6367     {
6368       errmsg ("no addresses set");
6369       return -99;
6370     }
6371
6372   /* Construct the API message */
6373   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6374
6375   mp->sw_if_index = ntohl (sw_if_index);
6376   mp->is_add = is_add;
6377   mp->del_all = del_all;
6378   if (v6_address_set)
6379     {
6380       mp->is_ipv6 = 1;
6381       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6382     }
6383   else
6384     {
6385       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6386     }
6387   mp->address_length = address_length;
6388
6389   /* send it... */
6390   S (mp);
6391
6392   /* Wait for a reply, return good/bad news  */
6393   W (ret);
6394   return ret;
6395 }
6396
6397 static int
6398 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6399 {
6400   unformat_input_t *i = vam->input;
6401   vl_api_sw_interface_set_mpls_enable_t *mp;
6402   u32 sw_if_index;
6403   u8 sw_if_index_set = 0;
6404   u8 enable = 1;
6405   int ret;
6406
6407   /* Parse args required to build the message */
6408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6409     {
6410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6411         sw_if_index_set = 1;
6412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "disable"))
6415         enable = 0;
6416       else if (unformat (i, "dis"))
6417         enable = 0;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6430
6431   mp->sw_if_index = ntohl (sw_if_index);
6432   mp->enable = enable;
6433
6434   /* send it... */
6435   S (mp);
6436
6437   /* Wait for a reply... */
6438   W (ret);
6439   return ret;
6440 }
6441
6442 static int
6443 api_sw_interface_set_table (vat_main_t * vam)
6444 {
6445   unformat_input_t *i = vam->input;
6446   vl_api_sw_interface_set_table_t *mp;
6447   u32 sw_if_index, vrf_id = 0;
6448   u8 sw_if_index_set = 0;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "vrf %d", &vrf_id))
6460         ;
6461       else if (unformat (i, "ipv6"))
6462         is_ipv6 = 1;
6463       else
6464         break;
6465     }
6466
6467   if (sw_if_index_set == 0)
6468     {
6469       errmsg ("missing interface name or sw_if_index");
6470       return -99;
6471     }
6472
6473   /* Construct the API message */
6474   M (SW_INTERFACE_SET_TABLE, mp);
6475
6476   mp->sw_if_index = ntohl (sw_if_index);
6477   mp->is_ipv6 = is_ipv6;
6478   mp->vrf_id = ntohl (vrf_id);
6479
6480   /* send it... */
6481   S (mp);
6482
6483   /* Wait for a reply... */
6484   W (ret);
6485   return ret;
6486 }
6487
6488 static void vl_api_sw_interface_get_table_reply_t_handler
6489   (vl_api_sw_interface_get_table_reply_t * mp)
6490 {
6491   vat_main_t *vam = &vat_main;
6492
6493   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6494
6495   vam->retval = ntohl (mp->retval);
6496   vam->result_ready = 1;
6497
6498 }
6499
6500 static void vl_api_sw_interface_get_table_reply_t_handler_json
6501   (vl_api_sw_interface_get_table_reply_t * mp)
6502 {
6503   vat_main_t *vam = &vat_main;
6504   vat_json_node_t node;
6505
6506   vat_json_init_object (&node);
6507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6508   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6509
6510   vat_json_print (vam->ofp, &node);
6511   vat_json_free (&node);
6512
6513   vam->retval = ntohl (mp->retval);
6514   vam->result_ready = 1;
6515 }
6516
6517 static int
6518 api_sw_interface_get_table (vat_main_t * vam)
6519 {
6520   unformat_input_t *i = vam->input;
6521   vl_api_sw_interface_get_table_t *mp;
6522   u32 sw_if_index;
6523   u8 sw_if_index_set = 0;
6524   u8 is_ipv6 = 0;
6525   int ret;
6526
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "ipv6"))
6534         is_ipv6 = 1;
6535       else
6536         break;
6537     }
6538
6539   if (sw_if_index_set == 0)
6540     {
6541       errmsg ("missing interface name or sw_if_index");
6542       return -99;
6543     }
6544
6545   M (SW_INTERFACE_GET_TABLE, mp);
6546   mp->sw_if_index = htonl (sw_if_index);
6547   mp->is_ipv6 = is_ipv6;
6548
6549   S (mp);
6550   W (ret);
6551   return ret;
6552 }
6553
6554 static int
6555 api_sw_interface_set_vpath (vat_main_t * vam)
6556 {
6557   unformat_input_t *i = vam->input;
6558   vl_api_sw_interface_set_vpath_t *mp;
6559   u32 sw_if_index = 0;
6560   u8 sw_if_index_set = 0;
6561   u8 is_enable = 0;
6562   int ret;
6563
6564   /* Parse args required to build the message */
6565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6566     {
6567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6568         sw_if_index_set = 1;
6569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6570         sw_if_index_set = 1;
6571       else if (unformat (i, "enable"))
6572         is_enable = 1;
6573       else if (unformat (i, "disable"))
6574         is_enable = 0;
6575       else
6576         break;
6577     }
6578
6579   if (sw_if_index_set == 0)
6580     {
6581       errmsg ("missing interface name or sw_if_index");
6582       return -99;
6583     }
6584
6585   /* Construct the API message */
6586   M (SW_INTERFACE_SET_VPATH, mp);
6587
6588   mp->sw_if_index = ntohl (sw_if_index);
6589   mp->enable = is_enable;
6590
6591   /* send it... */
6592   S (mp);
6593
6594   /* Wait for a reply... */
6595   W (ret);
6596   return ret;
6597 }
6598
6599 static int
6600 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6601 {
6602   unformat_input_t *i = vam->input;
6603   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6604   u32 sw_if_index = 0;
6605   u8 sw_if_index_set = 0;
6606   u8 is_enable = 1;
6607   u8 is_ipv6 = 0;
6608   int ret;
6609
6610   /* Parse args required to build the message */
6611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6612     {
6613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6614         sw_if_index_set = 1;
6615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "enable"))
6618         is_enable = 1;
6619       else if (unformat (i, "disable"))
6620         is_enable = 0;
6621       else if (unformat (i, "ip4"))
6622         is_ipv6 = 0;
6623       else if (unformat (i, "ip6"))
6624         is_ipv6 = 1;
6625       else
6626         break;
6627     }
6628
6629   if (sw_if_index_set == 0)
6630     {
6631       errmsg ("missing interface name or sw_if_index");
6632       return -99;
6633     }
6634
6635   /* Construct the API message */
6636   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6637
6638   mp->sw_if_index = ntohl (sw_if_index);
6639   mp->enable = is_enable;
6640   mp->is_ipv6 = is_ipv6;
6641
6642   /* send it... */
6643   S (mp);
6644
6645   /* Wait for a reply... */
6646   W (ret);
6647   return ret;
6648 }
6649
6650 static int
6651 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6652 {
6653   unformat_input_t *i = vam->input;
6654   vl_api_sw_interface_set_geneve_bypass_t *mp;
6655   u32 sw_if_index = 0;
6656   u8 sw_if_index_set = 0;
6657   u8 is_enable = 1;
6658   u8 is_ipv6 = 0;
6659   int ret;
6660
6661   /* Parse args required to build the message */
6662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663     {
6664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6665         sw_if_index_set = 1;
6666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "enable"))
6669         is_enable = 1;
6670       else if (unformat (i, "disable"))
6671         is_enable = 0;
6672       else if (unformat (i, "ip4"))
6673         is_ipv6 = 0;
6674       else if (unformat (i, "ip6"))
6675         is_ipv6 = 1;
6676       else
6677         break;
6678     }
6679
6680   if (sw_if_index_set == 0)
6681     {
6682       errmsg ("missing interface name or sw_if_index");
6683       return -99;
6684     }
6685
6686   /* Construct the API message */
6687   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6688
6689   mp->sw_if_index = ntohl (sw_if_index);
6690   mp->enable = is_enable;
6691   mp->is_ipv6 = is_ipv6;
6692
6693   /* send it... */
6694   S (mp);
6695
6696   /* Wait for a reply... */
6697   W (ret);
6698   return ret;
6699 }
6700
6701 static int
6702 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_set_l2_xconnect_t *mp;
6706   u32 rx_sw_if_index;
6707   u8 rx_sw_if_index_set = 0;
6708   u32 tx_sw_if_index;
6709   u8 tx_sw_if_index_set = 0;
6710   u8 enable = 1;
6711   int ret;
6712
6713   /* Parse args required to build the message */
6714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6715     {
6716       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6717         rx_sw_if_index_set = 1;
6718       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6719         tx_sw_if_index_set = 1;
6720       else if (unformat (i, "rx"))
6721         {
6722           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6723             {
6724               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6725                             &rx_sw_if_index))
6726                 rx_sw_if_index_set = 1;
6727             }
6728           else
6729             break;
6730         }
6731       else if (unformat (i, "tx"))
6732         {
6733           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6734             {
6735               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6736                             &tx_sw_if_index))
6737                 tx_sw_if_index_set = 1;
6738             }
6739           else
6740             break;
6741         }
6742       else if (unformat (i, "enable"))
6743         enable = 1;
6744       else if (unformat (i, "disable"))
6745         enable = 0;
6746       else
6747         break;
6748     }
6749
6750   if (rx_sw_if_index_set == 0)
6751     {
6752       errmsg ("missing rx interface name or rx_sw_if_index");
6753       return -99;
6754     }
6755
6756   if (enable && (tx_sw_if_index_set == 0))
6757     {
6758       errmsg ("missing tx interface name or tx_sw_if_index");
6759       return -99;
6760     }
6761
6762   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6763
6764   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6765   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6766   mp->enable = enable;
6767
6768   S (mp);
6769   W (ret);
6770   return ret;
6771 }
6772
6773 static int
6774 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6775 {
6776   unformat_input_t *i = vam->input;
6777   vl_api_sw_interface_set_l2_bridge_t *mp;
6778   vl_api_l2_port_type_t port_type;
6779   u32 rx_sw_if_index;
6780   u8 rx_sw_if_index_set = 0;
6781   u32 bd_id;
6782   u8 bd_id_set = 0;
6783   u32 shg = 0;
6784   u8 enable = 1;
6785   int ret;
6786
6787   port_type = L2_API_PORT_TYPE_NORMAL;
6788
6789   /* Parse args required to build the message */
6790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791     {
6792       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6793         rx_sw_if_index_set = 1;
6794       else if (unformat (i, "bd_id %d", &bd_id))
6795         bd_id_set = 1;
6796       else
6797         if (unformat
6798             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6799         rx_sw_if_index_set = 1;
6800       else if (unformat (i, "shg %d", &shg))
6801         ;
6802       else if (unformat (i, "bvi"))
6803         port_type = L2_API_PORT_TYPE_BVI;
6804       else if (unformat (i, "uu-fwd"))
6805         port_type = L2_API_PORT_TYPE_UU_FWD;
6806       else if (unformat (i, "enable"))
6807         enable = 1;
6808       else if (unformat (i, "disable"))
6809         enable = 0;
6810       else
6811         break;
6812     }
6813
6814   if (rx_sw_if_index_set == 0)
6815     {
6816       errmsg ("missing rx interface name or sw_if_index");
6817       return -99;
6818     }
6819
6820   if (enable && (bd_id_set == 0))
6821     {
6822       errmsg ("missing bridge domain");
6823       return -99;
6824     }
6825
6826   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6827
6828   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6829   mp->bd_id = ntohl (bd_id);
6830   mp->shg = (u8) shg;
6831   mp->port_type = ntohl (port_type);
6832   mp->enable = enable;
6833
6834   S (mp);
6835   W (ret);
6836   return ret;
6837 }
6838
6839 static int
6840 api_bridge_domain_dump (vat_main_t * vam)
6841 {
6842   unformat_input_t *i = vam->input;
6843   vl_api_bridge_domain_dump_t *mp;
6844   vl_api_control_ping_t *mp_ping;
6845   u32 bd_id = ~0;
6846   int ret;
6847
6848   /* Parse args required to build the message */
6849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6850     {
6851       if (unformat (i, "bd_id %d", &bd_id))
6852         ;
6853       else
6854         break;
6855     }
6856
6857   M (BRIDGE_DOMAIN_DUMP, mp);
6858   mp->bd_id = ntohl (bd_id);
6859   S (mp);
6860
6861   /* Use a control ping for synchronization */
6862   MPING (CONTROL_PING, mp_ping);
6863   S (mp_ping);
6864
6865   W (ret);
6866   return ret;
6867 }
6868
6869 static int
6870 api_bridge_domain_add_del (vat_main_t * vam)
6871 {
6872   unformat_input_t *i = vam->input;
6873   vl_api_bridge_domain_add_del_t *mp;
6874   u32 bd_id = ~0;
6875   u8 is_add = 1;
6876   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6877   u8 *bd_tag = NULL;
6878   u32 mac_age = 0;
6879   int ret;
6880
6881   /* Parse args required to build the message */
6882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6883     {
6884       if (unformat (i, "bd_id %d", &bd_id))
6885         ;
6886       else if (unformat (i, "flood %d", &flood))
6887         ;
6888       else if (unformat (i, "uu-flood %d", &uu_flood))
6889         ;
6890       else if (unformat (i, "forward %d", &forward))
6891         ;
6892       else if (unformat (i, "learn %d", &learn))
6893         ;
6894       else if (unformat (i, "arp-term %d", &arp_term))
6895         ;
6896       else if (unformat (i, "mac-age %d", &mac_age))
6897         ;
6898       else if (unformat (i, "bd-tag %s", &bd_tag))
6899         ;
6900       else if (unformat (i, "del"))
6901         {
6902           is_add = 0;
6903           flood = uu_flood = forward = learn = 0;
6904         }
6905       else
6906         break;
6907     }
6908
6909   if (bd_id == ~0)
6910     {
6911       errmsg ("missing bridge domain");
6912       ret = -99;
6913       goto done;
6914     }
6915
6916   if (mac_age > 255)
6917     {
6918       errmsg ("mac age must be less than 256 ");
6919       ret = -99;
6920       goto done;
6921     }
6922
6923   if ((bd_tag) && (vec_len (bd_tag) > 63))
6924     {
6925       errmsg ("bd-tag cannot be longer than 63");
6926       ret = -99;
6927       goto done;
6928     }
6929
6930   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6931
6932   mp->bd_id = ntohl (bd_id);
6933   mp->flood = flood;
6934   mp->uu_flood = uu_flood;
6935   mp->forward = forward;
6936   mp->learn = learn;
6937   mp->arp_term = arp_term;
6938   mp->is_add = is_add;
6939   mp->mac_age = (u8) mac_age;
6940   if (bd_tag)
6941     {
6942       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6943       mp->bd_tag[vec_len (bd_tag)] = 0;
6944     }
6945   S (mp);
6946   W (ret);
6947
6948 done:
6949   vec_free (bd_tag);
6950   return ret;
6951 }
6952
6953 static int
6954 api_l2fib_flush_bd (vat_main_t * vam)
6955 {
6956   unformat_input_t *i = vam->input;
6957   vl_api_l2fib_flush_bd_t *mp;
6958   u32 bd_id = ~0;
6959   int ret;
6960
6961   /* Parse args required to build the message */
6962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6963     {
6964       if (unformat (i, "bd_id %d", &bd_id));
6965       else
6966         break;
6967     }
6968
6969   if (bd_id == ~0)
6970     {
6971       errmsg ("missing bridge domain");
6972       return -99;
6973     }
6974
6975   M (L2FIB_FLUSH_BD, mp);
6976
6977   mp->bd_id = htonl (bd_id);
6978
6979   S (mp);
6980   W (ret);
6981   return ret;
6982 }
6983
6984 static int
6985 api_l2fib_flush_int (vat_main_t * vam)
6986 {
6987   unformat_input_t *i = vam->input;
6988   vl_api_l2fib_flush_int_t *mp;
6989   u32 sw_if_index = ~0;
6990   int ret;
6991
6992   /* Parse args required to build the message */
6993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6994     {
6995       if (unformat (i, "sw_if_index %d", &sw_if_index));
6996       else
6997         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6998       else
6999         break;
7000     }
7001
7002   if (sw_if_index == ~0)
7003     {
7004       errmsg ("missing interface name or sw_if_index");
7005       return -99;
7006     }
7007
7008   M (L2FIB_FLUSH_INT, mp);
7009
7010   mp->sw_if_index = ntohl (sw_if_index);
7011
7012   S (mp);
7013   W (ret);
7014   return ret;
7015 }
7016
7017 static int
7018 api_l2fib_add_del (vat_main_t * vam)
7019 {
7020   unformat_input_t *i = vam->input;
7021   vl_api_l2fib_add_del_t *mp;
7022   f64 timeout;
7023   u8 mac[6] = { 0 };
7024   u8 mac_set = 0;
7025   u32 bd_id;
7026   u8 bd_id_set = 0;
7027   u32 sw_if_index = 0;
7028   u8 sw_if_index_set = 0;
7029   u8 is_add = 1;
7030   u8 static_mac = 0;
7031   u8 filter_mac = 0;
7032   u8 bvi_mac = 0;
7033   int count = 1;
7034   f64 before = 0;
7035   int j;
7036
7037   /* Parse args required to build the message */
7038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7039     {
7040       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7041         mac_set = 1;
7042       else if (unformat (i, "bd_id %d", &bd_id))
7043         bd_id_set = 1;
7044       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7045         sw_if_index_set = 1;
7046       else if (unformat (i, "sw_if"))
7047         {
7048           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049             {
7050               if (unformat
7051                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7052                 sw_if_index_set = 1;
7053             }
7054           else
7055             break;
7056         }
7057       else if (unformat (i, "static"))
7058         static_mac = 1;
7059       else if (unformat (i, "filter"))
7060         {
7061           filter_mac = 1;
7062           static_mac = 1;
7063         }
7064       else if (unformat (i, "bvi"))
7065         {
7066           bvi_mac = 1;
7067           static_mac = 1;
7068         }
7069       else if (unformat (i, "del"))
7070         is_add = 0;
7071       else if (unformat (i, "count %d", &count))
7072         ;
7073       else
7074         break;
7075     }
7076
7077   if (mac_set == 0)
7078     {
7079       errmsg ("missing mac address");
7080       return -99;
7081     }
7082
7083   if (bd_id_set == 0)
7084     {
7085       errmsg ("missing bridge domain");
7086       return -99;
7087     }
7088
7089   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7090     {
7091       errmsg ("missing interface name or sw_if_index");
7092       return -99;
7093     }
7094
7095   if (count > 1)
7096     {
7097       /* Turn on async mode */
7098       vam->async_mode = 1;
7099       vam->async_errors = 0;
7100       before = vat_time_now (vam);
7101     }
7102
7103   for (j = 0; j < count; j++)
7104     {
7105       M (L2FIB_ADD_DEL, mp);
7106
7107       clib_memcpy (mp->mac, mac, 6);
7108       mp->bd_id = ntohl (bd_id);
7109       mp->is_add = is_add;
7110       mp->sw_if_index = ntohl (sw_if_index);
7111
7112       if (is_add)
7113         {
7114           mp->static_mac = static_mac;
7115           mp->filter_mac = filter_mac;
7116           mp->bvi_mac = bvi_mac;
7117         }
7118       increment_mac_address (mac);
7119       /* send it... */
7120       S (mp);
7121     }
7122
7123   if (count > 1)
7124     {
7125       vl_api_control_ping_t *mp_ping;
7126       f64 after;
7127
7128       /* Shut off async mode */
7129       vam->async_mode = 0;
7130
7131       MPING (CONTROL_PING, mp_ping);
7132       S (mp_ping);
7133
7134       timeout = vat_time_now (vam) + 1.0;
7135       while (vat_time_now (vam) < timeout)
7136         if (vam->result_ready == 1)
7137           goto out;
7138       vam->retval = -99;
7139
7140     out:
7141       if (vam->retval == -99)
7142         errmsg ("timeout");
7143
7144       if (vam->async_errors > 0)
7145         {
7146           errmsg ("%d asynchronous errors", vam->async_errors);
7147           vam->retval = -98;
7148         }
7149       vam->async_errors = 0;
7150       after = vat_time_now (vam);
7151
7152       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7153              count, after - before, count / (after - before));
7154     }
7155   else
7156     {
7157       int ret;
7158
7159       /* Wait for a reply... */
7160       W (ret);
7161       return ret;
7162     }
7163   /* Return the good/bad news */
7164   return (vam->retval);
7165 }
7166
7167 static int
7168 api_bridge_domain_set_mac_age (vat_main_t * vam)
7169 {
7170   unformat_input_t *i = vam->input;
7171   vl_api_bridge_domain_set_mac_age_t *mp;
7172   u32 bd_id = ~0;
7173   u32 mac_age = 0;
7174   int ret;
7175
7176   /* Parse args required to build the message */
7177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7178     {
7179       if (unformat (i, "bd_id %d", &bd_id));
7180       else if (unformat (i, "mac-age %d", &mac_age));
7181       else
7182         break;
7183     }
7184
7185   if (bd_id == ~0)
7186     {
7187       errmsg ("missing bridge domain");
7188       return -99;
7189     }
7190
7191   if (mac_age > 255)
7192     {
7193       errmsg ("mac age must be less than 256 ");
7194       return -99;
7195     }
7196
7197   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7198
7199   mp->bd_id = htonl (bd_id);
7200   mp->mac_age = (u8) mac_age;
7201
7202   S (mp);
7203   W (ret);
7204   return ret;
7205 }
7206
7207 static int
7208 api_l2_flags (vat_main_t * vam)
7209 {
7210   unformat_input_t *i = vam->input;
7211   vl_api_l2_flags_t *mp;
7212   u32 sw_if_index;
7213   u32 flags = 0;
7214   u8 sw_if_index_set = 0;
7215   u8 is_set = 0;
7216   int ret;
7217
7218   /* Parse args required to build the message */
7219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7220     {
7221       if (unformat (i, "sw_if_index %d", &sw_if_index))
7222         sw_if_index_set = 1;
7223       else if (unformat (i, "sw_if"))
7224         {
7225           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226             {
7227               if (unformat
7228                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7229                 sw_if_index_set = 1;
7230             }
7231           else
7232             break;
7233         }
7234       else if (unformat (i, "learn"))
7235         flags |= L2_LEARN;
7236       else if (unformat (i, "forward"))
7237         flags |= L2_FWD;
7238       else if (unformat (i, "flood"))
7239         flags |= L2_FLOOD;
7240       else if (unformat (i, "uu-flood"))
7241         flags |= L2_UU_FLOOD;
7242       else if (unformat (i, "arp-term"))
7243         flags |= L2_ARP_TERM;
7244       else if (unformat (i, "off"))
7245         is_set = 0;
7246       else if (unformat (i, "disable"))
7247         is_set = 0;
7248       else
7249         break;
7250     }
7251
7252   if (sw_if_index_set == 0)
7253     {
7254       errmsg ("missing interface name or sw_if_index");
7255       return -99;
7256     }
7257
7258   M (L2_FLAGS, mp);
7259
7260   mp->sw_if_index = ntohl (sw_if_index);
7261   mp->feature_bitmap = ntohl (flags);
7262   mp->is_set = is_set;
7263
7264   S (mp);
7265   W (ret);
7266   return ret;
7267 }
7268
7269 static int
7270 api_bridge_flags (vat_main_t * vam)
7271 {
7272   unformat_input_t *i = vam->input;
7273   vl_api_bridge_flags_t *mp;
7274   u32 bd_id;
7275   u8 bd_id_set = 0;
7276   u8 is_set = 1;
7277   bd_flags_t flags = 0;
7278   int ret;
7279
7280   /* Parse args required to build the message */
7281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7282     {
7283       if (unformat (i, "bd_id %d", &bd_id))
7284         bd_id_set = 1;
7285       else if (unformat (i, "learn"))
7286         flags |= BRIDGE_API_FLAG_LEARN;
7287       else if (unformat (i, "forward"))
7288         flags |= BRIDGE_API_FLAG_FWD;
7289       else if (unformat (i, "flood"))
7290         flags |= BRIDGE_API_FLAG_FLOOD;
7291       else if (unformat (i, "uu-flood"))
7292         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7293       else if (unformat (i, "arp-term"))
7294         flags |= BRIDGE_API_FLAG_ARP_TERM;
7295       else if (unformat (i, "off"))
7296         is_set = 0;
7297       else if (unformat (i, "disable"))
7298         is_set = 0;
7299       else
7300         break;
7301     }
7302
7303   if (bd_id_set == 0)
7304     {
7305       errmsg ("missing bridge domain");
7306       return -99;
7307     }
7308
7309   M (BRIDGE_FLAGS, mp);
7310
7311   mp->bd_id = ntohl (bd_id);
7312   mp->flags = ntohl (flags);
7313   mp->is_set = is_set;
7314
7315   S (mp);
7316   W (ret);
7317   return ret;
7318 }
7319
7320 static int
7321 api_bd_ip_mac_add_del (vat_main_t * vam)
7322 {
7323   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7324   vl_api_mac_address_t mac = { 0 };
7325   unformat_input_t *i = vam->input;
7326   vl_api_bd_ip_mac_add_del_t *mp;
7327   ip46_type_t type;
7328   u32 bd_id;
7329   u8 is_ipv6 = 0;
7330   u8 is_add = 1;
7331   u8 bd_id_set = 0;
7332   u8 ip_set = 0;
7333   u8 mac_set = 0;
7334   u8 macaddr[6];
7335   int ret;
7336
7337
7338   /* Parse args required to build the message */
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "bd_id %d", &bd_id))
7342         {
7343           bd_id_set++;
7344         }
7345       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7346         {
7347           ip_set++;
7348         }
7349       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7350         {
7351           mac_set++;
7352         }
7353       else if (unformat (i, "del"))
7354         is_add = 0;
7355       else
7356         break;
7357     }
7358
7359   if (bd_id_set == 0)
7360     {
7361       errmsg ("missing bridge domain");
7362       return -99;
7363     }
7364   else if (ip_set == 0)
7365     {
7366       errmsg ("missing IP address");
7367       return -99;
7368     }
7369   else if (mac_set == 0)
7370     {
7371       errmsg ("missing MAC address");
7372       return -99;
7373     }
7374
7375   M (BD_IP_MAC_ADD_DEL, mp);
7376
7377   mp->bd_id = ntohl (bd_id);
7378   mp->is_add = is_add;
7379
7380   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7381   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7382
7383   S (mp);
7384   W (ret);
7385   return ret;
7386 }
7387
7388 static void vl_api_bd_ip_mac_details_t_handler
7389   (vl_api_bd_ip_mac_details_t * mp)
7390 {
7391   vat_main_t *vam = &vat_main;
7392   u8 *ip = 0;
7393
7394   if (!mp->is_ipv6)
7395     ip =
7396       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7397   else
7398     ip =
7399       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7400
7401   print (vam->ofp,
7402          "\n%-5d %-7s %-20U %-30s",
7403          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7404          format_ethernet_address, mp->mac_address, ip);
7405
7406   vec_free (ip);
7407 }
7408
7409 static void vl_api_bd_ip_mac_details_t_handler_json
7410   (vl_api_bd_ip_mac_details_t * mp)
7411 {
7412   vat_main_t *vam = &vat_main;
7413   vat_json_node_t *node = NULL;
7414
7415   if (VAT_JSON_ARRAY != vam->json_tree.type)
7416     {
7417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7418       vat_json_init_array (&vam->json_tree);
7419     }
7420   node = vat_json_array_add (&vam->json_tree);
7421
7422   vat_json_init_object (node);
7423   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7424   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7425   vat_json_object_add_string_copy (node, "mac_address",
7426                                    format (0, "%U", format_ethernet_address,
7427                                            &mp->mac_address));
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   vat_json_object_add_string_copy (node, "ip_address", ip);
7437   vec_free (ip);
7438 }
7439
7440 static int
7441 api_bd_ip_mac_dump (vat_main_t * vam)
7442 {
7443   unformat_input_t *i = vam->input;
7444   vl_api_bd_ip_mac_dump_t *mp;
7445   vl_api_control_ping_t *mp_ping;
7446   int ret;
7447   u32 bd_id;
7448   u8 bd_id_set = 0;
7449
7450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7451     {
7452       if (unformat (i, "bd_id %d", &bd_id))
7453         {
7454           bd_id_set++;
7455         }
7456       else
7457         break;
7458     }
7459
7460   print (vam->ofp,
7461          "\n%-5s %-7s %-20s %-30s",
7462          "bd_id", "is_ipv6", "mac_address", "ip_address");
7463
7464   /* Dump Bridge Domain Ip to Mac entries */
7465   M (BD_IP_MAC_DUMP, mp);
7466
7467   if (bd_id_set)
7468     mp->bd_id = htonl (bd_id);
7469   else
7470     mp->bd_id = ~0;
7471
7472   S (mp);
7473
7474   /* Use a control ping for synchronization */
7475   MPING (CONTROL_PING, mp_ping);
7476   S (mp_ping);
7477
7478   W (ret);
7479   return ret;
7480 }
7481
7482 static int
7483 api_tap_connect (vat_main_t * vam)
7484 {
7485   unformat_input_t *i = vam->input;
7486   vl_api_tap_connect_t *mp;
7487   u8 mac_address[6];
7488   u8 random_mac = 1;
7489   u8 name_set = 0;
7490   u8 *tap_name;
7491   u8 *tag = 0;
7492   ip4_address_t ip4_address;
7493   u32 ip4_mask_width;
7494   int ip4_address_set = 0;
7495   ip6_address_t ip6_address;
7496   u32 ip6_mask_width;
7497   int ip6_address_set = 0;
7498   int ret;
7499
7500   clib_memset (mac_address, 0, sizeof (mac_address));
7501
7502   /* Parse args required to build the message */
7503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7504     {
7505       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7506         {
7507           random_mac = 0;
7508         }
7509       else if (unformat (i, "random-mac"))
7510         random_mac = 1;
7511       else if (unformat (i, "tapname %s", &tap_name))
7512         name_set = 1;
7513       else if (unformat (i, "tag %s", &tag))
7514         ;
7515       else if (unformat (i, "address %U/%d",
7516                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7517         ip4_address_set = 1;
7518       else if (unformat (i, "address %U/%d",
7519                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7520         ip6_address_set = 1;
7521       else
7522         break;
7523     }
7524
7525   if (name_set == 0)
7526     {
7527       errmsg ("missing tap name");
7528       return -99;
7529     }
7530   if (vec_len (tap_name) > 63)
7531     {
7532       errmsg ("tap name too long");
7533       return -99;
7534     }
7535   vec_add1 (tap_name, 0);
7536
7537   if (vec_len (tag) > 63)
7538     {
7539       errmsg ("tag too long");
7540       return -99;
7541     }
7542
7543   /* Construct the API message */
7544   M (TAP_CONNECT, mp);
7545
7546   mp->use_random_mac = random_mac;
7547   clib_memcpy (mp->mac_address, mac_address, 6);
7548   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7549   if (tag)
7550     clib_memcpy (mp->tag, tag, vec_len (tag));
7551
7552   if (ip4_address_set)
7553     {
7554       mp->ip4_address_set = 1;
7555       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7556       mp->ip4_mask_width = ip4_mask_width;
7557     }
7558   if (ip6_address_set)
7559     {
7560       mp->ip6_address_set = 1;
7561       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7562       mp->ip6_mask_width = ip6_mask_width;
7563     }
7564
7565   vec_free (tap_name);
7566   vec_free (tag);
7567
7568   /* send it... */
7569   S (mp);
7570
7571   /* Wait for a reply... */
7572   W (ret);
7573   return ret;
7574 }
7575
7576 static int
7577 api_tap_modify (vat_main_t * vam)
7578 {
7579   unformat_input_t *i = vam->input;
7580   vl_api_tap_modify_t *mp;
7581   u8 mac_address[6];
7582   u8 random_mac = 1;
7583   u8 name_set = 0;
7584   u8 *tap_name;
7585   u32 sw_if_index = ~0;
7586   u8 sw_if_index_set = 0;
7587   int ret;
7588
7589   clib_memset (mac_address, 0, sizeof (mac_address));
7590
7591   /* Parse args required to build the message */
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7595         sw_if_index_set = 1;
7596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7597         sw_if_index_set = 1;
7598       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7599         {
7600           random_mac = 0;
7601         }
7602       else if (unformat (i, "random-mac"))
7603         random_mac = 1;
7604       else if (unformat (i, "tapname %s", &tap_name))
7605         name_set = 1;
7606       else
7607         break;
7608     }
7609
7610   if (sw_if_index_set == 0)
7611     {
7612       errmsg ("missing vpp interface name");
7613       return -99;
7614     }
7615   if (name_set == 0)
7616     {
7617       errmsg ("missing tap name");
7618       return -99;
7619     }
7620   if (vec_len (tap_name) > 63)
7621     {
7622       errmsg ("tap name too long");
7623     }
7624   vec_add1 (tap_name, 0);
7625
7626   /* Construct the API message */
7627   M (TAP_MODIFY, mp);
7628
7629   mp->use_random_mac = random_mac;
7630   mp->sw_if_index = ntohl (sw_if_index);
7631   clib_memcpy (mp->mac_address, mac_address, 6);
7632   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7633   vec_free (tap_name);
7634
7635   /* send it... */
7636   S (mp);
7637
7638   /* Wait for a reply... */
7639   W (ret);
7640   return ret;
7641 }
7642
7643 static int
7644 api_tap_delete (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_tap_delete_t *mp;
7648   u32 sw_if_index = ~0;
7649   u8 sw_if_index_set = 0;
7650   int ret;
7651
7652   /* Parse args required to build the message */
7653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7654     {
7655       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7656         sw_if_index_set = 1;
7657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7658         sw_if_index_set = 1;
7659       else
7660         break;
7661     }
7662
7663   if (sw_if_index_set == 0)
7664     {
7665       errmsg ("missing vpp interface name");
7666       return -99;
7667     }
7668
7669   /* Construct the API message */
7670   M (TAP_DELETE, mp);
7671
7672   mp->sw_if_index = ntohl (sw_if_index);
7673
7674   /* send it... */
7675   S (mp);
7676
7677   /* Wait for a reply... */
7678   W (ret);
7679   return ret;
7680 }
7681
7682 static int
7683 api_tap_create_v2 (vat_main_t * vam)
7684 {
7685   unformat_input_t *i = vam->input;
7686   vl_api_tap_create_v2_t *mp;
7687   u8 mac_address[6];
7688   u8 random_mac = 1;
7689   u32 id = ~0;
7690   u8 *host_if_name = 0;
7691   u8 *host_ns = 0;
7692   u8 host_mac_addr[6];
7693   u8 host_mac_addr_set = 0;
7694   u8 *host_bridge = 0;
7695   ip4_address_t host_ip4_addr;
7696   ip4_address_t host_ip4_gw;
7697   u8 host_ip4_gw_set = 0;
7698   u32 host_ip4_prefix_len = 0;
7699   ip6_address_t host_ip6_addr;
7700   ip6_address_t host_ip6_gw;
7701   u8 host_ip6_gw_set = 0;
7702   u32 host_ip6_prefix_len = 0;
7703   int ret;
7704   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7705
7706   clib_memset (mac_address, 0, sizeof (mac_address));
7707
7708   /* Parse args required to build the message */
7709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7710     {
7711       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7712         {
7713           random_mac = 0;
7714         }
7715       else if (unformat (i, "id %u", &id))
7716         ;
7717       else if (unformat (i, "host-if-name %s", &host_if_name))
7718         ;
7719       else if (unformat (i, "host-ns %s", &host_ns))
7720         ;
7721       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7722                          host_mac_addr))
7723         host_mac_addr_set = 1;
7724       else if (unformat (i, "host-bridge %s", &host_bridge))
7725         ;
7726       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7727                          &host_ip4_addr, &host_ip4_prefix_len))
7728         ;
7729       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7730                          &host_ip6_addr, &host_ip6_prefix_len))
7731         ;
7732       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7733                          &host_ip4_gw))
7734         host_ip4_gw_set = 1;
7735       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7736                          &host_ip6_gw))
7737         host_ip6_gw_set = 1;
7738       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7739         ;
7740       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7741         ;
7742       else
7743         break;
7744     }
7745
7746   if (vec_len (host_if_name) > 63)
7747     {
7748       errmsg ("tap name too long. ");
7749       return -99;
7750     }
7751   if (vec_len (host_ns) > 63)
7752     {
7753       errmsg ("host name space too long. ");
7754       return -99;
7755     }
7756   if (vec_len (host_bridge) > 63)
7757     {
7758       errmsg ("host bridge name too long. ");
7759       return -99;
7760     }
7761   if (host_ip4_prefix_len > 32)
7762     {
7763       errmsg ("host ip4 prefix length not valid. ");
7764       return -99;
7765     }
7766   if (host_ip6_prefix_len > 128)
7767     {
7768       errmsg ("host ip6 prefix length not valid. ");
7769       return -99;
7770     }
7771   if (!is_pow2 (rx_ring_sz))
7772     {
7773       errmsg ("rx ring size must be power of 2. ");
7774       return -99;
7775     }
7776   if (rx_ring_sz > 32768)
7777     {
7778       errmsg ("rx ring size must be 32768 or lower. ");
7779       return -99;
7780     }
7781   if (!is_pow2 (tx_ring_sz))
7782     {
7783       errmsg ("tx ring size must be power of 2. ");
7784       return -99;
7785     }
7786   if (tx_ring_sz > 32768)
7787     {
7788       errmsg ("tx ring size must be 32768 or lower. ");
7789       return -99;
7790     }
7791
7792   /* Construct the API message */
7793   M (TAP_CREATE_V2, mp);
7794
7795   mp->use_random_mac = random_mac;
7796
7797   mp->id = ntohl (id);
7798   mp->host_namespace_set = host_ns != 0;
7799   mp->host_bridge_set = host_bridge != 0;
7800   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7801   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7802   mp->rx_ring_sz = ntohs (rx_ring_sz);
7803   mp->tx_ring_sz = ntohs (tx_ring_sz);
7804
7805   if (random_mac == 0)
7806     clib_memcpy (mp->mac_address, mac_address, 6);
7807   if (host_mac_addr_set)
7808     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7809   if (host_if_name)
7810     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7811   if (host_ns)
7812     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7813   if (host_bridge)
7814     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7815   if (host_ip4_prefix_len)
7816     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7817   if (host_ip6_prefix_len)
7818     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7819   if (host_ip4_gw_set)
7820     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7821   if (host_ip6_gw_set)
7822     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7823
7824   vec_free (host_ns);
7825   vec_free (host_if_name);
7826   vec_free (host_bridge);
7827
7828   /* send it... */
7829   S (mp);
7830
7831   /* Wait for a reply... */
7832   W (ret);
7833   return ret;
7834 }
7835
7836 static int
7837 api_tap_delete_v2 (vat_main_t * vam)
7838 {
7839   unformat_input_t *i = vam->input;
7840   vl_api_tap_delete_v2_t *mp;
7841   u32 sw_if_index = ~0;
7842   u8 sw_if_index_set = 0;
7843   int ret;
7844
7845   /* Parse args required to build the message */
7846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7847     {
7848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7849         sw_if_index_set = 1;
7850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7851         sw_if_index_set = 1;
7852       else
7853         break;
7854     }
7855
7856   if (sw_if_index_set == 0)
7857     {
7858       errmsg ("missing vpp interface name. ");
7859       return -99;
7860     }
7861
7862   /* Construct the API message */
7863   M (TAP_DELETE_V2, mp);
7864
7865   mp->sw_if_index = ntohl (sw_if_index);
7866
7867   /* send it... */
7868   S (mp);
7869
7870   /* Wait for a reply... */
7871   W (ret);
7872   return ret;
7873 }
7874
7875 static int
7876 api_bond_create (vat_main_t * vam)
7877 {
7878   unformat_input_t *i = vam->input;
7879   vl_api_bond_create_t *mp;
7880   u8 mac_address[6];
7881   u8 custom_mac = 0;
7882   int ret;
7883   u8 mode;
7884   u8 lb;
7885   u8 mode_is_set = 0;
7886
7887   clib_memset (mac_address, 0, sizeof (mac_address));
7888   lb = BOND_LB_L2;
7889
7890   /* Parse args required to build the message */
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7894         mode_is_set = 1;
7895       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7896                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7897         ;
7898       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7899                          mac_address))
7900         custom_mac = 1;
7901       else
7902         break;
7903     }
7904
7905   if (mode_is_set == 0)
7906     {
7907       errmsg ("Missing bond mode. ");
7908       return -99;
7909     }
7910
7911   /* Construct the API message */
7912   M (BOND_CREATE, mp);
7913
7914   mp->use_custom_mac = custom_mac;
7915
7916   mp->mode = mode;
7917   mp->lb = lb;
7918
7919   if (custom_mac)
7920     clib_memcpy (mp->mac_address, mac_address, 6);
7921
7922   /* send it... */
7923   S (mp);
7924
7925   /* Wait for a reply... */
7926   W (ret);
7927   return ret;
7928 }
7929
7930 static int
7931 api_bond_delete (vat_main_t * vam)
7932 {
7933   unformat_input_t *i = vam->input;
7934   vl_api_bond_delete_t *mp;
7935   u32 sw_if_index = ~0;
7936   u8 sw_if_index_set = 0;
7937   int ret;
7938
7939   /* Parse args required to build the message */
7940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7941     {
7942       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7943         sw_if_index_set = 1;
7944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7945         sw_if_index_set = 1;
7946       else
7947         break;
7948     }
7949
7950   if (sw_if_index_set == 0)
7951     {
7952       errmsg ("missing vpp interface name. ");
7953       return -99;
7954     }
7955
7956   /* Construct the API message */
7957   M (BOND_DELETE, mp);
7958
7959   mp->sw_if_index = ntohl (sw_if_index);
7960
7961   /* send it... */
7962   S (mp);
7963
7964   /* Wait for a reply... */
7965   W (ret);
7966   return ret;
7967 }
7968
7969 static int
7970 api_bond_enslave (vat_main_t * vam)
7971 {
7972   unformat_input_t *i = vam->input;
7973   vl_api_bond_enslave_t *mp;
7974   u32 bond_sw_if_index;
7975   int ret;
7976   u8 is_passive;
7977   u8 is_long_timeout;
7978   u32 bond_sw_if_index_is_set = 0;
7979   u32 sw_if_index;
7980   u8 sw_if_index_is_set = 0;
7981
7982   /* Parse args required to build the message */
7983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7984     {
7985       if (unformat (i, "sw_if_index %d", &sw_if_index))
7986         sw_if_index_is_set = 1;
7987       else if (unformat (i, "bond %u", &bond_sw_if_index))
7988         bond_sw_if_index_is_set = 1;
7989       else if (unformat (i, "passive %d", &is_passive))
7990         ;
7991       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7992         ;
7993       else
7994         break;
7995     }
7996
7997   if (bond_sw_if_index_is_set == 0)
7998     {
7999       errmsg ("Missing bond sw_if_index. ");
8000       return -99;
8001     }
8002   if (sw_if_index_is_set == 0)
8003     {
8004       errmsg ("Missing slave sw_if_index. ");
8005       return -99;
8006     }
8007
8008   /* Construct the API message */
8009   M (BOND_ENSLAVE, mp);
8010
8011   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8012   mp->sw_if_index = ntohl (sw_if_index);
8013   mp->is_long_timeout = is_long_timeout;
8014   mp->is_passive = is_passive;
8015
8016   /* send it... */
8017   S (mp);
8018
8019   /* Wait for a reply... */
8020   W (ret);
8021   return ret;
8022 }
8023
8024 static int
8025 api_bond_detach_slave (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_bond_detach_slave_t *mp;
8029   u32 sw_if_index = ~0;
8030   u8 sw_if_index_set = 0;
8031   int ret;
8032
8033   /* Parse args required to build the message */
8034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8035     {
8036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8037         sw_if_index_set = 1;
8038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8039         sw_if_index_set = 1;
8040       else
8041         break;
8042     }
8043
8044   if (sw_if_index_set == 0)
8045     {
8046       errmsg ("missing vpp interface name. ");
8047       return -99;
8048     }
8049
8050   /* Construct the API message */
8051   M (BOND_DETACH_SLAVE, mp);
8052
8053   mp->sw_if_index = ntohl (sw_if_index);
8054
8055   /* send it... */
8056   S (mp);
8057
8058   /* Wait for a reply... */
8059   W (ret);
8060   return ret;
8061 }
8062
8063 static int
8064 api_ip_table_add_del (vat_main_t * vam)
8065 {
8066   unformat_input_t *i = vam->input;
8067   vl_api_ip_table_add_del_t *mp;
8068   u32 table_id = ~0;
8069   u8 is_ipv6 = 0;
8070   u8 is_add = 1;
8071   int ret = 0;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "ipv6"))
8077         is_ipv6 = 1;
8078       else if (unformat (i, "del"))
8079         is_add = 0;
8080       else if (unformat (i, "add"))
8081         is_add = 1;
8082       else if (unformat (i, "table %d", &table_id))
8083         ;
8084       else
8085         {
8086           clib_warning ("parse error '%U'", format_unformat_error, i);
8087           return -99;
8088         }
8089     }
8090
8091   if (~0 == table_id)
8092     {
8093       errmsg ("missing table-ID");
8094       return -99;
8095     }
8096
8097   /* Construct the API message */
8098   M (IP_TABLE_ADD_DEL, mp);
8099
8100   mp->table_id = ntohl (table_id);
8101   mp->is_ipv6 = is_ipv6;
8102   mp->is_add = is_add;
8103
8104   /* send it... */
8105   S (mp);
8106
8107   /* Wait for a reply... */
8108   W (ret);
8109
8110   return ret;
8111 }
8112
8113 static int
8114 api_ip_add_del_route (vat_main_t * vam)
8115 {
8116   unformat_input_t *i = vam->input;
8117   vl_api_ip_add_del_route_t *mp;
8118   u32 sw_if_index = ~0, vrf_id = 0;
8119   u8 is_ipv6 = 0;
8120   u8 is_local = 0, is_drop = 0;
8121   u8 is_unreach = 0, is_prohibit = 0;
8122   u8 is_add = 1;
8123   u32 next_hop_weight = 1;
8124   u8 is_multipath = 0;
8125   u8 address_set = 0;
8126   u8 address_length_set = 0;
8127   u32 next_hop_table_id = 0;
8128   u32 resolve_attempts = 0;
8129   u32 dst_address_length = 0;
8130   u8 next_hop_set = 0;
8131   ip4_address_t v4_dst_address, v4_next_hop_address;
8132   ip6_address_t v6_dst_address, v6_next_hop_address;
8133   int count = 1;
8134   int j;
8135   f64 before = 0;
8136   u32 random_add_del = 0;
8137   u32 *random_vector = 0;
8138   uword *random_hash;
8139   u32 random_seed = 0xdeaddabe;
8140   u32 classify_table_index = ~0;
8141   u8 is_classify = 0;
8142   u8 resolve_host = 0, resolve_attached = 0;
8143   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8144   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8145   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8146
8147   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8148   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8149   /* Parse args required to build the message */
8150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8151     {
8152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8153         ;
8154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8155         ;
8156       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8157         {
8158           address_set = 1;
8159           is_ipv6 = 0;
8160         }
8161       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8162         {
8163           address_set = 1;
8164           is_ipv6 = 1;
8165         }
8166       else if (unformat (i, "/%d", &dst_address_length))
8167         {
8168           address_length_set = 1;
8169         }
8170
8171       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8172                                          &v4_next_hop_address))
8173         {
8174           next_hop_set = 1;
8175         }
8176       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8177                                          &v6_next_hop_address))
8178         {
8179           next_hop_set = 1;
8180         }
8181       else
8182         if (unformat
8183             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8184         {
8185           next_hop_set = 1;
8186         }
8187       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8188         {
8189           next_hop_set = 1;
8190         }
8191       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8192         ;
8193       else if (unformat (i, "weight %d", &next_hop_weight))
8194         ;
8195       else if (unformat (i, "drop"))
8196         {
8197           is_drop = 1;
8198         }
8199       else if (unformat (i, "null-send-unreach"))
8200         {
8201           is_unreach = 1;
8202         }
8203       else if (unformat (i, "null-send-prohibit"))
8204         {
8205           is_prohibit = 1;
8206         }
8207       else if (unformat (i, "local"))
8208         {
8209           is_local = 1;
8210         }
8211       else if (unformat (i, "classify %d", &classify_table_index))
8212         {
8213           is_classify = 1;
8214         }
8215       else if (unformat (i, "del"))
8216         is_add = 0;
8217       else if (unformat (i, "add"))
8218         is_add = 1;
8219       else if (unformat (i, "resolve-via-host"))
8220         resolve_host = 1;
8221       else if (unformat (i, "resolve-via-attached"))
8222         resolve_attached = 1;
8223       else if (unformat (i, "multipath"))
8224         is_multipath = 1;
8225       else if (unformat (i, "vrf %d", &vrf_id))
8226         ;
8227       else if (unformat (i, "count %d", &count))
8228         ;
8229       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8230         ;
8231       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8232         ;
8233       else if (unformat (i, "out-label %d", &next_hop_out_label))
8234         {
8235           vl_api_fib_mpls_label_t fib_label = {
8236             .label = ntohl (next_hop_out_label),
8237             .ttl = 64,
8238             .exp = 0,
8239           };
8240           vec_add1 (next_hop_out_label_stack, fib_label);
8241         }
8242       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8243         ;
8244       else if (unformat (i, "random"))
8245         random_add_del = 1;
8246       else if (unformat (i, "seed %d", &random_seed))
8247         ;
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (!next_hop_set && !is_drop && !is_local &&
8256       !is_classify && !is_unreach && !is_prohibit &&
8257       MPLS_LABEL_INVALID == next_hop_via_label)
8258     {
8259       errmsg
8260         ("next hop / local / drop / unreach / prohibit / classify not set");
8261       return -99;
8262     }
8263
8264   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8265     {
8266       errmsg ("next hop and next-hop via label set");
8267       return -99;
8268     }
8269   if (address_set == 0)
8270     {
8271       errmsg ("missing addresses");
8272       return -99;
8273     }
8274
8275   if (address_length_set == 0)
8276     {
8277       errmsg ("missing address length");
8278       return -99;
8279     }
8280
8281   /* Generate a pile of unique, random routes */
8282   if (random_add_del)
8283     {
8284       u32 this_random_address;
8285       random_hash = hash_create (count, sizeof (uword));
8286
8287       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8288       for (j = 0; j <= count; j++)
8289         {
8290           do
8291             {
8292               this_random_address = random_u32 (&random_seed);
8293               this_random_address =
8294                 clib_host_to_net_u32 (this_random_address);
8295             }
8296           while (hash_get (random_hash, this_random_address));
8297           vec_add1 (random_vector, this_random_address);
8298           hash_set (random_hash, this_random_address, 1);
8299         }
8300       hash_free (random_hash);
8301       v4_dst_address.as_u32 = random_vector[0];
8302     }
8303
8304   if (count > 1)
8305     {
8306       /* Turn on async mode */
8307       vam->async_mode = 1;
8308       vam->async_errors = 0;
8309       before = vat_time_now (vam);
8310     }
8311
8312   for (j = 0; j < count; j++)
8313     {
8314       /* Construct the API message */
8315       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8316           vec_len (next_hop_out_label_stack));
8317
8318       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8319       mp->table_id = ntohl (vrf_id);
8320
8321       mp->is_add = is_add;
8322       mp->is_drop = is_drop;
8323       mp->is_unreach = is_unreach;
8324       mp->is_prohibit = is_prohibit;
8325       mp->is_ipv6 = is_ipv6;
8326       mp->is_local = is_local;
8327       mp->is_classify = is_classify;
8328       mp->is_multipath = is_multipath;
8329       mp->is_resolve_host = resolve_host;
8330       mp->is_resolve_attached = resolve_attached;
8331       mp->next_hop_weight = next_hop_weight;
8332       mp->next_hop_preference = 0;
8333       mp->dst_address_length = dst_address_length;
8334       mp->next_hop_table_id = ntohl (next_hop_table_id);
8335       mp->classify_table_index = ntohl (classify_table_index);
8336       mp->next_hop_via_label = ntohl (next_hop_via_label);
8337       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8338       if (0 != mp->next_hop_n_out_labels)
8339         {
8340           memcpy (mp->next_hop_out_label_stack,
8341                   next_hop_out_label_stack,
8342                   (vec_len (next_hop_out_label_stack) *
8343                    sizeof (vl_api_fib_mpls_label_t)));
8344           vec_free (next_hop_out_label_stack);
8345         }
8346
8347       if (is_ipv6)
8348         {
8349           clib_memcpy (mp->dst_address, &v6_dst_address,
8350                        sizeof (v6_dst_address));
8351           if (next_hop_set)
8352             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8353                          sizeof (v6_next_hop_address));
8354           increment_v6_address (&v6_dst_address);
8355         }
8356       else
8357         {
8358           clib_memcpy (mp->dst_address, &v4_dst_address,
8359                        sizeof (v4_dst_address));
8360           if (next_hop_set)
8361             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8362                          sizeof (v4_next_hop_address));
8363           if (random_add_del)
8364             v4_dst_address.as_u32 = random_vector[j + 1];
8365           else
8366             increment_v4_address (&v4_dst_address);
8367         }
8368       /* send it... */
8369       S (mp);
8370       /* If we receive SIGTERM, stop now... */
8371       if (vam->do_exit)
8372         break;
8373     }
8374
8375   /* When testing multiple add/del ops, use a control-ping to sync */
8376   if (count > 1)
8377     {
8378       vl_api_control_ping_t *mp_ping;
8379       f64 after;
8380       f64 timeout;
8381
8382       /* Shut off async mode */
8383       vam->async_mode = 0;
8384
8385       MPING (CONTROL_PING, mp_ping);
8386       S (mp_ping);
8387
8388       timeout = vat_time_now (vam) + 1.0;
8389       while (vat_time_now (vam) < timeout)
8390         if (vam->result_ready == 1)
8391           goto out;
8392       vam->retval = -99;
8393
8394     out:
8395       if (vam->retval == -99)
8396         errmsg ("timeout");
8397
8398       if (vam->async_errors > 0)
8399         {
8400           errmsg ("%d asynchronous errors", vam->async_errors);
8401           vam->retval = -98;
8402         }
8403       vam->async_errors = 0;
8404       after = vat_time_now (vam);
8405
8406       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8407       if (j > 0)
8408         count = j;
8409
8410       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8411              count, after - before, count / (after - before));
8412     }
8413   else
8414     {
8415       int ret;
8416
8417       /* Wait for a reply... */
8418       W (ret);
8419       return ret;
8420     }
8421
8422   /* Return the good/bad news */
8423   return (vam->retval);
8424 }
8425
8426 static int
8427 api_ip_mroute_add_del (vat_main_t * vam)
8428 {
8429   unformat_input_t *i = vam->input;
8430   vl_api_ip_mroute_add_del_t *mp;
8431   u32 sw_if_index = ~0, vrf_id = 0;
8432   u8 is_ipv6 = 0;
8433   u8 is_local = 0;
8434   u8 is_add = 1;
8435   u8 address_set = 0;
8436   u32 grp_address_length = 0;
8437   ip4_address_t v4_grp_address, v4_src_address;
8438   ip6_address_t v6_grp_address, v6_src_address;
8439   mfib_itf_flags_t iflags = 0;
8440   mfib_entry_flags_t eflags = 0;
8441   int ret;
8442
8443   /* Parse args required to build the message */
8444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8445     {
8446       if (unformat (i, "sw_if_index %d", &sw_if_index))
8447         ;
8448       else if (unformat (i, "%U %U",
8449                          unformat_ip4_address, &v4_src_address,
8450                          unformat_ip4_address, &v4_grp_address))
8451         {
8452           grp_address_length = 64;
8453           address_set = 1;
8454           is_ipv6 = 0;
8455         }
8456       else if (unformat (i, "%U %U",
8457                          unformat_ip6_address, &v6_src_address,
8458                          unformat_ip6_address, &v6_grp_address))
8459         {
8460           grp_address_length = 256;
8461           address_set = 1;
8462           is_ipv6 = 1;
8463         }
8464       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8465         {
8466           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8467           grp_address_length = 32;
8468           address_set = 1;
8469           is_ipv6 = 0;
8470         }
8471       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8472         {
8473           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8474           grp_address_length = 128;
8475           address_set = 1;
8476           is_ipv6 = 1;
8477         }
8478       else if (unformat (i, "/%d", &grp_address_length))
8479         ;
8480       else if (unformat (i, "local"))
8481         {
8482           is_local = 1;
8483         }
8484       else if (unformat (i, "del"))
8485         is_add = 0;
8486       else if (unformat (i, "add"))
8487         is_add = 1;
8488       else if (unformat (i, "vrf %d", &vrf_id))
8489         ;
8490       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8491         ;
8492       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8493         ;
8494       else
8495         {
8496           clib_warning ("parse error '%U'", format_unformat_error, i);
8497           return -99;
8498         }
8499     }
8500
8501   if (address_set == 0)
8502     {
8503       errmsg ("missing addresses\n");
8504       return -99;
8505     }
8506
8507   /* Construct the API message */
8508   M (IP_MROUTE_ADD_DEL, mp);
8509
8510   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8511   mp->table_id = ntohl (vrf_id);
8512
8513   mp->is_add = is_add;
8514   mp->is_ipv6 = is_ipv6;
8515   mp->is_local = is_local;
8516   mp->itf_flags = ntohl (iflags);
8517   mp->entry_flags = ntohl (eflags);
8518   mp->grp_address_length = grp_address_length;
8519   mp->grp_address_length = ntohs (mp->grp_address_length);
8520
8521   if (is_ipv6)
8522     {
8523       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8524       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8525     }
8526   else
8527     {
8528       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8529       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8530
8531     }
8532
8533   /* send it... */
8534   S (mp);
8535   /* Wait for a reply... */
8536   W (ret);
8537   return ret;
8538 }
8539
8540 static int
8541 api_mpls_table_add_del (vat_main_t * vam)
8542 {
8543   unformat_input_t *i = vam->input;
8544   vl_api_mpls_table_add_del_t *mp;
8545   u32 table_id = ~0;
8546   u8 is_add = 1;
8547   int ret = 0;
8548
8549   /* Parse args required to build the message */
8550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (i, "table %d", &table_id))
8553         ;
8554       else if (unformat (i, "del"))
8555         is_add = 0;
8556       else if (unformat (i, "add"))
8557         is_add = 1;
8558       else
8559         {
8560           clib_warning ("parse error '%U'", format_unformat_error, i);
8561           return -99;
8562         }
8563     }
8564
8565   if (~0 == table_id)
8566     {
8567       errmsg ("missing table-ID");
8568       return -99;
8569     }
8570
8571   /* Construct the API message */
8572   M (MPLS_TABLE_ADD_DEL, mp);
8573
8574   mp->mt_table_id = ntohl (table_id);
8575   mp->mt_is_add = is_add;
8576
8577   /* send it... */
8578   S (mp);
8579
8580   /* Wait for a reply... */
8581   W (ret);
8582
8583   return ret;
8584 }
8585
8586 static int
8587 api_mpls_route_add_del (vat_main_t * vam)
8588 {
8589   unformat_input_t *i = vam->input;
8590   vl_api_mpls_route_add_del_t *mp;
8591   u32 sw_if_index = ~0, table_id = 0;
8592   u8 is_add = 1;
8593   u32 next_hop_weight = 1;
8594   u8 is_multipath = 0;
8595   u32 next_hop_table_id = 0;
8596   u8 next_hop_set = 0;
8597   ip4_address_t v4_next_hop_address = {
8598     .as_u32 = 0,
8599   };
8600   ip6_address_t v6_next_hop_address = { {0} };
8601   int count = 1;
8602   int j;
8603   f64 before = 0;
8604   u32 classify_table_index = ~0;
8605   u8 is_classify = 0;
8606   u8 resolve_host = 0, resolve_attached = 0;
8607   u8 is_interface_rx = 0;
8608   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8609   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8610   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8611   mpls_label_t local_label = MPLS_LABEL_INVALID;
8612   u8 is_eos = 0;
8613   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8614
8615   /* Parse args required to build the message */
8616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8617     {
8618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8619         ;
8620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8621         ;
8622       else if (unformat (i, "%d", &local_label))
8623         ;
8624       else if (unformat (i, "eos"))
8625         is_eos = 1;
8626       else if (unformat (i, "non-eos"))
8627         is_eos = 0;
8628       else if (unformat (i, "via %U", unformat_ip4_address,
8629                          &v4_next_hop_address))
8630         {
8631           next_hop_set = 1;
8632           next_hop_proto = DPO_PROTO_IP4;
8633         }
8634       else if (unformat (i, "via %U", unformat_ip6_address,
8635                          &v6_next_hop_address))
8636         {
8637           next_hop_set = 1;
8638           next_hop_proto = DPO_PROTO_IP6;
8639         }
8640       else if (unformat (i, "weight %d", &next_hop_weight))
8641         ;
8642       else if (unformat (i, "classify %d", &classify_table_index))
8643         {
8644           is_classify = 1;
8645         }
8646       else if (unformat (i, "del"))
8647         is_add = 0;
8648       else if (unformat (i, "add"))
8649         is_add = 1;
8650       else if (unformat (i, "resolve-via-host"))
8651         resolve_host = 1;
8652       else if (unformat (i, "resolve-via-attached"))
8653         resolve_attached = 1;
8654       else if (unformat (i, "multipath"))
8655         is_multipath = 1;
8656       else if (unformat (i, "count %d", &count))
8657         ;
8658       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8659         {
8660           next_hop_set = 1;
8661           next_hop_proto = DPO_PROTO_IP4;
8662         }
8663       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8664         {
8665           next_hop_set = 1;
8666           next_hop_proto = DPO_PROTO_IP6;
8667         }
8668       else
8669         if (unformat
8670             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8671              &sw_if_index))
8672         {
8673           next_hop_set = 1;
8674           next_hop_proto = DPO_PROTO_ETHERNET;
8675           is_interface_rx = 1;
8676         }
8677       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8678         {
8679           next_hop_set = 1;
8680           next_hop_proto = DPO_PROTO_ETHERNET;
8681           is_interface_rx = 1;
8682         }
8683       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8684         next_hop_set = 1;
8685       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8686         next_hop_set = 1;
8687       else if (unformat (i, "out-label %d", &next_hop_out_label))
8688         {
8689           vl_api_fib_mpls_label_t fib_label = {
8690             .label = ntohl (next_hop_out_label),
8691             .ttl = 64,
8692             .exp = 0,
8693           };
8694           vec_add1 (next_hop_out_label_stack, fib_label);
8695         }
8696       else
8697         {
8698           clib_warning ("parse error '%U'", format_unformat_error, i);
8699           return -99;
8700         }
8701     }
8702
8703   if (!next_hop_set && !is_classify)
8704     {
8705       errmsg ("next hop / classify not set");
8706       return -99;
8707     }
8708
8709   if (MPLS_LABEL_INVALID == local_label)
8710     {
8711       errmsg ("missing label");
8712       return -99;
8713     }
8714
8715   if (count > 1)
8716     {
8717       /* Turn on async mode */
8718       vam->async_mode = 1;
8719       vam->async_errors = 0;
8720       before = vat_time_now (vam);
8721     }
8722
8723   for (j = 0; j < count; j++)
8724     {
8725       /* Construct the API message */
8726       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8727           vec_len (next_hop_out_label_stack));
8728
8729       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8730       mp->mr_table_id = ntohl (table_id);
8731
8732       mp->mr_is_add = is_add;
8733       mp->mr_next_hop_proto = next_hop_proto;
8734       mp->mr_is_classify = is_classify;
8735       mp->mr_is_multipath = is_multipath;
8736       mp->mr_is_resolve_host = resolve_host;
8737       mp->mr_is_resolve_attached = resolve_attached;
8738       mp->mr_is_interface_rx = is_interface_rx;
8739       mp->mr_next_hop_weight = next_hop_weight;
8740       mp->mr_next_hop_preference = 0;
8741       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8742       mp->mr_classify_table_index = ntohl (classify_table_index);
8743       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8744       mp->mr_label = ntohl (local_label);
8745       mp->mr_eos = is_eos;
8746
8747       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8748       if (0 != mp->mr_next_hop_n_out_labels)
8749         {
8750           memcpy (mp->mr_next_hop_out_label_stack,
8751                   next_hop_out_label_stack,
8752                   vec_len (next_hop_out_label_stack) *
8753                   sizeof (vl_api_fib_mpls_label_t));
8754           vec_free (next_hop_out_label_stack);
8755         }
8756
8757       if (next_hop_set)
8758         {
8759           if (DPO_PROTO_IP4 == next_hop_proto)
8760             {
8761               clib_memcpy (mp->mr_next_hop,
8762                            &v4_next_hop_address,
8763                            sizeof (v4_next_hop_address));
8764             }
8765           else if (DPO_PROTO_IP6 == next_hop_proto)
8766
8767             {
8768               clib_memcpy (mp->mr_next_hop,
8769                            &v6_next_hop_address,
8770                            sizeof (v6_next_hop_address));
8771             }
8772         }
8773       local_label++;
8774
8775       /* send it... */
8776       S (mp);
8777       /* If we receive SIGTERM, stop now... */
8778       if (vam->do_exit)
8779         break;
8780     }
8781
8782   /* When testing multiple add/del ops, use a control-ping to sync */
8783   if (count > 1)
8784     {
8785       vl_api_control_ping_t *mp_ping;
8786       f64 after;
8787       f64 timeout;
8788
8789       /* Shut off async mode */
8790       vam->async_mode = 0;
8791
8792       MPING (CONTROL_PING, mp_ping);
8793       S (mp_ping);
8794
8795       timeout = vat_time_now (vam) + 1.0;
8796       while (vat_time_now (vam) < timeout)
8797         if (vam->result_ready == 1)
8798           goto out;
8799       vam->retval = -99;
8800
8801     out:
8802       if (vam->retval == -99)
8803         errmsg ("timeout");
8804
8805       if (vam->async_errors > 0)
8806         {
8807           errmsg ("%d asynchronous errors", vam->async_errors);
8808           vam->retval = -98;
8809         }
8810       vam->async_errors = 0;
8811       after = vat_time_now (vam);
8812
8813       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8814       if (j > 0)
8815         count = j;
8816
8817       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8818              count, after - before, count / (after - before));
8819     }
8820   else
8821     {
8822       int ret;
8823
8824       /* Wait for a reply... */
8825       W (ret);
8826       return ret;
8827     }
8828
8829   /* Return the good/bad news */
8830   return (vam->retval);
8831 }
8832
8833 static int
8834 api_mpls_ip_bind_unbind (vat_main_t * vam)
8835 {
8836   unformat_input_t *i = vam->input;
8837   vl_api_mpls_ip_bind_unbind_t *mp;
8838   u32 ip_table_id = 0;
8839   u8 is_bind = 1;
8840   u8 is_ip4 = 1;
8841   ip4_address_t v4_address;
8842   ip6_address_t v6_address;
8843   u32 address_length;
8844   u8 address_set = 0;
8845   mpls_label_t local_label = MPLS_LABEL_INVALID;
8846   int ret;
8847
8848   /* Parse args required to build the message */
8849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8850     {
8851       if (unformat (i, "%U/%d", unformat_ip4_address,
8852                     &v4_address, &address_length))
8853         {
8854           is_ip4 = 1;
8855           address_set = 1;
8856         }
8857       else if (unformat (i, "%U/%d", unformat_ip6_address,
8858                          &v6_address, &address_length))
8859         {
8860           is_ip4 = 0;
8861           address_set = 1;
8862         }
8863       else if (unformat (i, "%d", &local_label))
8864         ;
8865       else if (unformat (i, "table-id %d", &ip_table_id))
8866         ;
8867       else if (unformat (i, "unbind"))
8868         is_bind = 0;
8869       else if (unformat (i, "bind"))
8870         is_bind = 1;
8871       else
8872         {
8873           clib_warning ("parse error '%U'", format_unformat_error, i);
8874           return -99;
8875         }
8876     }
8877
8878   if (!address_set)
8879     {
8880       errmsg ("IP address not set");
8881       return -99;
8882     }
8883
8884   if (MPLS_LABEL_INVALID == local_label)
8885     {
8886       errmsg ("missing label");
8887       return -99;
8888     }
8889
8890   /* Construct the API message */
8891   M (MPLS_IP_BIND_UNBIND, mp);
8892
8893   mp->mb_is_bind = is_bind;
8894   mp->mb_is_ip4 = is_ip4;
8895   mp->mb_ip_table_id = ntohl (ip_table_id);
8896   mp->mb_mpls_table_id = 0;
8897   mp->mb_label = ntohl (local_label);
8898   mp->mb_address_length = address_length;
8899
8900   if (is_ip4)
8901     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8902   else
8903     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8904
8905   /* send it... */
8906   S (mp);
8907
8908   /* Wait for a reply... */
8909   W (ret);
8910   return ret;
8911 }
8912
8913 static int
8914 api_sr_mpls_policy_add (vat_main_t * vam)
8915 {
8916   unformat_input_t *i = vam->input;
8917   vl_api_sr_mpls_policy_add_t *mp;
8918   u32 bsid = 0;
8919   u32 weight = 1;
8920   u8 type = 0;
8921   u8 n_segments = 0;
8922   u32 sid;
8923   u32 *segments = NULL;
8924   int ret;
8925
8926   /* Parse args required to build the message */
8927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8928     {
8929       if (unformat (i, "bsid %d", &bsid))
8930         ;
8931       else if (unformat (i, "weight %d", &weight))
8932         ;
8933       else if (unformat (i, "spray"))
8934         type = 1;
8935       else if (unformat (i, "next %d", &sid))
8936         {
8937           n_segments += 1;
8938           vec_add1 (segments, htonl (sid));
8939         }
8940       else
8941         {
8942           clib_warning ("parse error '%U'", format_unformat_error, i);
8943           return -99;
8944         }
8945     }
8946
8947   if (bsid == 0)
8948     {
8949       errmsg ("bsid not set");
8950       return -99;
8951     }
8952
8953   if (n_segments == 0)
8954     {
8955       errmsg ("no sid in segment stack");
8956       return -99;
8957     }
8958
8959   /* Construct the API message */
8960   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8961
8962   mp->bsid = htonl (bsid);
8963   mp->weight = htonl (weight);
8964   mp->type = type;
8965   mp->n_segments = n_segments;
8966   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8967   vec_free (segments);
8968
8969   /* send it... */
8970   S (mp);
8971
8972   /* Wait for a reply... */
8973   W (ret);
8974   return ret;
8975 }
8976
8977 static int
8978 api_sr_mpls_policy_del (vat_main_t * vam)
8979 {
8980   unformat_input_t *i = vam->input;
8981   vl_api_sr_mpls_policy_del_t *mp;
8982   u32 bsid = 0;
8983   int ret;
8984
8985   /* Parse args required to build the message */
8986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8987     {
8988       if (unformat (i, "bsid %d", &bsid))
8989         ;
8990       else
8991         {
8992           clib_warning ("parse error '%U'", format_unformat_error, i);
8993           return -99;
8994         }
8995     }
8996
8997   if (bsid == 0)
8998     {
8999       errmsg ("bsid not set");
9000       return -99;
9001     }
9002
9003   /* Construct the API message */
9004   M (SR_MPLS_POLICY_DEL, mp);
9005
9006   mp->bsid = htonl (bsid);
9007
9008   /* send it... */
9009   S (mp);
9010
9011   /* Wait for a reply... */
9012   W (ret);
9013   return ret;
9014 }
9015
9016 static int
9017 api_bier_table_add_del (vat_main_t * vam)
9018 {
9019   unformat_input_t *i = vam->input;
9020   vl_api_bier_table_add_del_t *mp;
9021   u8 is_add = 1;
9022   u32 set = 0, sub_domain = 0, hdr_len = 3;
9023   mpls_label_t local_label = MPLS_LABEL_INVALID;
9024   int ret;
9025
9026   /* Parse args required to build the message */
9027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9028     {
9029       if (unformat (i, "sub-domain %d", &sub_domain))
9030         ;
9031       else if (unformat (i, "set %d", &set))
9032         ;
9033       else if (unformat (i, "label %d", &local_label))
9034         ;
9035       else if (unformat (i, "hdr-len %d", &hdr_len))
9036         ;
9037       else if (unformat (i, "add"))
9038         is_add = 1;
9039       else if (unformat (i, "del"))
9040         is_add = 0;
9041       else
9042         {
9043           clib_warning ("parse error '%U'", format_unformat_error, i);
9044           return -99;
9045         }
9046     }
9047
9048   if (MPLS_LABEL_INVALID == local_label)
9049     {
9050       errmsg ("missing label\n");
9051       return -99;
9052     }
9053
9054   /* Construct the API message */
9055   M (BIER_TABLE_ADD_DEL, mp);
9056
9057   mp->bt_is_add = is_add;
9058   mp->bt_label = ntohl (local_label);
9059   mp->bt_tbl_id.bt_set = set;
9060   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9061   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9062
9063   /* send it... */
9064   S (mp);
9065
9066   /* Wait for a reply... */
9067   W (ret);
9068
9069   return (ret);
9070 }
9071
9072 static int
9073 api_bier_route_add_del (vat_main_t * vam)
9074 {
9075   unformat_input_t *i = vam->input;
9076   vl_api_bier_route_add_del_t *mp;
9077   u8 is_add = 1;
9078   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9079   ip4_address_t v4_next_hop_address;
9080   ip6_address_t v6_next_hop_address;
9081   u8 next_hop_set = 0;
9082   u8 next_hop_proto_is_ip4 = 1;
9083   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9084   int ret;
9085
9086   /* Parse args required to build the message */
9087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9088     {
9089       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9090         {
9091           next_hop_proto_is_ip4 = 1;
9092           next_hop_set = 1;
9093         }
9094       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9095         {
9096           next_hop_proto_is_ip4 = 0;
9097           next_hop_set = 1;
9098         }
9099       if (unformat (i, "sub-domain %d", &sub_domain))
9100         ;
9101       else if (unformat (i, "set %d", &set))
9102         ;
9103       else if (unformat (i, "hdr-len %d", &hdr_len))
9104         ;
9105       else if (unformat (i, "bp %d", &bp))
9106         ;
9107       else if (unformat (i, "add"))
9108         is_add = 1;
9109       else if (unformat (i, "del"))
9110         is_add = 0;
9111       else if (unformat (i, "out-label %d", &next_hop_out_label))
9112         ;
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9121     {
9122       errmsg ("next hop / label set\n");
9123       return -99;
9124     }
9125   if (0 == bp)
9126     {
9127       errmsg ("bit=position not set\n");
9128       return -99;
9129     }
9130
9131   /* Construct the API message */
9132   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9133
9134   mp->br_is_add = is_add;
9135   mp->br_tbl_id.bt_set = set;
9136   mp->br_tbl_id.bt_sub_domain = sub_domain;
9137   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9138   mp->br_bp = ntohs (bp);
9139   mp->br_n_paths = 1;
9140   mp->br_paths[0].n_labels = 1;
9141   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9142   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9143
9144   if (next_hop_proto_is_ip4)
9145     {
9146       clib_memcpy (mp->br_paths[0].next_hop,
9147                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9148     }
9149   else
9150     {
9151       clib_memcpy (mp->br_paths[0].next_hop,
9152                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9153     }
9154
9155   /* send it... */
9156   S (mp);
9157
9158   /* Wait for a reply... */
9159   W (ret);
9160
9161   return (ret);
9162 }
9163
9164 static int
9165 api_proxy_arp_add_del (vat_main_t * vam)
9166 {
9167   unformat_input_t *i = vam->input;
9168   vl_api_proxy_arp_add_del_t *mp;
9169   u32 vrf_id = 0;
9170   u8 is_add = 1;
9171   ip4_address_t lo, hi;
9172   u8 range_set = 0;
9173   int ret;
9174
9175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9176     {
9177       if (unformat (i, "vrf %d", &vrf_id))
9178         ;
9179       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9180                          unformat_ip4_address, &hi))
9181         range_set = 1;
9182       else if (unformat (i, "del"))
9183         is_add = 0;
9184       else
9185         {
9186           clib_warning ("parse error '%U'", format_unformat_error, i);
9187           return -99;
9188         }
9189     }
9190
9191   if (range_set == 0)
9192     {
9193       errmsg ("address range not set");
9194       return -99;
9195     }
9196
9197   M (PROXY_ARP_ADD_DEL, mp);
9198
9199   mp->proxy.vrf_id = ntohl (vrf_id);
9200   mp->is_add = is_add;
9201   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9202   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9203
9204   S (mp);
9205   W (ret);
9206   return ret;
9207 }
9208
9209 static int
9210 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9211 {
9212   unformat_input_t *i = vam->input;
9213   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9214   u32 sw_if_index;
9215   u8 enable = 1;
9216   u8 sw_if_index_set = 0;
9217   int ret;
9218
9219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9220     {
9221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9222         sw_if_index_set = 1;
9223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9224         sw_if_index_set = 1;
9225       else if (unformat (i, "enable"))
9226         enable = 1;
9227       else if (unformat (i, "disable"))
9228         enable = 0;
9229       else
9230         {
9231           clib_warning ("parse error '%U'", format_unformat_error, i);
9232           return -99;
9233         }
9234     }
9235
9236   if (sw_if_index_set == 0)
9237     {
9238       errmsg ("missing interface name or sw_if_index");
9239       return -99;
9240     }
9241
9242   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9243
9244   mp->sw_if_index = ntohl (sw_if_index);
9245   mp->enable_disable = enable;
9246
9247   S (mp);
9248   W (ret);
9249   return ret;
9250 }
9251
9252 static int
9253 api_mpls_tunnel_add_del (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_mpls_tunnel_add_del_t *mp;
9257
9258   u8 is_add = 1;
9259   u8 l2_only = 0;
9260   u32 sw_if_index = ~0;
9261   u32 next_hop_sw_if_index = ~0;
9262   u32 next_hop_proto_is_ip4 = 1;
9263
9264   u32 next_hop_table_id = 0;
9265   ip4_address_t v4_next_hop_address = {
9266     .as_u32 = 0,
9267   };
9268   ip6_address_t v6_next_hop_address = { {0} };
9269   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9270   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9271   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9272   int ret;
9273
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "add"))
9277         is_add = 1;
9278       else
9279         if (unformat
9280             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9281         is_add = 0;
9282       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9283         is_add = 0;
9284       else if (unformat (i, "via %U",
9285                          unformat_ip4_address, &v4_next_hop_address))
9286         {
9287           next_hop_proto_is_ip4 = 1;
9288         }
9289       else if (unformat (i, "via %U",
9290                          unformat_ip6_address, &v6_next_hop_address))
9291         {
9292           next_hop_proto_is_ip4 = 0;
9293         }
9294       else if (unformat (i, "via-label %d", &next_hop_via_label))
9295         ;
9296       else
9297         if (unformat
9298             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9299         ;
9300       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9301         ;
9302       else if (unformat (i, "l2-only"))
9303         l2_only = 1;
9304       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9305         ;
9306       else if (unformat (i, "out-label %d", &next_hop_out_label))
9307         {
9308           vl_api_fib_mpls_label_t fib_label = {
9309             .label = ntohl (next_hop_out_label),
9310             .ttl = 64,
9311             .exp = 0,
9312           };
9313           vec_add1 (next_hop_out_label_stack, fib_label);
9314         }
9315       else
9316         {
9317           clib_warning ("parse error '%U'", format_unformat_error, i);
9318           return -99;
9319         }
9320     }
9321
9322   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9323       vec_len (next_hop_out_label_stack));
9324
9325   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9326   mp->mt_sw_if_index = ntohl (sw_if_index);
9327   mp->mt_is_add = is_add;
9328   mp->mt_l2_only = l2_only;
9329   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9330   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9331   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9332   mp->mt_next_hop_weight = 1;
9333   mp->mt_next_hop_preference = 0;
9334
9335   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9336
9337   if (0 != mp->mt_next_hop_n_out_labels)
9338     {
9339       clib_memcpy (mp->mt_next_hop_out_label_stack,
9340                    next_hop_out_label_stack,
9341                    (vec_len (next_hop_out_label_stack) *
9342                     sizeof (vl_api_fib_mpls_label_t)));
9343       vec_free (next_hop_out_label_stack);
9344     }
9345
9346   if (next_hop_proto_is_ip4)
9347     {
9348       clib_memcpy (mp->mt_next_hop,
9349                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9350     }
9351   else
9352     {
9353       clib_memcpy (mp->mt_next_hop,
9354                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9355     }
9356
9357   S (mp);
9358   W (ret);
9359   return ret;
9360 }
9361
9362 static int
9363 api_sw_interface_set_unnumbered (vat_main_t * vam)
9364 {
9365   unformat_input_t *i = vam->input;
9366   vl_api_sw_interface_set_unnumbered_t *mp;
9367   u32 sw_if_index;
9368   u32 unnum_sw_index = ~0;
9369   u8 is_add = 1;
9370   u8 sw_if_index_set = 0;
9371   int ret;
9372
9373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9374     {
9375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9376         sw_if_index_set = 1;
9377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9378         sw_if_index_set = 1;
9379       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9380         ;
9381       else if (unformat (i, "del"))
9382         is_add = 0;
9383       else
9384         {
9385           clib_warning ("parse error '%U'", format_unformat_error, i);
9386           return -99;
9387         }
9388     }
9389
9390   if (sw_if_index_set == 0)
9391     {
9392       errmsg ("missing interface name or sw_if_index");
9393       return -99;
9394     }
9395
9396   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9397
9398   mp->sw_if_index = ntohl (sw_if_index);
9399   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9400   mp->is_add = is_add;
9401
9402   S (mp);
9403   W (ret);
9404   return ret;
9405 }
9406
9407 static int
9408 api_ip_neighbor_add_del (vat_main_t * vam)
9409 {
9410   unformat_input_t *i = vam->input;
9411   vl_api_ip_neighbor_add_del_t *mp;
9412   u32 sw_if_index;
9413   u8 sw_if_index_set = 0;
9414   u8 is_add = 1;
9415   u8 is_static = 0;
9416   u8 is_no_fib_entry = 0;
9417   u8 mac_address[6];
9418   u8 mac_set = 0;
9419   u8 v4_address_set = 0;
9420   u8 v6_address_set = 0;
9421   ip4_address_t v4address;
9422   ip6_address_t v6address;
9423   int ret;
9424
9425   clib_memset (mac_address, 0, sizeof (mac_address));
9426
9427   /* Parse args required to build the message */
9428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9429     {
9430       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9431         {
9432           mac_set = 1;
9433         }
9434       else if (unformat (i, "del"))
9435         is_add = 0;
9436       else
9437         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9438         sw_if_index_set = 1;
9439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9440         sw_if_index_set = 1;
9441       else if (unformat (i, "is_static"))
9442         is_static = 1;
9443       else if (unformat (i, "no-fib-entry"))
9444         is_no_fib_entry = 1;
9445       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9446         v4_address_set = 1;
9447       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9448         v6_address_set = 1;
9449       else
9450         {
9451           clib_warning ("parse error '%U'", format_unformat_error, i);
9452           return -99;
9453         }
9454     }
9455
9456   if (sw_if_index_set == 0)
9457     {
9458       errmsg ("missing interface name or sw_if_index");
9459       return -99;
9460     }
9461   if (v4_address_set && v6_address_set)
9462     {
9463       errmsg ("both v4 and v6 addresses set");
9464       return -99;
9465     }
9466   if (!v4_address_set && !v6_address_set)
9467     {
9468       errmsg ("no address set");
9469       return -99;
9470     }
9471
9472   /* Construct the API message */
9473   M (IP_NEIGHBOR_ADD_DEL, mp);
9474
9475   mp->sw_if_index = ntohl (sw_if_index);
9476   mp->is_add = is_add;
9477   mp->is_static = is_static;
9478   mp->is_no_adj_fib = is_no_fib_entry;
9479   if (mac_set)
9480     clib_memcpy (mp->mac_address, mac_address, 6);
9481   if (v6_address_set)
9482     {
9483       mp->is_ipv6 = 1;
9484       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9485     }
9486   else
9487     {
9488       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9489       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9490     }
9491
9492   /* send it... */
9493   S (mp);
9494
9495   /* Wait for a reply, return good/bad news  */
9496   W (ret);
9497   return ret;
9498 }
9499
9500 static int
9501 api_create_vlan_subif (vat_main_t * vam)
9502 {
9503   unformat_input_t *i = vam->input;
9504   vl_api_create_vlan_subif_t *mp;
9505   u32 sw_if_index;
9506   u8 sw_if_index_set = 0;
9507   u32 vlan_id;
9508   u8 vlan_id_set = 0;
9509   int ret;
9510
9511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9512     {
9513       if (unformat (i, "sw_if_index %d", &sw_if_index))
9514         sw_if_index_set = 1;
9515       else
9516         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9517         sw_if_index_set = 1;
9518       else if (unformat (i, "vlan %d", &vlan_id))
9519         vlan_id_set = 1;
9520       else
9521         {
9522           clib_warning ("parse error '%U'", format_unformat_error, i);
9523           return -99;
9524         }
9525     }
9526
9527   if (sw_if_index_set == 0)
9528     {
9529       errmsg ("missing interface name or sw_if_index");
9530       return -99;
9531     }
9532
9533   if (vlan_id_set == 0)
9534     {
9535       errmsg ("missing vlan_id");
9536       return -99;
9537     }
9538   M (CREATE_VLAN_SUBIF, mp);
9539
9540   mp->sw_if_index = ntohl (sw_if_index);
9541   mp->vlan_id = ntohl (vlan_id);
9542
9543   S (mp);
9544   W (ret);
9545   return ret;
9546 }
9547
9548 #define foreach_create_subif_bit                \
9549 _(no_tags)                                      \
9550 _(one_tag)                                      \
9551 _(two_tags)                                     \
9552 _(dot1ad)                                       \
9553 _(exact_match)                                  \
9554 _(default_sub)                                  \
9555 _(outer_vlan_id_any)                            \
9556 _(inner_vlan_id_any)
9557
9558 static int
9559 api_create_subif (vat_main_t * vam)
9560 {
9561   unformat_input_t *i = vam->input;
9562   vl_api_create_subif_t *mp;
9563   u32 sw_if_index;
9564   u8 sw_if_index_set = 0;
9565   u32 sub_id;
9566   u8 sub_id_set = 0;
9567   u32 no_tags = 0;
9568   u32 one_tag = 0;
9569   u32 two_tags = 0;
9570   u32 dot1ad = 0;
9571   u32 exact_match = 0;
9572   u32 default_sub = 0;
9573   u32 outer_vlan_id_any = 0;
9574   u32 inner_vlan_id_any = 0;
9575   u32 tmp;
9576   u16 outer_vlan_id = 0;
9577   u16 inner_vlan_id = 0;
9578   int ret;
9579
9580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9581     {
9582       if (unformat (i, "sw_if_index %d", &sw_if_index))
9583         sw_if_index_set = 1;
9584       else
9585         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9586         sw_if_index_set = 1;
9587       else if (unformat (i, "sub_id %d", &sub_id))
9588         sub_id_set = 1;
9589       else if (unformat (i, "outer_vlan_id %d", &tmp))
9590         outer_vlan_id = tmp;
9591       else if (unformat (i, "inner_vlan_id %d", &tmp))
9592         inner_vlan_id = tmp;
9593
9594 #define _(a) else if (unformat (i, #a)) a = 1 ;
9595       foreach_create_subif_bit
9596 #undef _
9597         else
9598         {
9599           clib_warning ("parse error '%U'", format_unformat_error, i);
9600           return -99;
9601         }
9602     }
9603
9604   if (sw_if_index_set == 0)
9605     {
9606       errmsg ("missing interface name or sw_if_index");
9607       return -99;
9608     }
9609
9610   if (sub_id_set == 0)
9611     {
9612       errmsg ("missing sub_id");
9613       return -99;
9614     }
9615   M (CREATE_SUBIF, mp);
9616
9617   mp->sw_if_index = ntohl (sw_if_index);
9618   mp->sub_id = ntohl (sub_id);
9619
9620 #define _(a) mp->a = a;
9621   foreach_create_subif_bit;
9622 #undef _
9623
9624   mp->outer_vlan_id = ntohs (outer_vlan_id);
9625   mp->inner_vlan_id = ntohs (inner_vlan_id);
9626
9627   S (mp);
9628   W (ret);
9629   return ret;
9630 }
9631
9632 static int
9633 api_oam_add_del (vat_main_t * vam)
9634 {
9635   unformat_input_t *i = vam->input;
9636   vl_api_oam_add_del_t *mp;
9637   u32 vrf_id = 0;
9638   u8 is_add = 1;
9639   ip4_address_t src, dst;
9640   u8 src_set = 0;
9641   u8 dst_set = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "vrf %d", &vrf_id))
9647         ;
9648       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9649         src_set = 1;
9650       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9651         dst_set = 1;
9652       else if (unformat (i, "del"))
9653         is_add = 0;
9654       else
9655         {
9656           clib_warning ("parse error '%U'", format_unformat_error, i);
9657           return -99;
9658         }
9659     }
9660
9661   if (src_set == 0)
9662     {
9663       errmsg ("missing src addr");
9664       return -99;
9665     }
9666
9667   if (dst_set == 0)
9668     {
9669       errmsg ("missing dst addr");
9670       return -99;
9671     }
9672
9673   M (OAM_ADD_DEL, mp);
9674
9675   mp->vrf_id = ntohl (vrf_id);
9676   mp->is_add = is_add;
9677   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9678   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9679
9680   S (mp);
9681   W (ret);
9682   return ret;
9683 }
9684
9685 static int
9686 api_reset_fib (vat_main_t * vam)
9687 {
9688   unformat_input_t *i = vam->input;
9689   vl_api_reset_fib_t *mp;
9690   u32 vrf_id = 0;
9691   u8 is_ipv6 = 0;
9692   u8 vrf_id_set = 0;
9693
9694   int ret;
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "vrf %d", &vrf_id))
9698         vrf_id_set = 1;
9699       else if (unformat (i, "ipv6"))
9700         is_ipv6 = 1;
9701       else
9702         {
9703           clib_warning ("parse error '%U'", format_unformat_error, i);
9704           return -99;
9705         }
9706     }
9707
9708   if (vrf_id_set == 0)
9709     {
9710       errmsg ("missing vrf id");
9711       return -99;
9712     }
9713
9714   M (RESET_FIB, mp);
9715
9716   mp->vrf_id = ntohl (vrf_id);
9717   mp->is_ipv6 = is_ipv6;
9718
9719   S (mp);
9720   W (ret);
9721   return ret;
9722 }
9723
9724 static int
9725 api_dhcp_proxy_config (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_dhcp_proxy_config_t *mp;
9729   u32 rx_vrf_id = 0;
9730   u32 server_vrf_id = 0;
9731   u8 is_add = 1;
9732   u8 v4_address_set = 0;
9733   u8 v6_address_set = 0;
9734   ip4_address_t v4address;
9735   ip6_address_t v6address;
9736   u8 v4_src_address_set = 0;
9737   u8 v6_src_address_set = 0;
9738   ip4_address_t v4srcaddress;
9739   ip6_address_t v6srcaddress;
9740   int ret;
9741
9742   /* Parse args required to build the message */
9743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9744     {
9745       if (unformat (i, "del"))
9746         is_add = 0;
9747       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9748         ;
9749       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9750         ;
9751       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9752         v4_address_set = 1;
9753       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9754         v6_address_set = 1;
9755       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9756         v4_src_address_set = 1;
9757       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9758         v6_src_address_set = 1;
9759       else
9760         break;
9761     }
9762
9763   if (v4_address_set && v6_address_set)
9764     {
9765       errmsg ("both v4 and v6 server addresses set");
9766       return -99;
9767     }
9768   if (!v4_address_set && !v6_address_set)
9769     {
9770       errmsg ("no server addresses set");
9771       return -99;
9772     }
9773
9774   if (v4_src_address_set && v6_src_address_set)
9775     {
9776       errmsg ("both v4 and v6  src addresses set");
9777       return -99;
9778     }
9779   if (!v4_src_address_set && !v6_src_address_set)
9780     {
9781       errmsg ("no src addresses set");
9782       return -99;
9783     }
9784
9785   if (!(v4_src_address_set && v4_address_set) &&
9786       !(v6_src_address_set && v6_address_set))
9787     {
9788       errmsg ("no matching server and src addresses set");
9789       return -99;
9790     }
9791
9792   /* Construct the API message */
9793   M (DHCP_PROXY_CONFIG, mp);
9794
9795   mp->is_add = is_add;
9796   mp->rx_vrf_id = ntohl (rx_vrf_id);
9797   mp->server_vrf_id = ntohl (server_vrf_id);
9798   if (v6_address_set)
9799     {
9800       mp->is_ipv6 = 1;
9801       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9802       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9803     }
9804   else
9805     {
9806       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9807       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9808     }
9809
9810   /* send it... */
9811   S (mp);
9812
9813   /* Wait for a reply, return good/bad news  */
9814   W (ret);
9815   return ret;
9816 }
9817
9818 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9819 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9820
9821 static void
9822 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9823 {
9824   vat_main_t *vam = &vat_main;
9825   u32 i, count = mp->count;
9826   vl_api_dhcp_server_t *s;
9827
9828   if (mp->is_ipv6)
9829     print (vam->ofp,
9830            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9831            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9832            ntohl (mp->rx_vrf_id),
9833            format_ip6_address, mp->dhcp_src_address,
9834            mp->vss_type, mp->vss_vpn_ascii_id,
9835            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9836   else
9837     print (vam->ofp,
9838            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9839            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9840            ntohl (mp->rx_vrf_id),
9841            format_ip4_address, mp->dhcp_src_address,
9842            mp->vss_type, mp->vss_vpn_ascii_id,
9843            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9844
9845   for (i = 0; i < count; i++)
9846     {
9847       s = &mp->servers[i];
9848
9849       if (mp->is_ipv6)
9850         print (vam->ofp,
9851                " Server Table-ID %d, Server Address %U",
9852                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9853       else
9854         print (vam->ofp,
9855                " Server Table-ID %d, Server Address %U",
9856                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9857     }
9858 }
9859
9860 static void vl_api_dhcp_proxy_details_t_handler_json
9861   (vl_api_dhcp_proxy_details_t * mp)
9862 {
9863   vat_main_t *vam = &vat_main;
9864   vat_json_node_t *node = NULL;
9865   u32 i, count = mp->count;
9866   struct in_addr ip4;
9867   struct in6_addr ip6;
9868   vl_api_dhcp_server_t *s;
9869
9870   if (VAT_JSON_ARRAY != vam->json_tree.type)
9871     {
9872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9873       vat_json_init_array (&vam->json_tree);
9874     }
9875   node = vat_json_array_add (&vam->json_tree);
9876
9877   vat_json_init_object (node);
9878   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9879   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9880                              sizeof (mp->vss_type));
9881   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9882                                    mp->vss_vpn_ascii_id);
9883   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9884   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9885
9886   if (mp->is_ipv6)
9887     {
9888       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9889       vat_json_object_add_ip6 (node, "src_address", ip6);
9890     }
9891   else
9892     {
9893       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9894       vat_json_object_add_ip4 (node, "src_address", ip4);
9895     }
9896
9897   for (i = 0; i < count; i++)
9898     {
9899       s = &mp->servers[i];
9900
9901       vat_json_object_add_uint (node, "server-table-id",
9902                                 ntohl (s->server_vrf_id));
9903
9904       if (mp->is_ipv6)
9905         {
9906           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9907           vat_json_object_add_ip4 (node, "src_address", ip4);
9908         }
9909       else
9910         {
9911           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9912           vat_json_object_add_ip6 (node, "server_address", ip6);
9913         }
9914     }
9915 }
9916
9917 static int
9918 api_dhcp_proxy_dump (vat_main_t * vam)
9919 {
9920   unformat_input_t *i = vam->input;
9921   vl_api_control_ping_t *mp_ping;
9922   vl_api_dhcp_proxy_dump_t *mp;
9923   u8 is_ipv6 = 0;
9924   int ret;
9925
9926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9927     {
9928       if (unformat (i, "ipv6"))
9929         is_ipv6 = 1;
9930       else
9931         {
9932           clib_warning ("parse error '%U'", format_unformat_error, i);
9933           return -99;
9934         }
9935     }
9936
9937   M (DHCP_PROXY_DUMP, mp);
9938
9939   mp->is_ip6 = is_ipv6;
9940   S (mp);
9941
9942   /* Use a control ping for synchronization */
9943   MPING (CONTROL_PING, mp_ping);
9944   S (mp_ping);
9945
9946   W (ret);
9947   return ret;
9948 }
9949
9950 static int
9951 api_dhcp_proxy_set_vss (vat_main_t * vam)
9952 {
9953   unformat_input_t *i = vam->input;
9954   vl_api_dhcp_proxy_set_vss_t *mp;
9955   u8 is_ipv6 = 0;
9956   u8 is_add = 1;
9957   u32 tbl_id = ~0;
9958   u8 vss_type = VSS_TYPE_DEFAULT;
9959   u8 *vpn_ascii_id = 0;
9960   u32 oui = 0;
9961   u32 fib_id = 0;
9962   int ret;
9963
9964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9965     {
9966       if (unformat (i, "tbl_id %d", &tbl_id))
9967         ;
9968       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9969         vss_type = VSS_TYPE_ASCII;
9970       else if (unformat (i, "fib_id %d", &fib_id))
9971         vss_type = VSS_TYPE_VPN_ID;
9972       else if (unformat (i, "oui %d", &oui))
9973         vss_type = VSS_TYPE_VPN_ID;
9974       else if (unformat (i, "ipv6"))
9975         is_ipv6 = 1;
9976       else if (unformat (i, "del"))
9977         is_add = 0;
9978       else
9979         break;
9980     }
9981
9982   if (tbl_id == ~0)
9983     {
9984       errmsg ("missing tbl_id ");
9985       vec_free (vpn_ascii_id);
9986       return -99;
9987     }
9988
9989   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9990     {
9991       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9992       vec_free (vpn_ascii_id);
9993       return -99;
9994     }
9995
9996   M (DHCP_PROXY_SET_VSS, mp);
9997   mp->tbl_id = ntohl (tbl_id);
9998   mp->vss_type = vss_type;
9999   if (vpn_ascii_id)
10000     {
10001       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10002       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10003     }
10004   mp->vpn_index = ntohl (fib_id);
10005   mp->oui = ntohl (oui);
10006   mp->is_ipv6 = is_ipv6;
10007   mp->is_add = is_add;
10008
10009   S (mp);
10010   W (ret);
10011
10012   vec_free (vpn_ascii_id);
10013   return ret;
10014 }
10015
10016 static int
10017 api_dhcp_client_config (vat_main_t * vam)
10018 {
10019   unformat_input_t *i = vam->input;
10020   vl_api_dhcp_client_config_t *mp;
10021   u32 sw_if_index;
10022   u8 sw_if_index_set = 0;
10023   u8 is_add = 1;
10024   u8 *hostname = 0;
10025   u8 disable_event = 0;
10026   int ret;
10027
10028   /* Parse args required to build the message */
10029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10030     {
10031       if (unformat (i, "del"))
10032         is_add = 0;
10033       else
10034         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10035         sw_if_index_set = 1;
10036       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10037         sw_if_index_set = 1;
10038       else if (unformat (i, "hostname %s", &hostname))
10039         ;
10040       else if (unformat (i, "disable_event"))
10041         disable_event = 1;
10042       else
10043         break;
10044     }
10045
10046   if (sw_if_index_set == 0)
10047     {
10048       errmsg ("missing interface name or sw_if_index");
10049       return -99;
10050     }
10051
10052   if (vec_len (hostname) > 63)
10053     {
10054       errmsg ("hostname too long");
10055     }
10056   vec_add1 (hostname, 0);
10057
10058   /* Construct the API message */
10059   M (DHCP_CLIENT_CONFIG, mp);
10060
10061   mp->is_add = is_add;
10062   mp->client.sw_if_index = htonl (sw_if_index);
10063   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10064   vec_free (hostname);
10065   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10066   mp->client.pid = htonl (getpid ());
10067
10068   /* send it... */
10069   S (mp);
10070
10071   /* Wait for a reply, return good/bad news  */
10072   W (ret);
10073   return ret;
10074 }
10075
10076 static int
10077 api_set_ip_flow_hash (vat_main_t * vam)
10078 {
10079   unformat_input_t *i = vam->input;
10080   vl_api_set_ip_flow_hash_t *mp;
10081   u32 vrf_id = 0;
10082   u8 is_ipv6 = 0;
10083   u8 vrf_id_set = 0;
10084   u8 src = 0;
10085   u8 dst = 0;
10086   u8 sport = 0;
10087   u8 dport = 0;
10088   u8 proto = 0;
10089   u8 reverse = 0;
10090   int ret;
10091
10092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (i, "vrf %d", &vrf_id))
10095         vrf_id_set = 1;
10096       else if (unformat (i, "ipv6"))
10097         is_ipv6 = 1;
10098       else if (unformat (i, "src"))
10099         src = 1;
10100       else if (unformat (i, "dst"))
10101         dst = 1;
10102       else if (unformat (i, "sport"))
10103         sport = 1;
10104       else if (unformat (i, "dport"))
10105         dport = 1;
10106       else if (unformat (i, "proto"))
10107         proto = 1;
10108       else if (unformat (i, "reverse"))
10109         reverse = 1;
10110
10111       else
10112         {
10113           clib_warning ("parse error '%U'", format_unformat_error, i);
10114           return -99;
10115         }
10116     }
10117
10118   if (vrf_id_set == 0)
10119     {
10120       errmsg ("missing vrf id");
10121       return -99;
10122     }
10123
10124   M (SET_IP_FLOW_HASH, mp);
10125   mp->src = src;
10126   mp->dst = dst;
10127   mp->sport = sport;
10128   mp->dport = dport;
10129   mp->proto = proto;
10130   mp->reverse = reverse;
10131   mp->vrf_id = ntohl (vrf_id);
10132   mp->is_ipv6 = is_ipv6;
10133
10134   S (mp);
10135   W (ret);
10136   return ret;
10137 }
10138
10139 static int
10140 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10141 {
10142   unformat_input_t *i = vam->input;
10143   vl_api_sw_interface_ip6_enable_disable_t *mp;
10144   u32 sw_if_index;
10145   u8 sw_if_index_set = 0;
10146   u8 enable = 0;
10147   int ret;
10148
10149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10152         sw_if_index_set = 1;
10153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10154         sw_if_index_set = 1;
10155       else if (unformat (i, "enable"))
10156         enable = 1;
10157       else if (unformat (i, "disable"))
10158         enable = 0;
10159       else
10160         {
10161           clib_warning ("parse error '%U'", format_unformat_error, i);
10162           return -99;
10163         }
10164     }
10165
10166   if (sw_if_index_set == 0)
10167     {
10168       errmsg ("missing interface name or sw_if_index");
10169       return -99;
10170     }
10171
10172   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10173
10174   mp->sw_if_index = ntohl (sw_if_index);
10175   mp->enable = enable;
10176
10177   S (mp);
10178   W (ret);
10179   return ret;
10180 }
10181
10182 static int
10183 api_ip6nd_proxy_add_del (vat_main_t * vam)
10184 {
10185   unformat_input_t *i = vam->input;
10186   vl_api_ip6nd_proxy_add_del_t *mp;
10187   u32 sw_if_index = ~0;
10188   u8 v6_address_set = 0;
10189   ip6_address_t v6address;
10190   u8 is_del = 0;
10191   int ret;
10192
10193   /* Parse args required to build the message */
10194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10197         ;
10198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10199         ;
10200       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10201         v6_address_set = 1;
10202       if (unformat (i, "del"))
10203         is_del = 1;
10204       else
10205         {
10206           clib_warning ("parse error '%U'", format_unformat_error, i);
10207           return -99;
10208         }
10209     }
10210
10211   if (sw_if_index == ~0)
10212     {
10213       errmsg ("missing interface name or sw_if_index");
10214       return -99;
10215     }
10216   if (!v6_address_set)
10217     {
10218       errmsg ("no address set");
10219       return -99;
10220     }
10221
10222   /* Construct the API message */
10223   M (IP6ND_PROXY_ADD_DEL, mp);
10224
10225   mp->is_del = is_del;
10226   mp->sw_if_index = ntohl (sw_if_index);
10227   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10228
10229   /* send it... */
10230   S (mp);
10231
10232   /* Wait for a reply, return good/bad news  */
10233   W (ret);
10234   return ret;
10235 }
10236
10237 static int
10238 api_ip6nd_proxy_dump (vat_main_t * vam)
10239 {
10240   vl_api_ip6nd_proxy_dump_t *mp;
10241   vl_api_control_ping_t *mp_ping;
10242   int ret;
10243
10244   M (IP6ND_PROXY_DUMP, mp);
10245
10246   S (mp);
10247
10248   /* Use a control ping for synchronization */
10249   MPING (CONTROL_PING, mp_ping);
10250   S (mp_ping);
10251
10252   W (ret);
10253   return ret;
10254 }
10255
10256 static void vl_api_ip6nd_proxy_details_t_handler
10257   (vl_api_ip6nd_proxy_details_t * mp)
10258 {
10259   vat_main_t *vam = &vat_main;
10260
10261   print (vam->ofp, "host %U sw_if_index %d",
10262          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10263 }
10264
10265 static void vl_api_ip6nd_proxy_details_t_handler_json
10266   (vl_api_ip6nd_proxy_details_t * mp)
10267 {
10268   vat_main_t *vam = &vat_main;
10269   struct in6_addr ip6;
10270   vat_json_node_t *node = NULL;
10271
10272   if (VAT_JSON_ARRAY != vam->json_tree.type)
10273     {
10274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10275       vat_json_init_array (&vam->json_tree);
10276     }
10277   node = vat_json_array_add (&vam->json_tree);
10278
10279   vat_json_init_object (node);
10280   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10281
10282   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10283   vat_json_object_add_ip6 (node, "host", ip6);
10284 }
10285
10286 static int
10287 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10288 {
10289   unformat_input_t *i = vam->input;
10290   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10291   u32 sw_if_index;
10292   u8 sw_if_index_set = 0;
10293   u32 address_length = 0;
10294   u8 v6_address_set = 0;
10295   ip6_address_t v6address;
10296   u8 use_default = 0;
10297   u8 no_advertise = 0;
10298   u8 off_link = 0;
10299   u8 no_autoconfig = 0;
10300   u8 no_onlink = 0;
10301   u8 is_no = 0;
10302   u32 val_lifetime = 0;
10303   u32 pref_lifetime = 0;
10304   int ret;
10305
10306   /* Parse args required to build the message */
10307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10308     {
10309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10310         sw_if_index_set = 1;
10311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10312         sw_if_index_set = 1;
10313       else if (unformat (i, "%U/%d",
10314                          unformat_ip6_address, &v6address, &address_length))
10315         v6_address_set = 1;
10316       else if (unformat (i, "val_life %d", &val_lifetime))
10317         ;
10318       else if (unformat (i, "pref_life %d", &pref_lifetime))
10319         ;
10320       else if (unformat (i, "def"))
10321         use_default = 1;
10322       else if (unformat (i, "noadv"))
10323         no_advertise = 1;
10324       else if (unformat (i, "offl"))
10325         off_link = 1;
10326       else if (unformat (i, "noauto"))
10327         no_autoconfig = 1;
10328       else if (unformat (i, "nolink"))
10329         no_onlink = 1;
10330       else if (unformat (i, "isno"))
10331         is_no = 1;
10332       else
10333         {
10334           clib_warning ("parse error '%U'", format_unformat_error, i);
10335           return -99;
10336         }
10337     }
10338
10339   if (sw_if_index_set == 0)
10340     {
10341       errmsg ("missing interface name or sw_if_index");
10342       return -99;
10343     }
10344   if (!v6_address_set)
10345     {
10346       errmsg ("no address set");
10347       return -99;
10348     }
10349
10350   /* Construct the API message */
10351   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10352
10353   mp->sw_if_index = ntohl (sw_if_index);
10354   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10355   mp->address_length = address_length;
10356   mp->use_default = use_default;
10357   mp->no_advertise = no_advertise;
10358   mp->off_link = off_link;
10359   mp->no_autoconfig = no_autoconfig;
10360   mp->no_onlink = no_onlink;
10361   mp->is_no = is_no;
10362   mp->val_lifetime = ntohl (val_lifetime);
10363   mp->pref_lifetime = ntohl (pref_lifetime);
10364
10365   /* send it... */
10366   S (mp);
10367
10368   /* Wait for a reply, return good/bad news  */
10369   W (ret);
10370   return ret;
10371 }
10372
10373 static int
10374 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10375 {
10376   unformat_input_t *i = vam->input;
10377   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10378   u32 sw_if_index;
10379   u8 sw_if_index_set = 0;
10380   u8 suppress = 0;
10381   u8 managed = 0;
10382   u8 other = 0;
10383   u8 ll_option = 0;
10384   u8 send_unicast = 0;
10385   u8 cease = 0;
10386   u8 is_no = 0;
10387   u8 default_router = 0;
10388   u32 max_interval = 0;
10389   u32 min_interval = 0;
10390   u32 lifetime = 0;
10391   u32 initial_count = 0;
10392   u32 initial_interval = 0;
10393   int ret;
10394
10395
10396   /* Parse args required to build the message */
10397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10398     {
10399       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10400         sw_if_index_set = 1;
10401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10402         sw_if_index_set = 1;
10403       else if (unformat (i, "maxint %d", &max_interval))
10404         ;
10405       else if (unformat (i, "minint %d", &min_interval))
10406         ;
10407       else if (unformat (i, "life %d", &lifetime))
10408         ;
10409       else if (unformat (i, "count %d", &initial_count))
10410         ;
10411       else if (unformat (i, "interval %d", &initial_interval))
10412         ;
10413       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10414         suppress = 1;
10415       else if (unformat (i, "managed"))
10416         managed = 1;
10417       else if (unformat (i, "other"))
10418         other = 1;
10419       else if (unformat (i, "ll"))
10420         ll_option = 1;
10421       else if (unformat (i, "send"))
10422         send_unicast = 1;
10423       else if (unformat (i, "cease"))
10424         cease = 1;
10425       else if (unformat (i, "isno"))
10426         is_no = 1;
10427       else if (unformat (i, "def"))
10428         default_router = 1;
10429       else
10430         {
10431           clib_warning ("parse error '%U'", format_unformat_error, i);
10432           return -99;
10433         }
10434     }
10435
10436   if (sw_if_index_set == 0)
10437     {
10438       errmsg ("missing interface name or sw_if_index");
10439       return -99;
10440     }
10441
10442   /* Construct the API message */
10443   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10444
10445   mp->sw_if_index = ntohl (sw_if_index);
10446   mp->max_interval = ntohl (max_interval);
10447   mp->min_interval = ntohl (min_interval);
10448   mp->lifetime = ntohl (lifetime);
10449   mp->initial_count = ntohl (initial_count);
10450   mp->initial_interval = ntohl (initial_interval);
10451   mp->suppress = suppress;
10452   mp->managed = managed;
10453   mp->other = other;
10454   mp->ll_option = ll_option;
10455   mp->send_unicast = send_unicast;
10456   mp->cease = cease;
10457   mp->is_no = is_no;
10458   mp->default_router = default_router;
10459
10460   /* send it... */
10461   S (mp);
10462
10463   /* Wait for a reply, return good/bad news  */
10464   W (ret);
10465   return ret;
10466 }
10467
10468 static int
10469 api_set_arp_neighbor_limit (vat_main_t * vam)
10470 {
10471   unformat_input_t *i = vam->input;
10472   vl_api_set_arp_neighbor_limit_t *mp;
10473   u32 arp_nbr_limit;
10474   u8 limit_set = 0;
10475   u8 is_ipv6 = 0;
10476   int ret;
10477
10478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10479     {
10480       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10481         limit_set = 1;
10482       else if (unformat (i, "ipv6"))
10483         is_ipv6 = 1;
10484       else
10485         {
10486           clib_warning ("parse error '%U'", format_unformat_error, i);
10487           return -99;
10488         }
10489     }
10490
10491   if (limit_set == 0)
10492     {
10493       errmsg ("missing limit value");
10494       return -99;
10495     }
10496
10497   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10498
10499   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10500   mp->is_ipv6 = is_ipv6;
10501
10502   S (mp);
10503   W (ret);
10504   return ret;
10505 }
10506
10507 static int
10508 api_l2_patch_add_del (vat_main_t * vam)
10509 {
10510   unformat_input_t *i = vam->input;
10511   vl_api_l2_patch_add_del_t *mp;
10512   u32 rx_sw_if_index;
10513   u8 rx_sw_if_index_set = 0;
10514   u32 tx_sw_if_index;
10515   u8 tx_sw_if_index_set = 0;
10516   u8 is_add = 1;
10517   int ret;
10518
10519   /* Parse args required to build the message */
10520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10521     {
10522       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10523         rx_sw_if_index_set = 1;
10524       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10525         tx_sw_if_index_set = 1;
10526       else if (unformat (i, "rx"))
10527         {
10528           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10529             {
10530               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10531                             &rx_sw_if_index))
10532                 rx_sw_if_index_set = 1;
10533             }
10534           else
10535             break;
10536         }
10537       else if (unformat (i, "tx"))
10538         {
10539           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10540             {
10541               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10542                             &tx_sw_if_index))
10543                 tx_sw_if_index_set = 1;
10544             }
10545           else
10546             break;
10547         }
10548       else if (unformat (i, "del"))
10549         is_add = 0;
10550       else
10551         break;
10552     }
10553
10554   if (rx_sw_if_index_set == 0)
10555     {
10556       errmsg ("missing rx interface name or rx_sw_if_index");
10557       return -99;
10558     }
10559
10560   if (tx_sw_if_index_set == 0)
10561     {
10562       errmsg ("missing tx interface name or tx_sw_if_index");
10563       return -99;
10564     }
10565
10566   M (L2_PATCH_ADD_DEL, mp);
10567
10568   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10569   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10570   mp->is_add = is_add;
10571
10572   S (mp);
10573   W (ret);
10574   return ret;
10575 }
10576
10577 u8 is_del;
10578 u8 localsid_addr[16];
10579 u8 end_psp;
10580 u8 behavior;
10581 u32 sw_if_index;
10582 u32 vlan_index;
10583 u32 fib_table;
10584 u8 nh_addr[16];
10585
10586 static int
10587 api_sr_localsid_add_del (vat_main_t * vam)
10588 {
10589   unformat_input_t *i = vam->input;
10590   vl_api_sr_localsid_add_del_t *mp;
10591
10592   u8 is_del;
10593   ip6_address_t localsid;
10594   u8 end_psp = 0;
10595   u8 behavior = ~0;
10596   u32 sw_if_index;
10597   u32 fib_table = ~(u32) 0;
10598   ip6_address_t nh_addr6;
10599   ip4_address_t nh_addr4;
10600   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10601   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10602
10603   bool nexthop_set = 0;
10604
10605   int ret;
10606
10607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10608     {
10609       if (unformat (i, "del"))
10610         is_del = 1;
10611       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10612       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10613         nexthop_set = 1;
10614       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10615         nexthop_set = 1;
10616       else if (unformat (i, "behavior %u", &behavior));
10617       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10618       else if (unformat (i, "fib-table %u", &fib_table));
10619       else if (unformat (i, "end.psp %u", &behavior));
10620       else
10621         break;
10622     }
10623
10624   M (SR_LOCALSID_ADD_DEL, mp);
10625
10626   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10627   if (nexthop_set)
10628     {
10629       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10630       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10631     }
10632   mp->behavior = behavior;
10633   mp->sw_if_index = ntohl (sw_if_index);
10634   mp->fib_table = ntohl (fib_table);
10635   mp->end_psp = end_psp;
10636   mp->is_del = is_del;
10637
10638   S (mp);
10639   W (ret);
10640   return ret;
10641 }
10642
10643 static int
10644 api_ioam_enable (vat_main_t * vam)
10645 {
10646   unformat_input_t *input = vam->input;
10647   vl_api_ioam_enable_t *mp;
10648   u32 id = 0;
10649   int has_trace_option = 0;
10650   int has_pot_option = 0;
10651   int has_seqno_option = 0;
10652   int has_analyse_option = 0;
10653   int ret;
10654
10655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (input, "trace"))
10658         has_trace_option = 1;
10659       else if (unformat (input, "pot"))
10660         has_pot_option = 1;
10661       else if (unformat (input, "seqno"))
10662         has_seqno_option = 1;
10663       else if (unformat (input, "analyse"))
10664         has_analyse_option = 1;
10665       else
10666         break;
10667     }
10668   M (IOAM_ENABLE, mp);
10669   mp->id = htons (id);
10670   mp->seqno = has_seqno_option;
10671   mp->analyse = has_analyse_option;
10672   mp->pot_enable = has_pot_option;
10673   mp->trace_enable = has_trace_option;
10674
10675   S (mp);
10676   W (ret);
10677   return ret;
10678 }
10679
10680
10681 static int
10682 api_ioam_disable (vat_main_t * vam)
10683 {
10684   vl_api_ioam_disable_t *mp;
10685   int ret;
10686
10687   M (IOAM_DISABLE, mp);
10688   S (mp);
10689   W (ret);
10690   return ret;
10691 }
10692
10693 #define foreach_tcp_proto_field                 \
10694 _(src_port)                                     \
10695 _(dst_port)
10696
10697 #define foreach_udp_proto_field                 \
10698 _(src_port)                                     \
10699 _(dst_port)
10700
10701 #define foreach_ip4_proto_field                 \
10702 _(src_address)                                  \
10703 _(dst_address)                                  \
10704 _(tos)                                          \
10705 _(length)                                       \
10706 _(fragment_id)                                  \
10707 _(ttl)                                          \
10708 _(protocol)                                     \
10709 _(checksum)
10710
10711 typedef struct
10712 {
10713   u16 src_port, dst_port;
10714 } tcpudp_header_t;
10715
10716 #if VPP_API_TEST_BUILTIN == 0
10717 uword
10718 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10719 {
10720   u8 **maskp = va_arg (*args, u8 **);
10721   u8 *mask = 0;
10722   u8 found_something = 0;
10723   tcp_header_t *tcp;
10724
10725 #define _(a) u8 a=0;
10726   foreach_tcp_proto_field;
10727 #undef _
10728
10729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (0);
10732 #define _(a) else if (unformat (input, #a)) a=1;
10733       foreach_tcp_proto_field
10734 #undef _
10735         else
10736         break;
10737     }
10738
10739 #define _(a) found_something += a;
10740   foreach_tcp_proto_field;
10741 #undef _
10742
10743   if (found_something == 0)
10744     return 0;
10745
10746   vec_validate (mask, sizeof (*tcp) - 1);
10747
10748   tcp = (tcp_header_t *) mask;
10749
10750 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10751   foreach_tcp_proto_field;
10752 #undef _
10753
10754   *maskp = mask;
10755   return 1;
10756 }
10757
10758 uword
10759 unformat_udp_mask (unformat_input_t * input, va_list * args)
10760 {
10761   u8 **maskp = va_arg (*args, u8 **);
10762   u8 *mask = 0;
10763   u8 found_something = 0;
10764   udp_header_t *udp;
10765
10766 #define _(a) u8 a=0;
10767   foreach_udp_proto_field;
10768 #undef _
10769
10770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10771     {
10772       if (0);
10773 #define _(a) else if (unformat (input, #a)) a=1;
10774       foreach_udp_proto_field
10775 #undef _
10776         else
10777         break;
10778     }
10779
10780 #define _(a) found_something += a;
10781   foreach_udp_proto_field;
10782 #undef _
10783
10784   if (found_something == 0)
10785     return 0;
10786
10787   vec_validate (mask, sizeof (*udp) - 1);
10788
10789   udp = (udp_header_t *) mask;
10790
10791 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10792   foreach_udp_proto_field;
10793 #undef _
10794
10795   *maskp = mask;
10796   return 1;
10797 }
10798
10799 uword
10800 unformat_l4_mask (unformat_input_t * input, va_list * args)
10801 {
10802   u8 **maskp = va_arg (*args, u8 **);
10803   u16 src_port = 0, dst_port = 0;
10804   tcpudp_header_t *tcpudp;
10805
10806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10809         return 1;
10810       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10811         return 1;
10812       else if (unformat (input, "src_port"))
10813         src_port = 0xFFFF;
10814       else if (unformat (input, "dst_port"))
10815         dst_port = 0xFFFF;
10816       else
10817         return 0;
10818     }
10819
10820   if (!src_port && !dst_port)
10821     return 0;
10822
10823   u8 *mask = 0;
10824   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10825
10826   tcpudp = (tcpudp_header_t *) mask;
10827   tcpudp->src_port = src_port;
10828   tcpudp->dst_port = dst_port;
10829
10830   *maskp = mask;
10831
10832   return 1;
10833 }
10834
10835 uword
10836 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10837 {
10838   u8 **maskp = va_arg (*args, u8 **);
10839   u8 *mask = 0;
10840   u8 found_something = 0;
10841   ip4_header_t *ip;
10842
10843 #define _(a) u8 a=0;
10844   foreach_ip4_proto_field;
10845 #undef _
10846   u8 version = 0;
10847   u8 hdr_length = 0;
10848
10849
10850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (input, "version"))
10853         version = 1;
10854       else if (unformat (input, "hdr_length"))
10855         hdr_length = 1;
10856       else if (unformat (input, "src"))
10857         src_address = 1;
10858       else if (unformat (input, "dst"))
10859         dst_address = 1;
10860       else if (unformat (input, "proto"))
10861         protocol = 1;
10862
10863 #define _(a) else if (unformat (input, #a)) a=1;
10864       foreach_ip4_proto_field
10865 #undef _
10866         else
10867         break;
10868     }
10869
10870 #define _(a) found_something += a;
10871   foreach_ip4_proto_field;
10872 #undef _
10873
10874   if (found_something == 0)
10875     return 0;
10876
10877   vec_validate (mask, sizeof (*ip) - 1);
10878
10879   ip = (ip4_header_t *) mask;
10880
10881 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10882   foreach_ip4_proto_field;
10883 #undef _
10884
10885   ip->ip_version_and_header_length = 0;
10886
10887   if (version)
10888     ip->ip_version_and_header_length |= 0xF0;
10889
10890   if (hdr_length)
10891     ip->ip_version_and_header_length |= 0x0F;
10892
10893   *maskp = mask;
10894   return 1;
10895 }
10896
10897 #define foreach_ip6_proto_field                 \
10898 _(src_address)                                  \
10899 _(dst_address)                                  \
10900 _(payload_length)                               \
10901 _(hop_limit)                                    \
10902 _(protocol)
10903
10904 uword
10905 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10906 {
10907   u8 **maskp = va_arg (*args, u8 **);
10908   u8 *mask = 0;
10909   u8 found_something = 0;
10910   ip6_header_t *ip;
10911   u32 ip_version_traffic_class_and_flow_label;
10912
10913 #define _(a) u8 a=0;
10914   foreach_ip6_proto_field;
10915 #undef _
10916   u8 version = 0;
10917   u8 traffic_class = 0;
10918   u8 flow_label = 0;
10919
10920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (input, "version"))
10923         version = 1;
10924       else if (unformat (input, "traffic-class"))
10925         traffic_class = 1;
10926       else if (unformat (input, "flow-label"))
10927         flow_label = 1;
10928       else if (unformat (input, "src"))
10929         src_address = 1;
10930       else if (unformat (input, "dst"))
10931         dst_address = 1;
10932       else if (unformat (input, "proto"))
10933         protocol = 1;
10934
10935 #define _(a) else if (unformat (input, #a)) a=1;
10936       foreach_ip6_proto_field
10937 #undef _
10938         else
10939         break;
10940     }
10941
10942 #define _(a) found_something += a;
10943   foreach_ip6_proto_field;
10944 #undef _
10945
10946   if (found_something == 0)
10947     return 0;
10948
10949   vec_validate (mask, sizeof (*ip) - 1);
10950
10951   ip = (ip6_header_t *) mask;
10952
10953 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10954   foreach_ip6_proto_field;
10955 #undef _
10956
10957   ip_version_traffic_class_and_flow_label = 0;
10958
10959   if (version)
10960     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10961
10962   if (traffic_class)
10963     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10964
10965   if (flow_label)
10966     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10967
10968   ip->ip_version_traffic_class_and_flow_label =
10969     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10970
10971   *maskp = mask;
10972   return 1;
10973 }
10974
10975 uword
10976 unformat_l3_mask (unformat_input_t * input, va_list * args)
10977 {
10978   u8 **maskp = va_arg (*args, u8 **);
10979
10980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10983         return 1;
10984       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10985         return 1;
10986       else
10987         break;
10988     }
10989   return 0;
10990 }
10991
10992 uword
10993 unformat_l2_mask (unformat_input_t * input, va_list * args)
10994 {
10995   u8 **maskp = va_arg (*args, u8 **);
10996   u8 *mask = 0;
10997   u8 src = 0;
10998   u8 dst = 0;
10999   u8 proto = 0;
11000   u8 tag1 = 0;
11001   u8 tag2 = 0;
11002   u8 ignore_tag1 = 0;
11003   u8 ignore_tag2 = 0;
11004   u8 cos1 = 0;
11005   u8 cos2 = 0;
11006   u8 dot1q = 0;
11007   u8 dot1ad = 0;
11008   int len = 14;
11009
11010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11011     {
11012       if (unformat (input, "src"))
11013         src = 1;
11014       else if (unformat (input, "dst"))
11015         dst = 1;
11016       else if (unformat (input, "proto"))
11017         proto = 1;
11018       else if (unformat (input, "tag1"))
11019         tag1 = 1;
11020       else if (unformat (input, "tag2"))
11021         tag2 = 1;
11022       else if (unformat (input, "ignore-tag1"))
11023         ignore_tag1 = 1;
11024       else if (unformat (input, "ignore-tag2"))
11025         ignore_tag2 = 1;
11026       else if (unformat (input, "cos1"))
11027         cos1 = 1;
11028       else if (unformat (input, "cos2"))
11029         cos2 = 1;
11030       else if (unformat (input, "dot1q"))
11031         dot1q = 1;
11032       else if (unformat (input, "dot1ad"))
11033         dot1ad = 1;
11034       else
11035         break;
11036     }
11037   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11038        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11039     return 0;
11040
11041   if (tag1 || ignore_tag1 || cos1 || dot1q)
11042     len = 18;
11043   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11044     len = 22;
11045
11046   vec_validate (mask, len - 1);
11047
11048   if (dst)
11049     clib_memset (mask, 0xff, 6);
11050
11051   if (src)
11052     clib_memset (mask + 6, 0xff, 6);
11053
11054   if (tag2 || dot1ad)
11055     {
11056       /* inner vlan tag */
11057       if (tag2)
11058         {
11059           mask[19] = 0xff;
11060           mask[18] = 0x0f;
11061         }
11062       if (cos2)
11063         mask[18] |= 0xe0;
11064       if (proto)
11065         mask[21] = mask[20] = 0xff;
11066       if (tag1)
11067         {
11068           mask[15] = 0xff;
11069           mask[14] = 0x0f;
11070         }
11071       if (cos1)
11072         mask[14] |= 0xe0;
11073       *maskp = mask;
11074       return 1;
11075     }
11076   if (tag1 | dot1q)
11077     {
11078       if (tag1)
11079         {
11080           mask[15] = 0xff;
11081           mask[14] = 0x0f;
11082         }
11083       if (cos1)
11084         mask[14] |= 0xe0;
11085       if (proto)
11086         mask[16] = mask[17] = 0xff;
11087
11088       *maskp = mask;
11089       return 1;
11090     }
11091   if (cos2)
11092     mask[18] |= 0xe0;
11093   if (cos1)
11094     mask[14] |= 0xe0;
11095   if (proto)
11096     mask[12] = mask[13] = 0xff;
11097
11098   *maskp = mask;
11099   return 1;
11100 }
11101
11102 uword
11103 unformat_classify_mask (unformat_input_t * input, va_list * args)
11104 {
11105   u8 **maskp = va_arg (*args, u8 **);
11106   u32 *skipp = va_arg (*args, u32 *);
11107   u32 *matchp = va_arg (*args, u32 *);
11108   u32 match;
11109   u8 *mask = 0;
11110   u8 *l2 = 0;
11111   u8 *l3 = 0;
11112   u8 *l4 = 0;
11113   int i;
11114
11115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11118         ;
11119       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11120         ;
11121       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11122         ;
11123       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11124         ;
11125       else
11126         break;
11127     }
11128
11129   if (l4 && !l3)
11130     {
11131       vec_free (mask);
11132       vec_free (l2);
11133       vec_free (l4);
11134       return 0;
11135     }
11136
11137   if (mask || l2 || l3 || l4)
11138     {
11139       if (l2 || l3 || l4)
11140         {
11141           /* "With a free Ethernet header in every package" */
11142           if (l2 == 0)
11143             vec_validate (l2, 13);
11144           mask = l2;
11145           if (vec_len (l3))
11146             {
11147               vec_append (mask, l3);
11148               vec_free (l3);
11149             }
11150           if (vec_len (l4))
11151             {
11152               vec_append (mask, l4);
11153               vec_free (l4);
11154             }
11155         }
11156
11157       /* Scan forward looking for the first significant mask octet */
11158       for (i = 0; i < vec_len (mask); i++)
11159         if (mask[i])
11160           break;
11161
11162       /* compute (skip, match) params */
11163       *skipp = i / sizeof (u32x4);
11164       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11165
11166       /* Pad mask to an even multiple of the vector size */
11167       while (vec_len (mask) % sizeof (u32x4))
11168         vec_add1 (mask, 0);
11169
11170       match = vec_len (mask) / sizeof (u32x4);
11171
11172       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11173         {
11174           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11175           if (*tmp || *(tmp + 1))
11176             break;
11177           match--;
11178         }
11179       if (match == 0)
11180         clib_warning ("BUG: match 0");
11181
11182       _vec_len (mask) = match * sizeof (u32x4);
11183
11184       *matchp = match;
11185       *maskp = mask;
11186
11187       return 1;
11188     }
11189
11190   return 0;
11191 }
11192 #endif /* VPP_API_TEST_BUILTIN */
11193
11194 #define foreach_l2_next                         \
11195 _(drop, DROP)                                   \
11196 _(ethernet, ETHERNET_INPUT)                     \
11197 _(ip4, IP4_INPUT)                               \
11198 _(ip6, IP6_INPUT)
11199
11200 uword
11201 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11202 {
11203   u32 *miss_next_indexp = va_arg (*args, u32 *);
11204   u32 next_index = 0;
11205   u32 tmp;
11206
11207 #define _(n,N) \
11208   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11209   foreach_l2_next;
11210 #undef _
11211
11212   if (unformat (input, "%d", &tmp))
11213     {
11214       next_index = tmp;
11215       goto out;
11216     }
11217
11218   return 0;
11219
11220 out:
11221   *miss_next_indexp = next_index;
11222   return 1;
11223 }
11224
11225 #define foreach_ip_next                         \
11226 _(drop, DROP)                                   \
11227 _(local, LOCAL)                                 \
11228 _(rewrite, REWRITE)
11229
11230 uword
11231 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11232 {
11233   u32 *miss_next_indexp = va_arg (*args, u32 *);
11234   u32 next_index = 0;
11235   u32 tmp;
11236
11237 #define _(n,N) \
11238   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11239   foreach_ip_next;
11240 #undef _
11241
11242   if (unformat (input, "%d", &tmp))
11243     {
11244       next_index = tmp;
11245       goto out;
11246     }
11247
11248   return 0;
11249
11250 out:
11251   *miss_next_indexp = next_index;
11252   return 1;
11253 }
11254
11255 #define foreach_acl_next                        \
11256 _(deny, DENY)
11257
11258 uword
11259 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11260 {
11261   u32 *miss_next_indexp = va_arg (*args, u32 *);
11262   u32 next_index = 0;
11263   u32 tmp;
11264
11265 #define _(n,N) \
11266   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11267   foreach_acl_next;
11268 #undef _
11269
11270   if (unformat (input, "permit"))
11271     {
11272       next_index = ~0;
11273       goto out;
11274     }
11275   else if (unformat (input, "%d", &tmp))
11276     {
11277       next_index = tmp;
11278       goto out;
11279     }
11280
11281   return 0;
11282
11283 out:
11284   *miss_next_indexp = next_index;
11285   return 1;
11286 }
11287
11288 uword
11289 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11290 {
11291   u32 *r = va_arg (*args, u32 *);
11292
11293   if (unformat (input, "conform-color"))
11294     *r = POLICE_CONFORM;
11295   else if (unformat (input, "exceed-color"))
11296     *r = POLICE_EXCEED;
11297   else
11298     return 0;
11299
11300   return 1;
11301 }
11302
11303 static int
11304 api_classify_add_del_table (vat_main_t * vam)
11305 {
11306   unformat_input_t *i = vam->input;
11307   vl_api_classify_add_del_table_t *mp;
11308
11309   u32 nbuckets = 2;
11310   u32 skip = ~0;
11311   u32 match = ~0;
11312   int is_add = 1;
11313   int del_chain = 0;
11314   u32 table_index = ~0;
11315   u32 next_table_index = ~0;
11316   u32 miss_next_index = ~0;
11317   u32 memory_size = 32 << 20;
11318   u8 *mask = 0;
11319   u32 current_data_flag = 0;
11320   int current_data_offset = 0;
11321   int ret;
11322
11323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11324     {
11325       if (unformat (i, "del"))
11326         is_add = 0;
11327       else if (unformat (i, "del-chain"))
11328         {
11329           is_add = 0;
11330           del_chain = 1;
11331         }
11332       else if (unformat (i, "buckets %d", &nbuckets))
11333         ;
11334       else if (unformat (i, "memory_size %d", &memory_size))
11335         ;
11336       else if (unformat (i, "skip %d", &skip))
11337         ;
11338       else if (unformat (i, "match %d", &match))
11339         ;
11340       else if (unformat (i, "table %d", &table_index))
11341         ;
11342       else if (unformat (i, "mask %U", unformat_classify_mask,
11343                          &mask, &skip, &match))
11344         ;
11345       else if (unformat (i, "next-table %d", &next_table_index))
11346         ;
11347       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11348                          &miss_next_index))
11349         ;
11350       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11351                          &miss_next_index))
11352         ;
11353       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11354                          &miss_next_index))
11355         ;
11356       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11357         ;
11358       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11359         ;
11360       else
11361         break;
11362     }
11363
11364   if (is_add && mask == 0)
11365     {
11366       errmsg ("Mask required");
11367       return -99;
11368     }
11369
11370   if (is_add && skip == ~0)
11371     {
11372       errmsg ("skip count required");
11373       return -99;
11374     }
11375
11376   if (is_add && match == ~0)
11377     {
11378       errmsg ("match count required");
11379       return -99;
11380     }
11381
11382   if (!is_add && table_index == ~0)
11383     {
11384       errmsg ("table index required for delete");
11385       return -99;
11386     }
11387
11388   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11389
11390   mp->is_add = is_add;
11391   mp->del_chain = del_chain;
11392   mp->table_index = ntohl (table_index);
11393   mp->nbuckets = ntohl (nbuckets);
11394   mp->memory_size = ntohl (memory_size);
11395   mp->skip_n_vectors = ntohl (skip);
11396   mp->match_n_vectors = ntohl (match);
11397   mp->next_table_index = ntohl (next_table_index);
11398   mp->miss_next_index = ntohl (miss_next_index);
11399   mp->current_data_flag = ntohl (current_data_flag);
11400   mp->current_data_offset = ntohl (current_data_offset);
11401   mp->mask_len = ntohl (vec_len (mask));
11402   clib_memcpy (mp->mask, mask, vec_len (mask));
11403
11404   vec_free (mask);
11405
11406   S (mp);
11407   W (ret);
11408   return ret;
11409 }
11410
11411 #if VPP_API_TEST_BUILTIN == 0
11412 uword
11413 unformat_l4_match (unformat_input_t * input, va_list * args)
11414 {
11415   u8 **matchp = va_arg (*args, u8 **);
11416
11417   u8 *proto_header = 0;
11418   int src_port = 0;
11419   int dst_port = 0;
11420
11421   tcpudp_header_t h;
11422
11423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (input, "src_port %d", &src_port))
11426         ;
11427       else if (unformat (input, "dst_port %d", &dst_port))
11428         ;
11429       else
11430         return 0;
11431     }
11432
11433   h.src_port = clib_host_to_net_u16 (src_port);
11434   h.dst_port = clib_host_to_net_u16 (dst_port);
11435   vec_validate (proto_header, sizeof (h) - 1);
11436   memcpy (proto_header, &h, sizeof (h));
11437
11438   *matchp = proto_header;
11439
11440   return 1;
11441 }
11442
11443 uword
11444 unformat_ip4_match (unformat_input_t * input, va_list * args)
11445 {
11446   u8 **matchp = va_arg (*args, u8 **);
11447   u8 *match = 0;
11448   ip4_header_t *ip;
11449   int version = 0;
11450   u32 version_val;
11451   int hdr_length = 0;
11452   u32 hdr_length_val;
11453   int src = 0, dst = 0;
11454   ip4_address_t src_val, dst_val;
11455   int proto = 0;
11456   u32 proto_val;
11457   int tos = 0;
11458   u32 tos_val;
11459   int length = 0;
11460   u32 length_val;
11461   int fragment_id = 0;
11462   u32 fragment_id_val;
11463   int ttl = 0;
11464   int ttl_val;
11465   int checksum = 0;
11466   u32 checksum_val;
11467
11468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11469     {
11470       if (unformat (input, "version %d", &version_val))
11471         version = 1;
11472       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11473         hdr_length = 1;
11474       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11475         src = 1;
11476       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11477         dst = 1;
11478       else if (unformat (input, "proto %d", &proto_val))
11479         proto = 1;
11480       else if (unformat (input, "tos %d", &tos_val))
11481         tos = 1;
11482       else if (unformat (input, "length %d", &length_val))
11483         length = 1;
11484       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11485         fragment_id = 1;
11486       else if (unformat (input, "ttl %d", &ttl_val))
11487         ttl = 1;
11488       else if (unformat (input, "checksum %d", &checksum_val))
11489         checksum = 1;
11490       else
11491         break;
11492     }
11493
11494   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11495       + ttl + checksum == 0)
11496     return 0;
11497
11498   /*
11499    * Aligned because we use the real comparison functions
11500    */
11501   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11502
11503   ip = (ip4_header_t *) match;
11504
11505   /* These are realistically matched in practice */
11506   if (src)
11507     ip->src_address.as_u32 = src_val.as_u32;
11508
11509   if (dst)
11510     ip->dst_address.as_u32 = dst_val.as_u32;
11511
11512   if (proto)
11513     ip->protocol = proto_val;
11514
11515
11516   /* These are not, but they're included for completeness */
11517   if (version)
11518     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11519
11520   if (hdr_length)
11521     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11522
11523   if (tos)
11524     ip->tos = tos_val;
11525
11526   if (length)
11527     ip->length = clib_host_to_net_u16 (length_val);
11528
11529   if (ttl)
11530     ip->ttl = ttl_val;
11531
11532   if (checksum)
11533     ip->checksum = clib_host_to_net_u16 (checksum_val);
11534
11535   *matchp = match;
11536   return 1;
11537 }
11538
11539 uword
11540 unformat_ip6_match (unformat_input_t * input, va_list * args)
11541 {
11542   u8 **matchp = va_arg (*args, u8 **);
11543   u8 *match = 0;
11544   ip6_header_t *ip;
11545   int version = 0;
11546   u32 version_val;
11547   u8 traffic_class = 0;
11548   u32 traffic_class_val = 0;
11549   u8 flow_label = 0;
11550   u8 flow_label_val;
11551   int src = 0, dst = 0;
11552   ip6_address_t src_val, dst_val;
11553   int proto = 0;
11554   u32 proto_val;
11555   int payload_length = 0;
11556   u32 payload_length_val;
11557   int hop_limit = 0;
11558   int hop_limit_val;
11559   u32 ip_version_traffic_class_and_flow_label;
11560
11561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11562     {
11563       if (unformat (input, "version %d", &version_val))
11564         version = 1;
11565       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11566         traffic_class = 1;
11567       else if (unformat (input, "flow_label %d", &flow_label_val))
11568         flow_label = 1;
11569       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11570         src = 1;
11571       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11572         dst = 1;
11573       else if (unformat (input, "proto %d", &proto_val))
11574         proto = 1;
11575       else if (unformat (input, "payload_length %d", &payload_length_val))
11576         payload_length = 1;
11577       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11578         hop_limit = 1;
11579       else
11580         break;
11581     }
11582
11583   if (version + traffic_class + flow_label + src + dst + proto +
11584       payload_length + hop_limit == 0)
11585     return 0;
11586
11587   /*
11588    * Aligned because we use the real comparison functions
11589    */
11590   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11591
11592   ip = (ip6_header_t *) match;
11593
11594   if (src)
11595     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11596
11597   if (dst)
11598     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11599
11600   if (proto)
11601     ip->protocol = proto_val;
11602
11603   ip_version_traffic_class_and_flow_label = 0;
11604
11605   if (version)
11606     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11607
11608   if (traffic_class)
11609     ip_version_traffic_class_and_flow_label |=
11610       (traffic_class_val & 0xFF) << 20;
11611
11612   if (flow_label)
11613     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11614
11615   ip->ip_version_traffic_class_and_flow_label =
11616     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11617
11618   if (payload_length)
11619     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11620
11621   if (hop_limit)
11622     ip->hop_limit = hop_limit_val;
11623
11624   *matchp = match;
11625   return 1;
11626 }
11627
11628 uword
11629 unformat_l3_match (unformat_input_t * input, va_list * args)
11630 {
11631   u8 **matchp = va_arg (*args, u8 **);
11632
11633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11634     {
11635       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11636         return 1;
11637       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11638         return 1;
11639       else
11640         break;
11641     }
11642   return 0;
11643 }
11644
11645 uword
11646 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11647 {
11648   u8 *tagp = va_arg (*args, u8 *);
11649   u32 tag;
11650
11651   if (unformat (input, "%d", &tag))
11652     {
11653       tagp[0] = (tag >> 8) & 0x0F;
11654       tagp[1] = tag & 0xFF;
11655       return 1;
11656     }
11657
11658   return 0;
11659 }
11660
11661 uword
11662 unformat_l2_match (unformat_input_t * input, va_list * args)
11663 {
11664   u8 **matchp = va_arg (*args, u8 **);
11665   u8 *match = 0;
11666   u8 src = 0;
11667   u8 src_val[6];
11668   u8 dst = 0;
11669   u8 dst_val[6];
11670   u8 proto = 0;
11671   u16 proto_val;
11672   u8 tag1 = 0;
11673   u8 tag1_val[2];
11674   u8 tag2 = 0;
11675   u8 tag2_val[2];
11676   int len = 14;
11677   u8 ignore_tag1 = 0;
11678   u8 ignore_tag2 = 0;
11679   u8 cos1 = 0;
11680   u8 cos2 = 0;
11681   u32 cos1_val = 0;
11682   u32 cos2_val = 0;
11683
11684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11685     {
11686       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11687         src = 1;
11688       else
11689         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11690         dst = 1;
11691       else if (unformat (input, "proto %U",
11692                          unformat_ethernet_type_host_byte_order, &proto_val))
11693         proto = 1;
11694       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11695         tag1 = 1;
11696       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11697         tag2 = 1;
11698       else if (unformat (input, "ignore-tag1"))
11699         ignore_tag1 = 1;
11700       else if (unformat (input, "ignore-tag2"))
11701         ignore_tag2 = 1;
11702       else if (unformat (input, "cos1 %d", &cos1_val))
11703         cos1 = 1;
11704       else if (unformat (input, "cos2 %d", &cos2_val))
11705         cos2 = 1;
11706       else
11707         break;
11708     }
11709   if ((src + dst + proto + tag1 + tag2 +
11710        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11711     return 0;
11712
11713   if (tag1 || ignore_tag1 || cos1)
11714     len = 18;
11715   if (tag2 || ignore_tag2 || cos2)
11716     len = 22;
11717
11718   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11719
11720   if (dst)
11721     clib_memcpy (match, dst_val, 6);
11722
11723   if (src)
11724     clib_memcpy (match + 6, src_val, 6);
11725
11726   if (tag2)
11727     {
11728       /* inner vlan tag */
11729       match[19] = tag2_val[1];
11730       match[18] = tag2_val[0];
11731       if (cos2)
11732         match[18] |= (cos2_val & 0x7) << 5;
11733       if (proto)
11734         {
11735           match[21] = proto_val & 0xff;
11736           match[20] = proto_val >> 8;
11737         }
11738       if (tag1)
11739         {
11740           match[15] = tag1_val[1];
11741           match[14] = tag1_val[0];
11742         }
11743       if (cos1)
11744         match[14] |= (cos1_val & 0x7) << 5;
11745       *matchp = match;
11746       return 1;
11747     }
11748   if (tag1)
11749     {
11750       match[15] = tag1_val[1];
11751       match[14] = tag1_val[0];
11752       if (proto)
11753         {
11754           match[17] = proto_val & 0xff;
11755           match[16] = proto_val >> 8;
11756         }
11757       if (cos1)
11758         match[14] |= (cos1_val & 0x7) << 5;
11759
11760       *matchp = match;
11761       return 1;
11762     }
11763   if (cos2)
11764     match[18] |= (cos2_val & 0x7) << 5;
11765   if (cos1)
11766     match[14] |= (cos1_val & 0x7) << 5;
11767   if (proto)
11768     {
11769       match[13] = proto_val & 0xff;
11770       match[12] = proto_val >> 8;
11771     }
11772
11773   *matchp = match;
11774   return 1;
11775 }
11776
11777 uword
11778 unformat_qos_source (unformat_input_t * input, va_list * args)
11779 {
11780   int *qs = va_arg (*args, int *);
11781
11782   if (unformat (input, "ip"))
11783     *qs = QOS_SOURCE_IP;
11784   else if (unformat (input, "mpls"))
11785     *qs = QOS_SOURCE_MPLS;
11786   else if (unformat (input, "ext"))
11787     *qs = QOS_SOURCE_EXT;
11788   else if (unformat (input, "vlan"))
11789     *qs = QOS_SOURCE_VLAN;
11790   else
11791     return 0;
11792
11793   return 1;
11794 }
11795 #endif
11796
11797 uword
11798 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11799 {
11800   u8 **matchp = va_arg (*args, u8 **);
11801   u32 skip_n_vectors = va_arg (*args, u32);
11802   u32 match_n_vectors = va_arg (*args, u32);
11803
11804   u8 *match = 0;
11805   u8 *l2 = 0;
11806   u8 *l3 = 0;
11807   u8 *l4 = 0;
11808
11809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11810     {
11811       if (unformat (input, "hex %U", unformat_hex_string, &match))
11812         ;
11813       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11814         ;
11815       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11816         ;
11817       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11818         ;
11819       else
11820         break;
11821     }
11822
11823   if (l4 && !l3)
11824     {
11825       vec_free (match);
11826       vec_free (l2);
11827       vec_free (l4);
11828       return 0;
11829     }
11830
11831   if (match || l2 || l3 || l4)
11832     {
11833       if (l2 || l3 || l4)
11834         {
11835           /* "Win a free Ethernet header in every packet" */
11836           if (l2 == 0)
11837             vec_validate_aligned (l2, 13, sizeof (u32x4));
11838           match = l2;
11839           if (vec_len (l3))
11840             {
11841               vec_append_aligned (match, l3, sizeof (u32x4));
11842               vec_free (l3);
11843             }
11844           if (vec_len (l4))
11845             {
11846               vec_append_aligned (match, l4, sizeof (u32x4));
11847               vec_free (l4);
11848             }
11849         }
11850
11851       /* Make sure the vector is big enough even if key is all 0's */
11852       vec_validate_aligned
11853         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11854          sizeof (u32x4));
11855
11856       /* Set size, include skipped vectors */
11857       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11858
11859       *matchp = match;
11860
11861       return 1;
11862     }
11863
11864   return 0;
11865 }
11866
11867 static int
11868 api_classify_add_del_session (vat_main_t * vam)
11869 {
11870   unformat_input_t *i = vam->input;
11871   vl_api_classify_add_del_session_t *mp;
11872   int is_add = 1;
11873   u32 table_index = ~0;
11874   u32 hit_next_index = ~0;
11875   u32 opaque_index = ~0;
11876   u8 *match = 0;
11877   i32 advance = 0;
11878   u32 skip_n_vectors = 0;
11879   u32 match_n_vectors = 0;
11880   u32 action = 0;
11881   u32 metadata = 0;
11882   int ret;
11883
11884   /*
11885    * Warning: you have to supply skip_n and match_n
11886    * because the API client cant simply look at the classify
11887    * table object.
11888    */
11889
11890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11891     {
11892       if (unformat (i, "del"))
11893         is_add = 0;
11894       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11895                          &hit_next_index))
11896         ;
11897       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11898                          &hit_next_index))
11899         ;
11900       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11901                          &hit_next_index))
11902         ;
11903       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11904         ;
11905       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11906         ;
11907       else if (unformat (i, "opaque-index %d", &opaque_index))
11908         ;
11909       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11910         ;
11911       else if (unformat (i, "match_n %d", &match_n_vectors))
11912         ;
11913       else if (unformat (i, "match %U", api_unformat_classify_match,
11914                          &match, skip_n_vectors, match_n_vectors))
11915         ;
11916       else if (unformat (i, "advance %d", &advance))
11917         ;
11918       else if (unformat (i, "table-index %d", &table_index))
11919         ;
11920       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11921         action = 1;
11922       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11923         action = 2;
11924       else if (unformat (i, "action %d", &action))
11925         ;
11926       else if (unformat (i, "metadata %d", &metadata))
11927         ;
11928       else
11929         break;
11930     }
11931
11932   if (table_index == ~0)
11933     {
11934       errmsg ("Table index required");
11935       return -99;
11936     }
11937
11938   if (is_add && match == 0)
11939     {
11940       errmsg ("Match value required");
11941       return -99;
11942     }
11943
11944   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11945
11946   mp->is_add = is_add;
11947   mp->table_index = ntohl (table_index);
11948   mp->hit_next_index = ntohl (hit_next_index);
11949   mp->opaque_index = ntohl (opaque_index);
11950   mp->advance = ntohl (advance);
11951   mp->action = action;
11952   mp->metadata = ntohl (metadata);
11953   mp->match_len = ntohl (vec_len (match));
11954   clib_memcpy (mp->match, match, vec_len (match));
11955   vec_free (match);
11956
11957   S (mp);
11958   W (ret);
11959   return ret;
11960 }
11961
11962 static int
11963 api_classify_set_interface_ip_table (vat_main_t * vam)
11964 {
11965   unformat_input_t *i = vam->input;
11966   vl_api_classify_set_interface_ip_table_t *mp;
11967   u32 sw_if_index;
11968   int sw_if_index_set;
11969   u32 table_index = ~0;
11970   u8 is_ipv6 = 0;
11971   int ret;
11972
11973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11974     {
11975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11976         sw_if_index_set = 1;
11977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11978         sw_if_index_set = 1;
11979       else if (unformat (i, "table %d", &table_index))
11980         ;
11981       else
11982         {
11983           clib_warning ("parse error '%U'", format_unformat_error, i);
11984           return -99;
11985         }
11986     }
11987
11988   if (sw_if_index_set == 0)
11989     {
11990       errmsg ("missing interface name or sw_if_index");
11991       return -99;
11992     }
11993
11994
11995   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11996
11997   mp->sw_if_index = ntohl (sw_if_index);
11998   mp->table_index = ntohl (table_index);
11999   mp->is_ipv6 = is_ipv6;
12000
12001   S (mp);
12002   W (ret);
12003   return ret;
12004 }
12005
12006 static int
12007 api_classify_set_interface_l2_tables (vat_main_t * vam)
12008 {
12009   unformat_input_t *i = vam->input;
12010   vl_api_classify_set_interface_l2_tables_t *mp;
12011   u32 sw_if_index;
12012   int sw_if_index_set;
12013   u32 ip4_table_index = ~0;
12014   u32 ip6_table_index = ~0;
12015   u32 other_table_index = ~0;
12016   u32 is_input = 1;
12017   int ret;
12018
12019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12022         sw_if_index_set = 1;
12023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12024         sw_if_index_set = 1;
12025       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12026         ;
12027       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12028         ;
12029       else if (unformat (i, "other-table %d", &other_table_index))
12030         ;
12031       else if (unformat (i, "is-input %d", &is_input))
12032         ;
12033       else
12034         {
12035           clib_warning ("parse error '%U'", format_unformat_error, i);
12036           return -99;
12037         }
12038     }
12039
12040   if (sw_if_index_set == 0)
12041     {
12042       errmsg ("missing interface name or sw_if_index");
12043       return -99;
12044     }
12045
12046
12047   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12048
12049   mp->sw_if_index = ntohl (sw_if_index);
12050   mp->ip4_table_index = ntohl (ip4_table_index);
12051   mp->ip6_table_index = ntohl (ip6_table_index);
12052   mp->other_table_index = ntohl (other_table_index);
12053   mp->is_input = (u8) is_input;
12054
12055   S (mp);
12056   W (ret);
12057   return ret;
12058 }
12059
12060 static int
12061 api_set_ipfix_exporter (vat_main_t * vam)
12062 {
12063   unformat_input_t *i = vam->input;
12064   vl_api_set_ipfix_exporter_t *mp;
12065   ip4_address_t collector_address;
12066   u8 collector_address_set = 0;
12067   u32 collector_port = ~0;
12068   ip4_address_t src_address;
12069   u8 src_address_set = 0;
12070   u32 vrf_id = ~0;
12071   u32 path_mtu = ~0;
12072   u32 template_interval = ~0;
12073   u8 udp_checksum = 0;
12074   int ret;
12075
12076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12077     {
12078       if (unformat (i, "collector_address %U", unformat_ip4_address,
12079                     &collector_address))
12080         collector_address_set = 1;
12081       else if (unformat (i, "collector_port %d", &collector_port))
12082         ;
12083       else if (unformat (i, "src_address %U", unformat_ip4_address,
12084                          &src_address))
12085         src_address_set = 1;
12086       else if (unformat (i, "vrf_id %d", &vrf_id))
12087         ;
12088       else if (unformat (i, "path_mtu %d", &path_mtu))
12089         ;
12090       else if (unformat (i, "template_interval %d", &template_interval))
12091         ;
12092       else if (unformat (i, "udp_checksum"))
12093         udp_checksum = 1;
12094       else
12095         break;
12096     }
12097
12098   if (collector_address_set == 0)
12099     {
12100       errmsg ("collector_address required");
12101       return -99;
12102     }
12103
12104   if (src_address_set == 0)
12105     {
12106       errmsg ("src_address required");
12107       return -99;
12108     }
12109
12110   M (SET_IPFIX_EXPORTER, mp);
12111
12112   memcpy (mp->collector_address, collector_address.data,
12113           sizeof (collector_address.data));
12114   mp->collector_port = htons ((u16) collector_port);
12115   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12116   mp->vrf_id = htonl (vrf_id);
12117   mp->path_mtu = htonl (path_mtu);
12118   mp->template_interval = htonl (template_interval);
12119   mp->udp_checksum = udp_checksum;
12120
12121   S (mp);
12122   W (ret);
12123   return ret;
12124 }
12125
12126 static int
12127 api_set_ipfix_classify_stream (vat_main_t * vam)
12128 {
12129   unformat_input_t *i = vam->input;
12130   vl_api_set_ipfix_classify_stream_t *mp;
12131   u32 domain_id = 0;
12132   u32 src_port = UDP_DST_PORT_ipfix;
12133   int ret;
12134
12135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12136     {
12137       if (unformat (i, "domain %d", &domain_id))
12138         ;
12139       else if (unformat (i, "src_port %d", &src_port))
12140         ;
12141       else
12142         {
12143           errmsg ("unknown input `%U'", format_unformat_error, i);
12144           return -99;
12145         }
12146     }
12147
12148   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12149
12150   mp->domain_id = htonl (domain_id);
12151   mp->src_port = htons ((u16) src_port);
12152
12153   S (mp);
12154   W (ret);
12155   return ret;
12156 }
12157
12158 static int
12159 api_ipfix_classify_table_add_del (vat_main_t * vam)
12160 {
12161   unformat_input_t *i = vam->input;
12162   vl_api_ipfix_classify_table_add_del_t *mp;
12163   int is_add = -1;
12164   u32 classify_table_index = ~0;
12165   u8 ip_version = 0;
12166   u8 transport_protocol = 255;
12167   int ret;
12168
12169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12170     {
12171       if (unformat (i, "add"))
12172         is_add = 1;
12173       else if (unformat (i, "del"))
12174         is_add = 0;
12175       else if (unformat (i, "table %d", &classify_table_index))
12176         ;
12177       else if (unformat (i, "ip4"))
12178         ip_version = 4;
12179       else if (unformat (i, "ip6"))
12180         ip_version = 6;
12181       else if (unformat (i, "tcp"))
12182         transport_protocol = 6;
12183       else if (unformat (i, "udp"))
12184         transport_protocol = 17;
12185       else
12186         {
12187           errmsg ("unknown input `%U'", format_unformat_error, i);
12188           return -99;
12189         }
12190     }
12191
12192   if (is_add == -1)
12193     {
12194       errmsg ("expecting: add|del");
12195       return -99;
12196     }
12197   if (classify_table_index == ~0)
12198     {
12199       errmsg ("classifier table not specified");
12200       return -99;
12201     }
12202   if (ip_version == 0)
12203     {
12204       errmsg ("IP version not specified");
12205       return -99;
12206     }
12207
12208   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12209
12210   mp->is_add = is_add;
12211   mp->table_id = htonl (classify_table_index);
12212   mp->ip_version = ip_version;
12213   mp->transport_protocol = transport_protocol;
12214
12215   S (mp);
12216   W (ret);
12217   return ret;
12218 }
12219
12220 static int
12221 api_get_node_index (vat_main_t * vam)
12222 {
12223   unformat_input_t *i = vam->input;
12224   vl_api_get_node_index_t *mp;
12225   u8 *name = 0;
12226   int ret;
12227
12228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12229     {
12230       if (unformat (i, "node %s", &name))
12231         ;
12232       else
12233         break;
12234     }
12235   if (name == 0)
12236     {
12237       errmsg ("node name required");
12238       return -99;
12239     }
12240   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12241     {
12242       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12243       return -99;
12244     }
12245
12246   M (GET_NODE_INDEX, mp);
12247   clib_memcpy (mp->node_name, name, vec_len (name));
12248   vec_free (name);
12249
12250   S (mp);
12251   W (ret);
12252   return ret;
12253 }
12254
12255 static int
12256 api_get_next_index (vat_main_t * vam)
12257 {
12258   unformat_input_t *i = vam->input;
12259   vl_api_get_next_index_t *mp;
12260   u8 *node_name = 0, *next_node_name = 0;
12261   int ret;
12262
12263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12264     {
12265       if (unformat (i, "node-name %s", &node_name))
12266         ;
12267       else if (unformat (i, "next-node-name %s", &next_node_name))
12268         break;
12269     }
12270
12271   if (node_name == 0)
12272     {
12273       errmsg ("node name required");
12274       return -99;
12275     }
12276   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12277     {
12278       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12279       return -99;
12280     }
12281
12282   if (next_node_name == 0)
12283     {
12284       errmsg ("next node name required");
12285       return -99;
12286     }
12287   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12288     {
12289       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12290       return -99;
12291     }
12292
12293   M (GET_NEXT_INDEX, mp);
12294   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12295   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12296   vec_free (node_name);
12297   vec_free (next_node_name);
12298
12299   S (mp);
12300   W (ret);
12301   return ret;
12302 }
12303
12304 static int
12305 api_add_node_next (vat_main_t * vam)
12306 {
12307   unformat_input_t *i = vam->input;
12308   vl_api_add_node_next_t *mp;
12309   u8 *name = 0;
12310   u8 *next = 0;
12311   int ret;
12312
12313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12314     {
12315       if (unformat (i, "node %s", &name))
12316         ;
12317       else if (unformat (i, "next %s", &next))
12318         ;
12319       else
12320         break;
12321     }
12322   if (name == 0)
12323     {
12324       errmsg ("node name required");
12325       return -99;
12326     }
12327   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12328     {
12329       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12330       return -99;
12331     }
12332   if (next == 0)
12333     {
12334       errmsg ("next node required");
12335       return -99;
12336     }
12337   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12338     {
12339       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12340       return -99;
12341     }
12342
12343   M (ADD_NODE_NEXT, mp);
12344   clib_memcpy (mp->node_name, name, vec_len (name));
12345   clib_memcpy (mp->next_name, next, vec_len (next));
12346   vec_free (name);
12347   vec_free (next);
12348
12349   S (mp);
12350   W (ret);
12351   return ret;
12352 }
12353
12354 static int
12355 api_l2tpv3_create_tunnel (vat_main_t * vam)
12356 {
12357   unformat_input_t *i = vam->input;
12358   ip6_address_t client_address, our_address;
12359   int client_address_set = 0;
12360   int our_address_set = 0;
12361   u32 local_session_id = 0;
12362   u32 remote_session_id = 0;
12363   u64 local_cookie = 0;
12364   u64 remote_cookie = 0;
12365   u8 l2_sublayer_present = 0;
12366   vl_api_l2tpv3_create_tunnel_t *mp;
12367   int ret;
12368
12369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12370     {
12371       if (unformat (i, "client_address %U", unformat_ip6_address,
12372                     &client_address))
12373         client_address_set = 1;
12374       else if (unformat (i, "our_address %U", unformat_ip6_address,
12375                          &our_address))
12376         our_address_set = 1;
12377       else if (unformat (i, "local_session_id %d", &local_session_id))
12378         ;
12379       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12380         ;
12381       else if (unformat (i, "local_cookie %lld", &local_cookie))
12382         ;
12383       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12384         ;
12385       else if (unformat (i, "l2-sublayer-present"))
12386         l2_sublayer_present = 1;
12387       else
12388         break;
12389     }
12390
12391   if (client_address_set == 0)
12392     {
12393       errmsg ("client_address required");
12394       return -99;
12395     }
12396
12397   if (our_address_set == 0)
12398     {
12399       errmsg ("our_address required");
12400       return -99;
12401     }
12402
12403   M (L2TPV3_CREATE_TUNNEL, mp);
12404
12405   clib_memcpy (mp->client_address, client_address.as_u8,
12406                sizeof (mp->client_address));
12407
12408   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12409
12410   mp->local_session_id = ntohl (local_session_id);
12411   mp->remote_session_id = ntohl (remote_session_id);
12412   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12413   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12414   mp->l2_sublayer_present = l2_sublayer_present;
12415   mp->is_ipv6 = 1;
12416
12417   S (mp);
12418   W (ret);
12419   return ret;
12420 }
12421
12422 static int
12423 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12424 {
12425   unformat_input_t *i = vam->input;
12426   u32 sw_if_index;
12427   u8 sw_if_index_set = 0;
12428   u64 new_local_cookie = 0;
12429   u64 new_remote_cookie = 0;
12430   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12431   int ret;
12432
12433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12434     {
12435       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12436         sw_if_index_set = 1;
12437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12438         sw_if_index_set = 1;
12439       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12440         ;
12441       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12442         ;
12443       else
12444         break;
12445     }
12446
12447   if (sw_if_index_set == 0)
12448     {
12449       errmsg ("missing interface name or sw_if_index");
12450       return -99;
12451     }
12452
12453   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12454
12455   mp->sw_if_index = ntohl (sw_if_index);
12456   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12457   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12458
12459   S (mp);
12460   W (ret);
12461   return ret;
12462 }
12463
12464 static int
12465 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12466 {
12467   unformat_input_t *i = vam->input;
12468   vl_api_l2tpv3_interface_enable_disable_t *mp;
12469   u32 sw_if_index;
12470   u8 sw_if_index_set = 0;
12471   u8 enable_disable = 1;
12472   int ret;
12473
12474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12475     {
12476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12477         sw_if_index_set = 1;
12478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12479         sw_if_index_set = 1;
12480       else if (unformat (i, "enable"))
12481         enable_disable = 1;
12482       else if (unformat (i, "disable"))
12483         enable_disable = 0;
12484       else
12485         break;
12486     }
12487
12488   if (sw_if_index_set == 0)
12489     {
12490       errmsg ("missing interface name or sw_if_index");
12491       return -99;
12492     }
12493
12494   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12495
12496   mp->sw_if_index = ntohl (sw_if_index);
12497   mp->enable_disable = enable_disable;
12498
12499   S (mp);
12500   W (ret);
12501   return ret;
12502 }
12503
12504 static int
12505 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12506 {
12507   unformat_input_t *i = vam->input;
12508   vl_api_l2tpv3_set_lookup_key_t *mp;
12509   u8 key = ~0;
12510   int ret;
12511
12512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12513     {
12514       if (unformat (i, "lookup_v6_src"))
12515         key = L2T_LOOKUP_SRC_ADDRESS;
12516       else if (unformat (i, "lookup_v6_dst"))
12517         key = L2T_LOOKUP_DST_ADDRESS;
12518       else if (unformat (i, "lookup_session_id"))
12519         key = L2T_LOOKUP_SESSION_ID;
12520       else
12521         break;
12522     }
12523
12524   if (key == (u8) ~ 0)
12525     {
12526       errmsg ("l2tp session lookup key unset");
12527       return -99;
12528     }
12529
12530   M (L2TPV3_SET_LOOKUP_KEY, mp);
12531
12532   mp->key = key;
12533
12534   S (mp);
12535   W (ret);
12536   return ret;
12537 }
12538
12539 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12540   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12541 {
12542   vat_main_t *vam = &vat_main;
12543
12544   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12545          format_ip6_address, mp->our_address,
12546          format_ip6_address, mp->client_address,
12547          clib_net_to_host_u32 (mp->sw_if_index));
12548
12549   print (vam->ofp,
12550          "   local cookies %016llx %016llx remote cookie %016llx",
12551          clib_net_to_host_u64 (mp->local_cookie[0]),
12552          clib_net_to_host_u64 (mp->local_cookie[1]),
12553          clib_net_to_host_u64 (mp->remote_cookie));
12554
12555   print (vam->ofp, "   local session-id %d remote session-id %d",
12556          clib_net_to_host_u32 (mp->local_session_id),
12557          clib_net_to_host_u32 (mp->remote_session_id));
12558
12559   print (vam->ofp, "   l2 specific sublayer %s\n",
12560          mp->l2_sublayer_present ? "preset" : "absent");
12561
12562 }
12563
12564 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12565   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12566 {
12567   vat_main_t *vam = &vat_main;
12568   vat_json_node_t *node = NULL;
12569   struct in6_addr addr;
12570
12571   if (VAT_JSON_ARRAY != vam->json_tree.type)
12572     {
12573       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12574       vat_json_init_array (&vam->json_tree);
12575     }
12576   node = vat_json_array_add (&vam->json_tree);
12577
12578   vat_json_init_object (node);
12579
12580   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12581   vat_json_object_add_ip6 (node, "our_address", addr);
12582   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12583   vat_json_object_add_ip6 (node, "client_address", addr);
12584
12585   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12586   vat_json_init_array (lc);
12587   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12588   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12589   vat_json_object_add_uint (node, "remote_cookie",
12590                             clib_net_to_host_u64 (mp->remote_cookie));
12591
12592   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12593   vat_json_object_add_uint (node, "local_session_id",
12594                             clib_net_to_host_u32 (mp->local_session_id));
12595   vat_json_object_add_uint (node, "remote_session_id",
12596                             clib_net_to_host_u32 (mp->remote_session_id));
12597   vat_json_object_add_string_copy (node, "l2_sublayer",
12598                                    mp->l2_sublayer_present ? (u8 *) "present"
12599                                    : (u8 *) "absent");
12600 }
12601
12602 static int
12603 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12604 {
12605   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12606   vl_api_control_ping_t *mp_ping;
12607   int ret;
12608
12609   /* Get list of l2tpv3-tunnel interfaces */
12610   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12611   S (mp);
12612
12613   /* Use a control ping for synchronization */
12614   MPING (CONTROL_PING, mp_ping);
12615   S (mp_ping);
12616
12617   W (ret);
12618   return ret;
12619 }
12620
12621
12622 static void vl_api_sw_interface_tap_details_t_handler
12623   (vl_api_sw_interface_tap_details_t * mp)
12624 {
12625   vat_main_t *vam = &vat_main;
12626
12627   print (vam->ofp, "%-16s %d",
12628          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12629 }
12630
12631 static void vl_api_sw_interface_tap_details_t_handler_json
12632   (vl_api_sw_interface_tap_details_t * mp)
12633 {
12634   vat_main_t *vam = &vat_main;
12635   vat_json_node_t *node = NULL;
12636
12637   if (VAT_JSON_ARRAY != vam->json_tree.type)
12638     {
12639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12640       vat_json_init_array (&vam->json_tree);
12641     }
12642   node = vat_json_array_add (&vam->json_tree);
12643
12644   vat_json_init_object (node);
12645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12646   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12647 }
12648
12649 static int
12650 api_sw_interface_tap_dump (vat_main_t * vam)
12651 {
12652   vl_api_sw_interface_tap_dump_t *mp;
12653   vl_api_control_ping_t *mp_ping;
12654   int ret;
12655
12656   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12657   /* Get list of tap interfaces */
12658   M (SW_INTERFACE_TAP_DUMP, mp);
12659   S (mp);
12660
12661   /* Use a control ping for synchronization */
12662   MPING (CONTROL_PING, mp_ping);
12663   S (mp_ping);
12664
12665   W (ret);
12666   return ret;
12667 }
12668
12669 static void vl_api_sw_interface_tap_v2_details_t_handler
12670   (vl_api_sw_interface_tap_v2_details_t * mp)
12671 {
12672   vat_main_t *vam = &vat_main;
12673
12674   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12675                     mp->host_ip4_prefix_len);
12676   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12677                     mp->host_ip6_prefix_len);
12678
12679   print (vam->ofp,
12680          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12681          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12682          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12683          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12684          mp->host_bridge, ip4, ip6);
12685
12686   vec_free (ip4);
12687   vec_free (ip6);
12688 }
12689
12690 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12691   (vl_api_sw_interface_tap_v2_details_t * mp)
12692 {
12693   vat_main_t *vam = &vat_main;
12694   vat_json_node_t *node = NULL;
12695
12696   if (VAT_JSON_ARRAY != vam->json_tree.type)
12697     {
12698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12699       vat_json_init_array (&vam->json_tree);
12700     }
12701   node = vat_json_array_add (&vam->json_tree);
12702
12703   vat_json_init_object (node);
12704   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12706   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12707   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12708   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12709   vat_json_object_add_string_copy (node, "host_mac_addr",
12710                                    format (0, "%U", format_ethernet_address,
12711                                            &mp->host_mac_addr));
12712   vat_json_object_add_string_copy (node, "host_namespace",
12713                                    mp->host_namespace);
12714   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12715   vat_json_object_add_string_copy (node, "host_ip4_addr",
12716                                    format (0, "%U/%d", format_ip4_address,
12717                                            mp->host_ip4_addr,
12718                                            mp->host_ip4_prefix_len));
12719   vat_json_object_add_string_copy (node, "host_ip6_addr",
12720                                    format (0, "%U/%d", format_ip6_address,
12721                                            mp->host_ip6_addr,
12722                                            mp->host_ip6_prefix_len));
12723
12724 }
12725
12726 static int
12727 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12728 {
12729   vl_api_sw_interface_tap_v2_dump_t *mp;
12730   vl_api_control_ping_t *mp_ping;
12731   int ret;
12732
12733   print (vam->ofp,
12734          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12735          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12736          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12737          "host_ip6_addr");
12738
12739   /* Get list of tap interfaces */
12740   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12741   S (mp);
12742
12743   /* Use a control ping for synchronization */
12744   MPING (CONTROL_PING, mp_ping);
12745   S (mp_ping);
12746
12747   W (ret);
12748   return ret;
12749 }
12750
12751 static int
12752 api_vxlan_offload_rx (vat_main_t * vam)
12753 {
12754   unformat_input_t *line_input = vam->input;
12755   vl_api_vxlan_offload_rx_t *mp;
12756   u32 hw_if_index = ~0, rx_if_index = ~0;
12757   u8 is_add = 1;
12758   int ret;
12759
12760   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12761     {
12762       if (unformat (line_input, "del"))
12763         is_add = 0;
12764       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12765                          &hw_if_index))
12766         ;
12767       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12768         ;
12769       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12770                          &rx_if_index))
12771         ;
12772       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12773         ;
12774       else
12775         {
12776           errmsg ("parse error '%U'", format_unformat_error, line_input);
12777           return -99;
12778         }
12779     }
12780
12781   if (hw_if_index == ~0)
12782     {
12783       errmsg ("no hw interface");
12784       return -99;
12785     }
12786
12787   if (rx_if_index == ~0)
12788     {
12789       errmsg ("no rx tunnel");
12790       return -99;
12791     }
12792
12793   M (VXLAN_OFFLOAD_RX, mp);
12794
12795   mp->hw_if_index = ntohl (hw_if_index);
12796   mp->sw_if_index = ntohl (rx_if_index);
12797   mp->enable = is_add;
12798
12799   S (mp);
12800   W (ret);
12801   return ret;
12802 }
12803
12804 static uword unformat_vxlan_decap_next
12805   (unformat_input_t * input, va_list * args)
12806 {
12807   u32 *result = va_arg (*args, u32 *);
12808   u32 tmp;
12809
12810   if (unformat (input, "l2"))
12811     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12812   else if (unformat (input, "%d", &tmp))
12813     *result = tmp;
12814   else
12815     return 0;
12816   return 1;
12817 }
12818
12819 static int
12820 api_vxlan_add_del_tunnel (vat_main_t * vam)
12821 {
12822   unformat_input_t *line_input = vam->input;
12823   vl_api_vxlan_add_del_tunnel_t *mp;
12824   ip46_address_t src, dst;
12825   u8 is_add = 1;
12826   u8 ipv4_set = 0, ipv6_set = 0;
12827   u8 src_set = 0;
12828   u8 dst_set = 0;
12829   u8 grp_set = 0;
12830   u32 instance = ~0;
12831   u32 mcast_sw_if_index = ~0;
12832   u32 encap_vrf_id = 0;
12833   u32 decap_next_index = ~0;
12834   u32 vni = 0;
12835   int ret;
12836
12837   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12838   clib_memset (&src, 0, sizeof src);
12839   clib_memset (&dst, 0, sizeof dst);
12840
12841   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12842     {
12843       if (unformat (line_input, "del"))
12844         is_add = 0;
12845       else if (unformat (line_input, "instance %d", &instance))
12846         ;
12847       else
12848         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12849         {
12850           ipv4_set = 1;
12851           src_set = 1;
12852         }
12853       else
12854         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12855         {
12856           ipv4_set = 1;
12857           dst_set = 1;
12858         }
12859       else
12860         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12861         {
12862           ipv6_set = 1;
12863           src_set = 1;
12864         }
12865       else
12866         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12867         {
12868           ipv6_set = 1;
12869           dst_set = 1;
12870         }
12871       else if (unformat (line_input, "group %U %U",
12872                          unformat_ip4_address, &dst.ip4,
12873                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12874         {
12875           grp_set = dst_set = 1;
12876           ipv4_set = 1;
12877         }
12878       else if (unformat (line_input, "group %U",
12879                          unformat_ip4_address, &dst.ip4))
12880         {
12881           grp_set = dst_set = 1;
12882           ipv4_set = 1;
12883         }
12884       else if (unformat (line_input, "group %U %U",
12885                          unformat_ip6_address, &dst.ip6,
12886                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12887         {
12888           grp_set = dst_set = 1;
12889           ipv6_set = 1;
12890         }
12891       else if (unformat (line_input, "group %U",
12892                          unformat_ip6_address, &dst.ip6))
12893         {
12894           grp_set = dst_set = 1;
12895           ipv6_set = 1;
12896         }
12897       else
12898         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12899         ;
12900       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12901         ;
12902       else if (unformat (line_input, "decap-next %U",
12903                          unformat_vxlan_decap_next, &decap_next_index))
12904         ;
12905       else if (unformat (line_input, "vni %d", &vni))
12906         ;
12907       else
12908         {
12909           errmsg ("parse error '%U'", format_unformat_error, line_input);
12910           return -99;
12911         }
12912     }
12913
12914   if (src_set == 0)
12915     {
12916       errmsg ("tunnel src address not specified");
12917       return -99;
12918     }
12919   if (dst_set == 0)
12920     {
12921       errmsg ("tunnel dst address not specified");
12922       return -99;
12923     }
12924
12925   if (grp_set && !ip46_address_is_multicast (&dst))
12926     {
12927       errmsg ("tunnel group address not multicast");
12928       return -99;
12929     }
12930   if (grp_set && mcast_sw_if_index == ~0)
12931     {
12932       errmsg ("tunnel nonexistent multicast device");
12933       return -99;
12934     }
12935   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12936     {
12937       errmsg ("tunnel dst address must be unicast");
12938       return -99;
12939     }
12940
12941
12942   if (ipv4_set && ipv6_set)
12943     {
12944       errmsg ("both IPv4 and IPv6 addresses specified");
12945       return -99;
12946     }
12947
12948   if ((vni == 0) || (vni >> 24))
12949     {
12950       errmsg ("vni not specified or out of range");
12951       return -99;
12952     }
12953
12954   M (VXLAN_ADD_DEL_TUNNEL, mp);
12955
12956   if (ipv6_set)
12957     {
12958       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12959       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12960     }
12961   else
12962     {
12963       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12964       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12965     }
12966
12967   mp->instance = htonl (instance);
12968   mp->encap_vrf_id = ntohl (encap_vrf_id);
12969   mp->decap_next_index = ntohl (decap_next_index);
12970   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12971   mp->vni = ntohl (vni);
12972   mp->is_add = is_add;
12973   mp->is_ipv6 = ipv6_set;
12974
12975   S (mp);
12976   W (ret);
12977   return ret;
12978 }
12979
12980 static void vl_api_vxlan_tunnel_details_t_handler
12981   (vl_api_vxlan_tunnel_details_t * mp)
12982 {
12983   vat_main_t *vam = &vat_main;
12984   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12985   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12986
12987   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12988          ntohl (mp->sw_if_index),
12989          ntohl (mp->instance),
12990          format_ip46_address, &src, IP46_TYPE_ANY,
12991          format_ip46_address, &dst, IP46_TYPE_ANY,
12992          ntohl (mp->encap_vrf_id),
12993          ntohl (mp->decap_next_index), ntohl (mp->vni),
12994          ntohl (mp->mcast_sw_if_index));
12995 }
12996
12997 static void vl_api_vxlan_tunnel_details_t_handler_json
12998   (vl_api_vxlan_tunnel_details_t * mp)
12999 {
13000   vat_main_t *vam = &vat_main;
13001   vat_json_node_t *node = NULL;
13002
13003   if (VAT_JSON_ARRAY != vam->json_tree.type)
13004     {
13005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13006       vat_json_init_array (&vam->json_tree);
13007     }
13008   node = vat_json_array_add (&vam->json_tree);
13009
13010   vat_json_init_object (node);
13011   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13012
13013   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13014
13015   if (mp->is_ipv6)
13016     {
13017       struct in6_addr ip6;
13018
13019       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13020       vat_json_object_add_ip6 (node, "src_address", ip6);
13021       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13022       vat_json_object_add_ip6 (node, "dst_address", ip6);
13023     }
13024   else
13025     {
13026       struct in_addr ip4;
13027
13028       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13029       vat_json_object_add_ip4 (node, "src_address", ip4);
13030       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13031       vat_json_object_add_ip4 (node, "dst_address", ip4);
13032     }
13033   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13034   vat_json_object_add_uint (node, "decap_next_index",
13035                             ntohl (mp->decap_next_index));
13036   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13037   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13038   vat_json_object_add_uint (node, "mcast_sw_if_index",
13039                             ntohl (mp->mcast_sw_if_index));
13040 }
13041
13042 static int
13043 api_vxlan_tunnel_dump (vat_main_t * vam)
13044 {
13045   unformat_input_t *i = vam->input;
13046   vl_api_vxlan_tunnel_dump_t *mp;
13047   vl_api_control_ping_t *mp_ping;
13048   u32 sw_if_index;
13049   u8 sw_if_index_set = 0;
13050   int ret;
13051
13052   /* Parse args required to build the message */
13053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13054     {
13055       if (unformat (i, "sw_if_index %d", &sw_if_index))
13056         sw_if_index_set = 1;
13057       else
13058         break;
13059     }
13060
13061   if (sw_if_index_set == 0)
13062     {
13063       sw_if_index = ~0;
13064     }
13065
13066   if (!vam->json_output)
13067     {
13068       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13069              "sw_if_index", "instance", "src_address", "dst_address",
13070              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13071     }
13072
13073   /* Get list of vxlan-tunnel interfaces */
13074   M (VXLAN_TUNNEL_DUMP, mp);
13075
13076   mp->sw_if_index = htonl (sw_if_index);
13077
13078   S (mp);
13079
13080   /* Use a control ping for synchronization */
13081   MPING (CONTROL_PING, mp_ping);
13082   S (mp_ping);
13083
13084   W (ret);
13085   return ret;
13086 }
13087
13088 static uword unformat_geneve_decap_next
13089   (unformat_input_t * input, va_list * args)
13090 {
13091   u32 *result = va_arg (*args, u32 *);
13092   u32 tmp;
13093
13094   if (unformat (input, "l2"))
13095     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13096   else if (unformat (input, "%d", &tmp))
13097     *result = tmp;
13098   else
13099     return 0;
13100   return 1;
13101 }
13102
13103 static int
13104 api_geneve_add_del_tunnel (vat_main_t * vam)
13105 {
13106   unformat_input_t *line_input = vam->input;
13107   vl_api_geneve_add_del_tunnel_t *mp;
13108   ip46_address_t src, dst;
13109   u8 is_add = 1;
13110   u8 ipv4_set = 0, ipv6_set = 0;
13111   u8 src_set = 0;
13112   u8 dst_set = 0;
13113   u8 grp_set = 0;
13114   u32 mcast_sw_if_index = ~0;
13115   u32 encap_vrf_id = 0;
13116   u32 decap_next_index = ~0;
13117   u32 vni = 0;
13118   int ret;
13119
13120   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13121   clib_memset (&src, 0, sizeof src);
13122   clib_memset (&dst, 0, sizeof dst);
13123
13124   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13125     {
13126       if (unformat (line_input, "del"))
13127         is_add = 0;
13128       else
13129         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13130         {
13131           ipv4_set = 1;
13132           src_set = 1;
13133         }
13134       else
13135         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13136         {
13137           ipv4_set = 1;
13138           dst_set = 1;
13139         }
13140       else
13141         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13142         {
13143           ipv6_set = 1;
13144           src_set = 1;
13145         }
13146       else
13147         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13148         {
13149           ipv6_set = 1;
13150           dst_set = 1;
13151         }
13152       else if (unformat (line_input, "group %U %U",
13153                          unformat_ip4_address, &dst.ip4,
13154                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13155         {
13156           grp_set = dst_set = 1;
13157           ipv4_set = 1;
13158         }
13159       else if (unformat (line_input, "group %U",
13160                          unformat_ip4_address, &dst.ip4))
13161         {
13162           grp_set = dst_set = 1;
13163           ipv4_set = 1;
13164         }
13165       else if (unformat (line_input, "group %U %U",
13166                          unformat_ip6_address, &dst.ip6,
13167                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13168         {
13169           grp_set = dst_set = 1;
13170           ipv6_set = 1;
13171         }
13172       else if (unformat (line_input, "group %U",
13173                          unformat_ip6_address, &dst.ip6))
13174         {
13175           grp_set = dst_set = 1;
13176           ipv6_set = 1;
13177         }
13178       else
13179         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13180         ;
13181       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13182         ;
13183       else if (unformat (line_input, "decap-next %U",
13184                          unformat_geneve_decap_next, &decap_next_index))
13185         ;
13186       else if (unformat (line_input, "vni %d", &vni))
13187         ;
13188       else
13189         {
13190           errmsg ("parse error '%U'", format_unformat_error, line_input);
13191           return -99;
13192         }
13193     }
13194
13195   if (src_set == 0)
13196     {
13197       errmsg ("tunnel src address not specified");
13198       return -99;
13199     }
13200   if (dst_set == 0)
13201     {
13202       errmsg ("tunnel dst address not specified");
13203       return -99;
13204     }
13205
13206   if (grp_set && !ip46_address_is_multicast (&dst))
13207     {
13208       errmsg ("tunnel group address not multicast");
13209       return -99;
13210     }
13211   if (grp_set && mcast_sw_if_index == ~0)
13212     {
13213       errmsg ("tunnel nonexistent multicast device");
13214       return -99;
13215     }
13216   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13217     {
13218       errmsg ("tunnel dst address must be unicast");
13219       return -99;
13220     }
13221
13222
13223   if (ipv4_set && ipv6_set)
13224     {
13225       errmsg ("both IPv4 and IPv6 addresses specified");
13226       return -99;
13227     }
13228
13229   if ((vni == 0) || (vni >> 24))
13230     {
13231       errmsg ("vni not specified or out of range");
13232       return -99;
13233     }
13234
13235   M (GENEVE_ADD_DEL_TUNNEL, mp);
13236
13237   if (ipv6_set)
13238     {
13239       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13240       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13241     }
13242   else
13243     {
13244       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13245       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13246     }
13247   mp->encap_vrf_id = ntohl (encap_vrf_id);
13248   mp->decap_next_index = ntohl (decap_next_index);
13249   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13250   mp->vni = ntohl (vni);
13251   mp->is_add = is_add;
13252   mp->is_ipv6 = ipv6_set;
13253
13254   S (mp);
13255   W (ret);
13256   return ret;
13257 }
13258
13259 static void vl_api_geneve_tunnel_details_t_handler
13260   (vl_api_geneve_tunnel_details_t * mp)
13261 {
13262   vat_main_t *vam = &vat_main;
13263   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13264   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13265
13266   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13267          ntohl (mp->sw_if_index),
13268          format_ip46_address, &src, IP46_TYPE_ANY,
13269          format_ip46_address, &dst, IP46_TYPE_ANY,
13270          ntohl (mp->encap_vrf_id),
13271          ntohl (mp->decap_next_index), ntohl (mp->vni),
13272          ntohl (mp->mcast_sw_if_index));
13273 }
13274
13275 static void vl_api_geneve_tunnel_details_t_handler_json
13276   (vl_api_geneve_tunnel_details_t * mp)
13277 {
13278   vat_main_t *vam = &vat_main;
13279   vat_json_node_t *node = NULL;
13280
13281   if (VAT_JSON_ARRAY != vam->json_tree.type)
13282     {
13283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13284       vat_json_init_array (&vam->json_tree);
13285     }
13286   node = vat_json_array_add (&vam->json_tree);
13287
13288   vat_json_init_object (node);
13289   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13290   if (mp->is_ipv6)
13291     {
13292       struct in6_addr ip6;
13293
13294       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13295       vat_json_object_add_ip6 (node, "src_address", ip6);
13296       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13297       vat_json_object_add_ip6 (node, "dst_address", ip6);
13298     }
13299   else
13300     {
13301       struct in_addr ip4;
13302
13303       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13304       vat_json_object_add_ip4 (node, "src_address", ip4);
13305       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13306       vat_json_object_add_ip4 (node, "dst_address", ip4);
13307     }
13308   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13309   vat_json_object_add_uint (node, "decap_next_index",
13310                             ntohl (mp->decap_next_index));
13311   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13312   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13313   vat_json_object_add_uint (node, "mcast_sw_if_index",
13314                             ntohl (mp->mcast_sw_if_index));
13315 }
13316
13317 static int
13318 api_geneve_tunnel_dump (vat_main_t * vam)
13319 {
13320   unformat_input_t *i = vam->input;
13321   vl_api_geneve_tunnel_dump_t *mp;
13322   vl_api_control_ping_t *mp_ping;
13323   u32 sw_if_index;
13324   u8 sw_if_index_set = 0;
13325   int ret;
13326
13327   /* Parse args required to build the message */
13328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13329     {
13330       if (unformat (i, "sw_if_index %d", &sw_if_index))
13331         sw_if_index_set = 1;
13332       else
13333         break;
13334     }
13335
13336   if (sw_if_index_set == 0)
13337     {
13338       sw_if_index = ~0;
13339     }
13340
13341   if (!vam->json_output)
13342     {
13343       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13344              "sw_if_index", "local_address", "remote_address",
13345              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13346     }
13347
13348   /* Get list of geneve-tunnel interfaces */
13349   M (GENEVE_TUNNEL_DUMP, mp);
13350
13351   mp->sw_if_index = htonl (sw_if_index);
13352
13353   S (mp);
13354
13355   /* Use a control ping for synchronization */
13356   M (CONTROL_PING, mp_ping);
13357   S (mp_ping);
13358
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_gre_add_del_tunnel (vat_main_t * vam)
13365 {
13366   unformat_input_t *line_input = vam->input;
13367   vl_api_gre_add_del_tunnel_t *mp;
13368   ip4_address_t src4, dst4;
13369   ip6_address_t src6, dst6;
13370   u8 is_add = 1;
13371   u8 ipv4_set = 0;
13372   u8 ipv6_set = 0;
13373   u8 t_type = GRE_TUNNEL_TYPE_L3;
13374   u8 src_set = 0;
13375   u8 dst_set = 0;
13376   u32 outer_fib_id = 0;
13377   u32 session_id = 0;
13378   u32 instance = ~0;
13379   int ret;
13380
13381   clib_memset (&src4, 0, sizeof src4);
13382   clib_memset (&dst4, 0, sizeof dst4);
13383   clib_memset (&src6, 0, sizeof src6);
13384   clib_memset (&dst6, 0, sizeof dst6);
13385
13386   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13387     {
13388       if (unformat (line_input, "del"))
13389         is_add = 0;
13390       else if (unformat (line_input, "instance %d", &instance))
13391         ;
13392       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13393         {
13394           src_set = 1;
13395           ipv4_set = 1;
13396         }
13397       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13398         {
13399           dst_set = 1;
13400           ipv4_set = 1;
13401         }
13402       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13403         {
13404           src_set = 1;
13405           ipv6_set = 1;
13406         }
13407       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13408         {
13409           dst_set = 1;
13410           ipv6_set = 1;
13411         }
13412       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13413         ;
13414       else if (unformat (line_input, "teb"))
13415         t_type = GRE_TUNNEL_TYPE_TEB;
13416       else if (unformat (line_input, "erspan %d", &session_id))
13417         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13418       else
13419         {
13420           errmsg ("parse error '%U'", format_unformat_error, line_input);
13421           return -99;
13422         }
13423     }
13424
13425   if (src_set == 0)
13426     {
13427       errmsg ("tunnel src address not specified");
13428       return -99;
13429     }
13430   if (dst_set == 0)
13431     {
13432       errmsg ("tunnel dst address not specified");
13433       return -99;
13434     }
13435   if (ipv4_set && ipv6_set)
13436     {
13437       errmsg ("both IPv4 and IPv6 addresses specified");
13438       return -99;
13439     }
13440
13441
13442   M (GRE_ADD_DEL_TUNNEL, mp);
13443
13444   if (ipv4_set)
13445     {
13446       clib_memcpy (&mp->src_address, &src4, 4);
13447       clib_memcpy (&mp->dst_address, &dst4, 4);
13448     }
13449   else
13450     {
13451       clib_memcpy (&mp->src_address, &src6, 16);
13452       clib_memcpy (&mp->dst_address, &dst6, 16);
13453     }
13454   mp->instance = htonl (instance);
13455   mp->outer_fib_id = htonl (outer_fib_id);
13456   mp->is_add = is_add;
13457   mp->session_id = htons ((u16) session_id);
13458   mp->tunnel_type = t_type;
13459   mp->is_ipv6 = ipv6_set;
13460
13461   S (mp);
13462   W (ret);
13463   return ret;
13464 }
13465
13466 static void vl_api_gre_tunnel_details_t_handler
13467   (vl_api_gre_tunnel_details_t * mp)
13468 {
13469   vat_main_t *vam = &vat_main;
13470   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13471   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13472
13473   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13474          ntohl (mp->sw_if_index),
13475          ntohl (mp->instance),
13476          format_ip46_address, &src, IP46_TYPE_ANY,
13477          format_ip46_address, &dst, IP46_TYPE_ANY,
13478          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13479 }
13480
13481 static void vl_api_gre_tunnel_details_t_handler_json
13482   (vl_api_gre_tunnel_details_t * mp)
13483 {
13484   vat_main_t *vam = &vat_main;
13485   vat_json_node_t *node = NULL;
13486   struct in_addr ip4;
13487   struct in6_addr ip6;
13488
13489   if (VAT_JSON_ARRAY != vam->json_tree.type)
13490     {
13491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13492       vat_json_init_array (&vam->json_tree);
13493     }
13494   node = vat_json_array_add (&vam->json_tree);
13495
13496   vat_json_init_object (node);
13497   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13498   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13499   if (!mp->is_ipv6)
13500     {
13501       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13502       vat_json_object_add_ip4 (node, "src_address", ip4);
13503       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13504       vat_json_object_add_ip4 (node, "dst_address", ip4);
13505     }
13506   else
13507     {
13508       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13509       vat_json_object_add_ip6 (node, "src_address", ip6);
13510       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13511       vat_json_object_add_ip6 (node, "dst_address", ip6);
13512     }
13513   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13514   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13515   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13516   vat_json_object_add_uint (node, "session_id", mp->session_id);
13517 }
13518
13519 static int
13520 api_gre_tunnel_dump (vat_main_t * vam)
13521 {
13522   unformat_input_t *i = vam->input;
13523   vl_api_gre_tunnel_dump_t *mp;
13524   vl_api_control_ping_t *mp_ping;
13525   u32 sw_if_index;
13526   u8 sw_if_index_set = 0;
13527   int ret;
13528
13529   /* Parse args required to build the message */
13530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13531     {
13532       if (unformat (i, "sw_if_index %d", &sw_if_index))
13533         sw_if_index_set = 1;
13534       else
13535         break;
13536     }
13537
13538   if (sw_if_index_set == 0)
13539     {
13540       sw_if_index = ~0;
13541     }
13542
13543   if (!vam->json_output)
13544     {
13545       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13546              "sw_if_index", "instance", "src_address", "dst_address",
13547              "tunnel_type", "outer_fib_id", "session_id");
13548     }
13549
13550   /* Get list of gre-tunnel interfaces */
13551   M (GRE_TUNNEL_DUMP, mp);
13552
13553   mp->sw_if_index = htonl (sw_if_index);
13554
13555   S (mp);
13556
13557   /* Use a control ping for synchronization */
13558   MPING (CONTROL_PING, mp_ping);
13559   S (mp_ping);
13560
13561   W (ret);
13562   return ret;
13563 }
13564
13565 static int
13566 api_l2_fib_clear_table (vat_main_t * vam)
13567 {
13568 //  unformat_input_t * i = vam->input;
13569   vl_api_l2_fib_clear_table_t *mp;
13570   int ret;
13571
13572   M (L2_FIB_CLEAR_TABLE, mp);
13573
13574   S (mp);
13575   W (ret);
13576   return ret;
13577 }
13578
13579 static int
13580 api_l2_interface_efp_filter (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_l2_interface_efp_filter_t *mp;
13584   u32 sw_if_index;
13585   u8 enable = 1;
13586   u8 sw_if_index_set = 0;
13587   int ret;
13588
13589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13590     {
13591       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13592         sw_if_index_set = 1;
13593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13594         sw_if_index_set = 1;
13595       else if (unformat (i, "enable"))
13596         enable = 1;
13597       else if (unformat (i, "disable"))
13598         enable = 0;
13599       else
13600         {
13601           clib_warning ("parse error '%U'", format_unformat_error, i);
13602           return -99;
13603         }
13604     }
13605
13606   if (sw_if_index_set == 0)
13607     {
13608       errmsg ("missing sw_if_index");
13609       return -99;
13610     }
13611
13612   M (L2_INTERFACE_EFP_FILTER, mp);
13613
13614   mp->sw_if_index = ntohl (sw_if_index);
13615   mp->enable_disable = enable;
13616
13617   S (mp);
13618   W (ret);
13619   return ret;
13620 }
13621
13622 #define foreach_vtr_op                          \
13623 _("disable",  L2_VTR_DISABLED)                  \
13624 _("push-1",  L2_VTR_PUSH_1)                     \
13625 _("push-2",  L2_VTR_PUSH_2)                     \
13626 _("pop-1",  L2_VTR_POP_1)                       \
13627 _("pop-2",  L2_VTR_POP_2)                       \
13628 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13629 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13630 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13631 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13632
13633 static int
13634 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13635 {
13636   unformat_input_t *i = vam->input;
13637   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13638   u32 sw_if_index;
13639   u8 sw_if_index_set = 0;
13640   u8 vtr_op_set = 0;
13641   u32 vtr_op = 0;
13642   u32 push_dot1q = 1;
13643   u32 tag1 = ~0;
13644   u32 tag2 = ~0;
13645   int ret;
13646
13647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13648     {
13649       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13650         sw_if_index_set = 1;
13651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13652         sw_if_index_set = 1;
13653       else if (unformat (i, "vtr_op %d", &vtr_op))
13654         vtr_op_set = 1;
13655 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13656       foreach_vtr_op
13657 #undef _
13658         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13659         ;
13660       else if (unformat (i, "tag1 %d", &tag1))
13661         ;
13662       else if (unformat (i, "tag2 %d", &tag2))
13663         ;
13664       else
13665         {
13666           clib_warning ("parse error '%U'", format_unformat_error, i);
13667           return -99;
13668         }
13669     }
13670
13671   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13672     {
13673       errmsg ("missing vtr operation or sw_if_index");
13674       return -99;
13675     }
13676
13677   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13678   mp->sw_if_index = ntohl (sw_if_index);
13679   mp->vtr_op = ntohl (vtr_op);
13680   mp->push_dot1q = ntohl (push_dot1q);
13681   mp->tag1 = ntohl (tag1);
13682   mp->tag2 = ntohl (tag2);
13683
13684   S (mp);
13685   W (ret);
13686   return ret;
13687 }
13688
13689 static int
13690 api_create_vhost_user_if (vat_main_t * vam)
13691 {
13692   unformat_input_t *i = vam->input;
13693   vl_api_create_vhost_user_if_t *mp;
13694   u8 *file_name;
13695   u8 is_server = 0;
13696   u8 file_name_set = 0;
13697   u32 custom_dev_instance = ~0;
13698   u8 hwaddr[6];
13699   u8 use_custom_mac = 0;
13700   u8 disable_mrg_rxbuf = 0;
13701   u8 disable_indirect_desc = 0;
13702   u8 *tag = 0;
13703   int ret;
13704
13705   /* Shut up coverity */
13706   clib_memset (hwaddr, 0, sizeof (hwaddr));
13707
13708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (i, "socket %s", &file_name))
13711         {
13712           file_name_set = 1;
13713         }
13714       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13715         ;
13716       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13717         use_custom_mac = 1;
13718       else if (unformat (i, "server"))
13719         is_server = 1;
13720       else if (unformat (i, "disable_mrg_rxbuf"))
13721         disable_mrg_rxbuf = 1;
13722       else if (unformat (i, "disable_indirect_desc"))
13723         disable_indirect_desc = 1;
13724       else if (unformat (i, "tag %s", &tag))
13725         ;
13726       else
13727         break;
13728     }
13729
13730   if (file_name_set == 0)
13731     {
13732       errmsg ("missing socket file name");
13733       return -99;
13734     }
13735
13736   if (vec_len (file_name) > 255)
13737     {
13738       errmsg ("socket file name too long");
13739       return -99;
13740     }
13741   vec_add1 (file_name, 0);
13742
13743   M (CREATE_VHOST_USER_IF, mp);
13744
13745   mp->is_server = is_server;
13746   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13747   mp->disable_indirect_desc = disable_indirect_desc;
13748   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13749   vec_free (file_name);
13750   if (custom_dev_instance != ~0)
13751     {
13752       mp->renumber = 1;
13753       mp->custom_dev_instance = ntohl (custom_dev_instance);
13754     }
13755
13756   mp->use_custom_mac = use_custom_mac;
13757   clib_memcpy (mp->mac_address, hwaddr, 6);
13758   if (tag)
13759     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13760   vec_free (tag);
13761
13762   S (mp);
13763   W (ret);
13764   return ret;
13765 }
13766
13767 static int
13768 api_modify_vhost_user_if (vat_main_t * vam)
13769 {
13770   unformat_input_t *i = vam->input;
13771   vl_api_modify_vhost_user_if_t *mp;
13772   u8 *file_name;
13773   u8 is_server = 0;
13774   u8 file_name_set = 0;
13775   u32 custom_dev_instance = ~0;
13776   u8 sw_if_index_set = 0;
13777   u32 sw_if_index = (u32) ~ 0;
13778   int ret;
13779
13780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13781     {
13782       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13783         sw_if_index_set = 1;
13784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13785         sw_if_index_set = 1;
13786       else if (unformat (i, "socket %s", &file_name))
13787         {
13788           file_name_set = 1;
13789         }
13790       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13791         ;
13792       else if (unformat (i, "server"))
13793         is_server = 1;
13794       else
13795         break;
13796     }
13797
13798   if (sw_if_index_set == 0)
13799     {
13800       errmsg ("missing sw_if_index or interface name");
13801       return -99;
13802     }
13803
13804   if (file_name_set == 0)
13805     {
13806       errmsg ("missing socket file name");
13807       return -99;
13808     }
13809
13810   if (vec_len (file_name) > 255)
13811     {
13812       errmsg ("socket file name too long");
13813       return -99;
13814     }
13815   vec_add1 (file_name, 0);
13816
13817   M (MODIFY_VHOST_USER_IF, mp);
13818
13819   mp->sw_if_index = ntohl (sw_if_index);
13820   mp->is_server = is_server;
13821   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13822   vec_free (file_name);
13823   if (custom_dev_instance != ~0)
13824     {
13825       mp->renumber = 1;
13826       mp->custom_dev_instance = ntohl (custom_dev_instance);
13827     }
13828
13829   S (mp);
13830   W (ret);
13831   return ret;
13832 }
13833
13834 static int
13835 api_delete_vhost_user_if (vat_main_t * vam)
13836 {
13837   unformat_input_t *i = vam->input;
13838   vl_api_delete_vhost_user_if_t *mp;
13839   u32 sw_if_index = ~0;
13840   u8 sw_if_index_set = 0;
13841   int ret;
13842
13843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13844     {
13845       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13846         sw_if_index_set = 1;
13847       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13848         sw_if_index_set = 1;
13849       else
13850         break;
13851     }
13852
13853   if (sw_if_index_set == 0)
13854     {
13855       errmsg ("missing sw_if_index or interface name");
13856       return -99;
13857     }
13858
13859
13860   M (DELETE_VHOST_USER_IF, mp);
13861
13862   mp->sw_if_index = ntohl (sw_if_index);
13863
13864   S (mp);
13865   W (ret);
13866   return ret;
13867 }
13868
13869 static void vl_api_sw_interface_vhost_user_details_t_handler
13870   (vl_api_sw_interface_vhost_user_details_t * mp)
13871 {
13872   vat_main_t *vam = &vat_main;
13873
13874   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13875          (char *) mp->interface_name,
13876          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13877          clib_net_to_host_u64 (mp->features), mp->is_server,
13878          ntohl (mp->num_regions), (char *) mp->sock_filename);
13879   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13880 }
13881
13882 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13883   (vl_api_sw_interface_vhost_user_details_t * mp)
13884 {
13885   vat_main_t *vam = &vat_main;
13886   vat_json_node_t *node = NULL;
13887
13888   if (VAT_JSON_ARRAY != vam->json_tree.type)
13889     {
13890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13891       vat_json_init_array (&vam->json_tree);
13892     }
13893   node = vat_json_array_add (&vam->json_tree);
13894
13895   vat_json_init_object (node);
13896   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13897   vat_json_object_add_string_copy (node, "interface_name",
13898                                    mp->interface_name);
13899   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13900                             ntohl (mp->virtio_net_hdr_sz));
13901   vat_json_object_add_uint (node, "features",
13902                             clib_net_to_host_u64 (mp->features));
13903   vat_json_object_add_uint (node, "is_server", mp->is_server);
13904   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13905   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13906   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13907 }
13908
13909 static int
13910 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13911 {
13912   vl_api_sw_interface_vhost_user_dump_t *mp;
13913   vl_api_control_ping_t *mp_ping;
13914   int ret;
13915   print (vam->ofp,
13916          "Interface name            idx hdr_sz features server regions filename");
13917
13918   /* Get list of vhost-user interfaces */
13919   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13920   S (mp);
13921
13922   /* Use a control ping for synchronization */
13923   MPING (CONTROL_PING, mp_ping);
13924   S (mp_ping);
13925
13926   W (ret);
13927   return ret;
13928 }
13929
13930 static int
13931 api_show_version (vat_main_t * vam)
13932 {
13933   vl_api_show_version_t *mp;
13934   int ret;
13935
13936   M (SHOW_VERSION, mp);
13937
13938   S (mp);
13939   W (ret);
13940   return ret;
13941 }
13942
13943
13944 static int
13945 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13946 {
13947   unformat_input_t *line_input = vam->input;
13948   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13949   ip4_address_t local4, remote4;
13950   ip6_address_t local6, remote6;
13951   u8 is_add = 1;
13952   u8 ipv4_set = 0, ipv6_set = 0;
13953   u8 local_set = 0;
13954   u8 remote_set = 0;
13955   u8 grp_set = 0;
13956   u32 mcast_sw_if_index = ~0;
13957   u32 encap_vrf_id = 0;
13958   u32 decap_vrf_id = 0;
13959   u8 protocol = ~0;
13960   u32 vni;
13961   u8 vni_set = 0;
13962   int ret;
13963
13964   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13965   clib_memset (&local4, 0, sizeof local4);
13966   clib_memset (&remote4, 0, sizeof remote4);
13967   clib_memset (&local6, 0, sizeof local6);
13968   clib_memset (&remote6, 0, sizeof remote6);
13969
13970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (line_input, "del"))
13973         is_add = 0;
13974       else if (unformat (line_input, "local %U",
13975                          unformat_ip4_address, &local4))
13976         {
13977           local_set = 1;
13978           ipv4_set = 1;
13979         }
13980       else if (unformat (line_input, "remote %U",
13981                          unformat_ip4_address, &remote4))
13982         {
13983           remote_set = 1;
13984           ipv4_set = 1;
13985         }
13986       else if (unformat (line_input, "local %U",
13987                          unformat_ip6_address, &local6))
13988         {
13989           local_set = 1;
13990           ipv6_set = 1;
13991         }
13992       else if (unformat (line_input, "remote %U",
13993                          unformat_ip6_address, &remote6))
13994         {
13995           remote_set = 1;
13996           ipv6_set = 1;
13997         }
13998       else if (unformat (line_input, "group %U %U",
13999                          unformat_ip4_address, &remote4,
14000                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14001         {
14002           grp_set = remote_set = 1;
14003           ipv4_set = 1;
14004         }
14005       else if (unformat (line_input, "group %U",
14006                          unformat_ip4_address, &remote4))
14007         {
14008           grp_set = remote_set = 1;
14009           ipv4_set = 1;
14010         }
14011       else if (unformat (line_input, "group %U %U",
14012                          unformat_ip6_address, &remote6,
14013                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14014         {
14015           grp_set = remote_set = 1;
14016           ipv6_set = 1;
14017         }
14018       else if (unformat (line_input, "group %U",
14019                          unformat_ip6_address, &remote6))
14020         {
14021           grp_set = remote_set = 1;
14022           ipv6_set = 1;
14023         }
14024       else
14025         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14026         ;
14027       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14028         ;
14029       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14030         ;
14031       else if (unformat (line_input, "vni %d", &vni))
14032         vni_set = 1;
14033       else if (unformat (line_input, "next-ip4"))
14034         protocol = 1;
14035       else if (unformat (line_input, "next-ip6"))
14036         protocol = 2;
14037       else if (unformat (line_input, "next-ethernet"))
14038         protocol = 3;
14039       else if (unformat (line_input, "next-nsh"))
14040         protocol = 4;
14041       else
14042         {
14043           errmsg ("parse error '%U'", format_unformat_error, line_input);
14044           return -99;
14045         }
14046     }
14047
14048   if (local_set == 0)
14049     {
14050       errmsg ("tunnel local address not specified");
14051       return -99;
14052     }
14053   if (remote_set == 0)
14054     {
14055       errmsg ("tunnel remote address not specified");
14056       return -99;
14057     }
14058   if (grp_set && mcast_sw_if_index == ~0)
14059     {
14060       errmsg ("tunnel nonexistent multicast device");
14061       return -99;
14062     }
14063   if (ipv4_set && ipv6_set)
14064     {
14065       errmsg ("both IPv4 and IPv6 addresses specified");
14066       return -99;
14067     }
14068
14069   if (vni_set == 0)
14070     {
14071       errmsg ("vni not specified");
14072       return -99;
14073     }
14074
14075   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14076
14077
14078   if (ipv6_set)
14079     {
14080       clib_memcpy (&mp->local, &local6, sizeof (local6));
14081       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14082     }
14083   else
14084     {
14085       clib_memcpy (&mp->local, &local4, sizeof (local4));
14086       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14087     }
14088
14089   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14090   mp->encap_vrf_id = ntohl (encap_vrf_id);
14091   mp->decap_vrf_id = ntohl (decap_vrf_id);
14092   mp->protocol = protocol;
14093   mp->vni = ntohl (vni);
14094   mp->is_add = is_add;
14095   mp->is_ipv6 = ipv6_set;
14096
14097   S (mp);
14098   W (ret);
14099   return ret;
14100 }
14101
14102 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14103   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14104 {
14105   vat_main_t *vam = &vat_main;
14106   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14107   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14108
14109   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14110          ntohl (mp->sw_if_index),
14111          format_ip46_address, &local, IP46_TYPE_ANY,
14112          format_ip46_address, &remote, IP46_TYPE_ANY,
14113          ntohl (mp->vni), mp->protocol,
14114          ntohl (mp->mcast_sw_if_index),
14115          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14116 }
14117
14118
14119 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14120   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14121 {
14122   vat_main_t *vam = &vat_main;
14123   vat_json_node_t *node = NULL;
14124   struct in_addr ip4;
14125   struct in6_addr ip6;
14126
14127   if (VAT_JSON_ARRAY != vam->json_tree.type)
14128     {
14129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14130       vat_json_init_array (&vam->json_tree);
14131     }
14132   node = vat_json_array_add (&vam->json_tree);
14133
14134   vat_json_init_object (node);
14135   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14136   if (mp->is_ipv6)
14137     {
14138       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14139       vat_json_object_add_ip6 (node, "local", ip6);
14140       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14141       vat_json_object_add_ip6 (node, "remote", ip6);
14142     }
14143   else
14144     {
14145       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14146       vat_json_object_add_ip4 (node, "local", ip4);
14147       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14148       vat_json_object_add_ip4 (node, "remote", ip4);
14149     }
14150   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14151   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14152   vat_json_object_add_uint (node, "mcast_sw_if_index",
14153                             ntohl (mp->mcast_sw_if_index));
14154   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14155   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14156   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14157 }
14158
14159 static int
14160 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14161 {
14162   unformat_input_t *i = vam->input;
14163   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14164   vl_api_control_ping_t *mp_ping;
14165   u32 sw_if_index;
14166   u8 sw_if_index_set = 0;
14167   int ret;
14168
14169   /* Parse args required to build the message */
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "sw_if_index %d", &sw_if_index))
14173         sw_if_index_set = 1;
14174       else
14175         break;
14176     }
14177
14178   if (sw_if_index_set == 0)
14179     {
14180       sw_if_index = ~0;
14181     }
14182
14183   if (!vam->json_output)
14184     {
14185       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14186              "sw_if_index", "local", "remote", "vni",
14187              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14188     }
14189
14190   /* Get list of vxlan-tunnel interfaces */
14191   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14192
14193   mp->sw_if_index = htonl (sw_if_index);
14194
14195   S (mp);
14196
14197   /* Use a control ping for synchronization */
14198   MPING (CONTROL_PING, mp_ping);
14199   S (mp_ping);
14200
14201   W (ret);
14202   return ret;
14203 }
14204
14205 static void vl_api_l2_fib_table_details_t_handler
14206   (vl_api_l2_fib_table_details_t * mp)
14207 {
14208   vat_main_t *vam = &vat_main;
14209
14210   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14211          "       %d       %d     %d",
14212          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14213          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14214          mp->bvi_mac);
14215 }
14216
14217 static void vl_api_l2_fib_table_details_t_handler_json
14218   (vl_api_l2_fib_table_details_t * mp)
14219 {
14220   vat_main_t *vam = &vat_main;
14221   vat_json_node_t *node = NULL;
14222
14223   if (VAT_JSON_ARRAY != vam->json_tree.type)
14224     {
14225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14226       vat_json_init_array (&vam->json_tree);
14227     }
14228   node = vat_json_array_add (&vam->json_tree);
14229
14230   vat_json_init_object (node);
14231   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14232   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14233   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14234   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14235   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14236   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14237 }
14238
14239 static int
14240 api_l2_fib_table_dump (vat_main_t * vam)
14241 {
14242   unformat_input_t *i = vam->input;
14243   vl_api_l2_fib_table_dump_t *mp;
14244   vl_api_control_ping_t *mp_ping;
14245   u32 bd_id;
14246   u8 bd_id_set = 0;
14247   int ret;
14248
14249   /* Parse args required to build the message */
14250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (i, "bd_id %d", &bd_id))
14253         bd_id_set = 1;
14254       else
14255         break;
14256     }
14257
14258   if (bd_id_set == 0)
14259     {
14260       errmsg ("missing bridge domain");
14261       return -99;
14262     }
14263
14264   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14265
14266   /* Get list of l2 fib entries */
14267   M (L2_FIB_TABLE_DUMP, mp);
14268
14269   mp->bd_id = ntohl (bd_id);
14270   S (mp);
14271
14272   /* Use a control ping for synchronization */
14273   MPING (CONTROL_PING, mp_ping);
14274   S (mp_ping);
14275
14276   W (ret);
14277   return ret;
14278 }
14279
14280
14281 static int
14282 api_interface_name_renumber (vat_main_t * vam)
14283 {
14284   unformat_input_t *line_input = vam->input;
14285   vl_api_interface_name_renumber_t *mp;
14286   u32 sw_if_index = ~0;
14287   u32 new_show_dev_instance = ~0;
14288   int ret;
14289
14290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14293                     &sw_if_index))
14294         ;
14295       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14296         ;
14297       else if (unformat (line_input, "new_show_dev_instance %d",
14298                          &new_show_dev_instance))
14299         ;
14300       else
14301         break;
14302     }
14303
14304   if (sw_if_index == ~0)
14305     {
14306       errmsg ("missing interface name or sw_if_index");
14307       return -99;
14308     }
14309
14310   if (new_show_dev_instance == ~0)
14311     {
14312       errmsg ("missing new_show_dev_instance");
14313       return -99;
14314     }
14315
14316   M (INTERFACE_NAME_RENUMBER, mp);
14317
14318   mp->sw_if_index = ntohl (sw_if_index);
14319   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14320
14321   S (mp);
14322   W (ret);
14323   return ret;
14324 }
14325
14326 static int
14327 api_ip_probe_neighbor (vat_main_t * vam)
14328 {
14329   unformat_input_t *i = vam->input;
14330   vl_api_ip_probe_neighbor_t *mp;
14331   u8 int_set = 0;
14332   u8 adr_set = 0;
14333   u8 is_ipv6 = 0;
14334   u8 dst_adr[16];
14335   u32 sw_if_index;
14336   int ret;
14337
14338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14341         int_set = 1;
14342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14343         int_set = 1;
14344       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14345         adr_set = 1;
14346       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14347         {
14348           adr_set = 1;
14349           is_ipv6 = 1;
14350         }
14351       else
14352         break;
14353     }
14354
14355   if (int_set == 0)
14356     {
14357       errmsg ("missing interface");
14358       return -99;
14359     }
14360
14361   if (adr_set == 0)
14362     {
14363       errmsg ("missing addresses");
14364       return -99;
14365     }
14366
14367   M (IP_PROBE_NEIGHBOR, mp);
14368
14369   mp->sw_if_index = ntohl (sw_if_index);
14370   mp->is_ipv6 = is_ipv6;
14371   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14372
14373   S (mp);
14374   W (ret);
14375   return ret;
14376 }
14377
14378 static int
14379 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14380 {
14381   unformat_input_t *i = vam->input;
14382   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14383   u8 mode = IP_SCAN_V46_NEIGHBORS;
14384   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14385   int ret;
14386
14387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (i, "ip4"))
14390         mode = IP_SCAN_V4_NEIGHBORS;
14391       else if (unformat (i, "ip6"))
14392         mode = IP_SCAN_V6_NEIGHBORS;
14393       if (unformat (i, "both"))
14394         mode = IP_SCAN_V46_NEIGHBORS;
14395       else if (unformat (i, "disable"))
14396         mode = IP_SCAN_DISABLED;
14397       else if (unformat (i, "interval %d", &interval))
14398         ;
14399       else if (unformat (i, "max-time %d", &time))
14400         ;
14401       else if (unformat (i, "max-update %d", &update))
14402         ;
14403       else if (unformat (i, "delay %d", &delay))
14404         ;
14405       else if (unformat (i, "stale %d", &stale))
14406         ;
14407       else
14408         break;
14409     }
14410
14411   if (interval > 255)
14412     {
14413       errmsg ("interval cannot exceed 255 minutes.");
14414       return -99;
14415     }
14416   if (time > 255)
14417     {
14418       errmsg ("max-time cannot exceed 255 usec.");
14419       return -99;
14420     }
14421   if (update > 255)
14422     {
14423       errmsg ("max-update cannot exceed 255.");
14424       return -99;
14425     }
14426   if (delay > 255)
14427     {
14428       errmsg ("delay cannot exceed 255 msec.");
14429       return -99;
14430     }
14431   if (stale > 255)
14432     {
14433       errmsg ("stale cannot exceed 255 minutes.");
14434       return -99;
14435     }
14436
14437   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14438   mp->mode = mode;
14439   mp->scan_interval = interval;
14440   mp->max_proc_time = time;
14441   mp->max_update = update;
14442   mp->scan_int_delay = delay;
14443   mp->stale_threshold = stale;
14444
14445   S (mp);
14446   W (ret);
14447   return ret;
14448 }
14449
14450 static int
14451 api_want_ip4_arp_events (vat_main_t * vam)
14452 {
14453   unformat_input_t *line_input = vam->input;
14454   vl_api_want_ip4_arp_events_t *mp;
14455   ip4_address_t address;
14456   int address_set = 0;
14457   u32 enable_disable = 1;
14458   int ret;
14459
14460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14461     {
14462       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14463         address_set = 1;
14464       else if (unformat (line_input, "del"))
14465         enable_disable = 0;
14466       else
14467         break;
14468     }
14469
14470   if (address_set == 0)
14471     {
14472       errmsg ("missing addresses");
14473       return -99;
14474     }
14475
14476   M (WANT_IP4_ARP_EVENTS, mp);
14477   mp->enable_disable = enable_disable;
14478   mp->pid = htonl (getpid ());
14479   mp->address = address.as_u32;
14480
14481   S (mp);
14482   W (ret);
14483   return ret;
14484 }
14485
14486 static int
14487 api_want_ip6_nd_events (vat_main_t * vam)
14488 {
14489   unformat_input_t *line_input = vam->input;
14490   vl_api_want_ip6_nd_events_t *mp;
14491   ip6_address_t address;
14492   int address_set = 0;
14493   u32 enable_disable = 1;
14494   int ret;
14495
14496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14497     {
14498       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14499         address_set = 1;
14500       else if (unformat (line_input, "del"))
14501         enable_disable = 0;
14502       else
14503         break;
14504     }
14505
14506   if (address_set == 0)
14507     {
14508       errmsg ("missing addresses");
14509       return -99;
14510     }
14511
14512   M (WANT_IP6_ND_EVENTS, mp);
14513   mp->enable_disable = enable_disable;
14514   mp->pid = htonl (getpid ());
14515   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14516
14517   S (mp);
14518   W (ret);
14519   return ret;
14520 }
14521
14522 static int
14523 api_want_l2_macs_events (vat_main_t * vam)
14524 {
14525   unformat_input_t *line_input = vam->input;
14526   vl_api_want_l2_macs_events_t *mp;
14527   u8 enable_disable = 1;
14528   u32 scan_delay = 0;
14529   u32 max_macs_in_event = 0;
14530   u32 learn_limit = 0;
14531   int ret;
14532
14533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14534     {
14535       if (unformat (line_input, "learn-limit %d", &learn_limit))
14536         ;
14537       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14538         ;
14539       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14540         ;
14541       else if (unformat (line_input, "disable"))
14542         enable_disable = 0;
14543       else
14544         break;
14545     }
14546
14547   M (WANT_L2_MACS_EVENTS, mp);
14548   mp->enable_disable = enable_disable;
14549   mp->pid = htonl (getpid ());
14550   mp->learn_limit = htonl (learn_limit);
14551   mp->scan_delay = (u8) scan_delay;
14552   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14553   S (mp);
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_input_acl_set_interface (vat_main_t * vam)
14560 {
14561   unformat_input_t *i = vam->input;
14562   vl_api_input_acl_set_interface_t *mp;
14563   u32 sw_if_index;
14564   int sw_if_index_set;
14565   u32 ip4_table_index = ~0;
14566   u32 ip6_table_index = ~0;
14567   u32 l2_table_index = ~0;
14568   u8 is_add = 1;
14569   int ret;
14570
14571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14572     {
14573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14574         sw_if_index_set = 1;
14575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14576         sw_if_index_set = 1;
14577       else if (unformat (i, "del"))
14578         is_add = 0;
14579       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14580         ;
14581       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14582         ;
14583       else if (unformat (i, "l2-table %d", &l2_table_index))
14584         ;
14585       else
14586         {
14587           clib_warning ("parse error '%U'", format_unformat_error, i);
14588           return -99;
14589         }
14590     }
14591
14592   if (sw_if_index_set == 0)
14593     {
14594       errmsg ("missing interface name or sw_if_index");
14595       return -99;
14596     }
14597
14598   M (INPUT_ACL_SET_INTERFACE, mp);
14599
14600   mp->sw_if_index = ntohl (sw_if_index);
14601   mp->ip4_table_index = ntohl (ip4_table_index);
14602   mp->ip6_table_index = ntohl (ip6_table_index);
14603   mp->l2_table_index = ntohl (l2_table_index);
14604   mp->is_add = is_add;
14605
14606   S (mp);
14607   W (ret);
14608   return ret;
14609 }
14610
14611 static int
14612 api_output_acl_set_interface (vat_main_t * vam)
14613 {
14614   unformat_input_t *i = vam->input;
14615   vl_api_output_acl_set_interface_t *mp;
14616   u32 sw_if_index;
14617   int sw_if_index_set;
14618   u32 ip4_table_index = ~0;
14619   u32 ip6_table_index = ~0;
14620   u32 l2_table_index = ~0;
14621   u8 is_add = 1;
14622   int ret;
14623
14624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14627         sw_if_index_set = 1;
14628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14629         sw_if_index_set = 1;
14630       else if (unformat (i, "del"))
14631         is_add = 0;
14632       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14633         ;
14634       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14635         ;
14636       else if (unformat (i, "l2-table %d", &l2_table_index))
14637         ;
14638       else
14639         {
14640           clib_warning ("parse error '%U'", format_unformat_error, i);
14641           return -99;
14642         }
14643     }
14644
14645   if (sw_if_index_set == 0)
14646     {
14647       errmsg ("missing interface name or sw_if_index");
14648       return -99;
14649     }
14650
14651   M (OUTPUT_ACL_SET_INTERFACE, mp);
14652
14653   mp->sw_if_index = ntohl (sw_if_index);
14654   mp->ip4_table_index = ntohl (ip4_table_index);
14655   mp->ip6_table_index = ntohl (ip6_table_index);
14656   mp->l2_table_index = ntohl (l2_table_index);
14657   mp->is_add = is_add;
14658
14659   S (mp);
14660   W (ret);
14661   return ret;
14662 }
14663
14664 static int
14665 api_ip_address_dump (vat_main_t * vam)
14666 {
14667   unformat_input_t *i = vam->input;
14668   vl_api_ip_address_dump_t *mp;
14669   vl_api_control_ping_t *mp_ping;
14670   u32 sw_if_index = ~0;
14671   u8 sw_if_index_set = 0;
14672   u8 ipv4_set = 0;
14673   u8 ipv6_set = 0;
14674   int ret;
14675
14676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14677     {
14678       if (unformat (i, "sw_if_index %d", &sw_if_index))
14679         sw_if_index_set = 1;
14680       else
14681         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14682         sw_if_index_set = 1;
14683       else if (unformat (i, "ipv4"))
14684         ipv4_set = 1;
14685       else if (unformat (i, "ipv6"))
14686         ipv6_set = 1;
14687       else
14688         break;
14689     }
14690
14691   if (ipv4_set && ipv6_set)
14692     {
14693       errmsg ("ipv4 and ipv6 flags cannot be both set");
14694       return -99;
14695     }
14696
14697   if ((!ipv4_set) && (!ipv6_set))
14698     {
14699       errmsg ("no ipv4 nor ipv6 flag set");
14700       return -99;
14701     }
14702
14703   if (sw_if_index_set == 0)
14704     {
14705       errmsg ("missing interface name or sw_if_index");
14706       return -99;
14707     }
14708
14709   vam->current_sw_if_index = sw_if_index;
14710   vam->is_ipv6 = ipv6_set;
14711
14712   M (IP_ADDRESS_DUMP, mp);
14713   mp->sw_if_index = ntohl (sw_if_index);
14714   mp->is_ipv6 = ipv6_set;
14715   S (mp);
14716
14717   /* Use a control ping for synchronization */
14718   MPING (CONTROL_PING, mp_ping);
14719   S (mp_ping);
14720
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_ip_dump (vat_main_t * vam)
14727 {
14728   vl_api_ip_dump_t *mp;
14729   vl_api_control_ping_t *mp_ping;
14730   unformat_input_t *in = vam->input;
14731   int ipv4_set = 0;
14732   int ipv6_set = 0;
14733   int is_ipv6;
14734   int i;
14735   int ret;
14736
14737   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14738     {
14739       if (unformat (in, "ipv4"))
14740         ipv4_set = 1;
14741       else if (unformat (in, "ipv6"))
14742         ipv6_set = 1;
14743       else
14744         break;
14745     }
14746
14747   if (ipv4_set && ipv6_set)
14748     {
14749       errmsg ("ipv4 and ipv6 flags cannot be both set");
14750       return -99;
14751     }
14752
14753   if ((!ipv4_set) && (!ipv6_set))
14754     {
14755       errmsg ("no ipv4 nor ipv6 flag set");
14756       return -99;
14757     }
14758
14759   is_ipv6 = ipv6_set;
14760   vam->is_ipv6 = is_ipv6;
14761
14762   /* free old data */
14763   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14764     {
14765       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14766     }
14767   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14768
14769   M (IP_DUMP, mp);
14770   mp->is_ipv6 = ipv6_set;
14771   S (mp);
14772
14773   /* Use a control ping for synchronization */
14774   MPING (CONTROL_PING, mp_ping);
14775   S (mp_ping);
14776
14777   W (ret);
14778   return ret;
14779 }
14780
14781 static int
14782 api_ipsec_spd_add_del (vat_main_t * vam)
14783 {
14784   unformat_input_t *i = vam->input;
14785   vl_api_ipsec_spd_add_del_t *mp;
14786   u32 spd_id = ~0;
14787   u8 is_add = 1;
14788   int ret;
14789
14790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14791     {
14792       if (unformat (i, "spd_id %d", &spd_id))
14793         ;
14794       else if (unformat (i, "del"))
14795         is_add = 0;
14796       else
14797         {
14798           clib_warning ("parse error '%U'", format_unformat_error, i);
14799           return -99;
14800         }
14801     }
14802   if (spd_id == ~0)
14803     {
14804       errmsg ("spd_id must be set");
14805       return -99;
14806     }
14807
14808   M (IPSEC_SPD_ADD_DEL, mp);
14809
14810   mp->spd_id = ntohl (spd_id);
14811   mp->is_add = is_add;
14812
14813   S (mp);
14814   W (ret);
14815   return ret;
14816 }
14817
14818 static int
14819 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14820 {
14821   unformat_input_t *i = vam->input;
14822   vl_api_ipsec_interface_add_del_spd_t *mp;
14823   u32 sw_if_index;
14824   u8 sw_if_index_set = 0;
14825   u32 spd_id = (u32) ~ 0;
14826   u8 is_add = 1;
14827   int ret;
14828
14829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14830     {
14831       if (unformat (i, "del"))
14832         is_add = 0;
14833       else if (unformat (i, "spd_id %d", &spd_id))
14834         ;
14835       else
14836         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14837         sw_if_index_set = 1;
14838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14839         sw_if_index_set = 1;
14840       else
14841         {
14842           clib_warning ("parse error '%U'", format_unformat_error, i);
14843           return -99;
14844         }
14845
14846     }
14847
14848   if (spd_id == (u32) ~ 0)
14849     {
14850       errmsg ("spd_id must be set");
14851       return -99;
14852     }
14853
14854   if (sw_if_index_set == 0)
14855     {
14856       errmsg ("missing interface name or sw_if_index");
14857       return -99;
14858     }
14859
14860   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14861
14862   mp->spd_id = ntohl (spd_id);
14863   mp->sw_if_index = ntohl (sw_if_index);
14864   mp->is_add = is_add;
14865
14866   S (mp);
14867   W (ret);
14868   return ret;
14869 }
14870
14871 static int
14872 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14873 {
14874   unformat_input_t *i = vam->input;
14875   vl_api_ipsec_spd_add_del_entry_t *mp;
14876   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14877   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14878   i32 priority = 0;
14879   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14880   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14881   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14882   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14883   int ret;
14884
14885   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14886   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14887   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14888   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14889   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14890   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14891
14892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14893     {
14894       if (unformat (i, "del"))
14895         is_add = 0;
14896       if (unformat (i, "outbound"))
14897         is_outbound = 1;
14898       if (unformat (i, "inbound"))
14899         is_outbound = 0;
14900       else if (unformat (i, "spd_id %d", &spd_id))
14901         ;
14902       else if (unformat (i, "sa_id %d", &sa_id))
14903         ;
14904       else if (unformat (i, "priority %d", &priority))
14905         ;
14906       else if (unformat (i, "protocol %d", &protocol))
14907         ;
14908       else if (unformat (i, "lport_start %d", &lport_start))
14909         ;
14910       else if (unformat (i, "lport_stop %d", &lport_stop))
14911         ;
14912       else if (unformat (i, "rport_start %d", &rport_start))
14913         ;
14914       else if (unformat (i, "rport_stop %d", &rport_stop))
14915         ;
14916       else
14917         if (unformat
14918             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14919         {
14920           is_ipv6 = 0;
14921           is_ip_any = 0;
14922         }
14923       else
14924         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14925         {
14926           is_ipv6 = 0;
14927           is_ip_any = 0;
14928         }
14929       else
14930         if (unformat
14931             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14932         {
14933           is_ipv6 = 0;
14934           is_ip_any = 0;
14935         }
14936       else
14937         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14938         {
14939           is_ipv6 = 0;
14940           is_ip_any = 0;
14941         }
14942       else
14943         if (unformat
14944             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14945         {
14946           is_ipv6 = 1;
14947           is_ip_any = 0;
14948         }
14949       else
14950         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14951         {
14952           is_ipv6 = 1;
14953           is_ip_any = 0;
14954         }
14955       else
14956         if (unformat
14957             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14958         {
14959           is_ipv6 = 1;
14960           is_ip_any = 0;
14961         }
14962       else
14963         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14964         {
14965           is_ipv6 = 1;
14966           is_ip_any = 0;
14967         }
14968       else
14969         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14970         {
14971           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14972             {
14973               clib_warning ("unsupported action: 'resolve'");
14974               return -99;
14975             }
14976         }
14977       else
14978         {
14979           clib_warning ("parse error '%U'", format_unformat_error, i);
14980           return -99;
14981         }
14982
14983     }
14984
14985   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14986
14987   mp->spd_id = ntohl (spd_id);
14988   mp->priority = ntohl (priority);
14989   mp->is_outbound = is_outbound;
14990
14991   mp->is_ipv6 = is_ipv6;
14992   if (is_ipv6 || is_ip_any)
14993     {
14994       clib_memcpy (mp->remote_address_start, &raddr6_start,
14995                    sizeof (ip6_address_t));
14996       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14997                    sizeof (ip6_address_t));
14998       clib_memcpy (mp->local_address_start, &laddr6_start,
14999                    sizeof (ip6_address_t));
15000       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15001                    sizeof (ip6_address_t));
15002     }
15003   else
15004     {
15005       clib_memcpy (mp->remote_address_start, &raddr4_start,
15006                    sizeof (ip4_address_t));
15007       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15008                    sizeof (ip4_address_t));
15009       clib_memcpy (mp->local_address_start, &laddr4_start,
15010                    sizeof (ip4_address_t));
15011       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15012                    sizeof (ip4_address_t));
15013     }
15014   mp->protocol = (u8) protocol;
15015   mp->local_port_start = ntohs ((u16) lport_start);
15016   mp->local_port_stop = ntohs ((u16) lport_stop);
15017   mp->remote_port_start = ntohs ((u16) rport_start);
15018   mp->remote_port_stop = ntohs ((u16) rport_stop);
15019   mp->policy = (u8) policy;
15020   mp->sa_id = ntohl (sa_id);
15021   mp->is_add = is_add;
15022   mp->is_ip_any = is_ip_any;
15023   S (mp);
15024   W (ret);
15025   return ret;
15026 }
15027
15028 static int
15029 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15030 {
15031   unformat_input_t *i = vam->input;
15032   vl_api_ipsec_sad_add_del_entry_t *mp;
15033   u32 sad_id = 0, spi = 0;
15034   u8 *ck = 0, *ik = 0;
15035   u8 is_add = 1;
15036
15037   u8 protocol = IPSEC_PROTOCOL_AH;
15038   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15039   u32 crypto_alg = 0, integ_alg = 0;
15040   ip4_address_t tun_src4;
15041   ip4_address_t tun_dst4;
15042   ip6_address_t tun_src6;
15043   ip6_address_t tun_dst6;
15044   int ret;
15045
15046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15047     {
15048       if (unformat (i, "del"))
15049         is_add = 0;
15050       else if (unformat (i, "sad_id %d", &sad_id))
15051         ;
15052       else if (unformat (i, "spi %d", &spi))
15053         ;
15054       else if (unformat (i, "esp"))
15055         protocol = IPSEC_PROTOCOL_ESP;
15056       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15057         {
15058           is_tunnel = 1;
15059           is_tunnel_ipv6 = 0;
15060         }
15061       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15062         {
15063           is_tunnel = 1;
15064           is_tunnel_ipv6 = 0;
15065         }
15066       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15067         {
15068           is_tunnel = 1;
15069           is_tunnel_ipv6 = 1;
15070         }
15071       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15072         {
15073           is_tunnel = 1;
15074           is_tunnel_ipv6 = 1;
15075         }
15076       else
15077         if (unformat
15078             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15079         {
15080           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15081             {
15082               clib_warning ("unsupported crypto-alg: '%U'",
15083                             format_ipsec_crypto_alg, crypto_alg);
15084               return -99;
15085             }
15086         }
15087       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15088         ;
15089       else
15090         if (unformat
15091             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15092         {
15093           if (integ_alg >= IPSEC_INTEG_N_ALG)
15094             {
15095               clib_warning ("unsupported integ-alg: '%U'",
15096                             format_ipsec_integ_alg, integ_alg);
15097               return -99;
15098             }
15099         }
15100       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15101         ;
15102       else
15103         {
15104           clib_warning ("parse error '%U'", format_unformat_error, i);
15105           return -99;
15106         }
15107
15108     }
15109
15110   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15111
15112   mp->sad_id = ntohl (sad_id);
15113   mp->is_add = is_add;
15114   mp->protocol = protocol;
15115   mp->spi = ntohl (spi);
15116   mp->is_tunnel = is_tunnel;
15117   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15118   mp->crypto_algorithm = crypto_alg;
15119   mp->integrity_algorithm = integ_alg;
15120   mp->crypto_key_length = vec_len (ck);
15121   mp->integrity_key_length = vec_len (ik);
15122
15123   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15124     mp->crypto_key_length = sizeof (mp->crypto_key);
15125
15126   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15127     mp->integrity_key_length = sizeof (mp->integrity_key);
15128
15129   if (ck)
15130     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15131   if (ik)
15132     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15133
15134   if (is_tunnel)
15135     {
15136       if (is_tunnel_ipv6)
15137         {
15138           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15139                        sizeof (ip6_address_t));
15140           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15141                        sizeof (ip6_address_t));
15142         }
15143       else
15144         {
15145           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15146                        sizeof (ip4_address_t));
15147           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15148                        sizeof (ip4_address_t));
15149         }
15150     }
15151
15152   S (mp);
15153   W (ret);
15154   return ret;
15155 }
15156
15157 static int
15158 api_ipsec_sa_set_key (vat_main_t * vam)
15159 {
15160   unformat_input_t *i = vam->input;
15161   vl_api_ipsec_sa_set_key_t *mp;
15162   u32 sa_id;
15163   u8 *ck = 0, *ik = 0;
15164   int ret;
15165
15166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15167     {
15168       if (unformat (i, "sa_id %d", &sa_id))
15169         ;
15170       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15171         ;
15172       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15173         ;
15174       else
15175         {
15176           clib_warning ("parse error '%U'", format_unformat_error, i);
15177           return -99;
15178         }
15179     }
15180
15181   M (IPSEC_SA_SET_KEY, mp);
15182
15183   mp->sa_id = ntohl (sa_id);
15184   mp->crypto_key_length = vec_len (ck);
15185   mp->integrity_key_length = vec_len (ik);
15186
15187   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15188     mp->crypto_key_length = sizeof (mp->crypto_key);
15189
15190   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15191     mp->integrity_key_length = sizeof (mp->integrity_key);
15192
15193   if (ck)
15194     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15195   if (ik)
15196     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15197
15198   S (mp);
15199   W (ret);
15200   return ret;
15201 }
15202
15203 static int
15204 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15205 {
15206   unformat_input_t *i = vam->input;
15207   vl_api_ipsec_tunnel_if_add_del_t *mp;
15208   u32 local_spi = 0, remote_spi = 0;
15209   u32 crypto_alg = 0, integ_alg = 0;
15210   u8 *lck = NULL, *rck = NULL;
15211   u8 *lik = NULL, *rik = NULL;
15212   ip4_address_t local_ip = { {0} };
15213   ip4_address_t remote_ip = { {0} };
15214   u8 is_add = 1;
15215   u8 esn = 0;
15216   u8 anti_replay = 0;
15217   u8 renumber = 0;
15218   u32 instance = ~0;
15219   int ret;
15220
15221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15222     {
15223       if (unformat (i, "del"))
15224         is_add = 0;
15225       else if (unformat (i, "esn"))
15226         esn = 1;
15227       else if (unformat (i, "anti_replay"))
15228         anti_replay = 1;
15229       else if (unformat (i, "local_spi %d", &local_spi))
15230         ;
15231       else if (unformat (i, "remote_spi %d", &remote_spi))
15232         ;
15233       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15234         ;
15235       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15236         ;
15237       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15238         ;
15239       else
15240         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15241         ;
15242       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15243         ;
15244       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15245         ;
15246       else
15247         if (unformat
15248             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15249         {
15250           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15251             {
15252               errmsg ("unsupported crypto-alg: '%U'\n",
15253                       format_ipsec_crypto_alg, crypto_alg);
15254               return -99;
15255             }
15256         }
15257       else
15258         if (unformat
15259             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15260         {
15261           if (integ_alg >= IPSEC_INTEG_N_ALG)
15262             {
15263               errmsg ("unsupported integ-alg: '%U'\n",
15264                       format_ipsec_integ_alg, integ_alg);
15265               return -99;
15266             }
15267         }
15268       else if (unformat (i, "instance %u", &instance))
15269         renumber = 1;
15270       else
15271         {
15272           errmsg ("parse error '%U'\n", format_unformat_error, i);
15273           return -99;
15274         }
15275     }
15276
15277   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15278
15279   mp->is_add = is_add;
15280   mp->esn = esn;
15281   mp->anti_replay = anti_replay;
15282
15283   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15284   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15285
15286   mp->local_spi = htonl (local_spi);
15287   mp->remote_spi = htonl (remote_spi);
15288   mp->crypto_alg = (u8) crypto_alg;
15289
15290   mp->local_crypto_key_len = 0;
15291   if (lck)
15292     {
15293       mp->local_crypto_key_len = vec_len (lck);
15294       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15295         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15296       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15297     }
15298
15299   mp->remote_crypto_key_len = 0;
15300   if (rck)
15301     {
15302       mp->remote_crypto_key_len = vec_len (rck);
15303       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15304         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15305       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15306     }
15307
15308   mp->integ_alg = (u8) integ_alg;
15309
15310   mp->local_integ_key_len = 0;
15311   if (lik)
15312     {
15313       mp->local_integ_key_len = vec_len (lik);
15314       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15315         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15316       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15317     }
15318
15319   mp->remote_integ_key_len = 0;
15320   if (rik)
15321     {
15322       mp->remote_integ_key_len = vec_len (rik);
15323       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15324         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15325       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15326     }
15327
15328   if (renumber)
15329     {
15330       mp->renumber = renumber;
15331       mp->show_instance = ntohl (instance);
15332     }
15333
15334   S (mp);
15335   W (ret);
15336   return ret;
15337 }
15338
15339 static void
15340 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15341 {
15342   vat_main_t *vam = &vat_main;
15343
15344   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15345          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15346          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15347          "tunnel_src_addr %U tunnel_dst_addr %U "
15348          "salt %u seq_outbound %lu last_seq_inbound %lu "
15349          "replay_window %lu total_data_size %lu\n",
15350          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15351          mp->protocol,
15352          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15353          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15354          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15355          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15356          mp->tunnel_src_addr,
15357          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15358          mp->tunnel_dst_addr,
15359          ntohl (mp->salt),
15360          clib_net_to_host_u64 (mp->seq_outbound),
15361          clib_net_to_host_u64 (mp->last_seq_inbound),
15362          clib_net_to_host_u64 (mp->replay_window),
15363          clib_net_to_host_u64 (mp->total_data_size));
15364 }
15365
15366 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15367 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15368
15369 static void vl_api_ipsec_sa_details_t_handler_json
15370   (vl_api_ipsec_sa_details_t * mp)
15371 {
15372   vat_main_t *vam = &vat_main;
15373   vat_json_node_t *node = NULL;
15374   struct in_addr src_ip4, dst_ip4;
15375   struct in6_addr src_ip6, dst_ip6;
15376
15377   if (VAT_JSON_ARRAY != vam->json_tree.type)
15378     {
15379       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15380       vat_json_init_array (&vam->json_tree);
15381     }
15382   node = vat_json_array_add (&vam->json_tree);
15383
15384   vat_json_init_object (node);
15385   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15386   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15387   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15388   vat_json_object_add_uint (node, "proto", mp->protocol);
15389   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15390   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15391   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15392   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15393   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15394   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15395   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15396                              mp->crypto_key_len);
15397   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15398                              mp->integ_key_len);
15399   if (mp->is_tunnel_ip6)
15400     {
15401       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15402       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15403       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15404       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15405     }
15406   else
15407     {
15408       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15409       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15410       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15411       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15412     }
15413   vat_json_object_add_uint (node, "replay_window",
15414                             clib_net_to_host_u64 (mp->replay_window));
15415   vat_json_object_add_uint (node, "total_data_size",
15416                             clib_net_to_host_u64 (mp->total_data_size));
15417
15418 }
15419
15420 static int
15421 api_ipsec_sa_dump (vat_main_t * vam)
15422 {
15423   unformat_input_t *i = vam->input;
15424   vl_api_ipsec_sa_dump_t *mp;
15425   vl_api_control_ping_t *mp_ping;
15426   u32 sa_id = ~0;
15427   int ret;
15428
15429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (i, "sa_id %d", &sa_id))
15432         ;
15433       else
15434         {
15435           clib_warning ("parse error '%U'", format_unformat_error, i);
15436           return -99;
15437         }
15438     }
15439
15440   M (IPSEC_SA_DUMP, mp);
15441
15442   mp->sa_id = ntohl (sa_id);
15443
15444   S (mp);
15445
15446   /* Use a control ping for synchronization */
15447   M (CONTROL_PING, mp_ping);
15448   S (mp_ping);
15449
15450   W (ret);
15451   return ret;
15452 }
15453
15454 static int
15455 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15456 {
15457   unformat_input_t *i = vam->input;
15458   vl_api_ipsec_tunnel_if_set_key_t *mp;
15459   u32 sw_if_index = ~0;
15460   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15461   u8 *key = 0;
15462   u32 alg = ~0;
15463   int ret;
15464
15465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15468         ;
15469       else
15470         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15471         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15472       else
15473         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15474         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15475       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15476         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15477       else
15478         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15479         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15480       else if (unformat (i, "%U", unformat_hex_string, &key))
15481         ;
15482       else
15483         {
15484           clib_warning ("parse error '%U'", format_unformat_error, i);
15485           return -99;
15486         }
15487     }
15488
15489   if (sw_if_index == ~0)
15490     {
15491       errmsg ("interface must be specified");
15492       return -99;
15493     }
15494
15495   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15496     {
15497       errmsg ("key type must be specified");
15498       return -99;
15499     }
15500
15501   if (alg == ~0)
15502     {
15503       errmsg ("algorithm must be specified");
15504       return -99;
15505     }
15506
15507   if (vec_len (key) == 0)
15508     {
15509       errmsg ("key must be specified");
15510       return -99;
15511     }
15512
15513   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15514
15515   mp->sw_if_index = htonl (sw_if_index);
15516   mp->alg = alg;
15517   mp->key_type = key_type;
15518   mp->key_len = vec_len (key);
15519   clib_memcpy (mp->key, key, vec_len (key));
15520
15521   S (mp);
15522   W (ret);
15523
15524   return ret;
15525 }
15526
15527 static int
15528 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15529 {
15530   unformat_input_t *i = vam->input;
15531   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15532   u32 sw_if_index = ~0;
15533   u32 sa_id = ~0;
15534   u8 is_outbound = (u8) ~ 0;
15535   int ret;
15536
15537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15538     {
15539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15540         ;
15541       else if (unformat (i, "sa_id %d", &sa_id))
15542         ;
15543       else if (unformat (i, "outbound"))
15544         is_outbound = 1;
15545       else if (unformat (i, "inbound"))
15546         is_outbound = 0;
15547       else
15548         {
15549           clib_warning ("parse error '%U'", format_unformat_error, i);
15550           return -99;
15551         }
15552     }
15553
15554   if (sw_if_index == ~0)
15555     {
15556       errmsg ("interface must be specified");
15557       return -99;
15558     }
15559
15560   if (sa_id == ~0)
15561     {
15562       errmsg ("SA ID must be specified");
15563       return -99;
15564     }
15565
15566   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15567
15568   mp->sw_if_index = htonl (sw_if_index);
15569   mp->sa_id = htonl (sa_id);
15570   mp->is_outbound = is_outbound;
15571
15572   S (mp);
15573   W (ret);
15574
15575   return ret;
15576 }
15577
15578 static int
15579 api_ikev2_profile_add_del (vat_main_t * vam)
15580 {
15581   unformat_input_t *i = vam->input;
15582   vl_api_ikev2_profile_add_del_t *mp;
15583   u8 is_add = 1;
15584   u8 *name = 0;
15585   int ret;
15586
15587   const char *valid_chars = "a-zA-Z0-9_";
15588
15589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15590     {
15591       if (unformat (i, "del"))
15592         is_add = 0;
15593       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15594         vec_add1 (name, 0);
15595       else
15596         {
15597           errmsg ("parse error '%U'", format_unformat_error, i);
15598           return -99;
15599         }
15600     }
15601
15602   if (!vec_len (name))
15603     {
15604       errmsg ("profile name must be specified");
15605       return -99;
15606     }
15607
15608   if (vec_len (name) > 64)
15609     {
15610       errmsg ("profile name too long");
15611       return -99;
15612     }
15613
15614   M (IKEV2_PROFILE_ADD_DEL, mp);
15615
15616   clib_memcpy (mp->name, name, vec_len (name));
15617   mp->is_add = is_add;
15618   vec_free (name);
15619
15620   S (mp);
15621   W (ret);
15622   return ret;
15623 }
15624
15625 static int
15626 api_ikev2_profile_set_auth (vat_main_t * vam)
15627 {
15628   unformat_input_t *i = vam->input;
15629   vl_api_ikev2_profile_set_auth_t *mp;
15630   u8 *name = 0;
15631   u8 *data = 0;
15632   u32 auth_method = 0;
15633   u8 is_hex = 0;
15634   int ret;
15635
15636   const char *valid_chars = "a-zA-Z0-9_";
15637
15638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15641         vec_add1 (name, 0);
15642       else if (unformat (i, "auth_method %U",
15643                          unformat_ikev2_auth_method, &auth_method))
15644         ;
15645       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15646         is_hex = 1;
15647       else if (unformat (i, "auth_data %v", &data))
15648         ;
15649       else
15650         {
15651           errmsg ("parse error '%U'", format_unformat_error, i);
15652           return -99;
15653         }
15654     }
15655
15656   if (!vec_len (name))
15657     {
15658       errmsg ("profile name must be specified");
15659       return -99;
15660     }
15661
15662   if (vec_len (name) > 64)
15663     {
15664       errmsg ("profile name too long");
15665       return -99;
15666     }
15667
15668   if (!vec_len (data))
15669     {
15670       errmsg ("auth_data must be specified");
15671       return -99;
15672     }
15673
15674   if (!auth_method)
15675     {
15676       errmsg ("auth_method must be specified");
15677       return -99;
15678     }
15679
15680   M (IKEV2_PROFILE_SET_AUTH, mp);
15681
15682   mp->is_hex = is_hex;
15683   mp->auth_method = (u8) auth_method;
15684   mp->data_len = vec_len (data);
15685   clib_memcpy (mp->name, name, vec_len (name));
15686   clib_memcpy (mp->data, data, vec_len (data));
15687   vec_free (name);
15688   vec_free (data);
15689
15690   S (mp);
15691   W (ret);
15692   return ret;
15693 }
15694
15695 static int
15696 api_ikev2_profile_set_id (vat_main_t * vam)
15697 {
15698   unformat_input_t *i = vam->input;
15699   vl_api_ikev2_profile_set_id_t *mp;
15700   u8 *name = 0;
15701   u8 *data = 0;
15702   u8 is_local = 0;
15703   u32 id_type = 0;
15704   ip4_address_t ip4;
15705   int ret;
15706
15707   const char *valid_chars = "a-zA-Z0-9_";
15708
15709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15710     {
15711       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15712         vec_add1 (name, 0);
15713       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15714         ;
15715       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15716         {
15717           data = vec_new (u8, 4);
15718           clib_memcpy (data, ip4.as_u8, 4);
15719         }
15720       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15721         ;
15722       else if (unformat (i, "id_data %v", &data))
15723         ;
15724       else if (unformat (i, "local"))
15725         is_local = 1;
15726       else if (unformat (i, "remote"))
15727         is_local = 0;
15728       else
15729         {
15730           errmsg ("parse error '%U'", format_unformat_error, i);
15731           return -99;
15732         }
15733     }
15734
15735   if (!vec_len (name))
15736     {
15737       errmsg ("profile name must be specified");
15738       return -99;
15739     }
15740
15741   if (vec_len (name) > 64)
15742     {
15743       errmsg ("profile name too long");
15744       return -99;
15745     }
15746
15747   if (!vec_len (data))
15748     {
15749       errmsg ("id_data must be specified");
15750       return -99;
15751     }
15752
15753   if (!id_type)
15754     {
15755       errmsg ("id_type must be specified");
15756       return -99;
15757     }
15758
15759   M (IKEV2_PROFILE_SET_ID, mp);
15760
15761   mp->is_local = is_local;
15762   mp->id_type = (u8) id_type;
15763   mp->data_len = vec_len (data);
15764   clib_memcpy (mp->name, name, vec_len (name));
15765   clib_memcpy (mp->data, data, vec_len (data));
15766   vec_free (name);
15767   vec_free (data);
15768
15769   S (mp);
15770   W (ret);
15771   return ret;
15772 }
15773
15774 static int
15775 api_ikev2_profile_set_ts (vat_main_t * vam)
15776 {
15777   unformat_input_t *i = vam->input;
15778   vl_api_ikev2_profile_set_ts_t *mp;
15779   u8 *name = 0;
15780   u8 is_local = 0;
15781   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15782   ip4_address_t start_addr, end_addr;
15783
15784   const char *valid_chars = "a-zA-Z0-9_";
15785   int ret;
15786
15787   start_addr.as_u32 = 0;
15788   end_addr.as_u32 = (u32) ~ 0;
15789
15790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15791     {
15792       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15793         vec_add1 (name, 0);
15794       else if (unformat (i, "protocol %d", &proto))
15795         ;
15796       else if (unformat (i, "start_port %d", &start_port))
15797         ;
15798       else if (unformat (i, "end_port %d", &end_port))
15799         ;
15800       else
15801         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15802         ;
15803       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15804         ;
15805       else if (unformat (i, "local"))
15806         is_local = 1;
15807       else if (unformat (i, "remote"))
15808         is_local = 0;
15809       else
15810         {
15811           errmsg ("parse error '%U'", format_unformat_error, i);
15812           return -99;
15813         }
15814     }
15815
15816   if (!vec_len (name))
15817     {
15818       errmsg ("profile name must be specified");
15819       return -99;
15820     }
15821
15822   if (vec_len (name) > 64)
15823     {
15824       errmsg ("profile name too long");
15825       return -99;
15826     }
15827
15828   M (IKEV2_PROFILE_SET_TS, mp);
15829
15830   mp->is_local = is_local;
15831   mp->proto = (u8) proto;
15832   mp->start_port = (u16) start_port;
15833   mp->end_port = (u16) end_port;
15834   mp->start_addr = start_addr.as_u32;
15835   mp->end_addr = end_addr.as_u32;
15836   clib_memcpy (mp->name, name, vec_len (name));
15837   vec_free (name);
15838
15839   S (mp);
15840   W (ret);
15841   return ret;
15842 }
15843
15844 static int
15845 api_ikev2_set_local_key (vat_main_t * vam)
15846 {
15847   unformat_input_t *i = vam->input;
15848   vl_api_ikev2_set_local_key_t *mp;
15849   u8 *file = 0;
15850   int ret;
15851
15852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15853     {
15854       if (unformat (i, "file %v", &file))
15855         vec_add1 (file, 0);
15856       else
15857         {
15858           errmsg ("parse error '%U'", format_unformat_error, i);
15859           return -99;
15860         }
15861     }
15862
15863   if (!vec_len (file))
15864     {
15865       errmsg ("RSA key file must be specified");
15866       return -99;
15867     }
15868
15869   if (vec_len (file) > 256)
15870     {
15871       errmsg ("file name too long");
15872       return -99;
15873     }
15874
15875   M (IKEV2_SET_LOCAL_KEY, mp);
15876
15877   clib_memcpy (mp->key_file, file, vec_len (file));
15878   vec_free (file);
15879
15880   S (mp);
15881   W (ret);
15882   return ret;
15883 }
15884
15885 static int
15886 api_ikev2_set_responder (vat_main_t * vam)
15887 {
15888   unformat_input_t *i = vam->input;
15889   vl_api_ikev2_set_responder_t *mp;
15890   int ret;
15891   u8 *name = 0;
15892   u32 sw_if_index = ~0;
15893   ip4_address_t address;
15894
15895   const char *valid_chars = "a-zA-Z0-9_";
15896
15897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15898     {
15899       if (unformat
15900           (i, "%U interface %d address %U", unformat_token, valid_chars,
15901            &name, &sw_if_index, unformat_ip4_address, &address))
15902         vec_add1 (name, 0);
15903       else
15904         {
15905           errmsg ("parse error '%U'", format_unformat_error, i);
15906           return -99;
15907         }
15908     }
15909
15910   if (!vec_len (name))
15911     {
15912       errmsg ("profile name must be specified");
15913       return -99;
15914     }
15915
15916   if (vec_len (name) > 64)
15917     {
15918       errmsg ("profile name too long");
15919       return -99;
15920     }
15921
15922   M (IKEV2_SET_RESPONDER, mp);
15923
15924   clib_memcpy (mp->name, name, vec_len (name));
15925   vec_free (name);
15926
15927   mp->sw_if_index = sw_if_index;
15928   clib_memcpy (mp->address, &address, sizeof (address));
15929
15930   S (mp);
15931   W (ret);
15932   return ret;
15933 }
15934
15935 static int
15936 api_ikev2_set_ike_transforms (vat_main_t * vam)
15937 {
15938   unformat_input_t *i = vam->input;
15939   vl_api_ikev2_set_ike_transforms_t *mp;
15940   int ret;
15941   u8 *name = 0;
15942   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15943
15944   const char *valid_chars = "a-zA-Z0-9_";
15945
15946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15949                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15950         vec_add1 (name, 0);
15951       else
15952         {
15953           errmsg ("parse error '%U'", format_unformat_error, i);
15954           return -99;
15955         }
15956     }
15957
15958   if (!vec_len (name))
15959     {
15960       errmsg ("profile name must be specified");
15961       return -99;
15962     }
15963
15964   if (vec_len (name) > 64)
15965     {
15966       errmsg ("profile name too long");
15967       return -99;
15968     }
15969
15970   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15971
15972   clib_memcpy (mp->name, name, vec_len (name));
15973   vec_free (name);
15974   mp->crypto_alg = crypto_alg;
15975   mp->crypto_key_size = crypto_key_size;
15976   mp->integ_alg = integ_alg;
15977   mp->dh_group = dh_group;
15978
15979   S (mp);
15980   W (ret);
15981   return ret;
15982 }
15983
15984
15985 static int
15986 api_ikev2_set_esp_transforms (vat_main_t * vam)
15987 {
15988   unformat_input_t *i = vam->input;
15989   vl_api_ikev2_set_esp_transforms_t *mp;
15990   int ret;
15991   u8 *name = 0;
15992   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15993
15994   const char *valid_chars = "a-zA-Z0-9_";
15995
15996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15997     {
15998       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15999                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16000         vec_add1 (name, 0);
16001       else
16002         {
16003           errmsg ("parse error '%U'", format_unformat_error, i);
16004           return -99;
16005         }
16006     }
16007
16008   if (!vec_len (name))
16009     {
16010       errmsg ("profile name must be specified");
16011       return -99;
16012     }
16013
16014   if (vec_len (name) > 64)
16015     {
16016       errmsg ("profile name too long");
16017       return -99;
16018     }
16019
16020   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16021
16022   clib_memcpy (mp->name, name, vec_len (name));
16023   vec_free (name);
16024   mp->crypto_alg = crypto_alg;
16025   mp->crypto_key_size = crypto_key_size;
16026   mp->integ_alg = integ_alg;
16027   mp->dh_group = dh_group;
16028
16029   S (mp);
16030   W (ret);
16031   return ret;
16032 }
16033
16034 static int
16035 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16036 {
16037   unformat_input_t *i = vam->input;
16038   vl_api_ikev2_set_sa_lifetime_t *mp;
16039   int ret;
16040   u8 *name = 0;
16041   u64 lifetime, lifetime_maxdata;
16042   u32 lifetime_jitter, handover;
16043
16044   const char *valid_chars = "a-zA-Z0-9_";
16045
16046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16047     {
16048       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16049                     &lifetime, &lifetime_jitter, &handover,
16050                     &lifetime_maxdata))
16051         vec_add1 (name, 0);
16052       else
16053         {
16054           errmsg ("parse error '%U'", format_unformat_error, i);
16055           return -99;
16056         }
16057     }
16058
16059   if (!vec_len (name))
16060     {
16061       errmsg ("profile name must be specified");
16062       return -99;
16063     }
16064
16065   if (vec_len (name) > 64)
16066     {
16067       errmsg ("profile name too long");
16068       return -99;
16069     }
16070
16071   M (IKEV2_SET_SA_LIFETIME, mp);
16072
16073   clib_memcpy (mp->name, name, vec_len (name));
16074   vec_free (name);
16075   mp->lifetime = lifetime;
16076   mp->lifetime_jitter = lifetime_jitter;
16077   mp->handover = handover;
16078   mp->lifetime_maxdata = lifetime_maxdata;
16079
16080   S (mp);
16081   W (ret);
16082   return ret;
16083 }
16084
16085 static int
16086 api_ikev2_initiate_sa_init (vat_main_t * vam)
16087 {
16088   unformat_input_t *i = vam->input;
16089   vl_api_ikev2_initiate_sa_init_t *mp;
16090   int ret;
16091   u8 *name = 0;
16092
16093   const char *valid_chars = "a-zA-Z0-9_";
16094
16095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16096     {
16097       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16098         vec_add1 (name, 0);
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vec_len (name))
16107     {
16108       errmsg ("profile name must be specified");
16109       return -99;
16110     }
16111
16112   if (vec_len (name) > 64)
16113     {
16114       errmsg ("profile name too long");
16115       return -99;
16116     }
16117
16118   M (IKEV2_INITIATE_SA_INIT, mp);
16119
16120   clib_memcpy (mp->name, name, vec_len (name));
16121   vec_free (name);
16122
16123   S (mp);
16124   W (ret);
16125   return ret;
16126 }
16127
16128 static int
16129 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16130 {
16131   unformat_input_t *i = vam->input;
16132   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16133   int ret;
16134   u64 ispi;
16135
16136
16137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16138     {
16139       if (unformat (i, "%lx", &ispi))
16140         ;
16141       else
16142         {
16143           errmsg ("parse error '%U'", format_unformat_error, i);
16144           return -99;
16145         }
16146     }
16147
16148   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16149
16150   mp->ispi = ispi;
16151
16152   S (mp);
16153   W (ret);
16154   return ret;
16155 }
16156
16157 static int
16158 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16159 {
16160   unformat_input_t *i = vam->input;
16161   vl_api_ikev2_initiate_del_child_sa_t *mp;
16162   int ret;
16163   u32 ispi;
16164
16165
16166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16167     {
16168       if (unformat (i, "%x", &ispi))
16169         ;
16170       else
16171         {
16172           errmsg ("parse error '%U'", format_unformat_error, i);
16173           return -99;
16174         }
16175     }
16176
16177   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16178
16179   mp->ispi = ispi;
16180
16181   S (mp);
16182   W (ret);
16183   return ret;
16184 }
16185
16186 static int
16187 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16188 {
16189   unformat_input_t *i = vam->input;
16190   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16191   int ret;
16192   u32 ispi;
16193
16194
16195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16196     {
16197       if (unformat (i, "%x", &ispi))
16198         ;
16199       else
16200         {
16201           errmsg ("parse error '%U'", format_unformat_error, i);
16202           return -99;
16203         }
16204     }
16205
16206   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16207
16208   mp->ispi = ispi;
16209
16210   S (mp);
16211   W (ret);
16212   return ret;
16213 }
16214
16215 static int
16216 api_get_first_msg_id (vat_main_t * vam)
16217 {
16218   vl_api_get_first_msg_id_t *mp;
16219   unformat_input_t *i = vam->input;
16220   u8 *name;
16221   u8 name_set = 0;
16222   int ret;
16223
16224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (i, "client %s", &name))
16227         name_set = 1;
16228       else
16229         break;
16230     }
16231
16232   if (name_set == 0)
16233     {
16234       errmsg ("missing client name");
16235       return -99;
16236     }
16237   vec_add1 (name, 0);
16238
16239   if (vec_len (name) > 63)
16240     {
16241       errmsg ("client name too long");
16242       return -99;
16243     }
16244
16245   M (GET_FIRST_MSG_ID, mp);
16246   clib_memcpy (mp->name, name, vec_len (name));
16247   S (mp);
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static int
16253 api_cop_interface_enable_disable (vat_main_t * vam)
16254 {
16255   unformat_input_t *line_input = vam->input;
16256   vl_api_cop_interface_enable_disable_t *mp;
16257   u32 sw_if_index = ~0;
16258   u8 enable_disable = 1;
16259   int ret;
16260
16261   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (line_input, "disable"))
16264         enable_disable = 0;
16265       if (unformat (line_input, "enable"))
16266         enable_disable = 1;
16267       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16268                          vam, &sw_if_index))
16269         ;
16270       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16271         ;
16272       else
16273         break;
16274     }
16275
16276   if (sw_if_index == ~0)
16277     {
16278       errmsg ("missing interface name or sw_if_index");
16279       return -99;
16280     }
16281
16282   /* Construct the API message */
16283   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16284   mp->sw_if_index = ntohl (sw_if_index);
16285   mp->enable_disable = enable_disable;
16286
16287   /* send it... */
16288   S (mp);
16289   /* Wait for the reply */
16290   W (ret);
16291   return ret;
16292 }
16293
16294 static int
16295 api_cop_whitelist_enable_disable (vat_main_t * vam)
16296 {
16297   unformat_input_t *line_input = vam->input;
16298   vl_api_cop_whitelist_enable_disable_t *mp;
16299   u32 sw_if_index = ~0;
16300   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16301   u32 fib_id = 0;
16302   int ret;
16303
16304   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16305     {
16306       if (unformat (line_input, "ip4"))
16307         ip4 = 1;
16308       else if (unformat (line_input, "ip6"))
16309         ip6 = 1;
16310       else if (unformat (line_input, "default"))
16311         default_cop = 1;
16312       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16313                          vam, &sw_if_index))
16314         ;
16315       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16316         ;
16317       else if (unformat (line_input, "fib-id %d", &fib_id))
16318         ;
16319       else
16320         break;
16321     }
16322
16323   if (sw_if_index == ~0)
16324     {
16325       errmsg ("missing interface name or sw_if_index");
16326       return -99;
16327     }
16328
16329   /* Construct the API message */
16330   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16331   mp->sw_if_index = ntohl (sw_if_index);
16332   mp->fib_id = ntohl (fib_id);
16333   mp->ip4 = ip4;
16334   mp->ip6 = ip6;
16335   mp->default_cop = default_cop;
16336
16337   /* send it... */
16338   S (mp);
16339   /* Wait for the reply */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_get_node_graph (vat_main_t * vam)
16346 {
16347   vl_api_get_node_graph_t *mp;
16348   int ret;
16349
16350   M (GET_NODE_GRAPH, mp);
16351
16352   /* send it... */
16353   S (mp);
16354   /* Wait for the reply */
16355   W (ret);
16356   return ret;
16357 }
16358
16359 /* *INDENT-OFF* */
16360 /** Used for parsing LISP eids */
16361 typedef CLIB_PACKED(struct{
16362   u8 addr[16];   /**< eid address */
16363   u32 len;       /**< prefix length if IP */
16364   u8 type;      /**< type of eid */
16365 }) lisp_eid_vat_t;
16366 /* *INDENT-ON* */
16367
16368 static uword
16369 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16370 {
16371   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16372
16373   clib_memset (a, 0, sizeof (a[0]));
16374
16375   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16376     {
16377       a->type = 0;              /* ipv4 type */
16378     }
16379   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16380     {
16381       a->type = 1;              /* ipv6 type */
16382     }
16383   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16384     {
16385       a->type = 2;              /* mac type */
16386     }
16387   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16388     {
16389       a->type = 3;              /* NSH type */
16390       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16391       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16392     }
16393   else
16394     {
16395       return 0;
16396     }
16397
16398   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16399     {
16400       return 0;
16401     }
16402
16403   return 1;
16404 }
16405
16406 static int
16407 lisp_eid_size_vat (u8 type)
16408 {
16409   switch (type)
16410     {
16411     case 0:
16412       return 4;
16413     case 1:
16414       return 16;
16415     case 2:
16416       return 6;
16417     case 3:
16418       return 5;
16419     }
16420   return 0;
16421 }
16422
16423 static void
16424 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16425 {
16426   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16427 }
16428
16429 static int
16430 api_one_add_del_locator_set (vat_main_t * vam)
16431 {
16432   unformat_input_t *input = vam->input;
16433   vl_api_one_add_del_locator_set_t *mp;
16434   u8 is_add = 1;
16435   u8 *locator_set_name = NULL;
16436   u8 locator_set_name_set = 0;
16437   vl_api_local_locator_t locator, *locators = 0;
16438   u32 sw_if_index, priority, weight;
16439   u32 data_len = 0;
16440
16441   int ret;
16442   /* Parse args required to build the message */
16443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16444     {
16445       if (unformat (input, "del"))
16446         {
16447           is_add = 0;
16448         }
16449       else if (unformat (input, "locator-set %s", &locator_set_name))
16450         {
16451           locator_set_name_set = 1;
16452         }
16453       else if (unformat (input, "sw_if_index %u p %u w %u",
16454                          &sw_if_index, &priority, &weight))
16455         {
16456           locator.sw_if_index = htonl (sw_if_index);
16457           locator.priority = priority;
16458           locator.weight = weight;
16459           vec_add1 (locators, locator);
16460         }
16461       else
16462         if (unformat
16463             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16464              &sw_if_index, &priority, &weight))
16465         {
16466           locator.sw_if_index = htonl (sw_if_index);
16467           locator.priority = priority;
16468           locator.weight = weight;
16469           vec_add1 (locators, locator);
16470         }
16471       else
16472         break;
16473     }
16474
16475   if (locator_set_name_set == 0)
16476     {
16477       errmsg ("missing locator-set name");
16478       vec_free (locators);
16479       return -99;
16480     }
16481
16482   if (vec_len (locator_set_name) > 64)
16483     {
16484       errmsg ("locator-set name too long");
16485       vec_free (locator_set_name);
16486       vec_free (locators);
16487       return -99;
16488     }
16489   vec_add1 (locator_set_name, 0);
16490
16491   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16492
16493   /* Construct the API message */
16494   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16495
16496   mp->is_add = is_add;
16497   clib_memcpy (mp->locator_set_name, locator_set_name,
16498                vec_len (locator_set_name));
16499   vec_free (locator_set_name);
16500
16501   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16502   if (locators)
16503     clib_memcpy (mp->locators, locators, data_len);
16504   vec_free (locators);
16505
16506   /* send it... */
16507   S (mp);
16508
16509   /* Wait for a reply... */
16510   W (ret);
16511   return ret;
16512 }
16513
16514 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16515
16516 static int
16517 api_one_add_del_locator (vat_main_t * vam)
16518 {
16519   unformat_input_t *input = vam->input;
16520   vl_api_one_add_del_locator_t *mp;
16521   u32 tmp_if_index = ~0;
16522   u32 sw_if_index = ~0;
16523   u8 sw_if_index_set = 0;
16524   u8 sw_if_index_if_name_set = 0;
16525   u32 priority = ~0;
16526   u8 priority_set = 0;
16527   u32 weight = ~0;
16528   u8 weight_set = 0;
16529   u8 is_add = 1;
16530   u8 *locator_set_name = NULL;
16531   u8 locator_set_name_set = 0;
16532   int ret;
16533
16534   /* Parse args required to build the message */
16535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16536     {
16537       if (unformat (input, "del"))
16538         {
16539           is_add = 0;
16540         }
16541       else if (unformat (input, "locator-set %s", &locator_set_name))
16542         {
16543           locator_set_name_set = 1;
16544         }
16545       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16546                          &tmp_if_index))
16547         {
16548           sw_if_index_if_name_set = 1;
16549           sw_if_index = tmp_if_index;
16550         }
16551       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16552         {
16553           sw_if_index_set = 1;
16554           sw_if_index = tmp_if_index;
16555         }
16556       else if (unformat (input, "p %d", &priority))
16557         {
16558           priority_set = 1;
16559         }
16560       else if (unformat (input, "w %d", &weight))
16561         {
16562           weight_set = 1;
16563         }
16564       else
16565         break;
16566     }
16567
16568   if (locator_set_name_set == 0)
16569     {
16570       errmsg ("missing locator-set name");
16571       return -99;
16572     }
16573
16574   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16575     {
16576       errmsg ("missing sw_if_index");
16577       vec_free (locator_set_name);
16578       return -99;
16579     }
16580
16581   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16582     {
16583       errmsg ("cannot use both params interface name and sw_if_index");
16584       vec_free (locator_set_name);
16585       return -99;
16586     }
16587
16588   if (priority_set == 0)
16589     {
16590       errmsg ("missing locator-set priority");
16591       vec_free (locator_set_name);
16592       return -99;
16593     }
16594
16595   if (weight_set == 0)
16596     {
16597       errmsg ("missing locator-set weight");
16598       vec_free (locator_set_name);
16599       return -99;
16600     }
16601
16602   if (vec_len (locator_set_name) > 64)
16603     {
16604       errmsg ("locator-set name too long");
16605       vec_free (locator_set_name);
16606       return -99;
16607     }
16608   vec_add1 (locator_set_name, 0);
16609
16610   /* Construct the API message */
16611   M (ONE_ADD_DEL_LOCATOR, mp);
16612
16613   mp->is_add = is_add;
16614   mp->sw_if_index = ntohl (sw_if_index);
16615   mp->priority = priority;
16616   mp->weight = weight;
16617   clib_memcpy (mp->locator_set_name, locator_set_name,
16618                vec_len (locator_set_name));
16619   vec_free (locator_set_name);
16620
16621   /* send it... */
16622   S (mp);
16623
16624   /* Wait for a reply... */
16625   W (ret);
16626   return ret;
16627 }
16628
16629 #define api_lisp_add_del_locator api_one_add_del_locator
16630
16631 uword
16632 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16633 {
16634   u32 *key_id = va_arg (*args, u32 *);
16635   u8 *s = 0;
16636
16637   if (unformat (input, "%s", &s))
16638     {
16639       if (!strcmp ((char *) s, "sha1"))
16640         key_id[0] = HMAC_SHA_1_96;
16641       else if (!strcmp ((char *) s, "sha256"))
16642         key_id[0] = HMAC_SHA_256_128;
16643       else
16644         {
16645           clib_warning ("invalid key_id: '%s'", s);
16646           key_id[0] = HMAC_NO_KEY;
16647         }
16648     }
16649   else
16650     return 0;
16651
16652   vec_free (s);
16653   return 1;
16654 }
16655
16656 static int
16657 api_one_add_del_local_eid (vat_main_t * vam)
16658 {
16659   unformat_input_t *input = vam->input;
16660   vl_api_one_add_del_local_eid_t *mp;
16661   u8 is_add = 1;
16662   u8 eid_set = 0;
16663   lisp_eid_vat_t _eid, *eid = &_eid;
16664   u8 *locator_set_name = 0;
16665   u8 locator_set_name_set = 0;
16666   u32 vni = 0;
16667   u16 key_id = 0;
16668   u8 *key = 0;
16669   int ret;
16670
16671   /* Parse args required to build the message */
16672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (input, "del"))
16675         {
16676           is_add = 0;
16677         }
16678       else if (unformat (input, "vni %d", &vni))
16679         {
16680           ;
16681         }
16682       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16683         {
16684           eid_set = 1;
16685         }
16686       else if (unformat (input, "locator-set %s", &locator_set_name))
16687         {
16688           locator_set_name_set = 1;
16689         }
16690       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16691         ;
16692       else if (unformat (input, "secret-key %_%v%_", &key))
16693         ;
16694       else
16695         break;
16696     }
16697
16698   if (locator_set_name_set == 0)
16699     {
16700       errmsg ("missing locator-set name");
16701       return -99;
16702     }
16703
16704   if (0 == eid_set)
16705     {
16706       errmsg ("EID address not set!");
16707       vec_free (locator_set_name);
16708       return -99;
16709     }
16710
16711   if (key && (0 == key_id))
16712     {
16713       errmsg ("invalid key_id!");
16714       return -99;
16715     }
16716
16717   if (vec_len (key) > 64)
16718     {
16719       errmsg ("key too long");
16720       vec_free (key);
16721       return -99;
16722     }
16723
16724   if (vec_len (locator_set_name) > 64)
16725     {
16726       errmsg ("locator-set name too long");
16727       vec_free (locator_set_name);
16728       return -99;
16729     }
16730   vec_add1 (locator_set_name, 0);
16731
16732   /* Construct the API message */
16733   M (ONE_ADD_DEL_LOCAL_EID, mp);
16734
16735   mp->is_add = is_add;
16736   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16737   mp->eid_type = eid->type;
16738   mp->prefix_len = eid->len;
16739   mp->vni = clib_host_to_net_u32 (vni);
16740   mp->key_id = clib_host_to_net_u16 (key_id);
16741   clib_memcpy (mp->locator_set_name, locator_set_name,
16742                vec_len (locator_set_name));
16743   clib_memcpy (mp->key, key, vec_len (key));
16744
16745   vec_free (locator_set_name);
16746   vec_free (key);
16747
16748   /* send it... */
16749   S (mp);
16750
16751   /* Wait for a reply... */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16757
16758 static int
16759 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16760 {
16761   u32 dp_table = 0, vni = 0;;
16762   unformat_input_t *input = vam->input;
16763   vl_api_gpe_add_del_fwd_entry_t *mp;
16764   u8 is_add = 1;
16765   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16766   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16767   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16768   u32 action = ~0, w;
16769   ip4_address_t rmt_rloc4, lcl_rloc4;
16770   ip6_address_t rmt_rloc6, lcl_rloc6;
16771   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16772   int ret;
16773
16774   clib_memset (&rloc, 0, sizeof (rloc));
16775
16776   /* Parse args required to build the message */
16777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16778     {
16779       if (unformat (input, "del"))
16780         is_add = 0;
16781       else if (unformat (input, "add"))
16782         is_add = 1;
16783       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16784         {
16785           rmt_eid_set = 1;
16786         }
16787       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16788         {
16789           lcl_eid_set = 1;
16790         }
16791       else if (unformat (input, "vrf %d", &dp_table))
16792         ;
16793       else if (unformat (input, "bd %d", &dp_table))
16794         ;
16795       else if (unformat (input, "vni %d", &vni))
16796         ;
16797       else if (unformat (input, "w %d", &w))
16798         {
16799           if (!curr_rloc)
16800             {
16801               errmsg ("No RLOC configured for setting priority/weight!");
16802               return -99;
16803             }
16804           curr_rloc->weight = w;
16805         }
16806       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16807                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16808         {
16809           rloc.is_ip4 = 1;
16810
16811           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16812           rloc.weight = 0;
16813           vec_add1 (lcl_locs, rloc);
16814
16815           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16816           vec_add1 (rmt_locs, rloc);
16817           /* weight saved in rmt loc */
16818           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16819         }
16820       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16821                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16822         {
16823           rloc.is_ip4 = 0;
16824           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16825           rloc.weight = 0;
16826           vec_add1 (lcl_locs, rloc);
16827
16828           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16829           vec_add1 (rmt_locs, rloc);
16830           /* weight saved in rmt loc */
16831           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16832         }
16833       else if (unformat (input, "action %d", &action))
16834         {
16835           ;
16836         }
16837       else
16838         {
16839           clib_warning ("parse error '%U'", format_unformat_error, input);
16840           return -99;
16841         }
16842     }
16843
16844   if (!rmt_eid_set)
16845     {
16846       errmsg ("remote eid addresses not set");
16847       return -99;
16848     }
16849
16850   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16851     {
16852       errmsg ("eid types don't match");
16853       return -99;
16854     }
16855
16856   if (0 == rmt_locs && (u32) ~ 0 == action)
16857     {
16858       errmsg ("action not set for negative mapping");
16859       return -99;
16860     }
16861
16862   /* Construct the API message */
16863   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16864       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16865
16866   mp->is_add = is_add;
16867   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16868   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16869   mp->eid_type = rmt_eid->type;
16870   mp->dp_table = clib_host_to_net_u32 (dp_table);
16871   mp->vni = clib_host_to_net_u32 (vni);
16872   mp->rmt_len = rmt_eid->len;
16873   mp->lcl_len = lcl_eid->len;
16874   mp->action = action;
16875
16876   if (0 != rmt_locs && 0 != lcl_locs)
16877     {
16878       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16879       clib_memcpy (mp->locs, lcl_locs,
16880                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16881
16882       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16883       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16884                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16885     }
16886   vec_free (lcl_locs);
16887   vec_free (rmt_locs);
16888
16889   /* send it... */
16890   S (mp);
16891
16892   /* Wait for a reply... */
16893   W (ret);
16894   return ret;
16895 }
16896
16897 static int
16898 api_one_add_del_map_server (vat_main_t * vam)
16899 {
16900   unformat_input_t *input = vam->input;
16901   vl_api_one_add_del_map_server_t *mp;
16902   u8 is_add = 1;
16903   u8 ipv4_set = 0;
16904   u8 ipv6_set = 0;
16905   ip4_address_t ipv4;
16906   ip6_address_t ipv6;
16907   int ret;
16908
16909   /* Parse args required to build the message */
16910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (input, "del"))
16913         {
16914           is_add = 0;
16915         }
16916       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16917         {
16918           ipv4_set = 1;
16919         }
16920       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16921         {
16922           ipv6_set = 1;
16923         }
16924       else
16925         break;
16926     }
16927
16928   if (ipv4_set && ipv6_set)
16929     {
16930       errmsg ("both eid v4 and v6 addresses set");
16931       return -99;
16932     }
16933
16934   if (!ipv4_set && !ipv6_set)
16935     {
16936       errmsg ("eid addresses not set");
16937       return -99;
16938     }
16939
16940   /* Construct the API message */
16941   M (ONE_ADD_DEL_MAP_SERVER, mp);
16942
16943   mp->is_add = is_add;
16944   if (ipv6_set)
16945     {
16946       mp->is_ipv6 = 1;
16947       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16948     }
16949   else
16950     {
16951       mp->is_ipv6 = 0;
16952       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16953     }
16954
16955   /* send it... */
16956   S (mp);
16957
16958   /* Wait for a reply... */
16959   W (ret);
16960   return ret;
16961 }
16962
16963 #define api_lisp_add_del_map_server api_one_add_del_map_server
16964
16965 static int
16966 api_one_add_del_map_resolver (vat_main_t * vam)
16967 {
16968   unformat_input_t *input = vam->input;
16969   vl_api_one_add_del_map_resolver_t *mp;
16970   u8 is_add = 1;
16971   u8 ipv4_set = 0;
16972   u8 ipv6_set = 0;
16973   ip4_address_t ipv4;
16974   ip6_address_t ipv6;
16975   int ret;
16976
16977   /* Parse args required to build the message */
16978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16979     {
16980       if (unformat (input, "del"))
16981         {
16982           is_add = 0;
16983         }
16984       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16985         {
16986           ipv4_set = 1;
16987         }
16988       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16989         {
16990           ipv6_set = 1;
16991         }
16992       else
16993         break;
16994     }
16995
16996   if (ipv4_set && ipv6_set)
16997     {
16998       errmsg ("both eid v4 and v6 addresses set");
16999       return -99;
17000     }
17001
17002   if (!ipv4_set && !ipv6_set)
17003     {
17004       errmsg ("eid addresses not set");
17005       return -99;
17006     }
17007
17008   /* Construct the API message */
17009   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17010
17011   mp->is_add = is_add;
17012   if (ipv6_set)
17013     {
17014       mp->is_ipv6 = 1;
17015       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17016     }
17017   else
17018     {
17019       mp->is_ipv6 = 0;
17020       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17021     }
17022
17023   /* send it... */
17024   S (mp);
17025
17026   /* Wait for a reply... */
17027   W (ret);
17028   return ret;
17029 }
17030
17031 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17032
17033 static int
17034 api_lisp_gpe_enable_disable (vat_main_t * vam)
17035 {
17036   unformat_input_t *input = vam->input;
17037   vl_api_gpe_enable_disable_t *mp;
17038   u8 is_set = 0;
17039   u8 is_en = 1;
17040   int ret;
17041
17042   /* Parse args required to build the message */
17043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17044     {
17045       if (unformat (input, "enable"))
17046         {
17047           is_set = 1;
17048           is_en = 1;
17049         }
17050       else if (unformat (input, "disable"))
17051         {
17052           is_set = 1;
17053           is_en = 0;
17054         }
17055       else
17056         break;
17057     }
17058
17059   if (is_set == 0)
17060     {
17061       errmsg ("Value not set");
17062       return -99;
17063     }
17064
17065   /* Construct the API message */
17066   M (GPE_ENABLE_DISABLE, mp);
17067
17068   mp->is_en = is_en;
17069
17070   /* send it... */
17071   S (mp);
17072
17073   /* Wait for a reply... */
17074   W (ret);
17075   return ret;
17076 }
17077
17078 static int
17079 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17080 {
17081   unformat_input_t *input = vam->input;
17082   vl_api_one_rloc_probe_enable_disable_t *mp;
17083   u8 is_set = 0;
17084   u8 is_en = 0;
17085   int ret;
17086
17087   /* Parse args required to build the message */
17088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17089     {
17090       if (unformat (input, "enable"))
17091         {
17092           is_set = 1;
17093           is_en = 1;
17094         }
17095       else if (unformat (input, "disable"))
17096         is_set = 1;
17097       else
17098         break;
17099     }
17100
17101   if (!is_set)
17102     {
17103       errmsg ("Value not set");
17104       return -99;
17105     }
17106
17107   /* Construct the API message */
17108   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17109
17110   mp->is_enabled = is_en;
17111
17112   /* send it... */
17113   S (mp);
17114
17115   /* Wait for a reply... */
17116   W (ret);
17117   return ret;
17118 }
17119
17120 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17121
17122 static int
17123 api_one_map_register_enable_disable (vat_main_t * vam)
17124 {
17125   unformat_input_t *input = vam->input;
17126   vl_api_one_map_register_enable_disable_t *mp;
17127   u8 is_set = 0;
17128   u8 is_en = 0;
17129   int ret;
17130
17131   /* Parse args required to build the message */
17132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17133     {
17134       if (unformat (input, "enable"))
17135         {
17136           is_set = 1;
17137           is_en = 1;
17138         }
17139       else if (unformat (input, "disable"))
17140         is_set = 1;
17141       else
17142         break;
17143     }
17144
17145   if (!is_set)
17146     {
17147       errmsg ("Value not set");
17148       return -99;
17149     }
17150
17151   /* Construct the API message */
17152   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17153
17154   mp->is_enabled = is_en;
17155
17156   /* send it... */
17157   S (mp);
17158
17159   /* Wait for a reply... */
17160   W (ret);
17161   return ret;
17162 }
17163
17164 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17165
17166 static int
17167 api_one_enable_disable (vat_main_t * vam)
17168 {
17169   unformat_input_t *input = vam->input;
17170   vl_api_one_enable_disable_t *mp;
17171   u8 is_set = 0;
17172   u8 is_en = 0;
17173   int ret;
17174
17175   /* Parse args required to build the message */
17176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17177     {
17178       if (unformat (input, "enable"))
17179         {
17180           is_set = 1;
17181           is_en = 1;
17182         }
17183       else if (unformat (input, "disable"))
17184         {
17185           is_set = 1;
17186         }
17187       else
17188         break;
17189     }
17190
17191   if (!is_set)
17192     {
17193       errmsg ("Value not set");
17194       return -99;
17195     }
17196
17197   /* Construct the API message */
17198   M (ONE_ENABLE_DISABLE, mp);
17199
17200   mp->is_en = is_en;
17201
17202   /* send it... */
17203   S (mp);
17204
17205   /* Wait for a reply... */
17206   W (ret);
17207   return ret;
17208 }
17209
17210 #define api_lisp_enable_disable api_one_enable_disable
17211
17212 static int
17213 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17214 {
17215   unformat_input_t *input = vam->input;
17216   vl_api_one_enable_disable_xtr_mode_t *mp;
17217   u8 is_set = 0;
17218   u8 is_en = 0;
17219   int ret;
17220
17221   /* Parse args required to build the message */
17222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (input, "enable"))
17225         {
17226           is_set = 1;
17227           is_en = 1;
17228         }
17229       else if (unformat (input, "disable"))
17230         {
17231           is_set = 1;
17232         }
17233       else
17234         break;
17235     }
17236
17237   if (!is_set)
17238     {
17239       errmsg ("Value not set");
17240       return -99;
17241     }
17242
17243   /* Construct the API message */
17244   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17245
17246   mp->is_en = is_en;
17247
17248   /* send it... */
17249   S (mp);
17250
17251   /* Wait for a reply... */
17252   W (ret);
17253   return ret;
17254 }
17255
17256 static int
17257 api_one_show_xtr_mode (vat_main_t * vam)
17258 {
17259   vl_api_one_show_xtr_mode_t *mp;
17260   int ret;
17261
17262   /* Construct the API message */
17263   M (ONE_SHOW_XTR_MODE, mp);
17264
17265   /* send it... */
17266   S (mp);
17267
17268   /* Wait for a reply... */
17269   W (ret);
17270   return ret;
17271 }
17272
17273 static int
17274 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17275 {
17276   unformat_input_t *input = vam->input;
17277   vl_api_one_enable_disable_pitr_mode_t *mp;
17278   u8 is_set = 0;
17279   u8 is_en = 0;
17280   int ret;
17281
17282   /* Parse args required to build the message */
17283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17284     {
17285       if (unformat (input, "enable"))
17286         {
17287           is_set = 1;
17288           is_en = 1;
17289         }
17290       else if (unformat (input, "disable"))
17291         {
17292           is_set = 1;
17293         }
17294       else
17295         break;
17296     }
17297
17298   if (!is_set)
17299     {
17300       errmsg ("Value not set");
17301       return -99;
17302     }
17303
17304   /* Construct the API message */
17305   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17306
17307   mp->is_en = is_en;
17308
17309   /* send it... */
17310   S (mp);
17311
17312   /* Wait for a reply... */
17313   W (ret);
17314   return ret;
17315 }
17316
17317 static int
17318 api_one_show_pitr_mode (vat_main_t * vam)
17319 {
17320   vl_api_one_show_pitr_mode_t *mp;
17321   int ret;
17322
17323   /* Construct the API message */
17324   M (ONE_SHOW_PITR_MODE, mp);
17325
17326   /* send it... */
17327   S (mp);
17328
17329   /* Wait for a reply... */
17330   W (ret);
17331   return ret;
17332 }
17333
17334 static int
17335 api_one_enable_disable_petr_mode (vat_main_t * vam)
17336 {
17337   unformat_input_t *input = vam->input;
17338   vl_api_one_enable_disable_petr_mode_t *mp;
17339   u8 is_set = 0;
17340   u8 is_en = 0;
17341   int ret;
17342
17343   /* Parse args required to build the message */
17344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17345     {
17346       if (unformat (input, "enable"))
17347         {
17348           is_set = 1;
17349           is_en = 1;
17350         }
17351       else if (unformat (input, "disable"))
17352         {
17353           is_set = 1;
17354         }
17355       else
17356         break;
17357     }
17358
17359   if (!is_set)
17360     {
17361       errmsg ("Value not set");
17362       return -99;
17363     }
17364
17365   /* Construct the API message */
17366   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17367
17368   mp->is_en = is_en;
17369
17370   /* send it... */
17371   S (mp);
17372
17373   /* Wait for a reply... */
17374   W (ret);
17375   return ret;
17376 }
17377
17378 static int
17379 api_one_show_petr_mode (vat_main_t * vam)
17380 {
17381   vl_api_one_show_petr_mode_t *mp;
17382   int ret;
17383
17384   /* Construct the API message */
17385   M (ONE_SHOW_PETR_MODE, mp);
17386
17387   /* send it... */
17388   S (mp);
17389
17390   /* Wait for a reply... */
17391   W (ret);
17392   return ret;
17393 }
17394
17395 static int
17396 api_show_one_map_register_state (vat_main_t * vam)
17397 {
17398   vl_api_show_one_map_register_state_t *mp;
17399   int ret;
17400
17401   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17402
17403   /* send */
17404   S (mp);
17405
17406   /* wait for reply */
17407   W (ret);
17408   return ret;
17409 }
17410
17411 #define api_show_lisp_map_register_state api_show_one_map_register_state
17412
17413 static int
17414 api_show_one_rloc_probe_state (vat_main_t * vam)
17415 {
17416   vl_api_show_one_rloc_probe_state_t *mp;
17417   int ret;
17418
17419   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17420
17421   /* send */
17422   S (mp);
17423
17424   /* wait for reply */
17425   W (ret);
17426   return ret;
17427 }
17428
17429 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17430
17431 static int
17432 api_one_add_del_ndp_entry (vat_main_t * vam)
17433 {
17434   vl_api_one_add_del_ndp_entry_t *mp;
17435   unformat_input_t *input = vam->input;
17436   u8 is_add = 1;
17437   u8 mac_set = 0;
17438   u8 bd_set = 0;
17439   u8 ip_set = 0;
17440   u8 mac[6] = { 0, };
17441   u8 ip6[16] = { 0, };
17442   u32 bd = ~0;
17443   int ret;
17444
17445   /* Parse args required to build the message */
17446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17447     {
17448       if (unformat (input, "del"))
17449         is_add = 0;
17450       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17451         mac_set = 1;
17452       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17453         ip_set = 1;
17454       else if (unformat (input, "bd %d", &bd))
17455         bd_set = 1;
17456       else
17457         {
17458           errmsg ("parse error '%U'", format_unformat_error, input);
17459           return -99;
17460         }
17461     }
17462
17463   if (!bd_set || !ip_set || (!mac_set && is_add))
17464     {
17465       errmsg ("Missing BD, IP or MAC!");
17466       return -99;
17467     }
17468
17469   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17470   mp->is_add = is_add;
17471   clib_memcpy (mp->mac, mac, 6);
17472   mp->bd = clib_host_to_net_u32 (bd);
17473   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17474
17475   /* send */
17476   S (mp);
17477
17478   /* wait for reply */
17479   W (ret);
17480   return ret;
17481 }
17482
17483 static int
17484 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17485 {
17486   vl_api_one_add_del_l2_arp_entry_t *mp;
17487   unformat_input_t *input = vam->input;
17488   u8 is_add = 1;
17489   u8 mac_set = 0;
17490   u8 bd_set = 0;
17491   u8 ip_set = 0;
17492   u8 mac[6] = { 0, };
17493   u32 ip4 = 0, bd = ~0;
17494   int ret;
17495
17496   /* Parse args required to build the message */
17497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17498     {
17499       if (unformat (input, "del"))
17500         is_add = 0;
17501       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17502         mac_set = 1;
17503       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17504         ip_set = 1;
17505       else if (unformat (input, "bd %d", &bd))
17506         bd_set = 1;
17507       else
17508         {
17509           errmsg ("parse error '%U'", format_unformat_error, input);
17510           return -99;
17511         }
17512     }
17513
17514   if (!bd_set || !ip_set || (!mac_set && is_add))
17515     {
17516       errmsg ("Missing BD, IP or MAC!");
17517       return -99;
17518     }
17519
17520   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17521   mp->is_add = is_add;
17522   clib_memcpy (mp->mac, mac, 6);
17523   mp->bd = clib_host_to_net_u32 (bd);
17524   mp->ip4 = ip4;
17525
17526   /* send */
17527   S (mp);
17528
17529   /* wait for reply */
17530   W (ret);
17531   return ret;
17532 }
17533
17534 static int
17535 api_one_ndp_bd_get (vat_main_t * vam)
17536 {
17537   vl_api_one_ndp_bd_get_t *mp;
17538   int ret;
17539
17540   M (ONE_NDP_BD_GET, mp);
17541
17542   /* send */
17543   S (mp);
17544
17545   /* wait for reply */
17546   W (ret);
17547   return ret;
17548 }
17549
17550 static int
17551 api_one_ndp_entries_get (vat_main_t * vam)
17552 {
17553   vl_api_one_ndp_entries_get_t *mp;
17554   unformat_input_t *input = vam->input;
17555   u8 bd_set = 0;
17556   u32 bd = ~0;
17557   int ret;
17558
17559   /* Parse args required to build the message */
17560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17561     {
17562       if (unformat (input, "bd %d", &bd))
17563         bd_set = 1;
17564       else
17565         {
17566           errmsg ("parse error '%U'", format_unformat_error, input);
17567           return -99;
17568         }
17569     }
17570
17571   if (!bd_set)
17572     {
17573       errmsg ("Expected bridge domain!");
17574       return -99;
17575     }
17576
17577   M (ONE_NDP_ENTRIES_GET, mp);
17578   mp->bd = clib_host_to_net_u32 (bd);
17579
17580   /* send */
17581   S (mp);
17582
17583   /* wait for reply */
17584   W (ret);
17585   return ret;
17586 }
17587
17588 static int
17589 api_one_l2_arp_bd_get (vat_main_t * vam)
17590 {
17591   vl_api_one_l2_arp_bd_get_t *mp;
17592   int ret;
17593
17594   M (ONE_L2_ARP_BD_GET, mp);
17595
17596   /* send */
17597   S (mp);
17598
17599   /* wait for reply */
17600   W (ret);
17601   return ret;
17602 }
17603
17604 static int
17605 api_one_l2_arp_entries_get (vat_main_t * vam)
17606 {
17607   vl_api_one_l2_arp_entries_get_t *mp;
17608   unformat_input_t *input = vam->input;
17609   u8 bd_set = 0;
17610   u32 bd = ~0;
17611   int ret;
17612
17613   /* Parse args required to build the message */
17614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17615     {
17616       if (unformat (input, "bd %d", &bd))
17617         bd_set = 1;
17618       else
17619         {
17620           errmsg ("parse error '%U'", format_unformat_error, input);
17621           return -99;
17622         }
17623     }
17624
17625   if (!bd_set)
17626     {
17627       errmsg ("Expected bridge domain!");
17628       return -99;
17629     }
17630
17631   M (ONE_L2_ARP_ENTRIES_GET, mp);
17632   mp->bd = clib_host_to_net_u32 (bd);
17633
17634   /* send */
17635   S (mp);
17636
17637   /* wait for reply */
17638   W (ret);
17639   return ret;
17640 }
17641
17642 static int
17643 api_one_stats_enable_disable (vat_main_t * vam)
17644 {
17645   vl_api_one_stats_enable_disable_t *mp;
17646   unformat_input_t *input = vam->input;
17647   u8 is_set = 0;
17648   u8 is_en = 0;
17649   int ret;
17650
17651   /* Parse args required to build the message */
17652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17653     {
17654       if (unformat (input, "enable"))
17655         {
17656           is_set = 1;
17657           is_en = 1;
17658         }
17659       else if (unformat (input, "disable"))
17660         {
17661           is_set = 1;
17662         }
17663       else
17664         break;
17665     }
17666
17667   if (!is_set)
17668     {
17669       errmsg ("Value not set");
17670       return -99;
17671     }
17672
17673   M (ONE_STATS_ENABLE_DISABLE, mp);
17674   mp->is_en = is_en;
17675
17676   /* send */
17677   S (mp);
17678
17679   /* wait for reply */
17680   W (ret);
17681   return ret;
17682 }
17683
17684 static int
17685 api_show_one_stats_enable_disable (vat_main_t * vam)
17686 {
17687   vl_api_show_one_stats_enable_disable_t *mp;
17688   int ret;
17689
17690   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17691
17692   /* send */
17693   S (mp);
17694
17695   /* wait for reply */
17696   W (ret);
17697   return ret;
17698 }
17699
17700 static int
17701 api_show_one_map_request_mode (vat_main_t * vam)
17702 {
17703   vl_api_show_one_map_request_mode_t *mp;
17704   int ret;
17705
17706   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17707
17708   /* send */
17709   S (mp);
17710
17711   /* wait for reply */
17712   W (ret);
17713   return ret;
17714 }
17715
17716 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17717
17718 static int
17719 api_one_map_request_mode (vat_main_t * vam)
17720 {
17721   unformat_input_t *input = vam->input;
17722   vl_api_one_map_request_mode_t *mp;
17723   u8 mode = 0;
17724   int ret;
17725
17726   /* Parse args required to build the message */
17727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17728     {
17729       if (unformat (input, "dst-only"))
17730         mode = 0;
17731       else if (unformat (input, "src-dst"))
17732         mode = 1;
17733       else
17734         {
17735           errmsg ("parse error '%U'", format_unformat_error, input);
17736           return -99;
17737         }
17738     }
17739
17740   M (ONE_MAP_REQUEST_MODE, mp);
17741
17742   mp->mode = mode;
17743
17744   /* send */
17745   S (mp);
17746
17747   /* wait for reply */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 #define api_lisp_map_request_mode api_one_map_request_mode
17753
17754 /**
17755  * Enable/disable ONE proxy ITR.
17756  *
17757  * @param vam vpp API test context
17758  * @return return code
17759  */
17760 static int
17761 api_one_pitr_set_locator_set (vat_main_t * vam)
17762 {
17763   u8 ls_name_set = 0;
17764   unformat_input_t *input = vam->input;
17765   vl_api_one_pitr_set_locator_set_t *mp;
17766   u8 is_add = 1;
17767   u8 *ls_name = 0;
17768   int ret;
17769
17770   /* Parse args required to build the message */
17771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17772     {
17773       if (unformat (input, "del"))
17774         is_add = 0;
17775       else if (unformat (input, "locator-set %s", &ls_name))
17776         ls_name_set = 1;
17777       else
17778         {
17779           errmsg ("parse error '%U'", format_unformat_error, input);
17780           return -99;
17781         }
17782     }
17783
17784   if (!ls_name_set)
17785     {
17786       errmsg ("locator-set name not set!");
17787       return -99;
17788     }
17789
17790   M (ONE_PITR_SET_LOCATOR_SET, mp);
17791
17792   mp->is_add = is_add;
17793   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17794   vec_free (ls_name);
17795
17796   /* send */
17797   S (mp);
17798
17799   /* wait for reply */
17800   W (ret);
17801   return ret;
17802 }
17803
17804 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17805
17806 static int
17807 api_one_nsh_set_locator_set (vat_main_t * vam)
17808 {
17809   u8 ls_name_set = 0;
17810   unformat_input_t *input = vam->input;
17811   vl_api_one_nsh_set_locator_set_t *mp;
17812   u8 is_add = 1;
17813   u8 *ls_name = 0;
17814   int ret;
17815
17816   /* Parse args required to build the message */
17817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (input, "del"))
17820         is_add = 0;
17821       else if (unformat (input, "ls %s", &ls_name))
17822         ls_name_set = 1;
17823       else
17824         {
17825           errmsg ("parse error '%U'", format_unformat_error, input);
17826           return -99;
17827         }
17828     }
17829
17830   if (!ls_name_set && is_add)
17831     {
17832       errmsg ("locator-set name not set!");
17833       return -99;
17834     }
17835
17836   M (ONE_NSH_SET_LOCATOR_SET, mp);
17837
17838   mp->is_add = is_add;
17839   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17840   vec_free (ls_name);
17841
17842   /* send */
17843   S (mp);
17844
17845   /* wait for reply */
17846   W (ret);
17847   return ret;
17848 }
17849
17850 static int
17851 api_show_one_pitr (vat_main_t * vam)
17852 {
17853   vl_api_show_one_pitr_t *mp;
17854   int ret;
17855
17856   if (!vam->json_output)
17857     {
17858       print (vam->ofp, "%=20s", "lisp status:");
17859     }
17860
17861   M (SHOW_ONE_PITR, mp);
17862   /* send it... */
17863   S (mp);
17864
17865   /* Wait for a reply... */
17866   W (ret);
17867   return ret;
17868 }
17869
17870 #define api_show_lisp_pitr api_show_one_pitr
17871
17872 static int
17873 api_one_use_petr (vat_main_t * vam)
17874 {
17875   unformat_input_t *input = vam->input;
17876   vl_api_one_use_petr_t *mp;
17877   u8 is_add = 0;
17878   ip_address_t ip;
17879   int ret;
17880
17881   clib_memset (&ip, 0, sizeof (ip));
17882
17883   /* Parse args required to build the message */
17884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17885     {
17886       if (unformat (input, "disable"))
17887         is_add = 0;
17888       else
17889         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17890         {
17891           is_add = 1;
17892           ip_addr_version (&ip) = IP4;
17893         }
17894       else
17895         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17896         {
17897           is_add = 1;
17898           ip_addr_version (&ip) = IP6;
17899         }
17900       else
17901         {
17902           errmsg ("parse error '%U'", format_unformat_error, input);
17903           return -99;
17904         }
17905     }
17906
17907   M (ONE_USE_PETR, mp);
17908
17909   mp->is_add = is_add;
17910   if (is_add)
17911     {
17912       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17913       if (mp->is_ip4)
17914         clib_memcpy (mp->address, &ip, 4);
17915       else
17916         clib_memcpy (mp->address, &ip, 16);
17917     }
17918
17919   /* send */
17920   S (mp);
17921
17922   /* wait for reply */
17923   W (ret);
17924   return ret;
17925 }
17926
17927 #define api_lisp_use_petr api_one_use_petr
17928
17929 static int
17930 api_show_one_nsh_mapping (vat_main_t * vam)
17931 {
17932   vl_api_show_one_use_petr_t *mp;
17933   int ret;
17934
17935   if (!vam->json_output)
17936     {
17937       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17938     }
17939
17940   M (SHOW_ONE_NSH_MAPPING, mp);
17941   /* send it... */
17942   S (mp);
17943
17944   /* Wait for a reply... */
17945   W (ret);
17946   return ret;
17947 }
17948
17949 static int
17950 api_show_one_use_petr (vat_main_t * vam)
17951 {
17952   vl_api_show_one_use_petr_t *mp;
17953   int ret;
17954
17955   if (!vam->json_output)
17956     {
17957       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17958     }
17959
17960   M (SHOW_ONE_USE_PETR, mp);
17961   /* send it... */
17962   S (mp);
17963
17964   /* Wait for a reply... */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 #define api_show_lisp_use_petr api_show_one_use_petr
17970
17971 /**
17972  * Add/delete mapping between vni and vrf
17973  */
17974 static int
17975 api_one_eid_table_add_del_map (vat_main_t * vam)
17976 {
17977   unformat_input_t *input = vam->input;
17978   vl_api_one_eid_table_add_del_map_t *mp;
17979   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17980   u32 vni, vrf, bd_index;
17981   int ret;
17982
17983   /* Parse args required to build the message */
17984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17985     {
17986       if (unformat (input, "del"))
17987         is_add = 0;
17988       else if (unformat (input, "vrf %d", &vrf))
17989         vrf_set = 1;
17990       else if (unformat (input, "bd_index %d", &bd_index))
17991         bd_index_set = 1;
17992       else if (unformat (input, "vni %d", &vni))
17993         vni_set = 1;
17994       else
17995         break;
17996     }
17997
17998   if (!vni_set || (!vrf_set && !bd_index_set))
17999     {
18000       errmsg ("missing arguments!");
18001       return -99;
18002     }
18003
18004   if (vrf_set && bd_index_set)
18005     {
18006       errmsg ("error: both vrf and bd entered!");
18007       return -99;
18008     }
18009
18010   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18011
18012   mp->is_add = is_add;
18013   mp->vni = htonl (vni);
18014   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18015   mp->is_l2 = bd_index_set;
18016
18017   /* send */
18018   S (mp);
18019
18020   /* wait for reply */
18021   W (ret);
18022   return ret;
18023 }
18024
18025 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18026
18027 uword
18028 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18029 {
18030   u32 *action = va_arg (*args, u32 *);
18031   u8 *s = 0;
18032
18033   if (unformat (input, "%s", &s))
18034     {
18035       if (!strcmp ((char *) s, "no-action"))
18036         action[0] = 0;
18037       else if (!strcmp ((char *) s, "natively-forward"))
18038         action[0] = 1;
18039       else if (!strcmp ((char *) s, "send-map-request"))
18040         action[0] = 2;
18041       else if (!strcmp ((char *) s, "drop"))
18042         action[0] = 3;
18043       else
18044         {
18045           clib_warning ("invalid action: '%s'", s);
18046           action[0] = 3;
18047         }
18048     }
18049   else
18050     return 0;
18051
18052   vec_free (s);
18053   return 1;
18054 }
18055
18056 /**
18057  * Add/del remote mapping to/from ONE control plane
18058  *
18059  * @param vam vpp API test context
18060  * @return return code
18061  */
18062 static int
18063 api_one_add_del_remote_mapping (vat_main_t * vam)
18064 {
18065   unformat_input_t *input = vam->input;
18066   vl_api_one_add_del_remote_mapping_t *mp;
18067   u32 vni = 0;
18068   lisp_eid_vat_t _eid, *eid = &_eid;
18069   lisp_eid_vat_t _seid, *seid = &_seid;
18070   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18071   u32 action = ~0, p, w, data_len;
18072   ip4_address_t rloc4;
18073   ip6_address_t rloc6;
18074   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18075   int ret;
18076
18077   clib_memset (&rloc, 0, sizeof (rloc));
18078
18079   /* Parse args required to build the message */
18080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18081     {
18082       if (unformat (input, "del-all"))
18083         {
18084           del_all = 1;
18085         }
18086       else if (unformat (input, "del"))
18087         {
18088           is_add = 0;
18089         }
18090       else if (unformat (input, "add"))
18091         {
18092           is_add = 1;
18093         }
18094       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18095         {
18096           eid_set = 1;
18097         }
18098       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18099         {
18100           seid_set = 1;
18101         }
18102       else if (unformat (input, "vni %d", &vni))
18103         {
18104           ;
18105         }
18106       else if (unformat (input, "p %d w %d", &p, &w))
18107         {
18108           if (!curr_rloc)
18109             {
18110               errmsg ("No RLOC configured for setting priority/weight!");
18111               return -99;
18112             }
18113           curr_rloc->priority = p;
18114           curr_rloc->weight = w;
18115         }
18116       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18117         {
18118           rloc.is_ip4 = 1;
18119           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18120           vec_add1 (rlocs, rloc);
18121           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18122         }
18123       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18124         {
18125           rloc.is_ip4 = 0;
18126           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18127           vec_add1 (rlocs, rloc);
18128           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18129         }
18130       else if (unformat (input, "action %U",
18131                          unformat_negative_mapping_action, &action))
18132         {
18133           ;
18134         }
18135       else
18136         {
18137           clib_warning ("parse error '%U'", format_unformat_error, input);
18138           return -99;
18139         }
18140     }
18141
18142   if (0 == eid_set)
18143     {
18144       errmsg ("missing params!");
18145       return -99;
18146     }
18147
18148   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18149     {
18150       errmsg ("no action set for negative map-reply!");
18151       return -99;
18152     }
18153
18154   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18155
18156   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18157   mp->is_add = is_add;
18158   mp->vni = htonl (vni);
18159   mp->action = (u8) action;
18160   mp->is_src_dst = seid_set;
18161   mp->eid_len = eid->len;
18162   mp->seid_len = seid->len;
18163   mp->del_all = del_all;
18164   mp->eid_type = eid->type;
18165   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18166   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18167
18168   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18169   clib_memcpy (mp->rlocs, rlocs, data_len);
18170   vec_free (rlocs);
18171
18172   /* send it... */
18173   S (mp);
18174
18175   /* Wait for a reply... */
18176   W (ret);
18177   return ret;
18178 }
18179
18180 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18181
18182 /**
18183  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18184  * forwarding entries in data-plane accordingly.
18185  *
18186  * @param vam vpp API test context
18187  * @return return code
18188  */
18189 static int
18190 api_one_add_del_adjacency (vat_main_t * vam)
18191 {
18192   unformat_input_t *input = vam->input;
18193   vl_api_one_add_del_adjacency_t *mp;
18194   u32 vni = 0;
18195   ip4_address_t leid4, reid4;
18196   ip6_address_t leid6, reid6;
18197   u8 reid_mac[6] = { 0 };
18198   u8 leid_mac[6] = { 0 };
18199   u8 reid_type, leid_type;
18200   u32 leid_len = 0, reid_len = 0, len;
18201   u8 is_add = 1;
18202   int ret;
18203
18204   leid_type = reid_type = (u8) ~ 0;
18205
18206   /* Parse args required to build the message */
18207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18208     {
18209       if (unformat (input, "del"))
18210         {
18211           is_add = 0;
18212         }
18213       else if (unformat (input, "add"))
18214         {
18215           is_add = 1;
18216         }
18217       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18218                          &reid4, &len))
18219         {
18220           reid_type = 0;        /* ipv4 */
18221           reid_len = len;
18222         }
18223       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18224                          &reid6, &len))
18225         {
18226           reid_type = 1;        /* ipv6 */
18227           reid_len = len;
18228         }
18229       else if (unformat (input, "reid %U", unformat_ethernet_address,
18230                          reid_mac))
18231         {
18232           reid_type = 2;        /* mac */
18233         }
18234       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18235                          &leid4, &len))
18236         {
18237           leid_type = 0;        /* ipv4 */
18238           leid_len = len;
18239         }
18240       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18241                          &leid6, &len))
18242         {
18243           leid_type = 1;        /* ipv6 */
18244           leid_len = len;
18245         }
18246       else if (unformat (input, "leid %U", unformat_ethernet_address,
18247                          leid_mac))
18248         {
18249           leid_type = 2;        /* mac */
18250         }
18251       else if (unformat (input, "vni %d", &vni))
18252         {
18253           ;
18254         }
18255       else
18256         {
18257           errmsg ("parse error '%U'", format_unformat_error, input);
18258           return -99;
18259         }
18260     }
18261
18262   if ((u8) ~ 0 == reid_type)
18263     {
18264       errmsg ("missing params!");
18265       return -99;
18266     }
18267
18268   if (leid_type != reid_type)
18269     {
18270       errmsg ("remote and local EIDs are of different types!");
18271       return -99;
18272     }
18273
18274   M (ONE_ADD_DEL_ADJACENCY, mp);
18275   mp->is_add = is_add;
18276   mp->vni = htonl (vni);
18277   mp->leid_len = leid_len;
18278   mp->reid_len = reid_len;
18279   mp->eid_type = reid_type;
18280
18281   switch (mp->eid_type)
18282     {
18283     case 0:
18284       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18285       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18286       break;
18287     case 1:
18288       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18289       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18290       break;
18291     case 2:
18292       clib_memcpy (mp->leid, leid_mac, 6);
18293       clib_memcpy (mp->reid, reid_mac, 6);
18294       break;
18295     default:
18296       errmsg ("unknown EID type %d!", mp->eid_type);
18297       return 0;
18298     }
18299
18300   /* send it... */
18301   S (mp);
18302
18303   /* Wait for a reply... */
18304   W (ret);
18305   return ret;
18306 }
18307
18308 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18309
18310 uword
18311 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18312 {
18313   u32 *mode = va_arg (*args, u32 *);
18314
18315   if (unformat (input, "lisp"))
18316     *mode = 0;
18317   else if (unformat (input, "vxlan"))
18318     *mode = 1;
18319   else
18320     return 0;
18321
18322   return 1;
18323 }
18324
18325 static int
18326 api_gpe_get_encap_mode (vat_main_t * vam)
18327 {
18328   vl_api_gpe_get_encap_mode_t *mp;
18329   int ret;
18330
18331   /* Construct the API message */
18332   M (GPE_GET_ENCAP_MODE, mp);
18333
18334   /* send it... */
18335   S (mp);
18336
18337   /* Wait for a reply... */
18338   W (ret);
18339   return ret;
18340 }
18341
18342 static int
18343 api_gpe_set_encap_mode (vat_main_t * vam)
18344 {
18345   unformat_input_t *input = vam->input;
18346   vl_api_gpe_set_encap_mode_t *mp;
18347   int ret;
18348   u32 mode = 0;
18349
18350   /* Parse args required to build the message */
18351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18352     {
18353       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18354         ;
18355       else
18356         break;
18357     }
18358
18359   /* Construct the API message */
18360   M (GPE_SET_ENCAP_MODE, mp);
18361
18362   mp->mode = mode;
18363
18364   /* send it... */
18365   S (mp);
18366
18367   /* Wait for a reply... */
18368   W (ret);
18369   return ret;
18370 }
18371
18372 static int
18373 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18374 {
18375   unformat_input_t *input = vam->input;
18376   vl_api_gpe_add_del_iface_t *mp;
18377   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18378   u32 dp_table = 0, vni = 0;
18379   int ret;
18380
18381   /* Parse args required to build the message */
18382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18383     {
18384       if (unformat (input, "up"))
18385         {
18386           action_set = 1;
18387           is_add = 1;
18388         }
18389       else if (unformat (input, "down"))
18390         {
18391           action_set = 1;
18392           is_add = 0;
18393         }
18394       else if (unformat (input, "table_id %d", &dp_table))
18395         {
18396           dp_table_set = 1;
18397         }
18398       else if (unformat (input, "bd_id %d", &dp_table))
18399         {
18400           dp_table_set = 1;
18401           is_l2 = 1;
18402         }
18403       else if (unformat (input, "vni %d", &vni))
18404         {
18405           vni_set = 1;
18406         }
18407       else
18408         break;
18409     }
18410
18411   if (action_set == 0)
18412     {
18413       errmsg ("Action not set");
18414       return -99;
18415     }
18416   if (dp_table_set == 0 || vni_set == 0)
18417     {
18418       errmsg ("vni and dp_table must be set");
18419       return -99;
18420     }
18421
18422   /* Construct the API message */
18423   M (GPE_ADD_DEL_IFACE, mp);
18424
18425   mp->is_add = is_add;
18426   mp->dp_table = clib_host_to_net_u32 (dp_table);
18427   mp->is_l2 = is_l2;
18428   mp->vni = clib_host_to_net_u32 (vni);
18429
18430   /* send it... */
18431   S (mp);
18432
18433   /* Wait for a reply... */
18434   W (ret);
18435   return ret;
18436 }
18437
18438 static int
18439 api_one_map_register_fallback_threshold (vat_main_t * vam)
18440 {
18441   unformat_input_t *input = vam->input;
18442   vl_api_one_map_register_fallback_threshold_t *mp;
18443   u32 value = 0;
18444   u8 is_set = 0;
18445   int ret;
18446
18447   /* Parse args required to build the message */
18448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18449     {
18450       if (unformat (input, "%u", &value))
18451         is_set = 1;
18452       else
18453         {
18454           clib_warning ("parse error '%U'", format_unformat_error, input);
18455           return -99;
18456         }
18457     }
18458
18459   if (!is_set)
18460     {
18461       errmsg ("fallback threshold value is missing!");
18462       return -99;
18463     }
18464
18465   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18466   mp->value = clib_host_to_net_u32 (value);
18467
18468   /* send it... */
18469   S (mp);
18470
18471   /* Wait for a reply... */
18472   W (ret);
18473   return ret;
18474 }
18475
18476 static int
18477 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18478 {
18479   vl_api_show_one_map_register_fallback_threshold_t *mp;
18480   int ret;
18481
18482   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18483
18484   /* send it... */
18485   S (mp);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 uword
18493 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18494 {
18495   u32 *proto = va_arg (*args, u32 *);
18496
18497   if (unformat (input, "udp"))
18498     *proto = 1;
18499   else if (unformat (input, "api"))
18500     *proto = 2;
18501   else
18502     return 0;
18503
18504   return 1;
18505 }
18506
18507 static int
18508 api_one_set_transport_protocol (vat_main_t * vam)
18509 {
18510   unformat_input_t *input = vam->input;
18511   vl_api_one_set_transport_protocol_t *mp;
18512   u8 is_set = 0;
18513   u32 protocol = 0;
18514   int ret;
18515
18516   /* Parse args required to build the message */
18517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18518     {
18519       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18520         is_set = 1;
18521       else
18522         {
18523           clib_warning ("parse error '%U'", format_unformat_error, input);
18524           return -99;
18525         }
18526     }
18527
18528   if (!is_set)
18529     {
18530       errmsg ("Transport protocol missing!");
18531       return -99;
18532     }
18533
18534   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18535   mp->protocol = (u8) protocol;
18536
18537   /* send it... */
18538   S (mp);
18539
18540   /* Wait for a reply... */
18541   W (ret);
18542   return ret;
18543 }
18544
18545 static int
18546 api_one_get_transport_protocol (vat_main_t * vam)
18547 {
18548   vl_api_one_get_transport_protocol_t *mp;
18549   int ret;
18550
18551   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18552
18553   /* send it... */
18554   S (mp);
18555
18556   /* Wait for a reply... */
18557   W (ret);
18558   return ret;
18559 }
18560
18561 static int
18562 api_one_map_register_set_ttl (vat_main_t * vam)
18563 {
18564   unformat_input_t *input = vam->input;
18565   vl_api_one_map_register_set_ttl_t *mp;
18566   u32 ttl = 0;
18567   u8 is_set = 0;
18568   int ret;
18569
18570   /* Parse args required to build the message */
18571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18572     {
18573       if (unformat (input, "%u", &ttl))
18574         is_set = 1;
18575       else
18576         {
18577           clib_warning ("parse error '%U'", format_unformat_error, input);
18578           return -99;
18579         }
18580     }
18581
18582   if (!is_set)
18583     {
18584       errmsg ("TTL value missing!");
18585       return -99;
18586     }
18587
18588   M (ONE_MAP_REGISTER_SET_TTL, mp);
18589   mp->ttl = clib_host_to_net_u32 (ttl);
18590
18591   /* send it... */
18592   S (mp);
18593
18594   /* Wait for a reply... */
18595   W (ret);
18596   return ret;
18597 }
18598
18599 static int
18600 api_show_one_map_register_ttl (vat_main_t * vam)
18601 {
18602   vl_api_show_one_map_register_ttl_t *mp;
18603   int ret;
18604
18605   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18606
18607   /* send it... */
18608   S (mp);
18609
18610   /* Wait for a reply... */
18611   W (ret);
18612   return ret;
18613 }
18614
18615 /**
18616  * Add/del map request itr rlocs from ONE control plane and updates
18617  *
18618  * @param vam vpp API test context
18619  * @return return code
18620  */
18621 static int
18622 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18623 {
18624   unformat_input_t *input = vam->input;
18625   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18626   u8 *locator_set_name = 0;
18627   u8 locator_set_name_set = 0;
18628   u8 is_add = 1;
18629   int ret;
18630
18631   /* Parse args required to build the message */
18632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18633     {
18634       if (unformat (input, "del"))
18635         {
18636           is_add = 0;
18637         }
18638       else if (unformat (input, "%_%v%_", &locator_set_name))
18639         {
18640           locator_set_name_set = 1;
18641         }
18642       else
18643         {
18644           clib_warning ("parse error '%U'", format_unformat_error, input);
18645           return -99;
18646         }
18647     }
18648
18649   if (is_add && !locator_set_name_set)
18650     {
18651       errmsg ("itr-rloc is not set!");
18652       return -99;
18653     }
18654
18655   if (is_add && vec_len (locator_set_name) > 64)
18656     {
18657       errmsg ("itr-rloc locator-set name too long");
18658       vec_free (locator_set_name);
18659       return -99;
18660     }
18661
18662   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18663   mp->is_add = is_add;
18664   if (is_add)
18665     {
18666       clib_memcpy (mp->locator_set_name, locator_set_name,
18667                    vec_len (locator_set_name));
18668     }
18669   else
18670     {
18671       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18672     }
18673   vec_free (locator_set_name);
18674
18675   /* send it... */
18676   S (mp);
18677
18678   /* Wait for a reply... */
18679   W (ret);
18680   return ret;
18681 }
18682
18683 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18684
18685 static int
18686 api_one_locator_dump (vat_main_t * vam)
18687 {
18688   unformat_input_t *input = vam->input;
18689   vl_api_one_locator_dump_t *mp;
18690   vl_api_control_ping_t *mp_ping;
18691   u8 is_index_set = 0, is_name_set = 0;
18692   u8 *ls_name = 0;
18693   u32 ls_index = ~0;
18694   int ret;
18695
18696   /* Parse args required to build the message */
18697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18698     {
18699       if (unformat (input, "ls_name %_%v%_", &ls_name))
18700         {
18701           is_name_set = 1;
18702         }
18703       else if (unformat (input, "ls_index %d", &ls_index))
18704         {
18705           is_index_set = 1;
18706         }
18707       else
18708         {
18709           errmsg ("parse error '%U'", format_unformat_error, input);
18710           return -99;
18711         }
18712     }
18713
18714   if (!is_index_set && !is_name_set)
18715     {
18716       errmsg ("error: expected one of index or name!");
18717       return -99;
18718     }
18719
18720   if (is_index_set && is_name_set)
18721     {
18722       errmsg ("error: only one param expected!");
18723       return -99;
18724     }
18725
18726   if (vec_len (ls_name) > 62)
18727     {
18728       errmsg ("error: locator set name too long!");
18729       return -99;
18730     }
18731
18732   if (!vam->json_output)
18733     {
18734       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18735     }
18736
18737   M (ONE_LOCATOR_DUMP, mp);
18738   mp->is_index_set = is_index_set;
18739
18740   if (is_index_set)
18741     mp->ls_index = clib_host_to_net_u32 (ls_index);
18742   else
18743     {
18744       vec_add1 (ls_name, 0);
18745       strncpy ((char *) mp->ls_name, (char *) ls_name,
18746                sizeof (mp->ls_name) - 1);
18747     }
18748
18749   /* send it... */
18750   S (mp);
18751
18752   /* Use a control ping for synchronization */
18753   MPING (CONTROL_PING, mp_ping);
18754   S (mp_ping);
18755
18756   /* Wait for a reply... */
18757   W (ret);
18758   return ret;
18759 }
18760
18761 #define api_lisp_locator_dump api_one_locator_dump
18762
18763 static int
18764 api_one_locator_set_dump (vat_main_t * vam)
18765 {
18766   vl_api_one_locator_set_dump_t *mp;
18767   vl_api_control_ping_t *mp_ping;
18768   unformat_input_t *input = vam->input;
18769   u8 filter = 0;
18770   int ret;
18771
18772   /* Parse args required to build the message */
18773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18774     {
18775       if (unformat (input, "local"))
18776         {
18777           filter = 1;
18778         }
18779       else if (unformat (input, "remote"))
18780         {
18781           filter = 2;
18782         }
18783       else
18784         {
18785           errmsg ("parse error '%U'", format_unformat_error, input);
18786           return -99;
18787         }
18788     }
18789
18790   if (!vam->json_output)
18791     {
18792       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18793     }
18794
18795   M (ONE_LOCATOR_SET_DUMP, mp);
18796
18797   mp->filter = filter;
18798
18799   /* send it... */
18800   S (mp);
18801
18802   /* Use a control ping for synchronization */
18803   MPING (CONTROL_PING, mp_ping);
18804   S (mp_ping);
18805
18806   /* Wait for a reply... */
18807   W (ret);
18808   return ret;
18809 }
18810
18811 #define api_lisp_locator_set_dump api_one_locator_set_dump
18812
18813 static int
18814 api_one_eid_table_map_dump (vat_main_t * vam)
18815 {
18816   u8 is_l2 = 0;
18817   u8 mode_set = 0;
18818   unformat_input_t *input = vam->input;
18819   vl_api_one_eid_table_map_dump_t *mp;
18820   vl_api_control_ping_t *mp_ping;
18821   int ret;
18822
18823   /* Parse args required to build the message */
18824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18825     {
18826       if (unformat (input, "l2"))
18827         {
18828           is_l2 = 1;
18829           mode_set = 1;
18830         }
18831       else if (unformat (input, "l3"))
18832         {
18833           is_l2 = 0;
18834           mode_set = 1;
18835         }
18836       else
18837         {
18838           errmsg ("parse error '%U'", format_unformat_error, input);
18839           return -99;
18840         }
18841     }
18842
18843   if (!mode_set)
18844     {
18845       errmsg ("expected one of 'l2' or 'l3' parameter!");
18846       return -99;
18847     }
18848
18849   if (!vam->json_output)
18850     {
18851       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18852     }
18853
18854   M (ONE_EID_TABLE_MAP_DUMP, mp);
18855   mp->is_l2 = is_l2;
18856
18857   /* send it... */
18858   S (mp);
18859
18860   /* Use a control ping for synchronization */
18861   MPING (CONTROL_PING, mp_ping);
18862   S (mp_ping);
18863
18864   /* Wait for a reply... */
18865   W (ret);
18866   return ret;
18867 }
18868
18869 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18870
18871 static int
18872 api_one_eid_table_vni_dump (vat_main_t * vam)
18873 {
18874   vl_api_one_eid_table_vni_dump_t *mp;
18875   vl_api_control_ping_t *mp_ping;
18876   int ret;
18877
18878   if (!vam->json_output)
18879     {
18880       print (vam->ofp, "VNI");
18881     }
18882
18883   M (ONE_EID_TABLE_VNI_DUMP, mp);
18884
18885   /* send it... */
18886   S (mp);
18887
18888   /* Use a control ping for synchronization */
18889   MPING (CONTROL_PING, mp_ping);
18890   S (mp_ping);
18891
18892   /* Wait for a reply... */
18893   W (ret);
18894   return ret;
18895 }
18896
18897 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18898
18899 static int
18900 api_one_eid_table_dump (vat_main_t * vam)
18901 {
18902   unformat_input_t *i = vam->input;
18903   vl_api_one_eid_table_dump_t *mp;
18904   vl_api_control_ping_t *mp_ping;
18905   struct in_addr ip4;
18906   struct in6_addr ip6;
18907   u8 mac[6];
18908   u8 eid_type = ~0, eid_set = 0;
18909   u32 prefix_length = ~0, t, vni = 0;
18910   u8 filter = 0;
18911   int ret;
18912   lisp_nsh_api_t nsh;
18913
18914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18915     {
18916       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18917         {
18918           eid_set = 1;
18919           eid_type = 0;
18920           prefix_length = t;
18921         }
18922       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18923         {
18924           eid_set = 1;
18925           eid_type = 1;
18926           prefix_length = t;
18927         }
18928       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18929         {
18930           eid_set = 1;
18931           eid_type = 2;
18932         }
18933       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18934         {
18935           eid_set = 1;
18936           eid_type = 3;
18937         }
18938       else if (unformat (i, "vni %d", &t))
18939         {
18940           vni = t;
18941         }
18942       else if (unformat (i, "local"))
18943         {
18944           filter = 1;
18945         }
18946       else if (unformat (i, "remote"))
18947         {
18948           filter = 2;
18949         }
18950       else
18951         {
18952           errmsg ("parse error '%U'", format_unformat_error, i);
18953           return -99;
18954         }
18955     }
18956
18957   if (!vam->json_output)
18958     {
18959       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18960              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18961     }
18962
18963   M (ONE_EID_TABLE_DUMP, mp);
18964
18965   mp->filter = filter;
18966   if (eid_set)
18967     {
18968       mp->eid_set = 1;
18969       mp->vni = htonl (vni);
18970       mp->eid_type = eid_type;
18971       switch (eid_type)
18972         {
18973         case 0:
18974           mp->prefix_length = prefix_length;
18975           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18976           break;
18977         case 1:
18978           mp->prefix_length = prefix_length;
18979           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18980           break;
18981         case 2:
18982           clib_memcpy (mp->eid, mac, sizeof (mac));
18983           break;
18984         case 3:
18985           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18986           break;
18987         default:
18988           errmsg ("unknown EID type %d!", eid_type);
18989           return -99;
18990         }
18991     }
18992
18993   /* send it... */
18994   S (mp);
18995
18996   /* Use a control ping for synchronization */
18997   MPING (CONTROL_PING, mp_ping);
18998   S (mp_ping);
18999
19000   /* Wait for a reply... */
19001   W (ret);
19002   return ret;
19003 }
19004
19005 #define api_lisp_eid_table_dump api_one_eid_table_dump
19006
19007 static int
19008 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19009 {
19010   unformat_input_t *i = vam->input;
19011   vl_api_gpe_fwd_entries_get_t *mp;
19012   u8 vni_set = 0;
19013   u32 vni = ~0;
19014   int ret;
19015
19016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19017     {
19018       if (unformat (i, "vni %d", &vni))
19019         {
19020           vni_set = 1;
19021         }
19022       else
19023         {
19024           errmsg ("parse error '%U'", format_unformat_error, i);
19025           return -99;
19026         }
19027     }
19028
19029   if (!vni_set)
19030     {
19031       errmsg ("vni not set!");
19032       return -99;
19033     }
19034
19035   if (!vam->json_output)
19036     {
19037       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19038              "leid", "reid");
19039     }
19040
19041   M (GPE_FWD_ENTRIES_GET, mp);
19042   mp->vni = clib_host_to_net_u32 (vni);
19043
19044   /* send it... */
19045   S (mp);
19046
19047   /* Wait for a reply... */
19048   W (ret);
19049   return ret;
19050 }
19051
19052 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19053 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19054 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19055 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19056 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19057 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19058 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19059 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19060
19061 static int
19062 api_one_adjacencies_get (vat_main_t * vam)
19063 {
19064   unformat_input_t *i = vam->input;
19065   vl_api_one_adjacencies_get_t *mp;
19066   u8 vni_set = 0;
19067   u32 vni = ~0;
19068   int ret;
19069
19070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19071     {
19072       if (unformat (i, "vni %d", &vni))
19073         {
19074           vni_set = 1;
19075         }
19076       else
19077         {
19078           errmsg ("parse error '%U'", format_unformat_error, i);
19079           return -99;
19080         }
19081     }
19082
19083   if (!vni_set)
19084     {
19085       errmsg ("vni not set!");
19086       return -99;
19087     }
19088
19089   if (!vam->json_output)
19090     {
19091       print (vam->ofp, "%s %40s", "leid", "reid");
19092     }
19093
19094   M (ONE_ADJACENCIES_GET, mp);
19095   mp->vni = clib_host_to_net_u32 (vni);
19096
19097   /* send it... */
19098   S (mp);
19099
19100   /* Wait for a reply... */
19101   W (ret);
19102   return ret;
19103 }
19104
19105 #define api_lisp_adjacencies_get api_one_adjacencies_get
19106
19107 static int
19108 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19109 {
19110   unformat_input_t *i = vam->input;
19111   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19112   int ret;
19113   u8 ip_family_set = 0, is_ip4 = 1;
19114
19115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19116     {
19117       if (unformat (i, "ip4"))
19118         {
19119           ip_family_set = 1;
19120           is_ip4 = 1;
19121         }
19122       else if (unformat (i, "ip6"))
19123         {
19124           ip_family_set = 1;
19125           is_ip4 = 0;
19126         }
19127       else
19128         {
19129           errmsg ("parse error '%U'", format_unformat_error, i);
19130           return -99;
19131         }
19132     }
19133
19134   if (!ip_family_set)
19135     {
19136       errmsg ("ip family not set!");
19137       return -99;
19138     }
19139
19140   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19141   mp->is_ip4 = is_ip4;
19142
19143   /* send it... */
19144   S (mp);
19145
19146   /* Wait for a reply... */
19147   W (ret);
19148   return ret;
19149 }
19150
19151 static int
19152 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19153 {
19154   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19155   int ret;
19156
19157   if (!vam->json_output)
19158     {
19159       print (vam->ofp, "VNIs");
19160     }
19161
19162   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19163
19164   /* send it... */
19165   S (mp);
19166
19167   /* Wait for a reply... */
19168   W (ret);
19169   return ret;
19170 }
19171
19172 static int
19173 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19174 {
19175   unformat_input_t *i = vam->input;
19176   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19177   int ret = 0;
19178   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19179   struct in_addr ip4;
19180   struct in6_addr ip6;
19181   u32 table_id = 0, nh_sw_if_index = ~0;
19182
19183   clib_memset (&ip4, 0, sizeof (ip4));
19184   clib_memset (&ip6, 0, sizeof (ip6));
19185
19186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19187     {
19188       if (unformat (i, "del"))
19189         is_add = 0;
19190       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19191                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19192         {
19193           ip_set = 1;
19194           is_ip4 = 1;
19195         }
19196       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19197                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19198         {
19199           ip_set = 1;
19200           is_ip4 = 0;
19201         }
19202       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19203         {
19204           ip_set = 1;
19205           is_ip4 = 1;
19206           nh_sw_if_index = ~0;
19207         }
19208       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19209         {
19210           ip_set = 1;
19211           is_ip4 = 0;
19212           nh_sw_if_index = ~0;
19213         }
19214       else if (unformat (i, "table %d", &table_id))
19215         ;
19216       else
19217         {
19218           errmsg ("parse error '%U'", format_unformat_error, i);
19219           return -99;
19220         }
19221     }
19222
19223   if (!ip_set)
19224     {
19225       errmsg ("nh addr not set!");
19226       return -99;
19227     }
19228
19229   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19230   mp->is_add = is_add;
19231   mp->table_id = clib_host_to_net_u32 (table_id);
19232   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19233   mp->is_ip4 = is_ip4;
19234   if (is_ip4)
19235     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19236   else
19237     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19238
19239   /* send it... */
19240   S (mp);
19241
19242   /* Wait for a reply... */
19243   W (ret);
19244   return ret;
19245 }
19246
19247 static int
19248 api_one_map_server_dump (vat_main_t * vam)
19249 {
19250   vl_api_one_map_server_dump_t *mp;
19251   vl_api_control_ping_t *mp_ping;
19252   int ret;
19253
19254   if (!vam->json_output)
19255     {
19256       print (vam->ofp, "%=20s", "Map server");
19257     }
19258
19259   M (ONE_MAP_SERVER_DUMP, mp);
19260   /* send it... */
19261   S (mp);
19262
19263   /* Use a control ping for synchronization */
19264   MPING (CONTROL_PING, mp_ping);
19265   S (mp_ping);
19266
19267   /* Wait for a reply... */
19268   W (ret);
19269   return ret;
19270 }
19271
19272 #define api_lisp_map_server_dump api_one_map_server_dump
19273
19274 static int
19275 api_one_map_resolver_dump (vat_main_t * vam)
19276 {
19277   vl_api_one_map_resolver_dump_t *mp;
19278   vl_api_control_ping_t *mp_ping;
19279   int ret;
19280
19281   if (!vam->json_output)
19282     {
19283       print (vam->ofp, "%=20s", "Map resolver");
19284     }
19285
19286   M (ONE_MAP_RESOLVER_DUMP, mp);
19287   /* send it... */
19288   S (mp);
19289
19290   /* Use a control ping for synchronization */
19291   MPING (CONTROL_PING, mp_ping);
19292   S (mp_ping);
19293
19294   /* Wait for a reply... */
19295   W (ret);
19296   return ret;
19297 }
19298
19299 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19300
19301 static int
19302 api_one_stats_flush (vat_main_t * vam)
19303 {
19304   vl_api_one_stats_flush_t *mp;
19305   int ret = 0;
19306
19307   M (ONE_STATS_FLUSH, mp);
19308   S (mp);
19309   W (ret);
19310   return ret;
19311 }
19312
19313 static int
19314 api_one_stats_dump (vat_main_t * vam)
19315 {
19316   vl_api_one_stats_dump_t *mp;
19317   vl_api_control_ping_t *mp_ping;
19318   int ret;
19319
19320   M (ONE_STATS_DUMP, mp);
19321   /* send it... */
19322   S (mp);
19323
19324   /* Use a control ping for synchronization */
19325   MPING (CONTROL_PING, mp_ping);
19326   S (mp_ping);
19327
19328   /* Wait for a reply... */
19329   W (ret);
19330   return ret;
19331 }
19332
19333 static int
19334 api_show_one_status (vat_main_t * vam)
19335 {
19336   vl_api_show_one_status_t *mp;
19337   int ret;
19338
19339   if (!vam->json_output)
19340     {
19341       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19342     }
19343
19344   M (SHOW_ONE_STATUS, mp);
19345   /* send it... */
19346   S (mp);
19347   /* Wait for a reply... */
19348   W (ret);
19349   return ret;
19350 }
19351
19352 #define api_show_lisp_status api_show_one_status
19353
19354 static int
19355 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19356 {
19357   vl_api_gpe_fwd_entry_path_dump_t *mp;
19358   vl_api_control_ping_t *mp_ping;
19359   unformat_input_t *i = vam->input;
19360   u32 fwd_entry_index = ~0;
19361   int ret;
19362
19363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19364     {
19365       if (unformat (i, "index %d", &fwd_entry_index))
19366         ;
19367       else
19368         break;
19369     }
19370
19371   if (~0 == fwd_entry_index)
19372     {
19373       errmsg ("no index specified!");
19374       return -99;
19375     }
19376
19377   if (!vam->json_output)
19378     {
19379       print (vam->ofp, "first line");
19380     }
19381
19382   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19383
19384   /* send it... */
19385   S (mp);
19386   /* Use a control ping for synchronization */
19387   MPING (CONTROL_PING, mp_ping);
19388   S (mp_ping);
19389
19390   /* Wait for a reply... */
19391   W (ret);
19392   return ret;
19393 }
19394
19395 static int
19396 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19397 {
19398   vl_api_one_get_map_request_itr_rlocs_t *mp;
19399   int ret;
19400
19401   if (!vam->json_output)
19402     {
19403       print (vam->ofp, "%=20s", "itr-rlocs:");
19404     }
19405
19406   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19407   /* send it... */
19408   S (mp);
19409   /* Wait for a reply... */
19410   W (ret);
19411   return ret;
19412 }
19413
19414 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19415
19416 static int
19417 api_af_packet_create (vat_main_t * vam)
19418 {
19419   unformat_input_t *i = vam->input;
19420   vl_api_af_packet_create_t *mp;
19421   u8 *host_if_name = 0;
19422   u8 hw_addr[6];
19423   u8 random_hw_addr = 1;
19424   int ret;
19425
19426   clib_memset (hw_addr, 0, sizeof (hw_addr));
19427
19428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19429     {
19430       if (unformat (i, "name %s", &host_if_name))
19431         vec_add1 (host_if_name, 0);
19432       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19433         random_hw_addr = 0;
19434       else
19435         break;
19436     }
19437
19438   if (!vec_len (host_if_name))
19439     {
19440       errmsg ("host-interface name must be specified");
19441       return -99;
19442     }
19443
19444   if (vec_len (host_if_name) > 64)
19445     {
19446       errmsg ("host-interface name too long");
19447       return -99;
19448     }
19449
19450   M (AF_PACKET_CREATE, mp);
19451
19452   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19453   clib_memcpy (mp->hw_addr, hw_addr, 6);
19454   mp->use_random_hw_addr = random_hw_addr;
19455   vec_free (host_if_name);
19456
19457   S (mp);
19458
19459   /* *INDENT-OFF* */
19460   W2 (ret,
19461       ({
19462         if (ret == 0)
19463           fprintf (vam->ofp ? vam->ofp : stderr,
19464                    " new sw_if_index = %d\n", vam->sw_if_index);
19465       }));
19466   /* *INDENT-ON* */
19467   return ret;
19468 }
19469
19470 static int
19471 api_af_packet_delete (vat_main_t * vam)
19472 {
19473   unformat_input_t *i = vam->input;
19474   vl_api_af_packet_delete_t *mp;
19475   u8 *host_if_name = 0;
19476   int ret;
19477
19478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19479     {
19480       if (unformat (i, "name %s", &host_if_name))
19481         vec_add1 (host_if_name, 0);
19482       else
19483         break;
19484     }
19485
19486   if (!vec_len (host_if_name))
19487     {
19488       errmsg ("host-interface name must be specified");
19489       return -99;
19490     }
19491
19492   if (vec_len (host_if_name) > 64)
19493     {
19494       errmsg ("host-interface name too long");
19495       return -99;
19496     }
19497
19498   M (AF_PACKET_DELETE, mp);
19499
19500   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19501   vec_free (host_if_name);
19502
19503   S (mp);
19504   W (ret);
19505   return ret;
19506 }
19507
19508 static void vl_api_af_packet_details_t_handler
19509   (vl_api_af_packet_details_t * mp)
19510 {
19511   vat_main_t *vam = &vat_main;
19512
19513   print (vam->ofp, "%-16s %d",
19514          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19515 }
19516
19517 static void vl_api_af_packet_details_t_handler_json
19518   (vl_api_af_packet_details_t * mp)
19519 {
19520   vat_main_t *vam = &vat_main;
19521   vat_json_node_t *node = NULL;
19522
19523   if (VAT_JSON_ARRAY != vam->json_tree.type)
19524     {
19525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19526       vat_json_init_array (&vam->json_tree);
19527     }
19528   node = vat_json_array_add (&vam->json_tree);
19529
19530   vat_json_init_object (node);
19531   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19532   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19533 }
19534
19535 static int
19536 api_af_packet_dump (vat_main_t * vam)
19537 {
19538   vl_api_af_packet_dump_t *mp;
19539   vl_api_control_ping_t *mp_ping;
19540   int ret;
19541
19542   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19543   /* Get list of tap interfaces */
19544   M (AF_PACKET_DUMP, mp);
19545   S (mp);
19546
19547   /* Use a control ping for synchronization */
19548   MPING (CONTROL_PING, mp_ping);
19549   S (mp_ping);
19550
19551   W (ret);
19552   return ret;
19553 }
19554
19555 static int
19556 api_policer_add_del (vat_main_t * vam)
19557 {
19558   unformat_input_t *i = vam->input;
19559   vl_api_policer_add_del_t *mp;
19560   u8 is_add = 1;
19561   u8 *name = 0;
19562   u32 cir = 0;
19563   u32 eir = 0;
19564   u64 cb = 0;
19565   u64 eb = 0;
19566   u8 rate_type = 0;
19567   u8 round_type = 0;
19568   u8 type = 0;
19569   u8 color_aware = 0;
19570   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19571   int ret;
19572
19573   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19574   conform_action.dscp = 0;
19575   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19576   exceed_action.dscp = 0;
19577   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19578   violate_action.dscp = 0;
19579
19580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19581     {
19582       if (unformat (i, "del"))
19583         is_add = 0;
19584       else if (unformat (i, "name %s", &name))
19585         vec_add1 (name, 0);
19586       else if (unformat (i, "cir %u", &cir))
19587         ;
19588       else if (unformat (i, "eir %u", &eir))
19589         ;
19590       else if (unformat (i, "cb %u", &cb))
19591         ;
19592       else if (unformat (i, "eb %u", &eb))
19593         ;
19594       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19595                          &rate_type))
19596         ;
19597       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19598                          &round_type))
19599         ;
19600       else if (unformat (i, "type %U", unformat_policer_type, &type))
19601         ;
19602       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19603                          &conform_action))
19604         ;
19605       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19606                          &exceed_action))
19607         ;
19608       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19609                          &violate_action))
19610         ;
19611       else if (unformat (i, "color-aware"))
19612         color_aware = 1;
19613       else
19614         break;
19615     }
19616
19617   if (!vec_len (name))
19618     {
19619       errmsg ("policer name must be specified");
19620       return -99;
19621     }
19622
19623   if (vec_len (name) > 64)
19624     {
19625       errmsg ("policer name too long");
19626       return -99;
19627     }
19628
19629   M (POLICER_ADD_DEL, mp);
19630
19631   clib_memcpy (mp->name, name, vec_len (name));
19632   vec_free (name);
19633   mp->is_add = is_add;
19634   mp->cir = ntohl (cir);
19635   mp->eir = ntohl (eir);
19636   mp->cb = clib_net_to_host_u64 (cb);
19637   mp->eb = clib_net_to_host_u64 (eb);
19638   mp->rate_type = rate_type;
19639   mp->round_type = round_type;
19640   mp->type = type;
19641   mp->conform_action_type = conform_action.action_type;
19642   mp->conform_dscp = conform_action.dscp;
19643   mp->exceed_action_type = exceed_action.action_type;
19644   mp->exceed_dscp = exceed_action.dscp;
19645   mp->violate_action_type = violate_action.action_type;
19646   mp->violate_dscp = violate_action.dscp;
19647   mp->color_aware = color_aware;
19648
19649   S (mp);
19650   W (ret);
19651   return ret;
19652 }
19653
19654 static int
19655 api_policer_dump (vat_main_t * vam)
19656 {
19657   unformat_input_t *i = vam->input;
19658   vl_api_policer_dump_t *mp;
19659   vl_api_control_ping_t *mp_ping;
19660   u8 *match_name = 0;
19661   u8 match_name_valid = 0;
19662   int ret;
19663
19664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19665     {
19666       if (unformat (i, "name %s", &match_name))
19667         {
19668           vec_add1 (match_name, 0);
19669           match_name_valid = 1;
19670         }
19671       else
19672         break;
19673     }
19674
19675   M (POLICER_DUMP, mp);
19676   mp->match_name_valid = match_name_valid;
19677   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19678   vec_free (match_name);
19679   /* send it... */
19680   S (mp);
19681
19682   /* Use a control ping for synchronization */
19683   MPING (CONTROL_PING, mp_ping);
19684   S (mp_ping);
19685
19686   /* Wait for a reply... */
19687   W (ret);
19688   return ret;
19689 }
19690
19691 static int
19692 api_policer_classify_set_interface (vat_main_t * vam)
19693 {
19694   unformat_input_t *i = vam->input;
19695   vl_api_policer_classify_set_interface_t *mp;
19696   u32 sw_if_index;
19697   int sw_if_index_set;
19698   u32 ip4_table_index = ~0;
19699   u32 ip6_table_index = ~0;
19700   u32 l2_table_index = ~0;
19701   u8 is_add = 1;
19702   int ret;
19703
19704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19705     {
19706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19707         sw_if_index_set = 1;
19708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19709         sw_if_index_set = 1;
19710       else if (unformat (i, "del"))
19711         is_add = 0;
19712       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19713         ;
19714       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19715         ;
19716       else if (unformat (i, "l2-table %d", &l2_table_index))
19717         ;
19718       else
19719         {
19720           clib_warning ("parse error '%U'", format_unformat_error, i);
19721           return -99;
19722         }
19723     }
19724
19725   if (sw_if_index_set == 0)
19726     {
19727       errmsg ("missing interface name or sw_if_index");
19728       return -99;
19729     }
19730
19731   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19732
19733   mp->sw_if_index = ntohl (sw_if_index);
19734   mp->ip4_table_index = ntohl (ip4_table_index);
19735   mp->ip6_table_index = ntohl (ip6_table_index);
19736   mp->l2_table_index = ntohl (l2_table_index);
19737   mp->is_add = is_add;
19738
19739   S (mp);
19740   W (ret);
19741   return ret;
19742 }
19743
19744 static int
19745 api_policer_classify_dump (vat_main_t * vam)
19746 {
19747   unformat_input_t *i = vam->input;
19748   vl_api_policer_classify_dump_t *mp;
19749   vl_api_control_ping_t *mp_ping;
19750   u8 type = POLICER_CLASSIFY_N_TABLES;
19751   int ret;
19752
19753   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19754     ;
19755   else
19756     {
19757       errmsg ("classify table type must be specified");
19758       return -99;
19759     }
19760
19761   if (!vam->json_output)
19762     {
19763       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19764     }
19765
19766   M (POLICER_CLASSIFY_DUMP, mp);
19767   mp->type = type;
19768   /* send it... */
19769   S (mp);
19770
19771   /* Use a control ping for synchronization */
19772   MPING (CONTROL_PING, mp_ping);
19773   S (mp_ping);
19774
19775   /* Wait for a reply... */
19776   W (ret);
19777   return ret;
19778 }
19779
19780 static int
19781 api_netmap_create (vat_main_t * vam)
19782 {
19783   unformat_input_t *i = vam->input;
19784   vl_api_netmap_create_t *mp;
19785   u8 *if_name = 0;
19786   u8 hw_addr[6];
19787   u8 random_hw_addr = 1;
19788   u8 is_pipe = 0;
19789   u8 is_master = 0;
19790   int ret;
19791
19792   clib_memset (hw_addr, 0, sizeof (hw_addr));
19793
19794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19795     {
19796       if (unformat (i, "name %s", &if_name))
19797         vec_add1 (if_name, 0);
19798       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19799         random_hw_addr = 0;
19800       else if (unformat (i, "pipe"))
19801         is_pipe = 1;
19802       else if (unformat (i, "master"))
19803         is_master = 1;
19804       else if (unformat (i, "slave"))
19805         is_master = 0;
19806       else
19807         break;
19808     }
19809
19810   if (!vec_len (if_name))
19811     {
19812       errmsg ("interface name must be specified");
19813       return -99;
19814     }
19815
19816   if (vec_len (if_name) > 64)
19817     {
19818       errmsg ("interface name too long");
19819       return -99;
19820     }
19821
19822   M (NETMAP_CREATE, mp);
19823
19824   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19825   clib_memcpy (mp->hw_addr, hw_addr, 6);
19826   mp->use_random_hw_addr = random_hw_addr;
19827   mp->is_pipe = is_pipe;
19828   mp->is_master = is_master;
19829   vec_free (if_name);
19830
19831   S (mp);
19832   W (ret);
19833   return ret;
19834 }
19835
19836 static int
19837 api_netmap_delete (vat_main_t * vam)
19838 {
19839   unformat_input_t *i = vam->input;
19840   vl_api_netmap_delete_t *mp;
19841   u8 *if_name = 0;
19842   int ret;
19843
19844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19845     {
19846       if (unformat (i, "name %s", &if_name))
19847         vec_add1 (if_name, 0);
19848       else
19849         break;
19850     }
19851
19852   if (!vec_len (if_name))
19853     {
19854       errmsg ("interface name must be specified");
19855       return -99;
19856     }
19857
19858   if (vec_len (if_name) > 64)
19859     {
19860       errmsg ("interface name too long");
19861       return -99;
19862     }
19863
19864   M (NETMAP_DELETE, mp);
19865
19866   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19867   vec_free (if_name);
19868
19869   S (mp);
19870   W (ret);
19871   return ret;
19872 }
19873
19874 static void
19875 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19876 {
19877   if (fp->afi == IP46_TYPE_IP6)
19878     print (vam->ofp,
19879            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19880            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19881            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19882            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19883            format_ip6_address, fp->next_hop);
19884   else if (fp->afi == IP46_TYPE_IP4)
19885     print (vam->ofp,
19886            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19887            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19888            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19889            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19890            format_ip4_address, fp->next_hop);
19891 }
19892
19893 static void
19894 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19895                                  vl_api_fib_path_t * fp)
19896 {
19897   struct in_addr ip4;
19898   struct in6_addr ip6;
19899
19900   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19901   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19902   vat_json_object_add_uint (node, "is_local", fp->is_local);
19903   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19904   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19905   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19906   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19907   if (fp->afi == IP46_TYPE_IP4)
19908     {
19909       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19910       vat_json_object_add_ip4 (node, "next_hop", ip4);
19911     }
19912   else if (fp->afi == IP46_TYPE_IP6)
19913     {
19914       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19915       vat_json_object_add_ip6 (node, "next_hop", ip6);
19916     }
19917 }
19918
19919 static void
19920 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19921 {
19922   vat_main_t *vam = &vat_main;
19923   int count = ntohl (mp->mt_count);
19924   vl_api_fib_path_t *fp;
19925   i32 i;
19926
19927   print (vam->ofp, "[%d]: sw_if_index %d via:",
19928          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19929   fp = mp->mt_paths;
19930   for (i = 0; i < count; i++)
19931     {
19932       vl_api_mpls_fib_path_print (vam, fp);
19933       fp++;
19934     }
19935
19936   print (vam->ofp, "");
19937 }
19938
19939 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19940 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19941
19942 static void
19943 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19944 {
19945   vat_main_t *vam = &vat_main;
19946   vat_json_node_t *node = NULL;
19947   int count = ntohl (mp->mt_count);
19948   vl_api_fib_path_t *fp;
19949   i32 i;
19950
19951   if (VAT_JSON_ARRAY != vam->json_tree.type)
19952     {
19953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19954       vat_json_init_array (&vam->json_tree);
19955     }
19956   node = vat_json_array_add (&vam->json_tree);
19957
19958   vat_json_init_object (node);
19959   vat_json_object_add_uint (node, "tunnel_index",
19960                             ntohl (mp->mt_tunnel_index));
19961   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19962
19963   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19964
19965   fp = mp->mt_paths;
19966   for (i = 0; i < count; i++)
19967     {
19968       vl_api_mpls_fib_path_json_print (node, fp);
19969       fp++;
19970     }
19971 }
19972
19973 static int
19974 api_mpls_tunnel_dump (vat_main_t * vam)
19975 {
19976   vl_api_mpls_tunnel_dump_t *mp;
19977   vl_api_control_ping_t *mp_ping;
19978   u32 sw_if_index = ~0;
19979   int ret;
19980
19981   /* Parse args required to build the message */
19982   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19983     {
19984       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19985         ;
19986     }
19987
19988   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19989
19990   M (MPLS_TUNNEL_DUMP, mp);
19991   mp->sw_if_index = htonl (sw_if_index);
19992   S (mp);
19993
19994   /* Use a control ping for synchronization */
19995   MPING (CONTROL_PING, mp_ping);
19996   S (mp_ping);
19997
19998   W (ret);
19999   return ret;
20000 }
20001
20002 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20003 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20004
20005
20006 static void
20007 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20008 {
20009   vat_main_t *vam = &vat_main;
20010   int count = ntohl (mp->count);
20011   vl_api_fib_path_t *fp;
20012   int i;
20013
20014   print (vam->ofp,
20015          "table-id %d, label %u, ess_bit %u",
20016          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20017   fp = mp->path;
20018   for (i = 0; i < count; i++)
20019     {
20020       vl_api_mpls_fib_path_print (vam, fp);
20021       fp++;
20022     }
20023 }
20024
20025 static void vl_api_mpls_fib_details_t_handler_json
20026   (vl_api_mpls_fib_details_t * mp)
20027 {
20028   vat_main_t *vam = &vat_main;
20029   int count = ntohl (mp->count);
20030   vat_json_node_t *node = NULL;
20031   vl_api_fib_path_t *fp;
20032   int i;
20033
20034   if (VAT_JSON_ARRAY != vam->json_tree.type)
20035     {
20036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20037       vat_json_init_array (&vam->json_tree);
20038     }
20039   node = vat_json_array_add (&vam->json_tree);
20040
20041   vat_json_init_object (node);
20042   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20043   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20044   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20045   vat_json_object_add_uint (node, "path_count", count);
20046   fp = mp->path;
20047   for (i = 0; i < count; i++)
20048     {
20049       vl_api_mpls_fib_path_json_print (node, fp);
20050       fp++;
20051     }
20052 }
20053
20054 static int
20055 api_mpls_fib_dump (vat_main_t * vam)
20056 {
20057   vl_api_mpls_fib_dump_t *mp;
20058   vl_api_control_ping_t *mp_ping;
20059   int ret;
20060
20061   M (MPLS_FIB_DUMP, mp);
20062   S (mp);
20063
20064   /* Use a control ping for synchronization */
20065   MPING (CONTROL_PING, mp_ping);
20066   S (mp_ping);
20067
20068   W (ret);
20069   return ret;
20070 }
20071
20072 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20073 #define vl_api_ip_fib_details_t_print vl_noop_handler
20074
20075 static void
20076 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20077 {
20078   vat_main_t *vam = &vat_main;
20079   int count = ntohl (mp->count);
20080   vl_api_fib_path_t *fp;
20081   int i;
20082
20083   print (vam->ofp,
20084          "table-id %d, prefix %U/%d stats-index %d",
20085          ntohl (mp->table_id), format_ip4_address, mp->address,
20086          mp->address_length, ntohl (mp->stats_index));
20087   fp = mp->path;
20088   for (i = 0; i < count; i++)
20089     {
20090       if (fp->afi == IP46_TYPE_IP6)
20091         print (vam->ofp,
20092                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20093                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20094                "next_hop_table %d",
20095                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20096                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20097                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20098       else if (fp->afi == IP46_TYPE_IP4)
20099         print (vam->ofp,
20100                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20101                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20102                "next_hop_table %d",
20103                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20104                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20105                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20106       fp++;
20107     }
20108 }
20109
20110 static void vl_api_ip_fib_details_t_handler_json
20111   (vl_api_ip_fib_details_t * mp)
20112 {
20113   vat_main_t *vam = &vat_main;
20114   int count = ntohl (mp->count);
20115   vat_json_node_t *node = NULL;
20116   struct in_addr ip4;
20117   struct in6_addr ip6;
20118   vl_api_fib_path_t *fp;
20119   int i;
20120
20121   if (VAT_JSON_ARRAY != vam->json_tree.type)
20122     {
20123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20124       vat_json_init_array (&vam->json_tree);
20125     }
20126   node = vat_json_array_add (&vam->json_tree);
20127
20128   vat_json_init_object (node);
20129   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20130   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20131   vat_json_object_add_ip4 (node, "prefix", ip4);
20132   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20133   vat_json_object_add_uint (node, "path_count", count);
20134   fp = mp->path;
20135   for (i = 0; i < count; i++)
20136     {
20137       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20138       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20139       vat_json_object_add_uint (node, "is_local", fp->is_local);
20140       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20141       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20142       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20143       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20144       if (fp->afi == IP46_TYPE_IP4)
20145         {
20146           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20147           vat_json_object_add_ip4 (node, "next_hop", ip4);
20148         }
20149       else if (fp->afi == IP46_TYPE_IP6)
20150         {
20151           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20152           vat_json_object_add_ip6 (node, "next_hop", ip6);
20153         }
20154     }
20155 }
20156
20157 static int
20158 api_ip_fib_dump (vat_main_t * vam)
20159 {
20160   vl_api_ip_fib_dump_t *mp;
20161   vl_api_control_ping_t *mp_ping;
20162   int ret;
20163
20164   M (IP_FIB_DUMP, mp);
20165   S (mp);
20166
20167   /* Use a control ping for synchronization */
20168   MPING (CONTROL_PING, mp_ping);
20169   S (mp_ping);
20170
20171   W (ret);
20172   return ret;
20173 }
20174
20175 static int
20176 api_ip_mfib_dump (vat_main_t * vam)
20177 {
20178   vl_api_ip_mfib_dump_t *mp;
20179   vl_api_control_ping_t *mp_ping;
20180   int ret;
20181
20182   M (IP_MFIB_DUMP, mp);
20183   S (mp);
20184
20185   /* Use a control ping for synchronization */
20186   MPING (CONTROL_PING, mp_ping);
20187   S (mp_ping);
20188
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static void vl_api_ip_neighbor_details_t_handler
20194   (vl_api_ip_neighbor_details_t * mp)
20195 {
20196   vat_main_t *vam = &vat_main;
20197
20198   print (vam->ofp, "%c %U %U",
20199          (mp->is_static) ? 'S' : 'D',
20200          format_ethernet_address, &mp->mac_address,
20201          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20202          &mp->ip_address);
20203 }
20204
20205 static void vl_api_ip_neighbor_details_t_handler_json
20206   (vl_api_ip_neighbor_details_t * mp)
20207 {
20208
20209   vat_main_t *vam = &vat_main;
20210   vat_json_node_t *node;
20211   struct in_addr ip4;
20212   struct in6_addr ip6;
20213
20214   if (VAT_JSON_ARRAY != vam->json_tree.type)
20215     {
20216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20217       vat_json_init_array (&vam->json_tree);
20218     }
20219   node = vat_json_array_add (&vam->json_tree);
20220
20221   vat_json_init_object (node);
20222   vat_json_object_add_string_copy (node, "flag",
20223                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20224                                    "dynamic");
20225
20226   vat_json_object_add_string_copy (node, "link_layer",
20227                                    format (0, "%U", format_ethernet_address,
20228                                            &mp->mac_address));
20229
20230   if (mp->is_ipv6)
20231     {
20232       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20233       vat_json_object_add_ip6 (node, "ip_address", ip6);
20234     }
20235   else
20236     {
20237       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20238       vat_json_object_add_ip4 (node, "ip_address", ip4);
20239     }
20240 }
20241
20242 static int
20243 api_ip_neighbor_dump (vat_main_t * vam)
20244 {
20245   unformat_input_t *i = vam->input;
20246   vl_api_ip_neighbor_dump_t *mp;
20247   vl_api_control_ping_t *mp_ping;
20248   u8 is_ipv6 = 0;
20249   u32 sw_if_index = ~0;
20250   int ret;
20251
20252   /* Parse args required to build the message */
20253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20254     {
20255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20256         ;
20257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20258         ;
20259       else if (unformat (i, "ip6"))
20260         is_ipv6 = 1;
20261       else
20262         break;
20263     }
20264
20265   if (sw_if_index == ~0)
20266     {
20267       errmsg ("missing interface name or sw_if_index");
20268       return -99;
20269     }
20270
20271   M (IP_NEIGHBOR_DUMP, mp);
20272   mp->is_ipv6 = (u8) is_ipv6;
20273   mp->sw_if_index = ntohl (sw_if_index);
20274   S (mp);
20275
20276   /* Use a control ping for synchronization */
20277   MPING (CONTROL_PING, mp_ping);
20278   S (mp_ping);
20279
20280   W (ret);
20281   return ret;
20282 }
20283
20284 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20285 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20286
20287 static void
20288 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20289 {
20290   vat_main_t *vam = &vat_main;
20291   int count = ntohl (mp->count);
20292   vl_api_fib_path_t *fp;
20293   int i;
20294
20295   print (vam->ofp,
20296          "table-id %d, prefix %U/%d stats-index %d",
20297          ntohl (mp->table_id), format_ip6_address, mp->address,
20298          mp->address_length, ntohl (mp->stats_index));
20299   fp = mp->path;
20300   for (i = 0; i < count; i++)
20301     {
20302       if (fp->afi == IP46_TYPE_IP6)
20303         print (vam->ofp,
20304                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20305                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20306                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20307                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20308                format_ip6_address, fp->next_hop);
20309       else if (fp->afi == IP46_TYPE_IP4)
20310         print (vam->ofp,
20311                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20312                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20313                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20314                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20315                format_ip4_address, fp->next_hop);
20316       fp++;
20317     }
20318 }
20319
20320 static void vl_api_ip6_fib_details_t_handler_json
20321   (vl_api_ip6_fib_details_t * mp)
20322 {
20323   vat_main_t *vam = &vat_main;
20324   int count = ntohl (mp->count);
20325   vat_json_node_t *node = NULL;
20326   struct in_addr ip4;
20327   struct in6_addr ip6;
20328   vl_api_fib_path_t *fp;
20329   int i;
20330
20331   if (VAT_JSON_ARRAY != vam->json_tree.type)
20332     {
20333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20334       vat_json_init_array (&vam->json_tree);
20335     }
20336   node = vat_json_array_add (&vam->json_tree);
20337
20338   vat_json_init_object (node);
20339   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20340   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20341   vat_json_object_add_ip6 (node, "prefix", ip6);
20342   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20343   vat_json_object_add_uint (node, "path_count", count);
20344   fp = mp->path;
20345   for (i = 0; i < count; i++)
20346     {
20347       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20348       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20349       vat_json_object_add_uint (node, "is_local", fp->is_local);
20350       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20351       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20352       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20353       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20354       if (fp->afi == IP46_TYPE_IP4)
20355         {
20356           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20357           vat_json_object_add_ip4 (node, "next_hop", ip4);
20358         }
20359       else if (fp->afi == IP46_TYPE_IP6)
20360         {
20361           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20362           vat_json_object_add_ip6 (node, "next_hop", ip6);
20363         }
20364     }
20365 }
20366
20367 static int
20368 api_ip6_fib_dump (vat_main_t * vam)
20369 {
20370   vl_api_ip6_fib_dump_t *mp;
20371   vl_api_control_ping_t *mp_ping;
20372   int ret;
20373
20374   M (IP6_FIB_DUMP, mp);
20375   S (mp);
20376
20377   /* Use a control ping for synchronization */
20378   MPING (CONTROL_PING, mp_ping);
20379   S (mp_ping);
20380
20381   W (ret);
20382   return ret;
20383 }
20384
20385 static int
20386 api_ip6_mfib_dump (vat_main_t * vam)
20387 {
20388   vl_api_ip6_mfib_dump_t *mp;
20389   vl_api_control_ping_t *mp_ping;
20390   int ret;
20391
20392   M (IP6_MFIB_DUMP, mp);
20393   S (mp);
20394
20395   /* Use a control ping for synchronization */
20396   MPING (CONTROL_PING, mp_ping);
20397   S (mp_ping);
20398
20399   W (ret);
20400   return ret;
20401 }
20402
20403 int
20404 api_classify_table_ids (vat_main_t * vam)
20405 {
20406   vl_api_classify_table_ids_t *mp;
20407   int ret;
20408
20409   /* Construct the API message */
20410   M (CLASSIFY_TABLE_IDS, mp);
20411   mp->context = 0;
20412
20413   S (mp);
20414   W (ret);
20415   return ret;
20416 }
20417
20418 int
20419 api_classify_table_by_interface (vat_main_t * vam)
20420 {
20421   unformat_input_t *input = vam->input;
20422   vl_api_classify_table_by_interface_t *mp;
20423
20424   u32 sw_if_index = ~0;
20425   int ret;
20426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20427     {
20428       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20429         ;
20430       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20431         ;
20432       else
20433         break;
20434     }
20435   if (sw_if_index == ~0)
20436     {
20437       errmsg ("missing interface name or sw_if_index");
20438       return -99;
20439     }
20440
20441   /* Construct the API message */
20442   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20443   mp->context = 0;
20444   mp->sw_if_index = ntohl (sw_if_index);
20445
20446   S (mp);
20447   W (ret);
20448   return ret;
20449 }
20450
20451 int
20452 api_classify_table_info (vat_main_t * vam)
20453 {
20454   unformat_input_t *input = vam->input;
20455   vl_api_classify_table_info_t *mp;
20456
20457   u32 table_id = ~0;
20458   int ret;
20459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20460     {
20461       if (unformat (input, "table_id %d", &table_id))
20462         ;
20463       else
20464         break;
20465     }
20466   if (table_id == ~0)
20467     {
20468       errmsg ("missing table id");
20469       return -99;
20470     }
20471
20472   /* Construct the API message */
20473   M (CLASSIFY_TABLE_INFO, mp);
20474   mp->context = 0;
20475   mp->table_id = ntohl (table_id);
20476
20477   S (mp);
20478   W (ret);
20479   return ret;
20480 }
20481
20482 int
20483 api_classify_session_dump (vat_main_t * vam)
20484 {
20485   unformat_input_t *input = vam->input;
20486   vl_api_classify_session_dump_t *mp;
20487   vl_api_control_ping_t *mp_ping;
20488
20489   u32 table_id = ~0;
20490   int ret;
20491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20492     {
20493       if (unformat (input, "table_id %d", &table_id))
20494         ;
20495       else
20496         break;
20497     }
20498   if (table_id == ~0)
20499     {
20500       errmsg ("missing table id");
20501       return -99;
20502     }
20503
20504   /* Construct the API message */
20505   M (CLASSIFY_SESSION_DUMP, mp);
20506   mp->context = 0;
20507   mp->table_id = ntohl (table_id);
20508   S (mp);
20509
20510   /* Use a control ping for synchronization */
20511   MPING (CONTROL_PING, mp_ping);
20512   S (mp_ping);
20513
20514   W (ret);
20515   return ret;
20516 }
20517
20518 static void
20519 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20520 {
20521   vat_main_t *vam = &vat_main;
20522
20523   print (vam->ofp, "collector_address %U, collector_port %d, "
20524          "src_address %U, vrf_id %d, path_mtu %u, "
20525          "template_interval %u, udp_checksum %d",
20526          format_ip4_address, mp->collector_address,
20527          ntohs (mp->collector_port),
20528          format_ip4_address, mp->src_address,
20529          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20530          ntohl (mp->template_interval), mp->udp_checksum);
20531
20532   vam->retval = 0;
20533   vam->result_ready = 1;
20534 }
20535
20536 static void
20537   vl_api_ipfix_exporter_details_t_handler_json
20538   (vl_api_ipfix_exporter_details_t * mp)
20539 {
20540   vat_main_t *vam = &vat_main;
20541   vat_json_node_t node;
20542   struct in_addr collector_address;
20543   struct in_addr src_address;
20544
20545   vat_json_init_object (&node);
20546   clib_memcpy (&collector_address, &mp->collector_address,
20547                sizeof (collector_address));
20548   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20549   vat_json_object_add_uint (&node, "collector_port",
20550                             ntohs (mp->collector_port));
20551   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20552   vat_json_object_add_ip4 (&node, "src_address", src_address);
20553   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20554   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20555   vat_json_object_add_uint (&node, "template_interval",
20556                             ntohl (mp->template_interval));
20557   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20558
20559   vat_json_print (vam->ofp, &node);
20560   vat_json_free (&node);
20561   vam->retval = 0;
20562   vam->result_ready = 1;
20563 }
20564
20565 int
20566 api_ipfix_exporter_dump (vat_main_t * vam)
20567 {
20568   vl_api_ipfix_exporter_dump_t *mp;
20569   int ret;
20570
20571   /* Construct the API message */
20572   M (IPFIX_EXPORTER_DUMP, mp);
20573   mp->context = 0;
20574
20575   S (mp);
20576   W (ret);
20577   return ret;
20578 }
20579
20580 static int
20581 api_ipfix_classify_stream_dump (vat_main_t * vam)
20582 {
20583   vl_api_ipfix_classify_stream_dump_t *mp;
20584   int ret;
20585
20586   /* Construct the API message */
20587   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20588   mp->context = 0;
20589
20590   S (mp);
20591   W (ret);
20592   return ret;
20593   /* NOTREACHED */
20594   return 0;
20595 }
20596
20597 static void
20598   vl_api_ipfix_classify_stream_details_t_handler
20599   (vl_api_ipfix_classify_stream_details_t * mp)
20600 {
20601   vat_main_t *vam = &vat_main;
20602   print (vam->ofp, "domain_id %d, src_port %d",
20603          ntohl (mp->domain_id), ntohs (mp->src_port));
20604   vam->retval = 0;
20605   vam->result_ready = 1;
20606 }
20607
20608 static void
20609   vl_api_ipfix_classify_stream_details_t_handler_json
20610   (vl_api_ipfix_classify_stream_details_t * mp)
20611 {
20612   vat_main_t *vam = &vat_main;
20613   vat_json_node_t node;
20614
20615   vat_json_init_object (&node);
20616   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20617   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20618
20619   vat_json_print (vam->ofp, &node);
20620   vat_json_free (&node);
20621   vam->retval = 0;
20622   vam->result_ready = 1;
20623 }
20624
20625 static int
20626 api_ipfix_classify_table_dump (vat_main_t * vam)
20627 {
20628   vl_api_ipfix_classify_table_dump_t *mp;
20629   vl_api_control_ping_t *mp_ping;
20630   int ret;
20631
20632   if (!vam->json_output)
20633     {
20634       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20635              "transport_protocol");
20636     }
20637
20638   /* Construct the API message */
20639   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20640
20641   /* send it... */
20642   S (mp);
20643
20644   /* Use a control ping for synchronization */
20645   MPING (CONTROL_PING, mp_ping);
20646   S (mp_ping);
20647
20648   W (ret);
20649   return ret;
20650 }
20651
20652 static void
20653   vl_api_ipfix_classify_table_details_t_handler
20654   (vl_api_ipfix_classify_table_details_t * mp)
20655 {
20656   vat_main_t *vam = &vat_main;
20657   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20658          mp->transport_protocol);
20659 }
20660
20661 static void
20662   vl_api_ipfix_classify_table_details_t_handler_json
20663   (vl_api_ipfix_classify_table_details_t * mp)
20664 {
20665   vat_json_node_t *node = NULL;
20666   vat_main_t *vam = &vat_main;
20667
20668   if (VAT_JSON_ARRAY != vam->json_tree.type)
20669     {
20670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20671       vat_json_init_array (&vam->json_tree);
20672     }
20673
20674   node = vat_json_array_add (&vam->json_tree);
20675   vat_json_init_object (node);
20676
20677   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20678   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20679   vat_json_object_add_uint (node, "transport_protocol",
20680                             mp->transport_protocol);
20681 }
20682
20683 static int
20684 api_sw_interface_span_enable_disable (vat_main_t * vam)
20685 {
20686   unformat_input_t *i = vam->input;
20687   vl_api_sw_interface_span_enable_disable_t *mp;
20688   u32 src_sw_if_index = ~0;
20689   u32 dst_sw_if_index = ~0;
20690   u8 state = 3;
20691   int ret;
20692   u8 is_l2 = 0;
20693
20694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20695     {
20696       if (unformat
20697           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20698         ;
20699       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20700         ;
20701       else
20702         if (unformat
20703             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20704         ;
20705       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20706         ;
20707       else if (unformat (i, "disable"))
20708         state = 0;
20709       else if (unformat (i, "rx"))
20710         state = 1;
20711       else if (unformat (i, "tx"))
20712         state = 2;
20713       else if (unformat (i, "both"))
20714         state = 3;
20715       else if (unformat (i, "l2"))
20716         is_l2 = 1;
20717       else
20718         break;
20719     }
20720
20721   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20722
20723   mp->sw_if_index_from = htonl (src_sw_if_index);
20724   mp->sw_if_index_to = htonl (dst_sw_if_index);
20725   mp->state = state;
20726   mp->is_l2 = is_l2;
20727
20728   S (mp);
20729   W (ret);
20730   return ret;
20731 }
20732
20733 static void
20734 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20735                                             * mp)
20736 {
20737   vat_main_t *vam = &vat_main;
20738   u8 *sw_if_from_name = 0;
20739   u8 *sw_if_to_name = 0;
20740   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20741   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20742   char *states[] = { "none", "rx", "tx", "both" };
20743   hash_pair_t *p;
20744
20745   /* *INDENT-OFF* */
20746   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20747   ({
20748     if ((u32) p->value[0] == sw_if_index_from)
20749       {
20750         sw_if_from_name = (u8 *)(p->key);
20751         if (sw_if_to_name)
20752           break;
20753       }
20754     if ((u32) p->value[0] == sw_if_index_to)
20755       {
20756         sw_if_to_name = (u8 *)(p->key);
20757         if (sw_if_from_name)
20758           break;
20759       }
20760   }));
20761   /* *INDENT-ON* */
20762   print (vam->ofp, "%20s => %20s (%s) %s",
20763          sw_if_from_name, sw_if_to_name, states[mp->state],
20764          mp->is_l2 ? "l2" : "device");
20765 }
20766
20767 static void
20768   vl_api_sw_interface_span_details_t_handler_json
20769   (vl_api_sw_interface_span_details_t * mp)
20770 {
20771   vat_main_t *vam = &vat_main;
20772   vat_json_node_t *node = NULL;
20773   u8 *sw_if_from_name = 0;
20774   u8 *sw_if_to_name = 0;
20775   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20776   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20777   hash_pair_t *p;
20778
20779   /* *INDENT-OFF* */
20780   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20781   ({
20782     if ((u32) p->value[0] == sw_if_index_from)
20783       {
20784         sw_if_from_name = (u8 *)(p->key);
20785         if (sw_if_to_name)
20786           break;
20787       }
20788     if ((u32) p->value[0] == sw_if_index_to)
20789       {
20790         sw_if_to_name = (u8 *)(p->key);
20791         if (sw_if_from_name)
20792           break;
20793       }
20794   }));
20795   /* *INDENT-ON* */
20796
20797   if (VAT_JSON_ARRAY != vam->json_tree.type)
20798     {
20799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20800       vat_json_init_array (&vam->json_tree);
20801     }
20802   node = vat_json_array_add (&vam->json_tree);
20803
20804   vat_json_init_object (node);
20805   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20806   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20807   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20808   if (0 != sw_if_to_name)
20809     {
20810       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20811     }
20812   vat_json_object_add_uint (node, "state", mp->state);
20813   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20814 }
20815
20816 static int
20817 api_sw_interface_span_dump (vat_main_t * vam)
20818 {
20819   unformat_input_t *input = vam->input;
20820   vl_api_sw_interface_span_dump_t *mp;
20821   vl_api_control_ping_t *mp_ping;
20822   u8 is_l2 = 0;
20823   int ret;
20824
20825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20826     {
20827       if (unformat (input, "l2"))
20828         is_l2 = 1;
20829       else
20830         break;
20831     }
20832
20833   M (SW_INTERFACE_SPAN_DUMP, mp);
20834   mp->is_l2 = is_l2;
20835   S (mp);
20836
20837   /* Use a control ping for synchronization */
20838   MPING (CONTROL_PING, mp_ping);
20839   S (mp_ping);
20840
20841   W (ret);
20842   return ret;
20843 }
20844
20845 int
20846 api_pg_create_interface (vat_main_t * vam)
20847 {
20848   unformat_input_t *input = vam->input;
20849   vl_api_pg_create_interface_t *mp;
20850
20851   u32 if_id = ~0;
20852   int ret;
20853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20854     {
20855       if (unformat (input, "if_id %d", &if_id))
20856         ;
20857       else
20858         break;
20859     }
20860   if (if_id == ~0)
20861     {
20862       errmsg ("missing pg interface index");
20863       return -99;
20864     }
20865
20866   /* Construct the API message */
20867   M (PG_CREATE_INTERFACE, mp);
20868   mp->context = 0;
20869   mp->interface_id = ntohl (if_id);
20870
20871   S (mp);
20872   W (ret);
20873   return ret;
20874 }
20875
20876 int
20877 api_pg_capture (vat_main_t * vam)
20878 {
20879   unformat_input_t *input = vam->input;
20880   vl_api_pg_capture_t *mp;
20881
20882   u32 if_id = ~0;
20883   u8 enable = 1;
20884   u32 count = 1;
20885   u8 pcap_file_set = 0;
20886   u8 *pcap_file = 0;
20887   int ret;
20888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20889     {
20890       if (unformat (input, "if_id %d", &if_id))
20891         ;
20892       else if (unformat (input, "pcap %s", &pcap_file))
20893         pcap_file_set = 1;
20894       else if (unformat (input, "count %d", &count))
20895         ;
20896       else if (unformat (input, "disable"))
20897         enable = 0;
20898       else
20899         break;
20900     }
20901   if (if_id == ~0)
20902     {
20903       errmsg ("missing pg interface index");
20904       return -99;
20905     }
20906   if (pcap_file_set > 0)
20907     {
20908       if (vec_len (pcap_file) > 255)
20909         {
20910           errmsg ("pcap file name is too long");
20911           return -99;
20912         }
20913     }
20914
20915   u32 name_len = vec_len (pcap_file);
20916   /* Construct the API message */
20917   M (PG_CAPTURE, mp);
20918   mp->context = 0;
20919   mp->interface_id = ntohl (if_id);
20920   mp->is_enabled = enable;
20921   mp->count = ntohl (count);
20922   mp->pcap_name_length = ntohl (name_len);
20923   if (pcap_file_set != 0)
20924     {
20925       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20926     }
20927   vec_free (pcap_file);
20928
20929   S (mp);
20930   W (ret);
20931   return ret;
20932 }
20933
20934 int
20935 api_pg_enable_disable (vat_main_t * vam)
20936 {
20937   unformat_input_t *input = vam->input;
20938   vl_api_pg_enable_disable_t *mp;
20939
20940   u8 enable = 1;
20941   u8 stream_name_set = 0;
20942   u8 *stream_name = 0;
20943   int ret;
20944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20945     {
20946       if (unformat (input, "stream %s", &stream_name))
20947         stream_name_set = 1;
20948       else if (unformat (input, "disable"))
20949         enable = 0;
20950       else
20951         break;
20952     }
20953
20954   if (stream_name_set > 0)
20955     {
20956       if (vec_len (stream_name) > 255)
20957         {
20958           errmsg ("stream name too long");
20959           return -99;
20960         }
20961     }
20962
20963   u32 name_len = vec_len (stream_name);
20964   /* Construct the API message */
20965   M (PG_ENABLE_DISABLE, mp);
20966   mp->context = 0;
20967   mp->is_enabled = enable;
20968   if (stream_name_set != 0)
20969     {
20970       mp->stream_name_length = ntohl (name_len);
20971       clib_memcpy (mp->stream_name, stream_name, name_len);
20972     }
20973   vec_free (stream_name);
20974
20975   S (mp);
20976   W (ret);
20977   return ret;
20978 }
20979
20980 int
20981 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20982 {
20983   unformat_input_t *input = vam->input;
20984   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20985
20986   u16 *low_ports = 0;
20987   u16 *high_ports = 0;
20988   u16 this_low;
20989   u16 this_hi;
20990   ip4_address_t ip4_addr;
20991   ip6_address_t ip6_addr;
20992   u32 length;
20993   u32 tmp, tmp2;
20994   u8 prefix_set = 0;
20995   u32 vrf_id = ~0;
20996   u8 is_add = 1;
20997   u8 is_ipv6 = 0;
20998   int ret;
20999
21000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21001     {
21002       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21003         {
21004           prefix_set = 1;
21005         }
21006       else
21007         if (unformat
21008             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21009         {
21010           prefix_set = 1;
21011           is_ipv6 = 1;
21012         }
21013       else if (unformat (input, "vrf %d", &vrf_id))
21014         ;
21015       else if (unformat (input, "del"))
21016         is_add = 0;
21017       else if (unformat (input, "port %d", &tmp))
21018         {
21019           if (tmp == 0 || tmp > 65535)
21020             {
21021               errmsg ("port %d out of range", tmp);
21022               return -99;
21023             }
21024           this_low = tmp;
21025           this_hi = this_low + 1;
21026           vec_add1 (low_ports, this_low);
21027           vec_add1 (high_ports, this_hi);
21028         }
21029       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21030         {
21031           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21032             {
21033               errmsg ("incorrect range parameters");
21034               return -99;
21035             }
21036           this_low = tmp;
21037           /* Note: in debug CLI +1 is added to high before
21038              passing to real fn that does "the work"
21039              (ip_source_and_port_range_check_add_del).
21040              This fn is a wrapper around the binary API fn a
21041              control plane will call, which expects this increment
21042              to have occurred. Hence letting the binary API control
21043              plane fn do the increment for consistency between VAT
21044              and other control planes.
21045            */
21046           this_hi = tmp2;
21047           vec_add1 (low_ports, this_low);
21048           vec_add1 (high_ports, this_hi);
21049         }
21050       else
21051         break;
21052     }
21053
21054   if (prefix_set == 0)
21055     {
21056       errmsg ("<address>/<mask> not specified");
21057       return -99;
21058     }
21059
21060   if (vrf_id == ~0)
21061     {
21062       errmsg ("VRF ID required, not specified");
21063       return -99;
21064     }
21065
21066   if (vrf_id == 0)
21067     {
21068       errmsg
21069         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21070       return -99;
21071     }
21072
21073   if (vec_len (low_ports) == 0)
21074     {
21075       errmsg ("At least one port or port range required");
21076       return -99;
21077     }
21078
21079   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21080
21081   mp->is_add = is_add;
21082
21083   if (is_ipv6)
21084     {
21085       mp->is_ipv6 = 1;
21086       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21087     }
21088   else
21089     {
21090       mp->is_ipv6 = 0;
21091       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21092     }
21093
21094   mp->mask_length = length;
21095   mp->number_of_ranges = vec_len (low_ports);
21096
21097   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21098   vec_free (low_ports);
21099
21100   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21101   vec_free (high_ports);
21102
21103   mp->vrf_id = ntohl (vrf_id);
21104
21105   S (mp);
21106   W (ret);
21107   return ret;
21108 }
21109
21110 int
21111 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21112 {
21113   unformat_input_t *input = vam->input;
21114   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21115   u32 sw_if_index = ~0;
21116   int vrf_set = 0;
21117   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21118   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21119   u8 is_add = 1;
21120   int ret;
21121
21122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21123     {
21124       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21125         ;
21126       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21127         ;
21128       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21129         vrf_set = 1;
21130       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21131         vrf_set = 1;
21132       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21133         vrf_set = 1;
21134       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21135         vrf_set = 1;
21136       else if (unformat (input, "del"))
21137         is_add = 0;
21138       else
21139         break;
21140     }
21141
21142   if (sw_if_index == ~0)
21143     {
21144       errmsg ("Interface required but not specified");
21145       return -99;
21146     }
21147
21148   if (vrf_set == 0)
21149     {
21150       errmsg ("VRF ID required but not specified");
21151       return -99;
21152     }
21153
21154   if (tcp_out_vrf_id == 0
21155       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21156     {
21157       errmsg
21158         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21159       return -99;
21160     }
21161
21162   /* Construct the API message */
21163   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21164
21165   mp->sw_if_index = ntohl (sw_if_index);
21166   mp->is_add = is_add;
21167   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21168   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21169   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21170   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21171
21172   /* send it... */
21173   S (mp);
21174
21175   /* Wait for a reply... */
21176   W (ret);
21177   return ret;
21178 }
21179
21180 static int
21181 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21182 {
21183   unformat_input_t *i = vam->input;
21184   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21185   u32 local_sa_id = 0;
21186   u32 remote_sa_id = 0;
21187   ip4_address_t src_address;
21188   ip4_address_t dst_address;
21189   u8 is_add = 1;
21190   int ret;
21191
21192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21193     {
21194       if (unformat (i, "local_sa %d", &local_sa_id))
21195         ;
21196       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21197         ;
21198       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21199         ;
21200       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21201         ;
21202       else if (unformat (i, "del"))
21203         is_add = 0;
21204       else
21205         {
21206           clib_warning ("parse error '%U'", format_unformat_error, i);
21207           return -99;
21208         }
21209     }
21210
21211   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21212
21213   mp->local_sa_id = ntohl (local_sa_id);
21214   mp->remote_sa_id = ntohl (remote_sa_id);
21215   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21216   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21217   mp->is_add = is_add;
21218
21219   S (mp);
21220   W (ret);
21221   return ret;
21222 }
21223
21224 static int
21225 api_set_punt (vat_main_t * vam)
21226 {
21227   unformat_input_t *i = vam->input;
21228   vl_api_set_punt_t *mp;
21229   u32 ipv = ~0;
21230   u32 protocol = ~0;
21231   u32 port = ~0;
21232   int is_add = 1;
21233   int ret;
21234
21235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21236     {
21237       if (unformat (i, "ip %d", &ipv))
21238         ;
21239       else if (unformat (i, "protocol %d", &protocol))
21240         ;
21241       else if (unformat (i, "port %d", &port))
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 (SET_PUNT, mp);
21253
21254   mp->is_add = (u8) is_add;
21255   mp->punt.ipv = (u8) ipv;
21256   mp->punt.l4_protocol = (u8) protocol;
21257   mp->punt.l4_port = htons ((u16) port);
21258
21259   S (mp);
21260   W (ret);
21261   return ret;
21262 }
21263
21264 static void vl_api_ipsec_gre_tunnel_details_t_handler
21265   (vl_api_ipsec_gre_tunnel_details_t * mp)
21266 {
21267   vat_main_t *vam = &vat_main;
21268
21269   print (vam->ofp, "%11d%15U%15U%14d%14d",
21270          ntohl (mp->sw_if_index),
21271          format_ip4_address, &mp->src_address,
21272          format_ip4_address, &mp->dst_address,
21273          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21274 }
21275
21276 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21277   (vl_api_ipsec_gre_tunnel_details_t * mp)
21278 {
21279   vat_main_t *vam = &vat_main;
21280   vat_json_node_t *node = NULL;
21281   struct in_addr ip4;
21282
21283   if (VAT_JSON_ARRAY != vam->json_tree.type)
21284     {
21285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21286       vat_json_init_array (&vam->json_tree);
21287     }
21288   node = vat_json_array_add (&vam->json_tree);
21289
21290   vat_json_init_object (node);
21291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21292   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21293   vat_json_object_add_ip4 (node, "src_address", ip4);
21294   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21295   vat_json_object_add_ip4 (node, "dst_address", ip4);
21296   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21297   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21298 }
21299
21300 static int
21301 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21302 {
21303   unformat_input_t *i = vam->input;
21304   vl_api_ipsec_gre_tunnel_dump_t *mp;
21305   vl_api_control_ping_t *mp_ping;
21306   u32 sw_if_index;
21307   u8 sw_if_index_set = 0;
21308   int ret;
21309
21310   /* Parse args required to build the message */
21311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21312     {
21313       if (unformat (i, "sw_if_index %d", &sw_if_index))
21314         sw_if_index_set = 1;
21315       else
21316         break;
21317     }
21318
21319   if (sw_if_index_set == 0)
21320     {
21321       sw_if_index = ~0;
21322     }
21323
21324   if (!vam->json_output)
21325     {
21326       print (vam->ofp, "%11s%15s%15s%14s%14s",
21327              "sw_if_index", "src_address", "dst_address",
21328              "local_sa_id", "remote_sa_id");
21329     }
21330
21331   /* Get list of gre-tunnel interfaces */
21332   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21333
21334   mp->sw_if_index = htonl (sw_if_index);
21335
21336   S (mp);
21337
21338   /* Use a control ping for synchronization */
21339   MPING (CONTROL_PING, mp_ping);
21340   S (mp_ping);
21341
21342   W (ret);
21343   return ret;
21344 }
21345
21346 static int
21347 api_delete_subif (vat_main_t * vam)
21348 {
21349   unformat_input_t *i = vam->input;
21350   vl_api_delete_subif_t *mp;
21351   u32 sw_if_index = ~0;
21352   int ret;
21353
21354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21355     {
21356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21357         ;
21358       if (unformat (i, "sw_if_index %d", &sw_if_index))
21359         ;
21360       else
21361         break;
21362     }
21363
21364   if (sw_if_index == ~0)
21365     {
21366       errmsg ("missing sw_if_index");
21367       return -99;
21368     }
21369
21370   /* Construct the API message */
21371   M (DELETE_SUBIF, mp);
21372   mp->sw_if_index = ntohl (sw_if_index);
21373
21374   S (mp);
21375   W (ret);
21376   return ret;
21377 }
21378
21379 #define foreach_pbb_vtr_op      \
21380 _("disable",  L2_VTR_DISABLED)  \
21381 _("pop",  L2_VTR_POP_2)         \
21382 _("push",  L2_VTR_PUSH_2)
21383
21384 static int
21385 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21386 {
21387   unformat_input_t *i = vam->input;
21388   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21389   u32 sw_if_index = ~0, vtr_op = ~0;
21390   u16 outer_tag = ~0;
21391   u8 dmac[6], smac[6];
21392   u8 dmac_set = 0, smac_set = 0;
21393   u16 vlanid = 0;
21394   u32 sid = ~0;
21395   u32 tmp;
21396   int ret;
21397
21398   /* Shut up coverity */
21399   clib_memset (dmac, 0, sizeof (dmac));
21400   clib_memset (smac, 0, sizeof (smac));
21401
21402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21403     {
21404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21405         ;
21406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21407         ;
21408       else if (unformat (i, "vtr_op %d", &vtr_op))
21409         ;
21410 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21411       foreach_pbb_vtr_op
21412 #undef _
21413         else if (unformat (i, "translate_pbb_stag"))
21414         {
21415           if (unformat (i, "%d", &tmp))
21416             {
21417               vtr_op = L2_VTR_TRANSLATE_2_1;
21418               outer_tag = tmp;
21419             }
21420           else
21421             {
21422               errmsg
21423                 ("translate_pbb_stag operation requires outer tag definition");
21424               return -99;
21425             }
21426         }
21427       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21428         dmac_set++;
21429       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21430         smac_set++;
21431       else if (unformat (i, "sid %d", &sid))
21432         ;
21433       else if (unformat (i, "vlanid %d", &tmp))
21434         vlanid = tmp;
21435       else
21436         {
21437           clib_warning ("parse error '%U'", format_unformat_error, i);
21438           return -99;
21439         }
21440     }
21441
21442   if ((sw_if_index == ~0) || (vtr_op == ~0))
21443     {
21444       errmsg ("missing sw_if_index or vtr operation");
21445       return -99;
21446     }
21447   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21448       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21449     {
21450       errmsg
21451         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21452       return -99;
21453     }
21454
21455   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21456   mp->sw_if_index = ntohl (sw_if_index);
21457   mp->vtr_op = ntohl (vtr_op);
21458   mp->outer_tag = ntohs (outer_tag);
21459   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21460   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21461   mp->b_vlanid = ntohs (vlanid);
21462   mp->i_sid = ntohl (sid);
21463
21464   S (mp);
21465   W (ret);
21466   return ret;
21467 }
21468
21469 static int
21470 api_flow_classify_set_interface (vat_main_t * vam)
21471 {
21472   unformat_input_t *i = vam->input;
21473   vl_api_flow_classify_set_interface_t *mp;
21474   u32 sw_if_index;
21475   int sw_if_index_set;
21476   u32 ip4_table_index = ~0;
21477   u32 ip6_table_index = ~0;
21478   u8 is_add = 1;
21479   int ret;
21480
21481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21482     {
21483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21484         sw_if_index_set = 1;
21485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21486         sw_if_index_set = 1;
21487       else if (unformat (i, "del"))
21488         is_add = 0;
21489       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21490         ;
21491       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21492         ;
21493       else
21494         {
21495           clib_warning ("parse error '%U'", format_unformat_error, i);
21496           return -99;
21497         }
21498     }
21499
21500   if (sw_if_index_set == 0)
21501     {
21502       errmsg ("missing interface name or sw_if_index");
21503       return -99;
21504     }
21505
21506   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21507
21508   mp->sw_if_index = ntohl (sw_if_index);
21509   mp->ip4_table_index = ntohl (ip4_table_index);
21510   mp->ip6_table_index = ntohl (ip6_table_index);
21511   mp->is_add = is_add;
21512
21513   S (mp);
21514   W (ret);
21515   return ret;
21516 }
21517
21518 static int
21519 api_flow_classify_dump (vat_main_t * vam)
21520 {
21521   unformat_input_t *i = vam->input;
21522   vl_api_flow_classify_dump_t *mp;
21523   vl_api_control_ping_t *mp_ping;
21524   u8 type = FLOW_CLASSIFY_N_TABLES;
21525   int ret;
21526
21527   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21528     ;
21529   else
21530     {
21531       errmsg ("classify table type must be specified");
21532       return -99;
21533     }
21534
21535   if (!vam->json_output)
21536     {
21537       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21538     }
21539
21540   M (FLOW_CLASSIFY_DUMP, mp);
21541   mp->type = type;
21542   /* send it... */
21543   S (mp);
21544
21545   /* Use a control ping for synchronization */
21546   MPING (CONTROL_PING, mp_ping);
21547   S (mp_ping);
21548
21549   /* Wait for a reply... */
21550   W (ret);
21551   return ret;
21552 }
21553
21554 static int
21555 api_feature_enable_disable (vat_main_t * vam)
21556 {
21557   unformat_input_t *i = vam->input;
21558   vl_api_feature_enable_disable_t *mp;
21559   u8 *arc_name = 0;
21560   u8 *feature_name = 0;
21561   u32 sw_if_index = ~0;
21562   u8 enable = 1;
21563   int ret;
21564
21565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21566     {
21567       if (unformat (i, "arc_name %s", &arc_name))
21568         ;
21569       else if (unformat (i, "feature_name %s", &feature_name))
21570         ;
21571       else
21572         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21573         ;
21574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21575         ;
21576       else if (unformat (i, "disable"))
21577         enable = 0;
21578       else
21579         break;
21580     }
21581
21582   if (arc_name == 0)
21583     {
21584       errmsg ("missing arc name");
21585       return -99;
21586     }
21587   if (vec_len (arc_name) > 63)
21588     {
21589       errmsg ("arc name too long");
21590     }
21591
21592   if (feature_name == 0)
21593     {
21594       errmsg ("missing feature name");
21595       return -99;
21596     }
21597   if (vec_len (feature_name) > 63)
21598     {
21599       errmsg ("feature name too long");
21600     }
21601
21602   if (sw_if_index == ~0)
21603     {
21604       errmsg ("missing interface name or sw_if_index");
21605       return -99;
21606     }
21607
21608   /* Construct the API message */
21609   M (FEATURE_ENABLE_DISABLE, mp);
21610   mp->sw_if_index = ntohl (sw_if_index);
21611   mp->enable = enable;
21612   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21613   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21614   vec_free (arc_name);
21615   vec_free (feature_name);
21616
21617   S (mp);
21618   W (ret);
21619   return ret;
21620 }
21621
21622 static int
21623 api_sw_interface_tag_add_del (vat_main_t * vam)
21624 {
21625   unformat_input_t *i = vam->input;
21626   vl_api_sw_interface_tag_add_del_t *mp;
21627   u32 sw_if_index = ~0;
21628   u8 *tag = 0;
21629   u8 enable = 1;
21630   int ret;
21631
21632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21633     {
21634       if (unformat (i, "tag %s", &tag))
21635         ;
21636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21637         ;
21638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21639         ;
21640       else if (unformat (i, "del"))
21641         enable = 0;
21642       else
21643         break;
21644     }
21645
21646   if (sw_if_index == ~0)
21647     {
21648       errmsg ("missing interface name or sw_if_index");
21649       return -99;
21650     }
21651
21652   if (enable && (tag == 0))
21653     {
21654       errmsg ("no tag specified");
21655       return -99;
21656     }
21657
21658   /* Construct the API message */
21659   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21660   mp->sw_if_index = ntohl (sw_if_index);
21661   mp->is_add = enable;
21662   if (enable)
21663     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21664   vec_free (tag);
21665
21666   S (mp);
21667   W (ret);
21668   return ret;
21669 }
21670
21671 static void vl_api_l2_xconnect_details_t_handler
21672   (vl_api_l2_xconnect_details_t * mp)
21673 {
21674   vat_main_t *vam = &vat_main;
21675
21676   print (vam->ofp, "%15d%15d",
21677          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21678 }
21679
21680 static void vl_api_l2_xconnect_details_t_handler_json
21681   (vl_api_l2_xconnect_details_t * mp)
21682 {
21683   vat_main_t *vam = &vat_main;
21684   vat_json_node_t *node = NULL;
21685
21686   if (VAT_JSON_ARRAY != vam->json_tree.type)
21687     {
21688       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21689       vat_json_init_array (&vam->json_tree);
21690     }
21691   node = vat_json_array_add (&vam->json_tree);
21692
21693   vat_json_init_object (node);
21694   vat_json_object_add_uint (node, "rx_sw_if_index",
21695                             ntohl (mp->rx_sw_if_index));
21696   vat_json_object_add_uint (node, "tx_sw_if_index",
21697                             ntohl (mp->tx_sw_if_index));
21698 }
21699
21700 static int
21701 api_l2_xconnect_dump (vat_main_t * vam)
21702 {
21703   vl_api_l2_xconnect_dump_t *mp;
21704   vl_api_control_ping_t *mp_ping;
21705   int ret;
21706
21707   if (!vam->json_output)
21708     {
21709       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21710     }
21711
21712   M (L2_XCONNECT_DUMP, mp);
21713
21714   S (mp);
21715
21716   /* Use a control ping for synchronization */
21717   MPING (CONTROL_PING, mp_ping);
21718   S (mp_ping);
21719
21720   W (ret);
21721   return ret;
21722 }
21723
21724 static int
21725 api_hw_interface_set_mtu (vat_main_t * vam)
21726 {
21727   unformat_input_t *i = vam->input;
21728   vl_api_hw_interface_set_mtu_t *mp;
21729   u32 sw_if_index = ~0;
21730   u32 mtu = 0;
21731   int ret;
21732
21733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21734     {
21735       if (unformat (i, "mtu %d", &mtu))
21736         ;
21737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21738         ;
21739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21740         ;
21741       else
21742         break;
21743     }
21744
21745   if (sw_if_index == ~0)
21746     {
21747       errmsg ("missing interface name or sw_if_index");
21748       return -99;
21749     }
21750
21751   if (mtu == 0)
21752     {
21753       errmsg ("no mtu specified");
21754       return -99;
21755     }
21756
21757   /* Construct the API message */
21758   M (HW_INTERFACE_SET_MTU, mp);
21759   mp->sw_if_index = ntohl (sw_if_index);
21760   mp->mtu = ntohs ((u16) mtu);
21761
21762   S (mp);
21763   W (ret);
21764   return ret;
21765 }
21766
21767 static int
21768 api_p2p_ethernet_add (vat_main_t * vam)
21769 {
21770   unformat_input_t *i = vam->input;
21771   vl_api_p2p_ethernet_add_t *mp;
21772   u32 parent_if_index = ~0;
21773   u32 sub_id = ~0;
21774   u8 remote_mac[6];
21775   u8 mac_set = 0;
21776   int ret;
21777
21778   clib_memset (remote_mac, 0, sizeof (remote_mac));
21779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21780     {
21781       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21782         ;
21783       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21784         ;
21785       else
21786         if (unformat
21787             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21788         mac_set++;
21789       else if (unformat (i, "sub_id %d", &sub_id))
21790         ;
21791       else
21792         {
21793           clib_warning ("parse error '%U'", format_unformat_error, i);
21794           return -99;
21795         }
21796     }
21797
21798   if (parent_if_index == ~0)
21799     {
21800       errmsg ("missing interface name or sw_if_index");
21801       return -99;
21802     }
21803   if (mac_set == 0)
21804     {
21805       errmsg ("missing remote mac address");
21806       return -99;
21807     }
21808   if (sub_id == ~0)
21809     {
21810       errmsg ("missing sub-interface id");
21811       return -99;
21812     }
21813
21814   M (P2P_ETHERNET_ADD, mp);
21815   mp->parent_if_index = ntohl (parent_if_index);
21816   mp->subif_id = ntohl (sub_id);
21817   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21818
21819   S (mp);
21820   W (ret);
21821   return ret;
21822 }
21823
21824 static int
21825 api_p2p_ethernet_del (vat_main_t * vam)
21826 {
21827   unformat_input_t *i = vam->input;
21828   vl_api_p2p_ethernet_del_t *mp;
21829   u32 parent_if_index = ~0;
21830   u8 remote_mac[6];
21831   u8 mac_set = 0;
21832   int ret;
21833
21834   clib_memset (remote_mac, 0, sizeof (remote_mac));
21835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21836     {
21837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21838         ;
21839       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21840         ;
21841       else
21842         if (unformat
21843             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21844         mac_set++;
21845       else
21846         {
21847           clib_warning ("parse error '%U'", format_unformat_error, i);
21848           return -99;
21849         }
21850     }
21851
21852   if (parent_if_index == ~0)
21853     {
21854       errmsg ("missing interface name or sw_if_index");
21855       return -99;
21856     }
21857   if (mac_set == 0)
21858     {
21859       errmsg ("missing remote mac address");
21860       return -99;
21861     }
21862
21863   M (P2P_ETHERNET_DEL, mp);
21864   mp->parent_if_index = ntohl (parent_if_index);
21865   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21866
21867   S (mp);
21868   W (ret);
21869   return ret;
21870 }
21871
21872 static int
21873 api_lldp_config (vat_main_t * vam)
21874 {
21875   unformat_input_t *i = vam->input;
21876   vl_api_lldp_config_t *mp;
21877   int tx_hold = 0;
21878   int tx_interval = 0;
21879   u8 *sys_name = NULL;
21880   int ret;
21881
21882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21883     {
21884       if (unformat (i, "system-name %s", &sys_name))
21885         ;
21886       else if (unformat (i, "tx-hold %d", &tx_hold))
21887         ;
21888       else if (unformat (i, "tx-interval %d", &tx_interval))
21889         ;
21890       else
21891         {
21892           clib_warning ("parse error '%U'", format_unformat_error, i);
21893           return -99;
21894         }
21895     }
21896
21897   vec_add1 (sys_name, 0);
21898
21899   M (LLDP_CONFIG, mp);
21900   mp->tx_hold = htonl (tx_hold);
21901   mp->tx_interval = htonl (tx_interval);
21902   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21903   vec_free (sys_name);
21904
21905   S (mp);
21906   W (ret);
21907   return ret;
21908 }
21909
21910 static int
21911 api_sw_interface_set_lldp (vat_main_t * vam)
21912 {
21913   unformat_input_t *i = vam->input;
21914   vl_api_sw_interface_set_lldp_t *mp;
21915   u32 sw_if_index = ~0;
21916   u32 enable = 1;
21917   u8 *port_desc = NULL, *mgmt_oid = NULL;
21918   ip4_address_t ip4_addr;
21919   ip6_address_t ip6_addr;
21920   int ret;
21921
21922   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21923   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21924
21925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21926     {
21927       if (unformat (i, "disable"))
21928         enable = 0;
21929       else
21930         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21931         ;
21932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21933         ;
21934       else if (unformat (i, "port-desc %s", &port_desc))
21935         ;
21936       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21937         ;
21938       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21939         ;
21940       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21941         ;
21942       else
21943         break;
21944     }
21945
21946   if (sw_if_index == ~0)
21947     {
21948       errmsg ("missing interface name or sw_if_index");
21949       return -99;
21950     }
21951
21952   /* Construct the API message */
21953   vec_add1 (port_desc, 0);
21954   vec_add1 (mgmt_oid, 0);
21955   M (SW_INTERFACE_SET_LLDP, mp);
21956   mp->sw_if_index = ntohl (sw_if_index);
21957   mp->enable = enable;
21958   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21959   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21960   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21961   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21962   vec_free (port_desc);
21963   vec_free (mgmt_oid);
21964
21965   S (mp);
21966   W (ret);
21967   return ret;
21968 }
21969
21970 static int
21971 api_tcp_configure_src_addresses (vat_main_t * vam)
21972 {
21973   vl_api_tcp_configure_src_addresses_t *mp;
21974   unformat_input_t *i = vam->input;
21975   ip4_address_t v4first, v4last;
21976   ip6_address_t v6first, v6last;
21977   u8 range_set = 0;
21978   u32 vrf_id = 0;
21979   int ret;
21980
21981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21982     {
21983       if (unformat (i, "%U - %U",
21984                     unformat_ip4_address, &v4first,
21985                     unformat_ip4_address, &v4last))
21986         {
21987           if (range_set)
21988             {
21989               errmsg ("one range per message (range already set)");
21990               return -99;
21991             }
21992           range_set = 1;
21993         }
21994       else if (unformat (i, "%U - %U",
21995                          unformat_ip6_address, &v6first,
21996                          unformat_ip6_address, &v6last))
21997         {
21998           if (range_set)
21999             {
22000               errmsg ("one range per message (range already set)");
22001               return -99;
22002             }
22003           range_set = 2;
22004         }
22005       else if (unformat (i, "vrf %d", &vrf_id))
22006         ;
22007       else
22008         break;
22009     }
22010
22011   if (range_set == 0)
22012     {
22013       errmsg ("address range not set");
22014       return -99;
22015     }
22016
22017   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22018   mp->vrf_id = ntohl (vrf_id);
22019   /* ipv6? */
22020   if (range_set == 2)
22021     {
22022       mp->is_ipv6 = 1;
22023       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22024       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22025     }
22026   else
22027     {
22028       mp->is_ipv6 = 0;
22029       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22030       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22031     }
22032   S (mp);
22033   W (ret);
22034   return ret;
22035 }
22036
22037 static void vl_api_app_namespace_add_del_reply_t_handler
22038   (vl_api_app_namespace_add_del_reply_t * mp)
22039 {
22040   vat_main_t *vam = &vat_main;
22041   i32 retval = ntohl (mp->retval);
22042   if (vam->async_mode)
22043     {
22044       vam->async_errors += (retval < 0);
22045     }
22046   else
22047     {
22048       vam->retval = retval;
22049       if (retval == 0)
22050         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22051       vam->result_ready = 1;
22052     }
22053 }
22054
22055 static void vl_api_app_namespace_add_del_reply_t_handler_json
22056   (vl_api_app_namespace_add_del_reply_t * mp)
22057 {
22058   vat_main_t *vam = &vat_main;
22059   vat_json_node_t node;
22060
22061   vat_json_init_object (&node);
22062   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22063   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22064
22065   vat_json_print (vam->ofp, &node);
22066   vat_json_free (&node);
22067
22068   vam->retval = ntohl (mp->retval);
22069   vam->result_ready = 1;
22070 }
22071
22072 static int
22073 api_app_namespace_add_del (vat_main_t * vam)
22074 {
22075   vl_api_app_namespace_add_del_t *mp;
22076   unformat_input_t *i = vam->input;
22077   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22078   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22079   u64 secret;
22080   int ret;
22081
22082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22083     {
22084       if (unformat (i, "id %_%v%_", &ns_id))
22085         ;
22086       else if (unformat (i, "secret %lu", &secret))
22087         secret_set = 1;
22088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22089         sw_if_index_set = 1;
22090       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22091         ;
22092       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22093         ;
22094       else
22095         break;
22096     }
22097   if (!ns_id || !secret_set || !sw_if_index_set)
22098     {
22099       errmsg ("namespace id, secret and sw_if_index must be set");
22100       return -99;
22101     }
22102   if (vec_len (ns_id) > 64)
22103     {
22104       errmsg ("namespace id too long");
22105       return -99;
22106     }
22107   M (APP_NAMESPACE_ADD_DEL, mp);
22108
22109   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22110   mp->namespace_id_len = vec_len (ns_id);
22111   mp->secret = clib_host_to_net_u64 (secret);
22112   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22113   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22114   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22115   vec_free (ns_id);
22116   S (mp);
22117   W (ret);
22118   return ret;
22119 }
22120
22121 static int
22122 api_sock_init_shm (vat_main_t * vam)
22123 {
22124 #if VPP_API_TEST_BUILTIN == 0
22125   unformat_input_t *i = vam->input;
22126   vl_api_shm_elem_config_t *config = 0;
22127   u64 size = 64 << 20;
22128   int rv;
22129
22130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22131     {
22132       if (unformat (i, "size %U", unformat_memory_size, &size))
22133         ;
22134       else
22135         break;
22136     }
22137
22138   /*
22139    * Canned custom ring allocator config.
22140    * Should probably parse all of this
22141    */
22142   vec_validate (config, 6);
22143   config[0].type = VL_API_VLIB_RING;
22144   config[0].size = 256;
22145   config[0].count = 32;
22146
22147   config[1].type = VL_API_VLIB_RING;
22148   config[1].size = 1024;
22149   config[1].count = 16;
22150
22151   config[2].type = VL_API_VLIB_RING;
22152   config[2].size = 4096;
22153   config[2].count = 2;
22154
22155   config[3].type = VL_API_CLIENT_RING;
22156   config[3].size = 256;
22157   config[3].count = 32;
22158
22159   config[4].type = VL_API_CLIENT_RING;
22160   config[4].size = 1024;
22161   config[4].count = 16;
22162
22163   config[5].type = VL_API_CLIENT_RING;
22164   config[5].size = 4096;
22165   config[5].count = 2;
22166
22167   config[6].type = VL_API_QUEUE;
22168   config[6].count = 128;
22169   config[6].size = sizeof (uword);
22170
22171   rv = vl_socket_client_init_shm (config);
22172   if (!rv)
22173     vam->client_index_invalid = 1;
22174   return rv;
22175 #else
22176   return -99;
22177 #endif
22178 }
22179
22180 static int
22181 api_dns_enable_disable (vat_main_t * vam)
22182 {
22183   unformat_input_t *line_input = vam->input;
22184   vl_api_dns_enable_disable_t *mp;
22185   u8 enable_disable = 1;
22186   int ret;
22187
22188   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22189     {
22190       if (unformat (line_input, "disable"))
22191         enable_disable = 0;
22192       if (unformat (line_input, "enable"))
22193         enable_disable = 1;
22194       else
22195         break;
22196     }
22197
22198   /* Construct the API message */
22199   M (DNS_ENABLE_DISABLE, mp);
22200   mp->enable = enable_disable;
22201
22202   /* send it... */
22203   S (mp);
22204   /* Wait for the reply */
22205   W (ret);
22206   return ret;
22207 }
22208
22209 static int
22210 api_dns_resolve_name (vat_main_t * vam)
22211 {
22212   unformat_input_t *line_input = vam->input;
22213   vl_api_dns_resolve_name_t *mp;
22214   u8 *name = 0;
22215   int ret;
22216
22217   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22218     {
22219       if (unformat (line_input, "%s", &name))
22220         ;
22221       else
22222         break;
22223     }
22224
22225   if (vec_len (name) > 127)
22226     {
22227       errmsg ("name too long");
22228       return -99;
22229     }
22230
22231   /* Construct the API message */
22232   M (DNS_RESOLVE_NAME, mp);
22233   memcpy (mp->name, name, vec_len (name));
22234   vec_free (name);
22235
22236   /* send it... */
22237   S (mp);
22238   /* Wait for the reply */
22239   W (ret);
22240   return ret;
22241 }
22242
22243 static int
22244 api_dns_resolve_ip (vat_main_t * vam)
22245 {
22246   unformat_input_t *line_input = vam->input;
22247   vl_api_dns_resolve_ip_t *mp;
22248   int is_ip6 = -1;
22249   ip4_address_t addr4;
22250   ip6_address_t addr6;
22251   int ret;
22252
22253   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22254     {
22255       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22256         is_ip6 = 1;
22257       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22258         is_ip6 = 0;
22259       else
22260         break;
22261     }
22262
22263   if (is_ip6 == -1)
22264     {
22265       errmsg ("missing address");
22266       return -99;
22267     }
22268
22269   /* Construct the API message */
22270   M (DNS_RESOLVE_IP, mp);
22271   mp->is_ip6 = is_ip6;
22272   if (is_ip6)
22273     memcpy (mp->address, &addr6, sizeof (addr6));
22274   else
22275     memcpy (mp->address, &addr4, sizeof (addr4));
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_name_server_add_del (vat_main_t * vam)
22286 {
22287   unformat_input_t *i = vam->input;
22288   vl_api_dns_name_server_add_del_t *mp;
22289   u8 is_add = 1;
22290   ip6_address_t ip6_server;
22291   ip4_address_t ip4_server;
22292   int ip6_set = 0;
22293   int ip4_set = 0;
22294   int ret = 0;
22295
22296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22297     {
22298       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22299         ip6_set = 1;
22300       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22301         ip4_set = 1;
22302       else if (unformat (i, "del"))
22303         is_add = 0;
22304       else
22305         {
22306           clib_warning ("parse error '%U'", format_unformat_error, i);
22307           return -99;
22308         }
22309     }
22310
22311   if (ip4_set && ip6_set)
22312     {
22313       errmsg ("Only one server address allowed per message");
22314       return -99;
22315     }
22316   if ((ip4_set + ip6_set) == 0)
22317     {
22318       errmsg ("Server address required");
22319       return -99;
22320     }
22321
22322   /* Construct the API message */
22323   M (DNS_NAME_SERVER_ADD_DEL, mp);
22324
22325   if (ip6_set)
22326     {
22327       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22328       mp->is_ip6 = 1;
22329     }
22330   else
22331     {
22332       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22333       mp->is_ip6 = 0;
22334     }
22335
22336   mp->is_add = is_add;
22337
22338   /* send it... */
22339   S (mp);
22340
22341   /* Wait for a reply, return good/bad news  */
22342   W (ret);
22343   return ret;
22344 }
22345
22346 static void
22347 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22348 {
22349   vat_main_t *vam = &vat_main;
22350
22351   if (mp->is_ip4)
22352     {
22353       print (vam->ofp,
22354              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22355              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22356              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22357              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22358              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22359              clib_net_to_host_u32 (mp->action_index), mp->tag);
22360     }
22361   else
22362     {
22363       print (vam->ofp,
22364              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22365              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22366              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22367              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22368              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22369              clib_net_to_host_u32 (mp->action_index), mp->tag);
22370     }
22371 }
22372
22373 static void
22374 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22375                                              mp)
22376 {
22377   vat_main_t *vam = &vat_main;
22378   vat_json_node_t *node = NULL;
22379   struct in6_addr ip6;
22380   struct in_addr ip4;
22381
22382   if (VAT_JSON_ARRAY != vam->json_tree.type)
22383     {
22384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22385       vat_json_init_array (&vam->json_tree);
22386     }
22387   node = vat_json_array_add (&vam->json_tree);
22388   vat_json_init_object (node);
22389
22390   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22391   vat_json_object_add_uint (node, "appns_index",
22392                             clib_net_to_host_u32 (mp->appns_index));
22393   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22394   vat_json_object_add_uint (node, "scope", mp->scope);
22395   vat_json_object_add_uint (node, "action_index",
22396                             clib_net_to_host_u32 (mp->action_index));
22397   vat_json_object_add_uint (node, "lcl_port",
22398                             clib_net_to_host_u16 (mp->lcl_port));
22399   vat_json_object_add_uint (node, "rmt_port",
22400                             clib_net_to_host_u16 (mp->rmt_port));
22401   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22402   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22403   vat_json_object_add_string_copy (node, "tag", mp->tag);
22404   if (mp->is_ip4)
22405     {
22406       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22407       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22408       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22409       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22410     }
22411   else
22412     {
22413       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22414       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22415       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22416       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22417     }
22418 }
22419
22420 static int
22421 api_session_rule_add_del (vat_main_t * vam)
22422 {
22423   vl_api_session_rule_add_del_t *mp;
22424   unformat_input_t *i = vam->input;
22425   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22426   u32 appns_index = 0, scope = 0;
22427   ip4_address_t lcl_ip4, rmt_ip4;
22428   ip6_address_t lcl_ip6, rmt_ip6;
22429   u8 is_ip4 = 1, conn_set = 0;
22430   u8 is_add = 1, *tag = 0;
22431   int ret;
22432
22433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22434     {
22435       if (unformat (i, "del"))
22436         is_add = 0;
22437       else if (unformat (i, "add"))
22438         ;
22439       else if (unformat (i, "proto tcp"))
22440         proto = 0;
22441       else if (unformat (i, "proto udp"))
22442         proto = 1;
22443       else if (unformat (i, "appns %d", &appns_index))
22444         ;
22445       else if (unformat (i, "scope %d", &scope))
22446         ;
22447       else if (unformat (i, "tag %_%v%_", &tag))
22448         ;
22449       else
22450         if (unformat
22451             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22452              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22453              &rmt_port))
22454         {
22455           is_ip4 = 1;
22456           conn_set = 1;
22457         }
22458       else
22459         if (unformat
22460             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22461              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22462              &rmt_port))
22463         {
22464           is_ip4 = 0;
22465           conn_set = 1;
22466         }
22467       else if (unformat (i, "action %d", &action))
22468         ;
22469       else
22470         break;
22471     }
22472   if (proto == ~0 || !conn_set || action == ~0)
22473     {
22474       errmsg ("transport proto, connection and action must be set");
22475       return -99;
22476     }
22477
22478   if (scope > 3)
22479     {
22480       errmsg ("scope should be 0-3");
22481       return -99;
22482     }
22483
22484   M (SESSION_RULE_ADD_DEL, mp);
22485
22486   mp->is_ip4 = is_ip4;
22487   mp->transport_proto = proto;
22488   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22489   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22490   mp->lcl_plen = lcl_plen;
22491   mp->rmt_plen = rmt_plen;
22492   mp->action_index = clib_host_to_net_u32 (action);
22493   mp->appns_index = clib_host_to_net_u32 (appns_index);
22494   mp->scope = scope;
22495   mp->is_add = is_add;
22496   if (is_ip4)
22497     {
22498       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22499       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22500     }
22501   else
22502     {
22503       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22504       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22505     }
22506   if (tag)
22507     {
22508       clib_memcpy (mp->tag, tag, vec_len (tag));
22509       vec_free (tag);
22510     }
22511
22512   S (mp);
22513   W (ret);
22514   return ret;
22515 }
22516
22517 static int
22518 api_session_rules_dump (vat_main_t * vam)
22519 {
22520   vl_api_session_rules_dump_t *mp;
22521   vl_api_control_ping_t *mp_ping;
22522   int ret;
22523
22524   if (!vam->json_output)
22525     {
22526       print (vam->ofp, "%=20s", "Session Rules");
22527     }
22528
22529   M (SESSION_RULES_DUMP, mp);
22530   /* send it... */
22531   S (mp);
22532
22533   /* Use a control ping for synchronization */
22534   MPING (CONTROL_PING, mp_ping);
22535   S (mp_ping);
22536
22537   /* Wait for a reply... */
22538   W (ret);
22539   return ret;
22540 }
22541
22542 static int
22543 api_ip_container_proxy_add_del (vat_main_t * vam)
22544 {
22545   vl_api_ip_container_proxy_add_del_t *mp;
22546   unformat_input_t *i = vam->input;
22547   u32 plen = ~0, sw_if_index = ~0;
22548   ip4_address_t ip4;
22549   ip6_address_t ip6;
22550   u8 is_ip4 = 1;
22551   u8 is_add = 1;
22552   int ret;
22553
22554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22555     {
22556       if (unformat (i, "del"))
22557         is_add = 0;
22558       else if (unformat (i, "add"))
22559         ;
22560       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22561         {
22562           is_ip4 = 1;
22563           plen = 32;
22564         }
22565       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22566         {
22567           is_ip4 = 0;
22568           plen = 128;
22569         }
22570       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22571         ;
22572       else
22573         break;
22574     }
22575   if (sw_if_index == ~0 || plen == ~0)
22576     {
22577       errmsg ("address and sw_if_index must be set");
22578       return -99;
22579     }
22580
22581   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22582
22583   mp->is_ip4 = is_ip4;
22584   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22585   mp->plen = plen;
22586   mp->is_add = is_add;
22587   if (is_ip4)
22588     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22589   else
22590     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22591
22592   S (mp);
22593   W (ret);
22594   return ret;
22595 }
22596
22597 static int
22598 api_qos_record_enable_disable (vat_main_t * vam)
22599 {
22600   unformat_input_t *i = vam->input;
22601   vl_api_qos_record_enable_disable_t *mp;
22602   u32 sw_if_index, qs = 0xff;
22603   u8 sw_if_index_set = 0;
22604   u8 enable = 1;
22605   int ret;
22606
22607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22608     {
22609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22610         sw_if_index_set = 1;
22611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22612         sw_if_index_set = 1;
22613       else if (unformat (i, "%U", unformat_qos_source, &qs))
22614         ;
22615       else if (unformat (i, "disable"))
22616         enable = 0;
22617       else
22618         {
22619           clib_warning ("parse error '%U'", format_unformat_error, i);
22620           return -99;
22621         }
22622     }
22623
22624   if (sw_if_index_set == 0)
22625     {
22626       errmsg ("missing interface name or sw_if_index");
22627       return -99;
22628     }
22629   if (qs == 0xff)
22630     {
22631       errmsg ("input location must be specified");
22632       return -99;
22633     }
22634
22635   M (QOS_RECORD_ENABLE_DISABLE, mp);
22636
22637   mp->sw_if_index = ntohl (sw_if_index);
22638   mp->input_source = qs;
22639   mp->enable = enable;
22640
22641   S (mp);
22642   W (ret);
22643   return ret;
22644 }
22645
22646
22647 static int
22648 q_or_quit (vat_main_t * vam)
22649 {
22650 #if VPP_API_TEST_BUILTIN == 0
22651   longjmp (vam->jump_buf, 1);
22652 #endif
22653   return 0;                     /* not so much */
22654 }
22655
22656 static int
22657 q (vat_main_t * vam)
22658 {
22659   return q_or_quit (vam);
22660 }
22661
22662 static int
22663 quit (vat_main_t * vam)
22664 {
22665   return q_or_quit (vam);
22666 }
22667
22668 static int
22669 comment (vat_main_t * vam)
22670 {
22671   return 0;
22672 }
22673
22674 static int
22675 statseg (vat_main_t * vam)
22676 {
22677   ssvm_private_t *ssvmp = &vam->stat_segment;
22678   ssvm_shared_header_t *shared_header = ssvmp->sh;
22679   vlib_counter_t **counters;
22680   u64 thread0_index1_packets;
22681   u64 thread0_index1_bytes;
22682   f64 vector_rate, input_rate;
22683   uword *p;
22684
22685   uword *counter_vector_by_name;
22686   if (vam->stat_segment_lockp == 0)
22687     {
22688       errmsg ("Stat segment not mapped...");
22689       return -99;
22690     }
22691
22692   /* look up "/if/rx for sw_if_index 1 as a test */
22693
22694   clib_spinlock_lock (vam->stat_segment_lockp);
22695
22696   counter_vector_by_name = (uword *) shared_header->opaque[1];
22697
22698   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22699   if (p == 0)
22700     {
22701       clib_spinlock_unlock (vam->stat_segment_lockp);
22702       errmsg ("/if/tx not found?");
22703       return -99;
22704     }
22705
22706   /* Fish per-thread vector of combined counters from shared memory */
22707   counters = (vlib_counter_t **) p[0];
22708
22709   if (vec_len (counters[0]) < 2)
22710     {
22711       clib_spinlock_unlock (vam->stat_segment_lockp);
22712       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22713       return -99;
22714     }
22715
22716   /* Read thread 0 sw_if_index 1 counter */
22717   thread0_index1_packets = counters[0][1].packets;
22718   thread0_index1_bytes = counters[0][1].bytes;
22719
22720   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22721   if (p == 0)
22722     {
22723       clib_spinlock_unlock (vam->stat_segment_lockp);
22724       errmsg ("vector_rate not found?");
22725       return -99;
22726     }
22727
22728   vector_rate = *(f64 *) (p[0]);
22729   p = hash_get_mem (counter_vector_by_name, "input_rate");
22730   if (p == 0)
22731     {
22732       clib_spinlock_unlock (vam->stat_segment_lockp);
22733       errmsg ("input_rate not found?");
22734       return -99;
22735     }
22736   input_rate = *(f64 *) (p[0]);
22737
22738   clib_spinlock_unlock (vam->stat_segment_lockp);
22739
22740   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22741          vector_rate, input_rate);
22742   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22743          thread0_index1_packets, thread0_index1_bytes);
22744
22745   return 0;
22746 }
22747
22748 static int
22749 cmd_cmp (void *a1, void *a2)
22750 {
22751   u8 **c1 = a1;
22752   u8 **c2 = a2;
22753
22754   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22755 }
22756
22757 static int
22758 help (vat_main_t * vam)
22759 {
22760   u8 **cmds = 0;
22761   u8 *name = 0;
22762   hash_pair_t *p;
22763   unformat_input_t *i = vam->input;
22764   int j;
22765
22766   if (unformat (i, "%s", &name))
22767     {
22768       uword *hs;
22769
22770       vec_add1 (name, 0);
22771
22772       hs = hash_get_mem (vam->help_by_name, name);
22773       if (hs)
22774         print (vam->ofp, "usage: %s %s", name, hs[0]);
22775       else
22776         print (vam->ofp, "No such msg / command '%s'", name);
22777       vec_free (name);
22778       return 0;
22779     }
22780
22781   print (vam->ofp, "Help is available for the following:");
22782
22783     /* *INDENT-OFF* */
22784     hash_foreach_pair (p, vam->function_by_name,
22785     ({
22786       vec_add1 (cmds, (u8 *)(p->key));
22787     }));
22788     /* *INDENT-ON* */
22789
22790   vec_sort_with_function (cmds, cmd_cmp);
22791
22792   for (j = 0; j < vec_len (cmds); j++)
22793     print (vam->ofp, "%s", cmds[j]);
22794
22795   vec_free (cmds);
22796   return 0;
22797 }
22798
22799 static int
22800 set (vat_main_t * vam)
22801 {
22802   u8 *name = 0, *value = 0;
22803   unformat_input_t *i = vam->input;
22804
22805   if (unformat (i, "%s", &name))
22806     {
22807       /* The input buffer is a vector, not a string. */
22808       value = vec_dup (i->buffer);
22809       vec_delete (value, i->index, 0);
22810       /* Almost certainly has a trailing newline */
22811       if (value[vec_len (value) - 1] == '\n')
22812         value[vec_len (value) - 1] = 0;
22813       /* Make sure it's a proper string, one way or the other */
22814       vec_add1 (value, 0);
22815       (void) clib_macro_set_value (&vam->macro_main,
22816                                    (char *) name, (char *) value);
22817     }
22818   else
22819     errmsg ("usage: set <name> <value>");
22820
22821   vec_free (name);
22822   vec_free (value);
22823   return 0;
22824 }
22825
22826 static int
22827 unset (vat_main_t * vam)
22828 {
22829   u8 *name = 0;
22830
22831   if (unformat (vam->input, "%s", &name))
22832     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22833       errmsg ("unset: %s wasn't set", name);
22834   vec_free (name);
22835   return 0;
22836 }
22837
22838 typedef struct
22839 {
22840   u8 *name;
22841   u8 *value;
22842 } macro_sort_t;
22843
22844
22845 static int
22846 macro_sort_cmp (void *a1, void *a2)
22847 {
22848   macro_sort_t *s1 = a1;
22849   macro_sort_t *s2 = a2;
22850
22851   return strcmp ((char *) (s1->name), (char *) (s2->name));
22852 }
22853
22854 static int
22855 dump_macro_table (vat_main_t * vam)
22856 {
22857   macro_sort_t *sort_me = 0, *sm;
22858   int i;
22859   hash_pair_t *p;
22860
22861     /* *INDENT-OFF* */
22862     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22863     ({
22864       vec_add2 (sort_me, sm, 1);
22865       sm->name = (u8 *)(p->key);
22866       sm->value = (u8 *) (p->value[0]);
22867     }));
22868     /* *INDENT-ON* */
22869
22870   vec_sort_with_function (sort_me, macro_sort_cmp);
22871
22872   if (vec_len (sort_me))
22873     print (vam->ofp, "%-15s%s", "Name", "Value");
22874   else
22875     print (vam->ofp, "The macro table is empty...");
22876
22877   for (i = 0; i < vec_len (sort_me); i++)
22878     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22879   return 0;
22880 }
22881
22882 static int
22883 dump_node_table (vat_main_t * vam)
22884 {
22885   int i, j;
22886   vlib_node_t *node, *next_node;
22887
22888   if (vec_len (vam->graph_nodes) == 0)
22889     {
22890       print (vam->ofp, "Node table empty, issue get_node_graph...");
22891       return 0;
22892     }
22893
22894   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22895     {
22896       node = vam->graph_nodes[0][i];
22897       print (vam->ofp, "[%d] %s", i, node->name);
22898       for (j = 0; j < vec_len (node->next_nodes); j++)
22899         {
22900           if (node->next_nodes[j] != ~0)
22901             {
22902               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22903               print (vam->ofp, "  [%d] %s", j, next_node->name);
22904             }
22905         }
22906     }
22907   return 0;
22908 }
22909
22910 static int
22911 value_sort_cmp (void *a1, void *a2)
22912 {
22913   name_sort_t *n1 = a1;
22914   name_sort_t *n2 = a2;
22915
22916   if (n1->value < n2->value)
22917     return -1;
22918   if (n1->value > n2->value)
22919     return 1;
22920   return 0;
22921 }
22922
22923
22924 static int
22925 dump_msg_api_table (vat_main_t * vam)
22926 {
22927   api_main_t *am = &api_main;
22928   name_sort_t *nses = 0, *ns;
22929   hash_pair_t *hp;
22930   int i;
22931
22932   /* *INDENT-OFF* */
22933   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22934   ({
22935     vec_add2 (nses, ns, 1);
22936     ns->name = (u8 *)(hp->key);
22937     ns->value = (u32) hp->value[0];
22938   }));
22939   /* *INDENT-ON* */
22940
22941   vec_sort_with_function (nses, value_sort_cmp);
22942
22943   for (i = 0; i < vec_len (nses); i++)
22944     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22945   vec_free (nses);
22946   return 0;
22947 }
22948
22949 static int
22950 get_msg_id (vat_main_t * vam)
22951 {
22952   u8 *name_and_crc;
22953   u32 message_index;
22954
22955   if (unformat (vam->input, "%s", &name_and_crc))
22956     {
22957       message_index = vl_msg_api_get_msg_index (name_and_crc);
22958       if (message_index == ~0)
22959         {
22960           print (vam->ofp, " '%s' not found", name_and_crc);
22961           return 0;
22962         }
22963       print (vam->ofp, " '%s' has message index %d",
22964              name_and_crc, message_index);
22965       return 0;
22966     }
22967   errmsg ("name_and_crc required...");
22968   return 0;
22969 }
22970
22971 static int
22972 search_node_table (vat_main_t * vam)
22973 {
22974   unformat_input_t *line_input = vam->input;
22975   u8 *node_to_find;
22976   int j;
22977   vlib_node_t *node, *next_node;
22978   uword *p;
22979
22980   if (vam->graph_node_index_by_name == 0)
22981     {
22982       print (vam->ofp, "Node table empty, issue get_node_graph...");
22983       return 0;
22984     }
22985
22986   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22987     {
22988       if (unformat (line_input, "%s", &node_to_find))
22989         {
22990           vec_add1 (node_to_find, 0);
22991           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22992           if (p == 0)
22993             {
22994               print (vam->ofp, "%s not found...", node_to_find);
22995               goto out;
22996             }
22997           node = vam->graph_nodes[0][p[0]];
22998           print (vam->ofp, "[%d] %s", p[0], node->name);
22999           for (j = 0; j < vec_len (node->next_nodes); j++)
23000             {
23001               if (node->next_nodes[j] != ~0)
23002                 {
23003                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23004                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23005                 }
23006             }
23007         }
23008
23009       else
23010         {
23011           clib_warning ("parse error '%U'", format_unformat_error,
23012                         line_input);
23013           return -99;
23014         }
23015
23016     out:
23017       vec_free (node_to_find);
23018
23019     }
23020
23021   return 0;
23022 }
23023
23024
23025 static int
23026 script (vat_main_t * vam)
23027 {
23028 #if (VPP_API_TEST_BUILTIN==0)
23029   u8 *s = 0;
23030   char *save_current_file;
23031   unformat_input_t save_input;
23032   jmp_buf save_jump_buf;
23033   u32 save_line_number;
23034
23035   FILE *new_fp, *save_ifp;
23036
23037   if (unformat (vam->input, "%s", &s))
23038     {
23039       new_fp = fopen ((char *) s, "r");
23040       if (new_fp == 0)
23041         {
23042           errmsg ("Couldn't open script file %s", s);
23043           vec_free (s);
23044           return -99;
23045         }
23046     }
23047   else
23048     {
23049       errmsg ("Missing script name");
23050       return -99;
23051     }
23052
23053   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23054   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23055   save_ifp = vam->ifp;
23056   save_line_number = vam->input_line_number;
23057   save_current_file = (char *) vam->current_file;
23058
23059   vam->input_line_number = 0;
23060   vam->ifp = new_fp;
23061   vam->current_file = s;
23062   do_one_file (vam);
23063
23064   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23065   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23066   vam->ifp = save_ifp;
23067   vam->input_line_number = save_line_number;
23068   vam->current_file = (u8 *) save_current_file;
23069   vec_free (s);
23070
23071   return 0;
23072 #else
23073   clib_warning ("use the exec command...");
23074   return -99;
23075 #endif
23076 }
23077
23078 static int
23079 echo (vat_main_t * vam)
23080 {
23081   print (vam->ofp, "%v", vam->input->buffer);
23082   return 0;
23083 }
23084
23085 /* List of API message constructors, CLI names map to api_xxx */
23086 #define foreach_vpe_api_msg                                             \
23087 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23088 _(sw_interface_dump,"")                                                 \
23089 _(sw_interface_set_flags,                                               \
23090   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23091 _(sw_interface_add_del_address,                                         \
23092   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23093 _(sw_interface_set_rx_mode,                                             \
23094   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23095 _(sw_interface_set_rx_placement,                                        \
23096   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23097 _(sw_interface_rx_placement_dump,                                       \
23098   "[<intfc> | sw_if_index <id>]")                                         \
23099 _(sw_interface_set_table,                                               \
23100   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23101 _(sw_interface_set_mpls_enable,                                         \
23102   "<intfc> | sw_if_index [disable | dis]")                              \
23103 _(sw_interface_set_vpath,                                               \
23104   "<intfc> | sw_if_index <id> enable | disable")                        \
23105 _(sw_interface_set_vxlan_bypass,                                        \
23106   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23107 _(sw_interface_set_geneve_bypass,                                       \
23108   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23109 _(sw_interface_set_l2_xconnect,                                         \
23110   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23111   "enable | disable")                                                   \
23112 _(sw_interface_set_l2_bridge,                                           \
23113   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23114   "[shg <split-horizon-group>] [bvi]\n"                                 \
23115   "enable | disable")                                                   \
23116 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23117 _(bridge_domain_add_del,                                                \
23118   "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") \
23119 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23120 _(l2fib_add_del,                                                        \
23121   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23122 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23123 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23124 _(l2_flags,                                                             \
23125   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23126 _(bridge_flags,                                                         \
23127   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23128 _(tap_connect,                                                          \
23129   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23130 _(tap_modify,                                                           \
23131   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23132 _(tap_delete,                                                           \
23133   "<vpp-if-name> | sw_if_index <id>")                                   \
23134 _(sw_interface_tap_dump, "")                                            \
23135 _(tap_create_v2,                                                        \
23136   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23137 _(tap_delete_v2,                                                        \
23138   "<vpp-if-name> | sw_if_index <id>")                                   \
23139 _(sw_interface_tap_v2_dump, "")                                         \
23140 _(bond_create,                                                          \
23141   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23142   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23143 _(bond_delete,                                                          \
23144   "<vpp-if-name> | sw_if_index <id>")                                   \
23145 _(bond_enslave,                                                         \
23146   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23147 _(bond_detach_slave,                                                    \
23148   "sw_if_index <n>")                                                    \
23149 _(sw_interface_bond_dump, "")                                           \
23150 _(sw_interface_slave_dump,                                              \
23151   "<vpp-if-name> | sw_if_index <id>")                                   \
23152 _(ip_table_add_del,                                                     \
23153   "table <n> [ipv6] [add | del]\n")                                     \
23154 _(ip_add_del_route,                                                     \
23155   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23156   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23157   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23158   "[multipath] [count <n>] [del]")                                      \
23159 _(ip_mroute_add_del,                                                    \
23160   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23161   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23162 _(mpls_table_add_del,                                                   \
23163   "table <n> [add | del]\n")                                            \
23164 _(mpls_route_add_del,                                                   \
23165   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23166   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23167   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23168   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23169   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23170   "[count <n>] [del]")                                                  \
23171 _(mpls_ip_bind_unbind,                                                  \
23172   "<label> <addr/len>")                                                 \
23173 _(mpls_tunnel_add_del,                                                  \
23174   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23175   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23176   "[l2-only]  [out-label <n>]")                                         \
23177 _(sr_mpls_policy_add,                                                   \
23178   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23179 _(sr_mpls_policy_del,                                                   \
23180   "bsid <id>")                                                          \
23181 _(bier_table_add_del,                                                   \
23182   "<label> <sub-domain> <set> <bsl> [del]")                             \
23183 _(bier_route_add_del,                                                   \
23184   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23185   "[<intfc> | sw_if_index <id>]"                                        \
23186   "[weight <n>] [del] [multipath]")                                     \
23187 _(proxy_arp_add_del,                                                    \
23188   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23189 _(proxy_arp_intfc_enable_disable,                                       \
23190   "<intfc> | sw_if_index <id> enable | disable")                        \
23191 _(sw_interface_set_unnumbered,                                          \
23192   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23193 _(ip_neighbor_add_del,                                                  \
23194   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23195   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23196 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23197 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23198   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23199   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23200   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23201 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23202 _(reset_fib, "vrf <n> [ipv6]")                                          \
23203 _(dhcp_proxy_config,                                                    \
23204   "svr <v46-address> src <v46-address>\n"                               \
23205    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23206 _(dhcp_proxy_set_vss,                                                   \
23207   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23208 _(dhcp_proxy_dump, "ip6")                                               \
23209 _(dhcp_client_config,                                                   \
23210   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23211 _(set_ip_flow_hash,                                                     \
23212   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23213 _(sw_interface_ip6_enable_disable,                                      \
23214   "<intfc> | sw_if_index <id> enable | disable")                        \
23215 _(ip6nd_proxy_add_del,                                                  \
23216   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23217 _(ip6nd_proxy_dump, "")                                                 \
23218 _(sw_interface_ip6nd_ra_prefix,                                         \
23219   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23220   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23221   "[nolink] [isno]")                                                    \
23222 _(sw_interface_ip6nd_ra_config,                                         \
23223   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23224   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23225   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23226 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23227 _(l2_patch_add_del,                                                     \
23228   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23229   "enable | disable")                                                   \
23230 _(sr_localsid_add_del,                                                  \
23231   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23232   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23233 _(classify_add_del_table,                                               \
23234   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23235   " [del] [del-chain] mask <mask-value>\n"                              \
23236   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23237   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23238 _(classify_add_del_session,                                             \
23239   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23240   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23241   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23242   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23243 _(classify_set_interface_ip_table,                                      \
23244   "<intfc> | sw_if_index <nn> table <nn>")                              \
23245 _(classify_set_interface_l2_tables,                                     \
23246   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23247   "  [other-table <nn>]")                                               \
23248 _(get_node_index, "node <node-name")                                    \
23249 _(add_node_next, "node <node-name> next <next-node-name>")              \
23250 _(l2tpv3_create_tunnel,                                                 \
23251   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23252   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23253   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23254 _(l2tpv3_set_tunnel_cookies,                                            \
23255   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23256   "[new_remote_cookie <nn>]\n")                                         \
23257 _(l2tpv3_interface_enable_disable,                                      \
23258   "<intfc> | sw_if_index <nn> enable | disable")                        \
23259 _(l2tpv3_set_lookup_key,                                                \
23260   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23261 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23262 _(vxlan_offload_rx,                                                     \
23263   "hw { <interface name> | hw_if_index <nn>} "                          \
23264   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23265 _(vxlan_add_del_tunnel,                                                 \
23266   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23267   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23268   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23269 _(geneve_add_del_tunnel,                                                \
23270   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23271   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23272   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23273 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23274 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23275 _(gre_add_del_tunnel,                                                   \
23276   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23277   "[teb | erspan <session-id>] [del]")                                  \
23278 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23279 _(l2_fib_clear_table, "")                                               \
23280 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23281 _(l2_interface_vlan_tag_rewrite,                                        \
23282   "<intfc> | sw_if_index <nn> \n"                                       \
23283   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23284   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23285 _(create_vhost_user_if,                                                 \
23286         "socket <filename> [server] [renumber <dev_instance>] "         \
23287         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23288         "[mac <mac_address>]")                                          \
23289 _(modify_vhost_user_if,                                                 \
23290         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23291         "[server] [renumber <dev_instance>]")                           \
23292 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23293 _(sw_interface_vhost_user_dump, "")                                     \
23294 _(show_version, "")                                                     \
23295 _(show_threads, "")                                                     \
23296 _(vxlan_gpe_add_del_tunnel,                                             \
23297   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23298   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23299   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23300   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23301 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23302 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23303 _(interface_name_renumber,                                              \
23304   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23305 _(input_acl_set_interface,                                              \
23306   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23307   "  [l2-table <nn>] [del]")                                            \
23308 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23309 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23310   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23311 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23312 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23313 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23314 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23315 _(ip_dump, "ipv4 | ipv6")                                               \
23316 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23317 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23318   "  spid_id <n> ")                                                     \
23319 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23320   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23321   "  integ_alg <alg> integ_key <hex>")                                  \
23322 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23323   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23324   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23325   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23326 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23327 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23328   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23329   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23330   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23331   "  [instance <n>]")     \
23332 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23333 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23334   "  <alg> <hex>\n")                                                    \
23335 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23336 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23337 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23338   "(auth_data 0x<data> | auth_data <data>)")                            \
23339 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23340   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23341 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23342   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23343   "(local|remote)")                                                     \
23344 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23345 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23346 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23347 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23348 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23349 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23350 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23351 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23352 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23353 _(delete_loopback,"sw_if_index <nn>")                                   \
23354 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23355 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23356 _(want_interface_events,  "enable|disable")                             \
23357 _(get_first_msg_id, "client <name>")                                    \
23358 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23359 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23360   "fib-id <nn> [ip4][ip6][default]")                                    \
23361 _(get_node_graph, " ")                                                  \
23362 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23363 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23364 _(ioam_disable, "")                                                     \
23365 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23366                             " sw_if_index <sw_if_index> p <priority> "  \
23367                             "w <weight>] [del]")                        \
23368 _(one_add_del_locator, "locator-set <locator_name> "                    \
23369                         "iface <intf> | sw_if_index <sw_if_index> "     \
23370                         "p <priority> w <weight> [del]")                \
23371 _(one_add_del_local_eid,"vni <vni> eid "                                \
23372                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23373                          "locator-set <locator_name> [del]"             \
23374                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23375 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23376 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23377 _(one_enable_disable, "enable|disable")                                 \
23378 _(one_map_register_enable_disable, "enable|disable")                    \
23379 _(one_map_register_fallback_threshold, "<value>")                       \
23380 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23381 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23382                                "[seid <seid>] "                         \
23383                                "rloc <locator> p <prio> "               \
23384                                "w <weight> [rloc <loc> ... ] "          \
23385                                "action <action> [del-all]")             \
23386 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23387                           "<local-eid>")                                \
23388 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23389 _(one_use_petr, "ip-address> | disable")                                \
23390 _(one_map_request_mode, "src-dst|dst-only")                             \
23391 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23392 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23393 _(one_locator_set_dump, "[local | remote]")                             \
23394 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23395 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23396                        "[local] | [remote]")                            \
23397 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23398 _(one_ndp_bd_get, "")                                                   \
23399 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23400 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23401 _(one_l2_arp_bd_get, "")                                                \
23402 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23403 _(one_stats_enable_disable, "enable|disable")                           \
23404 _(show_one_stats_enable_disable, "")                                    \
23405 _(one_eid_table_vni_dump, "")                                           \
23406 _(one_eid_table_map_dump, "l2|l3")                                      \
23407 _(one_map_resolver_dump, "")                                            \
23408 _(one_map_server_dump, "")                                              \
23409 _(one_adjacencies_get, "vni <vni>")                                     \
23410 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23411 _(show_one_rloc_probe_state, "")                                        \
23412 _(show_one_map_register_state, "")                                      \
23413 _(show_one_status, "")                                                  \
23414 _(one_stats_dump, "")                                                   \
23415 _(one_stats_flush, "")                                                  \
23416 _(one_get_map_request_itr_rlocs, "")                                    \
23417 _(one_map_register_set_ttl, "<ttl>")                                    \
23418 _(one_set_transport_protocol, "udp|api")                                \
23419 _(one_get_transport_protocol, "")                                       \
23420 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23421 _(one_show_xtr_mode, "")                                                \
23422 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23423 _(one_show_pitr_mode, "")                                               \
23424 _(one_enable_disable_petr_mode, "enable|disable")                       \
23425 _(one_show_petr_mode, "")                                               \
23426 _(show_one_nsh_mapping, "")                                             \
23427 _(show_one_pitr, "")                                                    \
23428 _(show_one_use_petr, "")                                                \
23429 _(show_one_map_request_mode, "")                                        \
23430 _(show_one_map_register_ttl, "")                                        \
23431 _(show_one_map_register_fallback_threshold, "")                         \
23432 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23433                             " sw_if_index <sw_if_index> p <priority> "  \
23434                             "w <weight>] [del]")                        \
23435 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23436                         "iface <intf> | sw_if_index <sw_if_index> "     \
23437                         "p <priority> w <weight> [del]")                \
23438 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23439                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23440                          "locator-set <locator_name> [del]"             \
23441                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23442 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23443 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23444 _(lisp_enable_disable, "enable|disable")                                \
23445 _(lisp_map_register_enable_disable, "enable|disable")                   \
23446 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23447 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23448                                "[seid <seid>] "                         \
23449                                "rloc <locator> p <prio> "               \
23450                                "w <weight> [rloc <loc> ... ] "          \
23451                                "action <action> [del-all]")             \
23452 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23453                           "<local-eid>")                                \
23454 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23455 _(lisp_use_petr, "<ip-address> | disable")                              \
23456 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23457 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23458 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23459 _(lisp_locator_set_dump, "[local | remote]")                            \
23460 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23461 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23462                        "[local] | [remote]")                            \
23463 _(lisp_eid_table_vni_dump, "")                                          \
23464 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23465 _(lisp_map_resolver_dump, "")                                           \
23466 _(lisp_map_server_dump, "")                                             \
23467 _(lisp_adjacencies_get, "vni <vni>")                                    \
23468 _(gpe_fwd_entry_vnis_get, "")                                           \
23469 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23470 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23471                                 "[table <table-id>]")                   \
23472 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23473 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23474 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23475 _(gpe_get_encap_mode, "")                                               \
23476 _(lisp_gpe_add_del_iface, "up|down")                                    \
23477 _(lisp_gpe_enable_disable, "enable|disable")                            \
23478 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23479   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23480 _(show_lisp_rloc_probe_state, "")                                       \
23481 _(show_lisp_map_register_state, "")                                     \
23482 _(show_lisp_status, "")                                                 \
23483 _(lisp_get_map_request_itr_rlocs, "")                                   \
23484 _(show_lisp_pitr, "")                                                   \
23485 _(show_lisp_use_petr, "")                                               \
23486 _(show_lisp_map_request_mode, "")                                       \
23487 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23488 _(af_packet_delete, "name <host interface name>")                       \
23489 _(af_packet_dump, "")                                                   \
23490 _(policer_add_del, "name <policer name> <params> [del]")                \
23491 _(policer_dump, "[name <policer name>]")                                \
23492 _(policer_classify_set_interface,                                       \
23493   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23494   "  [l2-table <nn>] [del]")                                            \
23495 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23496 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23497     "[master|slave]")                                                   \
23498 _(netmap_delete, "name <interface name>")                               \
23499 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23500 _(mpls_fib_dump, "")                                                    \
23501 _(classify_table_ids, "")                                               \
23502 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23503 _(classify_table_info, "table_id <nn>")                                 \
23504 _(classify_session_dump, "table_id <nn>")                               \
23505 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23506     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23507     "[template_interval <nn>] [udp_checksum]")                          \
23508 _(ipfix_exporter_dump, "")                                              \
23509 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23510 _(ipfix_classify_stream_dump, "")                                       \
23511 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23512 _(ipfix_classify_table_dump, "")                                        \
23513 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23514 _(sw_interface_span_dump, "[l2]")                                           \
23515 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23516 _(pg_create_interface, "if_id <nn>")                                    \
23517 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23518 _(pg_enable_disable, "[stream <id>] disable")                           \
23519 _(ip_source_and_port_range_check_add_del,                               \
23520   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23521 _(ip_source_and_port_range_check_interface_add_del,                     \
23522   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23523   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23524 _(ipsec_gre_add_del_tunnel,                                             \
23525   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23526 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23527 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23528 _(l2_interface_pbb_tag_rewrite,                                         \
23529   "<intfc> | sw_if_index <nn> \n"                                       \
23530   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23531   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23532 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23533 _(flow_classify_set_interface,                                          \
23534   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23535 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23536 _(ip_fib_dump, "")                                                      \
23537 _(ip_mfib_dump, "")                                                     \
23538 _(ip6_fib_dump, "")                                                     \
23539 _(ip6_mfib_dump, "")                                                    \
23540 _(feature_enable_disable, "arc_name <arc_name> "                        \
23541   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23542 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23543 "[disable]")                                                            \
23544 _(l2_xconnect_dump, "")                                                 \
23545 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23546 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23547 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23548 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23549 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23550 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23551 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23552   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23553 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23554 _(sock_init_shm, "size <nnn>")                                          \
23555 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23556 _(dns_enable_disable, "[enable][disable]")                              \
23557 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23558 _(dns_resolve_name, "<hostname>")                                       \
23559 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23560 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23561 _(dns_resolve_name, "<hostname>")                                       \
23562 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23563   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23564 _(session_rules_dump, "")                                               \
23565 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23566 _(output_acl_set_interface,                                             \
23567   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23568   "  [l2-table <nn>] [del]")                                            \
23569 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23570
23571 /* List of command functions, CLI names map directly to functions */
23572 #define foreach_cli_function                                    \
23573 _(comment, "usage: comment <ignore-rest-of-line>")              \
23574 _(dump_interface_table, "usage: dump_interface_table")          \
23575 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23576 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23577 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23578 _(dump_macro_table, "usage: dump_macro_table ")                 \
23579 _(dump_node_table, "usage: dump_node_table")                    \
23580 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23581 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23582 _(echo, "usage: echo <message>")                                \
23583 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23584 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23585 _(help, "usage: help")                                          \
23586 _(q, "usage: quit")                                             \
23587 _(quit, "usage: quit")                                          \
23588 _(search_node_table, "usage: search_node_table <name>...")      \
23589 _(set, "usage: set <variable-name> <value>")                    \
23590 _(script, "usage: script <file-name>")                          \
23591 _(statseg, "usage: statseg");                                   \
23592 _(unset, "usage: unset <variable-name>")
23593
23594 #define _(N,n)                                  \
23595     static void vl_api_##n##_t_handler_uni      \
23596     (vl_api_##n##_t * mp)                       \
23597     {                                           \
23598         vat_main_t * vam = &vat_main;           \
23599         if (vam->json_output) {                 \
23600             vl_api_##n##_t_handler_json(mp);    \
23601         } else {                                \
23602             vl_api_##n##_t_handler(mp);         \
23603         }                                       \
23604     }
23605 foreach_vpe_api_reply_msg;
23606 #if VPP_API_TEST_BUILTIN == 0
23607 foreach_standalone_reply_msg;
23608 #endif
23609 #undef _
23610
23611 void
23612 vat_api_hookup (vat_main_t * vam)
23613 {
23614 #define _(N,n)                                                  \
23615     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23616                            vl_api_##n##_t_handler_uni,          \
23617                            vl_noop_handler,                     \
23618                            vl_api_##n##_t_endian,               \
23619                            vl_api_##n##_t_print,                \
23620                            sizeof(vl_api_##n##_t), 1);
23621   foreach_vpe_api_reply_msg;
23622 #if VPP_API_TEST_BUILTIN == 0
23623   foreach_standalone_reply_msg;
23624 #endif
23625 #undef _
23626
23627 #if (VPP_API_TEST_BUILTIN==0)
23628   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23629
23630   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23631
23632   vam->function_by_name = hash_create_string (0, sizeof (uword));
23633
23634   vam->help_by_name = hash_create_string (0, sizeof (uword));
23635 #endif
23636
23637   /* API messages we can send */
23638 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23639   foreach_vpe_api_msg;
23640 #undef _
23641
23642   /* Help strings */
23643 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23644   foreach_vpe_api_msg;
23645 #undef _
23646
23647   /* CLI functions */
23648 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23649   foreach_cli_function;
23650 #undef _
23651
23652   /* Help strings */
23653 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23654   foreach_cli_function;
23655 #undef _
23656 }
23657
23658 #if VPP_API_TEST_BUILTIN
23659 static clib_error_t *
23660 vat_api_hookup_shim (vlib_main_t * vm)
23661 {
23662   vat_api_hookup (&vat_main);
23663   return 0;
23664 }
23665
23666 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23667 #endif
23668
23669 /*
23670  * fd.io coding-style-patch-verification: ON
23671  *
23672  * Local Variables:
23673  * eval: (c-set-style "gnu")
23674  * End:
23675  */