tapv2: add "tap_flags" field to the TAPv2 interface API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 u32
86 vl (void *p)
87 {
88   return vec_len (p);
89 }
90
91 int
92 vat_socket_connect (vat_main_t * vam)
93 {
94   int rv;
95   vam->socket_client_main = &socket_client_main;
96   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
97                                       "vpp_api_test",
98                                       0 /* default socket rx, tx buffer */ )))
99     return rv;
100   /* vpp expects the client index in network order */
101   vam->my_client_index = htonl (socket_client_main.client_index);
102   return 0;
103 }
104 #else /* vpp built-in case, we don't do sockets... */
105 int
106 vat_socket_connect (vat_main_t * vam)
107 {
108   return 0;
109 }
110
111 int
112 vl_socket_client_read (int wait)
113 {
114   return -1;
115 };
116
117 int
118 vl_socket_client_write ()
119 {
120   return -1;
121 };
122
123 void *
124 vl_socket_client_msg_alloc (int nbytes)
125 {
126   return 0;
127 }
128 #endif
129
130
131 f64
132 vat_time_now (vat_main_t * vam)
133 {
134 #if VPP_API_TEST_BUILTIN
135   return vlib_time_now (vam->vlib_main);
136 #else
137   return clib_time_now (&vam->clib_time);
138 #endif
139 }
140
141 void
142 errmsg (char *fmt, ...)
143 {
144   vat_main_t *vam = &vat_main;
145   va_list va;
146   u8 *s;
147
148   va_start (va, fmt);
149   s = va_format (0, fmt, &va);
150   va_end (va);
151
152   vec_add1 (s, 0);
153
154 #if VPP_API_TEST_BUILTIN
155   vlib_cli_output (vam->vlib_main, (char *) s);
156 #else
157   {
158     if (vam->ifp != stdin)
159       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
160                vam->input_line_number);
161     fformat (vam->ofp, (char *) s);
162     fflush (vam->ofp);
163   }
164 #endif
165
166   vec_free (s);
167 }
168
169 #if VPP_API_TEST_BUILTIN == 0
170 static uword
171 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
172 {
173   vat_main_t *vam = va_arg (*args, vat_main_t *);
174   u32 *result = va_arg (*args, u32 *);
175   u8 *if_name;
176   uword *p;
177
178   if (!unformat (input, "%s", &if_name))
179     return 0;
180
181   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
182   if (p == 0)
183     return 0;
184   *result = p[0];
185   return 1;
186 }
187
188 static uword
189 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
190 {
191   return 0;
192 }
193
194 /* Parse an IP4 address %d.%d.%d.%d. */
195 uword
196 unformat_ip4_address (unformat_input_t * input, va_list * args)
197 {
198   u8 *result = va_arg (*args, u8 *);
199   unsigned a[4];
200
201   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
202     return 0;
203
204   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
205     return 0;
206
207   result[0] = a[0];
208   result[1] = a[1];
209   result[2] = a[2];
210   result[3] = a[3];
211
212   return 1;
213 }
214
215 uword
216 unformat_ethernet_address (unformat_input_t * input, va_list * args)
217 {
218   u8 *result = va_arg (*args, u8 *);
219   u32 i, a[6];
220
221   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
222                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
223     return 0;
224
225   /* Check range. */
226   for (i = 0; i < 6; i++)
227     if (a[i] >= (1 << 8))
228       return 0;
229
230   for (i = 0; i < 6; i++)
231     result[i] = a[i];
232
233   return 1;
234 }
235
236 /* Returns ethernet type as an int in host byte order. */
237 uword
238 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
239                                         va_list * args)
240 {
241   u16 *result = va_arg (*args, u16 *);
242   int type;
243
244   /* Numeric type. */
245   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
246     {
247       if (type >= (1 << 16))
248         return 0;
249       *result = type;
250       return 1;
251     }
252   return 0;
253 }
254
255 /* Parse an IP6 address. */
256 uword
257 unformat_ip6_address (unformat_input_t * input, va_list * args)
258 {
259   ip6_address_t *result = va_arg (*args, ip6_address_t *);
260   u16 hex_quads[8];
261   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
262   uword c, n_colon, double_colon_index;
263
264   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
265   double_colon_index = ARRAY_LEN (hex_quads);
266   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
267     {
268       hex_digit = 16;
269       if (c >= '0' && c <= '9')
270         hex_digit = c - '0';
271       else if (c >= 'a' && c <= 'f')
272         hex_digit = c + 10 - 'a';
273       else if (c >= 'A' && c <= 'F')
274         hex_digit = c + 10 - 'A';
275       else if (c == ':' && n_colon < 2)
276         n_colon++;
277       else
278         {
279           unformat_put_input (input);
280           break;
281         }
282
283       /* Too many hex quads. */
284       if (n_hex_quads >= ARRAY_LEN (hex_quads))
285         return 0;
286
287       if (hex_digit < 16)
288         {
289           hex_quad = (hex_quad << 4) | hex_digit;
290
291           /* Hex quad must fit in 16 bits. */
292           if (n_hex_digits >= 4)
293             return 0;
294
295           n_colon = 0;
296           n_hex_digits++;
297         }
298
299       /* Save position of :: */
300       if (n_colon == 2)
301         {
302           /* More than one :: ? */
303           if (double_colon_index < ARRAY_LEN (hex_quads))
304             return 0;
305           double_colon_index = n_hex_quads;
306         }
307
308       if (n_colon > 0 && n_hex_digits > 0)
309         {
310           hex_quads[n_hex_quads++] = hex_quad;
311           hex_quad = 0;
312           n_hex_digits = 0;
313         }
314     }
315
316   if (n_hex_digits > 0)
317     hex_quads[n_hex_quads++] = hex_quad;
318
319   {
320     word i;
321
322     /* Expand :: to appropriate number of zero hex quads. */
323     if (double_colon_index < ARRAY_LEN (hex_quads))
324       {
325         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
326
327         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
328           hex_quads[n_zero + i] = hex_quads[i];
329
330         for (i = 0; i < n_zero; i++)
331           hex_quads[double_colon_index + i] = 0;
332
333         n_hex_quads = ARRAY_LEN (hex_quads);
334       }
335
336     /* Too few hex quads given. */
337     if (n_hex_quads < ARRAY_LEN (hex_quads))
338       return 0;
339
340     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
341       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
342
343     return 1;
344   }
345 }
346
347 uword
348 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
354   foreach_ipsec_policy_action
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 uword
362 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
363 {
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
368   foreach_ipsec_crypto_alg
369 #undef _
370     else
371     return 0;
372   return 1;
373 }
374
375 u8 *
376 format_ipsec_crypto_alg (u8 * s, va_list * args)
377 {
378   u32 i = va_arg (*args, u32);
379   u8 *t = 0;
380
381   switch (i)
382     {
383 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
384       foreach_ipsec_crypto_alg
385 #undef _
386     default:
387       return format (s, "unknown");
388     }
389   return format (s, "%s", t);
390 }
391
392 uword
393 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
394 {
395   u32 *r = va_arg (*args, u32 *);
396
397   if (0);
398 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
399   foreach_ipsec_integ_alg
400 #undef _
401     else
402     return 0;
403   return 1;
404 }
405
406 u8 *
407 format_ipsec_integ_alg (u8 * s, va_list * args)
408 {
409   u32 i = va_arg (*args, u32);
410   u8 *t = 0;
411
412   switch (i)
413     {
414 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
415       foreach_ipsec_integ_alg
416 #undef _
417     default:
418       return format (s, "unknown");
419     }
420   return format (s, "%s", t);
421 }
422
423 uword
424 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
430   foreach_ikev2_auth_method
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436
437 uword
438 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
439 {
440   u32 *r = va_arg (*args, u32 *);
441
442   if (0);
443 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
444   foreach_ikev2_id_type
445 #undef _
446     else
447     return 0;
448   return 1;
449 }
450 #else /* VPP_API_TEST_BUILTIN == 1 */
451 static uword
452 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
453 {
454   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
455   vnet_main_t *vnm = vnet_get_main ();
456   u32 *result = va_arg (*args, u32 *);
457
458   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
459 }
460
461 static uword
462 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
463 {
464   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
465   vnet_main_t *vnm = vnet_get_main ();
466   u32 *result = va_arg (*args, u32 *);
467
468   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
469 }
470
471 #endif /* VPP_API_TEST_BUILTIN */
472
473 static uword
474 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
475 {
476   u8 *r = va_arg (*args, u8 *);
477
478   if (unformat (input, "kbps"))
479     *r = SSE2_QOS_RATE_KBPS;
480   else if (unformat (input, "pps"))
481     *r = SSE2_QOS_RATE_PPS;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_round_type (unformat_input_t * input, va_list * args)
489 {
490   u8 *r = va_arg (*args, u8 *);
491
492   if (unformat (input, "closest"))
493     *r = SSE2_QOS_ROUND_TO_CLOSEST;
494   else if (unformat (input, "up"))
495     *r = SSE2_QOS_ROUND_TO_UP;
496   else if (unformat (input, "down"))
497     *r = SSE2_QOS_ROUND_TO_DOWN;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_type (unformat_input_t * input, va_list * args)
505 {
506   u8 *r = va_arg (*args, u8 *);
507
508   if (unformat (input, "1r2c"))
509     *r = SSE2_QOS_POLICER_TYPE_1R2C;
510   else if (unformat (input, "1r3c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
512   else if (unformat (input, "2r3c-2698"))
513     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
514   else if (unformat (input, "2r3c-4115"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
516   else if (unformat (input, "2r3c-mef5cf1"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
518   else
519     return 0;
520   return 1;
521 }
522
523 static uword
524 unformat_dscp (unformat_input_t * input, va_list * va)
525 {
526   u8 *r = va_arg (*va, u8 *);
527
528   if (0);
529 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
530   foreach_vnet_dscp
531 #undef _
532     else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_action_type (unformat_input_t * input, va_list * va)
539 {
540   sse2_qos_pol_action_params_st *a
541     = va_arg (*va, sse2_qos_pol_action_params_st *);
542
543   if (unformat (input, "drop"))
544     a->action_type = SSE2_QOS_ACTION_DROP;
545   else if (unformat (input, "transmit"))
546     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
547   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
548     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
549   else
550     return 0;
551   return 1;
552 }
553
554 static uword
555 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
556 {
557   u32 *r = va_arg (*va, u32 *);
558   u32 tid;
559
560   if (unformat (input, "ip4"))
561     tid = POLICER_CLASSIFY_TABLE_IP4;
562   else if (unformat (input, "ip6"))
563     tid = POLICER_CLASSIFY_TABLE_IP6;
564   else if (unformat (input, "l2"))
565     tid = POLICER_CLASSIFY_TABLE_L2;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 static uword
574 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
575 {
576   u32 *r = va_arg (*va, u32 *);
577   u32 tid;
578
579   if (unformat (input, "ip4"))
580     tid = FLOW_CLASSIFY_TABLE_IP4;
581   else if (unformat (input, "ip6"))
582     tid = FLOW_CLASSIFY_TABLE_IP6;
583   else
584     return 0;
585
586   *r = tid;
587   return 1;
588 }
589
590 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
591 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
592 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
593 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
594
595 #if (VPP_API_TEST_BUILTIN==0)
596 uword
597 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
598 {
599   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
600   mfib_itf_attribute_t attr;
601
602   old = *iflags;
603   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
604   {
605     if (unformat (input, mfib_itf_flag_long_names[attr]))
606       *iflags |= (1 << attr);
607   }
608   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_itf_flag_names[attr]))
611       *iflags |= (1 << attr);
612   }
613
614   return (old == *iflags ? 0 : 1);
615 }
616
617 uword
618 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
619 {
620   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
621   mfib_entry_attribute_t attr;
622
623   old = *eflags;
624   FOR_EACH_MFIB_ATTRIBUTE (attr)
625   {
626     if (unformat (input, mfib_flag_long_names[attr]))
627       *eflags |= (1 << attr);
628   }
629   FOR_EACH_MFIB_ATTRIBUTE (attr)
630   {
631     if (unformat (input, mfib_flag_names[attr]))
632       *eflags |= (1 << attr);
633   }
634
635   return (old == *eflags ? 0 : 1);
636 }
637
638 u8 *
639 format_ip4_address (u8 * s, va_list * args)
640 {
641   u8 *a = va_arg (*args, u8 *);
642   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
643 }
644
645 u8 *
646 format_ip6_address (u8 * s, va_list * args)
647 {
648   ip6_address_t *a = va_arg (*args, ip6_address_t *);
649   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
650
651   i_max_n_zero = ARRAY_LEN (a->as_u16);
652   max_n_zeros = 0;
653   i_first_zero = i_max_n_zero;
654   n_zeros = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       u32 is_zero = a->as_u16[i] == 0;
658       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
659         {
660           i_first_zero = i;
661           n_zeros = 0;
662         }
663       n_zeros += is_zero;
664       if ((!is_zero && n_zeros > max_n_zeros)
665           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
666         {
667           i_max_n_zero = i_first_zero;
668           max_n_zeros = n_zeros;
669           i_first_zero = ARRAY_LEN (a->as_u16);
670           n_zeros = 0;
671         }
672     }
673
674   last_double_colon = 0;
675   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
676     {
677       if (i == i_max_n_zero && max_n_zeros > 1)
678         {
679           s = format (s, "::");
680           i += max_n_zeros - 1;
681           last_double_colon = 1;
682         }
683       else
684         {
685           s = format (s, "%s%x",
686                       (last_double_colon || i == 0) ? "" : ":",
687                       clib_net_to_host_u16 (a->as_u16[i]));
688           last_double_colon = 0;
689         }
690     }
691
692   return s;
693 }
694
695 /* Format an IP46 address. */
696 u8 *
697 format_ip46_address (u8 * s, va_list * args)
698 {
699   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
700   ip46_type_t type = va_arg (*args, ip46_type_t);
701   int is_ip4 = 1;
702
703   switch (type)
704     {
705     case IP46_TYPE_ANY:
706       is_ip4 = ip46_address_is_ip4 (ip46);
707       break;
708     case IP46_TYPE_IP4:
709       is_ip4 = 1;
710       break;
711     case IP46_TYPE_IP6:
712       is_ip4 = 0;
713       break;
714     }
715
716   return is_ip4 ?
717     format (s, "%U", format_ip4_address, &ip46->ip4) :
718     format (s, "%U", format_ip6_address, &ip46->ip6);
719 }
720
721 u8 *
722 format_ethernet_address (u8 * s, va_list * args)
723 {
724   u8 *a = va_arg (*args, u8 *);
725
726   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
727                  a[0], a[1], a[2], a[3], a[4], a[5]);
728 }
729 #endif
730
731 static void
732 increment_v4_address (ip4_address_t * a)
733 {
734   u32 v;
735
736   v = ntohl (a->as_u32) + 1;
737   a->as_u32 = ntohl (v);
738 }
739
740 static void
741 increment_v6_address (ip6_address_t * a)
742 {
743   u64 v0, v1;
744
745   v0 = clib_net_to_host_u64 (a->as_u64[0]);
746   v1 = clib_net_to_host_u64 (a->as_u64[1]);
747
748   v1 += 1;
749   if (v1 == 0)
750     v0 += 1;
751   a->as_u64[0] = clib_net_to_host_u64 (v0);
752   a->as_u64[1] = clib_net_to_host_u64 (v1);
753 }
754
755 static void
756 increment_mac_address (u8 * mac)
757 {
758   u64 tmp = *((u64 *) mac);
759   tmp = clib_net_to_host_u64 (tmp);
760   tmp += 1 << 16;               /* skip unused (least significant) octets */
761   tmp = clib_host_to_net_u64 (tmp);
762
763   clib_memcpy (mac, &tmp, 6);
764 }
765
766 static void vl_api_create_loopback_reply_t_handler
767   (vl_api_create_loopback_reply_t * mp)
768 {
769   vat_main_t *vam = &vat_main;
770   i32 retval = ntohl (mp->retval);
771
772   vam->retval = retval;
773   vam->regenerate_interface_table = 1;
774   vam->sw_if_index = ntohl (mp->sw_if_index);
775   vam->result_ready = 1;
776 }
777
778 static void vl_api_create_loopback_reply_t_handler_json
779   (vl_api_create_loopback_reply_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t node;
783
784   vat_json_init_object (&node);
785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
787
788   vat_json_print (vam->ofp, &node);
789   vat_json_free (&node);
790   vam->retval = ntohl (mp->retval);
791   vam->result_ready = 1;
792 }
793
794 static void vl_api_create_loopback_instance_reply_t_handler
795   (vl_api_create_loopback_instance_reply_t * mp)
796 {
797   vat_main_t *vam = &vat_main;
798   i32 retval = ntohl (mp->retval);
799
800   vam->retval = retval;
801   vam->regenerate_interface_table = 1;
802   vam->sw_if_index = ntohl (mp->sw_if_index);
803   vam->result_ready = 1;
804 }
805
806 static void vl_api_create_loopback_instance_reply_t_handler_json
807   (vl_api_create_loopback_instance_reply_t * mp)
808 {
809   vat_main_t *vam = &vat_main;
810   vat_json_node_t node;
811
812   vat_json_init_object (&node);
813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
814   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
815
816   vat_json_print (vam->ofp, &node);
817   vat_json_free (&node);
818   vam->retval = ntohl (mp->retval);
819   vam->result_ready = 1;
820 }
821
822 static void vl_api_af_packet_create_reply_t_handler
823   (vl_api_af_packet_create_reply_t * mp)
824 {
825   vat_main_t *vam = &vat_main;
826   i32 retval = ntohl (mp->retval);
827
828   vam->retval = retval;
829   vam->regenerate_interface_table = 1;
830   vam->sw_if_index = ntohl (mp->sw_if_index);
831   vam->result_ready = 1;
832 }
833
834 static void vl_api_af_packet_create_reply_t_handler_json
835   (vl_api_af_packet_create_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   vat_json_node_t node;
839
840   vat_json_init_object (&node);
841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
842   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
843
844   vat_json_print (vam->ofp, &node);
845   vat_json_free (&node);
846
847   vam->retval = ntohl (mp->retval);
848   vam->result_ready = 1;
849 }
850
851 static void vl_api_create_vlan_subif_reply_t_handler
852   (vl_api_create_vlan_subif_reply_t * mp)
853 {
854   vat_main_t *vam = &vat_main;
855   i32 retval = ntohl (mp->retval);
856
857   vam->retval = retval;
858   vam->regenerate_interface_table = 1;
859   vam->sw_if_index = ntohl (mp->sw_if_index);
860   vam->result_ready = 1;
861 }
862
863 static void vl_api_create_vlan_subif_reply_t_handler_json
864   (vl_api_create_vlan_subif_reply_t * mp)
865 {
866   vat_main_t *vam = &vat_main;
867   vat_json_node_t node;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
872
873   vat_json_print (vam->ofp, &node);
874   vat_json_free (&node);
875
876   vam->retval = ntohl (mp->retval);
877   vam->result_ready = 1;
878 }
879
880 static void vl_api_create_subif_reply_t_handler
881   (vl_api_create_subif_reply_t * mp)
882 {
883   vat_main_t *vam = &vat_main;
884   i32 retval = ntohl (mp->retval);
885
886   vam->retval = retval;
887   vam->regenerate_interface_table = 1;
888   vam->sw_if_index = ntohl (mp->sw_if_index);
889   vam->result_ready = 1;
890 }
891
892 static void vl_api_create_subif_reply_t_handler_json
893   (vl_api_create_subif_reply_t * mp)
894 {
895   vat_main_t *vam = &vat_main;
896   vat_json_node_t node;
897
898   vat_json_init_object (&node);
899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 static void vl_api_interface_name_renumber_reply_t_handler
910   (vl_api_interface_name_renumber_reply_t * mp)
911 {
912   vat_main_t *vam = &vat_main;
913   i32 retval = ntohl (mp->retval);
914
915   vam->retval = retval;
916   vam->regenerate_interface_table = 1;
917   vam->result_ready = 1;
918 }
919
920 static void vl_api_interface_name_renumber_reply_t_handler_json
921   (vl_api_interface_name_renumber_reply_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   vat_json_node_t node;
925
926   vat_json_init_object (&node);
927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
928
929   vat_json_print (vam->ofp, &node);
930   vat_json_free (&node);
931
932   vam->retval = ntohl (mp->retval);
933   vam->result_ready = 1;
934 }
935
936 /*
937  * Special-case: build the interface table, maintain
938  * the next loopback sw_if_index vbl.
939  */
940 static void vl_api_sw_interface_details_t_handler
941   (vl_api_sw_interface_details_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   u8 *s = format (0, "%s%c", mp->interface_name, 0);
945
946   hash_set_mem (vam->sw_if_index_by_interface_name, s,
947                 ntohl (mp->sw_if_index));
948
949   /* In sub interface case, fill the sub interface table entry */
950   if (mp->sw_if_index != mp->sup_sw_if_index)
951     {
952       sw_interface_subif_t *sub = NULL;
953
954       vec_add2 (vam->sw_if_subif_table, sub, 1);
955
956       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
957       strncpy ((char *) sub->interface_name, (char *) s,
958                vec_len (sub->interface_name));
959       sub->sw_if_index = ntohl (mp->sw_if_index);
960       sub->sub_id = ntohl (mp->sub_id);
961
962       sub->sub_dot1ad = mp->sub_dot1ad;
963       sub->sub_number_of_tags = mp->sub_number_of_tags;
964       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
965       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
966       sub->sub_exact_match = mp->sub_exact_match;
967       sub->sub_default = mp->sub_default;
968       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
969       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
970
971       /* vlan tag rewrite */
972       sub->vtr_op = ntohl (mp->vtr_op);
973       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
974       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
975       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
976     }
977 }
978
979 static void vl_api_sw_interface_details_t_handler_json
980   (vl_api_sw_interface_details_t * mp)
981 {
982   vat_main_t *vam = &vat_main;
983   vat_json_node_t *node = NULL;
984
985   if (VAT_JSON_ARRAY != vam->json_tree.type)
986     {
987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
988       vat_json_init_array (&vam->json_tree);
989     }
990   node = vat_json_array_add (&vam->json_tree);
991
992   vat_json_init_object (node);
993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
994   vat_json_object_add_uint (node, "sup_sw_if_index",
995                             ntohl (mp->sup_sw_if_index));
996   vat_json_object_add_uint (node, "l2_address_length",
997                             ntohl (mp->l2_address_length));
998   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
999                              sizeof (mp->l2_address));
1000   vat_json_object_add_string_copy (node, "interface_name",
1001                                    mp->interface_name);
1002   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1003   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1004   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1005   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1006   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1007   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1008   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1009   vat_json_object_add_uint (node, "sub_number_of_tags",
1010                             mp->sub_number_of_tags);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1012                             ntohs (mp->sub_outer_vlan_id));
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1014                             ntohs (mp->sub_inner_vlan_id));
1015   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1016   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1017   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1018                             mp->sub_outer_vlan_id_any);
1019   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1020                             mp->sub_inner_vlan_id_any);
1021   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1022   vat_json_object_add_uint (node, "vtr_push_dot1q",
1023                             ntohl (mp->vtr_push_dot1q));
1024   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1025   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1026   if (mp->sub_dot1ah)
1027     {
1028       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1029                                        format (0, "%U",
1030                                                format_ethernet_address,
1031                                                &mp->b_dmac));
1032       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1033                                        format (0, "%U",
1034                                                format_ethernet_address,
1035                                                &mp->b_smac));
1036       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1037       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1038     }
1039 }
1040
1041 #if VPP_API_TEST_BUILTIN == 0
1042 static void vl_api_sw_interface_event_t_handler
1043   (vl_api_sw_interface_event_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   if (vam->interface_event_display)
1047     errmsg ("interface flags: sw_if_index %d %s %s",
1048             ntohl (mp->sw_if_index),
1049             mp->admin_up_down ? "admin-up" : "admin-down",
1050             mp->link_up_down ? "link-up" : "link-down");
1051 }
1052 #endif
1053
1054 static void vl_api_sw_interface_event_t_handler_json
1055   (vl_api_sw_interface_event_t * mp)
1056 {
1057   /* JSON output not supported */
1058 }
1059
1060 static void
1061 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   i32 retval = ntohl (mp->retval);
1065
1066   vam->retval = retval;
1067   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vam->result_ready = 1;
1069 }
1070
1071 static void
1072 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1073 {
1074   vat_main_t *vam = &vat_main;
1075   vat_json_node_t node;
1076   api_main_t *am = &api_main;
1077   void *oldheap;
1078   u8 *reply;
1079
1080   vat_json_init_object (&node);
1081   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1082   vat_json_object_add_uint (&node, "reply_in_shmem",
1083                             ntohl (mp->reply_in_shmem));
1084   /* Toss the shared-memory original... */
1085   pthread_mutex_lock (&am->vlib_rp->mutex);
1086   oldheap = svm_push_data_heap (am->vlib_rp);
1087
1088   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1089   vec_free (reply);
1090
1091   svm_pop_heap (oldheap);
1092   pthread_mutex_unlock (&am->vlib_rp->mutex);
1093
1094   vat_json_print (vam->ofp, &node);
1095   vat_json_free (&node);
1096
1097   vam->retval = ntohl (mp->retval);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   i32 retval = ntohl (mp->retval);
1106   u32 length = vl_api_string_len (&mp->reply);
1107
1108   vec_reset_length (vam->cmd_reply);
1109
1110   vam->retval = retval;
1111   if (retval == 0)
1112     {
1113       vec_validate (vam->cmd_reply, length);
1114       clib_memcpy ((char *) (vam->cmd_reply),
1115                    vl_api_from_api_string (&mp->reply), length);
1116       vam->cmd_reply[length] = 0;
1117     }
1118   vam->result_ready = 1;
1119 }
1120
1121 static void
1122 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   vat_json_node_t node;
1126
1127   vec_reset_length (vam->cmd_reply);
1128
1129   vat_json_init_object (&node);
1130   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1131   vat_json_object_add_string_copy (&node, "reply",
1132                                    vl_api_from_api_string (&mp->reply));
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       char *s;
1304       char *p = (char *) &mp->program;
1305
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        program: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("        version: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("     build date: %s\n", s);
1320       free (s);
1321
1322       p +=
1323         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1324       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1325       errmsg ("build directory: %s\n", s);
1326       free (s);
1327     }
1328   vam->retval = retval;
1329   vam->result_ready = 1;
1330 }
1331
1332 static void vl_api_show_version_reply_t_handler_json
1333   (vl_api_show_version_reply_t * mp)
1334 {
1335   vat_main_t *vam = &vat_main;
1336   vat_json_node_t node;
1337
1338   vat_json_init_object (&node);
1339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1340   char *p = (char *) &mp->program;
1341   vat_json_object_add_string_copy (&node, "program",
1342                                    vl_api_from_api_string ((vl_api_string_t *)
1343                                                            p));
1344   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1345   vat_json_object_add_string_copy (&node, "version",
1346                                    vl_api_from_api_string ((vl_api_string_t *)
1347                                                            p));
1348   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1349   vat_json_object_add_string_copy (&node, "build_date",
1350                                    vl_api_from_api_string ((vl_api_string_t *)
1351                                                            p));
1352   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1353   vat_json_object_add_string_copy (&node, "build_directory",
1354                                    vl_api_from_api_string ((vl_api_string_t *)
1355                                                            p));
1356
1357   vat_json_print (vam->ofp, &node);
1358   vat_json_free (&node);
1359
1360   vam->retval = ntohl (mp->retval);
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_threads_reply_t_handler
1365   (vl_api_show_threads_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   i32 retval = ntohl (mp->retval);
1369   int i, count = 0;
1370
1371   if (retval >= 0)
1372     count = ntohl (mp->count);
1373
1374   for (i = 0; i < count; i++)
1375     print (vam->ofp,
1376            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1377            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1378            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1379            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1380            ntohl (mp->thread_data[i].cpu_socket));
1381
1382   vam->retval = retval;
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler_json
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391   vl_api_thread_data_t *td;
1392   i32 retval = ntohl (mp->retval);
1393   int i, count = 0;
1394
1395   if (retval >= 0)
1396     count = ntohl (mp->count);
1397
1398   vat_json_init_object (&node);
1399   vat_json_object_add_int (&node, "retval", retval);
1400   vat_json_object_add_uint (&node, "count", count);
1401
1402   for (i = 0; i < count; i++)
1403     {
1404       td = &mp->thread_data[i];
1405       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1406       vat_json_object_add_string_copy (&node, "name", td->name);
1407       vat_json_object_add_string_copy (&node, "type", td->type);
1408       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1409       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1410       vat_json_object_add_int (&node, "core", ntohl (td->id));
1411       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1412     }
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static int
1422 api_show_threads (vat_main_t * vam)
1423 {
1424   vl_api_show_threads_t *mp;
1425   int ret;
1426
1427   print (vam->ofp,
1428          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1429          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1430
1431   M (SHOW_THREADS, mp);
1432
1433   S (mp);
1434   W (ret);
1435   return ret;
1436 }
1437
1438 static void
1439 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1440 {
1441   u32 sw_if_index = ntohl (mp->sw_if_index);
1442   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1443           mp->mac_ip ? "mac/ip binding" : "address resolution",
1444           ntohl (mp->pid), format_ip4_address, &mp->address,
1445           format_ethernet_address, mp->new_mac, sw_if_index);
1446 }
1447
1448 static void
1449 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1450 {
1451   /* JSON output not supported */
1452 }
1453
1454 static void
1455 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1456 {
1457   u32 sw_if_index = ntohl (mp->sw_if_index);
1458   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1459           mp->mac_ip ? "mac/ip binding" : "address resolution",
1460           ntohl (mp->pid), format_ip6_address, mp->address,
1461           format_ethernet_address, mp->new_mac, sw_if_index);
1462 }
1463
1464 static void
1465 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1466 {
1467   /* JSON output not supported */
1468 }
1469
1470 static void
1471 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1472 {
1473   u32 n_macs = ntohl (mp->n_macs);
1474   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1475           ntohl (mp->pid), mp->client_index, n_macs);
1476   int i;
1477   for (i = 0; i < n_macs; i++)
1478     {
1479       vl_api_mac_entry_t *mac = &mp->mac[i];
1480       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1481               i + 1, ntohl (mac->sw_if_index),
1482               format_ethernet_address, mac->mac_addr, mac->action);
1483       if (i == 1000)
1484         break;
1485     }
1486 }
1487
1488 static void
1489 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1490 {
1491   /* JSON output not supported */
1492 }
1493
1494 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1495 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1496
1497 /*
1498  * Special-case: build the bridge domain table, maintain
1499  * the next bd id vbl.
1500  */
1501 static void vl_api_bridge_domain_details_t_handler
1502   (vl_api_bridge_domain_details_t * mp)
1503 {
1504   vat_main_t *vam = &vat_main;
1505   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1506   int i;
1507
1508   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1509          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1510
1511   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1512          ntohl (mp->bd_id), mp->learn, mp->forward,
1513          mp->flood, ntohl (mp->bvi_sw_if_index),
1514          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1515
1516   if (n_sw_ifs)
1517     {
1518       vl_api_bridge_domain_sw_if_t *sw_ifs;
1519       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1520              "Interface Name");
1521
1522       sw_ifs = mp->sw_if_details;
1523       for (i = 0; i < n_sw_ifs; i++)
1524         {
1525           u8 *sw_if_name = 0;
1526           u32 sw_if_index;
1527           hash_pair_t *p;
1528
1529           sw_if_index = ntohl (sw_ifs->sw_if_index);
1530
1531           /* *INDENT-OFF* */
1532           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1533                              ({
1534                                if ((u32) p->value[0] == sw_if_index)
1535                                  {
1536                                    sw_if_name = (u8 *)(p->key);
1537                                    break;
1538                                  }
1539                              }));
1540           /* *INDENT-ON* */
1541           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1542                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1543                  "sw_if_index not found!");
1544
1545           sw_ifs++;
1546         }
1547     }
1548 }
1549
1550 static void vl_api_bridge_domain_details_t_handler_json
1551   (vl_api_bridge_domain_details_t * mp)
1552 {
1553   vat_main_t *vam = &vat_main;
1554   vat_json_node_t *node, *array = NULL;
1555   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1556
1557   if (VAT_JSON_ARRAY != vam->json_tree.type)
1558     {
1559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1560       vat_json_init_array (&vam->json_tree);
1561     }
1562   node = vat_json_array_add (&vam->json_tree);
1563
1564   vat_json_init_object (node);
1565   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1566   vat_json_object_add_uint (node, "flood", mp->flood);
1567   vat_json_object_add_uint (node, "forward", mp->forward);
1568   vat_json_object_add_uint (node, "learn", mp->learn);
1569   vat_json_object_add_uint (node, "bvi_sw_if_index",
1570                             ntohl (mp->bvi_sw_if_index));
1571   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1572   array = vat_json_object_add (node, "sw_if");
1573   vat_json_init_array (array);
1574
1575
1576
1577   if (n_sw_ifs)
1578     {
1579       vl_api_bridge_domain_sw_if_t *sw_ifs;
1580       int i;
1581
1582       sw_ifs = mp->sw_if_details;
1583       for (i = 0; i < n_sw_ifs; i++)
1584         {
1585           node = vat_json_array_add (array);
1586           vat_json_init_object (node);
1587           vat_json_object_add_uint (node, "sw_if_index",
1588                                     ntohl (sw_ifs->sw_if_index));
1589           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1590           sw_ifs++;
1591         }
1592     }
1593 }
1594
1595 static void vl_api_control_ping_reply_t_handler
1596   (vl_api_control_ping_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->result_ready = 1;
1608     }
1609   if (vam->socket_client_main)
1610     vam->socket_client_main->control_pings_outstanding--;
1611 }
1612
1613 static void vl_api_control_ping_reply_t_handler_json
1614   (vl_api_control_ping_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618
1619   if (VAT_JSON_NONE != vam->json_tree.type)
1620     {
1621       vat_json_print (vam->ofp, &vam->json_tree);
1622       vat_json_free (&vam->json_tree);
1623       vam->json_tree.type = VAT_JSON_NONE;
1624     }
1625   else
1626     {
1627       /* just print [] */
1628       vat_json_init_array (&vam->json_tree);
1629       vat_json_print (vam->ofp, &vam->json_tree);
1630       vam->json_tree.type = VAT_JSON_NONE;
1631     }
1632
1633   vam->retval = retval;
1634   vam->result_ready = 1;
1635 }
1636
1637 static void
1638   vl_api_bridge_domain_set_mac_age_reply_t_handler
1639   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1640 {
1641   vat_main_t *vam = &vat_main;
1642   i32 retval = ntohl (mp->retval);
1643   if (vam->async_mode)
1644     {
1645       vam->async_errors += (retval < 0);
1646     }
1647   else
1648     {
1649       vam->retval = retval;
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1655   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662
1663   vat_json_print (vam->ofp, &node);
1664   vat_json_free (&node);
1665
1666   vam->retval = ntohl (mp->retval);
1667   vam->result_ready = 1;
1668 }
1669
1670 static void
1671 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   i32 retval = ntohl (mp->retval);
1675   if (vam->async_mode)
1676     {
1677       vam->async_errors += (retval < 0);
1678     }
1679   else
1680     {
1681       vam->retval = retval;
1682       vam->result_ready = 1;
1683     }
1684 }
1685
1686 static void vl_api_l2_flags_reply_t_handler_json
1687   (vl_api_l2_flags_reply_t * mp)
1688 {
1689   vat_main_t *vam = &vat_main;
1690   vat_json_node_t node;
1691
1692   vat_json_init_object (&node);
1693   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1694   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1695                             ntohl (mp->resulting_feature_bitmap));
1696
1697   vat_json_print (vam->ofp, &node);
1698   vat_json_free (&node);
1699
1700   vam->retval = ntohl (mp->retval);
1701   vam->result_ready = 1;
1702 }
1703
1704 static void vl_api_bridge_flags_reply_t_handler
1705   (vl_api_bridge_flags_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   i32 retval = ntohl (mp->retval);
1709   if (vam->async_mode)
1710     {
1711       vam->async_errors += (retval < 0);
1712     }
1713   else
1714     {
1715       vam->retval = retval;
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_bridge_flags_reply_t_handler_json
1721   (vl_api_bridge_flags_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1729                             ntohl (mp->resulting_feature_bitmap));
1730
1731   vat_json_print (vam->ofp, &node);
1732   vat_json_free (&node);
1733
1734   vam->retval = ntohl (mp->retval);
1735   vam->result_ready = 1;
1736 }
1737
1738 static void vl_api_tap_connect_reply_t_handler
1739   (vl_api_tap_connect_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   i32 retval = ntohl (mp->retval);
1743   if (vam->async_mode)
1744     {
1745       vam->async_errors += (retval < 0);
1746     }
1747   else
1748     {
1749       vam->retval = retval;
1750       vam->sw_if_index = ntohl (mp->sw_if_index);
1751       vam->result_ready = 1;
1752     }
1753
1754 }
1755
1756 static void vl_api_tap_connect_reply_t_handler_json
1757   (vl_api_tap_connect_reply_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   vat_json_node_t node;
1761
1762   vat_json_init_object (&node);
1763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1765
1766   vat_json_print (vam->ofp, &node);
1767   vat_json_free (&node);
1768
1769   vam->retval = ntohl (mp->retval);
1770   vam->result_ready = 1;
1771
1772 }
1773
1774 static void
1775 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1776 {
1777   vat_main_t *vam = &vat_main;
1778   i32 retval = ntohl (mp->retval);
1779   if (vam->async_mode)
1780     {
1781       vam->async_errors += (retval < 0);
1782     }
1783   else
1784     {
1785       vam->retval = retval;
1786       vam->sw_if_index = ntohl (mp->sw_if_index);
1787       vam->result_ready = 1;
1788     }
1789 }
1790
1791 static void vl_api_tap_modify_reply_t_handler_json
1792   (vl_api_tap_modify_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   vat_json_node_t node;
1796
1797   vat_json_init_object (&node);
1798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1799   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1800
1801   vat_json_print (vam->ofp, &node);
1802   vat_json_free (&node);
1803
1804   vam->retval = ntohl (mp->retval);
1805   vam->result_ready = 1;
1806 }
1807
1808 static void
1809 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   i32 retval = ntohl (mp->retval);
1813   if (vam->async_mode)
1814     {
1815       vam->async_errors += (retval < 0);
1816     }
1817   else
1818     {
1819       vam->retval = retval;
1820       vam->result_ready = 1;
1821     }
1822 }
1823
1824 static void vl_api_tap_delete_reply_t_handler_json
1825   (vl_api_tap_delete_reply_t * mp)
1826 {
1827   vat_main_t *vam = &vat_main;
1828   vat_json_node_t node;
1829
1830   vat_json_init_object (&node);
1831   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1832
1833   vat_json_print (vam->ofp, &node);
1834   vat_json_free (&node);
1835
1836   vam->retval = ntohl (mp->retval);
1837   vam->result_ready = 1;
1838 }
1839
1840 static void
1841 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845   if (vam->async_mode)
1846     {
1847       vam->async_errors += (retval < 0);
1848     }
1849   else
1850     {
1851       vam->retval = retval;
1852       vam->sw_if_index = ntohl (mp->sw_if_index);
1853       vam->result_ready = 1;
1854     }
1855
1856 }
1857
1858 static void vl_api_tap_create_v2_reply_t_handler_json
1859   (vl_api_tap_create_v2_reply_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   vat_json_node_t node;
1863
1864   vat_json_init_object (&node);
1865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1867
1868   vat_json_print (vam->ofp, &node);
1869   vat_json_free (&node);
1870
1871   vam->retval = ntohl (mp->retval);
1872   vam->result_ready = 1;
1873
1874 }
1875
1876 static void
1877 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_tap_delete_v2_reply_t_handler_json
1893   (vl_api_tap_delete_v2_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   i32 retval = ntohl (mp->retval);
1913
1914   if (vam->async_mode)
1915     {
1916       vam->async_errors += (retval < 0);
1917     }
1918   else
1919     {
1920       vam->retval = retval;
1921       vam->sw_if_index = ntohl (mp->sw_if_index);
1922       vam->result_ready = 1;
1923     }
1924 }
1925
1926 static void vl_api_bond_create_reply_t_handler_json
1927   (vl_api_bond_create_reply_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t node;
1931
1932   vat_json_init_object (&node);
1933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1934   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1935
1936   vat_json_print (vam->ofp, &node);
1937   vat_json_free (&node);
1938
1939   vam->retval = ntohl (mp->retval);
1940   vam->result_ready = 1;
1941 }
1942
1943 static void
1944 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1945 {
1946   vat_main_t *vam = &vat_main;
1947   i32 retval = ntohl (mp->retval);
1948
1949   if (vam->async_mode)
1950     {
1951       vam->async_errors += (retval < 0);
1952     }
1953   else
1954     {
1955       vam->retval = retval;
1956       vam->result_ready = 1;
1957     }
1958 }
1959
1960 static void vl_api_bond_delete_reply_t_handler_json
1961   (vl_api_bond_delete_reply_t * mp)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   vat_json_node_t node;
1965
1966   vat_json_init_object (&node);
1967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1968
1969   vat_json_print (vam->ofp, &node);
1970   vat_json_free (&node);
1971
1972   vam->retval = ntohl (mp->retval);
1973   vam->result_ready = 1;
1974 }
1975
1976 static void
1977 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   i32 retval = ntohl (mp->retval);
1981
1982   if (vam->async_mode)
1983     {
1984       vam->async_errors += (retval < 0);
1985     }
1986   else
1987     {
1988       vam->retval = retval;
1989       vam->result_ready = 1;
1990     }
1991 }
1992
1993 static void vl_api_bond_enslave_reply_t_handler_json
1994   (vl_api_bond_enslave_reply_t * mp)
1995 {
1996   vat_main_t *vam = &vat_main;
1997   vat_json_node_t node;
1998
1999   vat_json_init_object (&node);
2000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2001
2002   vat_json_print (vam->ofp, &node);
2003   vat_json_free (&node);
2004
2005   vam->retval = ntohl (mp->retval);
2006   vam->result_ready = 1;
2007 }
2008
2009 static void
2010 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2011                                           mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014   i32 retval = ntohl (mp->retval);
2015
2016   if (vam->async_mode)
2017     {
2018       vam->async_errors += (retval < 0);
2019     }
2020   else
2021     {
2022       vam->retval = retval;
2023       vam->result_ready = 1;
2024     }
2025 }
2026
2027 static void vl_api_bond_detach_slave_reply_t_handler_json
2028   (vl_api_bond_detach_slave_reply_t * mp)
2029 {
2030   vat_main_t *vam = &vat_main;
2031   vat_json_node_t node;
2032
2033   vat_json_init_object (&node);
2034   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2035
2036   vat_json_print (vam->ofp, &node);
2037   vat_json_free (&node);
2038
2039   vam->retval = ntohl (mp->retval);
2040   vam->result_ready = 1;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2052          ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", mp->mode);
2073   vat_json_object_add_uint (node, "load_balance", mp->lb);
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-12d %d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2110 }
2111
2112 static void vl_api_sw_interface_slave_details_t_handler_json
2113   (vl_api_sw_interface_slave_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t *node = NULL;
2117
2118   if (VAT_JSON_ARRAY != vam->json_tree.type)
2119     {
2120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2121       vat_json_init_array (&vam->json_tree);
2122     }
2123   node = vat_json_array_add (&vam->json_tree);
2124
2125   vat_json_init_object (node);
2126   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2127   vat_json_object_add_string_copy (node, "interface_name",
2128                                    mp->interface_name);
2129   vat_json_object_add_uint (node, "passive", mp->is_passive);
2130   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2131 }
2132
2133 static int
2134 api_sw_interface_slave_dump (vat_main_t * vam)
2135 {
2136   unformat_input_t *i = vam->input;
2137   vl_api_sw_interface_slave_dump_t *mp;
2138   vl_api_control_ping_t *mp_ping;
2139   u32 sw_if_index = ~0;
2140   u8 sw_if_index_set = 0;
2141   int ret;
2142
2143   /* Parse args required to build the message */
2144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145     {
2146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147         sw_if_index_set = 1;
2148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2149         sw_if_index_set = 1;
2150       else
2151         break;
2152     }
2153
2154   if (sw_if_index_set == 0)
2155     {
2156       errmsg ("missing vpp interface name. ");
2157       return -99;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-25s %-12s %-12s %s",
2162          "slave interface name", "sw_if_index", "passive", "long_timeout");
2163
2164   /* Get list of bond interfaces */
2165   M (SW_INTERFACE_SLAVE_DUMP, mp);
2166   mp->sw_if_index = ntohl (sw_if_index);
2167   S (mp);
2168
2169   /* Use a control ping for synchronization */
2170   MPING (CONTROL_PING, mp_ping);
2171   S (mp_ping);
2172
2173   W (ret);
2174   return ret;
2175 }
2176
2177 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2178   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2179 {
2180   vat_main_t *vam = &vat_main;
2181   i32 retval = ntohl (mp->retval);
2182   if (vam->async_mode)
2183     {
2184       vam->async_errors += (retval < 0);
2185     }
2186   else
2187     {
2188       vam->retval = retval;
2189       vam->sw_if_index = ntohl (mp->sw_if_index);
2190       vam->result_ready = 1;
2191     }
2192   vam->regenerate_interface_table = 1;
2193 }
2194
2195 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2196   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t node;
2200
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2204                             ntohl (mp->sw_if_index));
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2214   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   i32 retval = ntohl (mp->retval);
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->sw_if_index = ntohl (mp->sw_if_index);
2226       vam->result_ready = 1;
2227     }
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vat_json_node_t node;
2235
2236   vat_json_init_object (&node);
2237   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2238   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2248   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   i32 retval = ntohl (mp->retval);
2252   if (vam->async_mode)
2253     {
2254       vam->async_errors += (retval < 0);
2255     }
2256   else
2257     {
2258       vam->retval = retval;
2259       vam->result_ready = 1;
2260     }
2261 }
2262
2263 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2264   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   vat_json_node_t node;
2268
2269   vat_json_init_object (&node);
2270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2271   vat_json_object_add_uint (&node, "fwd_entry_index",
2272                             clib_net_to_host_u32 (mp->fwd_entry_index));
2273
2274   vat_json_print (vam->ofp, &node);
2275   vat_json_free (&node);
2276
2277   vam->retval = ntohl (mp->retval);
2278   vam->result_ready = 1;
2279 }
2280
2281 u8 *
2282 format_lisp_transport_protocol (u8 * s, va_list * args)
2283 {
2284   u32 proto = va_arg (*args, u32);
2285
2286   switch (proto)
2287     {
2288     case 1:
2289       return format (s, "udp");
2290     case 2:
2291       return format (s, "api");
2292     default:
2293       return 0;
2294     }
2295   return 0;
2296 }
2297
2298 static void vl_api_one_get_transport_protocol_reply_t_handler
2299   (vl_api_one_get_transport_protocol_reply_t * mp)
2300 {
2301   vat_main_t *vam = &vat_main;
2302   i32 retval = ntohl (mp->retval);
2303   if (vam->async_mode)
2304     {
2305       vam->async_errors += (retval < 0);
2306     }
2307   else
2308     {
2309       u32 proto = mp->protocol;
2310       print (vam->ofp, "Transport protocol: %U",
2311              format_lisp_transport_protocol, proto);
2312       vam->retval = retval;
2313       vam->result_ready = 1;
2314     }
2315 }
2316
2317 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2318   (vl_api_one_get_transport_protocol_reply_t * mp)
2319 {
2320   vat_main_t *vam = &vat_main;
2321   vat_json_node_t node;
2322   u8 *s;
2323
2324   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2325   vec_add1 (s, 0);
2326
2327   vat_json_init_object (&node);
2328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2329   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2330
2331   vec_free (s);
2332   vat_json_print (vam->ofp, &node);
2333   vat_json_free (&node);
2334
2335   vam->retval = ntohl (mp->retval);
2336   vam->result_ready = 1;
2337 }
2338
2339 static void vl_api_one_add_del_locator_set_reply_t_handler
2340   (vl_api_one_add_del_locator_set_reply_t * mp)
2341 {
2342   vat_main_t *vam = &vat_main;
2343   i32 retval = ntohl (mp->retval);
2344   if (vam->async_mode)
2345     {
2346       vam->async_errors += (retval < 0);
2347     }
2348   else
2349     {
2350       vam->retval = retval;
2351       vam->result_ready = 1;
2352     }
2353 }
2354
2355 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2356   (vl_api_one_add_del_locator_set_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   vat_json_node_t node;
2360
2361   vat_json_init_object (&node);
2362   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2363   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2364
2365   vat_json_print (vam->ofp, &node);
2366   vat_json_free (&node);
2367
2368   vam->retval = ntohl (mp->retval);
2369   vam->result_ready = 1;
2370 }
2371
2372 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2373   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   i32 retval = ntohl (mp->retval);
2377   if (vam->async_mode)
2378     {
2379       vam->async_errors += (retval < 0);
2380     }
2381   else
2382     {
2383       vam->retval = retval;
2384       vam->sw_if_index = ntohl (mp->sw_if_index);
2385       vam->result_ready = 1;
2386     }
2387   vam->regenerate_interface_table = 1;
2388 }
2389
2390 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2391   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   vat_json_node_t node;
2395
2396   vat_json_init_object (&node);
2397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2398   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2399
2400   vat_json_print (vam->ofp, &node);
2401   vat_json_free (&node);
2402
2403   vam->retval = ntohl (mp->retval);
2404   vam->result_ready = 1;
2405 }
2406
2407 static void vl_api_vxlan_offload_rx_reply_t_handler
2408   (vl_api_vxlan_offload_rx_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   i32 retval = ntohl (mp->retval);
2412   if (vam->async_mode)
2413     {
2414       vam->async_errors += (retval < 0);
2415     }
2416   else
2417     {
2418       vam->retval = retval;
2419       vam->result_ready = 1;
2420     }
2421 }
2422
2423 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2424   (vl_api_vxlan_offload_rx_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   vat_json_node_t node;
2428
2429   vat_json_init_object (&node);
2430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2431
2432   vat_json_print (vam->ofp, &node);
2433   vat_json_free (&node);
2434
2435   vam->retval = ntohl (mp->retval);
2436   vam->result_ready = 1;
2437 }
2438
2439 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2440   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   i32 retval = ntohl (mp->retval);
2444   if (vam->async_mode)
2445     {
2446       vam->async_errors += (retval < 0);
2447     }
2448   else
2449     {
2450       vam->retval = retval;
2451       vam->sw_if_index = ntohl (mp->sw_if_index);
2452       vam->result_ready = 1;
2453     }
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t node;
2461
2462   vat_json_init_object (&node);
2463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2465
2466   vat_json_print (vam->ofp, &node);
2467   vat_json_free (&node);
2468
2469   vam->retval = ntohl (mp->retval);
2470   vam->result_ready = 1;
2471 }
2472
2473 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2474   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   i32 retval = ntohl (mp->retval);
2478   if (vam->async_mode)
2479     {
2480       vam->async_errors += (retval < 0);
2481     }
2482   else
2483     {
2484       vam->retval = retval;
2485       vam->sw_if_index = ntohl (mp->sw_if_index);
2486       vam->result_ready = 1;
2487     }
2488   vam->regenerate_interface_table = 1;
2489 }
2490
2491 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2492   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   vat_json_node_t node;
2496
2497   vat_json_init_object (&node);
2498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2499   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_gre_add_del_tunnel_reply_t_handler
2509   (vl_api_gre_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   i32 retval = ntohl (mp->retval);
2513   if (vam->async_mode)
2514     {
2515       vam->async_errors += (retval < 0);
2516     }
2517   else
2518     {
2519       vam->retval = retval;
2520       vam->sw_if_index = ntohl (mp->sw_if_index);
2521       vam->result_ready = 1;
2522     }
2523 }
2524
2525 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2526   (vl_api_gre_add_del_tunnel_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t node;
2530
2531   vat_json_init_object (&node);
2532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2533   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2534
2535   vat_json_print (vam->ofp, &node);
2536   vat_json_free (&node);
2537
2538   vam->retval = ntohl (mp->retval);
2539   vam->result_ready = 1;
2540 }
2541
2542 static void vl_api_create_vhost_user_if_reply_t_handler
2543   (vl_api_create_vhost_user_if_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   i32 retval = ntohl (mp->retval);
2547   if (vam->async_mode)
2548     {
2549       vam->async_errors += (retval < 0);
2550     }
2551   else
2552     {
2553       vam->retval = retval;
2554       vam->sw_if_index = ntohl (mp->sw_if_index);
2555       vam->result_ready = 1;
2556     }
2557   vam->regenerate_interface_table = 1;
2558 }
2559
2560 static void vl_api_create_vhost_user_if_reply_t_handler_json
2561   (vl_api_create_vhost_user_if_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   vat_json_node_t node;
2565
2566   vat_json_init_object (&node);
2567   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2568   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2569
2570   vat_json_print (vam->ofp, &node);
2571   vat_json_free (&node);
2572
2573   vam->retval = ntohl (mp->retval);
2574   vam->result_ready = 1;
2575 }
2576
2577 static void vl_api_dns_resolve_name_reply_t_handler
2578   (vl_api_dns_resolve_name_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   i32 retval = ntohl (mp->retval);
2582   if (vam->async_mode)
2583     {
2584       vam->async_errors += (retval < 0);
2585     }
2586   else
2587     {
2588       vam->retval = retval;
2589       vam->result_ready = 1;
2590
2591       if (retval == 0)
2592         {
2593           if (mp->ip4_set)
2594             clib_warning ("ip4 address %U", format_ip4_address,
2595                           (ip4_address_t *) mp->ip4_address);
2596           if (mp->ip6_set)
2597             clib_warning ("ip6 address %U", format_ip6_address,
2598                           (ip6_address_t *) mp->ip6_address);
2599         }
2600       else
2601         clib_warning ("retval %d", retval);
2602     }
2603 }
2604
2605 static void vl_api_dns_resolve_name_reply_t_handler_json
2606   (vl_api_dns_resolve_name_reply_t * mp)
2607 {
2608   clib_warning ("not implemented");
2609 }
2610
2611 static void vl_api_dns_resolve_ip_reply_t_handler
2612   (vl_api_dns_resolve_ip_reply_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   i32 retval = ntohl (mp->retval);
2616   if (vam->async_mode)
2617     {
2618       vam->async_errors += (retval < 0);
2619     }
2620   else
2621     {
2622       vam->retval = retval;
2623       vam->result_ready = 1;
2624
2625       if (retval == 0)
2626         {
2627           clib_warning ("canonical name %s", mp->name);
2628         }
2629       else
2630         clib_warning ("retval %d", retval);
2631     }
2632 }
2633
2634 static void vl_api_dns_resolve_ip_reply_t_handler_json
2635   (vl_api_dns_resolve_ip_reply_t * mp)
2636 {
2637   clib_warning ("not implemented");
2638 }
2639
2640
2641 static void vl_api_ip_address_details_t_handler
2642   (vl_api_ip_address_details_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   static ip_address_details_t empty_ip_address_details = { {0} };
2646   ip_address_details_t *address = NULL;
2647   ip_details_t *current_ip_details = NULL;
2648   ip_details_t *details = NULL;
2649
2650   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2651
2652   if (!details || vam->current_sw_if_index >= vec_len (details)
2653       || !details[vam->current_sw_if_index].present)
2654     {
2655       errmsg ("ip address details arrived but not stored");
2656       errmsg ("ip_dump should be called first");
2657       return;
2658     }
2659
2660   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2661
2662 #define addresses (current_ip_details->addr)
2663
2664   vec_validate_init_empty (addresses, vec_len (addresses),
2665                            empty_ip_address_details);
2666
2667   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2668
2669   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2670   address->prefix_length = mp->prefix_length;
2671 #undef addresses
2672 }
2673
2674 static void vl_api_ip_address_details_t_handler_json
2675   (vl_api_ip_address_details_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   vat_json_node_t *node = NULL;
2679   struct in6_addr ip6;
2680   struct in_addr ip4;
2681
2682   if (VAT_JSON_ARRAY != vam->json_tree.type)
2683     {
2684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2685       vat_json_init_array (&vam->json_tree);
2686     }
2687   node = vat_json_array_add (&vam->json_tree);
2688
2689   vat_json_init_object (node);
2690   if (vam->is_ipv6)
2691     {
2692       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2693       vat_json_object_add_ip6 (node, "ip", ip6);
2694     }
2695   else
2696     {
2697       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2698       vat_json_object_add_ip4 (node, "ip", ip4);
2699     }
2700   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2701 }
2702
2703 static void
2704 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   static ip_details_t empty_ip_details = { 0 };
2708   ip_details_t *ip = NULL;
2709   u32 sw_if_index = ~0;
2710
2711   sw_if_index = ntohl (mp->sw_if_index);
2712
2713   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2714                            sw_if_index, empty_ip_details);
2715
2716   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2717                          sw_if_index);
2718
2719   ip->present = 1;
2720 }
2721
2722 static void
2723 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2724 {
2725   vat_main_t *vam = &vat_main;
2726
2727   if (VAT_JSON_ARRAY != vam->json_tree.type)
2728     {
2729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2730       vat_json_init_array (&vam->json_tree);
2731     }
2732   vat_json_array_add_uint (&vam->json_tree,
2733                            clib_net_to_host_u32 (mp->sw_if_index));
2734 }
2735
2736 static void
2737 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2738 {
2739   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2740           "router_addr %U host_mac %U",
2741           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2742           mp->lease.hostname,
2743           format_ip4_address, &mp->lease.host_address,
2744           format_ip4_address, &mp->lease.router_address,
2745           format_ethernet_address, mp->lease.host_mac);
2746 }
2747
2748 static void vl_api_dhcp_compl_event_t_handler_json
2749   (vl_api_dhcp_compl_event_t * mp)
2750 {
2751   /* JSON output not supported */
2752 }
2753
2754 static void vl_api_get_first_msg_id_reply_t_handler
2755   (vl_api_get_first_msg_id_reply_t * mp)
2756 {
2757   vat_main_t *vam = &vat_main;
2758   i32 retval = ntohl (mp->retval);
2759
2760   if (vam->async_mode)
2761     {
2762       vam->async_errors += (retval < 0);
2763     }
2764   else
2765     {
2766       vam->retval = retval;
2767       vam->result_ready = 1;
2768     }
2769   if (retval >= 0)
2770     {
2771       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2772     }
2773 }
2774
2775 static void vl_api_get_first_msg_id_reply_t_handler_json
2776   (vl_api_get_first_msg_id_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780
2781   vat_json_init_object (&node);
2782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2783   vat_json_object_add_uint (&node, "first_msg_id",
2784                             (uint) ntohs (mp->first_msg_id));
2785
2786   vat_json_print (vam->ofp, &node);
2787   vat_json_free (&node);
2788
2789   vam->retval = ntohl (mp->retval);
2790   vam->result_ready = 1;
2791 }
2792
2793 static void vl_api_get_node_graph_reply_t_handler
2794   (vl_api_get_node_graph_reply_t * mp)
2795 {
2796   vat_main_t *vam = &vat_main;
2797   api_main_t *am = &api_main;
2798   i32 retval = ntohl (mp->retval);
2799   u8 *pvt_copy, *reply;
2800   void *oldheap;
2801   vlib_node_t *node;
2802   int i;
2803
2804   if (vam->async_mode)
2805     {
2806       vam->async_errors += (retval < 0);
2807     }
2808   else
2809     {
2810       vam->retval = retval;
2811       vam->result_ready = 1;
2812     }
2813
2814   /* "Should never happen..." */
2815   if (retval != 0)
2816     return;
2817
2818   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2819   pvt_copy = vec_dup (reply);
2820
2821   /* Toss the shared-memory original... */
2822   pthread_mutex_lock (&am->vlib_rp->mutex);
2823   oldheap = svm_push_data_heap (am->vlib_rp);
2824
2825   vec_free (reply);
2826
2827   svm_pop_heap (oldheap);
2828   pthread_mutex_unlock (&am->vlib_rp->mutex);
2829
2830   if (vam->graph_nodes)
2831     {
2832       hash_free (vam->graph_node_index_by_name);
2833
2834       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2835         {
2836           node = vam->graph_nodes[0][i];
2837           vec_free (node->name);
2838           vec_free (node->next_nodes);
2839           vec_free (node);
2840         }
2841       vec_free (vam->graph_nodes[0]);
2842       vec_free (vam->graph_nodes);
2843     }
2844
2845   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2846   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2847   vec_free (pvt_copy);
2848
2849   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2850     {
2851       node = vam->graph_nodes[0][i];
2852       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2853     }
2854 }
2855
2856 static void vl_api_get_node_graph_reply_t_handler_json
2857   (vl_api_get_node_graph_reply_t * mp)
2858 {
2859   vat_main_t *vam = &vat_main;
2860   api_main_t *am = &api_main;
2861   void *oldheap;
2862   vat_json_node_t node;
2863   u8 *reply;
2864
2865   /* $$$$ make this real? */
2866   vat_json_init_object (&node);
2867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2868   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2869
2870   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2871
2872   /* Toss the shared-memory original... */
2873   pthread_mutex_lock (&am->vlib_rp->mutex);
2874   oldheap = svm_push_data_heap (am->vlib_rp);
2875
2876   vec_free (reply);
2877
2878   svm_pop_heap (oldheap);
2879   pthread_mutex_unlock (&am->vlib_rp->mutex);
2880
2881   vat_json_print (vam->ofp, &node);
2882   vat_json_free (&node);
2883
2884   vam->retval = ntohl (mp->retval);
2885   vam->result_ready = 1;
2886 }
2887
2888 static void
2889 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2890 {
2891   vat_main_t *vam = &vat_main;
2892   u8 *s = 0;
2893
2894   if (mp->local)
2895     {
2896       s = format (s, "%=16d%=16d%=16d",
2897                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2898     }
2899   else
2900     {
2901       s = format (s, "%=16U%=16d%=16d",
2902                   mp->is_ipv6 ? format_ip6_address :
2903                   format_ip4_address,
2904                   mp->ip_address, mp->priority, mp->weight);
2905     }
2906
2907   print (vam->ofp, "%v", s);
2908   vec_free (s);
2909 }
2910
2911 static void
2912 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node = NULL;
2916   struct in6_addr ip6;
2917   struct in_addr ip4;
2918
2919   if (VAT_JSON_ARRAY != vam->json_tree.type)
2920     {
2921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2922       vat_json_init_array (&vam->json_tree);
2923     }
2924   node = vat_json_array_add (&vam->json_tree);
2925   vat_json_init_object (node);
2926
2927   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2928   vat_json_object_add_uint (node, "priority", mp->priority);
2929   vat_json_object_add_uint (node, "weight", mp->weight);
2930
2931   if (mp->local)
2932     vat_json_object_add_uint (node, "sw_if_index",
2933                               clib_net_to_host_u32 (mp->sw_if_index));
2934   else
2935     {
2936       if (mp->is_ipv6)
2937         {
2938           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2939           vat_json_object_add_ip6 (node, "address", ip6);
2940         }
2941       else
2942         {
2943           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2944           vat_json_object_add_ip4 (node, "address", ip4);
2945         }
2946     }
2947 }
2948
2949 static void
2950 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2951                                           mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   u8 *ls_name = 0;
2955
2956   ls_name = format (0, "%s", mp->ls_name);
2957
2958   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2959          ls_name);
2960   vec_free (ls_name);
2961 }
2962
2963 static void
2964   vl_api_one_locator_set_details_t_handler_json
2965   (vl_api_one_locator_set_details_t * mp)
2966 {
2967   vat_main_t *vam = &vat_main;
2968   vat_json_node_t *node = 0;
2969   u8 *ls_name = 0;
2970
2971   ls_name = format (0, "%s", mp->ls_name);
2972   vec_add1 (ls_name, 0);
2973
2974   if (VAT_JSON_ARRAY != vam->json_tree.type)
2975     {
2976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2977       vat_json_init_array (&vam->json_tree);
2978     }
2979   node = vat_json_array_add (&vam->json_tree);
2980
2981   vat_json_init_object (node);
2982   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2983   vat_json_object_add_uint (node, "ls_index",
2984                             clib_net_to_host_u32 (mp->ls_index));
2985   vec_free (ls_name);
2986 }
2987
2988 typedef struct
2989 {
2990   u32 spi;
2991   u8 si;
2992 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2993
2994 uword
2995 unformat_nsh_address (unformat_input_t * input, va_list * args)
2996 {
2997   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2998   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2999 }
3000
3001 u8 *
3002 format_nsh_address_vat (u8 * s, va_list * args)
3003 {
3004   nsh_t *a = va_arg (*args, nsh_t *);
3005   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3006 }
3007
3008 static u8 *
3009 format_lisp_flat_eid (u8 * s, va_list * args)
3010 {
3011   u32 type = va_arg (*args, u32);
3012   u8 *eid = va_arg (*args, u8 *);
3013   u32 eid_len = va_arg (*args, u32);
3014
3015   switch (type)
3016     {
3017     case 0:
3018       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3019     case 1:
3020       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3021     case 2:
3022       return format (s, "%U", format_ethernet_address, eid);
3023     case 3:
3024       return format (s, "%U", format_nsh_address_vat, eid);
3025     }
3026   return 0;
3027 }
3028
3029 static u8 *
3030 format_lisp_eid_vat (u8 * s, va_list * args)
3031 {
3032   u32 type = va_arg (*args, u32);
3033   u8 *eid = va_arg (*args, u8 *);
3034   u32 eid_len = va_arg (*args, u32);
3035   u8 *seid = va_arg (*args, u8 *);
3036   u32 seid_len = va_arg (*args, u32);
3037   u32 is_src_dst = va_arg (*args, u32);
3038
3039   if (is_src_dst)
3040     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3041
3042   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3043
3044   return s;
3045 }
3046
3047 static void
3048 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   u8 *s = 0, *eid = 0;
3052
3053   if (~0 == mp->locator_set_index)
3054     s = format (0, "action: %d", mp->action);
3055   else
3056     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3057
3058   eid = format (0, "%U", format_lisp_eid_vat,
3059                 mp->eid_type,
3060                 mp->eid,
3061                 mp->eid_prefix_len,
3062                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3063   vec_add1 (eid, 0);
3064
3065   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3066          clib_net_to_host_u32 (mp->vni),
3067          eid,
3068          mp->is_local ? "local" : "remote",
3069          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3070          clib_net_to_host_u16 (mp->key_id), mp->key);
3071
3072   vec_free (s);
3073   vec_free (eid);
3074 }
3075
3076 static void
3077 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3078                                              * mp)
3079 {
3080   vat_main_t *vam = &vat_main;
3081   vat_json_node_t *node = 0;
3082   u8 *eid = 0;
3083
3084   if (VAT_JSON_ARRAY != vam->json_tree.type)
3085     {
3086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3087       vat_json_init_array (&vam->json_tree);
3088     }
3089   node = vat_json_array_add (&vam->json_tree);
3090
3091   vat_json_init_object (node);
3092   if (~0 == mp->locator_set_index)
3093     vat_json_object_add_uint (node, "action", mp->action);
3094   else
3095     vat_json_object_add_uint (node, "locator_set_index",
3096                               clib_net_to_host_u32 (mp->locator_set_index));
3097
3098   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3099   if (mp->eid_type == 3)
3100     {
3101       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3102       vat_json_init_object (nsh_json);
3103       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3104       vat_json_object_add_uint (nsh_json, "spi",
3105                                 clib_net_to_host_u32 (nsh->spi));
3106       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3107     }
3108   else
3109     {
3110       eid = format (0, "%U", format_lisp_eid_vat,
3111                     mp->eid_type,
3112                     mp->eid,
3113                     mp->eid_prefix_len,
3114                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3115       vec_add1 (eid, 0);
3116       vat_json_object_add_string_copy (node, "eid", eid);
3117       vec_free (eid);
3118     }
3119   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3120   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3121   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3122
3123   if (mp->key_id)
3124     {
3125       vat_json_object_add_uint (node, "key_id",
3126                                 clib_net_to_host_u16 (mp->key_id));
3127       vat_json_object_add_string_copy (node, "key", mp->key);
3128     }
3129 }
3130
3131 static void
3132 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3133 {
3134   vat_main_t *vam = &vat_main;
3135   u8 *seid = 0, *deid = 0;
3136   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3137
3138   deid = format (0, "%U", format_lisp_eid_vat,
3139                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3140
3141   seid = format (0, "%U", format_lisp_eid_vat,
3142                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3143
3144   vec_add1 (deid, 0);
3145   vec_add1 (seid, 0);
3146
3147   if (mp->is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152
3153   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3154          clib_net_to_host_u32 (mp->vni),
3155          seid, deid,
3156          format_ip_address_fcn, mp->lloc,
3157          format_ip_address_fcn, mp->rloc,
3158          clib_net_to_host_u32 (mp->pkt_count),
3159          clib_net_to_host_u32 (mp->bytes));
3160
3161   vec_free (deid);
3162   vec_free (seid);
3163 }
3164
3165 static void
3166 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3167 {
3168   struct in6_addr ip6;
3169   struct in_addr ip4;
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t *node = 0;
3172   u8 *deid = 0, *seid = 0;
3173
3174   if (VAT_JSON_ARRAY != vam->json_tree.type)
3175     {
3176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3177       vat_json_init_array (&vam->json_tree);
3178     }
3179   node = vat_json_array_add (&vam->json_tree);
3180
3181   vat_json_init_object (node);
3182   deid = format (0, "%U", format_lisp_eid_vat,
3183                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3184
3185   seid = format (0, "%U", format_lisp_eid_vat,
3186                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3187
3188   vec_add1 (deid, 0);
3189   vec_add1 (seid, 0);
3190
3191   vat_json_object_add_string_copy (node, "seid", seid);
3192   vat_json_object_add_string_copy (node, "deid", deid);
3193   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3194
3195   if (mp->is_ip4)
3196     {
3197       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3198       vat_json_object_add_ip4 (node, "lloc", ip4);
3199       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3200       vat_json_object_add_ip4 (node, "rloc", ip4);
3201     }
3202   else
3203     {
3204       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3205       vat_json_object_add_ip6 (node, "lloc", ip6);
3206       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3207       vat_json_object_add_ip6 (node, "rloc", ip6);
3208     }
3209   vat_json_object_add_uint (node, "pkt_count",
3210                             clib_net_to_host_u32 (mp->pkt_count));
3211   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3212
3213   vec_free (deid);
3214   vec_free (seid);
3215 }
3216
3217 static void
3218   vl_api_one_eid_table_map_details_t_handler
3219   (vl_api_one_eid_table_map_details_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222
3223   u8 *line = format (0, "%=10d%=10d",
3224                      clib_net_to_host_u32 (mp->vni),
3225                      clib_net_to_host_u32 (mp->dp_table));
3226   print (vam->ofp, "%v", line);
3227   vec_free (line);
3228 }
3229
3230 static void
3231   vl_api_one_eid_table_map_details_t_handler_json
3232   (vl_api_one_eid_table_map_details_t * mp)
3233 {
3234   vat_main_t *vam = &vat_main;
3235   vat_json_node_t *node = NULL;
3236
3237   if (VAT_JSON_ARRAY != vam->json_tree.type)
3238     {
3239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3240       vat_json_init_array (&vam->json_tree);
3241     }
3242   node = vat_json_array_add (&vam->json_tree);
3243   vat_json_init_object (node);
3244   vat_json_object_add_uint (node, "dp_table",
3245                             clib_net_to_host_u32 (mp->dp_table));
3246   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3247 }
3248
3249 static void
3250   vl_api_one_eid_table_vni_details_t_handler
3251   (vl_api_one_eid_table_vni_details_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254
3255   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3256   print (vam->ofp, "%v", line);
3257   vec_free (line);
3258 }
3259
3260 static void
3261   vl_api_one_eid_table_vni_details_t_handler_json
3262   (vl_api_one_eid_table_vni_details_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   vat_json_node_t *node = NULL;
3266
3267   if (VAT_JSON_ARRAY != vam->json_tree.type)
3268     {
3269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3270       vat_json_init_array (&vam->json_tree);
3271     }
3272   node = vat_json_array_add (&vam->json_tree);
3273   vat_json_init_object (node);
3274   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3275 }
3276
3277 static void
3278   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3279   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3285   print (vam->ofp, "fallback threshold value: %d", mp->value);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289 }
3290
3291 static void
3292   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3293   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t _node, *node = &_node;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3300   vat_json_init_object (node);
3301   vat_json_object_add_uint (node, "value", mp->value);
3302
3303   vat_json_print (vam->ofp, node);
3304   vat_json_free (node);
3305
3306   vam->retval = retval;
3307   vam->result_ready = 1;
3308 }
3309
3310 static void
3311   vl_api_show_one_map_register_state_reply_t_handler
3312   (vl_api_show_one_map_register_state_reply_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315   int retval = clib_net_to_host_u32 (mp->retval);
3316
3317   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3318
3319   vam->retval = retval;
3320   vam->result_ready = 1;
3321 }
3322
3323 static void
3324   vl_api_show_one_map_register_state_reply_t_handler_json
3325   (vl_api_show_one_map_register_state_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   vat_json_node_t _node, *node = &_node;
3329   int retval = clib_net_to_host_u32 (mp->retval);
3330
3331   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3332
3333   vat_json_init_object (node);
3334   vat_json_object_add_string_copy (node, "state", s);
3335
3336   vat_json_print (vam->ofp, node);
3337   vat_json_free (node);
3338
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341   vec_free (s);
3342 }
3343
3344 static void
3345   vl_api_show_one_rloc_probe_state_reply_t_handler
3346   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3347 {
3348   vat_main_t *vam = &vat_main;
3349   int retval = clib_net_to_host_u32 (mp->retval);
3350
3351   if (retval)
3352     goto end;
3353
3354   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3355 end:
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3362   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t _node, *node = &_node;
3366   int retval = clib_net_to_host_u32 (mp->retval);
3367
3368   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3369   vat_json_init_object (node);
3370   vat_json_object_add_string_copy (node, "state", s);
3371
3372   vat_json_print (vam->ofp, node);
3373   vat_json_free (node);
3374
3375   vam->retval = retval;
3376   vam->result_ready = 1;
3377   vec_free (s);
3378 }
3379
3380 static void
3381   vl_api_show_one_stats_enable_disable_reply_t_handler
3382   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385   int retval = clib_net_to_host_u32 (mp->retval);
3386
3387   if (retval)
3388     goto end;
3389
3390   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3391 end:
3392   vam->retval = retval;
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3398   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   vat_json_node_t _node, *node = &_node;
3402   int retval = clib_net_to_host_u32 (mp->retval);
3403
3404   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3405   vat_json_init_object (node);
3406   vat_json_object_add_string_copy (node, "state", s);
3407
3408   vat_json_print (vam->ofp, node);
3409   vat_json_free (node);
3410
3411   vam->retval = retval;
3412   vam->result_ready = 1;
3413   vec_free (s);
3414 }
3415
3416 static void
3417 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3418 {
3419   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3420   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3421   e->vni = clib_net_to_host_u32 (e->vni);
3422 }
3423
3424 static void
3425   gpe_fwd_entries_get_reply_t_net_to_host
3426   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3427 {
3428   u32 i;
3429
3430   mp->count = clib_net_to_host_u32 (mp->count);
3431   for (i = 0; i < mp->count; i++)
3432     {
3433       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3434     }
3435 }
3436
3437 static u8 *
3438 format_gpe_encap_mode (u8 * s, va_list * args)
3439 {
3440   u32 mode = va_arg (*args, u32);
3441
3442   switch (mode)
3443     {
3444     case 0:
3445       return format (s, "lisp");
3446     case 1:
3447       return format (s, "vxlan");
3448     }
3449   return 0;
3450 }
3451
3452 static void
3453   vl_api_gpe_get_encap_mode_reply_t_handler
3454   (vl_api_gpe_get_encap_mode_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457
3458   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3459   vam->retval = ntohl (mp->retval);
3460   vam->result_ready = 1;
3461 }
3462
3463 static void
3464   vl_api_gpe_get_encap_mode_reply_t_handler_json
3465   (vl_api_gpe_get_encap_mode_reply_t * mp)
3466 {
3467   vat_main_t *vam = &vat_main;
3468   vat_json_node_t node;
3469
3470   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3471   vec_add1 (encap_mode, 0);
3472
3473   vat_json_init_object (&node);
3474   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3475
3476   vec_free (encap_mode);
3477   vat_json_print (vam->ofp, &node);
3478   vat_json_free (&node);
3479
3480   vam->retval = ntohl (mp->retval);
3481   vam->result_ready = 1;
3482 }
3483
3484 static void
3485   vl_api_gpe_fwd_entry_path_details_t_handler
3486   (vl_api_gpe_fwd_entry_path_details_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3490
3491   if (mp->lcl_loc.is_ip4)
3492     format_ip_address_fcn = format_ip4_address;
3493   else
3494     format_ip_address_fcn = format_ip6_address;
3495
3496   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3497          format_ip_address_fcn, &mp->lcl_loc,
3498          format_ip_address_fcn, &mp->rmt_loc);
3499 }
3500
3501 static void
3502 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3503 {
3504   struct in6_addr ip6;
3505   struct in_addr ip4;
3506
3507   if (loc->is_ip4)
3508     {
3509       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3510       vat_json_object_add_ip4 (n, "address", ip4);
3511     }
3512   else
3513     {
3514       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3515       vat_json_object_add_ip6 (n, "address", ip6);
3516     }
3517   vat_json_object_add_uint (n, "weight", loc->weight);
3518 }
3519
3520 static void
3521   vl_api_gpe_fwd_entry_path_details_t_handler_json
3522   (vl_api_gpe_fwd_entry_path_details_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   vat_json_node_t *node = NULL;
3526   vat_json_node_t *loc_node;
3527
3528   if (VAT_JSON_ARRAY != vam->json_tree.type)
3529     {
3530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3531       vat_json_init_array (&vam->json_tree);
3532     }
3533   node = vat_json_array_add (&vam->json_tree);
3534   vat_json_init_object (node);
3535
3536   loc_node = vat_json_object_add (node, "local_locator");
3537   vat_json_init_object (loc_node);
3538   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3539
3540   loc_node = vat_json_object_add (node, "remote_locator");
3541   vat_json_init_object (loc_node);
3542   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3543 }
3544
3545 static void
3546   vl_api_gpe_fwd_entries_get_reply_t_handler
3547   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u32 i;
3551   int retval = clib_net_to_host_u32 (mp->retval);
3552   vl_api_gpe_fwd_entry_t *e;
3553
3554   if (retval)
3555     goto end;
3556
3557   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3558
3559   for (i = 0; i < mp->count; i++)
3560     {
3561       e = &mp->entries[i];
3562       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3563              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3564              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3565     }
3566
3567 end:
3568   vam->retval = retval;
3569   vam->result_ready = 1;
3570 }
3571
3572 static void
3573   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3574   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3575 {
3576   u8 *s = 0;
3577   vat_main_t *vam = &vat_main;
3578   vat_json_node_t *e = 0, root;
3579   u32 i;
3580   int retval = clib_net_to_host_u32 (mp->retval);
3581   vl_api_gpe_fwd_entry_t *fwd;
3582
3583   if (retval)
3584     goto end;
3585
3586   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3587   vat_json_init_array (&root);
3588
3589   for (i = 0; i < mp->count; i++)
3590     {
3591       e = vat_json_array_add (&root);
3592       fwd = &mp->entries[i];
3593
3594       vat_json_init_object (e);
3595       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3596       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3597       vat_json_object_add_int (e, "vni", fwd->vni);
3598       vat_json_object_add_int (e, "action", fwd->action);
3599
3600       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3601                   fwd->leid_prefix_len);
3602       vec_add1 (s, 0);
3603       vat_json_object_add_string_copy (e, "leid", s);
3604       vec_free (s);
3605
3606       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3607                   fwd->reid_prefix_len);
3608       vec_add1 (s, 0);
3609       vat_json_object_add_string_copy (e, "reid", s);
3610       vec_free (s);
3611     }
3612
3613   vat_json_print (vam->ofp, &root);
3614   vat_json_free (&root);
3615
3616 end:
3617   vam->retval = retval;
3618   vam->result_ready = 1;
3619 }
3620
3621 static void
3622   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3623   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3624 {
3625   vat_main_t *vam = &vat_main;
3626   u32 i, n;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628   vl_api_gpe_native_fwd_rpath_t *r;
3629
3630   if (retval)
3631     goto end;
3632
3633   n = clib_net_to_host_u32 (mp->count);
3634
3635   for (i = 0; i < n; i++)
3636     {
3637       r = &mp->entries[i];
3638       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3639              clib_net_to_host_u32 (r->fib_index),
3640              clib_net_to_host_u32 (r->nh_sw_if_index),
3641              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3642     }
3643
3644 end:
3645   vam->retval = retval;
3646   vam->result_ready = 1;
3647 }
3648
3649 static void
3650   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3651   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3652 {
3653   vat_main_t *vam = &vat_main;
3654   vat_json_node_t root, *e;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657   vl_api_gpe_native_fwd_rpath_t *r;
3658   u8 *s;
3659
3660   if (retval)
3661     goto end;
3662
3663   n = clib_net_to_host_u32 (mp->count);
3664   vat_json_init_array (&root);
3665
3666   for (i = 0; i < n; i++)
3667     {
3668       e = vat_json_array_add (&root);
3669       vat_json_init_object (e);
3670       r = &mp->entries[i];
3671       s =
3672         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3673                 r->nh_addr);
3674       vec_add1 (s, 0);
3675       vat_json_object_add_string_copy (e, "ip4", s);
3676       vec_free (s);
3677
3678       vat_json_object_add_uint (e, "fib_index",
3679                                 clib_net_to_host_u32 (r->fib_index));
3680       vat_json_object_add_uint (e, "nh_sw_if_index",
3681                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3682     }
3683
3684   vat_json_print (vam->ofp, &root);
3685   vat_json_free (&root);
3686
3687 end:
3688   vam->retval = retval;
3689   vam->result_ready = 1;
3690 }
3691
3692 static void
3693   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3694   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3695 {
3696   vat_main_t *vam = &vat_main;
3697   u32 i, n;
3698   int retval = clib_net_to_host_u32 (mp->retval);
3699
3700   if (retval)
3701     goto end;
3702
3703   n = clib_net_to_host_u32 (mp->count);
3704
3705   for (i = 0; i < n; i++)
3706     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3707
3708 end:
3709   vam->retval = retval;
3710   vam->result_ready = 1;
3711 }
3712
3713 static void
3714   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3715   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3716 {
3717   vat_main_t *vam = &vat_main;
3718   vat_json_node_t root;
3719   u32 i, n;
3720   int retval = clib_net_to_host_u32 (mp->retval);
3721
3722   if (retval)
3723     goto end;
3724
3725   n = clib_net_to_host_u32 (mp->count);
3726   vat_json_init_array (&root);
3727
3728   for (i = 0; i < n; i++)
3729     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3730
3731   vat_json_print (vam->ofp, &root);
3732   vat_json_free (&root);
3733
3734 end:
3735   vam->retval = retval;
3736   vam->result_ready = 1;
3737 }
3738
3739 static void
3740   vl_api_one_ndp_entries_get_reply_t_handler
3741   (vl_api_one_ndp_entries_get_reply_t * mp)
3742 {
3743   vat_main_t *vam = &vat_main;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746
3747   if (retval)
3748     goto end;
3749
3750   n = clib_net_to_host_u32 (mp->count);
3751
3752   for (i = 0; i < n; i++)
3753     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3754            format_ethernet_address, mp->entries[i].mac);
3755
3756 end:
3757   vam->retval = retval;
3758   vam->result_ready = 1;
3759 }
3760
3761 static void
3762   vl_api_one_ndp_entries_get_reply_t_handler_json
3763   (vl_api_one_ndp_entries_get_reply_t * mp)
3764 {
3765   u8 *s = 0;
3766   vat_main_t *vam = &vat_main;
3767   vat_json_node_t *e = 0, root;
3768   u32 i, n;
3769   int retval = clib_net_to_host_u32 (mp->retval);
3770   vl_api_one_ndp_entry_t *arp_entry;
3771
3772   if (retval)
3773     goto end;
3774
3775   n = clib_net_to_host_u32 (mp->count);
3776   vat_json_init_array (&root);
3777
3778   for (i = 0; i < n; i++)
3779     {
3780       e = vat_json_array_add (&root);
3781       arp_entry = &mp->entries[i];
3782
3783       vat_json_init_object (e);
3784       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3785       vec_add1 (s, 0);
3786
3787       vat_json_object_add_string_copy (e, "mac", s);
3788       vec_free (s);
3789
3790       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3791       vec_add1 (s, 0);
3792       vat_json_object_add_string_copy (e, "ip6", s);
3793       vec_free (s);
3794     }
3795
3796   vat_json_print (vam->ofp, &root);
3797   vat_json_free (&root);
3798
3799 end:
3800   vam->retval = retval;
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_one_l2_arp_entries_get_reply_t_handler
3806   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   u32 i, n;
3810   int retval = clib_net_to_host_u32 (mp->retval);
3811
3812   if (retval)
3813     goto end;
3814
3815   n = clib_net_to_host_u32 (mp->count);
3816
3817   for (i = 0; i < n; i++)
3818     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3819            format_ethernet_address, mp->entries[i].mac);
3820
3821 end:
3822   vam->retval = retval;
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3828   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3829 {
3830   u8 *s = 0;
3831   vat_main_t *vam = &vat_main;
3832   vat_json_node_t *e = 0, root;
3833   u32 i, n;
3834   int retval = clib_net_to_host_u32 (mp->retval);
3835   vl_api_one_l2_arp_entry_t *arp_entry;
3836
3837   if (retval)
3838     goto end;
3839
3840   n = clib_net_to_host_u32 (mp->count);
3841   vat_json_init_array (&root);
3842
3843   for (i = 0; i < n; i++)
3844     {
3845       e = vat_json_array_add (&root);
3846       arp_entry = &mp->entries[i];
3847
3848       vat_json_init_object (e);
3849       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3850       vec_add1 (s, 0);
3851
3852       vat_json_object_add_string_copy (e, "mac", s);
3853       vec_free (s);
3854
3855       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3856       vec_add1 (s, 0);
3857       vat_json_object_add_string_copy (e, "ip4", s);
3858       vec_free (s);
3859     }
3860
3861   vat_json_print (vam->ofp, &root);
3862   vat_json_free (&root);
3863
3864 end:
3865   vam->retval = retval;
3866   vam->result_ready = 1;
3867 }
3868
3869 static void
3870 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   u32 i, n;
3874   int retval = clib_net_to_host_u32 (mp->retval);
3875
3876   if (retval)
3877     goto end;
3878
3879   n = clib_net_to_host_u32 (mp->count);
3880
3881   for (i = 0; i < n; i++)
3882     {
3883       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3884     }
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_ndp_bd_get_reply_t_handler_json
3893   (vl_api_one_ndp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   vat_json_node_t root;
3897   u32 i, n;
3898   int retval = clib_net_to_host_u32 (mp->retval);
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904   vat_json_init_array (&root);
3905
3906   for (i = 0; i < n; i++)
3907     {
3908       vat_json_array_add_uint (&root,
3909                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3910     }
3911
3912   vat_json_print (vam->ofp, &root);
3913   vat_json_free (&root);
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_l2_arp_bd_get_reply_t_handler
3922   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   u32 i, n;
3926   int retval = clib_net_to_host_u32 (mp->retval);
3927
3928   if (retval)
3929     goto end;
3930
3931   n = clib_net_to_host_u32 (mp->count);
3932
3933   for (i = 0; i < n; i++)
3934     {
3935       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3936     }
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3945   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   vat_json_node_t root;
3949   u32 i, n;
3950   int retval = clib_net_to_host_u32 (mp->retval);
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956   vat_json_init_array (&root);
3957
3958   for (i = 0; i < n; i++)
3959     {
3960       vat_json_array_add_uint (&root,
3961                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3962     }
3963
3964   vat_json_print (vam->ofp, &root);
3965   vat_json_free (&root);
3966
3967 end:
3968   vam->retval = retval;
3969   vam->result_ready = 1;
3970 }
3971
3972 static void
3973   vl_api_one_adjacencies_get_reply_t_handler
3974   (vl_api_one_adjacencies_get_reply_t * mp)
3975 {
3976   vat_main_t *vam = &vat_main;
3977   u32 i, n;
3978   int retval = clib_net_to_host_u32 (mp->retval);
3979   vl_api_one_adjacency_t *a;
3980
3981   if (retval)
3982     goto end;
3983
3984   n = clib_net_to_host_u32 (mp->count);
3985
3986   for (i = 0; i < n; i++)
3987     {
3988       a = &mp->adjacencies[i];
3989       print (vam->ofp, "%U %40U",
3990              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3991              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3992     }
3993
3994 end:
3995   vam->retval = retval;
3996   vam->result_ready = 1;
3997 }
3998
3999 static void
4000   vl_api_one_adjacencies_get_reply_t_handler_json
4001   (vl_api_one_adjacencies_get_reply_t * mp)
4002 {
4003   u8 *s = 0;
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t *e = 0, root;
4006   u32 i, n;
4007   int retval = clib_net_to_host_u32 (mp->retval);
4008   vl_api_one_adjacency_t *a;
4009
4010   if (retval)
4011     goto end;
4012
4013   n = clib_net_to_host_u32 (mp->count);
4014   vat_json_init_array (&root);
4015
4016   for (i = 0; i < n; i++)
4017     {
4018       e = vat_json_array_add (&root);
4019       a = &mp->adjacencies[i];
4020
4021       vat_json_init_object (e);
4022       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4023                   a->leid_prefix_len);
4024       vec_add1 (s, 0);
4025       vat_json_object_add_string_copy (e, "leid", s);
4026       vec_free (s);
4027
4028       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4029                   a->reid_prefix_len);
4030       vec_add1 (s, 0);
4031       vat_json_object_add_string_copy (e, "reid", s);
4032       vec_free (s);
4033     }
4034
4035   vat_json_print (vam->ofp, &root);
4036   vat_json_free (&root);
4037
4038 end:
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4045 {
4046   vat_main_t *vam = &vat_main;
4047
4048   print (vam->ofp, "%=20U",
4049          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4050          mp->ip_address);
4051 }
4052
4053 static void
4054   vl_api_one_map_server_details_t_handler_json
4055   (vl_api_one_map_server_details_t * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058   vat_json_node_t *node = NULL;
4059   struct in6_addr ip6;
4060   struct in_addr ip4;
4061
4062   if (VAT_JSON_ARRAY != vam->json_tree.type)
4063     {
4064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4065       vat_json_init_array (&vam->json_tree);
4066     }
4067   node = vat_json_array_add (&vam->json_tree);
4068
4069   vat_json_init_object (node);
4070   if (mp->is_ipv6)
4071     {
4072       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4073       vat_json_object_add_ip6 (node, "map-server", ip6);
4074     }
4075   else
4076     {
4077       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4078       vat_json_object_add_ip4 (node, "map-server", ip4);
4079     }
4080 }
4081
4082 static void
4083 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4084                                            * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087
4088   print (vam->ofp, "%=20U",
4089          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4090          mp->ip_address);
4091 }
4092
4093 static void
4094   vl_api_one_map_resolver_details_t_handler_json
4095   (vl_api_one_map_resolver_details_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098   vat_json_node_t *node = NULL;
4099   struct in6_addr ip6;
4100   struct in_addr ip4;
4101
4102   if (VAT_JSON_ARRAY != vam->json_tree.type)
4103     {
4104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4105       vat_json_init_array (&vam->json_tree);
4106     }
4107   node = vat_json_array_add (&vam->json_tree);
4108
4109   vat_json_init_object (node);
4110   if (mp->is_ipv6)
4111     {
4112       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4113       vat_json_object_add_ip6 (node, "map resolver", ip6);
4114     }
4115   else
4116     {
4117       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4118       vat_json_object_add_ip4 (node, "map resolver", ip4);
4119     }
4120 }
4121
4122 static void
4123 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4124 {
4125   vat_main_t *vam = &vat_main;
4126   i32 retval = ntohl (mp->retval);
4127
4128   if (0 <= retval)
4129     {
4130       print (vam->ofp, "feature: %s\ngpe: %s",
4131              mp->feature_status ? "enabled" : "disabled",
4132              mp->gpe_status ? "enabled" : "disabled");
4133     }
4134
4135   vam->retval = retval;
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_show_one_status_reply_t_handler_json
4141   (vl_api_show_one_status_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   vat_json_node_t node;
4145   u8 *gpe_status = NULL;
4146   u8 *feature_status = NULL;
4147
4148   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4149   feature_status = format (0, "%s",
4150                            mp->feature_status ? "enabled" : "disabled");
4151   vec_add1 (gpe_status, 0);
4152   vec_add1 (feature_status, 0);
4153
4154   vat_json_init_object (&node);
4155   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4156   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4157
4158   vec_free (gpe_status);
4159   vec_free (feature_status);
4160
4161   vat_json_print (vam->ofp, &node);
4162   vat_json_free (&node);
4163
4164   vam->retval = ntohl (mp->retval);
4165   vam->result_ready = 1;
4166 }
4167
4168 static void
4169   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4170   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   i32 retval = ntohl (mp->retval);
4174
4175   if (retval >= 0)
4176     {
4177       print (vam->ofp, "%=20s", mp->locator_set_name);
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4186   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t *node = NULL;
4190
4191   if (VAT_JSON_ARRAY != vam->json_tree.type)
4192     {
4193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4194       vat_json_init_array (&vam->json_tree);
4195     }
4196   node = vat_json_array_add (&vam->json_tree);
4197
4198   vat_json_init_object (node);
4199   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4200
4201   vat_json_print (vam->ofp, node);
4202   vat_json_free (node);
4203
4204   vam->retval = ntohl (mp->retval);
4205   vam->result_ready = 1;
4206 }
4207
4208 static u8 *
4209 format_lisp_map_request_mode (u8 * s, va_list * args)
4210 {
4211   u32 mode = va_arg (*args, u32);
4212
4213   switch (mode)
4214     {
4215     case 0:
4216       return format (0, "dst-only");
4217     case 1:
4218       return format (0, "src-dst");
4219     }
4220   return 0;
4221 }
4222
4223 static void
4224   vl_api_show_one_map_request_mode_reply_t_handler
4225   (vl_api_show_one_map_request_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   i32 retval = ntohl (mp->retval);
4229
4230   if (0 <= retval)
4231     {
4232       u32 mode = mp->mode;
4233       print (vam->ofp, "map_request_mode: %U",
4234              format_lisp_map_request_mode, mode);
4235     }
4236
4237   vam->retval = retval;
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_show_one_map_request_mode_reply_t_handler_json
4243   (vl_api_show_one_map_request_mode_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   vat_json_node_t node;
4247   u8 *s = 0;
4248   u32 mode;
4249
4250   mode = mp->mode;
4251   s = format (0, "%U", format_lisp_map_request_mode, mode);
4252   vec_add1 (s, 0);
4253
4254   vat_json_init_object (&node);
4255   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4256   vat_json_print (vam->ofp, &node);
4257   vat_json_free (&node);
4258
4259   vec_free (s);
4260   vam->retval = ntohl (mp->retval);
4261   vam->result_ready = 1;
4262 }
4263
4264 static void
4265   vl_api_one_show_xtr_mode_reply_t_handler
4266   (vl_api_one_show_xtr_mode_reply_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   i32 retval = ntohl (mp->retval);
4270
4271   if (0 <= retval)
4272     {
4273       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4274     }
4275
4276   vam->retval = retval;
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_one_show_xtr_mode_reply_t_handler_json
4282   (vl_api_one_show_xtr_mode_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286   u8 *status = 0;
4287
4288   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293
4294   vec_free (status);
4295
4296   vat_json_print (vam->ofp, &node);
4297   vat_json_free (&node);
4298
4299   vam->retval = ntohl (mp->retval);
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_one_show_pitr_mode_reply_t_handler
4305   (vl_api_one_show_pitr_mode_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   i32 retval = ntohl (mp->retval);
4309
4310   if (0 <= retval)
4311     {
4312       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_one_show_pitr_mode_reply_t_handler_json
4321   (vl_api_one_show_pitr_mode_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "status", status);
4332
4333   vec_free (status);
4334
4335   vat_json_print (vam->ofp, &node);
4336   vat_json_free (&node);
4337
4338   vam->retval = ntohl (mp->retval);
4339   vam->result_ready = 1;
4340 }
4341
4342 static void
4343   vl_api_one_show_petr_mode_reply_t_handler
4344   (vl_api_one_show_petr_mode_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   i32 retval = ntohl (mp->retval);
4348
4349   if (0 <= retval)
4350     {
4351       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4352     }
4353
4354   vam->retval = retval;
4355   vam->result_ready = 1;
4356 }
4357
4358 static void
4359   vl_api_one_show_petr_mode_reply_t_handler_json
4360   (vl_api_one_show_petr_mode_reply_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   vat_json_node_t node;
4364   u8 *status = 0;
4365
4366   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4367   vec_add1 (status, 0);
4368
4369   vat_json_init_object (&node);
4370   vat_json_object_add_string_copy (&node, "status", status);
4371
4372   vec_free (status);
4373
4374   vat_json_print (vam->ofp, &node);
4375   vat_json_free (&node);
4376
4377   vam->retval = ntohl (mp->retval);
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_use_petr_reply_t_handler
4383   (vl_api_show_one_use_petr_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   i32 retval = ntohl (mp->retval);
4387
4388   if (0 <= retval)
4389     {
4390       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4391       if (mp->status)
4392         {
4393           print (vam->ofp, "Proxy-ETR address; %U",
4394                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4395                  mp->address);
4396         }
4397     }
4398
4399   vam->retval = retval;
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_show_one_use_petr_reply_t_handler_json
4405   (vl_api_show_one_use_petr_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   vat_json_node_t node;
4409   u8 *status = 0;
4410   struct in_addr ip4;
4411   struct in6_addr ip6;
4412
4413   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4414   vec_add1 (status, 0);
4415
4416   vat_json_init_object (&node);
4417   vat_json_object_add_string_copy (&node, "status", status);
4418   if (mp->status)
4419     {
4420       if (mp->is_ip4)
4421         {
4422           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4423           vat_json_object_add_ip6 (&node, "address", ip6);
4424         }
4425       else
4426         {
4427           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4428           vat_json_object_add_ip4 (&node, "address", ip4);
4429         }
4430     }
4431
4432   vec_free (status);
4433
4434   vat_json_print (vam->ofp, &node);
4435   vat_json_free (&node);
4436
4437   vam->retval = ntohl (mp->retval);
4438   vam->result_ready = 1;
4439 }
4440
4441 static void
4442   vl_api_show_one_nsh_mapping_reply_t_handler
4443   (vl_api_show_one_nsh_mapping_reply_t * mp)
4444 {
4445   vat_main_t *vam = &vat_main;
4446   i32 retval = ntohl (mp->retval);
4447
4448   if (0 <= retval)
4449     {
4450       print (vam->ofp, "%-20s%-16s",
4451              mp->is_set ? "set" : "not-set",
4452              mp->is_set ? (char *) mp->locator_set_name : "");
4453     }
4454
4455   vam->retval = retval;
4456   vam->result_ready = 1;
4457 }
4458
4459 static void
4460   vl_api_show_one_nsh_mapping_reply_t_handler_json
4461   (vl_api_show_one_nsh_mapping_reply_t * mp)
4462 {
4463   vat_main_t *vam = &vat_main;
4464   vat_json_node_t node;
4465   u8 *status = 0;
4466
4467   status = format (0, "%s", mp->is_set ? "yes" : "no");
4468   vec_add1 (status, 0);
4469
4470   vat_json_init_object (&node);
4471   vat_json_object_add_string_copy (&node, "is_set", status);
4472   if (mp->is_set)
4473     {
4474       vat_json_object_add_string_copy (&node, "locator_set",
4475                                        mp->locator_set_name);
4476     }
4477
4478   vec_free (status);
4479
4480   vat_json_print (vam->ofp, &node);
4481   vat_json_free (&node);
4482
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void
4488   vl_api_show_one_map_register_ttl_reply_t_handler
4489   (vl_api_show_one_map_register_ttl_reply_t * mp)
4490 {
4491   vat_main_t *vam = &vat_main;
4492   i32 retval = ntohl (mp->retval);
4493
4494   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4495
4496   if (0 <= retval)
4497     {
4498       print (vam->ofp, "ttl: %u", mp->ttl);
4499     }
4500
4501   vam->retval = retval;
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_show_one_map_register_ttl_reply_t_handler_json
4507   (vl_api_show_one_map_register_ttl_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   vat_json_node_t node;
4511
4512   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4513   vat_json_init_object (&node);
4514   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4515
4516   vat_json_print (vam->ofp, &node);
4517   vat_json_free (&node);
4518
4519   vam->retval = ntohl (mp->retval);
4520   vam->result_ready = 1;
4521 }
4522
4523 static void
4524 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4525 {
4526   vat_main_t *vam = &vat_main;
4527   i32 retval = ntohl (mp->retval);
4528
4529   if (0 <= retval)
4530     {
4531       print (vam->ofp, "%-20s%-16s",
4532              mp->status ? "enabled" : "disabled",
4533              mp->status ? (char *) mp->locator_set_name : "");
4534     }
4535
4536   vam->retval = retval;
4537   vam->result_ready = 1;
4538 }
4539
4540 static void
4541 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4542 {
4543   vat_main_t *vam = &vat_main;
4544   vat_json_node_t node;
4545   u8 *status = 0;
4546
4547   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4548   vec_add1 (status, 0);
4549
4550   vat_json_init_object (&node);
4551   vat_json_object_add_string_copy (&node, "status", status);
4552   if (mp->status)
4553     {
4554       vat_json_object_add_string_copy (&node, "locator_set",
4555                                        mp->locator_set_name);
4556     }
4557
4558   vec_free (status);
4559
4560   vat_json_print (vam->ofp, &node);
4561   vat_json_free (&node);
4562
4563   vam->retval = ntohl (mp->retval);
4564   vam->result_ready = 1;
4565 }
4566
4567 static u8 *
4568 format_policer_type (u8 * s, va_list * va)
4569 {
4570   u32 i = va_arg (*va, u32);
4571
4572   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4573     s = format (s, "1r2c");
4574   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4575     s = format (s, "1r3c");
4576   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4577     s = format (s, "2r3c-2698");
4578   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4579     s = format (s, "2r3c-4115");
4580   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4581     s = format (s, "2r3c-mef5cf1");
4582   else
4583     s = format (s, "ILLEGAL");
4584   return s;
4585 }
4586
4587 static u8 *
4588 format_policer_rate_type (u8 * s, va_list * va)
4589 {
4590   u32 i = va_arg (*va, u32);
4591
4592   if (i == SSE2_QOS_RATE_KBPS)
4593     s = format (s, "kbps");
4594   else if (i == SSE2_QOS_RATE_PPS)
4595     s = format (s, "pps");
4596   else
4597     s = format (s, "ILLEGAL");
4598   return s;
4599 }
4600
4601 static u8 *
4602 format_policer_round_type (u8 * s, va_list * va)
4603 {
4604   u32 i = va_arg (*va, u32);
4605
4606   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4607     s = format (s, "closest");
4608   else if (i == SSE2_QOS_ROUND_TO_UP)
4609     s = format (s, "up");
4610   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4611     s = format (s, "down");
4612   else
4613     s = format (s, "ILLEGAL");
4614   return s;
4615 }
4616
4617 static u8 *
4618 format_policer_action_type (u8 * s, va_list * va)
4619 {
4620   u32 i = va_arg (*va, u32);
4621
4622   if (i == SSE2_QOS_ACTION_DROP)
4623     s = format (s, "drop");
4624   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4625     s = format (s, "transmit");
4626   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4627     s = format (s, "mark-and-transmit");
4628   else
4629     s = format (s, "ILLEGAL");
4630   return s;
4631 }
4632
4633 static u8 *
4634 format_dscp (u8 * s, va_list * va)
4635 {
4636   u32 i = va_arg (*va, u32);
4637   char *t = 0;
4638
4639   switch (i)
4640     {
4641 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4642       foreach_vnet_dscp
4643 #undef _
4644     default:
4645       return format (s, "ILLEGAL");
4646     }
4647   s = format (s, "%s", t);
4648   return s;
4649 }
4650
4651 static void
4652 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4656
4657   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4658     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4659   else
4660     conform_dscp_str = format (0, "");
4661
4662   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4663     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4664   else
4665     exceed_dscp_str = format (0, "");
4666
4667   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4668     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4669   else
4670     violate_dscp_str = format (0, "");
4671
4672   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4673          "rate type %U, round type %U, %s rate, %s color-aware, "
4674          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4675          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4676          "conform action %U%s, exceed action %U%s, violate action %U%s",
4677          mp->name,
4678          format_policer_type, mp->type,
4679          ntohl (mp->cir),
4680          ntohl (mp->eir),
4681          clib_net_to_host_u64 (mp->cb),
4682          clib_net_to_host_u64 (mp->eb),
4683          format_policer_rate_type, mp->rate_type,
4684          format_policer_round_type, mp->round_type,
4685          mp->single_rate ? "single" : "dual",
4686          mp->color_aware ? "is" : "not",
4687          ntohl (mp->cir_tokens_per_period),
4688          ntohl (mp->pir_tokens_per_period),
4689          ntohl (mp->scale),
4690          ntohl (mp->current_limit),
4691          ntohl (mp->current_bucket),
4692          ntohl (mp->extended_limit),
4693          ntohl (mp->extended_bucket),
4694          clib_net_to_host_u64 (mp->last_update_time),
4695          format_policer_action_type, mp->conform_action_type,
4696          conform_dscp_str,
4697          format_policer_action_type, mp->exceed_action_type,
4698          exceed_dscp_str,
4699          format_policer_action_type, mp->violate_action_type,
4700          violate_dscp_str);
4701
4702   vec_free (conform_dscp_str);
4703   vec_free (exceed_dscp_str);
4704   vec_free (violate_dscp_str);
4705 }
4706
4707 static void vl_api_policer_details_t_handler_json
4708   (vl_api_policer_details_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   vat_json_node_t *node;
4712   u8 *rate_type_str, *round_type_str, *type_str;
4713   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4714
4715   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4716   round_type_str =
4717     format (0, "%U", format_policer_round_type, mp->round_type);
4718   type_str = format (0, "%U", format_policer_type, mp->type);
4719   conform_action_str = format (0, "%U", format_policer_action_type,
4720                                mp->conform_action_type);
4721   exceed_action_str = format (0, "%U", format_policer_action_type,
4722                               mp->exceed_action_type);
4723   violate_action_str = format (0, "%U", format_policer_action_type,
4724                                mp->violate_action_type);
4725
4726   if (VAT_JSON_ARRAY != vam->json_tree.type)
4727     {
4728       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4729       vat_json_init_array (&vam->json_tree);
4730     }
4731   node = vat_json_array_add (&vam->json_tree);
4732
4733   vat_json_init_object (node);
4734   vat_json_object_add_string_copy (node, "name", mp->name);
4735   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4736   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4737   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4738   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4739   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4740   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4741   vat_json_object_add_string_copy (node, "type", type_str);
4742   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4743   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4744   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4745   vat_json_object_add_uint (node, "cir_tokens_per_period",
4746                             ntohl (mp->cir_tokens_per_period));
4747   vat_json_object_add_uint (node, "eir_tokens_per_period",
4748                             ntohl (mp->pir_tokens_per_period));
4749   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4750   vat_json_object_add_uint (node, "current_bucket",
4751                             ntohl (mp->current_bucket));
4752   vat_json_object_add_uint (node, "extended_limit",
4753                             ntohl (mp->extended_limit));
4754   vat_json_object_add_uint (node, "extended_bucket",
4755                             ntohl (mp->extended_bucket));
4756   vat_json_object_add_uint (node, "last_update_time",
4757                             ntohl (mp->last_update_time));
4758   vat_json_object_add_string_copy (node, "conform_action",
4759                                    conform_action_str);
4760   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4761     {
4762       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4763       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4764       vec_free (dscp_str);
4765     }
4766   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4767   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4768     {
4769       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4770       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4771       vec_free (dscp_str);
4772     }
4773   vat_json_object_add_string_copy (node, "violate_action",
4774                                    violate_action_str);
4775   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4776     {
4777       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4778       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4779       vec_free (dscp_str);
4780     }
4781
4782   vec_free (rate_type_str);
4783   vec_free (round_type_str);
4784   vec_free (type_str);
4785   vec_free (conform_action_str);
4786   vec_free (exceed_action_str);
4787   vec_free (violate_action_str);
4788 }
4789
4790 static void
4791 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4792                                            mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   int i, count = ntohl (mp->count);
4796
4797   if (count > 0)
4798     print (vam->ofp, "classify table ids (%d) : ", count);
4799   for (i = 0; i < count; i++)
4800     {
4801       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4802       print (vam->ofp, (i < count - 1) ? "," : "");
4803     }
4804   vam->retval = ntohl (mp->retval);
4805   vam->result_ready = 1;
4806 }
4807
4808 static void
4809   vl_api_classify_table_ids_reply_t_handler_json
4810   (vl_api_classify_table_ids_reply_t * mp)
4811 {
4812   vat_main_t *vam = &vat_main;
4813   int i, count = ntohl (mp->count);
4814
4815   if (count > 0)
4816     {
4817       vat_json_node_t node;
4818
4819       vat_json_init_object (&node);
4820       for (i = 0; i < count; i++)
4821         {
4822           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4823         }
4824       vat_json_print (vam->ofp, &node);
4825       vat_json_free (&node);
4826     }
4827   vam->retval = ntohl (mp->retval);
4828   vam->result_ready = 1;
4829 }
4830
4831 static void
4832   vl_api_classify_table_by_interface_reply_t_handler
4833   (vl_api_classify_table_by_interface_reply_t * mp)
4834 {
4835   vat_main_t *vam = &vat_main;
4836   u32 table_id;
4837
4838   table_id = ntohl (mp->l2_table_id);
4839   if (table_id != ~0)
4840     print (vam->ofp, "l2 table id : %d", table_id);
4841   else
4842     print (vam->ofp, "l2 table id : No input ACL tables configured");
4843   table_id = ntohl (mp->ip4_table_id);
4844   if (table_id != ~0)
4845     print (vam->ofp, "ip4 table id : %d", table_id);
4846   else
4847     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4848   table_id = ntohl (mp->ip6_table_id);
4849   if (table_id != ~0)
4850     print (vam->ofp, "ip6 table id : %d", table_id);
4851   else
4852     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4853   vam->retval = ntohl (mp->retval);
4854   vam->result_ready = 1;
4855 }
4856
4857 static void
4858   vl_api_classify_table_by_interface_reply_t_handler_json
4859   (vl_api_classify_table_by_interface_reply_t * mp)
4860 {
4861   vat_main_t *vam = &vat_main;
4862   vat_json_node_t node;
4863
4864   vat_json_init_object (&node);
4865
4866   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4867   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4868   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4869
4870   vat_json_print (vam->ofp, &node);
4871   vat_json_free (&node);
4872
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void vl_api_policer_add_del_reply_t_handler
4878   (vl_api_policer_add_del_reply_t * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   i32 retval = ntohl (mp->retval);
4882   if (vam->async_mode)
4883     {
4884       vam->async_errors += (retval < 0);
4885     }
4886   else
4887     {
4888       vam->retval = retval;
4889       vam->result_ready = 1;
4890       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4891         /*
4892          * Note: this is just barely thread-safe, depends on
4893          * the main thread spinning waiting for an answer...
4894          */
4895         errmsg ("policer index %d", ntohl (mp->policer_index));
4896     }
4897 }
4898
4899 static void vl_api_policer_add_del_reply_t_handler_json
4900   (vl_api_policer_add_del_reply_t * mp)
4901 {
4902   vat_main_t *vam = &vat_main;
4903   vat_json_node_t node;
4904
4905   vat_json_init_object (&node);
4906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4907   vat_json_object_add_uint (&node, "policer_index",
4908                             ntohl (mp->policer_index));
4909
4910   vat_json_print (vam->ofp, &node);
4911   vat_json_free (&node);
4912
4913   vam->retval = ntohl (mp->retval);
4914   vam->result_ready = 1;
4915 }
4916
4917 /* Format hex dump. */
4918 u8 *
4919 format_hex_bytes (u8 * s, va_list * va)
4920 {
4921   u8 *bytes = va_arg (*va, u8 *);
4922   int n_bytes = va_arg (*va, int);
4923   uword i;
4924
4925   /* Print short or long form depending on byte count. */
4926   uword short_form = n_bytes <= 32;
4927   u32 indent = format_get_indent (s);
4928
4929   if (n_bytes == 0)
4930     return s;
4931
4932   for (i = 0; i < n_bytes; i++)
4933     {
4934       if (!short_form && (i % 32) == 0)
4935         s = format (s, "%08x: ", i);
4936       s = format (s, "%02x", bytes[i]);
4937       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4938         s = format (s, "\n%U", format_white_space, indent);
4939     }
4940
4941   return s;
4942 }
4943
4944 static void
4945 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4946                                             * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   i32 retval = ntohl (mp->retval);
4950   if (retval == 0)
4951     {
4952       print (vam->ofp, "classify table info :");
4953       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4954              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4955              ntohl (mp->miss_next_index));
4956       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4957              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4958              ntohl (mp->match_n_vectors));
4959       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4960              ntohl (mp->mask_length));
4961     }
4962   vam->retval = retval;
4963   vam->result_ready = 1;
4964 }
4965
4966 static void
4967   vl_api_classify_table_info_reply_t_handler_json
4968   (vl_api_classify_table_info_reply_t * mp)
4969 {
4970   vat_main_t *vam = &vat_main;
4971   vat_json_node_t node;
4972
4973   i32 retval = ntohl (mp->retval);
4974   if (retval == 0)
4975     {
4976       vat_json_init_object (&node);
4977
4978       vat_json_object_add_int (&node, "sessions",
4979                                ntohl (mp->active_sessions));
4980       vat_json_object_add_int (&node, "nexttbl",
4981                                ntohl (mp->next_table_index));
4982       vat_json_object_add_int (&node, "nextnode",
4983                                ntohl (mp->miss_next_index));
4984       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4985       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4986       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4987       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4988                       ntohl (mp->mask_length), 0);
4989       vat_json_object_add_string_copy (&node, "mask", s);
4990
4991       vat_json_print (vam->ofp, &node);
4992       vat_json_free (&node);
4993     }
4994   vam->retval = ntohl (mp->retval);
4995   vam->result_ready = 1;
4996 }
4997
4998 static void
4999 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5000                                            mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5005          ntohl (mp->hit_next_index), ntohl (mp->advance),
5006          ntohl (mp->opaque_index));
5007   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5008          ntohl (mp->match_length));
5009 }
5010
5011 static void
5012   vl_api_classify_session_details_t_handler_json
5013   (vl_api_classify_session_details_t * mp)
5014 {
5015   vat_main_t *vam = &vat_main;
5016   vat_json_node_t *node = NULL;
5017
5018   if (VAT_JSON_ARRAY != vam->json_tree.type)
5019     {
5020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5021       vat_json_init_array (&vam->json_tree);
5022     }
5023   node = vat_json_array_add (&vam->json_tree);
5024
5025   vat_json_init_object (node);
5026   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5027   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5028   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5029   u8 *s =
5030     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5031             0);
5032   vat_json_object_add_string_copy (node, "match", s);
5033 }
5034
5035 static void vl_api_pg_create_interface_reply_t_handler
5036   (vl_api_pg_create_interface_reply_t * mp)
5037 {
5038   vat_main_t *vam = &vat_main;
5039
5040   vam->retval = ntohl (mp->retval);
5041   vam->result_ready = 1;
5042 }
5043
5044 static void vl_api_pg_create_interface_reply_t_handler_json
5045   (vl_api_pg_create_interface_reply_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   vat_json_node_t node;
5049
5050   i32 retval = ntohl (mp->retval);
5051   if (retval == 0)
5052     {
5053       vat_json_init_object (&node);
5054
5055       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5056
5057       vat_json_print (vam->ofp, &node);
5058       vat_json_free (&node);
5059     }
5060   vam->retval = ntohl (mp->retval);
5061   vam->result_ready = 1;
5062 }
5063
5064 static void vl_api_policer_classify_details_t_handler
5065   (vl_api_policer_classify_details_t * mp)
5066 {
5067   vat_main_t *vam = &vat_main;
5068
5069   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5070          ntohl (mp->table_index));
5071 }
5072
5073 static void vl_api_policer_classify_details_t_handler_json
5074   (vl_api_policer_classify_details_t * mp)
5075 {
5076   vat_main_t *vam = &vat_main;
5077   vat_json_node_t *node;
5078
5079   if (VAT_JSON_ARRAY != vam->json_tree.type)
5080     {
5081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5082       vat_json_init_array (&vam->json_tree);
5083     }
5084   node = vat_json_array_add (&vam->json_tree);
5085
5086   vat_json_init_object (node);
5087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5088   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5089 }
5090
5091 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5092   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5093 {
5094   vat_main_t *vam = &vat_main;
5095   i32 retval = ntohl (mp->retval);
5096   if (vam->async_mode)
5097     {
5098       vam->async_errors += (retval < 0);
5099     }
5100   else
5101     {
5102       vam->retval = retval;
5103       vam->sw_if_index = ntohl (mp->sw_if_index);
5104       vam->result_ready = 1;
5105     }
5106   vam->regenerate_interface_table = 1;
5107 }
5108
5109 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5110   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   vat_json_node_t node;
5114
5115   vat_json_init_object (&node);
5116   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5117   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5118
5119   vat_json_print (vam->ofp, &node);
5120   vat_json_free (&node);
5121
5122   vam->retval = ntohl (mp->retval);
5123   vam->result_ready = 1;
5124 }
5125
5126 static void vl_api_flow_classify_details_t_handler
5127   (vl_api_flow_classify_details_t * mp)
5128 {
5129   vat_main_t *vam = &vat_main;
5130
5131   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5132          ntohl (mp->table_index));
5133 }
5134
5135 static void vl_api_flow_classify_details_t_handler_json
5136   (vl_api_flow_classify_details_t * mp)
5137 {
5138   vat_main_t *vam = &vat_main;
5139   vat_json_node_t *node;
5140
5141   if (VAT_JSON_ARRAY != vam->json_tree.type)
5142     {
5143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5144       vat_json_init_array (&vam->json_tree);
5145     }
5146   node = vat_json_array_add (&vam->json_tree);
5147
5148   vat_json_init_object (node);
5149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5150   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5151 }
5152
5153 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5154 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5155 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5156 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5157 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5158 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5159 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5160 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5161 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5162 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5163
5164 /*
5165  * Generate boilerplate reply handlers, which
5166  * dig the return value out of the xxx_reply_t API message,
5167  * stick it into vam->retval, and set vam->result_ready
5168  *
5169  * Could also do this by pointing N message decode slots at
5170  * a single function, but that could break in subtle ways.
5171  */
5172
5173 #define foreach_standard_reply_retval_handler           \
5174 _(sw_interface_set_flags_reply)                         \
5175 _(sw_interface_add_del_address_reply)                   \
5176 _(sw_interface_set_rx_mode_reply)                       \
5177 _(sw_interface_set_rx_placement_reply)                  \
5178 _(sw_interface_set_table_reply)                         \
5179 _(sw_interface_set_mpls_enable_reply)                   \
5180 _(sw_interface_set_vpath_reply)                         \
5181 _(sw_interface_set_vxlan_bypass_reply)                  \
5182 _(sw_interface_set_geneve_bypass_reply)                 \
5183 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5184 _(sw_interface_set_l2_bridge_reply)                     \
5185 _(bridge_domain_add_del_reply)                          \
5186 _(sw_interface_set_l2_xconnect_reply)                   \
5187 _(l2fib_add_del_reply)                                  \
5188 _(l2fib_flush_int_reply)                                \
5189 _(l2fib_flush_bd_reply)                                 \
5190 _(ip_add_del_route_reply)                               \
5191 _(ip_table_add_del_reply)                               \
5192 _(ip_mroute_add_del_reply)                              \
5193 _(mpls_route_add_del_reply)                             \
5194 _(mpls_table_add_del_reply)                             \
5195 _(mpls_ip_bind_unbind_reply)                            \
5196 _(bier_route_add_del_reply)                             \
5197 _(bier_table_add_del_reply)                             \
5198 _(proxy_arp_add_del_reply)                              \
5199 _(proxy_arp_intfc_enable_disable_reply)                 \
5200 _(sw_interface_set_unnumbered_reply)                    \
5201 _(ip_neighbor_add_del_reply)                            \
5202 _(oam_add_del_reply)                                    \
5203 _(reset_fib_reply)                                      \
5204 _(dhcp_proxy_config_reply)                              \
5205 _(dhcp_proxy_set_vss_reply)                             \
5206 _(dhcp_client_config_reply)                             \
5207 _(set_ip_flow_hash_reply)                               \
5208 _(sw_interface_ip6_enable_disable_reply)                \
5209 _(ip6nd_proxy_add_del_reply)                            \
5210 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5211 _(sw_interface_ip6nd_ra_config_reply)                   \
5212 _(set_arp_neighbor_limit_reply)                         \
5213 _(l2_patch_add_del_reply)                               \
5214 _(sr_mpls_policy_add_reply)                             \
5215 _(sr_mpls_policy_mod_reply)                             \
5216 _(sr_mpls_policy_del_reply)                             \
5217 _(sr_policy_add_reply)                                  \
5218 _(sr_policy_mod_reply)                                  \
5219 _(sr_policy_del_reply)                                  \
5220 _(sr_localsid_add_del_reply)                            \
5221 _(sr_steering_add_del_reply)                            \
5222 _(classify_add_del_session_reply)                       \
5223 _(classify_set_interface_ip_table_reply)                \
5224 _(classify_set_interface_l2_tables_reply)               \
5225 _(l2tpv3_set_tunnel_cookies_reply)                      \
5226 _(l2tpv3_interface_enable_disable_reply)                \
5227 _(l2tpv3_set_lookup_key_reply)                          \
5228 _(l2_fib_clear_table_reply)                             \
5229 _(l2_interface_efp_filter_reply)                        \
5230 _(l2_interface_vlan_tag_rewrite_reply)                  \
5231 _(modify_vhost_user_if_reply)                           \
5232 _(delete_vhost_user_if_reply)                           \
5233 _(ip_probe_neighbor_reply)                              \
5234 _(ip_scan_neighbor_enable_disable_reply)                \
5235 _(want_ip4_arp_events_reply)                            \
5236 _(want_ip6_nd_events_reply)                             \
5237 _(want_l2_macs_events_reply)                            \
5238 _(input_acl_set_interface_reply)                        \
5239 _(ipsec_spd_add_del_reply)                              \
5240 _(ipsec_interface_add_del_spd_reply)                    \
5241 _(ipsec_spd_add_del_entry_reply)                        \
5242 _(ipsec_sad_add_del_entry_reply)                        \
5243 _(ipsec_sa_set_key_reply)                               \
5244 _(ipsec_tunnel_if_add_del_reply)                        \
5245 _(ipsec_tunnel_if_set_key_reply)                        \
5246 _(ipsec_tunnel_if_set_sa_reply)                         \
5247 _(ikev2_profile_add_del_reply)                          \
5248 _(ikev2_profile_set_auth_reply)                         \
5249 _(ikev2_profile_set_id_reply)                           \
5250 _(ikev2_profile_set_ts_reply)                           \
5251 _(ikev2_set_local_key_reply)                            \
5252 _(ikev2_set_responder_reply)                            \
5253 _(ikev2_set_ike_transforms_reply)                       \
5254 _(ikev2_set_esp_transforms_reply)                       \
5255 _(ikev2_set_sa_lifetime_reply)                          \
5256 _(ikev2_initiate_sa_init_reply)                         \
5257 _(ikev2_initiate_del_ike_sa_reply)                      \
5258 _(ikev2_initiate_del_child_sa_reply)                    \
5259 _(ikev2_initiate_rekey_child_sa_reply)                  \
5260 _(delete_loopback_reply)                                \
5261 _(bd_ip_mac_add_del_reply)                              \
5262 _(bd_ip_mac_flush_reply)                                \
5263 _(want_interface_events_reply)                          \
5264 _(cop_interface_enable_disable_reply)                   \
5265 _(cop_whitelist_enable_disable_reply)                   \
5266 _(sw_interface_clear_stats_reply)                       \
5267 _(ioam_enable_reply)                                    \
5268 _(ioam_disable_reply)                                   \
5269 _(one_add_del_locator_reply)                            \
5270 _(one_add_del_local_eid_reply)                          \
5271 _(one_add_del_remote_mapping_reply)                     \
5272 _(one_add_del_adjacency_reply)                          \
5273 _(one_add_del_map_resolver_reply)                       \
5274 _(one_add_del_map_server_reply)                         \
5275 _(one_enable_disable_reply)                             \
5276 _(one_rloc_probe_enable_disable_reply)                  \
5277 _(one_map_register_enable_disable_reply)                \
5278 _(one_map_register_set_ttl_reply)                       \
5279 _(one_set_transport_protocol_reply)                     \
5280 _(one_map_register_fallback_threshold_reply)            \
5281 _(one_pitr_set_locator_set_reply)                       \
5282 _(one_map_request_mode_reply)                           \
5283 _(one_add_del_map_request_itr_rlocs_reply)              \
5284 _(one_eid_table_add_del_map_reply)                      \
5285 _(one_use_petr_reply)                                   \
5286 _(one_stats_enable_disable_reply)                       \
5287 _(one_add_del_l2_arp_entry_reply)                       \
5288 _(one_add_del_ndp_entry_reply)                          \
5289 _(one_stats_flush_reply)                                \
5290 _(one_enable_disable_xtr_mode_reply)                    \
5291 _(one_enable_disable_pitr_mode_reply)                   \
5292 _(one_enable_disable_petr_mode_reply)                   \
5293 _(gpe_enable_disable_reply)                             \
5294 _(gpe_set_encap_mode_reply)                             \
5295 _(gpe_add_del_iface_reply)                              \
5296 _(gpe_add_del_native_fwd_rpath_reply)                   \
5297 _(af_packet_delete_reply)                               \
5298 _(policer_classify_set_interface_reply)                 \
5299 _(netmap_create_reply)                                  \
5300 _(netmap_delete_reply)                                  \
5301 _(set_ipfix_exporter_reply)                             \
5302 _(set_ipfix_classify_stream_reply)                      \
5303 _(ipfix_classify_table_add_del_reply)                   \
5304 _(flow_classify_set_interface_reply)                    \
5305 _(sw_interface_span_enable_disable_reply)               \
5306 _(pg_capture_reply)                                     \
5307 _(pg_enable_disable_reply)                              \
5308 _(ip_source_and_port_range_check_add_del_reply)         \
5309 _(ip_source_and_port_range_check_interface_add_del_reply)\
5310 _(delete_subif_reply)                                   \
5311 _(l2_interface_pbb_tag_rewrite_reply)                   \
5312 _(set_punt_reply)                                       \
5313 _(feature_enable_disable_reply)                         \
5314 _(sw_interface_tag_add_del_reply)                       \
5315 _(hw_interface_set_mtu_reply)                           \
5316 _(p2p_ethernet_add_reply)                               \
5317 _(p2p_ethernet_del_reply)                               \
5318 _(lldp_config_reply)                                    \
5319 _(sw_interface_set_lldp_reply)                          \
5320 _(tcp_configure_src_addresses_reply)                    \
5321 _(dns_enable_disable_reply)                             \
5322 _(dns_name_server_add_del_reply)                        \
5323 _(session_rule_add_del_reply)                           \
5324 _(ip_container_proxy_add_del_reply)                     \
5325 _(output_acl_set_interface_reply)                       \
5326 _(qos_record_enable_disable_reply)
5327
5328 #define _(n)                                    \
5329     static void vl_api_##n##_t_handler          \
5330     (vl_api_##n##_t * mp)                       \
5331     {                                           \
5332         vat_main_t * vam = &vat_main;           \
5333         i32 retval = ntohl(mp->retval);         \
5334         if (vam->async_mode) {                  \
5335             vam->async_errors += (retval < 0);  \
5336         } else {                                \
5337             vam->retval = retval;               \
5338             vam->result_ready = 1;              \
5339         }                                       \
5340     }
5341 foreach_standard_reply_retval_handler;
5342 #undef _
5343
5344 #define _(n)                                    \
5345     static void vl_api_##n##_t_handler_json     \
5346     (vl_api_##n##_t * mp)                       \
5347     {                                           \
5348         vat_main_t * vam = &vat_main;           \
5349         vat_json_node_t node;                   \
5350         vat_json_init_object(&node);            \
5351         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5352         vat_json_print(vam->ofp, &node);        \
5353         vam->retval = ntohl(mp->retval);        \
5354         vam->result_ready = 1;                  \
5355     }
5356 foreach_standard_reply_retval_handler;
5357 #undef _
5358
5359 /*
5360  * Table of message reply handlers, must include boilerplate handlers
5361  * we just generated
5362  */
5363
5364 #define foreach_vpe_api_reply_msg                                       \
5365 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5366 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5367 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5368 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5369 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5370 _(CLI_REPLY, cli_reply)                                                 \
5371 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5372 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5373   sw_interface_add_del_address_reply)                                   \
5374 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5375 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5376 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5377 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5378 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5379 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5380 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5381 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5382 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5383 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5384   sw_interface_set_l2_xconnect_reply)                                   \
5385 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5386   sw_interface_set_l2_bridge_reply)                                     \
5387 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5388 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5389 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5390 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5391 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5392 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5393 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5394 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5395 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5396 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5397 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5398 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5399 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5400 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5401 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5402 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5403 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5404 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5405 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5406 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5407 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5408 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5409 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5410 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5411 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5412 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5413 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5414 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5415 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5416 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5417 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5418   proxy_arp_intfc_enable_disable_reply)                                 \
5419 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5420 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5421   sw_interface_set_unnumbered_reply)                                    \
5422 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5423 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5424 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5425 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5426 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5427 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5428 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5429 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5430 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5431 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5432 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5433   sw_interface_ip6_enable_disable_reply)                                \
5434 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5435 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5436 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5437   sw_interface_ip6nd_ra_prefix_reply)                                   \
5438 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5439   sw_interface_ip6nd_ra_config_reply)                                   \
5440 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5441 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5442 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5443 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5444 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5445 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5446 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5447 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5448 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5449 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5450 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5451 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5452 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5453 classify_set_interface_ip_table_reply)                                  \
5454 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5455   classify_set_interface_l2_tables_reply)                               \
5456 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5457 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5458 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5459 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5460 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5461   l2tpv3_interface_enable_disable_reply)                                \
5462 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5463 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5464 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5465 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5466 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5467 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5468 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5469 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5470 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5471 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5472 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5473 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5474 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5475 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5476 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5477 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5478 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5479 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5480 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5481 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5482 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5483 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5484 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5485 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5486 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5487 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5488 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5489 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5490 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5491 _(L2_MACS_EVENT, l2_macs_event)                                         \
5492 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5493 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5494 _(IP_DETAILS, ip_details)                                               \
5495 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5496 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5497 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5498 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5499 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5500 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5501 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5502 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5503 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5504 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5505 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5506 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5507 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5508 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5509 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5510 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5511 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5512 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5513 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5514 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5515 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5516 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5517 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5518 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5519 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5520 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5521 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5522 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5523 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5524 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5525 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5526 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5527 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5528 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5529 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5530 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5531 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5532 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5533 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5534 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5535 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5536 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5537 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5538 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5539   one_map_register_enable_disable_reply)                                \
5540 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5541 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5542 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5543 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5544   one_map_register_fallback_threshold_reply)                            \
5545 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5546   one_rloc_probe_enable_disable_reply)                                  \
5547 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5548 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5549 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5550 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5551 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5552 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5553 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5554 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5555 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5556 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5557 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5558 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5559 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5560 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5561 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5562 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5563   show_one_stats_enable_disable_reply)                                  \
5564 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5565 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5566 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5567 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5568 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5569 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5570 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5571 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5572   one_enable_disable_pitr_mode_reply)                                   \
5573 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5574   one_enable_disable_petr_mode_reply)                                   \
5575 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5576 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5577 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5578 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5579 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5580 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5581 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5582 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5583 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5584 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5585 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5586 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5587   gpe_add_del_native_fwd_rpath_reply)                                   \
5588 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5589   gpe_fwd_entry_path_details)                                           \
5590 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5591 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5592   one_add_del_map_request_itr_rlocs_reply)                              \
5593 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5594   one_get_map_request_itr_rlocs_reply)                                  \
5595 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5596 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5597 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5598 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5599 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5600 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5601   show_one_map_register_state_reply)                                    \
5602 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5603 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5604   show_one_map_register_fallback_threshold_reply)                       \
5605 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5606 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5607 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5608 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5609 _(POLICER_DETAILS, policer_details)                                     \
5610 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5611 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5612 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5613 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5614 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5615 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5616 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5617 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5618 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5619 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5620 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5621 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5622 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5623 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5624 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5625 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5626 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5627 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5628 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5629 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5630 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5631 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5632 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5633 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5634 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5635  ip_source_and_port_range_check_add_del_reply)                          \
5636 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5637  ip_source_and_port_range_check_interface_add_del_reply)                \
5638 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5639 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5640 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5641 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5642 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5643 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5644 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5645 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5646 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5647 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5648 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5649 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5650 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5651 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5652 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5653 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5654 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5655 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5656 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5657 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5658 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5659 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5660 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5661 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5662 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5663 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5664 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5665 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5666
5667 #define foreach_standalone_reply_msg                                    \
5668 _(SW_INTERFACE_EVENT, sw_interface_event)
5669
5670 typedef struct
5671 {
5672   u8 *name;
5673   u32 value;
5674 } name_sort_t;
5675
5676 #define STR_VTR_OP_CASE(op)     \
5677     case L2_VTR_ ## op:         \
5678         return "" # op;
5679
5680 static const char *
5681 str_vtr_op (u32 vtr_op)
5682 {
5683   switch (vtr_op)
5684     {
5685       STR_VTR_OP_CASE (DISABLED);
5686       STR_VTR_OP_CASE (PUSH_1);
5687       STR_VTR_OP_CASE (PUSH_2);
5688       STR_VTR_OP_CASE (POP_1);
5689       STR_VTR_OP_CASE (POP_2);
5690       STR_VTR_OP_CASE (TRANSLATE_1_1);
5691       STR_VTR_OP_CASE (TRANSLATE_1_2);
5692       STR_VTR_OP_CASE (TRANSLATE_2_1);
5693       STR_VTR_OP_CASE (TRANSLATE_2_2);
5694     }
5695
5696   return "UNKNOWN";
5697 }
5698
5699 static int
5700 dump_sub_interface_table (vat_main_t * vam)
5701 {
5702   const sw_interface_subif_t *sub = NULL;
5703
5704   if (vam->json_output)
5705     {
5706       clib_warning
5707         ("JSON output supported only for VPE API calls and dump_stats_table");
5708       return -99;
5709     }
5710
5711   print (vam->ofp,
5712          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5713          "Interface", "sw_if_index",
5714          "sub id", "dot1ad", "tags", "outer id",
5715          "inner id", "exact", "default", "outer any", "inner any");
5716
5717   vec_foreach (sub, vam->sw_if_subif_table)
5718   {
5719     print (vam->ofp,
5720            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5721            sub->interface_name,
5722            sub->sw_if_index,
5723            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5724            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5725            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5726            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5727     if (sub->vtr_op != L2_VTR_DISABLED)
5728       {
5729         print (vam->ofp,
5730                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5731                "tag1: %d tag2: %d ]",
5732                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5733                sub->vtr_tag1, sub->vtr_tag2);
5734       }
5735   }
5736
5737   return 0;
5738 }
5739
5740 static int
5741 name_sort_cmp (void *a1, void *a2)
5742 {
5743   name_sort_t *n1 = a1;
5744   name_sort_t *n2 = a2;
5745
5746   return strcmp ((char *) n1->name, (char *) n2->name);
5747 }
5748
5749 static int
5750 dump_interface_table (vat_main_t * vam)
5751 {
5752   hash_pair_t *p;
5753   name_sort_t *nses = 0, *ns;
5754
5755   if (vam->json_output)
5756     {
5757       clib_warning
5758         ("JSON output supported only for VPE API calls and dump_stats_table");
5759       return -99;
5760     }
5761
5762   /* *INDENT-OFF* */
5763   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5764   ({
5765     vec_add2 (nses, ns, 1);
5766     ns->name = (u8 *)(p->key);
5767     ns->value = (u32) p->value[0];
5768   }));
5769   /* *INDENT-ON* */
5770
5771   vec_sort_with_function (nses, name_sort_cmp);
5772
5773   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5774   vec_foreach (ns, nses)
5775   {
5776     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5777   }
5778   vec_free (nses);
5779   return 0;
5780 }
5781
5782 static int
5783 dump_ip_table (vat_main_t * vam, int is_ipv6)
5784 {
5785   const ip_details_t *det = NULL;
5786   const ip_address_details_t *address = NULL;
5787   u32 i = ~0;
5788
5789   print (vam->ofp, "%-12s", "sw_if_index");
5790
5791   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5792   {
5793     i++;
5794     if (!det->present)
5795       {
5796         continue;
5797       }
5798     print (vam->ofp, "%-12d", i);
5799     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5800     if (!det->addr)
5801       {
5802         continue;
5803       }
5804     vec_foreach (address, det->addr)
5805     {
5806       print (vam->ofp,
5807              "            %-30U%-13d",
5808              is_ipv6 ? format_ip6_address : format_ip4_address,
5809              address->ip, address->prefix_length);
5810     }
5811   }
5812
5813   return 0;
5814 }
5815
5816 static int
5817 dump_ipv4_table (vat_main_t * vam)
5818 {
5819   if (vam->json_output)
5820     {
5821       clib_warning
5822         ("JSON output supported only for VPE API calls and dump_stats_table");
5823       return -99;
5824     }
5825
5826   return dump_ip_table (vam, 0);
5827 }
5828
5829 static int
5830 dump_ipv6_table (vat_main_t * vam)
5831 {
5832   if (vam->json_output)
5833     {
5834       clib_warning
5835         ("JSON output supported only for VPE API calls and dump_stats_table");
5836       return -99;
5837     }
5838
5839   return dump_ip_table (vam, 1);
5840 }
5841
5842 /*
5843  * Pass CLI buffers directly in the CLI_INBAND API message,
5844  * instead of an additional shared memory area.
5845  */
5846 static int
5847 exec_inband (vat_main_t * vam)
5848 {
5849   vl_api_cli_inband_t *mp;
5850   unformat_input_t *i = vam->input;
5851   int ret;
5852
5853   if (vec_len (i->buffer) == 0)
5854     return -1;
5855
5856   if (vam->exec_mode == 0 && unformat (i, "mode"))
5857     {
5858       vam->exec_mode = 1;
5859       return 0;
5860     }
5861   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5862     {
5863       vam->exec_mode = 0;
5864       return 0;
5865     }
5866
5867   /*
5868    * In order for the CLI command to work, it
5869    * must be a vector ending in \n, not a C-string ending
5870    * in \n\0.
5871    */
5872   u32 len = vec_len (vam->input->buffer);
5873   M2 (CLI_INBAND, mp, len);
5874   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5875
5876   S (mp);
5877   W (ret);
5878   /* json responses may or may not include a useful reply... */
5879   if (vec_len (vam->cmd_reply))
5880     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5881   return ret;
5882 }
5883
5884 int
5885 exec (vat_main_t * vam)
5886 {
5887   return exec_inband (vam);
5888 }
5889
5890 static int
5891 api_create_loopback (vat_main_t * vam)
5892 {
5893   unformat_input_t *i = vam->input;
5894   vl_api_create_loopback_t *mp;
5895   vl_api_create_loopback_instance_t *mp_lbi;
5896   u8 mac_address[6];
5897   u8 mac_set = 0;
5898   u8 is_specified = 0;
5899   u32 user_instance = 0;
5900   int ret;
5901
5902   clib_memset (mac_address, 0, sizeof (mac_address));
5903
5904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5905     {
5906       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5907         mac_set = 1;
5908       if (unformat (i, "instance %d", &user_instance))
5909         is_specified = 1;
5910       else
5911         break;
5912     }
5913
5914   if (is_specified)
5915     {
5916       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5917       mp_lbi->is_specified = is_specified;
5918       if (is_specified)
5919         mp_lbi->user_instance = htonl (user_instance);
5920       if (mac_set)
5921         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5922       S (mp_lbi);
5923     }
5924   else
5925     {
5926       /* Construct the API message */
5927       M (CREATE_LOOPBACK, mp);
5928       if (mac_set)
5929         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5930       S (mp);
5931     }
5932
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_delete_loopback (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_delete_loopback_t *mp;
5942   u32 sw_if_index = ~0;
5943   int ret;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "sw_if_index %d", &sw_if_index))
5948         ;
5949       else
5950         break;
5951     }
5952
5953   if (sw_if_index == ~0)
5954     {
5955       errmsg ("missing sw_if_index");
5956       return -99;
5957     }
5958
5959   /* Construct the API message */
5960   M (DELETE_LOOPBACK, mp);
5961   mp->sw_if_index = ntohl (sw_if_index);
5962
5963   S (mp);
5964   W (ret);
5965   return ret;
5966 }
5967
5968 static int
5969 api_want_interface_events (vat_main_t * vam)
5970 {
5971   unformat_input_t *i = vam->input;
5972   vl_api_want_interface_events_t *mp;
5973   int enable = -1;
5974   int ret;
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "enable"))
5979         enable = 1;
5980       else if (unformat (i, "disable"))
5981         enable = 0;
5982       else
5983         break;
5984     }
5985
5986   if (enable == -1)
5987     {
5988       errmsg ("missing enable|disable");
5989       return -99;
5990     }
5991
5992   M (WANT_INTERFACE_EVENTS, mp);
5993   mp->enable_disable = enable;
5994
5995   vam->interface_event_display = enable;
5996
5997   S (mp);
5998   W (ret);
5999   return ret;
6000 }
6001
6002
6003 /* Note: non-static, called once to set up the initial intfc table */
6004 int
6005 api_sw_interface_dump (vat_main_t * vam)
6006 {
6007   vl_api_sw_interface_dump_t *mp;
6008   vl_api_control_ping_t *mp_ping;
6009   hash_pair_t *p;
6010   name_sort_t *nses = 0, *ns;
6011   sw_interface_subif_t *sub = NULL;
6012   int ret;
6013
6014   /* Toss the old name table */
6015   /* *INDENT-OFF* */
6016   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6017   ({
6018     vec_add2 (nses, ns, 1);
6019     ns->name = (u8 *)(p->key);
6020     ns->value = (u32) p->value[0];
6021   }));
6022   /* *INDENT-ON* */
6023
6024   hash_free (vam->sw_if_index_by_interface_name);
6025
6026   vec_foreach (ns, nses) vec_free (ns->name);
6027
6028   vec_free (nses);
6029
6030   vec_foreach (sub, vam->sw_if_subif_table)
6031   {
6032     vec_free (sub->interface_name);
6033   }
6034   vec_free (vam->sw_if_subif_table);
6035
6036   /* recreate the interface name hash table */
6037   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6038
6039   /*
6040    * Ask for all interface names. Otherwise, the epic catalog of
6041    * name filters becomes ridiculously long, and vat ends up needing
6042    * to be taught about new interface types.
6043    */
6044   M (SW_INTERFACE_DUMP, mp);
6045   S (mp);
6046
6047   /* Use a control ping for synchronization */
6048   MPING (CONTROL_PING, mp_ping);
6049   S (mp_ping);
6050
6051   W (ret);
6052   return ret;
6053 }
6054
6055 static int
6056 api_sw_interface_set_flags (vat_main_t * vam)
6057 {
6058   unformat_input_t *i = vam->input;
6059   vl_api_sw_interface_set_flags_t *mp;
6060   u32 sw_if_index;
6061   u8 sw_if_index_set = 0;
6062   u8 admin_up = 0;
6063   int ret;
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "admin-up"))
6069         admin_up = 1;
6070       else if (unformat (i, "admin-down"))
6071         admin_up = 0;
6072       else
6073         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6074         sw_if_index_set = 1;
6075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6076         sw_if_index_set = 1;
6077       else
6078         break;
6079     }
6080
6081   if (sw_if_index_set == 0)
6082     {
6083       errmsg ("missing interface name or sw_if_index");
6084       return -99;
6085     }
6086
6087   /* Construct the API message */
6088   M (SW_INTERFACE_SET_FLAGS, mp);
6089   mp->sw_if_index = ntohl (sw_if_index);
6090   mp->admin_up_down = admin_up;
6091
6092   /* send it... */
6093   S (mp);
6094
6095   /* Wait for a reply, return the good/bad news... */
6096   W (ret);
6097   return ret;
6098 }
6099
6100 static int
6101 api_sw_interface_set_rx_mode (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_sw_interface_set_rx_mode_t *mp;
6105   u32 sw_if_index;
6106   u8 sw_if_index_set = 0;
6107   int ret;
6108   u8 queue_id_valid = 0;
6109   u32 queue_id;
6110   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "queue %d", &queue_id))
6116         queue_id_valid = 1;
6117       else if (unformat (i, "polling"))
6118         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6119       else if (unformat (i, "interrupt"))
6120         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6121       else if (unformat (i, "adaptive"))
6122         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6123       else
6124         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6125         sw_if_index_set = 1;
6126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         sw_if_index_set = 1;
6128       else
6129         break;
6130     }
6131
6132   if (sw_if_index_set == 0)
6133     {
6134       errmsg ("missing interface name or sw_if_index");
6135       return -99;
6136     }
6137   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6138     {
6139       errmsg ("missing rx-mode");
6140       return -99;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_SET_RX_MODE, mp);
6145   mp->sw_if_index = ntohl (sw_if_index);
6146   mp->mode = mode;
6147   mp->queue_id_valid = queue_id_valid;
6148   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6149
6150   /* send it... */
6151   S (mp);
6152
6153   /* Wait for a reply, return the good/bad news... */
6154   W (ret);
6155   return ret;
6156 }
6157
6158 static int
6159 api_sw_interface_set_rx_placement (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_set_rx_placement_t *mp;
6163   u32 sw_if_index;
6164   u8 sw_if_index_set = 0;
6165   int ret;
6166   u8 is_main = 0;
6167   u32 queue_id, thread_index;
6168
6169   /* Parse args required to build the message */
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "queue %d", &queue_id))
6173         ;
6174       else if (unformat (i, "main"))
6175         is_main = 1;
6176       else if (unformat (i, "worker %d", &thread_index))
6177         ;
6178       else
6179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6182         sw_if_index_set = 1;
6183       else
6184         break;
6185     }
6186
6187   if (sw_if_index_set == 0)
6188     {
6189       errmsg ("missing interface name or sw_if_index");
6190       return -99;
6191     }
6192
6193   if (is_main)
6194     thread_index = 0;
6195   /* Construct the API message */
6196   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6197   mp->sw_if_index = ntohl (sw_if_index);
6198   mp->worker_id = ntohl (thread_index);
6199   mp->queue_id = ntohl (queue_id);
6200   mp->is_main = is_main;
6201
6202   /* send it... */
6203   S (mp);
6204   /* Wait for a reply, return the good/bad news... */
6205   W (ret);
6206   return ret;
6207 }
6208
6209 static void vl_api_sw_interface_rx_placement_details_t_handler
6210   (vl_api_sw_interface_rx_placement_details_t * mp)
6211 {
6212   vat_main_t *vam = &vat_main;
6213   u32 worker_id = ntohl (mp->worker_id);
6214
6215   print (vam->ofp,
6216          "\n%-11d %-11s %-6d %-5d %-9s",
6217          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6218          worker_id, ntohl (mp->queue_id),
6219          (mp->mode ==
6220           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6221 }
6222
6223 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6224   (vl_api_sw_interface_rx_placement_details_t * mp)
6225 {
6226   vat_main_t *vam = &vat_main;
6227   vat_json_node_t *node = NULL;
6228
6229   if (VAT_JSON_ARRAY != vam->json_tree.type)
6230     {
6231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6232       vat_json_init_array (&vam->json_tree);
6233     }
6234   node = vat_json_array_add (&vam->json_tree);
6235
6236   vat_json_init_object (node);
6237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6238   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6239   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6240   vat_json_object_add_uint (node, "mode", mp->mode);
6241 }
6242
6243 static int
6244 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6245 {
6246   unformat_input_t *i = vam->input;
6247   vl_api_sw_interface_rx_placement_dump_t *mp;
6248   vl_api_control_ping_t *mp_ping;
6249   int ret;
6250   u32 sw_if_index;
6251   u8 sw_if_index_set = 0;
6252
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set++;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set++;
6259       else
6260         break;
6261     }
6262
6263   print (vam->ofp,
6264          "\n%-11s %-11s %-6s %-5s %-4s",
6265          "sw_if_index", "main/worker", "thread", "queue", "mode");
6266
6267   /* Dump Interface rx placement */
6268   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6269
6270   if (sw_if_index_set)
6271     mp->sw_if_index = htonl (sw_if_index);
6272   else
6273     mp->sw_if_index = ~0;
6274
6275   S (mp);
6276
6277   /* Use a control ping for synchronization */
6278   MPING (CONTROL_PING, mp_ping);
6279   S (mp_ping);
6280
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static int
6286 api_sw_interface_clear_stats (vat_main_t * vam)
6287 {
6288   unformat_input_t *i = vam->input;
6289   vl_api_sw_interface_clear_stats_t *mp;
6290   u32 sw_if_index;
6291   u8 sw_if_index_set = 0;
6292   int ret;
6293
6294   /* Parse args required to build the message */
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else
6302         break;
6303     }
6304
6305   /* Construct the API message */
6306   M (SW_INTERFACE_CLEAR_STATS, mp);
6307
6308   if (sw_if_index_set == 1)
6309     mp->sw_if_index = ntohl (sw_if_index);
6310   else
6311     mp->sw_if_index = ~0;
6312
6313   /* send it... */
6314   S (mp);
6315
6316   /* Wait for a reply, return the good/bad news... */
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_sw_interface_add_del_address (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_add_del_address_t *mp;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u8 is_add = 1, del_all = 0;
6329   u32 address_length = 0;
6330   u8 v4_address_set = 0;
6331   u8 v6_address_set = 0;
6332   ip4_address_t v4address;
6333   ip6_address_t v6address;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "del-all"))
6340         del_all = 1;
6341       else if (unformat (i, "del"))
6342         is_add = 0;
6343       else
6344         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "%U/%d",
6349                          unformat_ip4_address, &v4address, &address_length))
6350         v4_address_set = 1;
6351       else if (unformat (i, "%U/%d",
6352                          unformat_ip6_address, &v6address, &address_length))
6353         v6_address_set = 1;
6354       else
6355         break;
6356     }
6357
6358   if (sw_if_index_set == 0)
6359     {
6360       errmsg ("missing interface name or sw_if_index");
6361       return -99;
6362     }
6363   if (v4_address_set && v6_address_set)
6364     {
6365       errmsg ("both v4 and v6 addresses set");
6366       return -99;
6367     }
6368   if (!v4_address_set && !v6_address_set && !del_all)
6369     {
6370       errmsg ("no addresses set");
6371       return -99;
6372     }
6373
6374   /* Construct the API message */
6375   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6376
6377   mp->sw_if_index = ntohl (sw_if_index);
6378   mp->is_add = is_add;
6379   mp->del_all = del_all;
6380   if (v6_address_set)
6381     {
6382       mp->is_ipv6 = 1;
6383       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6384     }
6385   else
6386     {
6387       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6388     }
6389   mp->address_length = address_length;
6390
6391   /* send it... */
6392   S (mp);
6393
6394   /* Wait for a reply, return good/bad news  */
6395   W (ret);
6396   return ret;
6397 }
6398
6399 static int
6400 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_sw_interface_set_mpls_enable_t *mp;
6404   u32 sw_if_index;
6405   u8 sw_if_index_set = 0;
6406   u8 enable = 1;
6407   int ret;
6408
6409   /* Parse args required to build the message */
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "disable"))
6417         enable = 0;
6418       else if (unformat (i, "dis"))
6419         enable = 0;
6420       else
6421         break;
6422     }
6423
6424   if (sw_if_index_set == 0)
6425     {
6426       errmsg ("missing interface name or sw_if_index");
6427       return -99;
6428     }
6429
6430   /* Construct the API message */
6431   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6432
6433   mp->sw_if_index = ntohl (sw_if_index);
6434   mp->enable = enable;
6435
6436   /* send it... */
6437   S (mp);
6438
6439   /* Wait for a reply... */
6440   W (ret);
6441   return ret;
6442 }
6443
6444 static int
6445 api_sw_interface_set_table (vat_main_t * vam)
6446 {
6447   unformat_input_t *i = vam->input;
6448   vl_api_sw_interface_set_table_t *mp;
6449   u32 sw_if_index, vrf_id = 0;
6450   u8 sw_if_index_set = 0;
6451   u8 is_ipv6 = 0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "vrf %d", &vrf_id))
6462         ;
6463       else if (unformat (i, "ipv6"))
6464         is_ipv6 = 1;
6465       else
6466         break;
6467     }
6468
6469   if (sw_if_index_set == 0)
6470     {
6471       errmsg ("missing interface name or sw_if_index");
6472       return -99;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_SET_TABLE, mp);
6477
6478   mp->sw_if_index = ntohl (sw_if_index);
6479   mp->is_ipv6 = is_ipv6;
6480   mp->vrf_id = ntohl (vrf_id);
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static void vl_api_sw_interface_get_table_reply_t_handler
6491   (vl_api_sw_interface_get_table_reply_t * mp)
6492 {
6493   vat_main_t *vam = &vat_main;
6494
6495   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6496
6497   vam->retval = ntohl (mp->retval);
6498   vam->result_ready = 1;
6499
6500 }
6501
6502 static void vl_api_sw_interface_get_table_reply_t_handler_json
6503   (vl_api_sw_interface_get_table_reply_t * mp)
6504 {
6505   vat_main_t *vam = &vat_main;
6506   vat_json_node_t node;
6507
6508   vat_json_init_object (&node);
6509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6510   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6511
6512   vat_json_print (vam->ofp, &node);
6513   vat_json_free (&node);
6514
6515   vam->retval = ntohl (mp->retval);
6516   vam->result_ready = 1;
6517 }
6518
6519 static int
6520 api_sw_interface_get_table (vat_main_t * vam)
6521 {
6522   unformat_input_t *i = vam->input;
6523   vl_api_sw_interface_get_table_t *mp;
6524   u32 sw_if_index;
6525   u8 sw_if_index_set = 0;
6526   u8 is_ipv6 = 0;
6527   int ret;
6528
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
6535       else if (unformat (i, "ipv6"))
6536         is_ipv6 = 1;
6537       else
6538         break;
6539     }
6540
6541   if (sw_if_index_set == 0)
6542     {
6543       errmsg ("missing interface name or sw_if_index");
6544       return -99;
6545     }
6546
6547   M (SW_INTERFACE_GET_TABLE, mp);
6548   mp->sw_if_index = htonl (sw_if_index);
6549   mp->is_ipv6 = is_ipv6;
6550
6551   S (mp);
6552   W (ret);
6553   return ret;
6554 }
6555
6556 static int
6557 api_sw_interface_set_vpath (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_sw_interface_set_vpath_t *mp;
6561   u32 sw_if_index = 0;
6562   u8 sw_if_index_set = 0;
6563   u8 is_enable = 0;
6564   int ret;
6565
6566   /* Parse args required to build the message */
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6570         sw_if_index_set = 1;
6571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6572         sw_if_index_set = 1;
6573       else if (unformat (i, "enable"))
6574         is_enable = 1;
6575       else if (unformat (i, "disable"))
6576         is_enable = 0;
6577       else
6578         break;
6579     }
6580
6581   if (sw_if_index_set == 0)
6582     {
6583       errmsg ("missing interface name or sw_if_index");
6584       return -99;
6585     }
6586
6587   /* Construct the API message */
6588   M (SW_INTERFACE_SET_VPATH, mp);
6589
6590   mp->sw_if_index = ntohl (sw_if_index);
6591   mp->enable = is_enable;
6592
6593   /* send it... */
6594   S (mp);
6595
6596   /* Wait for a reply... */
6597   W (ret);
6598   return ret;
6599 }
6600
6601 static int
6602 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6606   u32 sw_if_index = 0;
6607   u8 sw_if_index_set = 0;
6608   u8 is_enable = 1;
6609   u8 is_ipv6 = 0;
6610   int ret;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "enable"))
6620         is_enable = 1;
6621       else if (unformat (i, "disable"))
6622         is_enable = 0;
6623       else if (unformat (i, "ip4"))
6624         is_ipv6 = 0;
6625       else if (unformat (i, "ip6"))
6626         is_ipv6 = 1;
6627       else
6628         break;
6629     }
6630
6631   if (sw_if_index_set == 0)
6632     {
6633       errmsg ("missing interface name or sw_if_index");
6634       return -99;
6635     }
6636
6637   /* Construct the API message */
6638   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6639
6640   mp->sw_if_index = ntohl (sw_if_index);
6641   mp->enable = is_enable;
6642   mp->is_ipv6 = is_ipv6;
6643
6644   /* send it... */
6645   S (mp);
6646
6647   /* Wait for a reply... */
6648   W (ret);
6649   return ret;
6650 }
6651
6652 static int
6653 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6654 {
6655   unformat_input_t *i = vam->input;
6656   vl_api_sw_interface_set_geneve_bypass_t *mp;
6657   u32 sw_if_index = 0;
6658   u8 sw_if_index_set = 0;
6659   u8 is_enable = 1;
6660   u8 is_ipv6 = 0;
6661   int ret;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "enable"))
6671         is_enable = 1;
6672       else if (unformat (i, "disable"))
6673         is_enable = 0;
6674       else if (unformat (i, "ip4"))
6675         is_ipv6 = 0;
6676       else if (unformat (i, "ip6"))
6677         is_ipv6 = 1;
6678       else
6679         break;
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index");
6685       return -99;
6686     }
6687
6688   /* Construct the API message */
6689   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6690
6691   mp->sw_if_index = ntohl (sw_if_index);
6692   mp->enable = is_enable;
6693   mp->is_ipv6 = is_ipv6;
6694
6695   /* send it... */
6696   S (mp);
6697
6698   /* Wait for a reply... */
6699   W (ret);
6700   return ret;
6701 }
6702
6703 static int
6704 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6705 {
6706   unformat_input_t *i = vam->input;
6707   vl_api_sw_interface_set_l2_xconnect_t *mp;
6708   u32 rx_sw_if_index;
6709   u8 rx_sw_if_index_set = 0;
6710   u32 tx_sw_if_index;
6711   u8 tx_sw_if_index_set = 0;
6712   u8 enable = 1;
6713   int ret;
6714
6715   /* Parse args required to build the message */
6716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6717     {
6718       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6719         rx_sw_if_index_set = 1;
6720       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6721         tx_sw_if_index_set = 1;
6722       else if (unformat (i, "rx"))
6723         {
6724           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725             {
6726               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6727                             &rx_sw_if_index))
6728                 rx_sw_if_index_set = 1;
6729             }
6730           else
6731             break;
6732         }
6733       else if (unformat (i, "tx"))
6734         {
6735           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736             {
6737               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6738                             &tx_sw_if_index))
6739                 tx_sw_if_index_set = 1;
6740             }
6741           else
6742             break;
6743         }
6744       else if (unformat (i, "enable"))
6745         enable = 1;
6746       else if (unformat (i, "disable"))
6747         enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (rx_sw_if_index_set == 0)
6753     {
6754       errmsg ("missing rx interface name or rx_sw_if_index");
6755       return -99;
6756     }
6757
6758   if (enable && (tx_sw_if_index_set == 0))
6759     {
6760       errmsg ("missing tx interface name or tx_sw_if_index");
6761       return -99;
6762     }
6763
6764   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6765
6766   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6767   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6768   mp->enable = enable;
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_set_l2_bridge_t *mp;
6780   vl_api_l2_port_type_t port_type;
6781   u32 rx_sw_if_index;
6782   u8 rx_sw_if_index_set = 0;
6783   u32 bd_id;
6784   u8 bd_id_set = 0;
6785   u32 shg = 0;
6786   u8 enable = 1;
6787   int ret;
6788
6789   port_type = L2_API_PORT_TYPE_NORMAL;
6790
6791   /* Parse args required to build the message */
6792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6793     {
6794       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6795         rx_sw_if_index_set = 1;
6796       else if (unformat (i, "bd_id %d", &bd_id))
6797         bd_id_set = 1;
6798       else
6799         if (unformat
6800             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6801         rx_sw_if_index_set = 1;
6802       else if (unformat (i, "shg %d", &shg))
6803         ;
6804       else if (unformat (i, "bvi"))
6805         port_type = L2_API_PORT_TYPE_BVI;
6806       else if (unformat (i, "uu-fwd"))
6807         port_type = L2_API_PORT_TYPE_UU_FWD;
6808       else if (unformat (i, "enable"))
6809         enable = 1;
6810       else if (unformat (i, "disable"))
6811         enable = 0;
6812       else
6813         break;
6814     }
6815
6816   if (rx_sw_if_index_set == 0)
6817     {
6818       errmsg ("missing rx interface name or sw_if_index");
6819       return -99;
6820     }
6821
6822   if (enable && (bd_id_set == 0))
6823     {
6824       errmsg ("missing bridge domain");
6825       return -99;
6826     }
6827
6828   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6829
6830   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6831   mp->bd_id = ntohl (bd_id);
6832   mp->shg = (u8) shg;
6833   mp->port_type = ntohl (port_type);
6834   mp->enable = enable;
6835
6836   S (mp);
6837   W (ret);
6838   return ret;
6839 }
6840
6841 static int
6842 api_bridge_domain_dump (vat_main_t * vam)
6843 {
6844   unformat_input_t *i = vam->input;
6845   vl_api_bridge_domain_dump_t *mp;
6846   vl_api_control_ping_t *mp_ping;
6847   u32 bd_id = ~0;
6848   int ret;
6849
6850   /* Parse args required to build the message */
6851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6852     {
6853       if (unformat (i, "bd_id %d", &bd_id))
6854         ;
6855       else
6856         break;
6857     }
6858
6859   M (BRIDGE_DOMAIN_DUMP, mp);
6860   mp->bd_id = ntohl (bd_id);
6861   S (mp);
6862
6863   /* Use a control ping for synchronization */
6864   MPING (CONTROL_PING, mp_ping);
6865   S (mp_ping);
6866
6867   W (ret);
6868   return ret;
6869 }
6870
6871 static int
6872 api_bridge_domain_add_del (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_bridge_domain_add_del_t *mp;
6876   u32 bd_id = ~0;
6877   u8 is_add = 1;
6878   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6879   u8 *bd_tag = NULL;
6880   u32 mac_age = 0;
6881   int ret;
6882
6883   /* Parse args required to build the message */
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "bd_id %d", &bd_id))
6887         ;
6888       else if (unformat (i, "flood %d", &flood))
6889         ;
6890       else if (unformat (i, "uu-flood %d", &uu_flood))
6891         ;
6892       else if (unformat (i, "forward %d", &forward))
6893         ;
6894       else if (unformat (i, "learn %d", &learn))
6895         ;
6896       else if (unformat (i, "arp-term %d", &arp_term))
6897         ;
6898       else if (unformat (i, "mac-age %d", &mac_age))
6899         ;
6900       else if (unformat (i, "bd-tag %s", &bd_tag))
6901         ;
6902       else if (unformat (i, "del"))
6903         {
6904           is_add = 0;
6905           flood = uu_flood = forward = learn = 0;
6906         }
6907       else
6908         break;
6909     }
6910
6911   if (bd_id == ~0)
6912     {
6913       errmsg ("missing bridge domain");
6914       ret = -99;
6915       goto done;
6916     }
6917
6918   if (mac_age > 255)
6919     {
6920       errmsg ("mac age must be less than 256 ");
6921       ret = -99;
6922       goto done;
6923     }
6924
6925   if ((bd_tag) && (vec_len (bd_tag) > 63))
6926     {
6927       errmsg ("bd-tag cannot be longer than 63");
6928       ret = -99;
6929       goto done;
6930     }
6931
6932   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6933
6934   mp->bd_id = ntohl (bd_id);
6935   mp->flood = flood;
6936   mp->uu_flood = uu_flood;
6937   mp->forward = forward;
6938   mp->learn = learn;
6939   mp->arp_term = arp_term;
6940   mp->is_add = is_add;
6941   mp->mac_age = (u8) mac_age;
6942   if (bd_tag)
6943     {
6944       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6945       mp->bd_tag[vec_len (bd_tag)] = 0;
6946     }
6947   S (mp);
6948   W (ret);
6949
6950 done:
6951   vec_free (bd_tag);
6952   return ret;
6953 }
6954
6955 static int
6956 api_l2fib_flush_bd (vat_main_t * vam)
6957 {
6958   unformat_input_t *i = vam->input;
6959   vl_api_l2fib_flush_bd_t *mp;
6960   u32 bd_id = ~0;
6961   int ret;
6962
6963   /* Parse args required to build the message */
6964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6965     {
6966       if (unformat (i, "bd_id %d", &bd_id));
6967       else
6968         break;
6969     }
6970
6971   if (bd_id == ~0)
6972     {
6973       errmsg ("missing bridge domain");
6974       return -99;
6975     }
6976
6977   M (L2FIB_FLUSH_BD, mp);
6978
6979   mp->bd_id = htonl (bd_id);
6980
6981   S (mp);
6982   W (ret);
6983   return ret;
6984 }
6985
6986 static int
6987 api_l2fib_flush_int (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_l2fib_flush_int_t *mp;
6991   u32 sw_if_index = ~0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index));
6998       else
6999         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7000       else
7001         break;
7002     }
7003
7004   if (sw_if_index == ~0)
7005     {
7006       errmsg ("missing interface name or sw_if_index");
7007       return -99;
7008     }
7009
7010   M (L2FIB_FLUSH_INT, mp);
7011
7012   mp->sw_if_index = ntohl (sw_if_index);
7013
7014   S (mp);
7015   W (ret);
7016   return ret;
7017 }
7018
7019 static int
7020 api_l2fib_add_del (vat_main_t * vam)
7021 {
7022   unformat_input_t *i = vam->input;
7023   vl_api_l2fib_add_del_t *mp;
7024   f64 timeout;
7025   u8 mac[6] = { 0 };
7026   u8 mac_set = 0;
7027   u32 bd_id;
7028   u8 bd_id_set = 0;
7029   u32 sw_if_index = 0;
7030   u8 sw_if_index_set = 0;
7031   u8 is_add = 1;
7032   u8 static_mac = 0;
7033   u8 filter_mac = 0;
7034   u8 bvi_mac = 0;
7035   int count = 1;
7036   f64 before = 0;
7037   int j;
7038
7039   /* Parse args required to build the message */
7040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041     {
7042       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7043         mac_set = 1;
7044       else if (unformat (i, "bd_id %d", &bd_id))
7045         bd_id_set = 1;
7046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7047         sw_if_index_set = 1;
7048       else if (unformat (i, "sw_if"))
7049         {
7050           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051             {
7052               if (unformat
7053                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7054                 sw_if_index_set = 1;
7055             }
7056           else
7057             break;
7058         }
7059       else if (unformat (i, "static"))
7060         static_mac = 1;
7061       else if (unformat (i, "filter"))
7062         {
7063           filter_mac = 1;
7064           static_mac = 1;
7065         }
7066       else if (unformat (i, "bvi"))
7067         {
7068           bvi_mac = 1;
7069           static_mac = 1;
7070         }
7071       else if (unformat (i, "del"))
7072         is_add = 0;
7073       else if (unformat (i, "count %d", &count))
7074         ;
7075       else
7076         break;
7077     }
7078
7079   if (mac_set == 0)
7080     {
7081       errmsg ("missing mac address");
7082       return -99;
7083     }
7084
7085   if (bd_id_set == 0)
7086     {
7087       errmsg ("missing bridge domain");
7088       return -99;
7089     }
7090
7091   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7092     {
7093       errmsg ("missing interface name or sw_if_index");
7094       return -99;
7095     }
7096
7097   if (count > 1)
7098     {
7099       /* Turn on async mode */
7100       vam->async_mode = 1;
7101       vam->async_errors = 0;
7102       before = vat_time_now (vam);
7103     }
7104
7105   for (j = 0; j < count; j++)
7106     {
7107       M (L2FIB_ADD_DEL, mp);
7108
7109       clib_memcpy (mp->mac, mac, 6);
7110       mp->bd_id = ntohl (bd_id);
7111       mp->is_add = is_add;
7112       mp->sw_if_index = ntohl (sw_if_index);
7113
7114       if (is_add)
7115         {
7116           mp->static_mac = static_mac;
7117           mp->filter_mac = filter_mac;
7118           mp->bvi_mac = bvi_mac;
7119         }
7120       increment_mac_address (mac);
7121       /* send it... */
7122       S (mp);
7123     }
7124
7125   if (count > 1)
7126     {
7127       vl_api_control_ping_t *mp_ping;
7128       f64 after;
7129
7130       /* Shut off async mode */
7131       vam->async_mode = 0;
7132
7133       MPING (CONTROL_PING, mp_ping);
7134       S (mp_ping);
7135
7136       timeout = vat_time_now (vam) + 1.0;
7137       while (vat_time_now (vam) < timeout)
7138         if (vam->result_ready == 1)
7139           goto out;
7140       vam->retval = -99;
7141
7142     out:
7143       if (vam->retval == -99)
7144         errmsg ("timeout");
7145
7146       if (vam->async_errors > 0)
7147         {
7148           errmsg ("%d asynchronous errors", vam->async_errors);
7149           vam->retval = -98;
7150         }
7151       vam->async_errors = 0;
7152       after = vat_time_now (vam);
7153
7154       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7155              count, after - before, count / (after - before));
7156     }
7157   else
7158     {
7159       int ret;
7160
7161       /* Wait for a reply... */
7162       W (ret);
7163       return ret;
7164     }
7165   /* Return the good/bad news */
7166   return (vam->retval);
7167 }
7168
7169 static int
7170 api_bridge_domain_set_mac_age (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_bridge_domain_set_mac_age_t *mp;
7174   u32 bd_id = ~0;
7175   u32 mac_age = 0;
7176   int ret;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "bd_id %d", &bd_id));
7182       else if (unformat (i, "mac-age %d", &mac_age));
7183       else
7184         break;
7185     }
7186
7187   if (bd_id == ~0)
7188     {
7189       errmsg ("missing bridge domain");
7190       return -99;
7191     }
7192
7193   if (mac_age > 255)
7194     {
7195       errmsg ("mac age must be less than 256 ");
7196       return -99;
7197     }
7198
7199   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7200
7201   mp->bd_id = htonl (bd_id);
7202   mp->mac_age = (u8) mac_age;
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_l2_flags (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_l2_flags_t *mp;
7214   u32 sw_if_index;
7215   u32 flags = 0;
7216   u8 sw_if_index_set = 0;
7217   u8 is_set = 0;
7218   int ret;
7219
7220   /* Parse args required to build the message */
7221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222     {
7223       if (unformat (i, "sw_if_index %d", &sw_if_index))
7224         sw_if_index_set = 1;
7225       else if (unformat (i, "sw_if"))
7226         {
7227           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228             {
7229               if (unformat
7230                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7231                 sw_if_index_set = 1;
7232             }
7233           else
7234             break;
7235         }
7236       else if (unformat (i, "learn"))
7237         flags |= L2_LEARN;
7238       else if (unformat (i, "forward"))
7239         flags |= L2_FWD;
7240       else if (unformat (i, "flood"))
7241         flags |= L2_FLOOD;
7242       else if (unformat (i, "uu-flood"))
7243         flags |= L2_UU_FLOOD;
7244       else if (unformat (i, "arp-term"))
7245         flags |= L2_ARP_TERM;
7246       else if (unformat (i, "off"))
7247         is_set = 0;
7248       else if (unformat (i, "disable"))
7249         is_set = 0;
7250       else
7251         break;
7252     }
7253
7254   if (sw_if_index_set == 0)
7255     {
7256       errmsg ("missing interface name or sw_if_index");
7257       return -99;
7258     }
7259
7260   M (L2_FLAGS, mp);
7261
7262   mp->sw_if_index = ntohl (sw_if_index);
7263   mp->feature_bitmap = ntohl (flags);
7264   mp->is_set = is_set;
7265
7266   S (mp);
7267   W (ret);
7268   return ret;
7269 }
7270
7271 static int
7272 api_bridge_flags (vat_main_t * vam)
7273 {
7274   unformat_input_t *i = vam->input;
7275   vl_api_bridge_flags_t *mp;
7276   u32 bd_id;
7277   u8 bd_id_set = 0;
7278   u8 is_set = 1;
7279   bd_flags_t flags = 0;
7280   int ret;
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         bd_id_set = 1;
7287       else if (unformat (i, "learn"))
7288         flags |= BRIDGE_API_FLAG_LEARN;
7289       else if (unformat (i, "forward"))
7290         flags |= BRIDGE_API_FLAG_FWD;
7291       else if (unformat (i, "flood"))
7292         flags |= BRIDGE_API_FLAG_FLOOD;
7293       else if (unformat (i, "uu-flood"))
7294         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7295       else if (unformat (i, "arp-term"))
7296         flags |= BRIDGE_API_FLAG_ARP_TERM;
7297       else if (unformat (i, "off"))
7298         is_set = 0;
7299       else if (unformat (i, "disable"))
7300         is_set = 0;
7301       else
7302         break;
7303     }
7304
7305   if (bd_id_set == 0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310
7311   M (BRIDGE_FLAGS, mp);
7312
7313   mp->bd_id = ntohl (bd_id);
7314   mp->flags = ntohl (flags);
7315   mp->is_set = is_set;
7316
7317   S (mp);
7318   W (ret);
7319   return ret;
7320 }
7321
7322 static int
7323 api_bd_ip_mac_add_del (vat_main_t * vam)
7324 {
7325   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7326   vl_api_mac_address_t mac = { 0 };
7327   unformat_input_t *i = vam->input;
7328   vl_api_bd_ip_mac_add_del_t *mp;
7329   ip46_type_t type;
7330   u32 bd_id;
7331   u8 is_ipv6 = 0;
7332   u8 is_add = 1;
7333   u8 bd_id_set = 0;
7334   u8 ip_set = 0;
7335   u8 mac_set = 0;
7336   u8 macaddr[6];
7337   int ret;
7338
7339
7340   /* Parse args required to build the message */
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7348         {
7349           ip_set++;
7350         }
7351       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7352         {
7353           mac_set++;
7354         }
7355       else if (unformat (i, "del"))
7356         is_add = 0;
7357       else
7358         break;
7359     }
7360
7361   if (bd_id_set == 0)
7362     {
7363       errmsg ("missing bridge domain");
7364       return -99;
7365     }
7366   else if (ip_set == 0)
7367     {
7368       errmsg ("missing IP address");
7369       return -99;
7370     }
7371   else if (mac_set == 0)
7372     {
7373       errmsg ("missing MAC address");
7374       return -99;
7375     }
7376
7377   M (BD_IP_MAC_ADD_DEL, mp);
7378
7379   mp->bd_id = ntohl (bd_id);
7380   mp->is_add = is_add;
7381
7382   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7383   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7384
7385   S (mp);
7386   W (ret);
7387   return ret;
7388 }
7389
7390 static int
7391 api_bd_ip_mac_flush (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_bd_ip_mac_flush_t *mp;
7395   u32 bd_id;
7396   u8 bd_id_set = 0;
7397   int ret;
7398
7399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7400     {
7401       if (unformat (i, "bd_id %d", &bd_id))
7402         {
7403           bd_id_set++;
7404         }
7405       else
7406         break;
7407     }
7408
7409   if (bd_id_set == 0)
7410     {
7411       errmsg ("missing bridge domain");
7412       return -99;
7413     }
7414
7415   M (BD_IP_MAC_FLUSH, mp);
7416
7417   mp->bd_id = ntohl (bd_id);
7418
7419   S (mp);
7420   W (ret);
7421   return ret;
7422 }
7423
7424 static void vl_api_bd_ip_mac_details_t_handler
7425   (vl_api_bd_ip_mac_details_t * mp)
7426 {
7427   vat_main_t *vam = &vat_main;
7428   u8 *ip = 0;
7429
7430   if (!mp->is_ipv6)
7431     ip =
7432       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7433   else
7434     ip =
7435       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7436
7437   print (vam->ofp,
7438          "\n%-5d %-7s %-20U %-30s",
7439          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7440          format_ethernet_address, mp->mac_address, ip);
7441
7442   vec_free (ip);
7443 }
7444
7445 static void vl_api_bd_ip_mac_details_t_handler_json
7446   (vl_api_bd_ip_mac_details_t * mp)
7447 {
7448   vat_main_t *vam = &vat_main;
7449   vat_json_node_t *node = NULL;
7450
7451   if (VAT_JSON_ARRAY != vam->json_tree.type)
7452     {
7453       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7454       vat_json_init_array (&vam->json_tree);
7455     }
7456   node = vat_json_array_add (&vam->json_tree);
7457
7458   vat_json_init_object (node);
7459   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7460   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7461   vat_json_object_add_string_copy (node, "mac_address",
7462                                    format (0, "%U", format_ethernet_address,
7463                                            &mp->mac_address));
7464   u8 *ip = 0;
7465
7466   if (!mp->is_ipv6)
7467     ip =
7468       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7469   else
7470     ip =
7471       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7472   vat_json_object_add_string_copy (node, "ip_address", ip);
7473   vec_free (ip);
7474 }
7475
7476 static int
7477 api_bd_ip_mac_dump (vat_main_t * vam)
7478 {
7479   unformat_input_t *i = vam->input;
7480   vl_api_bd_ip_mac_dump_t *mp;
7481   vl_api_control_ping_t *mp_ping;
7482   int ret;
7483   u32 bd_id;
7484   u8 bd_id_set = 0;
7485
7486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7487     {
7488       if (unformat (i, "bd_id %d", &bd_id))
7489         {
7490           bd_id_set++;
7491         }
7492       else
7493         break;
7494     }
7495
7496   print (vam->ofp,
7497          "\n%-5s %-7s %-20s %-30s",
7498          "bd_id", "is_ipv6", "mac_address", "ip_address");
7499
7500   /* Dump Bridge Domain Ip to Mac entries */
7501   M (BD_IP_MAC_DUMP, mp);
7502
7503   if (bd_id_set)
7504     mp->bd_id = htonl (bd_id);
7505   else
7506     mp->bd_id = ~0;
7507
7508   S (mp);
7509
7510   /* Use a control ping for synchronization */
7511   MPING (CONTROL_PING, mp_ping);
7512   S (mp_ping);
7513
7514   W (ret);
7515   return ret;
7516 }
7517
7518 static int
7519 api_tap_connect (vat_main_t * vam)
7520 {
7521   unformat_input_t *i = vam->input;
7522   vl_api_tap_connect_t *mp;
7523   u8 mac_address[6];
7524   u8 random_mac = 1;
7525   u8 name_set = 0;
7526   u8 *tap_name;
7527   u8 *tag = 0;
7528   ip4_address_t ip4_address;
7529   u32 ip4_mask_width;
7530   int ip4_address_set = 0;
7531   ip6_address_t ip6_address;
7532   u32 ip6_mask_width;
7533   int ip6_address_set = 0;
7534   int ret;
7535
7536   clib_memset (mac_address, 0, sizeof (mac_address));
7537
7538   /* Parse args required to build the message */
7539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7540     {
7541       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7542         {
7543           random_mac = 0;
7544         }
7545       else if (unformat (i, "random-mac"))
7546         random_mac = 1;
7547       else if (unformat (i, "tapname %s", &tap_name))
7548         name_set = 1;
7549       else if (unformat (i, "tag %s", &tag))
7550         ;
7551       else if (unformat (i, "address %U/%d",
7552                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7553         ip4_address_set = 1;
7554       else if (unformat (i, "address %U/%d",
7555                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7556         ip6_address_set = 1;
7557       else
7558         break;
7559     }
7560
7561   if (name_set == 0)
7562     {
7563       errmsg ("missing tap name");
7564       return -99;
7565     }
7566   if (vec_len (tap_name) > 63)
7567     {
7568       errmsg ("tap name too long");
7569       return -99;
7570     }
7571   vec_add1 (tap_name, 0);
7572
7573   if (vec_len (tag) > 63)
7574     {
7575       errmsg ("tag too long");
7576       return -99;
7577     }
7578
7579   /* Construct the API message */
7580   M (TAP_CONNECT, mp);
7581
7582   mp->use_random_mac = random_mac;
7583   clib_memcpy (mp->mac_address, mac_address, 6);
7584   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7585   if (tag)
7586     clib_memcpy (mp->tag, tag, vec_len (tag));
7587
7588   if (ip4_address_set)
7589     {
7590       mp->ip4_address_set = 1;
7591       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7592       mp->ip4_mask_width = ip4_mask_width;
7593     }
7594   if (ip6_address_set)
7595     {
7596       mp->ip6_address_set = 1;
7597       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7598       mp->ip6_mask_width = ip6_mask_width;
7599     }
7600
7601   vec_free (tap_name);
7602   vec_free (tag);
7603
7604   /* send it... */
7605   S (mp);
7606
7607   /* Wait for a reply... */
7608   W (ret);
7609   return ret;
7610 }
7611
7612 static int
7613 api_tap_modify (vat_main_t * vam)
7614 {
7615   unformat_input_t *i = vam->input;
7616   vl_api_tap_modify_t *mp;
7617   u8 mac_address[6];
7618   u8 random_mac = 1;
7619   u8 name_set = 0;
7620   u8 *tap_name;
7621   u32 sw_if_index = ~0;
7622   u8 sw_if_index_set = 0;
7623   int ret;
7624
7625   clib_memset (mac_address, 0, sizeof (mac_address));
7626
7627   /* Parse args required to build the message */
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7631         sw_if_index_set = 1;
7632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7633         sw_if_index_set = 1;
7634       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7635         {
7636           random_mac = 0;
7637         }
7638       else if (unformat (i, "random-mac"))
7639         random_mac = 1;
7640       else if (unformat (i, "tapname %s", &tap_name))
7641         name_set = 1;
7642       else
7643         break;
7644     }
7645
7646   if (sw_if_index_set == 0)
7647     {
7648       errmsg ("missing vpp interface name");
7649       return -99;
7650     }
7651   if (name_set == 0)
7652     {
7653       errmsg ("missing tap name");
7654       return -99;
7655     }
7656   if (vec_len (tap_name) > 63)
7657     {
7658       errmsg ("tap name too long");
7659     }
7660   vec_add1 (tap_name, 0);
7661
7662   /* Construct the API message */
7663   M (TAP_MODIFY, mp);
7664
7665   mp->use_random_mac = random_mac;
7666   mp->sw_if_index = ntohl (sw_if_index);
7667   clib_memcpy (mp->mac_address, mac_address, 6);
7668   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7669   vec_free (tap_name);
7670
7671   /* send it... */
7672   S (mp);
7673
7674   /* Wait for a reply... */
7675   W (ret);
7676   return ret;
7677 }
7678
7679 static int
7680 api_tap_delete (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_tap_delete_t *mp;
7684   u32 sw_if_index = ~0;
7685   u8 sw_if_index_set = 0;
7686   int ret;
7687
7688   /* Parse args required to build the message */
7689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7690     {
7691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7692         sw_if_index_set = 1;
7693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7694         sw_if_index_set = 1;
7695       else
7696         break;
7697     }
7698
7699   if (sw_if_index_set == 0)
7700     {
7701       errmsg ("missing vpp interface name");
7702       return -99;
7703     }
7704
7705   /* Construct the API message */
7706   M (TAP_DELETE, mp);
7707
7708   mp->sw_if_index = ntohl (sw_if_index);
7709
7710   /* send it... */
7711   S (mp);
7712
7713   /* Wait for a reply... */
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_tap_create_v2 (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_tap_create_v2_t *mp;
7723   u8 mac_address[6];
7724   u8 random_mac = 1;
7725   u32 id = ~0;
7726   u8 *host_if_name = 0;
7727   u8 *host_ns = 0;
7728   u8 host_mac_addr[6];
7729   u8 host_mac_addr_set = 0;
7730   u8 *host_bridge = 0;
7731   ip4_address_t host_ip4_addr;
7732   ip4_address_t host_ip4_gw;
7733   u8 host_ip4_gw_set = 0;
7734   u32 host_ip4_prefix_len = 0;
7735   ip6_address_t host_ip6_addr;
7736   ip6_address_t host_ip6_gw;
7737   u8 host_ip6_gw_set = 0;
7738   u32 host_ip6_prefix_len = 0;
7739   int ret;
7740   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7741
7742   clib_memset (mac_address, 0, sizeof (mac_address));
7743
7744   /* Parse args required to build the message */
7745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7746     {
7747       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7748         {
7749           random_mac = 0;
7750         }
7751       else if (unformat (i, "id %u", &id))
7752         ;
7753       else if (unformat (i, "host-if-name %s", &host_if_name))
7754         ;
7755       else if (unformat (i, "host-ns %s", &host_ns))
7756         ;
7757       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7758                          host_mac_addr))
7759         host_mac_addr_set = 1;
7760       else if (unformat (i, "host-bridge %s", &host_bridge))
7761         ;
7762       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7763                          &host_ip4_addr, &host_ip4_prefix_len))
7764         ;
7765       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7766                          &host_ip6_addr, &host_ip6_prefix_len))
7767         ;
7768       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7769                          &host_ip4_gw))
7770         host_ip4_gw_set = 1;
7771       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7772                          &host_ip6_gw))
7773         host_ip6_gw_set = 1;
7774       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7775         ;
7776       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7777         ;
7778       else
7779         break;
7780     }
7781
7782   if (vec_len (host_if_name) > 63)
7783     {
7784       errmsg ("tap name too long. ");
7785       return -99;
7786     }
7787   if (vec_len (host_ns) > 63)
7788     {
7789       errmsg ("host name space too long. ");
7790       return -99;
7791     }
7792   if (vec_len (host_bridge) > 63)
7793     {
7794       errmsg ("host bridge name too long. ");
7795       return -99;
7796     }
7797   if (host_ip4_prefix_len > 32)
7798     {
7799       errmsg ("host ip4 prefix length not valid. ");
7800       return -99;
7801     }
7802   if (host_ip6_prefix_len > 128)
7803     {
7804       errmsg ("host ip6 prefix length not valid. ");
7805       return -99;
7806     }
7807   if (!is_pow2 (rx_ring_sz))
7808     {
7809       errmsg ("rx ring size must be power of 2. ");
7810       return -99;
7811     }
7812   if (rx_ring_sz > 32768)
7813     {
7814       errmsg ("rx ring size must be 32768 or lower. ");
7815       return -99;
7816     }
7817   if (!is_pow2 (tx_ring_sz))
7818     {
7819       errmsg ("tx ring size must be power of 2. ");
7820       return -99;
7821     }
7822   if (tx_ring_sz > 32768)
7823     {
7824       errmsg ("tx ring size must be 32768 or lower. ");
7825       return -99;
7826     }
7827
7828   /* Construct the API message */
7829   M (TAP_CREATE_V2, mp);
7830
7831   mp->use_random_mac = random_mac;
7832
7833   mp->id = ntohl (id);
7834   mp->host_namespace_set = host_ns != 0;
7835   mp->host_bridge_set = host_bridge != 0;
7836   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7837   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7838   mp->rx_ring_sz = ntohs (rx_ring_sz);
7839   mp->tx_ring_sz = ntohs (tx_ring_sz);
7840
7841   if (random_mac == 0)
7842     clib_memcpy (mp->mac_address, mac_address, 6);
7843   if (host_mac_addr_set)
7844     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7845   if (host_if_name)
7846     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7847   if (host_ns)
7848     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7849   if (host_bridge)
7850     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7851   if (host_ip4_prefix_len)
7852     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7853   if (host_ip6_prefix_len)
7854     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7855   if (host_ip4_gw_set)
7856     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7857   if (host_ip6_gw_set)
7858     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7859
7860   vec_free (host_ns);
7861   vec_free (host_if_name);
7862   vec_free (host_bridge);
7863
7864   /* send it... */
7865   S (mp);
7866
7867   /* Wait for a reply... */
7868   W (ret);
7869   return ret;
7870 }
7871
7872 static int
7873 api_tap_delete_v2 (vat_main_t * vam)
7874 {
7875   unformat_input_t *i = vam->input;
7876   vl_api_tap_delete_v2_t *mp;
7877   u32 sw_if_index = ~0;
7878   u8 sw_if_index_set = 0;
7879   int ret;
7880
7881   /* Parse args required to build the message */
7882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7883     {
7884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7885         sw_if_index_set = 1;
7886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7887         sw_if_index_set = 1;
7888       else
7889         break;
7890     }
7891
7892   if (sw_if_index_set == 0)
7893     {
7894       errmsg ("missing vpp interface name. ");
7895       return -99;
7896     }
7897
7898   /* Construct the API message */
7899   M (TAP_DELETE_V2, mp);
7900
7901   mp->sw_if_index = ntohl (sw_if_index);
7902
7903   /* send it... */
7904   S (mp);
7905
7906   /* Wait for a reply... */
7907   W (ret);
7908   return ret;
7909 }
7910
7911 static int
7912 api_bond_create (vat_main_t * vam)
7913 {
7914   unformat_input_t *i = vam->input;
7915   vl_api_bond_create_t *mp;
7916   u8 mac_address[6];
7917   u8 custom_mac = 0;
7918   int ret;
7919   u8 mode;
7920   u8 lb;
7921   u8 mode_is_set = 0;
7922
7923   clib_memset (mac_address, 0, sizeof (mac_address));
7924   lb = BOND_LB_L2;
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7930         mode_is_set = 1;
7931       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7932                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7933         ;
7934       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7935                          mac_address))
7936         custom_mac = 1;
7937       else
7938         break;
7939     }
7940
7941   if (mode_is_set == 0)
7942     {
7943       errmsg ("Missing bond mode. ");
7944       return -99;
7945     }
7946
7947   /* Construct the API message */
7948   M (BOND_CREATE, mp);
7949
7950   mp->use_custom_mac = custom_mac;
7951
7952   mp->mode = mode;
7953   mp->lb = lb;
7954
7955   if (custom_mac)
7956     clib_memcpy (mp->mac_address, mac_address, 6);
7957
7958   /* send it... */
7959   S (mp);
7960
7961   /* Wait for a reply... */
7962   W (ret);
7963   return ret;
7964 }
7965
7966 static int
7967 api_bond_delete (vat_main_t * vam)
7968 {
7969   unformat_input_t *i = vam->input;
7970   vl_api_bond_delete_t *mp;
7971   u32 sw_if_index = ~0;
7972   u8 sw_if_index_set = 0;
7973   int ret;
7974
7975   /* Parse args required to build the message */
7976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7977     {
7978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7979         sw_if_index_set = 1;
7980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7981         sw_if_index_set = 1;
7982       else
7983         break;
7984     }
7985
7986   if (sw_if_index_set == 0)
7987     {
7988       errmsg ("missing vpp interface name. ");
7989       return -99;
7990     }
7991
7992   /* Construct the API message */
7993   M (BOND_DELETE, mp);
7994
7995   mp->sw_if_index = ntohl (sw_if_index);
7996
7997   /* send it... */
7998   S (mp);
7999
8000   /* Wait for a reply... */
8001   W (ret);
8002   return ret;
8003 }
8004
8005 static int
8006 api_bond_enslave (vat_main_t * vam)
8007 {
8008   unformat_input_t *i = vam->input;
8009   vl_api_bond_enslave_t *mp;
8010   u32 bond_sw_if_index;
8011   int ret;
8012   u8 is_passive;
8013   u8 is_long_timeout;
8014   u32 bond_sw_if_index_is_set = 0;
8015   u32 sw_if_index;
8016   u8 sw_if_index_is_set = 0;
8017
8018   /* Parse args required to build the message */
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "sw_if_index %d", &sw_if_index))
8022         sw_if_index_is_set = 1;
8023       else if (unformat (i, "bond %u", &bond_sw_if_index))
8024         bond_sw_if_index_is_set = 1;
8025       else if (unformat (i, "passive %d", &is_passive))
8026         ;
8027       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8028         ;
8029       else
8030         break;
8031     }
8032
8033   if (bond_sw_if_index_is_set == 0)
8034     {
8035       errmsg ("Missing bond sw_if_index. ");
8036       return -99;
8037     }
8038   if (sw_if_index_is_set == 0)
8039     {
8040       errmsg ("Missing slave sw_if_index. ");
8041       return -99;
8042     }
8043
8044   /* Construct the API message */
8045   M (BOND_ENSLAVE, mp);
8046
8047   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8048   mp->sw_if_index = ntohl (sw_if_index);
8049   mp->is_long_timeout = is_long_timeout;
8050   mp->is_passive = is_passive;
8051
8052   /* send it... */
8053   S (mp);
8054
8055   /* Wait for a reply... */
8056   W (ret);
8057   return ret;
8058 }
8059
8060 static int
8061 api_bond_detach_slave (vat_main_t * vam)
8062 {
8063   unformat_input_t *i = vam->input;
8064   vl_api_bond_detach_slave_t *mp;
8065   u32 sw_if_index = ~0;
8066   u8 sw_if_index_set = 0;
8067   int ret;
8068
8069   /* Parse args required to build the message */
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8073         sw_if_index_set = 1;
8074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8075         sw_if_index_set = 1;
8076       else
8077         break;
8078     }
8079
8080   if (sw_if_index_set == 0)
8081     {
8082       errmsg ("missing vpp interface name. ");
8083       return -99;
8084     }
8085
8086   /* Construct the API message */
8087   M (BOND_DETACH_SLAVE, mp);
8088
8089   mp->sw_if_index = ntohl (sw_if_index);
8090
8091   /* send it... */
8092   S (mp);
8093
8094   /* Wait for a reply... */
8095   W (ret);
8096   return ret;
8097 }
8098
8099 static int
8100 api_ip_table_add_del (vat_main_t * vam)
8101 {
8102   unformat_input_t *i = vam->input;
8103   vl_api_ip_table_add_del_t *mp;
8104   u32 table_id = ~0;
8105   u8 is_ipv6 = 0;
8106   u8 is_add = 1;
8107   int ret = 0;
8108
8109   /* Parse args required to build the message */
8110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8111     {
8112       if (unformat (i, "ipv6"))
8113         is_ipv6 = 1;
8114       else if (unformat (i, "del"))
8115         is_add = 0;
8116       else if (unformat (i, "add"))
8117         is_add = 1;
8118       else if (unformat (i, "table %d", &table_id))
8119         ;
8120       else
8121         {
8122           clib_warning ("parse error '%U'", format_unformat_error, i);
8123           return -99;
8124         }
8125     }
8126
8127   if (~0 == table_id)
8128     {
8129       errmsg ("missing table-ID");
8130       return -99;
8131     }
8132
8133   /* Construct the API message */
8134   M (IP_TABLE_ADD_DEL, mp);
8135
8136   mp->table_id = ntohl (table_id);
8137   mp->is_ipv6 = is_ipv6;
8138   mp->is_add = is_add;
8139
8140   /* send it... */
8141   S (mp);
8142
8143   /* Wait for a reply... */
8144   W (ret);
8145
8146   return ret;
8147 }
8148
8149 static int
8150 api_ip_add_del_route (vat_main_t * vam)
8151 {
8152   unformat_input_t *i = vam->input;
8153   vl_api_ip_add_del_route_t *mp;
8154   u32 sw_if_index = ~0, vrf_id = 0;
8155   u8 is_ipv6 = 0;
8156   u8 is_local = 0, is_drop = 0;
8157   u8 is_unreach = 0, is_prohibit = 0;
8158   u8 is_add = 1;
8159   u32 next_hop_weight = 1;
8160   u8 is_multipath = 0;
8161   u8 address_set = 0;
8162   u8 address_length_set = 0;
8163   u32 next_hop_table_id = 0;
8164   u32 resolve_attempts = 0;
8165   u32 dst_address_length = 0;
8166   u8 next_hop_set = 0;
8167   ip4_address_t v4_dst_address, v4_next_hop_address;
8168   ip6_address_t v6_dst_address, v6_next_hop_address;
8169   int count = 1;
8170   int j;
8171   f64 before = 0;
8172   u32 random_add_del = 0;
8173   u32 *random_vector = 0;
8174   uword *random_hash;
8175   u32 random_seed = 0xdeaddabe;
8176   u32 classify_table_index = ~0;
8177   u8 is_classify = 0;
8178   u8 resolve_host = 0, resolve_attached = 0;
8179   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8180   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8181   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8182
8183   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8184   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8185   /* Parse args required to build the message */
8186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8187     {
8188       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8189         ;
8190       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8191         ;
8192       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8193         {
8194           address_set = 1;
8195           is_ipv6 = 0;
8196         }
8197       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8198         {
8199           address_set = 1;
8200           is_ipv6 = 1;
8201         }
8202       else if (unformat (i, "/%d", &dst_address_length))
8203         {
8204           address_length_set = 1;
8205         }
8206
8207       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8208                                          &v4_next_hop_address))
8209         {
8210           next_hop_set = 1;
8211         }
8212       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8213                                          &v6_next_hop_address))
8214         {
8215           next_hop_set = 1;
8216         }
8217       else
8218         if (unformat
8219             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8220         {
8221           next_hop_set = 1;
8222         }
8223       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8224         {
8225           next_hop_set = 1;
8226         }
8227       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8228         ;
8229       else if (unformat (i, "weight %d", &next_hop_weight))
8230         ;
8231       else if (unformat (i, "drop"))
8232         {
8233           is_drop = 1;
8234         }
8235       else if (unformat (i, "null-send-unreach"))
8236         {
8237           is_unreach = 1;
8238         }
8239       else if (unformat (i, "null-send-prohibit"))
8240         {
8241           is_prohibit = 1;
8242         }
8243       else if (unformat (i, "local"))
8244         {
8245           is_local = 1;
8246         }
8247       else if (unformat (i, "classify %d", &classify_table_index))
8248         {
8249           is_classify = 1;
8250         }
8251       else if (unformat (i, "del"))
8252         is_add = 0;
8253       else if (unformat (i, "add"))
8254         is_add = 1;
8255       else if (unformat (i, "resolve-via-host"))
8256         resolve_host = 1;
8257       else if (unformat (i, "resolve-via-attached"))
8258         resolve_attached = 1;
8259       else if (unformat (i, "multipath"))
8260         is_multipath = 1;
8261       else if (unformat (i, "vrf %d", &vrf_id))
8262         ;
8263       else if (unformat (i, "count %d", &count))
8264         ;
8265       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8266         ;
8267       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8268         ;
8269       else if (unformat (i, "out-label %d", &next_hop_out_label))
8270         {
8271           vl_api_fib_mpls_label_t fib_label = {
8272             .label = ntohl (next_hop_out_label),
8273             .ttl = 64,
8274             .exp = 0,
8275           };
8276           vec_add1 (next_hop_out_label_stack, fib_label);
8277         }
8278       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8279         ;
8280       else if (unformat (i, "random"))
8281         random_add_del = 1;
8282       else if (unformat (i, "seed %d", &random_seed))
8283         ;
8284       else
8285         {
8286           clib_warning ("parse error '%U'", format_unformat_error, i);
8287           return -99;
8288         }
8289     }
8290
8291   if (!next_hop_set && !is_drop && !is_local &&
8292       !is_classify && !is_unreach && !is_prohibit &&
8293       MPLS_LABEL_INVALID == next_hop_via_label)
8294     {
8295       errmsg
8296         ("next hop / local / drop / unreach / prohibit / classify not set");
8297       return -99;
8298     }
8299
8300   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8301     {
8302       errmsg ("next hop and next-hop via label set");
8303       return -99;
8304     }
8305   if (address_set == 0)
8306     {
8307       errmsg ("missing addresses");
8308       return -99;
8309     }
8310
8311   if (address_length_set == 0)
8312     {
8313       errmsg ("missing address length");
8314       return -99;
8315     }
8316
8317   /* Generate a pile of unique, random routes */
8318   if (random_add_del)
8319     {
8320       u32 this_random_address;
8321       random_hash = hash_create (count, sizeof (uword));
8322
8323       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8324       for (j = 0; j <= count; j++)
8325         {
8326           do
8327             {
8328               this_random_address = random_u32 (&random_seed);
8329               this_random_address =
8330                 clib_host_to_net_u32 (this_random_address);
8331             }
8332           while (hash_get (random_hash, this_random_address));
8333           vec_add1 (random_vector, this_random_address);
8334           hash_set (random_hash, this_random_address, 1);
8335         }
8336       hash_free (random_hash);
8337       v4_dst_address.as_u32 = random_vector[0];
8338     }
8339
8340   if (count > 1)
8341     {
8342       /* Turn on async mode */
8343       vam->async_mode = 1;
8344       vam->async_errors = 0;
8345       before = vat_time_now (vam);
8346     }
8347
8348   for (j = 0; j < count; j++)
8349     {
8350       /* Construct the API message */
8351       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8352           vec_len (next_hop_out_label_stack));
8353
8354       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8355       mp->table_id = ntohl (vrf_id);
8356
8357       mp->is_add = is_add;
8358       mp->is_drop = is_drop;
8359       mp->is_unreach = is_unreach;
8360       mp->is_prohibit = is_prohibit;
8361       mp->is_ipv6 = is_ipv6;
8362       mp->is_local = is_local;
8363       mp->is_classify = is_classify;
8364       mp->is_multipath = is_multipath;
8365       mp->is_resolve_host = resolve_host;
8366       mp->is_resolve_attached = resolve_attached;
8367       mp->next_hop_weight = next_hop_weight;
8368       mp->next_hop_preference = 0;
8369       mp->dst_address_length = dst_address_length;
8370       mp->next_hop_table_id = ntohl (next_hop_table_id);
8371       mp->classify_table_index = ntohl (classify_table_index);
8372       mp->next_hop_via_label = ntohl (next_hop_via_label);
8373       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8374       if (0 != mp->next_hop_n_out_labels)
8375         {
8376           memcpy (mp->next_hop_out_label_stack,
8377                   next_hop_out_label_stack,
8378                   (vec_len (next_hop_out_label_stack) *
8379                    sizeof (vl_api_fib_mpls_label_t)));
8380           vec_free (next_hop_out_label_stack);
8381         }
8382
8383       if (is_ipv6)
8384         {
8385           clib_memcpy (mp->dst_address, &v6_dst_address,
8386                        sizeof (v6_dst_address));
8387           if (next_hop_set)
8388             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8389                          sizeof (v6_next_hop_address));
8390           increment_v6_address (&v6_dst_address);
8391         }
8392       else
8393         {
8394           clib_memcpy (mp->dst_address, &v4_dst_address,
8395                        sizeof (v4_dst_address));
8396           if (next_hop_set)
8397             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8398                          sizeof (v4_next_hop_address));
8399           if (random_add_del)
8400             v4_dst_address.as_u32 = random_vector[j + 1];
8401           else
8402             increment_v4_address (&v4_dst_address);
8403         }
8404       /* send it... */
8405       S (mp);
8406       /* If we receive SIGTERM, stop now... */
8407       if (vam->do_exit)
8408         break;
8409     }
8410
8411   /* When testing multiple add/del ops, use a control-ping to sync */
8412   if (count > 1)
8413     {
8414       vl_api_control_ping_t *mp_ping;
8415       f64 after;
8416       f64 timeout;
8417
8418       /* Shut off async mode */
8419       vam->async_mode = 0;
8420
8421       MPING (CONTROL_PING, mp_ping);
8422       S (mp_ping);
8423
8424       timeout = vat_time_now (vam) + 1.0;
8425       while (vat_time_now (vam) < timeout)
8426         if (vam->result_ready == 1)
8427           goto out;
8428       vam->retval = -99;
8429
8430     out:
8431       if (vam->retval == -99)
8432         errmsg ("timeout");
8433
8434       if (vam->async_errors > 0)
8435         {
8436           errmsg ("%d asynchronous errors", vam->async_errors);
8437           vam->retval = -98;
8438         }
8439       vam->async_errors = 0;
8440       after = vat_time_now (vam);
8441
8442       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8443       if (j > 0)
8444         count = j;
8445
8446       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8447              count, after - before, count / (after - before));
8448     }
8449   else
8450     {
8451       int ret;
8452
8453       /* Wait for a reply... */
8454       W (ret);
8455       return ret;
8456     }
8457
8458   /* Return the good/bad news */
8459   return (vam->retval);
8460 }
8461
8462 static int
8463 api_ip_mroute_add_del (vat_main_t * vam)
8464 {
8465   unformat_input_t *i = vam->input;
8466   vl_api_ip_mroute_add_del_t *mp;
8467   u32 sw_if_index = ~0, vrf_id = 0;
8468   u8 is_ipv6 = 0;
8469   u8 is_local = 0;
8470   u8 is_add = 1;
8471   u8 address_set = 0;
8472   u32 grp_address_length = 0;
8473   ip4_address_t v4_grp_address, v4_src_address;
8474   ip6_address_t v6_grp_address, v6_src_address;
8475   mfib_itf_flags_t iflags = 0;
8476   mfib_entry_flags_t eflags = 0;
8477   int ret;
8478
8479   /* Parse args required to build the message */
8480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8481     {
8482       if (unformat (i, "sw_if_index %d", &sw_if_index))
8483         ;
8484       else if (unformat (i, "%U %U",
8485                          unformat_ip4_address, &v4_src_address,
8486                          unformat_ip4_address, &v4_grp_address))
8487         {
8488           grp_address_length = 64;
8489           address_set = 1;
8490           is_ipv6 = 0;
8491         }
8492       else if (unformat (i, "%U %U",
8493                          unformat_ip6_address, &v6_src_address,
8494                          unformat_ip6_address, &v6_grp_address))
8495         {
8496           grp_address_length = 256;
8497           address_set = 1;
8498           is_ipv6 = 1;
8499         }
8500       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8501         {
8502           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8503           grp_address_length = 32;
8504           address_set = 1;
8505           is_ipv6 = 0;
8506         }
8507       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8508         {
8509           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8510           grp_address_length = 128;
8511           address_set = 1;
8512           is_ipv6 = 1;
8513         }
8514       else if (unformat (i, "/%d", &grp_address_length))
8515         ;
8516       else if (unformat (i, "local"))
8517         {
8518           is_local = 1;
8519         }
8520       else if (unformat (i, "del"))
8521         is_add = 0;
8522       else if (unformat (i, "add"))
8523         is_add = 1;
8524       else if (unformat (i, "vrf %d", &vrf_id))
8525         ;
8526       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8527         ;
8528       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8529         ;
8530       else
8531         {
8532           clib_warning ("parse error '%U'", format_unformat_error, i);
8533           return -99;
8534         }
8535     }
8536
8537   if (address_set == 0)
8538     {
8539       errmsg ("missing addresses\n");
8540       return -99;
8541     }
8542
8543   /* Construct the API message */
8544   M (IP_MROUTE_ADD_DEL, mp);
8545
8546   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8547   mp->table_id = ntohl (vrf_id);
8548
8549   mp->is_add = is_add;
8550   mp->is_ipv6 = is_ipv6;
8551   mp->is_local = is_local;
8552   mp->itf_flags = ntohl (iflags);
8553   mp->entry_flags = ntohl (eflags);
8554   mp->grp_address_length = grp_address_length;
8555   mp->grp_address_length = ntohs (mp->grp_address_length);
8556
8557   if (is_ipv6)
8558     {
8559       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8560       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8561     }
8562   else
8563     {
8564       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8565       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8566
8567     }
8568
8569   /* send it... */
8570   S (mp);
8571   /* Wait for a reply... */
8572   W (ret);
8573   return ret;
8574 }
8575
8576 static int
8577 api_mpls_table_add_del (vat_main_t * vam)
8578 {
8579   unformat_input_t *i = vam->input;
8580   vl_api_mpls_table_add_del_t *mp;
8581   u32 table_id = ~0;
8582   u8 is_add = 1;
8583   int ret = 0;
8584
8585   /* Parse args required to build the message */
8586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8587     {
8588       if (unformat (i, "table %d", &table_id))
8589         ;
8590       else if (unformat (i, "del"))
8591         is_add = 0;
8592       else if (unformat (i, "add"))
8593         is_add = 1;
8594       else
8595         {
8596           clib_warning ("parse error '%U'", format_unformat_error, i);
8597           return -99;
8598         }
8599     }
8600
8601   if (~0 == table_id)
8602     {
8603       errmsg ("missing table-ID");
8604       return -99;
8605     }
8606
8607   /* Construct the API message */
8608   M (MPLS_TABLE_ADD_DEL, mp);
8609
8610   mp->mt_table_id = ntohl (table_id);
8611   mp->mt_is_add = is_add;
8612
8613   /* send it... */
8614   S (mp);
8615
8616   /* Wait for a reply... */
8617   W (ret);
8618
8619   return ret;
8620 }
8621
8622 static int
8623 api_mpls_route_add_del (vat_main_t * vam)
8624 {
8625   unformat_input_t *i = vam->input;
8626   vl_api_mpls_route_add_del_t *mp;
8627   u32 sw_if_index = ~0, table_id = 0;
8628   u8 is_add = 1;
8629   u32 next_hop_weight = 1;
8630   u8 is_multipath = 0;
8631   u32 next_hop_table_id = 0;
8632   u8 next_hop_set = 0;
8633   ip4_address_t v4_next_hop_address = {
8634     .as_u32 = 0,
8635   };
8636   ip6_address_t v6_next_hop_address = { {0} };
8637   int count = 1;
8638   int j;
8639   f64 before = 0;
8640   u32 classify_table_index = ~0;
8641   u8 is_classify = 0;
8642   u8 resolve_host = 0, resolve_attached = 0;
8643   u8 is_interface_rx = 0;
8644   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8645   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8646   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8647   mpls_label_t local_label = MPLS_LABEL_INVALID;
8648   u8 is_eos = 0;
8649   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8650
8651   /* Parse args required to build the message */
8652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8653     {
8654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8655         ;
8656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8657         ;
8658       else if (unformat (i, "%d", &local_label))
8659         ;
8660       else if (unformat (i, "eos"))
8661         is_eos = 1;
8662       else if (unformat (i, "non-eos"))
8663         is_eos = 0;
8664       else if (unformat (i, "via %U", unformat_ip4_address,
8665                          &v4_next_hop_address))
8666         {
8667           next_hop_set = 1;
8668           next_hop_proto = DPO_PROTO_IP4;
8669         }
8670       else if (unformat (i, "via %U", unformat_ip6_address,
8671                          &v6_next_hop_address))
8672         {
8673           next_hop_set = 1;
8674           next_hop_proto = DPO_PROTO_IP6;
8675         }
8676       else if (unformat (i, "weight %d", &next_hop_weight))
8677         ;
8678       else if (unformat (i, "classify %d", &classify_table_index))
8679         {
8680           is_classify = 1;
8681         }
8682       else if (unformat (i, "del"))
8683         is_add = 0;
8684       else if (unformat (i, "add"))
8685         is_add = 1;
8686       else if (unformat (i, "resolve-via-host"))
8687         resolve_host = 1;
8688       else if (unformat (i, "resolve-via-attached"))
8689         resolve_attached = 1;
8690       else if (unformat (i, "multipath"))
8691         is_multipath = 1;
8692       else if (unformat (i, "count %d", &count))
8693         ;
8694       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8695         {
8696           next_hop_set = 1;
8697           next_hop_proto = DPO_PROTO_IP4;
8698         }
8699       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8700         {
8701           next_hop_set = 1;
8702           next_hop_proto = DPO_PROTO_IP6;
8703         }
8704       else
8705         if (unformat
8706             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8707              &sw_if_index))
8708         {
8709           next_hop_set = 1;
8710           next_hop_proto = DPO_PROTO_ETHERNET;
8711           is_interface_rx = 1;
8712         }
8713       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8714         {
8715           next_hop_set = 1;
8716           next_hop_proto = DPO_PROTO_ETHERNET;
8717           is_interface_rx = 1;
8718         }
8719       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8720         next_hop_set = 1;
8721       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8722         next_hop_set = 1;
8723       else if (unformat (i, "out-label %d", &next_hop_out_label))
8724         {
8725           vl_api_fib_mpls_label_t fib_label = {
8726             .label = ntohl (next_hop_out_label),
8727             .ttl = 64,
8728             .exp = 0,
8729           };
8730           vec_add1 (next_hop_out_label_stack, fib_label);
8731         }
8732       else
8733         {
8734           clib_warning ("parse error '%U'", format_unformat_error, i);
8735           return -99;
8736         }
8737     }
8738
8739   if (!next_hop_set && !is_classify)
8740     {
8741       errmsg ("next hop / classify not set");
8742       return -99;
8743     }
8744
8745   if (MPLS_LABEL_INVALID == local_label)
8746     {
8747       errmsg ("missing label");
8748       return -99;
8749     }
8750
8751   if (count > 1)
8752     {
8753       /* Turn on async mode */
8754       vam->async_mode = 1;
8755       vam->async_errors = 0;
8756       before = vat_time_now (vam);
8757     }
8758
8759   for (j = 0; j < count; j++)
8760     {
8761       /* Construct the API message */
8762       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8763           vec_len (next_hop_out_label_stack));
8764
8765       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8766       mp->mr_table_id = ntohl (table_id);
8767
8768       mp->mr_is_add = is_add;
8769       mp->mr_next_hop_proto = next_hop_proto;
8770       mp->mr_is_classify = is_classify;
8771       mp->mr_is_multipath = is_multipath;
8772       mp->mr_is_resolve_host = resolve_host;
8773       mp->mr_is_resolve_attached = resolve_attached;
8774       mp->mr_is_interface_rx = is_interface_rx;
8775       mp->mr_next_hop_weight = next_hop_weight;
8776       mp->mr_next_hop_preference = 0;
8777       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8778       mp->mr_classify_table_index = ntohl (classify_table_index);
8779       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8780       mp->mr_label = ntohl (local_label);
8781       mp->mr_eos = is_eos;
8782
8783       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8784       if (0 != mp->mr_next_hop_n_out_labels)
8785         {
8786           memcpy (mp->mr_next_hop_out_label_stack,
8787                   next_hop_out_label_stack,
8788                   vec_len (next_hop_out_label_stack) *
8789                   sizeof (vl_api_fib_mpls_label_t));
8790           vec_free (next_hop_out_label_stack);
8791         }
8792
8793       if (next_hop_set)
8794         {
8795           if (DPO_PROTO_IP4 == next_hop_proto)
8796             {
8797               clib_memcpy (mp->mr_next_hop,
8798                            &v4_next_hop_address,
8799                            sizeof (v4_next_hop_address));
8800             }
8801           else if (DPO_PROTO_IP6 == next_hop_proto)
8802
8803             {
8804               clib_memcpy (mp->mr_next_hop,
8805                            &v6_next_hop_address,
8806                            sizeof (v6_next_hop_address));
8807             }
8808         }
8809       local_label++;
8810
8811       /* send it... */
8812       S (mp);
8813       /* If we receive SIGTERM, stop now... */
8814       if (vam->do_exit)
8815         break;
8816     }
8817
8818   /* When testing multiple add/del ops, use a control-ping to sync */
8819   if (count > 1)
8820     {
8821       vl_api_control_ping_t *mp_ping;
8822       f64 after;
8823       f64 timeout;
8824
8825       /* Shut off async mode */
8826       vam->async_mode = 0;
8827
8828       MPING (CONTROL_PING, mp_ping);
8829       S (mp_ping);
8830
8831       timeout = vat_time_now (vam) + 1.0;
8832       while (vat_time_now (vam) < timeout)
8833         if (vam->result_ready == 1)
8834           goto out;
8835       vam->retval = -99;
8836
8837     out:
8838       if (vam->retval == -99)
8839         errmsg ("timeout");
8840
8841       if (vam->async_errors > 0)
8842         {
8843           errmsg ("%d asynchronous errors", vam->async_errors);
8844           vam->retval = -98;
8845         }
8846       vam->async_errors = 0;
8847       after = vat_time_now (vam);
8848
8849       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8850       if (j > 0)
8851         count = j;
8852
8853       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8854              count, after - before, count / (after - before));
8855     }
8856   else
8857     {
8858       int ret;
8859
8860       /* Wait for a reply... */
8861       W (ret);
8862       return ret;
8863     }
8864
8865   /* Return the good/bad news */
8866   return (vam->retval);
8867 }
8868
8869 static int
8870 api_mpls_ip_bind_unbind (vat_main_t * vam)
8871 {
8872   unformat_input_t *i = vam->input;
8873   vl_api_mpls_ip_bind_unbind_t *mp;
8874   u32 ip_table_id = 0;
8875   u8 is_bind = 1;
8876   u8 is_ip4 = 1;
8877   ip4_address_t v4_address;
8878   ip6_address_t v6_address;
8879   u32 address_length;
8880   u8 address_set = 0;
8881   mpls_label_t local_label = MPLS_LABEL_INVALID;
8882   int ret;
8883
8884   /* Parse args required to build the message */
8885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (i, "%U/%d", unformat_ip4_address,
8888                     &v4_address, &address_length))
8889         {
8890           is_ip4 = 1;
8891           address_set = 1;
8892         }
8893       else if (unformat (i, "%U/%d", unformat_ip6_address,
8894                          &v6_address, &address_length))
8895         {
8896           is_ip4 = 0;
8897           address_set = 1;
8898         }
8899       else if (unformat (i, "%d", &local_label))
8900         ;
8901       else if (unformat (i, "table-id %d", &ip_table_id))
8902         ;
8903       else if (unformat (i, "unbind"))
8904         is_bind = 0;
8905       else if (unformat (i, "bind"))
8906         is_bind = 1;
8907       else
8908         {
8909           clib_warning ("parse error '%U'", format_unformat_error, i);
8910           return -99;
8911         }
8912     }
8913
8914   if (!address_set)
8915     {
8916       errmsg ("IP address not set");
8917       return -99;
8918     }
8919
8920   if (MPLS_LABEL_INVALID == local_label)
8921     {
8922       errmsg ("missing label");
8923       return -99;
8924     }
8925
8926   /* Construct the API message */
8927   M (MPLS_IP_BIND_UNBIND, mp);
8928
8929   mp->mb_is_bind = is_bind;
8930   mp->mb_is_ip4 = is_ip4;
8931   mp->mb_ip_table_id = ntohl (ip_table_id);
8932   mp->mb_mpls_table_id = 0;
8933   mp->mb_label = ntohl (local_label);
8934   mp->mb_address_length = address_length;
8935
8936   if (is_ip4)
8937     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8938   else
8939     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8940
8941   /* send it... */
8942   S (mp);
8943
8944   /* Wait for a reply... */
8945   W (ret);
8946   return ret;
8947 }
8948
8949 static int
8950 api_sr_mpls_policy_add (vat_main_t * vam)
8951 {
8952   unformat_input_t *i = vam->input;
8953   vl_api_sr_mpls_policy_add_t *mp;
8954   u32 bsid = 0;
8955   u32 weight = 1;
8956   u8 type = 0;
8957   u8 n_segments = 0;
8958   u32 sid;
8959   u32 *segments = NULL;
8960   int ret;
8961
8962   /* Parse args required to build the message */
8963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8964     {
8965       if (unformat (i, "bsid %d", &bsid))
8966         ;
8967       else if (unformat (i, "weight %d", &weight))
8968         ;
8969       else if (unformat (i, "spray"))
8970         type = 1;
8971       else if (unformat (i, "next %d", &sid))
8972         {
8973           n_segments += 1;
8974           vec_add1 (segments, htonl (sid));
8975         }
8976       else
8977         {
8978           clib_warning ("parse error '%U'", format_unformat_error, i);
8979           return -99;
8980         }
8981     }
8982
8983   if (bsid == 0)
8984     {
8985       errmsg ("bsid not set");
8986       return -99;
8987     }
8988
8989   if (n_segments == 0)
8990     {
8991       errmsg ("no sid in segment stack");
8992       return -99;
8993     }
8994
8995   /* Construct the API message */
8996   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8997
8998   mp->bsid = htonl (bsid);
8999   mp->weight = htonl (weight);
9000   mp->type = type;
9001   mp->n_segments = n_segments;
9002   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9003   vec_free (segments);
9004
9005   /* send it... */
9006   S (mp);
9007
9008   /* Wait for a reply... */
9009   W (ret);
9010   return ret;
9011 }
9012
9013 static int
9014 api_sr_mpls_policy_del (vat_main_t * vam)
9015 {
9016   unformat_input_t *i = vam->input;
9017   vl_api_sr_mpls_policy_del_t *mp;
9018   u32 bsid = 0;
9019   int ret;
9020
9021   /* Parse args required to build the message */
9022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9023     {
9024       if (unformat (i, "bsid %d", &bsid))
9025         ;
9026       else
9027         {
9028           clib_warning ("parse error '%U'", format_unformat_error, i);
9029           return -99;
9030         }
9031     }
9032
9033   if (bsid == 0)
9034     {
9035       errmsg ("bsid not set");
9036       return -99;
9037     }
9038
9039   /* Construct the API message */
9040   M (SR_MPLS_POLICY_DEL, mp);
9041
9042   mp->bsid = htonl (bsid);
9043
9044   /* send it... */
9045   S (mp);
9046
9047   /* Wait for a reply... */
9048   W (ret);
9049   return ret;
9050 }
9051
9052 static int
9053 api_bier_table_add_del (vat_main_t * vam)
9054 {
9055   unformat_input_t *i = vam->input;
9056   vl_api_bier_table_add_del_t *mp;
9057   u8 is_add = 1;
9058   u32 set = 0, sub_domain = 0, hdr_len = 3;
9059   mpls_label_t local_label = MPLS_LABEL_INVALID;
9060   int ret;
9061
9062   /* Parse args required to build the message */
9063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064     {
9065       if (unformat (i, "sub-domain %d", &sub_domain))
9066         ;
9067       else if (unformat (i, "set %d", &set))
9068         ;
9069       else if (unformat (i, "label %d", &local_label))
9070         ;
9071       else if (unformat (i, "hdr-len %d", &hdr_len))
9072         ;
9073       else if (unformat (i, "add"))
9074         is_add = 1;
9075       else if (unformat (i, "del"))
9076         is_add = 0;
9077       else
9078         {
9079           clib_warning ("parse error '%U'", format_unformat_error, i);
9080           return -99;
9081         }
9082     }
9083
9084   if (MPLS_LABEL_INVALID == local_label)
9085     {
9086       errmsg ("missing label\n");
9087       return -99;
9088     }
9089
9090   /* Construct the API message */
9091   M (BIER_TABLE_ADD_DEL, mp);
9092
9093   mp->bt_is_add = is_add;
9094   mp->bt_label = ntohl (local_label);
9095   mp->bt_tbl_id.bt_set = set;
9096   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9097   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9098
9099   /* send it... */
9100   S (mp);
9101
9102   /* Wait for a reply... */
9103   W (ret);
9104
9105   return (ret);
9106 }
9107
9108 static int
9109 api_bier_route_add_del (vat_main_t * vam)
9110 {
9111   unformat_input_t *i = vam->input;
9112   vl_api_bier_route_add_del_t *mp;
9113   u8 is_add = 1;
9114   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9115   ip4_address_t v4_next_hop_address;
9116   ip6_address_t v6_next_hop_address;
9117   u8 next_hop_set = 0;
9118   u8 next_hop_proto_is_ip4 = 1;
9119   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9120   int ret;
9121
9122   /* Parse args required to build the message */
9123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9124     {
9125       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9126         {
9127           next_hop_proto_is_ip4 = 1;
9128           next_hop_set = 1;
9129         }
9130       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9131         {
9132           next_hop_proto_is_ip4 = 0;
9133           next_hop_set = 1;
9134         }
9135       if (unformat (i, "sub-domain %d", &sub_domain))
9136         ;
9137       else if (unformat (i, "set %d", &set))
9138         ;
9139       else if (unformat (i, "hdr-len %d", &hdr_len))
9140         ;
9141       else if (unformat (i, "bp %d", &bp))
9142         ;
9143       else if (unformat (i, "add"))
9144         is_add = 1;
9145       else if (unformat (i, "del"))
9146         is_add = 0;
9147       else if (unformat (i, "out-label %d", &next_hop_out_label))
9148         ;
9149       else
9150         {
9151           clib_warning ("parse error '%U'", format_unformat_error, i);
9152           return -99;
9153         }
9154     }
9155
9156   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9157     {
9158       errmsg ("next hop / label set\n");
9159       return -99;
9160     }
9161   if (0 == bp)
9162     {
9163       errmsg ("bit=position not set\n");
9164       return -99;
9165     }
9166
9167   /* Construct the API message */
9168   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9169
9170   mp->br_is_add = is_add;
9171   mp->br_tbl_id.bt_set = set;
9172   mp->br_tbl_id.bt_sub_domain = sub_domain;
9173   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9174   mp->br_bp = ntohs (bp);
9175   mp->br_n_paths = 1;
9176   mp->br_paths[0].n_labels = 1;
9177   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9178   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9179
9180   if (next_hop_proto_is_ip4)
9181     {
9182       clib_memcpy (mp->br_paths[0].next_hop,
9183                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9184     }
9185   else
9186     {
9187       clib_memcpy (mp->br_paths[0].next_hop,
9188                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9189     }
9190
9191   /* send it... */
9192   S (mp);
9193
9194   /* Wait for a reply... */
9195   W (ret);
9196
9197   return (ret);
9198 }
9199
9200 static int
9201 api_proxy_arp_add_del (vat_main_t * vam)
9202 {
9203   unformat_input_t *i = vam->input;
9204   vl_api_proxy_arp_add_del_t *mp;
9205   u32 vrf_id = 0;
9206   u8 is_add = 1;
9207   ip4_address_t lo, hi;
9208   u8 range_set = 0;
9209   int ret;
9210
9211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9212     {
9213       if (unformat (i, "vrf %d", &vrf_id))
9214         ;
9215       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9216                          unformat_ip4_address, &hi))
9217         range_set = 1;
9218       else if (unformat (i, "del"))
9219         is_add = 0;
9220       else
9221         {
9222           clib_warning ("parse error '%U'", format_unformat_error, i);
9223           return -99;
9224         }
9225     }
9226
9227   if (range_set == 0)
9228     {
9229       errmsg ("address range not set");
9230       return -99;
9231     }
9232
9233   M (PROXY_ARP_ADD_DEL, mp);
9234
9235   mp->proxy.vrf_id = ntohl (vrf_id);
9236   mp->is_add = is_add;
9237   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9238   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9239
9240   S (mp);
9241   W (ret);
9242   return ret;
9243 }
9244
9245 static int
9246 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9247 {
9248   unformat_input_t *i = vam->input;
9249   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9250   u32 sw_if_index;
9251   u8 enable = 1;
9252   u8 sw_if_index_set = 0;
9253   int ret;
9254
9255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9256     {
9257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9258         sw_if_index_set = 1;
9259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9260         sw_if_index_set = 1;
9261       else if (unformat (i, "enable"))
9262         enable = 1;
9263       else if (unformat (i, "disable"))
9264         enable = 0;
9265       else
9266         {
9267           clib_warning ("parse error '%U'", format_unformat_error, i);
9268           return -99;
9269         }
9270     }
9271
9272   if (sw_if_index_set == 0)
9273     {
9274       errmsg ("missing interface name or sw_if_index");
9275       return -99;
9276     }
9277
9278   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9279
9280   mp->sw_if_index = ntohl (sw_if_index);
9281   mp->enable_disable = enable;
9282
9283   S (mp);
9284   W (ret);
9285   return ret;
9286 }
9287
9288 static int
9289 api_mpls_tunnel_add_del (vat_main_t * vam)
9290 {
9291   unformat_input_t *i = vam->input;
9292   vl_api_mpls_tunnel_add_del_t *mp;
9293
9294   u8 is_add = 1;
9295   u8 l2_only = 0;
9296   u32 sw_if_index = ~0;
9297   u32 next_hop_sw_if_index = ~0;
9298   u32 next_hop_proto_is_ip4 = 1;
9299
9300   u32 next_hop_table_id = 0;
9301   ip4_address_t v4_next_hop_address = {
9302     .as_u32 = 0,
9303   };
9304   ip6_address_t v6_next_hop_address = { {0} };
9305   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9306   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9307   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9308   int ret;
9309
9310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (i, "add"))
9313         is_add = 1;
9314       else
9315         if (unformat
9316             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9317         is_add = 0;
9318       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9319         is_add = 0;
9320       else if (unformat (i, "via %U",
9321                          unformat_ip4_address, &v4_next_hop_address))
9322         {
9323           next_hop_proto_is_ip4 = 1;
9324         }
9325       else if (unformat (i, "via %U",
9326                          unformat_ip6_address, &v6_next_hop_address))
9327         {
9328           next_hop_proto_is_ip4 = 0;
9329         }
9330       else if (unformat (i, "via-label %d", &next_hop_via_label))
9331         ;
9332       else
9333         if (unformat
9334             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9335         ;
9336       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9337         ;
9338       else if (unformat (i, "l2-only"))
9339         l2_only = 1;
9340       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9341         ;
9342       else if (unformat (i, "out-label %d", &next_hop_out_label))
9343         {
9344           vl_api_fib_mpls_label_t fib_label = {
9345             .label = ntohl (next_hop_out_label),
9346             .ttl = 64,
9347             .exp = 0,
9348           };
9349           vec_add1 (next_hop_out_label_stack, fib_label);
9350         }
9351       else
9352         {
9353           clib_warning ("parse error '%U'", format_unformat_error, i);
9354           return -99;
9355         }
9356     }
9357
9358   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9359       vec_len (next_hop_out_label_stack));
9360
9361   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9362   mp->mt_sw_if_index = ntohl (sw_if_index);
9363   mp->mt_is_add = is_add;
9364   mp->mt_l2_only = l2_only;
9365   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9366   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9367   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9368   mp->mt_next_hop_weight = 1;
9369   mp->mt_next_hop_preference = 0;
9370
9371   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9372
9373   if (0 != mp->mt_next_hop_n_out_labels)
9374     {
9375       clib_memcpy (mp->mt_next_hop_out_label_stack,
9376                    next_hop_out_label_stack,
9377                    (vec_len (next_hop_out_label_stack) *
9378                     sizeof (vl_api_fib_mpls_label_t)));
9379       vec_free (next_hop_out_label_stack);
9380     }
9381
9382   if (next_hop_proto_is_ip4)
9383     {
9384       clib_memcpy (mp->mt_next_hop,
9385                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9386     }
9387   else
9388     {
9389       clib_memcpy (mp->mt_next_hop,
9390                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9391     }
9392
9393   S (mp);
9394   W (ret);
9395   return ret;
9396 }
9397
9398 static int
9399 api_sw_interface_set_unnumbered (vat_main_t * vam)
9400 {
9401   unformat_input_t *i = vam->input;
9402   vl_api_sw_interface_set_unnumbered_t *mp;
9403   u32 sw_if_index;
9404   u32 unnum_sw_index = ~0;
9405   u8 is_add = 1;
9406   u8 sw_if_index_set = 0;
9407   int ret;
9408
9409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9410     {
9411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9412         sw_if_index_set = 1;
9413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9414         sw_if_index_set = 1;
9415       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9416         ;
9417       else if (unformat (i, "del"))
9418         is_add = 0;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (sw_if_index_set == 0)
9427     {
9428       errmsg ("missing interface name or sw_if_index");
9429       return -99;
9430     }
9431
9432   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9433
9434   mp->sw_if_index = ntohl (sw_if_index);
9435   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9436   mp->is_add = is_add;
9437
9438   S (mp);
9439   W (ret);
9440   return ret;
9441 }
9442
9443 static int
9444 api_ip_neighbor_add_del (vat_main_t * vam)
9445 {
9446   unformat_input_t *i = vam->input;
9447   vl_api_ip_neighbor_add_del_t *mp;
9448   u32 sw_if_index;
9449   u8 sw_if_index_set = 0;
9450   u8 is_add = 1;
9451   u8 is_static = 0;
9452   u8 is_no_fib_entry = 0;
9453   u8 mac_address[6];
9454   u8 mac_set = 0;
9455   u8 v4_address_set = 0;
9456   u8 v6_address_set = 0;
9457   ip4_address_t v4address;
9458   ip6_address_t v6address;
9459   int ret;
9460
9461   clib_memset (mac_address, 0, sizeof (mac_address));
9462
9463   /* Parse args required to build the message */
9464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9467         {
9468           mac_set = 1;
9469         }
9470       else if (unformat (i, "del"))
9471         is_add = 0;
9472       else
9473         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9474         sw_if_index_set = 1;
9475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9476         sw_if_index_set = 1;
9477       else if (unformat (i, "is_static"))
9478         is_static = 1;
9479       else if (unformat (i, "no-fib-entry"))
9480         is_no_fib_entry = 1;
9481       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9482         v4_address_set = 1;
9483       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9484         v6_address_set = 1;
9485       else
9486         {
9487           clib_warning ("parse error '%U'", format_unformat_error, i);
9488           return -99;
9489         }
9490     }
9491
9492   if (sw_if_index_set == 0)
9493     {
9494       errmsg ("missing interface name or sw_if_index");
9495       return -99;
9496     }
9497   if (v4_address_set && v6_address_set)
9498     {
9499       errmsg ("both v4 and v6 addresses set");
9500       return -99;
9501     }
9502   if (!v4_address_set && !v6_address_set)
9503     {
9504       errmsg ("no address set");
9505       return -99;
9506     }
9507
9508   /* Construct the API message */
9509   M (IP_NEIGHBOR_ADD_DEL, mp);
9510
9511   mp->sw_if_index = ntohl (sw_if_index);
9512   mp->is_add = is_add;
9513   mp->is_static = is_static;
9514   mp->is_no_adj_fib = is_no_fib_entry;
9515   if (mac_set)
9516     clib_memcpy (mp->mac_address, mac_address, 6);
9517   if (v6_address_set)
9518     {
9519       mp->is_ipv6 = 1;
9520       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9521     }
9522   else
9523     {
9524       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9525       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9526     }
9527
9528   /* send it... */
9529   S (mp);
9530
9531   /* Wait for a reply, return good/bad news  */
9532   W (ret);
9533   return ret;
9534 }
9535
9536 static int
9537 api_create_vlan_subif (vat_main_t * vam)
9538 {
9539   unformat_input_t *i = vam->input;
9540   vl_api_create_vlan_subif_t *mp;
9541   u32 sw_if_index;
9542   u8 sw_if_index_set = 0;
9543   u32 vlan_id;
9544   u8 vlan_id_set = 0;
9545   int ret;
9546
9547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9548     {
9549       if (unformat (i, "sw_if_index %d", &sw_if_index))
9550         sw_if_index_set = 1;
9551       else
9552         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9553         sw_if_index_set = 1;
9554       else if (unformat (i, "vlan %d", &vlan_id))
9555         vlan_id_set = 1;
9556       else
9557         {
9558           clib_warning ("parse error '%U'", format_unformat_error, i);
9559           return -99;
9560         }
9561     }
9562
9563   if (sw_if_index_set == 0)
9564     {
9565       errmsg ("missing interface name or sw_if_index");
9566       return -99;
9567     }
9568
9569   if (vlan_id_set == 0)
9570     {
9571       errmsg ("missing vlan_id");
9572       return -99;
9573     }
9574   M (CREATE_VLAN_SUBIF, mp);
9575
9576   mp->sw_if_index = ntohl (sw_if_index);
9577   mp->vlan_id = ntohl (vlan_id);
9578
9579   S (mp);
9580   W (ret);
9581   return ret;
9582 }
9583
9584 #define foreach_create_subif_bit                \
9585 _(no_tags)                                      \
9586 _(one_tag)                                      \
9587 _(two_tags)                                     \
9588 _(dot1ad)                                       \
9589 _(exact_match)                                  \
9590 _(default_sub)                                  \
9591 _(outer_vlan_id_any)                            \
9592 _(inner_vlan_id_any)
9593
9594 static int
9595 api_create_subif (vat_main_t * vam)
9596 {
9597   unformat_input_t *i = vam->input;
9598   vl_api_create_subif_t *mp;
9599   u32 sw_if_index;
9600   u8 sw_if_index_set = 0;
9601   u32 sub_id;
9602   u8 sub_id_set = 0;
9603   u32 no_tags = 0;
9604   u32 one_tag = 0;
9605   u32 two_tags = 0;
9606   u32 dot1ad = 0;
9607   u32 exact_match = 0;
9608   u32 default_sub = 0;
9609   u32 outer_vlan_id_any = 0;
9610   u32 inner_vlan_id_any = 0;
9611   u32 tmp;
9612   u16 outer_vlan_id = 0;
9613   u16 inner_vlan_id = 0;
9614   int ret;
9615
9616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9617     {
9618       if (unformat (i, "sw_if_index %d", &sw_if_index))
9619         sw_if_index_set = 1;
9620       else
9621         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9622         sw_if_index_set = 1;
9623       else if (unformat (i, "sub_id %d", &sub_id))
9624         sub_id_set = 1;
9625       else if (unformat (i, "outer_vlan_id %d", &tmp))
9626         outer_vlan_id = tmp;
9627       else if (unformat (i, "inner_vlan_id %d", &tmp))
9628         inner_vlan_id = tmp;
9629
9630 #define _(a) else if (unformat (i, #a)) a = 1 ;
9631       foreach_create_subif_bit
9632 #undef _
9633         else
9634         {
9635           clib_warning ("parse error '%U'", format_unformat_error, i);
9636           return -99;
9637         }
9638     }
9639
9640   if (sw_if_index_set == 0)
9641     {
9642       errmsg ("missing interface name or sw_if_index");
9643       return -99;
9644     }
9645
9646   if (sub_id_set == 0)
9647     {
9648       errmsg ("missing sub_id");
9649       return -99;
9650     }
9651   M (CREATE_SUBIF, mp);
9652
9653   mp->sw_if_index = ntohl (sw_if_index);
9654   mp->sub_id = ntohl (sub_id);
9655
9656 #define _(a) mp->a = a;
9657   foreach_create_subif_bit;
9658 #undef _
9659
9660   mp->outer_vlan_id = ntohs (outer_vlan_id);
9661   mp->inner_vlan_id = ntohs (inner_vlan_id);
9662
9663   S (mp);
9664   W (ret);
9665   return ret;
9666 }
9667
9668 static int
9669 api_oam_add_del (vat_main_t * vam)
9670 {
9671   unformat_input_t *i = vam->input;
9672   vl_api_oam_add_del_t *mp;
9673   u32 vrf_id = 0;
9674   u8 is_add = 1;
9675   ip4_address_t src, dst;
9676   u8 src_set = 0;
9677   u8 dst_set = 0;
9678   int ret;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "vrf %d", &vrf_id))
9683         ;
9684       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9685         src_set = 1;
9686       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9687         dst_set = 1;
9688       else if (unformat (i, "del"))
9689         is_add = 0;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   if (src_set == 0)
9698     {
9699       errmsg ("missing src addr");
9700       return -99;
9701     }
9702
9703   if (dst_set == 0)
9704     {
9705       errmsg ("missing dst addr");
9706       return -99;
9707     }
9708
9709   M (OAM_ADD_DEL, mp);
9710
9711   mp->vrf_id = ntohl (vrf_id);
9712   mp->is_add = is_add;
9713   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9714   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9715
9716   S (mp);
9717   W (ret);
9718   return ret;
9719 }
9720
9721 static int
9722 api_reset_fib (vat_main_t * vam)
9723 {
9724   unformat_input_t *i = vam->input;
9725   vl_api_reset_fib_t *mp;
9726   u32 vrf_id = 0;
9727   u8 is_ipv6 = 0;
9728   u8 vrf_id_set = 0;
9729
9730   int ret;
9731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9732     {
9733       if (unformat (i, "vrf %d", &vrf_id))
9734         vrf_id_set = 1;
9735       else if (unformat (i, "ipv6"))
9736         is_ipv6 = 1;
9737       else
9738         {
9739           clib_warning ("parse error '%U'", format_unformat_error, i);
9740           return -99;
9741         }
9742     }
9743
9744   if (vrf_id_set == 0)
9745     {
9746       errmsg ("missing vrf id");
9747       return -99;
9748     }
9749
9750   M (RESET_FIB, mp);
9751
9752   mp->vrf_id = ntohl (vrf_id);
9753   mp->is_ipv6 = is_ipv6;
9754
9755   S (mp);
9756   W (ret);
9757   return ret;
9758 }
9759
9760 static int
9761 api_dhcp_proxy_config (vat_main_t * vam)
9762 {
9763   unformat_input_t *i = vam->input;
9764   vl_api_dhcp_proxy_config_t *mp;
9765   u32 rx_vrf_id = 0;
9766   u32 server_vrf_id = 0;
9767   u8 is_add = 1;
9768   u8 v4_address_set = 0;
9769   u8 v6_address_set = 0;
9770   ip4_address_t v4address;
9771   ip6_address_t v6address;
9772   u8 v4_src_address_set = 0;
9773   u8 v6_src_address_set = 0;
9774   ip4_address_t v4srcaddress;
9775   ip6_address_t v6srcaddress;
9776   int ret;
9777
9778   /* Parse args required to build the message */
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "del"))
9782         is_add = 0;
9783       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9784         ;
9785       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9786         ;
9787       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9788         v4_address_set = 1;
9789       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9790         v6_address_set = 1;
9791       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9792         v4_src_address_set = 1;
9793       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9794         v6_src_address_set = 1;
9795       else
9796         break;
9797     }
9798
9799   if (v4_address_set && v6_address_set)
9800     {
9801       errmsg ("both v4 and v6 server addresses set");
9802       return -99;
9803     }
9804   if (!v4_address_set && !v6_address_set)
9805     {
9806       errmsg ("no server addresses set");
9807       return -99;
9808     }
9809
9810   if (v4_src_address_set && v6_src_address_set)
9811     {
9812       errmsg ("both v4 and v6  src addresses set");
9813       return -99;
9814     }
9815   if (!v4_src_address_set && !v6_src_address_set)
9816     {
9817       errmsg ("no src addresses set");
9818       return -99;
9819     }
9820
9821   if (!(v4_src_address_set && v4_address_set) &&
9822       !(v6_src_address_set && v6_address_set))
9823     {
9824       errmsg ("no matching server and src addresses set");
9825       return -99;
9826     }
9827
9828   /* Construct the API message */
9829   M (DHCP_PROXY_CONFIG, mp);
9830
9831   mp->is_add = is_add;
9832   mp->rx_vrf_id = ntohl (rx_vrf_id);
9833   mp->server_vrf_id = ntohl (server_vrf_id);
9834   if (v6_address_set)
9835     {
9836       mp->is_ipv6 = 1;
9837       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9838       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9839     }
9840   else
9841     {
9842       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9843       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9844     }
9845
9846   /* send it... */
9847   S (mp);
9848
9849   /* Wait for a reply, return good/bad news  */
9850   W (ret);
9851   return ret;
9852 }
9853
9854 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9855 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9856
9857 static void
9858 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9859 {
9860   vat_main_t *vam = &vat_main;
9861   u32 i, count = mp->count;
9862   vl_api_dhcp_server_t *s;
9863
9864   if (mp->is_ipv6)
9865     print (vam->ofp,
9866            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9867            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9868            ntohl (mp->rx_vrf_id),
9869            format_ip6_address, mp->dhcp_src_address,
9870            mp->vss_type, mp->vss_vpn_ascii_id,
9871            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9872   else
9873     print (vam->ofp,
9874            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9875            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9876            ntohl (mp->rx_vrf_id),
9877            format_ip4_address, mp->dhcp_src_address,
9878            mp->vss_type, mp->vss_vpn_ascii_id,
9879            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9880
9881   for (i = 0; i < count; i++)
9882     {
9883       s = &mp->servers[i];
9884
9885       if (mp->is_ipv6)
9886         print (vam->ofp,
9887                " Server Table-ID %d, Server Address %U",
9888                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9889       else
9890         print (vam->ofp,
9891                " Server Table-ID %d, Server Address %U",
9892                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9893     }
9894 }
9895
9896 static void vl_api_dhcp_proxy_details_t_handler_json
9897   (vl_api_dhcp_proxy_details_t * mp)
9898 {
9899   vat_main_t *vam = &vat_main;
9900   vat_json_node_t *node = NULL;
9901   u32 i, count = mp->count;
9902   struct in_addr ip4;
9903   struct in6_addr ip6;
9904   vl_api_dhcp_server_t *s;
9905
9906   if (VAT_JSON_ARRAY != vam->json_tree.type)
9907     {
9908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9909       vat_json_init_array (&vam->json_tree);
9910     }
9911   node = vat_json_array_add (&vam->json_tree);
9912
9913   vat_json_init_object (node);
9914   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9915   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9916                              sizeof (mp->vss_type));
9917   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9918                                    mp->vss_vpn_ascii_id);
9919   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9920   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9921
9922   if (mp->is_ipv6)
9923     {
9924       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9925       vat_json_object_add_ip6 (node, "src_address", ip6);
9926     }
9927   else
9928     {
9929       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9930       vat_json_object_add_ip4 (node, "src_address", ip4);
9931     }
9932
9933   for (i = 0; i < count; i++)
9934     {
9935       s = &mp->servers[i];
9936
9937       vat_json_object_add_uint (node, "server-table-id",
9938                                 ntohl (s->server_vrf_id));
9939
9940       if (mp->is_ipv6)
9941         {
9942           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9943           vat_json_object_add_ip4 (node, "src_address", ip4);
9944         }
9945       else
9946         {
9947           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9948           vat_json_object_add_ip6 (node, "server_address", ip6);
9949         }
9950     }
9951 }
9952
9953 static int
9954 api_dhcp_proxy_dump (vat_main_t * vam)
9955 {
9956   unformat_input_t *i = vam->input;
9957   vl_api_control_ping_t *mp_ping;
9958   vl_api_dhcp_proxy_dump_t *mp;
9959   u8 is_ipv6 = 0;
9960   int ret;
9961
9962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9963     {
9964       if (unformat (i, "ipv6"))
9965         is_ipv6 = 1;
9966       else
9967         {
9968           clib_warning ("parse error '%U'", format_unformat_error, i);
9969           return -99;
9970         }
9971     }
9972
9973   M (DHCP_PROXY_DUMP, mp);
9974
9975   mp->is_ip6 = is_ipv6;
9976   S (mp);
9977
9978   /* Use a control ping for synchronization */
9979   MPING (CONTROL_PING, mp_ping);
9980   S (mp_ping);
9981
9982   W (ret);
9983   return ret;
9984 }
9985
9986 static int
9987 api_dhcp_proxy_set_vss (vat_main_t * vam)
9988 {
9989   unformat_input_t *i = vam->input;
9990   vl_api_dhcp_proxy_set_vss_t *mp;
9991   u8 is_ipv6 = 0;
9992   u8 is_add = 1;
9993   u32 tbl_id = ~0;
9994   u8 vss_type = VSS_TYPE_DEFAULT;
9995   u8 *vpn_ascii_id = 0;
9996   u32 oui = 0;
9997   u32 fib_id = 0;
9998   int ret;
9999
10000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10001     {
10002       if (unformat (i, "tbl_id %d", &tbl_id))
10003         ;
10004       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10005         vss_type = VSS_TYPE_ASCII;
10006       else if (unformat (i, "fib_id %d", &fib_id))
10007         vss_type = VSS_TYPE_VPN_ID;
10008       else if (unformat (i, "oui %d", &oui))
10009         vss_type = VSS_TYPE_VPN_ID;
10010       else if (unformat (i, "ipv6"))
10011         is_ipv6 = 1;
10012       else if (unformat (i, "del"))
10013         is_add = 0;
10014       else
10015         break;
10016     }
10017
10018   if (tbl_id == ~0)
10019     {
10020       errmsg ("missing tbl_id ");
10021       vec_free (vpn_ascii_id);
10022       return -99;
10023     }
10024
10025   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10026     {
10027       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10028       vec_free (vpn_ascii_id);
10029       return -99;
10030     }
10031
10032   M (DHCP_PROXY_SET_VSS, mp);
10033   mp->tbl_id = ntohl (tbl_id);
10034   mp->vss_type = vss_type;
10035   if (vpn_ascii_id)
10036     {
10037       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10038       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10039     }
10040   mp->vpn_index = ntohl (fib_id);
10041   mp->oui = ntohl (oui);
10042   mp->is_ipv6 = is_ipv6;
10043   mp->is_add = is_add;
10044
10045   S (mp);
10046   W (ret);
10047
10048   vec_free (vpn_ascii_id);
10049   return ret;
10050 }
10051
10052 static int
10053 api_dhcp_client_config (vat_main_t * vam)
10054 {
10055   unformat_input_t *i = vam->input;
10056   vl_api_dhcp_client_config_t *mp;
10057   u32 sw_if_index;
10058   u8 sw_if_index_set = 0;
10059   u8 is_add = 1;
10060   u8 *hostname = 0;
10061   u8 disable_event = 0;
10062   int ret;
10063
10064   /* Parse args required to build the message */
10065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10066     {
10067       if (unformat (i, "del"))
10068         is_add = 0;
10069       else
10070         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10071         sw_if_index_set = 1;
10072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10073         sw_if_index_set = 1;
10074       else if (unformat (i, "hostname %s", &hostname))
10075         ;
10076       else if (unformat (i, "disable_event"))
10077         disable_event = 1;
10078       else
10079         break;
10080     }
10081
10082   if (sw_if_index_set == 0)
10083     {
10084       errmsg ("missing interface name or sw_if_index");
10085       return -99;
10086     }
10087
10088   if (vec_len (hostname) > 63)
10089     {
10090       errmsg ("hostname too long");
10091     }
10092   vec_add1 (hostname, 0);
10093
10094   /* Construct the API message */
10095   M (DHCP_CLIENT_CONFIG, mp);
10096
10097   mp->is_add = is_add;
10098   mp->client.sw_if_index = htonl (sw_if_index);
10099   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10100   vec_free (hostname);
10101   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10102   mp->client.pid = htonl (getpid ());
10103
10104   /* send it... */
10105   S (mp);
10106
10107   /* Wait for a reply, return good/bad news  */
10108   W (ret);
10109   return ret;
10110 }
10111
10112 static int
10113 api_set_ip_flow_hash (vat_main_t * vam)
10114 {
10115   unformat_input_t *i = vam->input;
10116   vl_api_set_ip_flow_hash_t *mp;
10117   u32 vrf_id = 0;
10118   u8 is_ipv6 = 0;
10119   u8 vrf_id_set = 0;
10120   u8 src = 0;
10121   u8 dst = 0;
10122   u8 sport = 0;
10123   u8 dport = 0;
10124   u8 proto = 0;
10125   u8 reverse = 0;
10126   int ret;
10127
10128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10129     {
10130       if (unformat (i, "vrf %d", &vrf_id))
10131         vrf_id_set = 1;
10132       else if (unformat (i, "ipv6"))
10133         is_ipv6 = 1;
10134       else if (unformat (i, "src"))
10135         src = 1;
10136       else if (unformat (i, "dst"))
10137         dst = 1;
10138       else if (unformat (i, "sport"))
10139         sport = 1;
10140       else if (unformat (i, "dport"))
10141         dport = 1;
10142       else if (unformat (i, "proto"))
10143         proto = 1;
10144       else if (unformat (i, "reverse"))
10145         reverse = 1;
10146
10147       else
10148         {
10149           clib_warning ("parse error '%U'", format_unformat_error, i);
10150           return -99;
10151         }
10152     }
10153
10154   if (vrf_id_set == 0)
10155     {
10156       errmsg ("missing vrf id");
10157       return -99;
10158     }
10159
10160   M (SET_IP_FLOW_HASH, mp);
10161   mp->src = src;
10162   mp->dst = dst;
10163   mp->sport = sport;
10164   mp->dport = dport;
10165   mp->proto = proto;
10166   mp->reverse = reverse;
10167   mp->vrf_id = ntohl (vrf_id);
10168   mp->is_ipv6 = is_ipv6;
10169
10170   S (mp);
10171   W (ret);
10172   return ret;
10173 }
10174
10175 static int
10176 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10177 {
10178   unformat_input_t *i = vam->input;
10179   vl_api_sw_interface_ip6_enable_disable_t *mp;
10180   u32 sw_if_index;
10181   u8 sw_if_index_set = 0;
10182   u8 enable = 0;
10183   int ret;
10184
10185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10186     {
10187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10188         sw_if_index_set = 1;
10189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10190         sw_if_index_set = 1;
10191       else if (unformat (i, "enable"))
10192         enable = 1;
10193       else if (unformat (i, "disable"))
10194         enable = 0;
10195       else
10196         {
10197           clib_warning ("parse error '%U'", format_unformat_error, i);
10198           return -99;
10199         }
10200     }
10201
10202   if (sw_if_index_set == 0)
10203     {
10204       errmsg ("missing interface name or sw_if_index");
10205       return -99;
10206     }
10207
10208   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10209
10210   mp->sw_if_index = ntohl (sw_if_index);
10211   mp->enable = enable;
10212
10213   S (mp);
10214   W (ret);
10215   return ret;
10216 }
10217
10218 static int
10219 api_ip6nd_proxy_add_del (vat_main_t * vam)
10220 {
10221   unformat_input_t *i = vam->input;
10222   vl_api_ip6nd_proxy_add_del_t *mp;
10223   u32 sw_if_index = ~0;
10224   u8 v6_address_set = 0;
10225   ip6_address_t v6address;
10226   u8 is_del = 0;
10227   int ret;
10228
10229   /* Parse args required to build the message */
10230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10231     {
10232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10233         ;
10234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10235         ;
10236       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10237         v6_address_set = 1;
10238       if (unformat (i, "del"))
10239         is_del = 1;
10240       else
10241         {
10242           clib_warning ("parse error '%U'", format_unformat_error, i);
10243           return -99;
10244         }
10245     }
10246
10247   if (sw_if_index == ~0)
10248     {
10249       errmsg ("missing interface name or sw_if_index");
10250       return -99;
10251     }
10252   if (!v6_address_set)
10253     {
10254       errmsg ("no address set");
10255       return -99;
10256     }
10257
10258   /* Construct the API message */
10259   M (IP6ND_PROXY_ADD_DEL, mp);
10260
10261   mp->is_del = is_del;
10262   mp->sw_if_index = ntohl (sw_if_index);
10263   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10264
10265   /* send it... */
10266   S (mp);
10267
10268   /* Wait for a reply, return good/bad news  */
10269   W (ret);
10270   return ret;
10271 }
10272
10273 static int
10274 api_ip6nd_proxy_dump (vat_main_t * vam)
10275 {
10276   vl_api_ip6nd_proxy_dump_t *mp;
10277   vl_api_control_ping_t *mp_ping;
10278   int ret;
10279
10280   M (IP6ND_PROXY_DUMP, mp);
10281
10282   S (mp);
10283
10284   /* Use a control ping for synchronization */
10285   MPING (CONTROL_PING, mp_ping);
10286   S (mp_ping);
10287
10288   W (ret);
10289   return ret;
10290 }
10291
10292 static void vl_api_ip6nd_proxy_details_t_handler
10293   (vl_api_ip6nd_proxy_details_t * mp)
10294 {
10295   vat_main_t *vam = &vat_main;
10296
10297   print (vam->ofp, "host %U sw_if_index %d",
10298          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10299 }
10300
10301 static void vl_api_ip6nd_proxy_details_t_handler_json
10302   (vl_api_ip6nd_proxy_details_t * mp)
10303 {
10304   vat_main_t *vam = &vat_main;
10305   struct in6_addr ip6;
10306   vat_json_node_t *node = NULL;
10307
10308   if (VAT_JSON_ARRAY != vam->json_tree.type)
10309     {
10310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10311       vat_json_init_array (&vam->json_tree);
10312     }
10313   node = vat_json_array_add (&vam->json_tree);
10314
10315   vat_json_init_object (node);
10316   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10317
10318   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10319   vat_json_object_add_ip6 (node, "host", ip6);
10320 }
10321
10322 static int
10323 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10327   u32 sw_if_index;
10328   u8 sw_if_index_set = 0;
10329   u32 address_length = 0;
10330   u8 v6_address_set = 0;
10331   ip6_address_t v6address;
10332   u8 use_default = 0;
10333   u8 no_advertise = 0;
10334   u8 off_link = 0;
10335   u8 no_autoconfig = 0;
10336   u8 no_onlink = 0;
10337   u8 is_no = 0;
10338   u32 val_lifetime = 0;
10339   u32 pref_lifetime = 0;
10340   int ret;
10341
10342   /* Parse args required to build the message */
10343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10344     {
10345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10346         sw_if_index_set = 1;
10347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10348         sw_if_index_set = 1;
10349       else if (unformat (i, "%U/%d",
10350                          unformat_ip6_address, &v6address, &address_length))
10351         v6_address_set = 1;
10352       else if (unformat (i, "val_life %d", &val_lifetime))
10353         ;
10354       else if (unformat (i, "pref_life %d", &pref_lifetime))
10355         ;
10356       else if (unformat (i, "def"))
10357         use_default = 1;
10358       else if (unformat (i, "noadv"))
10359         no_advertise = 1;
10360       else if (unformat (i, "offl"))
10361         off_link = 1;
10362       else if (unformat (i, "noauto"))
10363         no_autoconfig = 1;
10364       else if (unformat (i, "nolink"))
10365         no_onlink = 1;
10366       else if (unformat (i, "isno"))
10367         is_no = 1;
10368       else
10369         {
10370           clib_warning ("parse error '%U'", format_unformat_error, i);
10371           return -99;
10372         }
10373     }
10374
10375   if (sw_if_index_set == 0)
10376     {
10377       errmsg ("missing interface name or sw_if_index");
10378       return -99;
10379     }
10380   if (!v6_address_set)
10381     {
10382       errmsg ("no address set");
10383       return -99;
10384     }
10385
10386   /* Construct the API message */
10387   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10388
10389   mp->sw_if_index = ntohl (sw_if_index);
10390   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10391   mp->address_length = address_length;
10392   mp->use_default = use_default;
10393   mp->no_advertise = no_advertise;
10394   mp->off_link = off_link;
10395   mp->no_autoconfig = no_autoconfig;
10396   mp->no_onlink = no_onlink;
10397   mp->is_no = is_no;
10398   mp->val_lifetime = ntohl (val_lifetime);
10399   mp->pref_lifetime = ntohl (pref_lifetime);
10400
10401   /* send it... */
10402   S (mp);
10403
10404   /* Wait for a reply, return good/bad news  */
10405   W (ret);
10406   return ret;
10407 }
10408
10409 static int
10410 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10411 {
10412   unformat_input_t *i = vam->input;
10413   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10414   u32 sw_if_index;
10415   u8 sw_if_index_set = 0;
10416   u8 suppress = 0;
10417   u8 managed = 0;
10418   u8 other = 0;
10419   u8 ll_option = 0;
10420   u8 send_unicast = 0;
10421   u8 cease = 0;
10422   u8 is_no = 0;
10423   u8 default_router = 0;
10424   u32 max_interval = 0;
10425   u32 min_interval = 0;
10426   u32 lifetime = 0;
10427   u32 initial_count = 0;
10428   u32 initial_interval = 0;
10429   int ret;
10430
10431
10432   /* Parse args required to build the message */
10433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10434     {
10435       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10436         sw_if_index_set = 1;
10437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10438         sw_if_index_set = 1;
10439       else if (unformat (i, "maxint %d", &max_interval))
10440         ;
10441       else if (unformat (i, "minint %d", &min_interval))
10442         ;
10443       else if (unformat (i, "life %d", &lifetime))
10444         ;
10445       else if (unformat (i, "count %d", &initial_count))
10446         ;
10447       else if (unformat (i, "interval %d", &initial_interval))
10448         ;
10449       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10450         suppress = 1;
10451       else if (unformat (i, "managed"))
10452         managed = 1;
10453       else if (unformat (i, "other"))
10454         other = 1;
10455       else if (unformat (i, "ll"))
10456         ll_option = 1;
10457       else if (unformat (i, "send"))
10458         send_unicast = 1;
10459       else if (unformat (i, "cease"))
10460         cease = 1;
10461       else if (unformat (i, "isno"))
10462         is_no = 1;
10463       else if (unformat (i, "def"))
10464         default_router = 1;
10465       else
10466         {
10467           clib_warning ("parse error '%U'", format_unformat_error, i);
10468           return -99;
10469         }
10470     }
10471
10472   if (sw_if_index_set == 0)
10473     {
10474       errmsg ("missing interface name or sw_if_index");
10475       return -99;
10476     }
10477
10478   /* Construct the API message */
10479   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10480
10481   mp->sw_if_index = ntohl (sw_if_index);
10482   mp->max_interval = ntohl (max_interval);
10483   mp->min_interval = ntohl (min_interval);
10484   mp->lifetime = ntohl (lifetime);
10485   mp->initial_count = ntohl (initial_count);
10486   mp->initial_interval = ntohl (initial_interval);
10487   mp->suppress = suppress;
10488   mp->managed = managed;
10489   mp->other = other;
10490   mp->ll_option = ll_option;
10491   mp->send_unicast = send_unicast;
10492   mp->cease = cease;
10493   mp->is_no = is_no;
10494   mp->default_router = default_router;
10495
10496   /* send it... */
10497   S (mp);
10498
10499   /* Wait for a reply, return good/bad news  */
10500   W (ret);
10501   return ret;
10502 }
10503
10504 static int
10505 api_set_arp_neighbor_limit (vat_main_t * vam)
10506 {
10507   unformat_input_t *i = vam->input;
10508   vl_api_set_arp_neighbor_limit_t *mp;
10509   u32 arp_nbr_limit;
10510   u8 limit_set = 0;
10511   u8 is_ipv6 = 0;
10512   int ret;
10513
10514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10517         limit_set = 1;
10518       else if (unformat (i, "ipv6"))
10519         is_ipv6 = 1;
10520       else
10521         {
10522           clib_warning ("parse error '%U'", format_unformat_error, i);
10523           return -99;
10524         }
10525     }
10526
10527   if (limit_set == 0)
10528     {
10529       errmsg ("missing limit value");
10530       return -99;
10531     }
10532
10533   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10534
10535   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10536   mp->is_ipv6 = is_ipv6;
10537
10538   S (mp);
10539   W (ret);
10540   return ret;
10541 }
10542
10543 static int
10544 api_l2_patch_add_del (vat_main_t * vam)
10545 {
10546   unformat_input_t *i = vam->input;
10547   vl_api_l2_patch_add_del_t *mp;
10548   u32 rx_sw_if_index;
10549   u8 rx_sw_if_index_set = 0;
10550   u32 tx_sw_if_index;
10551   u8 tx_sw_if_index_set = 0;
10552   u8 is_add = 1;
10553   int ret;
10554
10555   /* Parse args required to build the message */
10556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10557     {
10558       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10559         rx_sw_if_index_set = 1;
10560       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10561         tx_sw_if_index_set = 1;
10562       else if (unformat (i, "rx"))
10563         {
10564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565             {
10566               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10567                             &rx_sw_if_index))
10568                 rx_sw_if_index_set = 1;
10569             }
10570           else
10571             break;
10572         }
10573       else if (unformat (i, "tx"))
10574         {
10575           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10576             {
10577               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10578                             &tx_sw_if_index))
10579                 tx_sw_if_index_set = 1;
10580             }
10581           else
10582             break;
10583         }
10584       else if (unformat (i, "del"))
10585         is_add = 0;
10586       else
10587         break;
10588     }
10589
10590   if (rx_sw_if_index_set == 0)
10591     {
10592       errmsg ("missing rx interface name or rx_sw_if_index");
10593       return -99;
10594     }
10595
10596   if (tx_sw_if_index_set == 0)
10597     {
10598       errmsg ("missing tx interface name or tx_sw_if_index");
10599       return -99;
10600     }
10601
10602   M (L2_PATCH_ADD_DEL, mp);
10603
10604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10605   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10606   mp->is_add = is_add;
10607
10608   S (mp);
10609   W (ret);
10610   return ret;
10611 }
10612
10613 u8 is_del;
10614 u8 localsid_addr[16];
10615 u8 end_psp;
10616 u8 behavior;
10617 u32 sw_if_index;
10618 u32 vlan_index;
10619 u32 fib_table;
10620 u8 nh_addr[16];
10621
10622 static int
10623 api_sr_localsid_add_del (vat_main_t * vam)
10624 {
10625   unformat_input_t *i = vam->input;
10626   vl_api_sr_localsid_add_del_t *mp;
10627
10628   u8 is_del;
10629   ip6_address_t localsid;
10630   u8 end_psp = 0;
10631   u8 behavior = ~0;
10632   u32 sw_if_index;
10633   u32 fib_table = ~(u32) 0;
10634   ip6_address_t nh_addr6;
10635   ip4_address_t nh_addr4;
10636   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10637   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10638
10639   bool nexthop_set = 0;
10640
10641   int ret;
10642
10643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10644     {
10645       if (unformat (i, "del"))
10646         is_del = 1;
10647       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10648       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10649         nexthop_set = 1;
10650       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10651         nexthop_set = 1;
10652       else if (unformat (i, "behavior %u", &behavior));
10653       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10654       else if (unformat (i, "fib-table %u", &fib_table));
10655       else if (unformat (i, "end.psp %u", &behavior));
10656       else
10657         break;
10658     }
10659
10660   M (SR_LOCALSID_ADD_DEL, mp);
10661
10662   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10663   if (nexthop_set)
10664     {
10665       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10666       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10667     }
10668   mp->behavior = behavior;
10669   mp->sw_if_index = ntohl (sw_if_index);
10670   mp->fib_table = ntohl (fib_table);
10671   mp->end_psp = end_psp;
10672   mp->is_del = is_del;
10673
10674   S (mp);
10675   W (ret);
10676   return ret;
10677 }
10678
10679 static int
10680 api_ioam_enable (vat_main_t * vam)
10681 {
10682   unformat_input_t *input = vam->input;
10683   vl_api_ioam_enable_t *mp;
10684   u32 id = 0;
10685   int has_trace_option = 0;
10686   int has_pot_option = 0;
10687   int has_seqno_option = 0;
10688   int has_analyse_option = 0;
10689   int ret;
10690
10691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10692     {
10693       if (unformat (input, "trace"))
10694         has_trace_option = 1;
10695       else if (unformat (input, "pot"))
10696         has_pot_option = 1;
10697       else if (unformat (input, "seqno"))
10698         has_seqno_option = 1;
10699       else if (unformat (input, "analyse"))
10700         has_analyse_option = 1;
10701       else
10702         break;
10703     }
10704   M (IOAM_ENABLE, mp);
10705   mp->id = htons (id);
10706   mp->seqno = has_seqno_option;
10707   mp->analyse = has_analyse_option;
10708   mp->pot_enable = has_pot_option;
10709   mp->trace_enable = has_trace_option;
10710
10711   S (mp);
10712   W (ret);
10713   return ret;
10714 }
10715
10716
10717 static int
10718 api_ioam_disable (vat_main_t * vam)
10719 {
10720   vl_api_ioam_disable_t *mp;
10721   int ret;
10722
10723   M (IOAM_DISABLE, mp);
10724   S (mp);
10725   W (ret);
10726   return ret;
10727 }
10728
10729 #define foreach_tcp_proto_field                 \
10730 _(src_port)                                     \
10731 _(dst_port)
10732
10733 #define foreach_udp_proto_field                 \
10734 _(src_port)                                     \
10735 _(dst_port)
10736
10737 #define foreach_ip4_proto_field                 \
10738 _(src_address)                                  \
10739 _(dst_address)                                  \
10740 _(tos)                                          \
10741 _(length)                                       \
10742 _(fragment_id)                                  \
10743 _(ttl)                                          \
10744 _(protocol)                                     \
10745 _(checksum)
10746
10747 typedef struct
10748 {
10749   u16 src_port, dst_port;
10750 } tcpudp_header_t;
10751
10752 #if VPP_API_TEST_BUILTIN == 0
10753 uword
10754 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10755 {
10756   u8 **maskp = va_arg (*args, u8 **);
10757   u8 *mask = 0;
10758   u8 found_something = 0;
10759   tcp_header_t *tcp;
10760
10761 #define _(a) u8 a=0;
10762   foreach_tcp_proto_field;
10763 #undef _
10764
10765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (0);
10768 #define _(a) else if (unformat (input, #a)) a=1;
10769       foreach_tcp_proto_field
10770 #undef _
10771         else
10772         break;
10773     }
10774
10775 #define _(a) found_something += a;
10776   foreach_tcp_proto_field;
10777 #undef _
10778
10779   if (found_something == 0)
10780     return 0;
10781
10782   vec_validate (mask, sizeof (*tcp) - 1);
10783
10784   tcp = (tcp_header_t *) mask;
10785
10786 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10787   foreach_tcp_proto_field;
10788 #undef _
10789
10790   *maskp = mask;
10791   return 1;
10792 }
10793
10794 uword
10795 unformat_udp_mask (unformat_input_t * input, va_list * args)
10796 {
10797   u8 **maskp = va_arg (*args, u8 **);
10798   u8 *mask = 0;
10799   u8 found_something = 0;
10800   udp_header_t *udp;
10801
10802 #define _(a) u8 a=0;
10803   foreach_udp_proto_field;
10804 #undef _
10805
10806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (0);
10809 #define _(a) else if (unformat (input, #a)) a=1;
10810       foreach_udp_proto_field
10811 #undef _
10812         else
10813         break;
10814     }
10815
10816 #define _(a) found_something += a;
10817   foreach_udp_proto_field;
10818 #undef _
10819
10820   if (found_something == 0)
10821     return 0;
10822
10823   vec_validate (mask, sizeof (*udp) - 1);
10824
10825   udp = (udp_header_t *) mask;
10826
10827 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10828   foreach_udp_proto_field;
10829 #undef _
10830
10831   *maskp = mask;
10832   return 1;
10833 }
10834
10835 uword
10836 unformat_l4_mask (unformat_input_t * input, va_list * args)
10837 {
10838   u8 **maskp = va_arg (*args, u8 **);
10839   u16 src_port = 0, dst_port = 0;
10840   tcpudp_header_t *tcpudp;
10841
10842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10843     {
10844       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10845         return 1;
10846       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10847         return 1;
10848       else if (unformat (input, "src_port"))
10849         src_port = 0xFFFF;
10850       else if (unformat (input, "dst_port"))
10851         dst_port = 0xFFFF;
10852       else
10853         return 0;
10854     }
10855
10856   if (!src_port && !dst_port)
10857     return 0;
10858
10859   u8 *mask = 0;
10860   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10861
10862   tcpudp = (tcpudp_header_t *) mask;
10863   tcpudp->src_port = src_port;
10864   tcpudp->dst_port = dst_port;
10865
10866   *maskp = mask;
10867
10868   return 1;
10869 }
10870
10871 uword
10872 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10873 {
10874   u8 **maskp = va_arg (*args, u8 **);
10875   u8 *mask = 0;
10876   u8 found_something = 0;
10877   ip4_header_t *ip;
10878
10879 #define _(a) u8 a=0;
10880   foreach_ip4_proto_field;
10881 #undef _
10882   u8 version = 0;
10883   u8 hdr_length = 0;
10884
10885
10886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (input, "version"))
10889         version = 1;
10890       else if (unformat (input, "hdr_length"))
10891         hdr_length = 1;
10892       else if (unformat (input, "src"))
10893         src_address = 1;
10894       else if (unformat (input, "dst"))
10895         dst_address = 1;
10896       else if (unformat (input, "proto"))
10897         protocol = 1;
10898
10899 #define _(a) else if (unformat (input, #a)) a=1;
10900       foreach_ip4_proto_field
10901 #undef _
10902         else
10903         break;
10904     }
10905
10906 #define _(a) found_something += a;
10907   foreach_ip4_proto_field;
10908 #undef _
10909
10910   if (found_something == 0)
10911     return 0;
10912
10913   vec_validate (mask, sizeof (*ip) - 1);
10914
10915   ip = (ip4_header_t *) mask;
10916
10917 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10918   foreach_ip4_proto_field;
10919 #undef _
10920
10921   ip->ip_version_and_header_length = 0;
10922
10923   if (version)
10924     ip->ip_version_and_header_length |= 0xF0;
10925
10926   if (hdr_length)
10927     ip->ip_version_and_header_length |= 0x0F;
10928
10929   *maskp = mask;
10930   return 1;
10931 }
10932
10933 #define foreach_ip6_proto_field                 \
10934 _(src_address)                                  \
10935 _(dst_address)                                  \
10936 _(payload_length)                               \
10937 _(hop_limit)                                    \
10938 _(protocol)
10939
10940 uword
10941 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10942 {
10943   u8 **maskp = va_arg (*args, u8 **);
10944   u8 *mask = 0;
10945   u8 found_something = 0;
10946   ip6_header_t *ip;
10947   u32 ip_version_traffic_class_and_flow_label;
10948
10949 #define _(a) u8 a=0;
10950   foreach_ip6_proto_field;
10951 #undef _
10952   u8 version = 0;
10953   u8 traffic_class = 0;
10954   u8 flow_label = 0;
10955
10956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10957     {
10958       if (unformat (input, "version"))
10959         version = 1;
10960       else if (unformat (input, "traffic-class"))
10961         traffic_class = 1;
10962       else if (unformat (input, "flow-label"))
10963         flow_label = 1;
10964       else if (unformat (input, "src"))
10965         src_address = 1;
10966       else if (unformat (input, "dst"))
10967         dst_address = 1;
10968       else if (unformat (input, "proto"))
10969         protocol = 1;
10970
10971 #define _(a) else if (unformat (input, #a)) a=1;
10972       foreach_ip6_proto_field
10973 #undef _
10974         else
10975         break;
10976     }
10977
10978 #define _(a) found_something += a;
10979   foreach_ip6_proto_field;
10980 #undef _
10981
10982   if (found_something == 0)
10983     return 0;
10984
10985   vec_validate (mask, sizeof (*ip) - 1);
10986
10987   ip = (ip6_header_t *) mask;
10988
10989 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10990   foreach_ip6_proto_field;
10991 #undef _
10992
10993   ip_version_traffic_class_and_flow_label = 0;
10994
10995   if (version)
10996     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10997
10998   if (traffic_class)
10999     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11000
11001   if (flow_label)
11002     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11003
11004   ip->ip_version_traffic_class_and_flow_label =
11005     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11006
11007   *maskp = mask;
11008   return 1;
11009 }
11010
11011 uword
11012 unformat_l3_mask (unformat_input_t * input, va_list * args)
11013 {
11014   u8 **maskp = va_arg (*args, u8 **);
11015
11016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11017     {
11018       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11019         return 1;
11020       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11021         return 1;
11022       else
11023         break;
11024     }
11025   return 0;
11026 }
11027
11028 uword
11029 unformat_l2_mask (unformat_input_t * input, va_list * args)
11030 {
11031   u8 **maskp = va_arg (*args, u8 **);
11032   u8 *mask = 0;
11033   u8 src = 0;
11034   u8 dst = 0;
11035   u8 proto = 0;
11036   u8 tag1 = 0;
11037   u8 tag2 = 0;
11038   u8 ignore_tag1 = 0;
11039   u8 ignore_tag2 = 0;
11040   u8 cos1 = 0;
11041   u8 cos2 = 0;
11042   u8 dot1q = 0;
11043   u8 dot1ad = 0;
11044   int len = 14;
11045
11046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11047     {
11048       if (unformat (input, "src"))
11049         src = 1;
11050       else if (unformat (input, "dst"))
11051         dst = 1;
11052       else if (unformat (input, "proto"))
11053         proto = 1;
11054       else if (unformat (input, "tag1"))
11055         tag1 = 1;
11056       else if (unformat (input, "tag2"))
11057         tag2 = 1;
11058       else if (unformat (input, "ignore-tag1"))
11059         ignore_tag1 = 1;
11060       else if (unformat (input, "ignore-tag2"))
11061         ignore_tag2 = 1;
11062       else if (unformat (input, "cos1"))
11063         cos1 = 1;
11064       else if (unformat (input, "cos2"))
11065         cos2 = 1;
11066       else if (unformat (input, "dot1q"))
11067         dot1q = 1;
11068       else if (unformat (input, "dot1ad"))
11069         dot1ad = 1;
11070       else
11071         break;
11072     }
11073   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11074        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11075     return 0;
11076
11077   if (tag1 || ignore_tag1 || cos1 || dot1q)
11078     len = 18;
11079   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11080     len = 22;
11081
11082   vec_validate (mask, len - 1);
11083
11084   if (dst)
11085     clib_memset (mask, 0xff, 6);
11086
11087   if (src)
11088     clib_memset (mask + 6, 0xff, 6);
11089
11090   if (tag2 || dot1ad)
11091     {
11092       /* inner vlan tag */
11093       if (tag2)
11094         {
11095           mask[19] = 0xff;
11096           mask[18] = 0x0f;
11097         }
11098       if (cos2)
11099         mask[18] |= 0xe0;
11100       if (proto)
11101         mask[21] = mask[20] = 0xff;
11102       if (tag1)
11103         {
11104           mask[15] = 0xff;
11105           mask[14] = 0x0f;
11106         }
11107       if (cos1)
11108         mask[14] |= 0xe0;
11109       *maskp = mask;
11110       return 1;
11111     }
11112   if (tag1 | dot1q)
11113     {
11114       if (tag1)
11115         {
11116           mask[15] = 0xff;
11117           mask[14] = 0x0f;
11118         }
11119       if (cos1)
11120         mask[14] |= 0xe0;
11121       if (proto)
11122         mask[16] = mask[17] = 0xff;
11123
11124       *maskp = mask;
11125       return 1;
11126     }
11127   if (cos2)
11128     mask[18] |= 0xe0;
11129   if (cos1)
11130     mask[14] |= 0xe0;
11131   if (proto)
11132     mask[12] = mask[13] = 0xff;
11133
11134   *maskp = mask;
11135   return 1;
11136 }
11137
11138 uword
11139 unformat_classify_mask (unformat_input_t * input, va_list * args)
11140 {
11141   u8 **maskp = va_arg (*args, u8 **);
11142   u32 *skipp = va_arg (*args, u32 *);
11143   u32 *matchp = va_arg (*args, u32 *);
11144   u32 match;
11145   u8 *mask = 0;
11146   u8 *l2 = 0;
11147   u8 *l3 = 0;
11148   u8 *l4 = 0;
11149   int i;
11150
11151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11152     {
11153       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11154         ;
11155       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11156         ;
11157       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11158         ;
11159       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11160         ;
11161       else
11162         break;
11163     }
11164
11165   if (l4 && !l3)
11166     {
11167       vec_free (mask);
11168       vec_free (l2);
11169       vec_free (l4);
11170       return 0;
11171     }
11172
11173   if (mask || l2 || l3 || l4)
11174     {
11175       if (l2 || l3 || l4)
11176         {
11177           /* "With a free Ethernet header in every package" */
11178           if (l2 == 0)
11179             vec_validate (l2, 13);
11180           mask = l2;
11181           if (vec_len (l3))
11182             {
11183               vec_append (mask, l3);
11184               vec_free (l3);
11185             }
11186           if (vec_len (l4))
11187             {
11188               vec_append (mask, l4);
11189               vec_free (l4);
11190             }
11191         }
11192
11193       /* Scan forward looking for the first significant mask octet */
11194       for (i = 0; i < vec_len (mask); i++)
11195         if (mask[i])
11196           break;
11197
11198       /* compute (skip, match) params */
11199       *skipp = i / sizeof (u32x4);
11200       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11201
11202       /* Pad mask to an even multiple of the vector size */
11203       while (vec_len (mask) % sizeof (u32x4))
11204         vec_add1 (mask, 0);
11205
11206       match = vec_len (mask) / sizeof (u32x4);
11207
11208       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11209         {
11210           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11211           if (*tmp || *(tmp + 1))
11212             break;
11213           match--;
11214         }
11215       if (match == 0)
11216         clib_warning ("BUG: match 0");
11217
11218       _vec_len (mask) = match * sizeof (u32x4);
11219
11220       *matchp = match;
11221       *maskp = mask;
11222
11223       return 1;
11224     }
11225
11226   return 0;
11227 }
11228 #endif /* VPP_API_TEST_BUILTIN */
11229
11230 #define foreach_l2_next                         \
11231 _(drop, DROP)                                   \
11232 _(ethernet, ETHERNET_INPUT)                     \
11233 _(ip4, IP4_INPUT)                               \
11234 _(ip6, IP6_INPUT)
11235
11236 uword
11237 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11238 {
11239   u32 *miss_next_indexp = va_arg (*args, u32 *);
11240   u32 next_index = 0;
11241   u32 tmp;
11242
11243 #define _(n,N) \
11244   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11245   foreach_l2_next;
11246 #undef _
11247
11248   if (unformat (input, "%d", &tmp))
11249     {
11250       next_index = tmp;
11251       goto out;
11252     }
11253
11254   return 0;
11255
11256 out:
11257   *miss_next_indexp = next_index;
11258   return 1;
11259 }
11260
11261 #define foreach_ip_next                         \
11262 _(drop, DROP)                                   \
11263 _(local, LOCAL)                                 \
11264 _(rewrite, REWRITE)
11265
11266 uword
11267 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11268 {
11269   u32 *miss_next_indexp = va_arg (*args, u32 *);
11270   u32 next_index = 0;
11271   u32 tmp;
11272
11273 #define _(n,N) \
11274   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11275   foreach_ip_next;
11276 #undef _
11277
11278   if (unformat (input, "%d", &tmp))
11279     {
11280       next_index = tmp;
11281       goto out;
11282     }
11283
11284   return 0;
11285
11286 out:
11287   *miss_next_indexp = next_index;
11288   return 1;
11289 }
11290
11291 #define foreach_acl_next                        \
11292 _(deny, DENY)
11293
11294 uword
11295 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11296 {
11297   u32 *miss_next_indexp = va_arg (*args, u32 *);
11298   u32 next_index = 0;
11299   u32 tmp;
11300
11301 #define _(n,N) \
11302   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11303   foreach_acl_next;
11304 #undef _
11305
11306   if (unformat (input, "permit"))
11307     {
11308       next_index = ~0;
11309       goto out;
11310     }
11311   else if (unformat (input, "%d", &tmp))
11312     {
11313       next_index = tmp;
11314       goto out;
11315     }
11316
11317   return 0;
11318
11319 out:
11320   *miss_next_indexp = next_index;
11321   return 1;
11322 }
11323
11324 uword
11325 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11326 {
11327   u32 *r = va_arg (*args, u32 *);
11328
11329   if (unformat (input, "conform-color"))
11330     *r = POLICE_CONFORM;
11331   else if (unformat (input, "exceed-color"))
11332     *r = POLICE_EXCEED;
11333   else
11334     return 0;
11335
11336   return 1;
11337 }
11338
11339 static int
11340 api_classify_add_del_table (vat_main_t * vam)
11341 {
11342   unformat_input_t *i = vam->input;
11343   vl_api_classify_add_del_table_t *mp;
11344
11345   u32 nbuckets = 2;
11346   u32 skip = ~0;
11347   u32 match = ~0;
11348   int is_add = 1;
11349   int del_chain = 0;
11350   u32 table_index = ~0;
11351   u32 next_table_index = ~0;
11352   u32 miss_next_index = ~0;
11353   u32 memory_size = 32 << 20;
11354   u8 *mask = 0;
11355   u32 current_data_flag = 0;
11356   int current_data_offset = 0;
11357   int ret;
11358
11359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11360     {
11361       if (unformat (i, "del"))
11362         is_add = 0;
11363       else if (unformat (i, "del-chain"))
11364         {
11365           is_add = 0;
11366           del_chain = 1;
11367         }
11368       else if (unformat (i, "buckets %d", &nbuckets))
11369         ;
11370       else if (unformat (i, "memory_size %d", &memory_size))
11371         ;
11372       else if (unformat (i, "skip %d", &skip))
11373         ;
11374       else if (unformat (i, "match %d", &match))
11375         ;
11376       else if (unformat (i, "table %d", &table_index))
11377         ;
11378       else if (unformat (i, "mask %U", unformat_classify_mask,
11379                          &mask, &skip, &match))
11380         ;
11381       else if (unformat (i, "next-table %d", &next_table_index))
11382         ;
11383       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11384                          &miss_next_index))
11385         ;
11386       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11387                          &miss_next_index))
11388         ;
11389       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11390                          &miss_next_index))
11391         ;
11392       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11393         ;
11394       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11395         ;
11396       else
11397         break;
11398     }
11399
11400   if (is_add && mask == 0)
11401     {
11402       errmsg ("Mask required");
11403       return -99;
11404     }
11405
11406   if (is_add && skip == ~0)
11407     {
11408       errmsg ("skip count required");
11409       return -99;
11410     }
11411
11412   if (is_add && match == ~0)
11413     {
11414       errmsg ("match count required");
11415       return -99;
11416     }
11417
11418   if (!is_add && table_index == ~0)
11419     {
11420       errmsg ("table index required for delete");
11421       return -99;
11422     }
11423
11424   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11425
11426   mp->is_add = is_add;
11427   mp->del_chain = del_chain;
11428   mp->table_index = ntohl (table_index);
11429   mp->nbuckets = ntohl (nbuckets);
11430   mp->memory_size = ntohl (memory_size);
11431   mp->skip_n_vectors = ntohl (skip);
11432   mp->match_n_vectors = ntohl (match);
11433   mp->next_table_index = ntohl (next_table_index);
11434   mp->miss_next_index = ntohl (miss_next_index);
11435   mp->current_data_flag = ntohl (current_data_flag);
11436   mp->current_data_offset = ntohl (current_data_offset);
11437   mp->mask_len = ntohl (vec_len (mask));
11438   clib_memcpy (mp->mask, mask, vec_len (mask));
11439
11440   vec_free (mask);
11441
11442   S (mp);
11443   W (ret);
11444   return ret;
11445 }
11446
11447 #if VPP_API_TEST_BUILTIN == 0
11448 uword
11449 unformat_l4_match (unformat_input_t * input, va_list * args)
11450 {
11451   u8 **matchp = va_arg (*args, u8 **);
11452
11453   u8 *proto_header = 0;
11454   int src_port = 0;
11455   int dst_port = 0;
11456
11457   tcpudp_header_t h;
11458
11459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11460     {
11461       if (unformat (input, "src_port %d", &src_port))
11462         ;
11463       else if (unformat (input, "dst_port %d", &dst_port))
11464         ;
11465       else
11466         return 0;
11467     }
11468
11469   h.src_port = clib_host_to_net_u16 (src_port);
11470   h.dst_port = clib_host_to_net_u16 (dst_port);
11471   vec_validate (proto_header, sizeof (h) - 1);
11472   memcpy (proto_header, &h, sizeof (h));
11473
11474   *matchp = proto_header;
11475
11476   return 1;
11477 }
11478
11479 uword
11480 unformat_ip4_match (unformat_input_t * input, va_list * args)
11481 {
11482   u8 **matchp = va_arg (*args, u8 **);
11483   u8 *match = 0;
11484   ip4_header_t *ip;
11485   int version = 0;
11486   u32 version_val;
11487   int hdr_length = 0;
11488   u32 hdr_length_val;
11489   int src = 0, dst = 0;
11490   ip4_address_t src_val, dst_val;
11491   int proto = 0;
11492   u32 proto_val;
11493   int tos = 0;
11494   u32 tos_val;
11495   int length = 0;
11496   u32 length_val;
11497   int fragment_id = 0;
11498   u32 fragment_id_val;
11499   int ttl = 0;
11500   int ttl_val;
11501   int checksum = 0;
11502   u32 checksum_val;
11503
11504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11505     {
11506       if (unformat (input, "version %d", &version_val))
11507         version = 1;
11508       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11509         hdr_length = 1;
11510       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11511         src = 1;
11512       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11513         dst = 1;
11514       else if (unformat (input, "proto %d", &proto_val))
11515         proto = 1;
11516       else if (unformat (input, "tos %d", &tos_val))
11517         tos = 1;
11518       else if (unformat (input, "length %d", &length_val))
11519         length = 1;
11520       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11521         fragment_id = 1;
11522       else if (unformat (input, "ttl %d", &ttl_val))
11523         ttl = 1;
11524       else if (unformat (input, "checksum %d", &checksum_val))
11525         checksum = 1;
11526       else
11527         break;
11528     }
11529
11530   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11531       + ttl + checksum == 0)
11532     return 0;
11533
11534   /*
11535    * Aligned because we use the real comparison functions
11536    */
11537   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11538
11539   ip = (ip4_header_t *) match;
11540
11541   /* These are realistically matched in practice */
11542   if (src)
11543     ip->src_address.as_u32 = src_val.as_u32;
11544
11545   if (dst)
11546     ip->dst_address.as_u32 = dst_val.as_u32;
11547
11548   if (proto)
11549     ip->protocol = proto_val;
11550
11551
11552   /* These are not, but they're included for completeness */
11553   if (version)
11554     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11555
11556   if (hdr_length)
11557     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11558
11559   if (tos)
11560     ip->tos = tos_val;
11561
11562   if (length)
11563     ip->length = clib_host_to_net_u16 (length_val);
11564
11565   if (ttl)
11566     ip->ttl = ttl_val;
11567
11568   if (checksum)
11569     ip->checksum = clib_host_to_net_u16 (checksum_val);
11570
11571   *matchp = match;
11572   return 1;
11573 }
11574
11575 uword
11576 unformat_ip6_match (unformat_input_t * input, va_list * args)
11577 {
11578   u8 **matchp = va_arg (*args, u8 **);
11579   u8 *match = 0;
11580   ip6_header_t *ip;
11581   int version = 0;
11582   u32 version_val;
11583   u8 traffic_class = 0;
11584   u32 traffic_class_val = 0;
11585   u8 flow_label = 0;
11586   u8 flow_label_val;
11587   int src = 0, dst = 0;
11588   ip6_address_t src_val, dst_val;
11589   int proto = 0;
11590   u32 proto_val;
11591   int payload_length = 0;
11592   u32 payload_length_val;
11593   int hop_limit = 0;
11594   int hop_limit_val;
11595   u32 ip_version_traffic_class_and_flow_label;
11596
11597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11598     {
11599       if (unformat (input, "version %d", &version_val))
11600         version = 1;
11601       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11602         traffic_class = 1;
11603       else if (unformat (input, "flow_label %d", &flow_label_val))
11604         flow_label = 1;
11605       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11606         src = 1;
11607       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11608         dst = 1;
11609       else if (unformat (input, "proto %d", &proto_val))
11610         proto = 1;
11611       else if (unformat (input, "payload_length %d", &payload_length_val))
11612         payload_length = 1;
11613       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11614         hop_limit = 1;
11615       else
11616         break;
11617     }
11618
11619   if (version + traffic_class + flow_label + src + dst + proto +
11620       payload_length + hop_limit == 0)
11621     return 0;
11622
11623   /*
11624    * Aligned because we use the real comparison functions
11625    */
11626   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11627
11628   ip = (ip6_header_t *) match;
11629
11630   if (src)
11631     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11632
11633   if (dst)
11634     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11635
11636   if (proto)
11637     ip->protocol = proto_val;
11638
11639   ip_version_traffic_class_and_flow_label = 0;
11640
11641   if (version)
11642     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11643
11644   if (traffic_class)
11645     ip_version_traffic_class_and_flow_label |=
11646       (traffic_class_val & 0xFF) << 20;
11647
11648   if (flow_label)
11649     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11650
11651   ip->ip_version_traffic_class_and_flow_label =
11652     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11653
11654   if (payload_length)
11655     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11656
11657   if (hop_limit)
11658     ip->hop_limit = hop_limit_val;
11659
11660   *matchp = match;
11661   return 1;
11662 }
11663
11664 uword
11665 unformat_l3_match (unformat_input_t * input, va_list * args)
11666 {
11667   u8 **matchp = va_arg (*args, u8 **);
11668
11669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11670     {
11671       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11672         return 1;
11673       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11674         return 1;
11675       else
11676         break;
11677     }
11678   return 0;
11679 }
11680
11681 uword
11682 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11683 {
11684   u8 *tagp = va_arg (*args, u8 *);
11685   u32 tag;
11686
11687   if (unformat (input, "%d", &tag))
11688     {
11689       tagp[0] = (tag >> 8) & 0x0F;
11690       tagp[1] = tag & 0xFF;
11691       return 1;
11692     }
11693
11694   return 0;
11695 }
11696
11697 uword
11698 unformat_l2_match (unformat_input_t * input, va_list * args)
11699 {
11700   u8 **matchp = va_arg (*args, u8 **);
11701   u8 *match = 0;
11702   u8 src = 0;
11703   u8 src_val[6];
11704   u8 dst = 0;
11705   u8 dst_val[6];
11706   u8 proto = 0;
11707   u16 proto_val;
11708   u8 tag1 = 0;
11709   u8 tag1_val[2];
11710   u8 tag2 = 0;
11711   u8 tag2_val[2];
11712   int len = 14;
11713   u8 ignore_tag1 = 0;
11714   u8 ignore_tag2 = 0;
11715   u8 cos1 = 0;
11716   u8 cos2 = 0;
11717   u32 cos1_val = 0;
11718   u32 cos2_val = 0;
11719
11720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11721     {
11722       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11723         src = 1;
11724       else
11725         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11726         dst = 1;
11727       else if (unformat (input, "proto %U",
11728                          unformat_ethernet_type_host_byte_order, &proto_val))
11729         proto = 1;
11730       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11731         tag1 = 1;
11732       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11733         tag2 = 1;
11734       else if (unformat (input, "ignore-tag1"))
11735         ignore_tag1 = 1;
11736       else if (unformat (input, "ignore-tag2"))
11737         ignore_tag2 = 1;
11738       else if (unformat (input, "cos1 %d", &cos1_val))
11739         cos1 = 1;
11740       else if (unformat (input, "cos2 %d", &cos2_val))
11741         cos2 = 1;
11742       else
11743         break;
11744     }
11745   if ((src + dst + proto + tag1 + tag2 +
11746        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11747     return 0;
11748
11749   if (tag1 || ignore_tag1 || cos1)
11750     len = 18;
11751   if (tag2 || ignore_tag2 || cos2)
11752     len = 22;
11753
11754   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11755
11756   if (dst)
11757     clib_memcpy (match, dst_val, 6);
11758
11759   if (src)
11760     clib_memcpy (match + 6, src_val, 6);
11761
11762   if (tag2)
11763     {
11764       /* inner vlan tag */
11765       match[19] = tag2_val[1];
11766       match[18] = tag2_val[0];
11767       if (cos2)
11768         match[18] |= (cos2_val & 0x7) << 5;
11769       if (proto)
11770         {
11771           match[21] = proto_val & 0xff;
11772           match[20] = proto_val >> 8;
11773         }
11774       if (tag1)
11775         {
11776           match[15] = tag1_val[1];
11777           match[14] = tag1_val[0];
11778         }
11779       if (cos1)
11780         match[14] |= (cos1_val & 0x7) << 5;
11781       *matchp = match;
11782       return 1;
11783     }
11784   if (tag1)
11785     {
11786       match[15] = tag1_val[1];
11787       match[14] = tag1_val[0];
11788       if (proto)
11789         {
11790           match[17] = proto_val & 0xff;
11791           match[16] = proto_val >> 8;
11792         }
11793       if (cos1)
11794         match[14] |= (cos1_val & 0x7) << 5;
11795
11796       *matchp = match;
11797       return 1;
11798     }
11799   if (cos2)
11800     match[18] |= (cos2_val & 0x7) << 5;
11801   if (cos1)
11802     match[14] |= (cos1_val & 0x7) << 5;
11803   if (proto)
11804     {
11805       match[13] = proto_val & 0xff;
11806       match[12] = proto_val >> 8;
11807     }
11808
11809   *matchp = match;
11810   return 1;
11811 }
11812
11813 uword
11814 unformat_qos_source (unformat_input_t * input, va_list * args)
11815 {
11816   int *qs = va_arg (*args, int *);
11817
11818   if (unformat (input, "ip"))
11819     *qs = QOS_SOURCE_IP;
11820   else if (unformat (input, "mpls"))
11821     *qs = QOS_SOURCE_MPLS;
11822   else if (unformat (input, "ext"))
11823     *qs = QOS_SOURCE_EXT;
11824   else if (unformat (input, "vlan"))
11825     *qs = QOS_SOURCE_VLAN;
11826   else
11827     return 0;
11828
11829   return 1;
11830 }
11831 #endif
11832
11833 uword
11834 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11835 {
11836   u8 **matchp = va_arg (*args, u8 **);
11837   u32 skip_n_vectors = va_arg (*args, u32);
11838   u32 match_n_vectors = va_arg (*args, u32);
11839
11840   u8 *match = 0;
11841   u8 *l2 = 0;
11842   u8 *l3 = 0;
11843   u8 *l4 = 0;
11844
11845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11846     {
11847       if (unformat (input, "hex %U", unformat_hex_string, &match))
11848         ;
11849       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11850         ;
11851       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11852         ;
11853       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11854         ;
11855       else
11856         break;
11857     }
11858
11859   if (l4 && !l3)
11860     {
11861       vec_free (match);
11862       vec_free (l2);
11863       vec_free (l4);
11864       return 0;
11865     }
11866
11867   if (match || l2 || l3 || l4)
11868     {
11869       if (l2 || l3 || l4)
11870         {
11871           /* "Win a free Ethernet header in every packet" */
11872           if (l2 == 0)
11873             vec_validate_aligned (l2, 13, sizeof (u32x4));
11874           match = l2;
11875           if (vec_len (l3))
11876             {
11877               vec_append_aligned (match, l3, sizeof (u32x4));
11878               vec_free (l3);
11879             }
11880           if (vec_len (l4))
11881             {
11882               vec_append_aligned (match, l4, sizeof (u32x4));
11883               vec_free (l4);
11884             }
11885         }
11886
11887       /* Make sure the vector is big enough even if key is all 0's */
11888       vec_validate_aligned
11889         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11890          sizeof (u32x4));
11891
11892       /* Set size, include skipped vectors */
11893       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11894
11895       *matchp = match;
11896
11897       return 1;
11898     }
11899
11900   return 0;
11901 }
11902
11903 static int
11904 api_classify_add_del_session (vat_main_t * vam)
11905 {
11906   unformat_input_t *i = vam->input;
11907   vl_api_classify_add_del_session_t *mp;
11908   int is_add = 1;
11909   u32 table_index = ~0;
11910   u32 hit_next_index = ~0;
11911   u32 opaque_index = ~0;
11912   u8 *match = 0;
11913   i32 advance = 0;
11914   u32 skip_n_vectors = 0;
11915   u32 match_n_vectors = 0;
11916   u32 action = 0;
11917   u32 metadata = 0;
11918   int ret;
11919
11920   /*
11921    * Warning: you have to supply skip_n and match_n
11922    * because the API client cant simply look at the classify
11923    * table object.
11924    */
11925
11926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11927     {
11928       if (unformat (i, "del"))
11929         is_add = 0;
11930       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11931                          &hit_next_index))
11932         ;
11933       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11934                          &hit_next_index))
11935         ;
11936       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11937                          &hit_next_index))
11938         ;
11939       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11940         ;
11941       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11942         ;
11943       else if (unformat (i, "opaque-index %d", &opaque_index))
11944         ;
11945       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11946         ;
11947       else if (unformat (i, "match_n %d", &match_n_vectors))
11948         ;
11949       else if (unformat (i, "match %U", api_unformat_classify_match,
11950                          &match, skip_n_vectors, match_n_vectors))
11951         ;
11952       else if (unformat (i, "advance %d", &advance))
11953         ;
11954       else if (unformat (i, "table-index %d", &table_index))
11955         ;
11956       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11957         action = 1;
11958       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11959         action = 2;
11960       else if (unformat (i, "action %d", &action))
11961         ;
11962       else if (unformat (i, "metadata %d", &metadata))
11963         ;
11964       else
11965         break;
11966     }
11967
11968   if (table_index == ~0)
11969     {
11970       errmsg ("Table index required");
11971       return -99;
11972     }
11973
11974   if (is_add && match == 0)
11975     {
11976       errmsg ("Match value required");
11977       return -99;
11978     }
11979
11980   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11981
11982   mp->is_add = is_add;
11983   mp->table_index = ntohl (table_index);
11984   mp->hit_next_index = ntohl (hit_next_index);
11985   mp->opaque_index = ntohl (opaque_index);
11986   mp->advance = ntohl (advance);
11987   mp->action = action;
11988   mp->metadata = ntohl (metadata);
11989   mp->match_len = ntohl (vec_len (match));
11990   clib_memcpy (mp->match, match, vec_len (match));
11991   vec_free (match);
11992
11993   S (mp);
11994   W (ret);
11995   return ret;
11996 }
11997
11998 static int
11999 api_classify_set_interface_ip_table (vat_main_t * vam)
12000 {
12001   unformat_input_t *i = vam->input;
12002   vl_api_classify_set_interface_ip_table_t *mp;
12003   u32 sw_if_index;
12004   int sw_if_index_set;
12005   u32 table_index = ~0;
12006   u8 is_ipv6 = 0;
12007   int ret;
12008
12009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12010     {
12011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12012         sw_if_index_set = 1;
12013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12014         sw_if_index_set = 1;
12015       else if (unformat (i, "table %d", &table_index))
12016         ;
12017       else
12018         {
12019           clib_warning ("parse error '%U'", format_unformat_error, i);
12020           return -99;
12021         }
12022     }
12023
12024   if (sw_if_index_set == 0)
12025     {
12026       errmsg ("missing interface name or sw_if_index");
12027       return -99;
12028     }
12029
12030
12031   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12032
12033   mp->sw_if_index = ntohl (sw_if_index);
12034   mp->table_index = ntohl (table_index);
12035   mp->is_ipv6 = is_ipv6;
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_classify_set_interface_l2_tables (vat_main_t * vam)
12044 {
12045   unformat_input_t *i = vam->input;
12046   vl_api_classify_set_interface_l2_tables_t *mp;
12047   u32 sw_if_index;
12048   int sw_if_index_set;
12049   u32 ip4_table_index = ~0;
12050   u32 ip6_table_index = ~0;
12051   u32 other_table_index = ~0;
12052   u32 is_input = 1;
12053   int ret;
12054
12055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12056     {
12057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12058         sw_if_index_set = 1;
12059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12060         sw_if_index_set = 1;
12061       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12062         ;
12063       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12064         ;
12065       else if (unformat (i, "other-table %d", &other_table_index))
12066         ;
12067       else if (unformat (i, "is-input %d", &is_input))
12068         ;
12069       else
12070         {
12071           clib_warning ("parse error '%U'", format_unformat_error, i);
12072           return -99;
12073         }
12074     }
12075
12076   if (sw_if_index_set == 0)
12077     {
12078       errmsg ("missing interface name or sw_if_index");
12079       return -99;
12080     }
12081
12082
12083   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12084
12085   mp->sw_if_index = ntohl (sw_if_index);
12086   mp->ip4_table_index = ntohl (ip4_table_index);
12087   mp->ip6_table_index = ntohl (ip6_table_index);
12088   mp->other_table_index = ntohl (other_table_index);
12089   mp->is_input = (u8) is_input;
12090
12091   S (mp);
12092   W (ret);
12093   return ret;
12094 }
12095
12096 static int
12097 api_set_ipfix_exporter (vat_main_t * vam)
12098 {
12099   unformat_input_t *i = vam->input;
12100   vl_api_set_ipfix_exporter_t *mp;
12101   ip4_address_t collector_address;
12102   u8 collector_address_set = 0;
12103   u32 collector_port = ~0;
12104   ip4_address_t src_address;
12105   u8 src_address_set = 0;
12106   u32 vrf_id = ~0;
12107   u32 path_mtu = ~0;
12108   u32 template_interval = ~0;
12109   u8 udp_checksum = 0;
12110   int ret;
12111
12112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (i, "collector_address %U", unformat_ip4_address,
12115                     &collector_address))
12116         collector_address_set = 1;
12117       else if (unformat (i, "collector_port %d", &collector_port))
12118         ;
12119       else if (unformat (i, "src_address %U", unformat_ip4_address,
12120                          &src_address))
12121         src_address_set = 1;
12122       else if (unformat (i, "vrf_id %d", &vrf_id))
12123         ;
12124       else if (unformat (i, "path_mtu %d", &path_mtu))
12125         ;
12126       else if (unformat (i, "template_interval %d", &template_interval))
12127         ;
12128       else if (unformat (i, "udp_checksum"))
12129         udp_checksum = 1;
12130       else
12131         break;
12132     }
12133
12134   if (collector_address_set == 0)
12135     {
12136       errmsg ("collector_address required");
12137       return -99;
12138     }
12139
12140   if (src_address_set == 0)
12141     {
12142       errmsg ("src_address required");
12143       return -99;
12144     }
12145
12146   M (SET_IPFIX_EXPORTER, mp);
12147
12148   memcpy (mp->collector_address, collector_address.data,
12149           sizeof (collector_address.data));
12150   mp->collector_port = htons ((u16) collector_port);
12151   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12152   mp->vrf_id = htonl (vrf_id);
12153   mp->path_mtu = htonl (path_mtu);
12154   mp->template_interval = htonl (template_interval);
12155   mp->udp_checksum = udp_checksum;
12156
12157   S (mp);
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static int
12163 api_set_ipfix_classify_stream (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   vl_api_set_ipfix_classify_stream_t *mp;
12167   u32 domain_id = 0;
12168   u32 src_port = UDP_DST_PORT_ipfix;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "domain %d", &domain_id))
12174         ;
12175       else if (unformat (i, "src_port %d", &src_port))
12176         ;
12177       else
12178         {
12179           errmsg ("unknown input `%U'", format_unformat_error, i);
12180           return -99;
12181         }
12182     }
12183
12184   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12185
12186   mp->domain_id = htonl (domain_id);
12187   mp->src_port = htons ((u16) src_port);
12188
12189   S (mp);
12190   W (ret);
12191   return ret;
12192 }
12193
12194 static int
12195 api_ipfix_classify_table_add_del (vat_main_t * vam)
12196 {
12197   unformat_input_t *i = vam->input;
12198   vl_api_ipfix_classify_table_add_del_t *mp;
12199   int is_add = -1;
12200   u32 classify_table_index = ~0;
12201   u8 ip_version = 0;
12202   u8 transport_protocol = 255;
12203   int ret;
12204
12205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12206     {
12207       if (unformat (i, "add"))
12208         is_add = 1;
12209       else if (unformat (i, "del"))
12210         is_add = 0;
12211       else if (unformat (i, "table %d", &classify_table_index))
12212         ;
12213       else if (unformat (i, "ip4"))
12214         ip_version = 4;
12215       else if (unformat (i, "ip6"))
12216         ip_version = 6;
12217       else if (unformat (i, "tcp"))
12218         transport_protocol = 6;
12219       else if (unformat (i, "udp"))
12220         transport_protocol = 17;
12221       else
12222         {
12223           errmsg ("unknown input `%U'", format_unformat_error, i);
12224           return -99;
12225         }
12226     }
12227
12228   if (is_add == -1)
12229     {
12230       errmsg ("expecting: add|del");
12231       return -99;
12232     }
12233   if (classify_table_index == ~0)
12234     {
12235       errmsg ("classifier table not specified");
12236       return -99;
12237     }
12238   if (ip_version == 0)
12239     {
12240       errmsg ("IP version not specified");
12241       return -99;
12242     }
12243
12244   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12245
12246   mp->is_add = is_add;
12247   mp->table_id = htonl (classify_table_index);
12248   mp->ip_version = ip_version;
12249   mp->transport_protocol = transport_protocol;
12250
12251   S (mp);
12252   W (ret);
12253   return ret;
12254 }
12255
12256 static int
12257 api_get_node_index (vat_main_t * vam)
12258 {
12259   unformat_input_t *i = vam->input;
12260   vl_api_get_node_index_t *mp;
12261   u8 *name = 0;
12262   int ret;
12263
12264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12265     {
12266       if (unformat (i, "node %s", &name))
12267         ;
12268       else
12269         break;
12270     }
12271   if (name == 0)
12272     {
12273       errmsg ("node name required");
12274       return -99;
12275     }
12276   if (vec_len (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   M (GET_NODE_INDEX, mp);
12283   clib_memcpy (mp->node_name, name, vec_len (name));
12284   vec_free (name);
12285
12286   S (mp);
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static int
12292 api_get_next_index (vat_main_t * vam)
12293 {
12294   unformat_input_t *i = vam->input;
12295   vl_api_get_next_index_t *mp;
12296   u8 *node_name = 0, *next_node_name = 0;
12297   int ret;
12298
12299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12300     {
12301       if (unformat (i, "node-name %s", &node_name))
12302         ;
12303       else if (unformat (i, "next-node-name %s", &next_node_name))
12304         break;
12305     }
12306
12307   if (node_name == 0)
12308     {
12309       errmsg ("node name required");
12310       return -99;
12311     }
12312   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12313     {
12314       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12315       return -99;
12316     }
12317
12318   if (next_node_name == 0)
12319     {
12320       errmsg ("next node name required");
12321       return -99;
12322     }
12323   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12324     {
12325       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12326       return -99;
12327     }
12328
12329   M (GET_NEXT_INDEX, mp);
12330   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12331   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12332   vec_free (node_name);
12333   vec_free (next_node_name);
12334
12335   S (mp);
12336   W (ret);
12337   return ret;
12338 }
12339
12340 static int
12341 api_add_node_next (vat_main_t * vam)
12342 {
12343   unformat_input_t *i = vam->input;
12344   vl_api_add_node_next_t *mp;
12345   u8 *name = 0;
12346   u8 *next = 0;
12347   int ret;
12348
12349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12350     {
12351       if (unformat (i, "node %s", &name))
12352         ;
12353       else if (unformat (i, "next %s", &next))
12354         ;
12355       else
12356         break;
12357     }
12358   if (name == 0)
12359     {
12360       errmsg ("node name required");
12361       return -99;
12362     }
12363   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12364     {
12365       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12366       return -99;
12367     }
12368   if (next == 0)
12369     {
12370       errmsg ("next node required");
12371       return -99;
12372     }
12373   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12374     {
12375       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12376       return -99;
12377     }
12378
12379   M (ADD_NODE_NEXT, mp);
12380   clib_memcpy (mp->node_name, name, vec_len (name));
12381   clib_memcpy (mp->next_name, next, vec_len (next));
12382   vec_free (name);
12383   vec_free (next);
12384
12385   S (mp);
12386   W (ret);
12387   return ret;
12388 }
12389
12390 static int
12391 api_l2tpv3_create_tunnel (vat_main_t * vam)
12392 {
12393   unformat_input_t *i = vam->input;
12394   ip6_address_t client_address, our_address;
12395   int client_address_set = 0;
12396   int our_address_set = 0;
12397   u32 local_session_id = 0;
12398   u32 remote_session_id = 0;
12399   u64 local_cookie = 0;
12400   u64 remote_cookie = 0;
12401   u8 l2_sublayer_present = 0;
12402   vl_api_l2tpv3_create_tunnel_t *mp;
12403   int ret;
12404
12405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12406     {
12407       if (unformat (i, "client_address %U", unformat_ip6_address,
12408                     &client_address))
12409         client_address_set = 1;
12410       else if (unformat (i, "our_address %U", unformat_ip6_address,
12411                          &our_address))
12412         our_address_set = 1;
12413       else if (unformat (i, "local_session_id %d", &local_session_id))
12414         ;
12415       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12416         ;
12417       else if (unformat (i, "local_cookie %lld", &local_cookie))
12418         ;
12419       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12420         ;
12421       else if (unformat (i, "l2-sublayer-present"))
12422         l2_sublayer_present = 1;
12423       else
12424         break;
12425     }
12426
12427   if (client_address_set == 0)
12428     {
12429       errmsg ("client_address required");
12430       return -99;
12431     }
12432
12433   if (our_address_set == 0)
12434     {
12435       errmsg ("our_address required");
12436       return -99;
12437     }
12438
12439   M (L2TPV3_CREATE_TUNNEL, mp);
12440
12441   clib_memcpy (mp->client_address, client_address.as_u8,
12442                sizeof (mp->client_address));
12443
12444   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12445
12446   mp->local_session_id = ntohl (local_session_id);
12447   mp->remote_session_id = ntohl (remote_session_id);
12448   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12449   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12450   mp->l2_sublayer_present = l2_sublayer_present;
12451   mp->is_ipv6 = 1;
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static int
12459 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12460 {
12461   unformat_input_t *i = vam->input;
12462   u32 sw_if_index;
12463   u8 sw_if_index_set = 0;
12464   u64 new_local_cookie = 0;
12465   u64 new_remote_cookie = 0;
12466   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12467   int ret;
12468
12469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12470     {
12471       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12472         sw_if_index_set = 1;
12473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12474         sw_if_index_set = 1;
12475       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12476         ;
12477       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12478         ;
12479       else
12480         break;
12481     }
12482
12483   if (sw_if_index_set == 0)
12484     {
12485       errmsg ("missing interface name or sw_if_index");
12486       return -99;
12487     }
12488
12489   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12490
12491   mp->sw_if_index = ntohl (sw_if_index);
12492   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12493   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12494
12495   S (mp);
12496   W (ret);
12497   return ret;
12498 }
12499
12500 static int
12501 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12502 {
12503   unformat_input_t *i = vam->input;
12504   vl_api_l2tpv3_interface_enable_disable_t *mp;
12505   u32 sw_if_index;
12506   u8 sw_if_index_set = 0;
12507   u8 enable_disable = 1;
12508   int ret;
12509
12510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12511     {
12512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12513         sw_if_index_set = 1;
12514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12515         sw_if_index_set = 1;
12516       else if (unformat (i, "enable"))
12517         enable_disable = 1;
12518       else if (unformat (i, "disable"))
12519         enable_disable = 0;
12520       else
12521         break;
12522     }
12523
12524   if (sw_if_index_set == 0)
12525     {
12526       errmsg ("missing interface name or sw_if_index");
12527       return -99;
12528     }
12529
12530   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12531
12532   mp->sw_if_index = ntohl (sw_if_index);
12533   mp->enable_disable = enable_disable;
12534
12535   S (mp);
12536   W (ret);
12537   return ret;
12538 }
12539
12540 static int
12541 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12542 {
12543   unformat_input_t *i = vam->input;
12544   vl_api_l2tpv3_set_lookup_key_t *mp;
12545   u8 key = ~0;
12546   int ret;
12547
12548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12549     {
12550       if (unformat (i, "lookup_v6_src"))
12551         key = L2T_LOOKUP_SRC_ADDRESS;
12552       else if (unformat (i, "lookup_v6_dst"))
12553         key = L2T_LOOKUP_DST_ADDRESS;
12554       else if (unformat (i, "lookup_session_id"))
12555         key = L2T_LOOKUP_SESSION_ID;
12556       else
12557         break;
12558     }
12559
12560   if (key == (u8) ~ 0)
12561     {
12562       errmsg ("l2tp session lookup key unset");
12563       return -99;
12564     }
12565
12566   M (L2TPV3_SET_LOOKUP_KEY, mp);
12567
12568   mp->key = key;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12576   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12577 {
12578   vat_main_t *vam = &vat_main;
12579
12580   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12581          format_ip6_address, mp->our_address,
12582          format_ip6_address, mp->client_address,
12583          clib_net_to_host_u32 (mp->sw_if_index));
12584
12585   print (vam->ofp,
12586          "   local cookies %016llx %016llx remote cookie %016llx",
12587          clib_net_to_host_u64 (mp->local_cookie[0]),
12588          clib_net_to_host_u64 (mp->local_cookie[1]),
12589          clib_net_to_host_u64 (mp->remote_cookie));
12590
12591   print (vam->ofp, "   local session-id %d remote session-id %d",
12592          clib_net_to_host_u32 (mp->local_session_id),
12593          clib_net_to_host_u32 (mp->remote_session_id));
12594
12595   print (vam->ofp, "   l2 specific sublayer %s\n",
12596          mp->l2_sublayer_present ? "preset" : "absent");
12597
12598 }
12599
12600 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12601   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12602 {
12603   vat_main_t *vam = &vat_main;
12604   vat_json_node_t *node = NULL;
12605   struct in6_addr addr;
12606
12607   if (VAT_JSON_ARRAY != vam->json_tree.type)
12608     {
12609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12610       vat_json_init_array (&vam->json_tree);
12611     }
12612   node = vat_json_array_add (&vam->json_tree);
12613
12614   vat_json_init_object (node);
12615
12616   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12617   vat_json_object_add_ip6 (node, "our_address", addr);
12618   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12619   vat_json_object_add_ip6 (node, "client_address", addr);
12620
12621   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12622   vat_json_init_array (lc);
12623   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12624   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12625   vat_json_object_add_uint (node, "remote_cookie",
12626                             clib_net_to_host_u64 (mp->remote_cookie));
12627
12628   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12629   vat_json_object_add_uint (node, "local_session_id",
12630                             clib_net_to_host_u32 (mp->local_session_id));
12631   vat_json_object_add_uint (node, "remote_session_id",
12632                             clib_net_to_host_u32 (mp->remote_session_id));
12633   vat_json_object_add_string_copy (node, "l2_sublayer",
12634                                    mp->l2_sublayer_present ? (u8 *) "present"
12635                                    : (u8 *) "absent");
12636 }
12637
12638 static int
12639 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12640 {
12641   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12642   vl_api_control_ping_t *mp_ping;
12643   int ret;
12644
12645   /* Get list of l2tpv3-tunnel interfaces */
12646   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12647   S (mp);
12648
12649   /* Use a control ping for synchronization */
12650   MPING (CONTROL_PING, mp_ping);
12651   S (mp_ping);
12652
12653   W (ret);
12654   return ret;
12655 }
12656
12657
12658 static void vl_api_sw_interface_tap_details_t_handler
12659   (vl_api_sw_interface_tap_details_t * mp)
12660 {
12661   vat_main_t *vam = &vat_main;
12662
12663   print (vam->ofp, "%-16s %d",
12664          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12665 }
12666
12667 static void vl_api_sw_interface_tap_details_t_handler_json
12668   (vl_api_sw_interface_tap_details_t * mp)
12669 {
12670   vat_main_t *vam = &vat_main;
12671   vat_json_node_t *node = NULL;
12672
12673   if (VAT_JSON_ARRAY != vam->json_tree.type)
12674     {
12675       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12676       vat_json_init_array (&vam->json_tree);
12677     }
12678   node = vat_json_array_add (&vam->json_tree);
12679
12680   vat_json_init_object (node);
12681   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12682   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12683 }
12684
12685 static int
12686 api_sw_interface_tap_dump (vat_main_t * vam)
12687 {
12688   vl_api_sw_interface_tap_dump_t *mp;
12689   vl_api_control_ping_t *mp_ping;
12690   int ret;
12691
12692   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12693   /* Get list of tap interfaces */
12694   M (SW_INTERFACE_TAP_DUMP, mp);
12695   S (mp);
12696
12697   /* Use a control ping for synchronization */
12698   MPING (CONTROL_PING, mp_ping);
12699   S (mp_ping);
12700
12701   W (ret);
12702   return ret;
12703 }
12704
12705 static void vl_api_sw_interface_tap_v2_details_t_handler
12706   (vl_api_sw_interface_tap_v2_details_t * mp)
12707 {
12708   vat_main_t *vam = &vat_main;
12709
12710   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12711                     mp->host_ip4_prefix_len);
12712   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12713                     mp->host_ip6_prefix_len);
12714
12715   print (vam->ofp,
12716          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12717          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12718          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12719          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12720          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12721
12722   vec_free (ip4);
12723   vec_free (ip6);
12724 }
12725
12726 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12727   (vl_api_sw_interface_tap_v2_details_t * mp)
12728 {
12729   vat_main_t *vam = &vat_main;
12730   vat_json_node_t *node = NULL;
12731
12732   if (VAT_JSON_ARRAY != vam->json_tree.type)
12733     {
12734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12735       vat_json_init_array (&vam->json_tree);
12736     }
12737   node = vat_json_array_add (&vam->json_tree);
12738
12739   vat_json_init_object (node);
12740   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12742   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12743   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12744   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12745   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12746   vat_json_object_add_string_copy (node, "host_mac_addr",
12747                                    format (0, "%U", format_ethernet_address,
12748                                            &mp->host_mac_addr));
12749   vat_json_object_add_string_copy (node, "host_namespace",
12750                                    mp->host_namespace);
12751   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12752   vat_json_object_add_string_copy (node, "host_ip4_addr",
12753                                    format (0, "%U/%d", format_ip4_address,
12754                                            mp->host_ip4_addr,
12755                                            mp->host_ip4_prefix_len));
12756   vat_json_object_add_string_copy (node, "host_ip6_addr",
12757                                    format (0, "%U/%d", format_ip6_address,
12758                                            mp->host_ip6_addr,
12759                                            mp->host_ip6_prefix_len));
12760
12761 }
12762
12763 static int
12764 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12765 {
12766   vl_api_sw_interface_tap_v2_dump_t *mp;
12767   vl_api_control_ping_t *mp_ping;
12768   int ret;
12769
12770   print (vam->ofp,
12771          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12772          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12773          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12774          "host_ip6_addr");
12775
12776   /* Get list of tap interfaces */
12777   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12778   S (mp);
12779
12780   /* Use a control ping for synchronization */
12781   MPING (CONTROL_PING, mp_ping);
12782   S (mp_ping);
12783
12784   W (ret);
12785   return ret;
12786 }
12787
12788 static int
12789 api_vxlan_offload_rx (vat_main_t * vam)
12790 {
12791   unformat_input_t *line_input = vam->input;
12792   vl_api_vxlan_offload_rx_t *mp;
12793   u32 hw_if_index = ~0, rx_if_index = ~0;
12794   u8 is_add = 1;
12795   int ret;
12796
12797   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12798     {
12799       if (unformat (line_input, "del"))
12800         is_add = 0;
12801       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12802                          &hw_if_index))
12803         ;
12804       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12805         ;
12806       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12807                          &rx_if_index))
12808         ;
12809       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12810         ;
12811       else
12812         {
12813           errmsg ("parse error '%U'", format_unformat_error, line_input);
12814           return -99;
12815         }
12816     }
12817
12818   if (hw_if_index == ~0)
12819     {
12820       errmsg ("no hw interface");
12821       return -99;
12822     }
12823
12824   if (rx_if_index == ~0)
12825     {
12826       errmsg ("no rx tunnel");
12827       return -99;
12828     }
12829
12830   M (VXLAN_OFFLOAD_RX, mp);
12831
12832   mp->hw_if_index = ntohl (hw_if_index);
12833   mp->sw_if_index = ntohl (rx_if_index);
12834   mp->enable = is_add;
12835
12836   S (mp);
12837   W (ret);
12838   return ret;
12839 }
12840
12841 static uword unformat_vxlan_decap_next
12842   (unformat_input_t * input, va_list * args)
12843 {
12844   u32 *result = va_arg (*args, u32 *);
12845   u32 tmp;
12846
12847   if (unformat (input, "l2"))
12848     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12849   else if (unformat (input, "%d", &tmp))
12850     *result = tmp;
12851   else
12852     return 0;
12853   return 1;
12854 }
12855
12856 static int
12857 api_vxlan_add_del_tunnel (vat_main_t * vam)
12858 {
12859   unformat_input_t *line_input = vam->input;
12860   vl_api_vxlan_add_del_tunnel_t *mp;
12861   ip46_address_t src, dst;
12862   u8 is_add = 1;
12863   u8 ipv4_set = 0, ipv6_set = 0;
12864   u8 src_set = 0;
12865   u8 dst_set = 0;
12866   u8 grp_set = 0;
12867   u32 instance = ~0;
12868   u32 mcast_sw_if_index = ~0;
12869   u32 encap_vrf_id = 0;
12870   u32 decap_next_index = ~0;
12871   u32 vni = 0;
12872   int ret;
12873
12874   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12875   clib_memset (&src, 0, sizeof src);
12876   clib_memset (&dst, 0, sizeof dst);
12877
12878   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (line_input, "del"))
12881         is_add = 0;
12882       else if (unformat (line_input, "instance %d", &instance))
12883         ;
12884       else
12885         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12886         {
12887           ipv4_set = 1;
12888           src_set = 1;
12889         }
12890       else
12891         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12892         {
12893           ipv4_set = 1;
12894           dst_set = 1;
12895         }
12896       else
12897         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12898         {
12899           ipv6_set = 1;
12900           src_set = 1;
12901         }
12902       else
12903         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12904         {
12905           ipv6_set = 1;
12906           dst_set = 1;
12907         }
12908       else if (unformat (line_input, "group %U %U",
12909                          unformat_ip4_address, &dst.ip4,
12910                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12911         {
12912           grp_set = dst_set = 1;
12913           ipv4_set = 1;
12914         }
12915       else if (unformat (line_input, "group %U",
12916                          unformat_ip4_address, &dst.ip4))
12917         {
12918           grp_set = dst_set = 1;
12919           ipv4_set = 1;
12920         }
12921       else if (unformat (line_input, "group %U %U",
12922                          unformat_ip6_address, &dst.ip6,
12923                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12924         {
12925           grp_set = dst_set = 1;
12926           ipv6_set = 1;
12927         }
12928       else if (unformat (line_input, "group %U",
12929                          unformat_ip6_address, &dst.ip6))
12930         {
12931           grp_set = dst_set = 1;
12932           ipv6_set = 1;
12933         }
12934       else
12935         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12936         ;
12937       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12938         ;
12939       else if (unformat (line_input, "decap-next %U",
12940                          unformat_vxlan_decap_next, &decap_next_index))
12941         ;
12942       else if (unformat (line_input, "vni %d", &vni))
12943         ;
12944       else
12945         {
12946           errmsg ("parse error '%U'", format_unformat_error, line_input);
12947           return -99;
12948         }
12949     }
12950
12951   if (src_set == 0)
12952     {
12953       errmsg ("tunnel src address not specified");
12954       return -99;
12955     }
12956   if (dst_set == 0)
12957     {
12958       errmsg ("tunnel dst address not specified");
12959       return -99;
12960     }
12961
12962   if (grp_set && !ip46_address_is_multicast (&dst))
12963     {
12964       errmsg ("tunnel group address not multicast");
12965       return -99;
12966     }
12967   if (grp_set && mcast_sw_if_index == ~0)
12968     {
12969       errmsg ("tunnel nonexistent multicast device");
12970       return -99;
12971     }
12972   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12973     {
12974       errmsg ("tunnel dst address must be unicast");
12975       return -99;
12976     }
12977
12978
12979   if (ipv4_set && ipv6_set)
12980     {
12981       errmsg ("both IPv4 and IPv6 addresses specified");
12982       return -99;
12983     }
12984
12985   if ((vni == 0) || (vni >> 24))
12986     {
12987       errmsg ("vni not specified or out of range");
12988       return -99;
12989     }
12990
12991   M (VXLAN_ADD_DEL_TUNNEL, mp);
12992
12993   if (ipv6_set)
12994     {
12995       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12996       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12997     }
12998   else
12999     {
13000       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13001       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13002     }
13003
13004   mp->instance = htonl (instance);
13005   mp->encap_vrf_id = ntohl (encap_vrf_id);
13006   mp->decap_next_index = ntohl (decap_next_index);
13007   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13008   mp->vni = ntohl (vni);
13009   mp->is_add = is_add;
13010   mp->is_ipv6 = ipv6_set;
13011
13012   S (mp);
13013   W (ret);
13014   return ret;
13015 }
13016
13017 static void vl_api_vxlan_tunnel_details_t_handler
13018   (vl_api_vxlan_tunnel_details_t * mp)
13019 {
13020   vat_main_t *vam = &vat_main;
13021   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13022   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13023
13024   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13025          ntohl (mp->sw_if_index),
13026          ntohl (mp->instance),
13027          format_ip46_address, &src, IP46_TYPE_ANY,
13028          format_ip46_address, &dst, IP46_TYPE_ANY,
13029          ntohl (mp->encap_vrf_id),
13030          ntohl (mp->decap_next_index), ntohl (mp->vni),
13031          ntohl (mp->mcast_sw_if_index));
13032 }
13033
13034 static void vl_api_vxlan_tunnel_details_t_handler_json
13035   (vl_api_vxlan_tunnel_details_t * mp)
13036 {
13037   vat_main_t *vam = &vat_main;
13038   vat_json_node_t *node = NULL;
13039
13040   if (VAT_JSON_ARRAY != vam->json_tree.type)
13041     {
13042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13043       vat_json_init_array (&vam->json_tree);
13044     }
13045   node = vat_json_array_add (&vam->json_tree);
13046
13047   vat_json_init_object (node);
13048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13049
13050   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13051
13052   if (mp->is_ipv6)
13053     {
13054       struct in6_addr ip6;
13055
13056       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13057       vat_json_object_add_ip6 (node, "src_address", ip6);
13058       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13059       vat_json_object_add_ip6 (node, "dst_address", ip6);
13060     }
13061   else
13062     {
13063       struct in_addr ip4;
13064
13065       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13066       vat_json_object_add_ip4 (node, "src_address", ip4);
13067       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13068       vat_json_object_add_ip4 (node, "dst_address", ip4);
13069     }
13070   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13071   vat_json_object_add_uint (node, "decap_next_index",
13072                             ntohl (mp->decap_next_index));
13073   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13074   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13075   vat_json_object_add_uint (node, "mcast_sw_if_index",
13076                             ntohl (mp->mcast_sw_if_index));
13077 }
13078
13079 static int
13080 api_vxlan_tunnel_dump (vat_main_t * vam)
13081 {
13082   unformat_input_t *i = vam->input;
13083   vl_api_vxlan_tunnel_dump_t *mp;
13084   vl_api_control_ping_t *mp_ping;
13085   u32 sw_if_index;
13086   u8 sw_if_index_set = 0;
13087   int ret;
13088
13089   /* Parse args required to build the message */
13090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13091     {
13092       if (unformat (i, "sw_if_index %d", &sw_if_index))
13093         sw_if_index_set = 1;
13094       else
13095         break;
13096     }
13097
13098   if (sw_if_index_set == 0)
13099     {
13100       sw_if_index = ~0;
13101     }
13102
13103   if (!vam->json_output)
13104     {
13105       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13106              "sw_if_index", "instance", "src_address", "dst_address",
13107              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13108     }
13109
13110   /* Get list of vxlan-tunnel interfaces */
13111   M (VXLAN_TUNNEL_DUMP, mp);
13112
13113   mp->sw_if_index = htonl (sw_if_index);
13114
13115   S (mp);
13116
13117   /* Use a control ping for synchronization */
13118   MPING (CONTROL_PING, mp_ping);
13119   S (mp_ping);
13120
13121   W (ret);
13122   return ret;
13123 }
13124
13125 static uword unformat_geneve_decap_next
13126   (unformat_input_t * input, va_list * args)
13127 {
13128   u32 *result = va_arg (*args, u32 *);
13129   u32 tmp;
13130
13131   if (unformat (input, "l2"))
13132     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13133   else if (unformat (input, "%d", &tmp))
13134     *result = tmp;
13135   else
13136     return 0;
13137   return 1;
13138 }
13139
13140 static int
13141 api_geneve_add_del_tunnel (vat_main_t * vam)
13142 {
13143   unformat_input_t *line_input = vam->input;
13144   vl_api_geneve_add_del_tunnel_t *mp;
13145   ip46_address_t src, dst;
13146   u8 is_add = 1;
13147   u8 ipv4_set = 0, ipv6_set = 0;
13148   u8 src_set = 0;
13149   u8 dst_set = 0;
13150   u8 grp_set = 0;
13151   u32 mcast_sw_if_index = ~0;
13152   u32 encap_vrf_id = 0;
13153   u32 decap_next_index = ~0;
13154   u32 vni = 0;
13155   int ret;
13156
13157   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13158   clib_memset (&src, 0, sizeof src);
13159   clib_memset (&dst, 0, sizeof dst);
13160
13161   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13162     {
13163       if (unformat (line_input, "del"))
13164         is_add = 0;
13165       else
13166         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13167         {
13168           ipv4_set = 1;
13169           src_set = 1;
13170         }
13171       else
13172         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13173         {
13174           ipv4_set = 1;
13175           dst_set = 1;
13176         }
13177       else
13178         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13179         {
13180           ipv6_set = 1;
13181           src_set = 1;
13182         }
13183       else
13184         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13185         {
13186           ipv6_set = 1;
13187           dst_set = 1;
13188         }
13189       else if (unformat (line_input, "group %U %U",
13190                          unformat_ip4_address, &dst.ip4,
13191                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13192         {
13193           grp_set = dst_set = 1;
13194           ipv4_set = 1;
13195         }
13196       else if (unformat (line_input, "group %U",
13197                          unformat_ip4_address, &dst.ip4))
13198         {
13199           grp_set = dst_set = 1;
13200           ipv4_set = 1;
13201         }
13202       else if (unformat (line_input, "group %U %U",
13203                          unformat_ip6_address, &dst.ip6,
13204                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13205         {
13206           grp_set = dst_set = 1;
13207           ipv6_set = 1;
13208         }
13209       else if (unformat (line_input, "group %U",
13210                          unformat_ip6_address, &dst.ip6))
13211         {
13212           grp_set = dst_set = 1;
13213           ipv6_set = 1;
13214         }
13215       else
13216         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13217         ;
13218       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13219         ;
13220       else if (unformat (line_input, "decap-next %U",
13221                          unformat_geneve_decap_next, &decap_next_index))
13222         ;
13223       else if (unformat (line_input, "vni %d", &vni))
13224         ;
13225       else
13226         {
13227           errmsg ("parse error '%U'", format_unformat_error, line_input);
13228           return -99;
13229         }
13230     }
13231
13232   if (src_set == 0)
13233     {
13234       errmsg ("tunnel src address not specified");
13235       return -99;
13236     }
13237   if (dst_set == 0)
13238     {
13239       errmsg ("tunnel dst address not specified");
13240       return -99;
13241     }
13242
13243   if (grp_set && !ip46_address_is_multicast (&dst))
13244     {
13245       errmsg ("tunnel group address not multicast");
13246       return -99;
13247     }
13248   if (grp_set && mcast_sw_if_index == ~0)
13249     {
13250       errmsg ("tunnel nonexistent multicast device");
13251       return -99;
13252     }
13253   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13254     {
13255       errmsg ("tunnel dst address must be unicast");
13256       return -99;
13257     }
13258
13259
13260   if (ipv4_set && ipv6_set)
13261     {
13262       errmsg ("both IPv4 and IPv6 addresses specified");
13263       return -99;
13264     }
13265
13266   if ((vni == 0) || (vni >> 24))
13267     {
13268       errmsg ("vni not specified or out of range");
13269       return -99;
13270     }
13271
13272   M (GENEVE_ADD_DEL_TUNNEL, mp);
13273
13274   if (ipv6_set)
13275     {
13276       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13277       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13278     }
13279   else
13280     {
13281       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13282       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13283     }
13284   mp->encap_vrf_id = ntohl (encap_vrf_id);
13285   mp->decap_next_index = ntohl (decap_next_index);
13286   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13287   mp->vni = ntohl (vni);
13288   mp->is_add = is_add;
13289   mp->is_ipv6 = ipv6_set;
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static void vl_api_geneve_tunnel_details_t_handler
13297   (vl_api_geneve_tunnel_details_t * mp)
13298 {
13299   vat_main_t *vam = &vat_main;
13300   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13301   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13302
13303   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13304          ntohl (mp->sw_if_index),
13305          format_ip46_address, &src, IP46_TYPE_ANY,
13306          format_ip46_address, &dst, IP46_TYPE_ANY,
13307          ntohl (mp->encap_vrf_id),
13308          ntohl (mp->decap_next_index), ntohl (mp->vni),
13309          ntohl (mp->mcast_sw_if_index));
13310 }
13311
13312 static void vl_api_geneve_tunnel_details_t_handler_json
13313   (vl_api_geneve_tunnel_details_t * mp)
13314 {
13315   vat_main_t *vam = &vat_main;
13316   vat_json_node_t *node = NULL;
13317
13318   if (VAT_JSON_ARRAY != vam->json_tree.type)
13319     {
13320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13321       vat_json_init_array (&vam->json_tree);
13322     }
13323   node = vat_json_array_add (&vam->json_tree);
13324
13325   vat_json_init_object (node);
13326   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13327   if (mp->is_ipv6)
13328     {
13329       struct in6_addr ip6;
13330
13331       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13332       vat_json_object_add_ip6 (node, "src_address", ip6);
13333       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13334       vat_json_object_add_ip6 (node, "dst_address", ip6);
13335     }
13336   else
13337     {
13338       struct in_addr ip4;
13339
13340       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13341       vat_json_object_add_ip4 (node, "src_address", ip4);
13342       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13343       vat_json_object_add_ip4 (node, "dst_address", ip4);
13344     }
13345   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13346   vat_json_object_add_uint (node, "decap_next_index",
13347                             ntohl (mp->decap_next_index));
13348   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13349   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13350   vat_json_object_add_uint (node, "mcast_sw_if_index",
13351                             ntohl (mp->mcast_sw_if_index));
13352 }
13353
13354 static int
13355 api_geneve_tunnel_dump (vat_main_t * vam)
13356 {
13357   unformat_input_t *i = vam->input;
13358   vl_api_geneve_tunnel_dump_t *mp;
13359   vl_api_control_ping_t *mp_ping;
13360   u32 sw_if_index;
13361   u8 sw_if_index_set = 0;
13362   int ret;
13363
13364   /* Parse args required to build the message */
13365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (i, "sw_if_index %d", &sw_if_index))
13368         sw_if_index_set = 1;
13369       else
13370         break;
13371     }
13372
13373   if (sw_if_index_set == 0)
13374     {
13375       sw_if_index = ~0;
13376     }
13377
13378   if (!vam->json_output)
13379     {
13380       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13381              "sw_if_index", "local_address", "remote_address",
13382              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13383     }
13384
13385   /* Get list of geneve-tunnel interfaces */
13386   M (GENEVE_TUNNEL_DUMP, mp);
13387
13388   mp->sw_if_index = htonl (sw_if_index);
13389
13390   S (mp);
13391
13392   /* Use a control ping for synchronization */
13393   M (CONTROL_PING, mp_ping);
13394   S (mp_ping);
13395
13396   W (ret);
13397   return ret;
13398 }
13399
13400 static int
13401 api_gre_add_del_tunnel (vat_main_t * vam)
13402 {
13403   unformat_input_t *line_input = vam->input;
13404   vl_api_gre_add_del_tunnel_t *mp;
13405   ip4_address_t src4, dst4;
13406   ip6_address_t src6, dst6;
13407   u8 is_add = 1;
13408   u8 ipv4_set = 0;
13409   u8 ipv6_set = 0;
13410   u8 t_type = GRE_TUNNEL_TYPE_L3;
13411   u8 src_set = 0;
13412   u8 dst_set = 0;
13413   u32 outer_fib_id = 0;
13414   u32 session_id = 0;
13415   u32 instance = ~0;
13416   int ret;
13417
13418   clib_memset (&src4, 0, sizeof src4);
13419   clib_memset (&dst4, 0, sizeof dst4);
13420   clib_memset (&src6, 0, sizeof src6);
13421   clib_memset (&dst6, 0, sizeof dst6);
13422
13423   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13424     {
13425       if (unformat (line_input, "del"))
13426         is_add = 0;
13427       else if (unformat (line_input, "instance %d", &instance))
13428         ;
13429       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13430         {
13431           src_set = 1;
13432           ipv4_set = 1;
13433         }
13434       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13435         {
13436           dst_set = 1;
13437           ipv4_set = 1;
13438         }
13439       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13440         {
13441           src_set = 1;
13442           ipv6_set = 1;
13443         }
13444       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13445         {
13446           dst_set = 1;
13447           ipv6_set = 1;
13448         }
13449       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13450         ;
13451       else if (unformat (line_input, "teb"))
13452         t_type = GRE_TUNNEL_TYPE_TEB;
13453       else if (unformat (line_input, "erspan %d", &session_id))
13454         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13455       else
13456         {
13457           errmsg ("parse error '%U'", format_unformat_error, line_input);
13458           return -99;
13459         }
13460     }
13461
13462   if (src_set == 0)
13463     {
13464       errmsg ("tunnel src address not specified");
13465       return -99;
13466     }
13467   if (dst_set == 0)
13468     {
13469       errmsg ("tunnel dst address not specified");
13470       return -99;
13471     }
13472   if (ipv4_set && ipv6_set)
13473     {
13474       errmsg ("both IPv4 and IPv6 addresses specified");
13475       return -99;
13476     }
13477
13478
13479   M (GRE_ADD_DEL_TUNNEL, mp);
13480
13481   if (ipv4_set)
13482     {
13483       clib_memcpy (&mp->src_address, &src4, 4);
13484       clib_memcpy (&mp->dst_address, &dst4, 4);
13485     }
13486   else
13487     {
13488       clib_memcpy (&mp->src_address, &src6, 16);
13489       clib_memcpy (&mp->dst_address, &dst6, 16);
13490     }
13491   mp->instance = htonl (instance);
13492   mp->outer_fib_id = htonl (outer_fib_id);
13493   mp->is_add = is_add;
13494   mp->session_id = htons ((u16) session_id);
13495   mp->tunnel_type = t_type;
13496   mp->is_ipv6 = ipv6_set;
13497
13498   S (mp);
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static void vl_api_gre_tunnel_details_t_handler
13504   (vl_api_gre_tunnel_details_t * mp)
13505 {
13506   vat_main_t *vam = &vat_main;
13507   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13508   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13509
13510   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13511          ntohl (mp->sw_if_index),
13512          ntohl (mp->instance),
13513          format_ip46_address, &src, IP46_TYPE_ANY,
13514          format_ip46_address, &dst, IP46_TYPE_ANY,
13515          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13516 }
13517
13518 static void vl_api_gre_tunnel_details_t_handler_json
13519   (vl_api_gre_tunnel_details_t * mp)
13520 {
13521   vat_main_t *vam = &vat_main;
13522   vat_json_node_t *node = NULL;
13523   struct in_addr ip4;
13524   struct in6_addr ip6;
13525
13526   if (VAT_JSON_ARRAY != vam->json_tree.type)
13527     {
13528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13529       vat_json_init_array (&vam->json_tree);
13530     }
13531   node = vat_json_array_add (&vam->json_tree);
13532
13533   vat_json_init_object (node);
13534   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13535   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13536   if (!mp->is_ipv6)
13537     {
13538       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13539       vat_json_object_add_ip4 (node, "src_address", ip4);
13540       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13541       vat_json_object_add_ip4 (node, "dst_address", ip4);
13542     }
13543   else
13544     {
13545       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13546       vat_json_object_add_ip6 (node, "src_address", ip6);
13547       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13548       vat_json_object_add_ip6 (node, "dst_address", ip6);
13549     }
13550   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13551   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13552   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13553   vat_json_object_add_uint (node, "session_id", mp->session_id);
13554 }
13555
13556 static int
13557 api_gre_tunnel_dump (vat_main_t * vam)
13558 {
13559   unformat_input_t *i = vam->input;
13560   vl_api_gre_tunnel_dump_t *mp;
13561   vl_api_control_ping_t *mp_ping;
13562   u32 sw_if_index;
13563   u8 sw_if_index_set = 0;
13564   int ret;
13565
13566   /* Parse args required to build the message */
13567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13568     {
13569       if (unformat (i, "sw_if_index %d", &sw_if_index))
13570         sw_if_index_set = 1;
13571       else
13572         break;
13573     }
13574
13575   if (sw_if_index_set == 0)
13576     {
13577       sw_if_index = ~0;
13578     }
13579
13580   if (!vam->json_output)
13581     {
13582       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13583              "sw_if_index", "instance", "src_address", "dst_address",
13584              "tunnel_type", "outer_fib_id", "session_id");
13585     }
13586
13587   /* Get list of gre-tunnel interfaces */
13588   M (GRE_TUNNEL_DUMP, mp);
13589
13590   mp->sw_if_index = htonl (sw_if_index);
13591
13592   S (mp);
13593
13594   /* Use a control ping for synchronization */
13595   MPING (CONTROL_PING, mp_ping);
13596   S (mp_ping);
13597
13598   W (ret);
13599   return ret;
13600 }
13601
13602 static int
13603 api_l2_fib_clear_table (vat_main_t * vam)
13604 {
13605 //  unformat_input_t * i = vam->input;
13606   vl_api_l2_fib_clear_table_t *mp;
13607   int ret;
13608
13609   M (L2_FIB_CLEAR_TABLE, mp);
13610
13611   S (mp);
13612   W (ret);
13613   return ret;
13614 }
13615
13616 static int
13617 api_l2_interface_efp_filter (vat_main_t * vam)
13618 {
13619   unformat_input_t *i = vam->input;
13620   vl_api_l2_interface_efp_filter_t *mp;
13621   u32 sw_if_index;
13622   u8 enable = 1;
13623   u8 sw_if_index_set = 0;
13624   int ret;
13625
13626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13627     {
13628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13629         sw_if_index_set = 1;
13630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13631         sw_if_index_set = 1;
13632       else if (unformat (i, "enable"))
13633         enable = 1;
13634       else if (unformat (i, "disable"))
13635         enable = 0;
13636       else
13637         {
13638           clib_warning ("parse error '%U'", format_unformat_error, i);
13639           return -99;
13640         }
13641     }
13642
13643   if (sw_if_index_set == 0)
13644     {
13645       errmsg ("missing sw_if_index");
13646       return -99;
13647     }
13648
13649   M (L2_INTERFACE_EFP_FILTER, mp);
13650
13651   mp->sw_if_index = ntohl (sw_if_index);
13652   mp->enable_disable = enable;
13653
13654   S (mp);
13655   W (ret);
13656   return ret;
13657 }
13658
13659 #define foreach_vtr_op                          \
13660 _("disable",  L2_VTR_DISABLED)                  \
13661 _("push-1",  L2_VTR_PUSH_1)                     \
13662 _("push-2",  L2_VTR_PUSH_2)                     \
13663 _("pop-1",  L2_VTR_POP_1)                       \
13664 _("pop-2",  L2_VTR_POP_2)                       \
13665 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13666 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13667 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13668 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13669
13670 static int
13671 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13672 {
13673   unformat_input_t *i = vam->input;
13674   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13675   u32 sw_if_index;
13676   u8 sw_if_index_set = 0;
13677   u8 vtr_op_set = 0;
13678   u32 vtr_op = 0;
13679   u32 push_dot1q = 1;
13680   u32 tag1 = ~0;
13681   u32 tag2 = ~0;
13682   int ret;
13683
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13687         sw_if_index_set = 1;
13688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13689         sw_if_index_set = 1;
13690       else if (unformat (i, "vtr_op %d", &vtr_op))
13691         vtr_op_set = 1;
13692 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13693       foreach_vtr_op
13694 #undef _
13695         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13696         ;
13697       else if (unformat (i, "tag1 %d", &tag1))
13698         ;
13699       else if (unformat (i, "tag2 %d", &tag2))
13700         ;
13701       else
13702         {
13703           clib_warning ("parse error '%U'", format_unformat_error, i);
13704           return -99;
13705         }
13706     }
13707
13708   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13709     {
13710       errmsg ("missing vtr operation or sw_if_index");
13711       return -99;
13712     }
13713
13714   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13715   mp->sw_if_index = ntohl (sw_if_index);
13716   mp->vtr_op = ntohl (vtr_op);
13717   mp->push_dot1q = ntohl (push_dot1q);
13718   mp->tag1 = ntohl (tag1);
13719   mp->tag2 = ntohl (tag2);
13720
13721   S (mp);
13722   W (ret);
13723   return ret;
13724 }
13725
13726 static int
13727 api_create_vhost_user_if (vat_main_t * vam)
13728 {
13729   unformat_input_t *i = vam->input;
13730   vl_api_create_vhost_user_if_t *mp;
13731   u8 *file_name;
13732   u8 is_server = 0;
13733   u8 file_name_set = 0;
13734   u32 custom_dev_instance = ~0;
13735   u8 hwaddr[6];
13736   u8 use_custom_mac = 0;
13737   u8 disable_mrg_rxbuf = 0;
13738   u8 disable_indirect_desc = 0;
13739   u8 *tag = 0;
13740   int ret;
13741
13742   /* Shut up coverity */
13743   clib_memset (hwaddr, 0, sizeof (hwaddr));
13744
13745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13746     {
13747       if (unformat (i, "socket %s", &file_name))
13748         {
13749           file_name_set = 1;
13750         }
13751       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13752         ;
13753       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13754         use_custom_mac = 1;
13755       else if (unformat (i, "server"))
13756         is_server = 1;
13757       else if (unformat (i, "disable_mrg_rxbuf"))
13758         disable_mrg_rxbuf = 1;
13759       else if (unformat (i, "disable_indirect_desc"))
13760         disable_indirect_desc = 1;
13761       else if (unformat (i, "tag %s", &tag))
13762         ;
13763       else
13764         break;
13765     }
13766
13767   if (file_name_set == 0)
13768     {
13769       errmsg ("missing socket file name");
13770       return -99;
13771     }
13772
13773   if (vec_len (file_name) > 255)
13774     {
13775       errmsg ("socket file name too long");
13776       return -99;
13777     }
13778   vec_add1 (file_name, 0);
13779
13780   M (CREATE_VHOST_USER_IF, mp);
13781
13782   mp->is_server = is_server;
13783   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13784   mp->disable_indirect_desc = disable_indirect_desc;
13785   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13786   vec_free (file_name);
13787   if (custom_dev_instance != ~0)
13788     {
13789       mp->renumber = 1;
13790       mp->custom_dev_instance = ntohl (custom_dev_instance);
13791     }
13792
13793   mp->use_custom_mac = use_custom_mac;
13794   clib_memcpy (mp->mac_address, hwaddr, 6);
13795   if (tag)
13796     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13797   vec_free (tag);
13798
13799   S (mp);
13800   W (ret);
13801   return ret;
13802 }
13803
13804 static int
13805 api_modify_vhost_user_if (vat_main_t * vam)
13806 {
13807   unformat_input_t *i = vam->input;
13808   vl_api_modify_vhost_user_if_t *mp;
13809   u8 *file_name;
13810   u8 is_server = 0;
13811   u8 file_name_set = 0;
13812   u32 custom_dev_instance = ~0;
13813   u8 sw_if_index_set = 0;
13814   u32 sw_if_index = (u32) ~ 0;
13815   int ret;
13816
13817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13818     {
13819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13820         sw_if_index_set = 1;
13821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13822         sw_if_index_set = 1;
13823       else if (unformat (i, "socket %s", &file_name))
13824         {
13825           file_name_set = 1;
13826         }
13827       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13828         ;
13829       else if (unformat (i, "server"))
13830         is_server = 1;
13831       else
13832         break;
13833     }
13834
13835   if (sw_if_index_set == 0)
13836     {
13837       errmsg ("missing sw_if_index or interface name");
13838       return -99;
13839     }
13840
13841   if (file_name_set == 0)
13842     {
13843       errmsg ("missing socket file name");
13844       return -99;
13845     }
13846
13847   if (vec_len (file_name) > 255)
13848     {
13849       errmsg ("socket file name too long");
13850       return -99;
13851     }
13852   vec_add1 (file_name, 0);
13853
13854   M (MODIFY_VHOST_USER_IF, mp);
13855
13856   mp->sw_if_index = ntohl (sw_if_index);
13857   mp->is_server = is_server;
13858   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13859   vec_free (file_name);
13860   if (custom_dev_instance != ~0)
13861     {
13862       mp->renumber = 1;
13863       mp->custom_dev_instance = ntohl (custom_dev_instance);
13864     }
13865
13866   S (mp);
13867   W (ret);
13868   return ret;
13869 }
13870
13871 static int
13872 api_delete_vhost_user_if (vat_main_t * vam)
13873 {
13874   unformat_input_t *i = vam->input;
13875   vl_api_delete_vhost_user_if_t *mp;
13876   u32 sw_if_index = ~0;
13877   u8 sw_if_index_set = 0;
13878   int ret;
13879
13880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13883         sw_if_index_set = 1;
13884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13885         sw_if_index_set = 1;
13886       else
13887         break;
13888     }
13889
13890   if (sw_if_index_set == 0)
13891     {
13892       errmsg ("missing sw_if_index or interface name");
13893       return -99;
13894     }
13895
13896
13897   M (DELETE_VHOST_USER_IF, mp);
13898
13899   mp->sw_if_index = ntohl (sw_if_index);
13900
13901   S (mp);
13902   W (ret);
13903   return ret;
13904 }
13905
13906 static void vl_api_sw_interface_vhost_user_details_t_handler
13907   (vl_api_sw_interface_vhost_user_details_t * mp)
13908 {
13909   vat_main_t *vam = &vat_main;
13910
13911   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13912          (char *) mp->interface_name,
13913          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13914          clib_net_to_host_u64 (mp->features), mp->is_server,
13915          ntohl (mp->num_regions), (char *) mp->sock_filename);
13916   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13917 }
13918
13919 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13920   (vl_api_sw_interface_vhost_user_details_t * mp)
13921 {
13922   vat_main_t *vam = &vat_main;
13923   vat_json_node_t *node = NULL;
13924
13925   if (VAT_JSON_ARRAY != vam->json_tree.type)
13926     {
13927       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13928       vat_json_init_array (&vam->json_tree);
13929     }
13930   node = vat_json_array_add (&vam->json_tree);
13931
13932   vat_json_init_object (node);
13933   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13934   vat_json_object_add_string_copy (node, "interface_name",
13935                                    mp->interface_name);
13936   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13937                             ntohl (mp->virtio_net_hdr_sz));
13938   vat_json_object_add_uint (node, "features",
13939                             clib_net_to_host_u64 (mp->features));
13940   vat_json_object_add_uint (node, "is_server", mp->is_server);
13941   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13942   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13943   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13944 }
13945
13946 static int
13947 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13948 {
13949   vl_api_sw_interface_vhost_user_dump_t *mp;
13950   vl_api_control_ping_t *mp_ping;
13951   int ret;
13952   print (vam->ofp,
13953          "Interface name            idx hdr_sz features server regions filename");
13954
13955   /* Get list of vhost-user interfaces */
13956   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13957   S (mp);
13958
13959   /* Use a control ping for synchronization */
13960   MPING (CONTROL_PING, mp_ping);
13961   S (mp_ping);
13962
13963   W (ret);
13964   return ret;
13965 }
13966
13967 static int
13968 api_show_version (vat_main_t * vam)
13969 {
13970   vl_api_show_version_t *mp;
13971   int ret;
13972
13973   M (SHOW_VERSION, mp);
13974
13975   S (mp);
13976   W (ret);
13977   return ret;
13978 }
13979
13980
13981 static int
13982 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13983 {
13984   unformat_input_t *line_input = vam->input;
13985   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13986   ip4_address_t local4, remote4;
13987   ip6_address_t local6, remote6;
13988   u8 is_add = 1;
13989   u8 ipv4_set = 0, ipv6_set = 0;
13990   u8 local_set = 0;
13991   u8 remote_set = 0;
13992   u8 grp_set = 0;
13993   u32 mcast_sw_if_index = ~0;
13994   u32 encap_vrf_id = 0;
13995   u32 decap_vrf_id = 0;
13996   u8 protocol = ~0;
13997   u32 vni;
13998   u8 vni_set = 0;
13999   int ret;
14000
14001   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14002   clib_memset (&local4, 0, sizeof local4);
14003   clib_memset (&remote4, 0, sizeof remote4);
14004   clib_memset (&local6, 0, sizeof local6);
14005   clib_memset (&remote6, 0, sizeof remote6);
14006
14007   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (line_input, "del"))
14010         is_add = 0;
14011       else if (unformat (line_input, "local %U",
14012                          unformat_ip4_address, &local4))
14013         {
14014           local_set = 1;
14015           ipv4_set = 1;
14016         }
14017       else if (unformat (line_input, "remote %U",
14018                          unformat_ip4_address, &remote4))
14019         {
14020           remote_set = 1;
14021           ipv4_set = 1;
14022         }
14023       else if (unformat (line_input, "local %U",
14024                          unformat_ip6_address, &local6))
14025         {
14026           local_set = 1;
14027           ipv6_set = 1;
14028         }
14029       else if (unformat (line_input, "remote %U",
14030                          unformat_ip6_address, &remote6))
14031         {
14032           remote_set = 1;
14033           ipv6_set = 1;
14034         }
14035       else if (unformat (line_input, "group %U %U",
14036                          unformat_ip4_address, &remote4,
14037                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14038         {
14039           grp_set = remote_set = 1;
14040           ipv4_set = 1;
14041         }
14042       else if (unformat (line_input, "group %U",
14043                          unformat_ip4_address, &remote4))
14044         {
14045           grp_set = remote_set = 1;
14046           ipv4_set = 1;
14047         }
14048       else if (unformat (line_input, "group %U %U",
14049                          unformat_ip6_address, &remote6,
14050                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14051         {
14052           grp_set = remote_set = 1;
14053           ipv6_set = 1;
14054         }
14055       else if (unformat (line_input, "group %U",
14056                          unformat_ip6_address, &remote6))
14057         {
14058           grp_set = remote_set = 1;
14059           ipv6_set = 1;
14060         }
14061       else
14062         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14063         ;
14064       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14065         ;
14066       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14067         ;
14068       else if (unformat (line_input, "vni %d", &vni))
14069         vni_set = 1;
14070       else if (unformat (line_input, "next-ip4"))
14071         protocol = 1;
14072       else if (unformat (line_input, "next-ip6"))
14073         protocol = 2;
14074       else if (unformat (line_input, "next-ethernet"))
14075         protocol = 3;
14076       else if (unformat (line_input, "next-nsh"))
14077         protocol = 4;
14078       else
14079         {
14080           errmsg ("parse error '%U'", format_unformat_error, line_input);
14081           return -99;
14082         }
14083     }
14084
14085   if (local_set == 0)
14086     {
14087       errmsg ("tunnel local address not specified");
14088       return -99;
14089     }
14090   if (remote_set == 0)
14091     {
14092       errmsg ("tunnel remote address not specified");
14093       return -99;
14094     }
14095   if (grp_set && mcast_sw_if_index == ~0)
14096     {
14097       errmsg ("tunnel nonexistent multicast device");
14098       return -99;
14099     }
14100   if (ipv4_set && ipv6_set)
14101     {
14102       errmsg ("both IPv4 and IPv6 addresses specified");
14103       return -99;
14104     }
14105
14106   if (vni_set == 0)
14107     {
14108       errmsg ("vni not specified");
14109       return -99;
14110     }
14111
14112   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14113
14114
14115   if (ipv6_set)
14116     {
14117       clib_memcpy (&mp->local, &local6, sizeof (local6));
14118       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14119     }
14120   else
14121     {
14122       clib_memcpy (&mp->local, &local4, sizeof (local4));
14123       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14124     }
14125
14126   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14127   mp->encap_vrf_id = ntohl (encap_vrf_id);
14128   mp->decap_vrf_id = ntohl (decap_vrf_id);
14129   mp->protocol = protocol;
14130   mp->vni = ntohl (vni);
14131   mp->is_add = is_add;
14132   mp->is_ipv6 = ipv6_set;
14133
14134   S (mp);
14135   W (ret);
14136   return ret;
14137 }
14138
14139 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14140   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14141 {
14142   vat_main_t *vam = &vat_main;
14143   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14144   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14145
14146   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14147          ntohl (mp->sw_if_index),
14148          format_ip46_address, &local, IP46_TYPE_ANY,
14149          format_ip46_address, &remote, IP46_TYPE_ANY,
14150          ntohl (mp->vni), mp->protocol,
14151          ntohl (mp->mcast_sw_if_index),
14152          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14153 }
14154
14155
14156 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14157   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14158 {
14159   vat_main_t *vam = &vat_main;
14160   vat_json_node_t *node = NULL;
14161   struct in_addr ip4;
14162   struct in6_addr ip6;
14163
14164   if (VAT_JSON_ARRAY != vam->json_tree.type)
14165     {
14166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14167       vat_json_init_array (&vam->json_tree);
14168     }
14169   node = vat_json_array_add (&vam->json_tree);
14170
14171   vat_json_init_object (node);
14172   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14173   if (mp->is_ipv6)
14174     {
14175       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14176       vat_json_object_add_ip6 (node, "local", ip6);
14177       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14178       vat_json_object_add_ip6 (node, "remote", ip6);
14179     }
14180   else
14181     {
14182       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14183       vat_json_object_add_ip4 (node, "local", ip4);
14184       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14185       vat_json_object_add_ip4 (node, "remote", ip4);
14186     }
14187   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14188   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14189   vat_json_object_add_uint (node, "mcast_sw_if_index",
14190                             ntohl (mp->mcast_sw_if_index));
14191   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14192   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14193   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14194 }
14195
14196 static int
14197 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14198 {
14199   unformat_input_t *i = vam->input;
14200   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14201   vl_api_control_ping_t *mp_ping;
14202   u32 sw_if_index;
14203   u8 sw_if_index_set = 0;
14204   int ret;
14205
14206   /* Parse args required to build the message */
14207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14208     {
14209       if (unformat (i, "sw_if_index %d", &sw_if_index))
14210         sw_if_index_set = 1;
14211       else
14212         break;
14213     }
14214
14215   if (sw_if_index_set == 0)
14216     {
14217       sw_if_index = ~0;
14218     }
14219
14220   if (!vam->json_output)
14221     {
14222       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14223              "sw_if_index", "local", "remote", "vni",
14224              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14225     }
14226
14227   /* Get list of vxlan-tunnel interfaces */
14228   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14229
14230   mp->sw_if_index = htonl (sw_if_index);
14231
14232   S (mp);
14233
14234   /* Use a control ping for synchronization */
14235   MPING (CONTROL_PING, mp_ping);
14236   S (mp_ping);
14237
14238   W (ret);
14239   return ret;
14240 }
14241
14242 static void vl_api_l2_fib_table_details_t_handler
14243   (vl_api_l2_fib_table_details_t * mp)
14244 {
14245   vat_main_t *vam = &vat_main;
14246
14247   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14248          "       %d       %d     %d",
14249          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14250          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14251          mp->bvi_mac);
14252 }
14253
14254 static void vl_api_l2_fib_table_details_t_handler_json
14255   (vl_api_l2_fib_table_details_t * mp)
14256 {
14257   vat_main_t *vam = &vat_main;
14258   vat_json_node_t *node = NULL;
14259
14260   if (VAT_JSON_ARRAY != vam->json_tree.type)
14261     {
14262       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14263       vat_json_init_array (&vam->json_tree);
14264     }
14265   node = vat_json_array_add (&vam->json_tree);
14266
14267   vat_json_init_object (node);
14268   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14269   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14270   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14271   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14272   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14273   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14274 }
14275
14276 static int
14277 api_l2_fib_table_dump (vat_main_t * vam)
14278 {
14279   unformat_input_t *i = vam->input;
14280   vl_api_l2_fib_table_dump_t *mp;
14281   vl_api_control_ping_t *mp_ping;
14282   u32 bd_id;
14283   u8 bd_id_set = 0;
14284   int ret;
14285
14286   /* Parse args required to build the message */
14287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14288     {
14289       if (unformat (i, "bd_id %d", &bd_id))
14290         bd_id_set = 1;
14291       else
14292         break;
14293     }
14294
14295   if (bd_id_set == 0)
14296     {
14297       errmsg ("missing bridge domain");
14298       return -99;
14299     }
14300
14301   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14302
14303   /* Get list of l2 fib entries */
14304   M (L2_FIB_TABLE_DUMP, mp);
14305
14306   mp->bd_id = ntohl (bd_id);
14307   S (mp);
14308
14309   /* Use a control ping for synchronization */
14310   MPING (CONTROL_PING, mp_ping);
14311   S (mp_ping);
14312
14313   W (ret);
14314   return ret;
14315 }
14316
14317
14318 static int
14319 api_interface_name_renumber (vat_main_t * vam)
14320 {
14321   unformat_input_t *line_input = vam->input;
14322   vl_api_interface_name_renumber_t *mp;
14323   u32 sw_if_index = ~0;
14324   u32 new_show_dev_instance = ~0;
14325   int ret;
14326
14327   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14328     {
14329       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14330                     &sw_if_index))
14331         ;
14332       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14333         ;
14334       else if (unformat (line_input, "new_show_dev_instance %d",
14335                          &new_show_dev_instance))
14336         ;
14337       else
14338         break;
14339     }
14340
14341   if (sw_if_index == ~0)
14342     {
14343       errmsg ("missing interface name or sw_if_index");
14344       return -99;
14345     }
14346
14347   if (new_show_dev_instance == ~0)
14348     {
14349       errmsg ("missing new_show_dev_instance");
14350       return -99;
14351     }
14352
14353   M (INTERFACE_NAME_RENUMBER, mp);
14354
14355   mp->sw_if_index = ntohl (sw_if_index);
14356   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14357
14358   S (mp);
14359   W (ret);
14360   return ret;
14361 }
14362
14363 static int
14364 api_ip_probe_neighbor (vat_main_t * vam)
14365 {
14366   unformat_input_t *i = vam->input;
14367   vl_api_ip_probe_neighbor_t *mp;
14368   u8 int_set = 0;
14369   u8 adr_set = 0;
14370   u8 is_ipv6 = 0;
14371   u8 dst_adr[16];
14372   u32 sw_if_index;
14373   int ret;
14374
14375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14376     {
14377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14378         int_set = 1;
14379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14380         int_set = 1;
14381       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14382         adr_set = 1;
14383       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14384         {
14385           adr_set = 1;
14386           is_ipv6 = 1;
14387         }
14388       else
14389         break;
14390     }
14391
14392   if (int_set == 0)
14393     {
14394       errmsg ("missing interface");
14395       return -99;
14396     }
14397
14398   if (adr_set == 0)
14399     {
14400       errmsg ("missing addresses");
14401       return -99;
14402     }
14403
14404   M (IP_PROBE_NEIGHBOR, mp);
14405
14406   mp->sw_if_index = ntohl (sw_if_index);
14407   mp->is_ipv6 = is_ipv6;
14408   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14409
14410   S (mp);
14411   W (ret);
14412   return ret;
14413 }
14414
14415 static int
14416 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14417 {
14418   unformat_input_t *i = vam->input;
14419   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14420   u8 mode = IP_SCAN_V46_NEIGHBORS;
14421   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14422   int ret;
14423
14424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14425     {
14426       if (unformat (i, "ip4"))
14427         mode = IP_SCAN_V4_NEIGHBORS;
14428       else if (unformat (i, "ip6"))
14429         mode = IP_SCAN_V6_NEIGHBORS;
14430       if (unformat (i, "both"))
14431         mode = IP_SCAN_V46_NEIGHBORS;
14432       else if (unformat (i, "disable"))
14433         mode = IP_SCAN_DISABLED;
14434       else if (unformat (i, "interval %d", &interval))
14435         ;
14436       else if (unformat (i, "max-time %d", &time))
14437         ;
14438       else if (unformat (i, "max-update %d", &update))
14439         ;
14440       else if (unformat (i, "delay %d", &delay))
14441         ;
14442       else if (unformat (i, "stale %d", &stale))
14443         ;
14444       else
14445         break;
14446     }
14447
14448   if (interval > 255)
14449     {
14450       errmsg ("interval cannot exceed 255 minutes.");
14451       return -99;
14452     }
14453   if (time > 255)
14454     {
14455       errmsg ("max-time cannot exceed 255 usec.");
14456       return -99;
14457     }
14458   if (update > 255)
14459     {
14460       errmsg ("max-update cannot exceed 255.");
14461       return -99;
14462     }
14463   if (delay > 255)
14464     {
14465       errmsg ("delay cannot exceed 255 msec.");
14466       return -99;
14467     }
14468   if (stale > 255)
14469     {
14470       errmsg ("stale cannot exceed 255 minutes.");
14471       return -99;
14472     }
14473
14474   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14475   mp->mode = mode;
14476   mp->scan_interval = interval;
14477   mp->max_proc_time = time;
14478   mp->max_update = update;
14479   mp->scan_int_delay = delay;
14480   mp->stale_threshold = stale;
14481
14482   S (mp);
14483   W (ret);
14484   return ret;
14485 }
14486
14487 static int
14488 api_want_ip4_arp_events (vat_main_t * vam)
14489 {
14490   unformat_input_t *line_input = vam->input;
14491   vl_api_want_ip4_arp_events_t *mp;
14492   ip4_address_t address;
14493   int address_set = 0;
14494   u32 enable_disable = 1;
14495   int ret;
14496
14497   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14498     {
14499       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14500         address_set = 1;
14501       else if (unformat (line_input, "del"))
14502         enable_disable = 0;
14503       else
14504         break;
14505     }
14506
14507   if (address_set == 0)
14508     {
14509       errmsg ("missing addresses");
14510       return -99;
14511     }
14512
14513   M (WANT_IP4_ARP_EVENTS, mp);
14514   mp->enable_disable = enable_disable;
14515   mp->pid = htonl (getpid ());
14516   mp->address = address.as_u32;
14517
14518   S (mp);
14519   W (ret);
14520   return ret;
14521 }
14522
14523 static int
14524 api_want_ip6_nd_events (vat_main_t * vam)
14525 {
14526   unformat_input_t *line_input = vam->input;
14527   vl_api_want_ip6_nd_events_t *mp;
14528   ip6_address_t address;
14529   int address_set = 0;
14530   u32 enable_disable = 1;
14531   int ret;
14532
14533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14534     {
14535       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14536         address_set = 1;
14537       else if (unformat (line_input, "del"))
14538         enable_disable = 0;
14539       else
14540         break;
14541     }
14542
14543   if (address_set == 0)
14544     {
14545       errmsg ("missing addresses");
14546       return -99;
14547     }
14548
14549   M (WANT_IP6_ND_EVENTS, mp);
14550   mp->enable_disable = enable_disable;
14551   mp->pid = htonl (getpid ());
14552   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14553
14554   S (mp);
14555   W (ret);
14556   return ret;
14557 }
14558
14559 static int
14560 api_want_l2_macs_events (vat_main_t * vam)
14561 {
14562   unformat_input_t *line_input = vam->input;
14563   vl_api_want_l2_macs_events_t *mp;
14564   u8 enable_disable = 1;
14565   u32 scan_delay = 0;
14566   u32 max_macs_in_event = 0;
14567   u32 learn_limit = 0;
14568   int ret;
14569
14570   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14571     {
14572       if (unformat (line_input, "learn-limit %d", &learn_limit))
14573         ;
14574       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14575         ;
14576       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14577         ;
14578       else if (unformat (line_input, "disable"))
14579         enable_disable = 0;
14580       else
14581         break;
14582     }
14583
14584   M (WANT_L2_MACS_EVENTS, mp);
14585   mp->enable_disable = enable_disable;
14586   mp->pid = htonl (getpid ());
14587   mp->learn_limit = htonl (learn_limit);
14588   mp->scan_delay = (u8) scan_delay;
14589   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14590   S (mp);
14591   W (ret);
14592   return ret;
14593 }
14594
14595 static int
14596 api_input_acl_set_interface (vat_main_t * vam)
14597 {
14598   unformat_input_t *i = vam->input;
14599   vl_api_input_acl_set_interface_t *mp;
14600   u32 sw_if_index;
14601   int sw_if_index_set;
14602   u32 ip4_table_index = ~0;
14603   u32 ip6_table_index = ~0;
14604   u32 l2_table_index = ~0;
14605   u8 is_add = 1;
14606   int ret;
14607
14608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14609     {
14610       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14611         sw_if_index_set = 1;
14612       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14613         sw_if_index_set = 1;
14614       else if (unformat (i, "del"))
14615         is_add = 0;
14616       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14617         ;
14618       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14619         ;
14620       else if (unformat (i, "l2-table %d", &l2_table_index))
14621         ;
14622       else
14623         {
14624           clib_warning ("parse error '%U'", format_unformat_error, i);
14625           return -99;
14626         }
14627     }
14628
14629   if (sw_if_index_set == 0)
14630     {
14631       errmsg ("missing interface name or sw_if_index");
14632       return -99;
14633     }
14634
14635   M (INPUT_ACL_SET_INTERFACE, mp);
14636
14637   mp->sw_if_index = ntohl (sw_if_index);
14638   mp->ip4_table_index = ntohl (ip4_table_index);
14639   mp->ip6_table_index = ntohl (ip6_table_index);
14640   mp->l2_table_index = ntohl (l2_table_index);
14641   mp->is_add = is_add;
14642
14643   S (mp);
14644   W (ret);
14645   return ret;
14646 }
14647
14648 static int
14649 api_output_acl_set_interface (vat_main_t * vam)
14650 {
14651   unformat_input_t *i = vam->input;
14652   vl_api_output_acl_set_interface_t *mp;
14653   u32 sw_if_index;
14654   int sw_if_index_set;
14655   u32 ip4_table_index = ~0;
14656   u32 ip6_table_index = ~0;
14657   u32 l2_table_index = ~0;
14658   u8 is_add = 1;
14659   int ret;
14660
14661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14662     {
14663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14664         sw_if_index_set = 1;
14665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14666         sw_if_index_set = 1;
14667       else if (unformat (i, "del"))
14668         is_add = 0;
14669       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14670         ;
14671       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14672         ;
14673       else if (unformat (i, "l2-table %d", &l2_table_index))
14674         ;
14675       else
14676         {
14677           clib_warning ("parse error '%U'", format_unformat_error, i);
14678           return -99;
14679         }
14680     }
14681
14682   if (sw_if_index_set == 0)
14683     {
14684       errmsg ("missing interface name or sw_if_index");
14685       return -99;
14686     }
14687
14688   M (OUTPUT_ACL_SET_INTERFACE, mp);
14689
14690   mp->sw_if_index = ntohl (sw_if_index);
14691   mp->ip4_table_index = ntohl (ip4_table_index);
14692   mp->ip6_table_index = ntohl (ip6_table_index);
14693   mp->l2_table_index = ntohl (l2_table_index);
14694   mp->is_add = is_add;
14695
14696   S (mp);
14697   W (ret);
14698   return ret;
14699 }
14700
14701 static int
14702 api_ip_address_dump (vat_main_t * vam)
14703 {
14704   unformat_input_t *i = vam->input;
14705   vl_api_ip_address_dump_t *mp;
14706   vl_api_control_ping_t *mp_ping;
14707   u32 sw_if_index = ~0;
14708   u8 sw_if_index_set = 0;
14709   u8 ipv4_set = 0;
14710   u8 ipv6_set = 0;
14711   int ret;
14712
14713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14714     {
14715       if (unformat (i, "sw_if_index %d", &sw_if_index))
14716         sw_if_index_set = 1;
14717       else
14718         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14719         sw_if_index_set = 1;
14720       else if (unformat (i, "ipv4"))
14721         ipv4_set = 1;
14722       else if (unformat (i, "ipv6"))
14723         ipv6_set = 1;
14724       else
14725         break;
14726     }
14727
14728   if (ipv4_set && ipv6_set)
14729     {
14730       errmsg ("ipv4 and ipv6 flags cannot be both set");
14731       return -99;
14732     }
14733
14734   if ((!ipv4_set) && (!ipv6_set))
14735     {
14736       errmsg ("no ipv4 nor ipv6 flag set");
14737       return -99;
14738     }
14739
14740   if (sw_if_index_set == 0)
14741     {
14742       errmsg ("missing interface name or sw_if_index");
14743       return -99;
14744     }
14745
14746   vam->current_sw_if_index = sw_if_index;
14747   vam->is_ipv6 = ipv6_set;
14748
14749   M (IP_ADDRESS_DUMP, mp);
14750   mp->sw_if_index = ntohl (sw_if_index);
14751   mp->is_ipv6 = ipv6_set;
14752   S (mp);
14753
14754   /* Use a control ping for synchronization */
14755   MPING (CONTROL_PING, mp_ping);
14756   S (mp_ping);
14757
14758   W (ret);
14759   return ret;
14760 }
14761
14762 static int
14763 api_ip_dump (vat_main_t * vam)
14764 {
14765   vl_api_ip_dump_t *mp;
14766   vl_api_control_ping_t *mp_ping;
14767   unformat_input_t *in = vam->input;
14768   int ipv4_set = 0;
14769   int ipv6_set = 0;
14770   int is_ipv6;
14771   int i;
14772   int ret;
14773
14774   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14775     {
14776       if (unformat (in, "ipv4"))
14777         ipv4_set = 1;
14778       else if (unformat (in, "ipv6"))
14779         ipv6_set = 1;
14780       else
14781         break;
14782     }
14783
14784   if (ipv4_set && ipv6_set)
14785     {
14786       errmsg ("ipv4 and ipv6 flags cannot be both set");
14787       return -99;
14788     }
14789
14790   if ((!ipv4_set) && (!ipv6_set))
14791     {
14792       errmsg ("no ipv4 nor ipv6 flag set");
14793       return -99;
14794     }
14795
14796   is_ipv6 = ipv6_set;
14797   vam->is_ipv6 = is_ipv6;
14798
14799   /* free old data */
14800   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14801     {
14802       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14803     }
14804   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14805
14806   M (IP_DUMP, mp);
14807   mp->is_ipv6 = ipv6_set;
14808   S (mp);
14809
14810   /* Use a control ping for synchronization */
14811   MPING (CONTROL_PING, mp_ping);
14812   S (mp_ping);
14813
14814   W (ret);
14815   return ret;
14816 }
14817
14818 static int
14819 api_ipsec_spd_add_del (vat_main_t * vam)
14820 {
14821   unformat_input_t *i = vam->input;
14822   vl_api_ipsec_spd_add_del_t *mp;
14823   u32 spd_id = ~0;
14824   u8 is_add = 1;
14825   int ret;
14826
14827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (i, "spd_id %d", &spd_id))
14830         ;
14831       else if (unformat (i, "del"))
14832         is_add = 0;
14833       else
14834         {
14835           clib_warning ("parse error '%U'", format_unformat_error, i);
14836           return -99;
14837         }
14838     }
14839   if (spd_id == ~0)
14840     {
14841       errmsg ("spd_id must be set");
14842       return -99;
14843     }
14844
14845   M (IPSEC_SPD_ADD_DEL, mp);
14846
14847   mp->spd_id = ntohl (spd_id);
14848   mp->is_add = is_add;
14849
14850   S (mp);
14851   W (ret);
14852   return ret;
14853 }
14854
14855 static int
14856 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14857 {
14858   unformat_input_t *i = vam->input;
14859   vl_api_ipsec_interface_add_del_spd_t *mp;
14860   u32 sw_if_index;
14861   u8 sw_if_index_set = 0;
14862   u32 spd_id = (u32) ~ 0;
14863   u8 is_add = 1;
14864   int ret;
14865
14866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14867     {
14868       if (unformat (i, "del"))
14869         is_add = 0;
14870       else if (unformat (i, "spd_id %d", &spd_id))
14871         ;
14872       else
14873         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14874         sw_if_index_set = 1;
14875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14876         sw_if_index_set = 1;
14877       else
14878         {
14879           clib_warning ("parse error '%U'", format_unformat_error, i);
14880           return -99;
14881         }
14882
14883     }
14884
14885   if (spd_id == (u32) ~ 0)
14886     {
14887       errmsg ("spd_id must be set");
14888       return -99;
14889     }
14890
14891   if (sw_if_index_set == 0)
14892     {
14893       errmsg ("missing interface name or sw_if_index");
14894       return -99;
14895     }
14896
14897   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14898
14899   mp->spd_id = ntohl (spd_id);
14900   mp->sw_if_index = ntohl (sw_if_index);
14901   mp->is_add = is_add;
14902
14903   S (mp);
14904   W (ret);
14905   return ret;
14906 }
14907
14908 static int
14909 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14910 {
14911   unformat_input_t *i = vam->input;
14912   vl_api_ipsec_spd_add_del_entry_t *mp;
14913   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14914   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14915   i32 priority = 0;
14916   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14917   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14918   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14919   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14920   int ret;
14921
14922   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14923   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14924   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14925   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14926   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14927   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14928
14929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14930     {
14931       if (unformat (i, "del"))
14932         is_add = 0;
14933       if (unformat (i, "outbound"))
14934         is_outbound = 1;
14935       if (unformat (i, "inbound"))
14936         is_outbound = 0;
14937       else if (unformat (i, "spd_id %d", &spd_id))
14938         ;
14939       else if (unformat (i, "sa_id %d", &sa_id))
14940         ;
14941       else if (unformat (i, "priority %d", &priority))
14942         ;
14943       else if (unformat (i, "protocol %d", &protocol))
14944         ;
14945       else if (unformat (i, "lport_start %d", &lport_start))
14946         ;
14947       else if (unformat (i, "lport_stop %d", &lport_stop))
14948         ;
14949       else if (unformat (i, "rport_start %d", &rport_start))
14950         ;
14951       else if (unformat (i, "rport_stop %d", &rport_stop))
14952         ;
14953       else
14954         if (unformat
14955             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14956         {
14957           is_ipv6 = 0;
14958           is_ip_any = 0;
14959         }
14960       else
14961         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14962         {
14963           is_ipv6 = 0;
14964           is_ip_any = 0;
14965         }
14966       else
14967         if (unformat
14968             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14969         {
14970           is_ipv6 = 0;
14971           is_ip_any = 0;
14972         }
14973       else
14974         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14975         {
14976           is_ipv6 = 0;
14977           is_ip_any = 0;
14978         }
14979       else
14980         if (unformat
14981             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14982         {
14983           is_ipv6 = 1;
14984           is_ip_any = 0;
14985         }
14986       else
14987         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14988         {
14989           is_ipv6 = 1;
14990           is_ip_any = 0;
14991         }
14992       else
14993         if (unformat
14994             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14995         {
14996           is_ipv6 = 1;
14997           is_ip_any = 0;
14998         }
14999       else
15000         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15001         {
15002           is_ipv6 = 1;
15003           is_ip_any = 0;
15004         }
15005       else
15006         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15007         {
15008           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15009             {
15010               clib_warning ("unsupported action: 'resolve'");
15011               return -99;
15012             }
15013         }
15014       else
15015         {
15016           clib_warning ("parse error '%U'", format_unformat_error, i);
15017           return -99;
15018         }
15019
15020     }
15021
15022   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15023
15024   mp->spd_id = ntohl (spd_id);
15025   mp->priority = ntohl (priority);
15026   mp->is_outbound = is_outbound;
15027
15028   mp->is_ipv6 = is_ipv6;
15029   if (is_ipv6 || is_ip_any)
15030     {
15031       clib_memcpy (mp->remote_address_start, &raddr6_start,
15032                    sizeof (ip6_address_t));
15033       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15034                    sizeof (ip6_address_t));
15035       clib_memcpy (mp->local_address_start, &laddr6_start,
15036                    sizeof (ip6_address_t));
15037       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15038                    sizeof (ip6_address_t));
15039     }
15040   else
15041     {
15042       clib_memcpy (mp->remote_address_start, &raddr4_start,
15043                    sizeof (ip4_address_t));
15044       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15045                    sizeof (ip4_address_t));
15046       clib_memcpy (mp->local_address_start, &laddr4_start,
15047                    sizeof (ip4_address_t));
15048       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15049                    sizeof (ip4_address_t));
15050     }
15051   mp->protocol = (u8) protocol;
15052   mp->local_port_start = ntohs ((u16) lport_start);
15053   mp->local_port_stop = ntohs ((u16) lport_stop);
15054   mp->remote_port_start = ntohs ((u16) rport_start);
15055   mp->remote_port_stop = ntohs ((u16) rport_stop);
15056   mp->policy = (u8) policy;
15057   mp->sa_id = ntohl (sa_id);
15058   mp->is_add = is_add;
15059   mp->is_ip_any = is_ip_any;
15060   S (mp);
15061   W (ret);
15062   return ret;
15063 }
15064
15065 static int
15066 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15067 {
15068   unformat_input_t *i = vam->input;
15069   vl_api_ipsec_sad_add_del_entry_t *mp;
15070   u32 sad_id = 0, spi = 0;
15071   u8 *ck = 0, *ik = 0;
15072   u8 is_add = 1;
15073
15074   u8 protocol = IPSEC_PROTOCOL_AH;
15075   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15076   u32 crypto_alg = 0, integ_alg = 0;
15077   ip4_address_t tun_src4;
15078   ip4_address_t tun_dst4;
15079   ip6_address_t tun_src6;
15080   ip6_address_t tun_dst6;
15081   int ret;
15082
15083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (i, "del"))
15086         is_add = 0;
15087       else if (unformat (i, "sad_id %d", &sad_id))
15088         ;
15089       else if (unformat (i, "spi %d", &spi))
15090         ;
15091       else if (unformat (i, "esp"))
15092         protocol = IPSEC_PROTOCOL_ESP;
15093       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15094         {
15095           is_tunnel = 1;
15096           is_tunnel_ipv6 = 0;
15097         }
15098       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15099         {
15100           is_tunnel = 1;
15101           is_tunnel_ipv6 = 0;
15102         }
15103       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15104         {
15105           is_tunnel = 1;
15106           is_tunnel_ipv6 = 1;
15107         }
15108       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15109         {
15110           is_tunnel = 1;
15111           is_tunnel_ipv6 = 1;
15112         }
15113       else
15114         if (unformat
15115             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15116         {
15117           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15118             {
15119               clib_warning ("unsupported crypto-alg: '%U'",
15120                             format_ipsec_crypto_alg, crypto_alg);
15121               return -99;
15122             }
15123         }
15124       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15125         ;
15126       else
15127         if (unformat
15128             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15129         {
15130           if (integ_alg >= IPSEC_INTEG_N_ALG)
15131             {
15132               clib_warning ("unsupported integ-alg: '%U'",
15133                             format_ipsec_integ_alg, integ_alg);
15134               return -99;
15135             }
15136         }
15137       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15138         ;
15139       else
15140         {
15141           clib_warning ("parse error '%U'", format_unformat_error, i);
15142           return -99;
15143         }
15144
15145     }
15146
15147   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15148
15149   mp->sad_id = ntohl (sad_id);
15150   mp->is_add = is_add;
15151   mp->protocol = protocol;
15152   mp->spi = ntohl (spi);
15153   mp->is_tunnel = is_tunnel;
15154   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15155   mp->crypto_algorithm = crypto_alg;
15156   mp->integrity_algorithm = integ_alg;
15157   mp->crypto_key_length = vec_len (ck);
15158   mp->integrity_key_length = vec_len (ik);
15159
15160   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15161     mp->crypto_key_length = sizeof (mp->crypto_key);
15162
15163   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15164     mp->integrity_key_length = sizeof (mp->integrity_key);
15165
15166   if (ck)
15167     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15168   if (ik)
15169     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15170
15171   if (is_tunnel)
15172     {
15173       if (is_tunnel_ipv6)
15174         {
15175           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15176                        sizeof (ip6_address_t));
15177           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15178                        sizeof (ip6_address_t));
15179         }
15180       else
15181         {
15182           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15183                        sizeof (ip4_address_t));
15184           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15185                        sizeof (ip4_address_t));
15186         }
15187     }
15188
15189   S (mp);
15190   W (ret);
15191   return ret;
15192 }
15193
15194 static int
15195 api_ipsec_sa_set_key (vat_main_t * vam)
15196 {
15197   unformat_input_t *i = vam->input;
15198   vl_api_ipsec_sa_set_key_t *mp;
15199   u32 sa_id;
15200   u8 *ck = 0, *ik = 0;
15201   int ret;
15202
15203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15204     {
15205       if (unformat (i, "sa_id %d", &sa_id))
15206         ;
15207       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15208         ;
15209       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15210         ;
15211       else
15212         {
15213           clib_warning ("parse error '%U'", format_unformat_error, i);
15214           return -99;
15215         }
15216     }
15217
15218   M (IPSEC_SA_SET_KEY, mp);
15219
15220   mp->sa_id = ntohl (sa_id);
15221   mp->crypto_key_length = vec_len (ck);
15222   mp->integrity_key_length = vec_len (ik);
15223
15224   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15225     mp->crypto_key_length = sizeof (mp->crypto_key);
15226
15227   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15228     mp->integrity_key_length = sizeof (mp->integrity_key);
15229
15230   if (ck)
15231     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15232   if (ik)
15233     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15234
15235   S (mp);
15236   W (ret);
15237   return ret;
15238 }
15239
15240 static int
15241 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15242 {
15243   unformat_input_t *i = vam->input;
15244   vl_api_ipsec_tunnel_if_add_del_t *mp;
15245   u32 local_spi = 0, remote_spi = 0;
15246   u32 crypto_alg = 0, integ_alg = 0;
15247   u8 *lck = NULL, *rck = NULL;
15248   u8 *lik = NULL, *rik = NULL;
15249   ip4_address_t local_ip = { {0} };
15250   ip4_address_t remote_ip = { {0} };
15251   u8 is_add = 1;
15252   u8 esn = 0;
15253   u8 anti_replay = 0;
15254   u8 renumber = 0;
15255   u32 instance = ~0;
15256   int ret;
15257
15258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15259     {
15260       if (unformat (i, "del"))
15261         is_add = 0;
15262       else if (unformat (i, "esn"))
15263         esn = 1;
15264       else if (unformat (i, "anti_replay"))
15265         anti_replay = 1;
15266       else if (unformat (i, "local_spi %d", &local_spi))
15267         ;
15268       else if (unformat (i, "remote_spi %d", &remote_spi))
15269         ;
15270       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15271         ;
15272       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15273         ;
15274       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15275         ;
15276       else
15277         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15278         ;
15279       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15280         ;
15281       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15282         ;
15283       else
15284         if (unformat
15285             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15286         {
15287           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15288             {
15289               errmsg ("unsupported crypto-alg: '%U'\n",
15290                       format_ipsec_crypto_alg, crypto_alg);
15291               return -99;
15292             }
15293         }
15294       else
15295         if (unformat
15296             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15297         {
15298           if (integ_alg >= IPSEC_INTEG_N_ALG)
15299             {
15300               errmsg ("unsupported integ-alg: '%U'\n",
15301                       format_ipsec_integ_alg, integ_alg);
15302               return -99;
15303             }
15304         }
15305       else if (unformat (i, "instance %u", &instance))
15306         renumber = 1;
15307       else
15308         {
15309           errmsg ("parse error '%U'\n", format_unformat_error, i);
15310           return -99;
15311         }
15312     }
15313
15314   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15315
15316   mp->is_add = is_add;
15317   mp->esn = esn;
15318   mp->anti_replay = anti_replay;
15319
15320   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15321   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15322
15323   mp->local_spi = htonl (local_spi);
15324   mp->remote_spi = htonl (remote_spi);
15325   mp->crypto_alg = (u8) crypto_alg;
15326
15327   mp->local_crypto_key_len = 0;
15328   if (lck)
15329     {
15330       mp->local_crypto_key_len = vec_len (lck);
15331       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15332         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15333       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15334     }
15335
15336   mp->remote_crypto_key_len = 0;
15337   if (rck)
15338     {
15339       mp->remote_crypto_key_len = vec_len (rck);
15340       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15341         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15342       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15343     }
15344
15345   mp->integ_alg = (u8) integ_alg;
15346
15347   mp->local_integ_key_len = 0;
15348   if (lik)
15349     {
15350       mp->local_integ_key_len = vec_len (lik);
15351       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15352         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15353       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15354     }
15355
15356   mp->remote_integ_key_len = 0;
15357   if (rik)
15358     {
15359       mp->remote_integ_key_len = vec_len (rik);
15360       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15361         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15362       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15363     }
15364
15365   if (renumber)
15366     {
15367       mp->renumber = renumber;
15368       mp->show_instance = ntohl (instance);
15369     }
15370
15371   S (mp);
15372   W (ret);
15373   return ret;
15374 }
15375
15376 static void
15377 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15378 {
15379   vat_main_t *vam = &vat_main;
15380
15381   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15382          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15383          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15384          "tunnel_src_addr %U tunnel_dst_addr %U "
15385          "salt %u seq_outbound %lu last_seq_inbound %lu "
15386          "replay_window %lu total_data_size %lu\n",
15387          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15388          mp->protocol,
15389          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15390          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15391          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15392          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15393          mp->tunnel_src_addr,
15394          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15395          mp->tunnel_dst_addr,
15396          ntohl (mp->salt),
15397          clib_net_to_host_u64 (mp->seq_outbound),
15398          clib_net_to_host_u64 (mp->last_seq_inbound),
15399          clib_net_to_host_u64 (mp->replay_window),
15400          clib_net_to_host_u64 (mp->total_data_size));
15401 }
15402
15403 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15404 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15405
15406 static void vl_api_ipsec_sa_details_t_handler_json
15407   (vl_api_ipsec_sa_details_t * mp)
15408 {
15409   vat_main_t *vam = &vat_main;
15410   vat_json_node_t *node = NULL;
15411   struct in_addr src_ip4, dst_ip4;
15412   struct in6_addr src_ip6, dst_ip6;
15413
15414   if (VAT_JSON_ARRAY != vam->json_tree.type)
15415     {
15416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15417       vat_json_init_array (&vam->json_tree);
15418     }
15419   node = vat_json_array_add (&vam->json_tree);
15420
15421   vat_json_init_object (node);
15422   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15424   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15425   vat_json_object_add_uint (node, "proto", mp->protocol);
15426   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15427   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15428   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15429   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15430   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15431   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15432   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15433                              mp->crypto_key_len);
15434   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15435                              mp->integ_key_len);
15436   if (mp->is_tunnel_ip6)
15437     {
15438       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15439       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15440       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15441       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15442     }
15443   else
15444     {
15445       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15446       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15447       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15448       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15449     }
15450   vat_json_object_add_uint (node, "replay_window",
15451                             clib_net_to_host_u64 (mp->replay_window));
15452   vat_json_object_add_uint (node, "total_data_size",
15453                             clib_net_to_host_u64 (mp->total_data_size));
15454
15455 }
15456
15457 static int
15458 api_ipsec_sa_dump (vat_main_t * vam)
15459 {
15460   unformat_input_t *i = vam->input;
15461   vl_api_ipsec_sa_dump_t *mp;
15462   vl_api_control_ping_t *mp_ping;
15463   u32 sa_id = ~0;
15464   int ret;
15465
15466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15467     {
15468       if (unformat (i, "sa_id %d", &sa_id))
15469         ;
15470       else
15471         {
15472           clib_warning ("parse error '%U'", format_unformat_error, i);
15473           return -99;
15474         }
15475     }
15476
15477   M (IPSEC_SA_DUMP, mp);
15478
15479   mp->sa_id = ntohl (sa_id);
15480
15481   S (mp);
15482
15483   /* Use a control ping for synchronization */
15484   M (CONTROL_PING, mp_ping);
15485   S (mp_ping);
15486
15487   W (ret);
15488   return ret;
15489 }
15490
15491 static int
15492 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15493 {
15494   unformat_input_t *i = vam->input;
15495   vl_api_ipsec_tunnel_if_set_key_t *mp;
15496   u32 sw_if_index = ~0;
15497   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15498   u8 *key = 0;
15499   u32 alg = ~0;
15500   int ret;
15501
15502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15503     {
15504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15505         ;
15506       else
15507         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15508         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15509       else
15510         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15511         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15512       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15513         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15514       else
15515         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15516         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15517       else if (unformat (i, "%U", unformat_hex_string, &key))
15518         ;
15519       else
15520         {
15521           clib_warning ("parse error '%U'", format_unformat_error, i);
15522           return -99;
15523         }
15524     }
15525
15526   if (sw_if_index == ~0)
15527     {
15528       errmsg ("interface must be specified");
15529       return -99;
15530     }
15531
15532   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15533     {
15534       errmsg ("key type must be specified");
15535       return -99;
15536     }
15537
15538   if (alg == ~0)
15539     {
15540       errmsg ("algorithm must be specified");
15541       return -99;
15542     }
15543
15544   if (vec_len (key) == 0)
15545     {
15546       errmsg ("key must be specified");
15547       return -99;
15548     }
15549
15550   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15551
15552   mp->sw_if_index = htonl (sw_if_index);
15553   mp->alg = alg;
15554   mp->key_type = key_type;
15555   mp->key_len = vec_len (key);
15556   clib_memcpy (mp->key, key, vec_len (key));
15557
15558   S (mp);
15559   W (ret);
15560
15561   return ret;
15562 }
15563
15564 static int
15565 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15566 {
15567   unformat_input_t *i = vam->input;
15568   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15569   u32 sw_if_index = ~0;
15570   u32 sa_id = ~0;
15571   u8 is_outbound = (u8) ~ 0;
15572   int ret;
15573
15574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15575     {
15576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15577         ;
15578       else if (unformat (i, "sa_id %d", &sa_id))
15579         ;
15580       else if (unformat (i, "outbound"))
15581         is_outbound = 1;
15582       else if (unformat (i, "inbound"))
15583         is_outbound = 0;
15584       else
15585         {
15586           clib_warning ("parse error '%U'", format_unformat_error, i);
15587           return -99;
15588         }
15589     }
15590
15591   if (sw_if_index == ~0)
15592     {
15593       errmsg ("interface must be specified");
15594       return -99;
15595     }
15596
15597   if (sa_id == ~0)
15598     {
15599       errmsg ("SA ID must be specified");
15600       return -99;
15601     }
15602
15603   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15604
15605   mp->sw_if_index = htonl (sw_if_index);
15606   mp->sa_id = htonl (sa_id);
15607   mp->is_outbound = is_outbound;
15608
15609   S (mp);
15610   W (ret);
15611
15612   return ret;
15613 }
15614
15615 static int
15616 api_ikev2_profile_add_del (vat_main_t * vam)
15617 {
15618   unformat_input_t *i = vam->input;
15619   vl_api_ikev2_profile_add_del_t *mp;
15620   u8 is_add = 1;
15621   u8 *name = 0;
15622   int ret;
15623
15624   const char *valid_chars = "a-zA-Z0-9_";
15625
15626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15627     {
15628       if (unformat (i, "del"))
15629         is_add = 0;
15630       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15631         vec_add1 (name, 0);
15632       else
15633         {
15634           errmsg ("parse error '%U'", format_unformat_error, i);
15635           return -99;
15636         }
15637     }
15638
15639   if (!vec_len (name))
15640     {
15641       errmsg ("profile name must be specified");
15642       return -99;
15643     }
15644
15645   if (vec_len (name) > 64)
15646     {
15647       errmsg ("profile name too long");
15648       return -99;
15649     }
15650
15651   M (IKEV2_PROFILE_ADD_DEL, mp);
15652
15653   clib_memcpy (mp->name, name, vec_len (name));
15654   mp->is_add = is_add;
15655   vec_free (name);
15656
15657   S (mp);
15658   W (ret);
15659   return ret;
15660 }
15661
15662 static int
15663 api_ikev2_profile_set_auth (vat_main_t * vam)
15664 {
15665   unformat_input_t *i = vam->input;
15666   vl_api_ikev2_profile_set_auth_t *mp;
15667   u8 *name = 0;
15668   u8 *data = 0;
15669   u32 auth_method = 0;
15670   u8 is_hex = 0;
15671   int ret;
15672
15673   const char *valid_chars = "a-zA-Z0-9_";
15674
15675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15678         vec_add1 (name, 0);
15679       else if (unformat (i, "auth_method %U",
15680                          unformat_ikev2_auth_method, &auth_method))
15681         ;
15682       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15683         is_hex = 1;
15684       else if (unformat (i, "auth_data %v", &data))
15685         ;
15686       else
15687         {
15688           errmsg ("parse error '%U'", format_unformat_error, i);
15689           return -99;
15690         }
15691     }
15692
15693   if (!vec_len (name))
15694     {
15695       errmsg ("profile name must be specified");
15696       return -99;
15697     }
15698
15699   if (vec_len (name) > 64)
15700     {
15701       errmsg ("profile name too long");
15702       return -99;
15703     }
15704
15705   if (!vec_len (data))
15706     {
15707       errmsg ("auth_data must be specified");
15708       return -99;
15709     }
15710
15711   if (!auth_method)
15712     {
15713       errmsg ("auth_method must be specified");
15714       return -99;
15715     }
15716
15717   M (IKEV2_PROFILE_SET_AUTH, mp);
15718
15719   mp->is_hex = is_hex;
15720   mp->auth_method = (u8) auth_method;
15721   mp->data_len = vec_len (data);
15722   clib_memcpy (mp->name, name, vec_len (name));
15723   clib_memcpy (mp->data, data, vec_len (data));
15724   vec_free (name);
15725   vec_free (data);
15726
15727   S (mp);
15728   W (ret);
15729   return ret;
15730 }
15731
15732 static int
15733 api_ikev2_profile_set_id (vat_main_t * vam)
15734 {
15735   unformat_input_t *i = vam->input;
15736   vl_api_ikev2_profile_set_id_t *mp;
15737   u8 *name = 0;
15738   u8 *data = 0;
15739   u8 is_local = 0;
15740   u32 id_type = 0;
15741   ip4_address_t ip4;
15742   int ret;
15743
15744   const char *valid_chars = "a-zA-Z0-9_";
15745
15746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15747     {
15748       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15749         vec_add1 (name, 0);
15750       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15751         ;
15752       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15753         {
15754           data = vec_new (u8, 4);
15755           clib_memcpy (data, ip4.as_u8, 4);
15756         }
15757       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15758         ;
15759       else if (unformat (i, "id_data %v", &data))
15760         ;
15761       else if (unformat (i, "local"))
15762         is_local = 1;
15763       else if (unformat (i, "remote"))
15764         is_local = 0;
15765       else
15766         {
15767           errmsg ("parse error '%U'", format_unformat_error, i);
15768           return -99;
15769         }
15770     }
15771
15772   if (!vec_len (name))
15773     {
15774       errmsg ("profile name must be specified");
15775       return -99;
15776     }
15777
15778   if (vec_len (name) > 64)
15779     {
15780       errmsg ("profile name too long");
15781       return -99;
15782     }
15783
15784   if (!vec_len (data))
15785     {
15786       errmsg ("id_data must be specified");
15787       return -99;
15788     }
15789
15790   if (!id_type)
15791     {
15792       errmsg ("id_type must be specified");
15793       return -99;
15794     }
15795
15796   M (IKEV2_PROFILE_SET_ID, mp);
15797
15798   mp->is_local = is_local;
15799   mp->id_type = (u8) id_type;
15800   mp->data_len = vec_len (data);
15801   clib_memcpy (mp->name, name, vec_len (name));
15802   clib_memcpy (mp->data, data, vec_len (data));
15803   vec_free (name);
15804   vec_free (data);
15805
15806   S (mp);
15807   W (ret);
15808   return ret;
15809 }
15810
15811 static int
15812 api_ikev2_profile_set_ts (vat_main_t * vam)
15813 {
15814   unformat_input_t *i = vam->input;
15815   vl_api_ikev2_profile_set_ts_t *mp;
15816   u8 *name = 0;
15817   u8 is_local = 0;
15818   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15819   ip4_address_t start_addr, end_addr;
15820
15821   const char *valid_chars = "a-zA-Z0-9_";
15822   int ret;
15823
15824   start_addr.as_u32 = 0;
15825   end_addr.as_u32 = (u32) ~ 0;
15826
15827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15828     {
15829       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15830         vec_add1 (name, 0);
15831       else if (unformat (i, "protocol %d", &proto))
15832         ;
15833       else if (unformat (i, "start_port %d", &start_port))
15834         ;
15835       else if (unformat (i, "end_port %d", &end_port))
15836         ;
15837       else
15838         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15839         ;
15840       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15841         ;
15842       else if (unformat (i, "local"))
15843         is_local = 1;
15844       else if (unformat (i, "remote"))
15845         is_local = 0;
15846       else
15847         {
15848           errmsg ("parse error '%U'", format_unformat_error, i);
15849           return -99;
15850         }
15851     }
15852
15853   if (!vec_len (name))
15854     {
15855       errmsg ("profile name must be specified");
15856       return -99;
15857     }
15858
15859   if (vec_len (name) > 64)
15860     {
15861       errmsg ("profile name too long");
15862       return -99;
15863     }
15864
15865   M (IKEV2_PROFILE_SET_TS, mp);
15866
15867   mp->is_local = is_local;
15868   mp->proto = (u8) proto;
15869   mp->start_port = (u16) start_port;
15870   mp->end_port = (u16) end_port;
15871   mp->start_addr = start_addr.as_u32;
15872   mp->end_addr = end_addr.as_u32;
15873   clib_memcpy (mp->name, name, vec_len (name));
15874   vec_free (name);
15875
15876   S (mp);
15877   W (ret);
15878   return ret;
15879 }
15880
15881 static int
15882 api_ikev2_set_local_key (vat_main_t * vam)
15883 {
15884   unformat_input_t *i = vam->input;
15885   vl_api_ikev2_set_local_key_t *mp;
15886   u8 *file = 0;
15887   int ret;
15888
15889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15890     {
15891       if (unformat (i, "file %v", &file))
15892         vec_add1 (file, 0);
15893       else
15894         {
15895           errmsg ("parse error '%U'", format_unformat_error, i);
15896           return -99;
15897         }
15898     }
15899
15900   if (!vec_len (file))
15901     {
15902       errmsg ("RSA key file must be specified");
15903       return -99;
15904     }
15905
15906   if (vec_len (file) > 256)
15907     {
15908       errmsg ("file name too long");
15909       return -99;
15910     }
15911
15912   M (IKEV2_SET_LOCAL_KEY, mp);
15913
15914   clib_memcpy (mp->key_file, file, vec_len (file));
15915   vec_free (file);
15916
15917   S (mp);
15918   W (ret);
15919   return ret;
15920 }
15921
15922 static int
15923 api_ikev2_set_responder (vat_main_t * vam)
15924 {
15925   unformat_input_t *i = vam->input;
15926   vl_api_ikev2_set_responder_t *mp;
15927   int ret;
15928   u8 *name = 0;
15929   u32 sw_if_index = ~0;
15930   ip4_address_t address;
15931
15932   const char *valid_chars = "a-zA-Z0-9_";
15933
15934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15935     {
15936       if (unformat
15937           (i, "%U interface %d address %U", unformat_token, valid_chars,
15938            &name, &sw_if_index, unformat_ip4_address, &address))
15939         vec_add1 (name, 0);
15940       else
15941         {
15942           errmsg ("parse error '%U'", format_unformat_error, i);
15943           return -99;
15944         }
15945     }
15946
15947   if (!vec_len (name))
15948     {
15949       errmsg ("profile name must be specified");
15950       return -99;
15951     }
15952
15953   if (vec_len (name) > 64)
15954     {
15955       errmsg ("profile name too long");
15956       return -99;
15957     }
15958
15959   M (IKEV2_SET_RESPONDER, mp);
15960
15961   clib_memcpy (mp->name, name, vec_len (name));
15962   vec_free (name);
15963
15964   mp->sw_if_index = sw_if_index;
15965   clib_memcpy (mp->address, &address, sizeof (address));
15966
15967   S (mp);
15968   W (ret);
15969   return ret;
15970 }
15971
15972 static int
15973 api_ikev2_set_ike_transforms (vat_main_t * vam)
15974 {
15975   unformat_input_t *i = vam->input;
15976   vl_api_ikev2_set_ike_transforms_t *mp;
15977   int ret;
15978   u8 *name = 0;
15979   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15980
15981   const char *valid_chars = "a-zA-Z0-9_";
15982
15983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15984     {
15985       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15986                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15987         vec_add1 (name, 0);
15988       else
15989         {
15990           errmsg ("parse error '%U'", format_unformat_error, i);
15991           return -99;
15992         }
15993     }
15994
15995   if (!vec_len (name))
15996     {
15997       errmsg ("profile name must be specified");
15998       return -99;
15999     }
16000
16001   if (vec_len (name) > 64)
16002     {
16003       errmsg ("profile name too long");
16004       return -99;
16005     }
16006
16007   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16008
16009   clib_memcpy (mp->name, name, vec_len (name));
16010   vec_free (name);
16011   mp->crypto_alg = crypto_alg;
16012   mp->crypto_key_size = crypto_key_size;
16013   mp->integ_alg = integ_alg;
16014   mp->dh_group = dh_group;
16015
16016   S (mp);
16017   W (ret);
16018   return ret;
16019 }
16020
16021
16022 static int
16023 api_ikev2_set_esp_transforms (vat_main_t * vam)
16024 {
16025   unformat_input_t *i = vam->input;
16026   vl_api_ikev2_set_esp_transforms_t *mp;
16027   int ret;
16028   u8 *name = 0;
16029   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16030
16031   const char *valid_chars = "a-zA-Z0-9_";
16032
16033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16034     {
16035       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16036                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16037         vec_add1 (name, 0);
16038       else
16039         {
16040           errmsg ("parse error '%U'", format_unformat_error, i);
16041           return -99;
16042         }
16043     }
16044
16045   if (!vec_len (name))
16046     {
16047       errmsg ("profile name must be specified");
16048       return -99;
16049     }
16050
16051   if (vec_len (name) > 64)
16052     {
16053       errmsg ("profile name too long");
16054       return -99;
16055     }
16056
16057   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16058
16059   clib_memcpy (mp->name, name, vec_len (name));
16060   vec_free (name);
16061   mp->crypto_alg = crypto_alg;
16062   mp->crypto_key_size = crypto_key_size;
16063   mp->integ_alg = integ_alg;
16064   mp->dh_group = dh_group;
16065
16066   S (mp);
16067   W (ret);
16068   return ret;
16069 }
16070
16071 static int
16072 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16073 {
16074   unformat_input_t *i = vam->input;
16075   vl_api_ikev2_set_sa_lifetime_t *mp;
16076   int ret;
16077   u8 *name = 0;
16078   u64 lifetime, lifetime_maxdata;
16079   u32 lifetime_jitter, handover;
16080
16081   const char *valid_chars = "a-zA-Z0-9_";
16082
16083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16086                     &lifetime, &lifetime_jitter, &handover,
16087                     &lifetime_maxdata))
16088         vec_add1 (name, 0);
16089       else
16090         {
16091           errmsg ("parse error '%U'", format_unformat_error, i);
16092           return -99;
16093         }
16094     }
16095
16096   if (!vec_len (name))
16097     {
16098       errmsg ("profile name must be specified");
16099       return -99;
16100     }
16101
16102   if (vec_len (name) > 64)
16103     {
16104       errmsg ("profile name too long");
16105       return -99;
16106     }
16107
16108   M (IKEV2_SET_SA_LIFETIME, mp);
16109
16110   clib_memcpy (mp->name, name, vec_len (name));
16111   vec_free (name);
16112   mp->lifetime = lifetime;
16113   mp->lifetime_jitter = lifetime_jitter;
16114   mp->handover = handover;
16115   mp->lifetime_maxdata = lifetime_maxdata;
16116
16117   S (mp);
16118   W (ret);
16119   return ret;
16120 }
16121
16122 static int
16123 api_ikev2_initiate_sa_init (vat_main_t * vam)
16124 {
16125   unformat_input_t *i = vam->input;
16126   vl_api_ikev2_initiate_sa_init_t *mp;
16127   int ret;
16128   u8 *name = 0;
16129
16130   const char *valid_chars = "a-zA-Z0-9_";
16131
16132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16133     {
16134       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16135         vec_add1 (name, 0);
16136       else
16137         {
16138           errmsg ("parse error '%U'", format_unformat_error, i);
16139           return -99;
16140         }
16141     }
16142
16143   if (!vec_len (name))
16144     {
16145       errmsg ("profile name must be specified");
16146       return -99;
16147     }
16148
16149   if (vec_len (name) > 64)
16150     {
16151       errmsg ("profile name too long");
16152       return -99;
16153     }
16154
16155   M (IKEV2_INITIATE_SA_INIT, mp);
16156
16157   clib_memcpy (mp->name, name, vec_len (name));
16158   vec_free (name);
16159
16160   S (mp);
16161   W (ret);
16162   return ret;
16163 }
16164
16165 static int
16166 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16167 {
16168   unformat_input_t *i = vam->input;
16169   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16170   int ret;
16171   u64 ispi;
16172
16173
16174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16175     {
16176       if (unformat (i, "%lx", &ispi))
16177         ;
16178       else
16179         {
16180           errmsg ("parse error '%U'", format_unformat_error, i);
16181           return -99;
16182         }
16183     }
16184
16185   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16186
16187   mp->ispi = ispi;
16188
16189   S (mp);
16190   W (ret);
16191   return ret;
16192 }
16193
16194 static int
16195 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16196 {
16197   unformat_input_t *i = vam->input;
16198   vl_api_ikev2_initiate_del_child_sa_t *mp;
16199   int ret;
16200   u32 ispi;
16201
16202
16203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16204     {
16205       if (unformat (i, "%x", &ispi))
16206         ;
16207       else
16208         {
16209           errmsg ("parse error '%U'", format_unformat_error, i);
16210           return -99;
16211         }
16212     }
16213
16214   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16215
16216   mp->ispi = ispi;
16217
16218   S (mp);
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16225 {
16226   unformat_input_t *i = vam->input;
16227   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16228   int ret;
16229   u32 ispi;
16230
16231
16232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (i, "%x", &ispi))
16235         ;
16236       else
16237         {
16238           errmsg ("parse error '%U'", format_unformat_error, i);
16239           return -99;
16240         }
16241     }
16242
16243   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16244
16245   mp->ispi = ispi;
16246
16247   S (mp);
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static int
16253 api_get_first_msg_id (vat_main_t * vam)
16254 {
16255   vl_api_get_first_msg_id_t *mp;
16256   unformat_input_t *i = vam->input;
16257   u8 *name;
16258   u8 name_set = 0;
16259   int ret;
16260
16261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (i, "client %s", &name))
16264         name_set = 1;
16265       else
16266         break;
16267     }
16268
16269   if (name_set == 0)
16270     {
16271       errmsg ("missing client name");
16272       return -99;
16273     }
16274   vec_add1 (name, 0);
16275
16276   if (vec_len (name) > 63)
16277     {
16278       errmsg ("client name too long");
16279       return -99;
16280     }
16281
16282   M (GET_FIRST_MSG_ID, mp);
16283   clib_memcpy (mp->name, name, vec_len (name));
16284   S (mp);
16285   W (ret);
16286   return ret;
16287 }
16288
16289 static int
16290 api_cop_interface_enable_disable (vat_main_t * vam)
16291 {
16292   unformat_input_t *line_input = vam->input;
16293   vl_api_cop_interface_enable_disable_t *mp;
16294   u32 sw_if_index = ~0;
16295   u8 enable_disable = 1;
16296   int ret;
16297
16298   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16299     {
16300       if (unformat (line_input, "disable"))
16301         enable_disable = 0;
16302       if (unformat (line_input, "enable"))
16303         enable_disable = 1;
16304       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16305                          vam, &sw_if_index))
16306         ;
16307       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16308         ;
16309       else
16310         break;
16311     }
16312
16313   if (sw_if_index == ~0)
16314     {
16315       errmsg ("missing interface name or sw_if_index");
16316       return -99;
16317     }
16318
16319   /* Construct the API message */
16320   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16321   mp->sw_if_index = ntohl (sw_if_index);
16322   mp->enable_disable = enable_disable;
16323
16324   /* send it... */
16325   S (mp);
16326   /* Wait for the reply */
16327   W (ret);
16328   return ret;
16329 }
16330
16331 static int
16332 api_cop_whitelist_enable_disable (vat_main_t * vam)
16333 {
16334   unformat_input_t *line_input = vam->input;
16335   vl_api_cop_whitelist_enable_disable_t *mp;
16336   u32 sw_if_index = ~0;
16337   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16338   u32 fib_id = 0;
16339   int ret;
16340
16341   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16342     {
16343       if (unformat (line_input, "ip4"))
16344         ip4 = 1;
16345       else if (unformat (line_input, "ip6"))
16346         ip6 = 1;
16347       else if (unformat (line_input, "default"))
16348         default_cop = 1;
16349       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16350                          vam, &sw_if_index))
16351         ;
16352       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16353         ;
16354       else if (unformat (line_input, "fib-id %d", &fib_id))
16355         ;
16356       else
16357         break;
16358     }
16359
16360   if (sw_if_index == ~0)
16361     {
16362       errmsg ("missing interface name or sw_if_index");
16363       return -99;
16364     }
16365
16366   /* Construct the API message */
16367   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16368   mp->sw_if_index = ntohl (sw_if_index);
16369   mp->fib_id = ntohl (fib_id);
16370   mp->ip4 = ip4;
16371   mp->ip6 = ip6;
16372   mp->default_cop = default_cop;
16373
16374   /* send it... */
16375   S (mp);
16376   /* Wait for the reply */
16377   W (ret);
16378   return ret;
16379 }
16380
16381 static int
16382 api_get_node_graph (vat_main_t * vam)
16383 {
16384   vl_api_get_node_graph_t *mp;
16385   int ret;
16386
16387   M (GET_NODE_GRAPH, mp);
16388
16389   /* send it... */
16390   S (mp);
16391   /* Wait for the reply */
16392   W (ret);
16393   return ret;
16394 }
16395
16396 /* *INDENT-OFF* */
16397 /** Used for parsing LISP eids */
16398 typedef CLIB_PACKED(struct{
16399   u8 addr[16];   /**< eid address */
16400   u32 len;       /**< prefix length if IP */
16401   u8 type;      /**< type of eid */
16402 }) lisp_eid_vat_t;
16403 /* *INDENT-ON* */
16404
16405 static uword
16406 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16407 {
16408   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16409
16410   clib_memset (a, 0, sizeof (a[0]));
16411
16412   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16413     {
16414       a->type = 0;              /* ipv4 type */
16415     }
16416   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16417     {
16418       a->type = 1;              /* ipv6 type */
16419     }
16420   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16421     {
16422       a->type = 2;              /* mac type */
16423     }
16424   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16425     {
16426       a->type = 3;              /* NSH type */
16427       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16428       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16429     }
16430   else
16431     {
16432       return 0;
16433     }
16434
16435   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16436     {
16437       return 0;
16438     }
16439
16440   return 1;
16441 }
16442
16443 static int
16444 lisp_eid_size_vat (u8 type)
16445 {
16446   switch (type)
16447     {
16448     case 0:
16449       return 4;
16450     case 1:
16451       return 16;
16452     case 2:
16453       return 6;
16454     case 3:
16455       return 5;
16456     }
16457   return 0;
16458 }
16459
16460 static void
16461 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16462 {
16463   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16464 }
16465
16466 static int
16467 api_one_add_del_locator_set (vat_main_t * vam)
16468 {
16469   unformat_input_t *input = vam->input;
16470   vl_api_one_add_del_locator_set_t *mp;
16471   u8 is_add = 1;
16472   u8 *locator_set_name = NULL;
16473   u8 locator_set_name_set = 0;
16474   vl_api_local_locator_t locator, *locators = 0;
16475   u32 sw_if_index, priority, weight;
16476   u32 data_len = 0;
16477
16478   int ret;
16479   /* Parse args required to build the message */
16480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16481     {
16482       if (unformat (input, "del"))
16483         {
16484           is_add = 0;
16485         }
16486       else if (unformat (input, "locator-set %s", &locator_set_name))
16487         {
16488           locator_set_name_set = 1;
16489         }
16490       else if (unformat (input, "sw_if_index %u p %u w %u",
16491                          &sw_if_index, &priority, &weight))
16492         {
16493           locator.sw_if_index = htonl (sw_if_index);
16494           locator.priority = priority;
16495           locator.weight = weight;
16496           vec_add1 (locators, locator);
16497         }
16498       else
16499         if (unformat
16500             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16501              &sw_if_index, &priority, &weight))
16502         {
16503           locator.sw_if_index = htonl (sw_if_index);
16504           locator.priority = priority;
16505           locator.weight = weight;
16506           vec_add1 (locators, locator);
16507         }
16508       else
16509         break;
16510     }
16511
16512   if (locator_set_name_set == 0)
16513     {
16514       errmsg ("missing locator-set name");
16515       vec_free (locators);
16516       return -99;
16517     }
16518
16519   if (vec_len (locator_set_name) > 64)
16520     {
16521       errmsg ("locator-set name too long");
16522       vec_free (locator_set_name);
16523       vec_free (locators);
16524       return -99;
16525     }
16526   vec_add1 (locator_set_name, 0);
16527
16528   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16529
16530   /* Construct the API message */
16531   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16532
16533   mp->is_add = is_add;
16534   clib_memcpy (mp->locator_set_name, locator_set_name,
16535                vec_len (locator_set_name));
16536   vec_free (locator_set_name);
16537
16538   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16539   if (locators)
16540     clib_memcpy (mp->locators, locators, data_len);
16541   vec_free (locators);
16542
16543   /* send it... */
16544   S (mp);
16545
16546   /* Wait for a reply... */
16547   W (ret);
16548   return ret;
16549 }
16550
16551 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16552
16553 static int
16554 api_one_add_del_locator (vat_main_t * vam)
16555 {
16556   unformat_input_t *input = vam->input;
16557   vl_api_one_add_del_locator_t *mp;
16558   u32 tmp_if_index = ~0;
16559   u32 sw_if_index = ~0;
16560   u8 sw_if_index_set = 0;
16561   u8 sw_if_index_if_name_set = 0;
16562   u32 priority = ~0;
16563   u8 priority_set = 0;
16564   u32 weight = ~0;
16565   u8 weight_set = 0;
16566   u8 is_add = 1;
16567   u8 *locator_set_name = NULL;
16568   u8 locator_set_name_set = 0;
16569   int ret;
16570
16571   /* Parse args required to build the message */
16572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16573     {
16574       if (unformat (input, "del"))
16575         {
16576           is_add = 0;
16577         }
16578       else if (unformat (input, "locator-set %s", &locator_set_name))
16579         {
16580           locator_set_name_set = 1;
16581         }
16582       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16583                          &tmp_if_index))
16584         {
16585           sw_if_index_if_name_set = 1;
16586           sw_if_index = tmp_if_index;
16587         }
16588       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16589         {
16590           sw_if_index_set = 1;
16591           sw_if_index = tmp_if_index;
16592         }
16593       else if (unformat (input, "p %d", &priority))
16594         {
16595           priority_set = 1;
16596         }
16597       else if (unformat (input, "w %d", &weight))
16598         {
16599           weight_set = 1;
16600         }
16601       else
16602         break;
16603     }
16604
16605   if (locator_set_name_set == 0)
16606     {
16607       errmsg ("missing locator-set name");
16608       return -99;
16609     }
16610
16611   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16612     {
16613       errmsg ("missing sw_if_index");
16614       vec_free (locator_set_name);
16615       return -99;
16616     }
16617
16618   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16619     {
16620       errmsg ("cannot use both params interface name and sw_if_index");
16621       vec_free (locator_set_name);
16622       return -99;
16623     }
16624
16625   if (priority_set == 0)
16626     {
16627       errmsg ("missing locator-set priority");
16628       vec_free (locator_set_name);
16629       return -99;
16630     }
16631
16632   if (weight_set == 0)
16633     {
16634       errmsg ("missing locator-set weight");
16635       vec_free (locator_set_name);
16636       return -99;
16637     }
16638
16639   if (vec_len (locator_set_name) > 64)
16640     {
16641       errmsg ("locator-set name too long");
16642       vec_free (locator_set_name);
16643       return -99;
16644     }
16645   vec_add1 (locator_set_name, 0);
16646
16647   /* Construct the API message */
16648   M (ONE_ADD_DEL_LOCATOR, mp);
16649
16650   mp->is_add = is_add;
16651   mp->sw_if_index = ntohl (sw_if_index);
16652   mp->priority = priority;
16653   mp->weight = weight;
16654   clib_memcpy (mp->locator_set_name, locator_set_name,
16655                vec_len (locator_set_name));
16656   vec_free (locator_set_name);
16657
16658   /* send it... */
16659   S (mp);
16660
16661   /* Wait for a reply... */
16662   W (ret);
16663   return ret;
16664 }
16665
16666 #define api_lisp_add_del_locator api_one_add_del_locator
16667
16668 uword
16669 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16670 {
16671   u32 *key_id = va_arg (*args, u32 *);
16672   u8 *s = 0;
16673
16674   if (unformat (input, "%s", &s))
16675     {
16676       if (!strcmp ((char *) s, "sha1"))
16677         key_id[0] = HMAC_SHA_1_96;
16678       else if (!strcmp ((char *) s, "sha256"))
16679         key_id[0] = HMAC_SHA_256_128;
16680       else
16681         {
16682           clib_warning ("invalid key_id: '%s'", s);
16683           key_id[0] = HMAC_NO_KEY;
16684         }
16685     }
16686   else
16687     return 0;
16688
16689   vec_free (s);
16690   return 1;
16691 }
16692
16693 static int
16694 api_one_add_del_local_eid (vat_main_t * vam)
16695 {
16696   unformat_input_t *input = vam->input;
16697   vl_api_one_add_del_local_eid_t *mp;
16698   u8 is_add = 1;
16699   u8 eid_set = 0;
16700   lisp_eid_vat_t _eid, *eid = &_eid;
16701   u8 *locator_set_name = 0;
16702   u8 locator_set_name_set = 0;
16703   u32 vni = 0;
16704   u16 key_id = 0;
16705   u8 *key = 0;
16706   int ret;
16707
16708   /* Parse args required to build the message */
16709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16710     {
16711       if (unformat (input, "del"))
16712         {
16713           is_add = 0;
16714         }
16715       else if (unformat (input, "vni %d", &vni))
16716         {
16717           ;
16718         }
16719       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16720         {
16721           eid_set = 1;
16722         }
16723       else if (unformat (input, "locator-set %s", &locator_set_name))
16724         {
16725           locator_set_name_set = 1;
16726         }
16727       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16728         ;
16729       else if (unformat (input, "secret-key %_%v%_", &key))
16730         ;
16731       else
16732         break;
16733     }
16734
16735   if (locator_set_name_set == 0)
16736     {
16737       errmsg ("missing locator-set name");
16738       return -99;
16739     }
16740
16741   if (0 == eid_set)
16742     {
16743       errmsg ("EID address not set!");
16744       vec_free (locator_set_name);
16745       return -99;
16746     }
16747
16748   if (key && (0 == key_id))
16749     {
16750       errmsg ("invalid key_id!");
16751       return -99;
16752     }
16753
16754   if (vec_len (key) > 64)
16755     {
16756       errmsg ("key too long");
16757       vec_free (key);
16758       return -99;
16759     }
16760
16761   if (vec_len (locator_set_name) > 64)
16762     {
16763       errmsg ("locator-set name too long");
16764       vec_free (locator_set_name);
16765       return -99;
16766     }
16767   vec_add1 (locator_set_name, 0);
16768
16769   /* Construct the API message */
16770   M (ONE_ADD_DEL_LOCAL_EID, mp);
16771
16772   mp->is_add = is_add;
16773   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16774   mp->eid_type = eid->type;
16775   mp->prefix_len = eid->len;
16776   mp->vni = clib_host_to_net_u32 (vni);
16777   mp->key_id = clib_host_to_net_u16 (key_id);
16778   clib_memcpy (mp->locator_set_name, locator_set_name,
16779                vec_len (locator_set_name));
16780   clib_memcpy (mp->key, key, vec_len (key));
16781
16782   vec_free (locator_set_name);
16783   vec_free (key);
16784
16785   /* send it... */
16786   S (mp);
16787
16788   /* Wait for a reply... */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16794
16795 static int
16796 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16797 {
16798   u32 dp_table = 0, vni = 0;;
16799   unformat_input_t *input = vam->input;
16800   vl_api_gpe_add_del_fwd_entry_t *mp;
16801   u8 is_add = 1;
16802   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16803   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16804   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16805   u32 action = ~0, w;
16806   ip4_address_t rmt_rloc4, lcl_rloc4;
16807   ip6_address_t rmt_rloc6, lcl_rloc6;
16808   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16809   int ret;
16810
16811   clib_memset (&rloc, 0, sizeof (rloc));
16812
16813   /* Parse args required to build the message */
16814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16815     {
16816       if (unformat (input, "del"))
16817         is_add = 0;
16818       else if (unformat (input, "add"))
16819         is_add = 1;
16820       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16821         {
16822           rmt_eid_set = 1;
16823         }
16824       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16825         {
16826           lcl_eid_set = 1;
16827         }
16828       else if (unformat (input, "vrf %d", &dp_table))
16829         ;
16830       else if (unformat (input, "bd %d", &dp_table))
16831         ;
16832       else if (unformat (input, "vni %d", &vni))
16833         ;
16834       else if (unformat (input, "w %d", &w))
16835         {
16836           if (!curr_rloc)
16837             {
16838               errmsg ("No RLOC configured for setting priority/weight!");
16839               return -99;
16840             }
16841           curr_rloc->weight = w;
16842         }
16843       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16844                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16845         {
16846           rloc.is_ip4 = 1;
16847
16848           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16849           rloc.weight = 0;
16850           vec_add1 (lcl_locs, rloc);
16851
16852           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16853           vec_add1 (rmt_locs, rloc);
16854           /* weight saved in rmt loc */
16855           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16856         }
16857       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16858                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16859         {
16860           rloc.is_ip4 = 0;
16861           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16862           rloc.weight = 0;
16863           vec_add1 (lcl_locs, rloc);
16864
16865           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16866           vec_add1 (rmt_locs, rloc);
16867           /* weight saved in rmt loc */
16868           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16869         }
16870       else if (unformat (input, "action %d", &action))
16871         {
16872           ;
16873         }
16874       else
16875         {
16876           clib_warning ("parse error '%U'", format_unformat_error, input);
16877           return -99;
16878         }
16879     }
16880
16881   if (!rmt_eid_set)
16882     {
16883       errmsg ("remote eid addresses not set");
16884       return -99;
16885     }
16886
16887   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16888     {
16889       errmsg ("eid types don't match");
16890       return -99;
16891     }
16892
16893   if (0 == rmt_locs && (u32) ~ 0 == action)
16894     {
16895       errmsg ("action not set for negative mapping");
16896       return -99;
16897     }
16898
16899   /* Construct the API message */
16900   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16901       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16902
16903   mp->is_add = is_add;
16904   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16905   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16906   mp->eid_type = rmt_eid->type;
16907   mp->dp_table = clib_host_to_net_u32 (dp_table);
16908   mp->vni = clib_host_to_net_u32 (vni);
16909   mp->rmt_len = rmt_eid->len;
16910   mp->lcl_len = lcl_eid->len;
16911   mp->action = action;
16912
16913   if (0 != rmt_locs && 0 != lcl_locs)
16914     {
16915       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16916       clib_memcpy (mp->locs, lcl_locs,
16917                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16918
16919       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16920       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16921                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16922     }
16923   vec_free (lcl_locs);
16924   vec_free (rmt_locs);
16925
16926   /* send it... */
16927   S (mp);
16928
16929   /* Wait for a reply... */
16930   W (ret);
16931   return ret;
16932 }
16933
16934 static int
16935 api_one_add_del_map_server (vat_main_t * vam)
16936 {
16937   unformat_input_t *input = vam->input;
16938   vl_api_one_add_del_map_server_t *mp;
16939   u8 is_add = 1;
16940   u8 ipv4_set = 0;
16941   u8 ipv6_set = 0;
16942   ip4_address_t ipv4;
16943   ip6_address_t ipv6;
16944   int ret;
16945
16946   /* Parse args required to build the message */
16947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16948     {
16949       if (unformat (input, "del"))
16950         {
16951           is_add = 0;
16952         }
16953       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16954         {
16955           ipv4_set = 1;
16956         }
16957       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16958         {
16959           ipv6_set = 1;
16960         }
16961       else
16962         break;
16963     }
16964
16965   if (ipv4_set && ipv6_set)
16966     {
16967       errmsg ("both eid v4 and v6 addresses set");
16968       return -99;
16969     }
16970
16971   if (!ipv4_set && !ipv6_set)
16972     {
16973       errmsg ("eid addresses not set");
16974       return -99;
16975     }
16976
16977   /* Construct the API message */
16978   M (ONE_ADD_DEL_MAP_SERVER, mp);
16979
16980   mp->is_add = is_add;
16981   if (ipv6_set)
16982     {
16983       mp->is_ipv6 = 1;
16984       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16985     }
16986   else
16987     {
16988       mp->is_ipv6 = 0;
16989       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16990     }
16991
16992   /* send it... */
16993   S (mp);
16994
16995   /* Wait for a reply... */
16996   W (ret);
16997   return ret;
16998 }
16999
17000 #define api_lisp_add_del_map_server api_one_add_del_map_server
17001
17002 static int
17003 api_one_add_del_map_resolver (vat_main_t * vam)
17004 {
17005   unformat_input_t *input = vam->input;
17006   vl_api_one_add_del_map_resolver_t *mp;
17007   u8 is_add = 1;
17008   u8 ipv4_set = 0;
17009   u8 ipv6_set = 0;
17010   ip4_address_t ipv4;
17011   ip6_address_t ipv6;
17012   int ret;
17013
17014   /* Parse args required to build the message */
17015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17016     {
17017       if (unformat (input, "del"))
17018         {
17019           is_add = 0;
17020         }
17021       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17022         {
17023           ipv4_set = 1;
17024         }
17025       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17026         {
17027           ipv6_set = 1;
17028         }
17029       else
17030         break;
17031     }
17032
17033   if (ipv4_set && ipv6_set)
17034     {
17035       errmsg ("both eid v4 and v6 addresses set");
17036       return -99;
17037     }
17038
17039   if (!ipv4_set && !ipv6_set)
17040     {
17041       errmsg ("eid addresses not set");
17042       return -99;
17043     }
17044
17045   /* Construct the API message */
17046   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17047
17048   mp->is_add = is_add;
17049   if (ipv6_set)
17050     {
17051       mp->is_ipv6 = 1;
17052       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17053     }
17054   else
17055     {
17056       mp->is_ipv6 = 0;
17057       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17058     }
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17069
17070 static int
17071 api_lisp_gpe_enable_disable (vat_main_t * vam)
17072 {
17073   unformat_input_t *input = vam->input;
17074   vl_api_gpe_enable_disable_t *mp;
17075   u8 is_set = 0;
17076   u8 is_en = 1;
17077   int ret;
17078
17079   /* Parse args required to build the message */
17080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17081     {
17082       if (unformat (input, "enable"))
17083         {
17084           is_set = 1;
17085           is_en = 1;
17086         }
17087       else if (unformat (input, "disable"))
17088         {
17089           is_set = 1;
17090           is_en = 0;
17091         }
17092       else
17093         break;
17094     }
17095
17096   if (is_set == 0)
17097     {
17098       errmsg ("Value not set");
17099       return -99;
17100     }
17101
17102   /* Construct the API message */
17103   M (GPE_ENABLE_DISABLE, mp);
17104
17105   mp->is_en = is_en;
17106
17107   /* send it... */
17108   S (mp);
17109
17110   /* Wait for a reply... */
17111   W (ret);
17112   return ret;
17113 }
17114
17115 static int
17116 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17117 {
17118   unformat_input_t *input = vam->input;
17119   vl_api_one_rloc_probe_enable_disable_t *mp;
17120   u8 is_set = 0;
17121   u8 is_en = 0;
17122   int ret;
17123
17124   /* Parse args required to build the message */
17125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17126     {
17127       if (unformat (input, "enable"))
17128         {
17129           is_set = 1;
17130           is_en = 1;
17131         }
17132       else if (unformat (input, "disable"))
17133         is_set = 1;
17134       else
17135         break;
17136     }
17137
17138   if (!is_set)
17139     {
17140       errmsg ("Value not set");
17141       return -99;
17142     }
17143
17144   /* Construct the API message */
17145   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17146
17147   mp->is_enabled = is_en;
17148
17149   /* send it... */
17150   S (mp);
17151
17152   /* Wait for a reply... */
17153   W (ret);
17154   return ret;
17155 }
17156
17157 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17158
17159 static int
17160 api_one_map_register_enable_disable (vat_main_t * vam)
17161 {
17162   unformat_input_t *input = vam->input;
17163   vl_api_one_map_register_enable_disable_t *mp;
17164   u8 is_set = 0;
17165   u8 is_en = 0;
17166   int ret;
17167
17168   /* Parse args required to build the message */
17169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17170     {
17171       if (unformat (input, "enable"))
17172         {
17173           is_set = 1;
17174           is_en = 1;
17175         }
17176       else if (unformat (input, "disable"))
17177         is_set = 1;
17178       else
17179         break;
17180     }
17181
17182   if (!is_set)
17183     {
17184       errmsg ("Value not set");
17185       return -99;
17186     }
17187
17188   /* Construct the API message */
17189   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17190
17191   mp->is_enabled = is_en;
17192
17193   /* send it... */
17194   S (mp);
17195
17196   /* Wait for a reply... */
17197   W (ret);
17198   return ret;
17199 }
17200
17201 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17202
17203 static int
17204 api_one_enable_disable (vat_main_t * vam)
17205 {
17206   unformat_input_t *input = vam->input;
17207   vl_api_one_enable_disable_t *mp;
17208   u8 is_set = 0;
17209   u8 is_en = 0;
17210   int ret;
17211
17212   /* Parse args required to build the message */
17213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17214     {
17215       if (unformat (input, "enable"))
17216         {
17217           is_set = 1;
17218           is_en = 1;
17219         }
17220       else if (unformat (input, "disable"))
17221         {
17222           is_set = 1;
17223         }
17224       else
17225         break;
17226     }
17227
17228   if (!is_set)
17229     {
17230       errmsg ("Value not set");
17231       return -99;
17232     }
17233
17234   /* Construct the API message */
17235   M (ONE_ENABLE_DISABLE, mp);
17236
17237   mp->is_en = is_en;
17238
17239   /* send it... */
17240   S (mp);
17241
17242   /* Wait for a reply... */
17243   W (ret);
17244   return ret;
17245 }
17246
17247 #define api_lisp_enable_disable api_one_enable_disable
17248
17249 static int
17250 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17251 {
17252   unformat_input_t *input = vam->input;
17253   vl_api_one_enable_disable_xtr_mode_t *mp;
17254   u8 is_set = 0;
17255   u8 is_en = 0;
17256   int ret;
17257
17258   /* Parse args required to build the message */
17259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17260     {
17261       if (unformat (input, "enable"))
17262         {
17263           is_set = 1;
17264           is_en = 1;
17265         }
17266       else if (unformat (input, "disable"))
17267         {
17268           is_set = 1;
17269         }
17270       else
17271         break;
17272     }
17273
17274   if (!is_set)
17275     {
17276       errmsg ("Value not set");
17277       return -99;
17278     }
17279
17280   /* Construct the API message */
17281   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17282
17283   mp->is_en = is_en;
17284
17285   /* send it... */
17286   S (mp);
17287
17288   /* Wait for a reply... */
17289   W (ret);
17290   return ret;
17291 }
17292
17293 static int
17294 api_one_show_xtr_mode (vat_main_t * vam)
17295 {
17296   vl_api_one_show_xtr_mode_t *mp;
17297   int ret;
17298
17299   /* Construct the API message */
17300   M (ONE_SHOW_XTR_MODE, mp);
17301
17302   /* send it... */
17303   S (mp);
17304
17305   /* Wait for a reply... */
17306   W (ret);
17307   return ret;
17308 }
17309
17310 static int
17311 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17312 {
17313   unformat_input_t *input = vam->input;
17314   vl_api_one_enable_disable_pitr_mode_t *mp;
17315   u8 is_set = 0;
17316   u8 is_en = 0;
17317   int ret;
17318
17319   /* Parse args required to build the message */
17320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17321     {
17322       if (unformat (input, "enable"))
17323         {
17324           is_set = 1;
17325           is_en = 1;
17326         }
17327       else if (unformat (input, "disable"))
17328         {
17329           is_set = 1;
17330         }
17331       else
17332         break;
17333     }
17334
17335   if (!is_set)
17336     {
17337       errmsg ("Value not set");
17338       return -99;
17339     }
17340
17341   /* Construct the API message */
17342   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17343
17344   mp->is_en = is_en;
17345
17346   /* send it... */
17347   S (mp);
17348
17349   /* Wait for a reply... */
17350   W (ret);
17351   return ret;
17352 }
17353
17354 static int
17355 api_one_show_pitr_mode (vat_main_t * vam)
17356 {
17357   vl_api_one_show_pitr_mode_t *mp;
17358   int ret;
17359
17360   /* Construct the API message */
17361   M (ONE_SHOW_PITR_MODE, mp);
17362
17363   /* send it... */
17364   S (mp);
17365
17366   /* Wait for a reply... */
17367   W (ret);
17368   return ret;
17369 }
17370
17371 static int
17372 api_one_enable_disable_petr_mode (vat_main_t * vam)
17373 {
17374   unformat_input_t *input = vam->input;
17375   vl_api_one_enable_disable_petr_mode_t *mp;
17376   u8 is_set = 0;
17377   u8 is_en = 0;
17378   int ret;
17379
17380   /* Parse args required to build the message */
17381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17382     {
17383       if (unformat (input, "enable"))
17384         {
17385           is_set = 1;
17386           is_en = 1;
17387         }
17388       else if (unformat (input, "disable"))
17389         {
17390           is_set = 1;
17391         }
17392       else
17393         break;
17394     }
17395
17396   if (!is_set)
17397     {
17398       errmsg ("Value not set");
17399       return -99;
17400     }
17401
17402   /* Construct the API message */
17403   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17404
17405   mp->is_en = is_en;
17406
17407   /* send it... */
17408   S (mp);
17409
17410   /* Wait for a reply... */
17411   W (ret);
17412   return ret;
17413 }
17414
17415 static int
17416 api_one_show_petr_mode (vat_main_t * vam)
17417 {
17418   vl_api_one_show_petr_mode_t *mp;
17419   int ret;
17420
17421   /* Construct the API message */
17422   M (ONE_SHOW_PETR_MODE, mp);
17423
17424   /* send it... */
17425   S (mp);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 static int
17433 api_show_one_map_register_state (vat_main_t * vam)
17434 {
17435   vl_api_show_one_map_register_state_t *mp;
17436   int ret;
17437
17438   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17439
17440   /* send */
17441   S (mp);
17442
17443   /* wait for reply */
17444   W (ret);
17445   return ret;
17446 }
17447
17448 #define api_show_lisp_map_register_state api_show_one_map_register_state
17449
17450 static int
17451 api_show_one_rloc_probe_state (vat_main_t * vam)
17452 {
17453   vl_api_show_one_rloc_probe_state_t *mp;
17454   int ret;
17455
17456   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17457
17458   /* send */
17459   S (mp);
17460
17461   /* wait for reply */
17462   W (ret);
17463   return ret;
17464 }
17465
17466 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17467
17468 static int
17469 api_one_add_del_ndp_entry (vat_main_t * vam)
17470 {
17471   vl_api_one_add_del_ndp_entry_t *mp;
17472   unformat_input_t *input = vam->input;
17473   u8 is_add = 1;
17474   u8 mac_set = 0;
17475   u8 bd_set = 0;
17476   u8 ip_set = 0;
17477   u8 mac[6] = { 0, };
17478   u8 ip6[16] = { 0, };
17479   u32 bd = ~0;
17480   int ret;
17481
17482   /* Parse args required to build the message */
17483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17484     {
17485       if (unformat (input, "del"))
17486         is_add = 0;
17487       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17488         mac_set = 1;
17489       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17490         ip_set = 1;
17491       else if (unformat (input, "bd %d", &bd))
17492         bd_set = 1;
17493       else
17494         {
17495           errmsg ("parse error '%U'", format_unformat_error, input);
17496           return -99;
17497         }
17498     }
17499
17500   if (!bd_set || !ip_set || (!mac_set && is_add))
17501     {
17502       errmsg ("Missing BD, IP or MAC!");
17503       return -99;
17504     }
17505
17506   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17507   mp->is_add = is_add;
17508   clib_memcpy (mp->mac, mac, 6);
17509   mp->bd = clib_host_to_net_u32 (bd);
17510   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17511
17512   /* send */
17513   S (mp);
17514
17515   /* wait for reply */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 static int
17521 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17522 {
17523   vl_api_one_add_del_l2_arp_entry_t *mp;
17524   unformat_input_t *input = vam->input;
17525   u8 is_add = 1;
17526   u8 mac_set = 0;
17527   u8 bd_set = 0;
17528   u8 ip_set = 0;
17529   u8 mac[6] = { 0, };
17530   u32 ip4 = 0, bd = ~0;
17531   int ret;
17532
17533   /* Parse args required to build the message */
17534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17535     {
17536       if (unformat (input, "del"))
17537         is_add = 0;
17538       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17539         mac_set = 1;
17540       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17541         ip_set = 1;
17542       else if (unformat (input, "bd %d", &bd))
17543         bd_set = 1;
17544       else
17545         {
17546           errmsg ("parse error '%U'", format_unformat_error, input);
17547           return -99;
17548         }
17549     }
17550
17551   if (!bd_set || !ip_set || (!mac_set && is_add))
17552     {
17553       errmsg ("Missing BD, IP or MAC!");
17554       return -99;
17555     }
17556
17557   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17558   mp->is_add = is_add;
17559   clib_memcpy (mp->mac, mac, 6);
17560   mp->bd = clib_host_to_net_u32 (bd);
17561   mp->ip4 = ip4;
17562
17563   /* send */
17564   S (mp);
17565
17566   /* wait for reply */
17567   W (ret);
17568   return ret;
17569 }
17570
17571 static int
17572 api_one_ndp_bd_get (vat_main_t * vam)
17573 {
17574   vl_api_one_ndp_bd_get_t *mp;
17575   int ret;
17576
17577   M (ONE_NDP_BD_GET, mp);
17578
17579   /* send */
17580   S (mp);
17581
17582   /* wait for reply */
17583   W (ret);
17584   return ret;
17585 }
17586
17587 static int
17588 api_one_ndp_entries_get (vat_main_t * vam)
17589 {
17590   vl_api_one_ndp_entries_get_t *mp;
17591   unformat_input_t *input = vam->input;
17592   u8 bd_set = 0;
17593   u32 bd = ~0;
17594   int ret;
17595
17596   /* Parse args required to build the message */
17597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17598     {
17599       if (unformat (input, "bd %d", &bd))
17600         bd_set = 1;
17601       else
17602         {
17603           errmsg ("parse error '%U'", format_unformat_error, input);
17604           return -99;
17605         }
17606     }
17607
17608   if (!bd_set)
17609     {
17610       errmsg ("Expected bridge domain!");
17611       return -99;
17612     }
17613
17614   M (ONE_NDP_ENTRIES_GET, mp);
17615   mp->bd = clib_host_to_net_u32 (bd);
17616
17617   /* send */
17618   S (mp);
17619
17620   /* wait for reply */
17621   W (ret);
17622   return ret;
17623 }
17624
17625 static int
17626 api_one_l2_arp_bd_get (vat_main_t * vam)
17627 {
17628   vl_api_one_l2_arp_bd_get_t *mp;
17629   int ret;
17630
17631   M (ONE_L2_ARP_BD_GET, mp);
17632
17633   /* send */
17634   S (mp);
17635
17636   /* wait for reply */
17637   W (ret);
17638   return ret;
17639 }
17640
17641 static int
17642 api_one_l2_arp_entries_get (vat_main_t * vam)
17643 {
17644   vl_api_one_l2_arp_entries_get_t *mp;
17645   unformat_input_t *input = vam->input;
17646   u8 bd_set = 0;
17647   u32 bd = ~0;
17648   int ret;
17649
17650   /* Parse args required to build the message */
17651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17652     {
17653       if (unformat (input, "bd %d", &bd))
17654         bd_set = 1;
17655       else
17656         {
17657           errmsg ("parse error '%U'", format_unformat_error, input);
17658           return -99;
17659         }
17660     }
17661
17662   if (!bd_set)
17663     {
17664       errmsg ("Expected bridge domain!");
17665       return -99;
17666     }
17667
17668   M (ONE_L2_ARP_ENTRIES_GET, mp);
17669   mp->bd = clib_host_to_net_u32 (bd);
17670
17671   /* send */
17672   S (mp);
17673
17674   /* wait for reply */
17675   W (ret);
17676   return ret;
17677 }
17678
17679 static int
17680 api_one_stats_enable_disable (vat_main_t * vam)
17681 {
17682   vl_api_one_stats_enable_disable_t *mp;
17683   unformat_input_t *input = vam->input;
17684   u8 is_set = 0;
17685   u8 is_en = 0;
17686   int ret;
17687
17688   /* Parse args required to build the message */
17689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17690     {
17691       if (unformat (input, "enable"))
17692         {
17693           is_set = 1;
17694           is_en = 1;
17695         }
17696       else if (unformat (input, "disable"))
17697         {
17698           is_set = 1;
17699         }
17700       else
17701         break;
17702     }
17703
17704   if (!is_set)
17705     {
17706       errmsg ("Value not set");
17707       return -99;
17708     }
17709
17710   M (ONE_STATS_ENABLE_DISABLE, mp);
17711   mp->is_en = is_en;
17712
17713   /* send */
17714   S (mp);
17715
17716   /* wait for reply */
17717   W (ret);
17718   return ret;
17719 }
17720
17721 static int
17722 api_show_one_stats_enable_disable (vat_main_t * vam)
17723 {
17724   vl_api_show_one_stats_enable_disable_t *mp;
17725   int ret;
17726
17727   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17728
17729   /* send */
17730   S (mp);
17731
17732   /* wait for reply */
17733   W (ret);
17734   return ret;
17735 }
17736
17737 static int
17738 api_show_one_map_request_mode (vat_main_t * vam)
17739 {
17740   vl_api_show_one_map_request_mode_t *mp;
17741   int ret;
17742
17743   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17744
17745   /* send */
17746   S (mp);
17747
17748   /* wait for reply */
17749   W (ret);
17750   return ret;
17751 }
17752
17753 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17754
17755 static int
17756 api_one_map_request_mode (vat_main_t * vam)
17757 {
17758   unformat_input_t *input = vam->input;
17759   vl_api_one_map_request_mode_t *mp;
17760   u8 mode = 0;
17761   int ret;
17762
17763   /* Parse args required to build the message */
17764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17765     {
17766       if (unformat (input, "dst-only"))
17767         mode = 0;
17768       else if (unformat (input, "src-dst"))
17769         mode = 1;
17770       else
17771         {
17772           errmsg ("parse error '%U'", format_unformat_error, input);
17773           return -99;
17774         }
17775     }
17776
17777   M (ONE_MAP_REQUEST_MODE, mp);
17778
17779   mp->mode = mode;
17780
17781   /* send */
17782   S (mp);
17783
17784   /* wait for reply */
17785   W (ret);
17786   return ret;
17787 }
17788
17789 #define api_lisp_map_request_mode api_one_map_request_mode
17790
17791 /**
17792  * Enable/disable ONE proxy ITR.
17793  *
17794  * @param vam vpp API test context
17795  * @return return code
17796  */
17797 static int
17798 api_one_pitr_set_locator_set (vat_main_t * vam)
17799 {
17800   u8 ls_name_set = 0;
17801   unformat_input_t *input = vam->input;
17802   vl_api_one_pitr_set_locator_set_t *mp;
17803   u8 is_add = 1;
17804   u8 *ls_name = 0;
17805   int ret;
17806
17807   /* Parse args required to build the message */
17808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17809     {
17810       if (unformat (input, "del"))
17811         is_add = 0;
17812       else if (unformat (input, "locator-set %s", &ls_name))
17813         ls_name_set = 1;
17814       else
17815         {
17816           errmsg ("parse error '%U'", format_unformat_error, input);
17817           return -99;
17818         }
17819     }
17820
17821   if (!ls_name_set)
17822     {
17823       errmsg ("locator-set name not set!");
17824       return -99;
17825     }
17826
17827   M (ONE_PITR_SET_LOCATOR_SET, mp);
17828
17829   mp->is_add = is_add;
17830   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17831   vec_free (ls_name);
17832
17833   /* send */
17834   S (mp);
17835
17836   /* wait for reply */
17837   W (ret);
17838   return ret;
17839 }
17840
17841 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17842
17843 static int
17844 api_one_nsh_set_locator_set (vat_main_t * vam)
17845 {
17846   u8 ls_name_set = 0;
17847   unformat_input_t *input = vam->input;
17848   vl_api_one_nsh_set_locator_set_t *mp;
17849   u8 is_add = 1;
17850   u8 *ls_name = 0;
17851   int ret;
17852
17853   /* Parse args required to build the message */
17854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17855     {
17856       if (unformat (input, "del"))
17857         is_add = 0;
17858       else if (unformat (input, "ls %s", &ls_name))
17859         ls_name_set = 1;
17860       else
17861         {
17862           errmsg ("parse error '%U'", format_unformat_error, input);
17863           return -99;
17864         }
17865     }
17866
17867   if (!ls_name_set && is_add)
17868     {
17869       errmsg ("locator-set name not set!");
17870       return -99;
17871     }
17872
17873   M (ONE_NSH_SET_LOCATOR_SET, mp);
17874
17875   mp->is_add = is_add;
17876   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17877   vec_free (ls_name);
17878
17879   /* send */
17880   S (mp);
17881
17882   /* wait for reply */
17883   W (ret);
17884   return ret;
17885 }
17886
17887 static int
17888 api_show_one_pitr (vat_main_t * vam)
17889 {
17890   vl_api_show_one_pitr_t *mp;
17891   int ret;
17892
17893   if (!vam->json_output)
17894     {
17895       print (vam->ofp, "%=20s", "lisp status:");
17896     }
17897
17898   M (SHOW_ONE_PITR, mp);
17899   /* send it... */
17900   S (mp);
17901
17902   /* Wait for a reply... */
17903   W (ret);
17904   return ret;
17905 }
17906
17907 #define api_show_lisp_pitr api_show_one_pitr
17908
17909 static int
17910 api_one_use_petr (vat_main_t * vam)
17911 {
17912   unformat_input_t *input = vam->input;
17913   vl_api_one_use_petr_t *mp;
17914   u8 is_add = 0;
17915   ip_address_t ip;
17916   int ret;
17917
17918   clib_memset (&ip, 0, sizeof (ip));
17919
17920   /* Parse args required to build the message */
17921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17922     {
17923       if (unformat (input, "disable"))
17924         is_add = 0;
17925       else
17926         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17927         {
17928           is_add = 1;
17929           ip_addr_version (&ip) = IP4;
17930         }
17931       else
17932         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17933         {
17934           is_add = 1;
17935           ip_addr_version (&ip) = IP6;
17936         }
17937       else
17938         {
17939           errmsg ("parse error '%U'", format_unformat_error, input);
17940           return -99;
17941         }
17942     }
17943
17944   M (ONE_USE_PETR, mp);
17945
17946   mp->is_add = is_add;
17947   if (is_add)
17948     {
17949       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17950       if (mp->is_ip4)
17951         clib_memcpy (mp->address, &ip, 4);
17952       else
17953         clib_memcpy (mp->address, &ip, 16);
17954     }
17955
17956   /* send */
17957   S (mp);
17958
17959   /* wait for reply */
17960   W (ret);
17961   return ret;
17962 }
17963
17964 #define api_lisp_use_petr api_one_use_petr
17965
17966 static int
17967 api_show_one_nsh_mapping (vat_main_t * vam)
17968 {
17969   vl_api_show_one_use_petr_t *mp;
17970   int ret;
17971
17972   if (!vam->json_output)
17973     {
17974       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17975     }
17976
17977   M (SHOW_ONE_NSH_MAPPING, mp);
17978   /* send it... */
17979   S (mp);
17980
17981   /* Wait for a reply... */
17982   W (ret);
17983   return ret;
17984 }
17985
17986 static int
17987 api_show_one_use_petr (vat_main_t * vam)
17988 {
17989   vl_api_show_one_use_petr_t *mp;
17990   int ret;
17991
17992   if (!vam->json_output)
17993     {
17994       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17995     }
17996
17997   M (SHOW_ONE_USE_PETR, mp);
17998   /* send it... */
17999   S (mp);
18000
18001   /* Wait for a reply... */
18002   W (ret);
18003   return ret;
18004 }
18005
18006 #define api_show_lisp_use_petr api_show_one_use_petr
18007
18008 /**
18009  * Add/delete mapping between vni and vrf
18010  */
18011 static int
18012 api_one_eid_table_add_del_map (vat_main_t * vam)
18013 {
18014   unformat_input_t *input = vam->input;
18015   vl_api_one_eid_table_add_del_map_t *mp;
18016   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18017   u32 vni, vrf, bd_index;
18018   int ret;
18019
18020   /* Parse args required to build the message */
18021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18022     {
18023       if (unformat (input, "del"))
18024         is_add = 0;
18025       else if (unformat (input, "vrf %d", &vrf))
18026         vrf_set = 1;
18027       else if (unformat (input, "bd_index %d", &bd_index))
18028         bd_index_set = 1;
18029       else if (unformat (input, "vni %d", &vni))
18030         vni_set = 1;
18031       else
18032         break;
18033     }
18034
18035   if (!vni_set || (!vrf_set && !bd_index_set))
18036     {
18037       errmsg ("missing arguments!");
18038       return -99;
18039     }
18040
18041   if (vrf_set && bd_index_set)
18042     {
18043       errmsg ("error: both vrf and bd entered!");
18044       return -99;
18045     }
18046
18047   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18048
18049   mp->is_add = is_add;
18050   mp->vni = htonl (vni);
18051   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18052   mp->is_l2 = bd_index_set;
18053
18054   /* send */
18055   S (mp);
18056
18057   /* wait for reply */
18058   W (ret);
18059   return ret;
18060 }
18061
18062 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18063
18064 uword
18065 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18066 {
18067   u32 *action = va_arg (*args, u32 *);
18068   u8 *s = 0;
18069
18070   if (unformat (input, "%s", &s))
18071     {
18072       if (!strcmp ((char *) s, "no-action"))
18073         action[0] = 0;
18074       else if (!strcmp ((char *) s, "natively-forward"))
18075         action[0] = 1;
18076       else if (!strcmp ((char *) s, "send-map-request"))
18077         action[0] = 2;
18078       else if (!strcmp ((char *) s, "drop"))
18079         action[0] = 3;
18080       else
18081         {
18082           clib_warning ("invalid action: '%s'", s);
18083           action[0] = 3;
18084         }
18085     }
18086   else
18087     return 0;
18088
18089   vec_free (s);
18090   return 1;
18091 }
18092
18093 /**
18094  * Add/del remote mapping to/from ONE control plane
18095  *
18096  * @param vam vpp API test context
18097  * @return return code
18098  */
18099 static int
18100 api_one_add_del_remote_mapping (vat_main_t * vam)
18101 {
18102   unformat_input_t *input = vam->input;
18103   vl_api_one_add_del_remote_mapping_t *mp;
18104   u32 vni = 0;
18105   lisp_eid_vat_t _eid, *eid = &_eid;
18106   lisp_eid_vat_t _seid, *seid = &_seid;
18107   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18108   u32 action = ~0, p, w, data_len;
18109   ip4_address_t rloc4;
18110   ip6_address_t rloc6;
18111   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18112   int ret;
18113
18114   clib_memset (&rloc, 0, sizeof (rloc));
18115
18116   /* Parse args required to build the message */
18117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (input, "del-all"))
18120         {
18121           del_all = 1;
18122         }
18123       else if (unformat (input, "del"))
18124         {
18125           is_add = 0;
18126         }
18127       else if (unformat (input, "add"))
18128         {
18129           is_add = 1;
18130         }
18131       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18132         {
18133           eid_set = 1;
18134         }
18135       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18136         {
18137           seid_set = 1;
18138         }
18139       else if (unformat (input, "vni %d", &vni))
18140         {
18141           ;
18142         }
18143       else if (unformat (input, "p %d w %d", &p, &w))
18144         {
18145           if (!curr_rloc)
18146             {
18147               errmsg ("No RLOC configured for setting priority/weight!");
18148               return -99;
18149             }
18150           curr_rloc->priority = p;
18151           curr_rloc->weight = w;
18152         }
18153       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18154         {
18155           rloc.is_ip4 = 1;
18156           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18157           vec_add1 (rlocs, rloc);
18158           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18159         }
18160       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18161         {
18162           rloc.is_ip4 = 0;
18163           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18164           vec_add1 (rlocs, rloc);
18165           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18166         }
18167       else if (unformat (input, "action %U",
18168                          unformat_negative_mapping_action, &action))
18169         {
18170           ;
18171         }
18172       else
18173         {
18174           clib_warning ("parse error '%U'", format_unformat_error, input);
18175           return -99;
18176         }
18177     }
18178
18179   if (0 == eid_set)
18180     {
18181       errmsg ("missing params!");
18182       return -99;
18183     }
18184
18185   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18186     {
18187       errmsg ("no action set for negative map-reply!");
18188       return -99;
18189     }
18190
18191   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18192
18193   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18194   mp->is_add = is_add;
18195   mp->vni = htonl (vni);
18196   mp->action = (u8) action;
18197   mp->is_src_dst = seid_set;
18198   mp->eid_len = eid->len;
18199   mp->seid_len = seid->len;
18200   mp->del_all = del_all;
18201   mp->eid_type = eid->type;
18202   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18203   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18204
18205   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18206   clib_memcpy (mp->rlocs, rlocs, data_len);
18207   vec_free (rlocs);
18208
18209   /* send it... */
18210   S (mp);
18211
18212   /* Wait for a reply... */
18213   W (ret);
18214   return ret;
18215 }
18216
18217 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18218
18219 /**
18220  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18221  * forwarding entries in data-plane accordingly.
18222  *
18223  * @param vam vpp API test context
18224  * @return return code
18225  */
18226 static int
18227 api_one_add_del_adjacency (vat_main_t * vam)
18228 {
18229   unformat_input_t *input = vam->input;
18230   vl_api_one_add_del_adjacency_t *mp;
18231   u32 vni = 0;
18232   ip4_address_t leid4, reid4;
18233   ip6_address_t leid6, reid6;
18234   u8 reid_mac[6] = { 0 };
18235   u8 leid_mac[6] = { 0 };
18236   u8 reid_type, leid_type;
18237   u32 leid_len = 0, reid_len = 0, len;
18238   u8 is_add = 1;
18239   int ret;
18240
18241   leid_type = reid_type = (u8) ~ 0;
18242
18243   /* Parse args required to build the message */
18244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18245     {
18246       if (unformat (input, "del"))
18247         {
18248           is_add = 0;
18249         }
18250       else if (unformat (input, "add"))
18251         {
18252           is_add = 1;
18253         }
18254       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18255                          &reid4, &len))
18256         {
18257           reid_type = 0;        /* ipv4 */
18258           reid_len = len;
18259         }
18260       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18261                          &reid6, &len))
18262         {
18263           reid_type = 1;        /* ipv6 */
18264           reid_len = len;
18265         }
18266       else if (unformat (input, "reid %U", unformat_ethernet_address,
18267                          reid_mac))
18268         {
18269           reid_type = 2;        /* mac */
18270         }
18271       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18272                          &leid4, &len))
18273         {
18274           leid_type = 0;        /* ipv4 */
18275           leid_len = len;
18276         }
18277       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18278                          &leid6, &len))
18279         {
18280           leid_type = 1;        /* ipv6 */
18281           leid_len = len;
18282         }
18283       else if (unformat (input, "leid %U", unformat_ethernet_address,
18284                          leid_mac))
18285         {
18286           leid_type = 2;        /* mac */
18287         }
18288       else if (unformat (input, "vni %d", &vni))
18289         {
18290           ;
18291         }
18292       else
18293         {
18294           errmsg ("parse error '%U'", format_unformat_error, input);
18295           return -99;
18296         }
18297     }
18298
18299   if ((u8) ~ 0 == reid_type)
18300     {
18301       errmsg ("missing params!");
18302       return -99;
18303     }
18304
18305   if (leid_type != reid_type)
18306     {
18307       errmsg ("remote and local EIDs are of different types!");
18308       return -99;
18309     }
18310
18311   M (ONE_ADD_DEL_ADJACENCY, mp);
18312   mp->is_add = is_add;
18313   mp->vni = htonl (vni);
18314   mp->leid_len = leid_len;
18315   mp->reid_len = reid_len;
18316   mp->eid_type = reid_type;
18317
18318   switch (mp->eid_type)
18319     {
18320     case 0:
18321       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18322       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18323       break;
18324     case 1:
18325       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18326       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18327       break;
18328     case 2:
18329       clib_memcpy (mp->leid, leid_mac, 6);
18330       clib_memcpy (mp->reid, reid_mac, 6);
18331       break;
18332     default:
18333       errmsg ("unknown EID type %d!", mp->eid_type);
18334       return 0;
18335     }
18336
18337   /* send it... */
18338   S (mp);
18339
18340   /* Wait for a reply... */
18341   W (ret);
18342   return ret;
18343 }
18344
18345 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18346
18347 uword
18348 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18349 {
18350   u32 *mode = va_arg (*args, u32 *);
18351
18352   if (unformat (input, "lisp"))
18353     *mode = 0;
18354   else if (unformat (input, "vxlan"))
18355     *mode = 1;
18356   else
18357     return 0;
18358
18359   return 1;
18360 }
18361
18362 static int
18363 api_gpe_get_encap_mode (vat_main_t * vam)
18364 {
18365   vl_api_gpe_get_encap_mode_t *mp;
18366   int ret;
18367
18368   /* Construct the API message */
18369   M (GPE_GET_ENCAP_MODE, mp);
18370
18371   /* send it... */
18372   S (mp);
18373
18374   /* Wait for a reply... */
18375   W (ret);
18376   return ret;
18377 }
18378
18379 static int
18380 api_gpe_set_encap_mode (vat_main_t * vam)
18381 {
18382   unformat_input_t *input = vam->input;
18383   vl_api_gpe_set_encap_mode_t *mp;
18384   int ret;
18385   u32 mode = 0;
18386
18387   /* Parse args required to build the message */
18388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18389     {
18390       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18391         ;
18392       else
18393         break;
18394     }
18395
18396   /* Construct the API message */
18397   M (GPE_SET_ENCAP_MODE, mp);
18398
18399   mp->mode = mode;
18400
18401   /* send it... */
18402   S (mp);
18403
18404   /* Wait for a reply... */
18405   W (ret);
18406   return ret;
18407 }
18408
18409 static int
18410 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18411 {
18412   unformat_input_t *input = vam->input;
18413   vl_api_gpe_add_del_iface_t *mp;
18414   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18415   u32 dp_table = 0, vni = 0;
18416   int ret;
18417
18418   /* Parse args required to build the message */
18419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18420     {
18421       if (unformat (input, "up"))
18422         {
18423           action_set = 1;
18424           is_add = 1;
18425         }
18426       else if (unformat (input, "down"))
18427         {
18428           action_set = 1;
18429           is_add = 0;
18430         }
18431       else if (unformat (input, "table_id %d", &dp_table))
18432         {
18433           dp_table_set = 1;
18434         }
18435       else if (unformat (input, "bd_id %d", &dp_table))
18436         {
18437           dp_table_set = 1;
18438           is_l2 = 1;
18439         }
18440       else if (unformat (input, "vni %d", &vni))
18441         {
18442           vni_set = 1;
18443         }
18444       else
18445         break;
18446     }
18447
18448   if (action_set == 0)
18449     {
18450       errmsg ("Action not set");
18451       return -99;
18452     }
18453   if (dp_table_set == 0 || vni_set == 0)
18454     {
18455       errmsg ("vni and dp_table must be set");
18456       return -99;
18457     }
18458
18459   /* Construct the API message */
18460   M (GPE_ADD_DEL_IFACE, mp);
18461
18462   mp->is_add = is_add;
18463   mp->dp_table = clib_host_to_net_u32 (dp_table);
18464   mp->is_l2 = is_l2;
18465   mp->vni = clib_host_to_net_u32 (vni);
18466
18467   /* send it... */
18468   S (mp);
18469
18470   /* Wait for a reply... */
18471   W (ret);
18472   return ret;
18473 }
18474
18475 static int
18476 api_one_map_register_fallback_threshold (vat_main_t * vam)
18477 {
18478   unformat_input_t *input = vam->input;
18479   vl_api_one_map_register_fallback_threshold_t *mp;
18480   u32 value = 0;
18481   u8 is_set = 0;
18482   int ret;
18483
18484   /* Parse args required to build the message */
18485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18486     {
18487       if (unformat (input, "%u", &value))
18488         is_set = 1;
18489       else
18490         {
18491           clib_warning ("parse error '%U'", format_unformat_error, input);
18492           return -99;
18493         }
18494     }
18495
18496   if (!is_set)
18497     {
18498       errmsg ("fallback threshold value is missing!");
18499       return -99;
18500     }
18501
18502   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18503   mp->value = clib_host_to_net_u32 (value);
18504
18505   /* send it... */
18506   S (mp);
18507
18508   /* Wait for a reply... */
18509   W (ret);
18510   return ret;
18511 }
18512
18513 static int
18514 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18515 {
18516   vl_api_show_one_map_register_fallback_threshold_t *mp;
18517   int ret;
18518
18519   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18520
18521   /* send it... */
18522   S (mp);
18523
18524   /* Wait for a reply... */
18525   W (ret);
18526   return ret;
18527 }
18528
18529 uword
18530 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18531 {
18532   u32 *proto = va_arg (*args, u32 *);
18533
18534   if (unformat (input, "udp"))
18535     *proto = 1;
18536   else if (unformat (input, "api"))
18537     *proto = 2;
18538   else
18539     return 0;
18540
18541   return 1;
18542 }
18543
18544 static int
18545 api_one_set_transport_protocol (vat_main_t * vam)
18546 {
18547   unformat_input_t *input = vam->input;
18548   vl_api_one_set_transport_protocol_t *mp;
18549   u8 is_set = 0;
18550   u32 protocol = 0;
18551   int ret;
18552
18553   /* Parse args required to build the message */
18554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18555     {
18556       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18557         is_set = 1;
18558       else
18559         {
18560           clib_warning ("parse error '%U'", format_unformat_error, input);
18561           return -99;
18562         }
18563     }
18564
18565   if (!is_set)
18566     {
18567       errmsg ("Transport protocol missing!");
18568       return -99;
18569     }
18570
18571   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18572   mp->protocol = (u8) protocol;
18573
18574   /* send it... */
18575   S (mp);
18576
18577   /* Wait for a reply... */
18578   W (ret);
18579   return ret;
18580 }
18581
18582 static int
18583 api_one_get_transport_protocol (vat_main_t * vam)
18584 {
18585   vl_api_one_get_transport_protocol_t *mp;
18586   int ret;
18587
18588   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18589
18590   /* send it... */
18591   S (mp);
18592
18593   /* Wait for a reply... */
18594   W (ret);
18595   return ret;
18596 }
18597
18598 static int
18599 api_one_map_register_set_ttl (vat_main_t * vam)
18600 {
18601   unformat_input_t *input = vam->input;
18602   vl_api_one_map_register_set_ttl_t *mp;
18603   u32 ttl = 0;
18604   u8 is_set = 0;
18605   int ret;
18606
18607   /* Parse args required to build the message */
18608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18609     {
18610       if (unformat (input, "%u", &ttl))
18611         is_set = 1;
18612       else
18613         {
18614           clib_warning ("parse error '%U'", format_unformat_error, input);
18615           return -99;
18616         }
18617     }
18618
18619   if (!is_set)
18620     {
18621       errmsg ("TTL value missing!");
18622       return -99;
18623     }
18624
18625   M (ONE_MAP_REGISTER_SET_TTL, mp);
18626   mp->ttl = clib_host_to_net_u32 (ttl);
18627
18628   /* send it... */
18629   S (mp);
18630
18631   /* Wait for a reply... */
18632   W (ret);
18633   return ret;
18634 }
18635
18636 static int
18637 api_show_one_map_register_ttl (vat_main_t * vam)
18638 {
18639   vl_api_show_one_map_register_ttl_t *mp;
18640   int ret;
18641
18642   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18643
18644   /* send it... */
18645   S (mp);
18646
18647   /* Wait for a reply... */
18648   W (ret);
18649   return ret;
18650 }
18651
18652 /**
18653  * Add/del map request itr rlocs from ONE control plane and updates
18654  *
18655  * @param vam vpp API test context
18656  * @return return code
18657  */
18658 static int
18659 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18660 {
18661   unformat_input_t *input = vam->input;
18662   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18663   u8 *locator_set_name = 0;
18664   u8 locator_set_name_set = 0;
18665   u8 is_add = 1;
18666   int ret;
18667
18668   /* Parse args required to build the message */
18669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18670     {
18671       if (unformat (input, "del"))
18672         {
18673           is_add = 0;
18674         }
18675       else if (unformat (input, "%_%v%_", &locator_set_name))
18676         {
18677           locator_set_name_set = 1;
18678         }
18679       else
18680         {
18681           clib_warning ("parse error '%U'", format_unformat_error, input);
18682           return -99;
18683         }
18684     }
18685
18686   if (is_add && !locator_set_name_set)
18687     {
18688       errmsg ("itr-rloc is not set!");
18689       return -99;
18690     }
18691
18692   if (is_add && vec_len (locator_set_name) > 64)
18693     {
18694       errmsg ("itr-rloc locator-set name too long");
18695       vec_free (locator_set_name);
18696       return -99;
18697     }
18698
18699   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18700   mp->is_add = is_add;
18701   if (is_add)
18702     {
18703       clib_memcpy (mp->locator_set_name, locator_set_name,
18704                    vec_len (locator_set_name));
18705     }
18706   else
18707     {
18708       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18709     }
18710   vec_free (locator_set_name);
18711
18712   /* send it... */
18713   S (mp);
18714
18715   /* Wait for a reply... */
18716   W (ret);
18717   return ret;
18718 }
18719
18720 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18721
18722 static int
18723 api_one_locator_dump (vat_main_t * vam)
18724 {
18725   unformat_input_t *input = vam->input;
18726   vl_api_one_locator_dump_t *mp;
18727   vl_api_control_ping_t *mp_ping;
18728   u8 is_index_set = 0, is_name_set = 0;
18729   u8 *ls_name = 0;
18730   u32 ls_index = ~0;
18731   int ret;
18732
18733   /* Parse args required to build the message */
18734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18735     {
18736       if (unformat (input, "ls_name %_%v%_", &ls_name))
18737         {
18738           is_name_set = 1;
18739         }
18740       else if (unformat (input, "ls_index %d", &ls_index))
18741         {
18742           is_index_set = 1;
18743         }
18744       else
18745         {
18746           errmsg ("parse error '%U'", format_unformat_error, input);
18747           return -99;
18748         }
18749     }
18750
18751   if (!is_index_set && !is_name_set)
18752     {
18753       errmsg ("error: expected one of index or name!");
18754       return -99;
18755     }
18756
18757   if (is_index_set && is_name_set)
18758     {
18759       errmsg ("error: only one param expected!");
18760       return -99;
18761     }
18762
18763   if (vec_len (ls_name) > 62)
18764     {
18765       errmsg ("error: locator set name too long!");
18766       return -99;
18767     }
18768
18769   if (!vam->json_output)
18770     {
18771       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18772     }
18773
18774   M (ONE_LOCATOR_DUMP, mp);
18775   mp->is_index_set = is_index_set;
18776
18777   if (is_index_set)
18778     mp->ls_index = clib_host_to_net_u32 (ls_index);
18779   else
18780     {
18781       vec_add1 (ls_name, 0);
18782       strncpy ((char *) mp->ls_name, (char *) ls_name,
18783                sizeof (mp->ls_name) - 1);
18784     }
18785
18786   /* send it... */
18787   S (mp);
18788
18789   /* Use a control ping for synchronization */
18790   MPING (CONTROL_PING, mp_ping);
18791   S (mp_ping);
18792
18793   /* Wait for a reply... */
18794   W (ret);
18795   return ret;
18796 }
18797
18798 #define api_lisp_locator_dump api_one_locator_dump
18799
18800 static int
18801 api_one_locator_set_dump (vat_main_t * vam)
18802 {
18803   vl_api_one_locator_set_dump_t *mp;
18804   vl_api_control_ping_t *mp_ping;
18805   unformat_input_t *input = vam->input;
18806   u8 filter = 0;
18807   int ret;
18808
18809   /* Parse args required to build the message */
18810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18811     {
18812       if (unformat (input, "local"))
18813         {
18814           filter = 1;
18815         }
18816       else if (unformat (input, "remote"))
18817         {
18818           filter = 2;
18819         }
18820       else
18821         {
18822           errmsg ("parse error '%U'", format_unformat_error, input);
18823           return -99;
18824         }
18825     }
18826
18827   if (!vam->json_output)
18828     {
18829       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18830     }
18831
18832   M (ONE_LOCATOR_SET_DUMP, mp);
18833
18834   mp->filter = filter;
18835
18836   /* send it... */
18837   S (mp);
18838
18839   /* Use a control ping for synchronization */
18840   MPING (CONTROL_PING, mp_ping);
18841   S (mp_ping);
18842
18843   /* Wait for a reply... */
18844   W (ret);
18845   return ret;
18846 }
18847
18848 #define api_lisp_locator_set_dump api_one_locator_set_dump
18849
18850 static int
18851 api_one_eid_table_map_dump (vat_main_t * vam)
18852 {
18853   u8 is_l2 = 0;
18854   u8 mode_set = 0;
18855   unformat_input_t *input = vam->input;
18856   vl_api_one_eid_table_map_dump_t *mp;
18857   vl_api_control_ping_t *mp_ping;
18858   int ret;
18859
18860   /* Parse args required to build the message */
18861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18862     {
18863       if (unformat (input, "l2"))
18864         {
18865           is_l2 = 1;
18866           mode_set = 1;
18867         }
18868       else if (unformat (input, "l3"))
18869         {
18870           is_l2 = 0;
18871           mode_set = 1;
18872         }
18873       else
18874         {
18875           errmsg ("parse error '%U'", format_unformat_error, input);
18876           return -99;
18877         }
18878     }
18879
18880   if (!mode_set)
18881     {
18882       errmsg ("expected one of 'l2' or 'l3' parameter!");
18883       return -99;
18884     }
18885
18886   if (!vam->json_output)
18887     {
18888       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18889     }
18890
18891   M (ONE_EID_TABLE_MAP_DUMP, mp);
18892   mp->is_l2 = is_l2;
18893
18894   /* send it... */
18895   S (mp);
18896
18897   /* Use a control ping for synchronization */
18898   MPING (CONTROL_PING, mp_ping);
18899   S (mp_ping);
18900
18901   /* Wait for a reply... */
18902   W (ret);
18903   return ret;
18904 }
18905
18906 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18907
18908 static int
18909 api_one_eid_table_vni_dump (vat_main_t * vam)
18910 {
18911   vl_api_one_eid_table_vni_dump_t *mp;
18912   vl_api_control_ping_t *mp_ping;
18913   int ret;
18914
18915   if (!vam->json_output)
18916     {
18917       print (vam->ofp, "VNI");
18918     }
18919
18920   M (ONE_EID_TABLE_VNI_DUMP, mp);
18921
18922   /* send it... */
18923   S (mp);
18924
18925   /* Use a control ping for synchronization */
18926   MPING (CONTROL_PING, mp_ping);
18927   S (mp_ping);
18928
18929   /* Wait for a reply... */
18930   W (ret);
18931   return ret;
18932 }
18933
18934 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18935
18936 static int
18937 api_one_eid_table_dump (vat_main_t * vam)
18938 {
18939   unformat_input_t *i = vam->input;
18940   vl_api_one_eid_table_dump_t *mp;
18941   vl_api_control_ping_t *mp_ping;
18942   struct in_addr ip4;
18943   struct in6_addr ip6;
18944   u8 mac[6];
18945   u8 eid_type = ~0, eid_set = 0;
18946   u32 prefix_length = ~0, t, vni = 0;
18947   u8 filter = 0;
18948   int ret;
18949   lisp_nsh_api_t nsh;
18950
18951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18952     {
18953       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18954         {
18955           eid_set = 1;
18956           eid_type = 0;
18957           prefix_length = t;
18958         }
18959       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18960         {
18961           eid_set = 1;
18962           eid_type = 1;
18963           prefix_length = t;
18964         }
18965       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18966         {
18967           eid_set = 1;
18968           eid_type = 2;
18969         }
18970       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18971         {
18972           eid_set = 1;
18973           eid_type = 3;
18974         }
18975       else if (unformat (i, "vni %d", &t))
18976         {
18977           vni = t;
18978         }
18979       else if (unformat (i, "local"))
18980         {
18981           filter = 1;
18982         }
18983       else if (unformat (i, "remote"))
18984         {
18985           filter = 2;
18986         }
18987       else
18988         {
18989           errmsg ("parse error '%U'", format_unformat_error, i);
18990           return -99;
18991         }
18992     }
18993
18994   if (!vam->json_output)
18995     {
18996       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18997              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18998     }
18999
19000   M (ONE_EID_TABLE_DUMP, mp);
19001
19002   mp->filter = filter;
19003   if (eid_set)
19004     {
19005       mp->eid_set = 1;
19006       mp->vni = htonl (vni);
19007       mp->eid_type = eid_type;
19008       switch (eid_type)
19009         {
19010         case 0:
19011           mp->prefix_length = prefix_length;
19012           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19013           break;
19014         case 1:
19015           mp->prefix_length = prefix_length;
19016           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19017           break;
19018         case 2:
19019           clib_memcpy (mp->eid, mac, sizeof (mac));
19020           break;
19021         case 3:
19022           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19023           break;
19024         default:
19025           errmsg ("unknown EID type %d!", eid_type);
19026           return -99;
19027         }
19028     }
19029
19030   /* send it... */
19031   S (mp);
19032
19033   /* Use a control ping for synchronization */
19034   MPING (CONTROL_PING, mp_ping);
19035   S (mp_ping);
19036
19037   /* Wait for a reply... */
19038   W (ret);
19039   return ret;
19040 }
19041
19042 #define api_lisp_eid_table_dump api_one_eid_table_dump
19043
19044 static int
19045 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19046 {
19047   unformat_input_t *i = vam->input;
19048   vl_api_gpe_fwd_entries_get_t *mp;
19049   u8 vni_set = 0;
19050   u32 vni = ~0;
19051   int ret;
19052
19053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19054     {
19055       if (unformat (i, "vni %d", &vni))
19056         {
19057           vni_set = 1;
19058         }
19059       else
19060         {
19061           errmsg ("parse error '%U'", format_unformat_error, i);
19062           return -99;
19063         }
19064     }
19065
19066   if (!vni_set)
19067     {
19068       errmsg ("vni not set!");
19069       return -99;
19070     }
19071
19072   if (!vam->json_output)
19073     {
19074       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19075              "leid", "reid");
19076     }
19077
19078   M (GPE_FWD_ENTRIES_GET, mp);
19079   mp->vni = clib_host_to_net_u32 (vni);
19080
19081   /* send it... */
19082   S (mp);
19083
19084   /* Wait for a reply... */
19085   W (ret);
19086   return ret;
19087 }
19088
19089 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19090 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19091 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19092 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19093 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19094 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19095 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19096 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19097
19098 static int
19099 api_one_adjacencies_get (vat_main_t * vam)
19100 {
19101   unformat_input_t *i = vam->input;
19102   vl_api_one_adjacencies_get_t *mp;
19103   u8 vni_set = 0;
19104   u32 vni = ~0;
19105   int ret;
19106
19107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19108     {
19109       if (unformat (i, "vni %d", &vni))
19110         {
19111           vni_set = 1;
19112         }
19113       else
19114         {
19115           errmsg ("parse error '%U'", format_unformat_error, i);
19116           return -99;
19117         }
19118     }
19119
19120   if (!vni_set)
19121     {
19122       errmsg ("vni not set!");
19123       return -99;
19124     }
19125
19126   if (!vam->json_output)
19127     {
19128       print (vam->ofp, "%s %40s", "leid", "reid");
19129     }
19130
19131   M (ONE_ADJACENCIES_GET, mp);
19132   mp->vni = clib_host_to_net_u32 (vni);
19133
19134   /* send it... */
19135   S (mp);
19136
19137   /* Wait for a reply... */
19138   W (ret);
19139   return ret;
19140 }
19141
19142 #define api_lisp_adjacencies_get api_one_adjacencies_get
19143
19144 static int
19145 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19146 {
19147   unformat_input_t *i = vam->input;
19148   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19149   int ret;
19150   u8 ip_family_set = 0, is_ip4 = 1;
19151
19152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19153     {
19154       if (unformat (i, "ip4"))
19155         {
19156           ip_family_set = 1;
19157           is_ip4 = 1;
19158         }
19159       else if (unformat (i, "ip6"))
19160         {
19161           ip_family_set = 1;
19162           is_ip4 = 0;
19163         }
19164       else
19165         {
19166           errmsg ("parse error '%U'", format_unformat_error, i);
19167           return -99;
19168         }
19169     }
19170
19171   if (!ip_family_set)
19172     {
19173       errmsg ("ip family not set!");
19174       return -99;
19175     }
19176
19177   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19178   mp->is_ip4 = is_ip4;
19179
19180   /* send it... */
19181   S (mp);
19182
19183   /* Wait for a reply... */
19184   W (ret);
19185   return ret;
19186 }
19187
19188 static int
19189 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19190 {
19191   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19192   int ret;
19193
19194   if (!vam->json_output)
19195     {
19196       print (vam->ofp, "VNIs");
19197     }
19198
19199   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19200
19201   /* send it... */
19202   S (mp);
19203
19204   /* Wait for a reply... */
19205   W (ret);
19206   return ret;
19207 }
19208
19209 static int
19210 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19211 {
19212   unformat_input_t *i = vam->input;
19213   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19214   int ret = 0;
19215   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19216   struct in_addr ip4;
19217   struct in6_addr ip6;
19218   u32 table_id = 0, nh_sw_if_index = ~0;
19219
19220   clib_memset (&ip4, 0, sizeof (ip4));
19221   clib_memset (&ip6, 0, sizeof (ip6));
19222
19223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19224     {
19225       if (unformat (i, "del"))
19226         is_add = 0;
19227       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19228                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19229         {
19230           ip_set = 1;
19231           is_ip4 = 1;
19232         }
19233       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19234                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19235         {
19236           ip_set = 1;
19237           is_ip4 = 0;
19238         }
19239       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19240         {
19241           ip_set = 1;
19242           is_ip4 = 1;
19243           nh_sw_if_index = ~0;
19244         }
19245       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19246         {
19247           ip_set = 1;
19248           is_ip4 = 0;
19249           nh_sw_if_index = ~0;
19250         }
19251       else if (unformat (i, "table %d", &table_id))
19252         ;
19253       else
19254         {
19255           errmsg ("parse error '%U'", format_unformat_error, i);
19256           return -99;
19257         }
19258     }
19259
19260   if (!ip_set)
19261     {
19262       errmsg ("nh addr not set!");
19263       return -99;
19264     }
19265
19266   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19267   mp->is_add = is_add;
19268   mp->table_id = clib_host_to_net_u32 (table_id);
19269   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19270   mp->is_ip4 = is_ip4;
19271   if (is_ip4)
19272     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19273   else
19274     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19275
19276   /* send it... */
19277   S (mp);
19278
19279   /* Wait for a reply... */
19280   W (ret);
19281   return ret;
19282 }
19283
19284 static int
19285 api_one_map_server_dump (vat_main_t * vam)
19286 {
19287   vl_api_one_map_server_dump_t *mp;
19288   vl_api_control_ping_t *mp_ping;
19289   int ret;
19290
19291   if (!vam->json_output)
19292     {
19293       print (vam->ofp, "%=20s", "Map server");
19294     }
19295
19296   M (ONE_MAP_SERVER_DUMP, mp);
19297   /* send it... */
19298   S (mp);
19299
19300   /* Use a control ping for synchronization */
19301   MPING (CONTROL_PING, mp_ping);
19302   S (mp_ping);
19303
19304   /* Wait for a reply... */
19305   W (ret);
19306   return ret;
19307 }
19308
19309 #define api_lisp_map_server_dump api_one_map_server_dump
19310
19311 static int
19312 api_one_map_resolver_dump (vat_main_t * vam)
19313 {
19314   vl_api_one_map_resolver_dump_t *mp;
19315   vl_api_control_ping_t *mp_ping;
19316   int ret;
19317
19318   if (!vam->json_output)
19319     {
19320       print (vam->ofp, "%=20s", "Map resolver");
19321     }
19322
19323   M (ONE_MAP_RESOLVER_DUMP, mp);
19324   /* send it... */
19325   S (mp);
19326
19327   /* Use a control ping for synchronization */
19328   MPING (CONTROL_PING, mp_ping);
19329   S (mp_ping);
19330
19331   /* Wait for a reply... */
19332   W (ret);
19333   return ret;
19334 }
19335
19336 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19337
19338 static int
19339 api_one_stats_flush (vat_main_t * vam)
19340 {
19341   vl_api_one_stats_flush_t *mp;
19342   int ret = 0;
19343
19344   M (ONE_STATS_FLUSH, mp);
19345   S (mp);
19346   W (ret);
19347   return ret;
19348 }
19349
19350 static int
19351 api_one_stats_dump (vat_main_t * vam)
19352 {
19353   vl_api_one_stats_dump_t *mp;
19354   vl_api_control_ping_t *mp_ping;
19355   int ret;
19356
19357   M (ONE_STATS_DUMP, mp);
19358   /* send it... */
19359   S (mp);
19360
19361   /* Use a control ping for synchronization */
19362   MPING (CONTROL_PING, mp_ping);
19363   S (mp_ping);
19364
19365   /* Wait for a reply... */
19366   W (ret);
19367   return ret;
19368 }
19369
19370 static int
19371 api_show_one_status (vat_main_t * vam)
19372 {
19373   vl_api_show_one_status_t *mp;
19374   int ret;
19375
19376   if (!vam->json_output)
19377     {
19378       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19379     }
19380
19381   M (SHOW_ONE_STATUS, mp);
19382   /* send it... */
19383   S (mp);
19384   /* Wait for a reply... */
19385   W (ret);
19386   return ret;
19387 }
19388
19389 #define api_show_lisp_status api_show_one_status
19390
19391 static int
19392 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19393 {
19394   vl_api_gpe_fwd_entry_path_dump_t *mp;
19395   vl_api_control_ping_t *mp_ping;
19396   unformat_input_t *i = vam->input;
19397   u32 fwd_entry_index = ~0;
19398   int ret;
19399
19400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19401     {
19402       if (unformat (i, "index %d", &fwd_entry_index))
19403         ;
19404       else
19405         break;
19406     }
19407
19408   if (~0 == fwd_entry_index)
19409     {
19410       errmsg ("no index specified!");
19411       return -99;
19412     }
19413
19414   if (!vam->json_output)
19415     {
19416       print (vam->ofp, "first line");
19417     }
19418
19419   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19420
19421   /* send it... */
19422   S (mp);
19423   /* Use a control ping for synchronization */
19424   MPING (CONTROL_PING, mp_ping);
19425   S (mp_ping);
19426
19427   /* Wait for a reply... */
19428   W (ret);
19429   return ret;
19430 }
19431
19432 static int
19433 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19434 {
19435   vl_api_one_get_map_request_itr_rlocs_t *mp;
19436   int ret;
19437
19438   if (!vam->json_output)
19439     {
19440       print (vam->ofp, "%=20s", "itr-rlocs:");
19441     }
19442
19443   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19444   /* send it... */
19445   S (mp);
19446   /* Wait for a reply... */
19447   W (ret);
19448   return ret;
19449 }
19450
19451 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19452
19453 static int
19454 api_af_packet_create (vat_main_t * vam)
19455 {
19456   unformat_input_t *i = vam->input;
19457   vl_api_af_packet_create_t *mp;
19458   u8 *host_if_name = 0;
19459   u8 hw_addr[6];
19460   u8 random_hw_addr = 1;
19461   int ret;
19462
19463   clib_memset (hw_addr, 0, sizeof (hw_addr));
19464
19465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19466     {
19467       if (unformat (i, "name %s", &host_if_name))
19468         vec_add1 (host_if_name, 0);
19469       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19470         random_hw_addr = 0;
19471       else
19472         break;
19473     }
19474
19475   if (!vec_len (host_if_name))
19476     {
19477       errmsg ("host-interface name must be specified");
19478       return -99;
19479     }
19480
19481   if (vec_len (host_if_name) > 64)
19482     {
19483       errmsg ("host-interface name too long");
19484       return -99;
19485     }
19486
19487   M (AF_PACKET_CREATE, mp);
19488
19489   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19490   clib_memcpy (mp->hw_addr, hw_addr, 6);
19491   mp->use_random_hw_addr = random_hw_addr;
19492   vec_free (host_if_name);
19493
19494   S (mp);
19495
19496   /* *INDENT-OFF* */
19497   W2 (ret,
19498       ({
19499         if (ret == 0)
19500           fprintf (vam->ofp ? vam->ofp : stderr,
19501                    " new sw_if_index = %d\n", vam->sw_if_index);
19502       }));
19503   /* *INDENT-ON* */
19504   return ret;
19505 }
19506
19507 static int
19508 api_af_packet_delete (vat_main_t * vam)
19509 {
19510   unformat_input_t *i = vam->input;
19511   vl_api_af_packet_delete_t *mp;
19512   u8 *host_if_name = 0;
19513   int ret;
19514
19515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19516     {
19517       if (unformat (i, "name %s", &host_if_name))
19518         vec_add1 (host_if_name, 0);
19519       else
19520         break;
19521     }
19522
19523   if (!vec_len (host_if_name))
19524     {
19525       errmsg ("host-interface name must be specified");
19526       return -99;
19527     }
19528
19529   if (vec_len (host_if_name) > 64)
19530     {
19531       errmsg ("host-interface name too long");
19532       return -99;
19533     }
19534
19535   M (AF_PACKET_DELETE, mp);
19536
19537   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19538   vec_free (host_if_name);
19539
19540   S (mp);
19541   W (ret);
19542   return ret;
19543 }
19544
19545 static void vl_api_af_packet_details_t_handler
19546   (vl_api_af_packet_details_t * mp)
19547 {
19548   vat_main_t *vam = &vat_main;
19549
19550   print (vam->ofp, "%-16s %d",
19551          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19552 }
19553
19554 static void vl_api_af_packet_details_t_handler_json
19555   (vl_api_af_packet_details_t * mp)
19556 {
19557   vat_main_t *vam = &vat_main;
19558   vat_json_node_t *node = NULL;
19559
19560   if (VAT_JSON_ARRAY != vam->json_tree.type)
19561     {
19562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19563       vat_json_init_array (&vam->json_tree);
19564     }
19565   node = vat_json_array_add (&vam->json_tree);
19566
19567   vat_json_init_object (node);
19568   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19569   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19570 }
19571
19572 static int
19573 api_af_packet_dump (vat_main_t * vam)
19574 {
19575   vl_api_af_packet_dump_t *mp;
19576   vl_api_control_ping_t *mp_ping;
19577   int ret;
19578
19579   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19580   /* Get list of tap interfaces */
19581   M (AF_PACKET_DUMP, mp);
19582   S (mp);
19583
19584   /* Use a control ping for synchronization */
19585   MPING (CONTROL_PING, mp_ping);
19586   S (mp_ping);
19587
19588   W (ret);
19589   return ret;
19590 }
19591
19592 static int
19593 api_policer_add_del (vat_main_t * vam)
19594 {
19595   unformat_input_t *i = vam->input;
19596   vl_api_policer_add_del_t *mp;
19597   u8 is_add = 1;
19598   u8 *name = 0;
19599   u32 cir = 0;
19600   u32 eir = 0;
19601   u64 cb = 0;
19602   u64 eb = 0;
19603   u8 rate_type = 0;
19604   u8 round_type = 0;
19605   u8 type = 0;
19606   u8 color_aware = 0;
19607   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19608   int ret;
19609
19610   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19611   conform_action.dscp = 0;
19612   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19613   exceed_action.dscp = 0;
19614   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19615   violate_action.dscp = 0;
19616
19617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19618     {
19619       if (unformat (i, "del"))
19620         is_add = 0;
19621       else if (unformat (i, "name %s", &name))
19622         vec_add1 (name, 0);
19623       else if (unformat (i, "cir %u", &cir))
19624         ;
19625       else if (unformat (i, "eir %u", &eir))
19626         ;
19627       else if (unformat (i, "cb %u", &cb))
19628         ;
19629       else if (unformat (i, "eb %u", &eb))
19630         ;
19631       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19632                          &rate_type))
19633         ;
19634       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19635                          &round_type))
19636         ;
19637       else if (unformat (i, "type %U", unformat_policer_type, &type))
19638         ;
19639       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19640                          &conform_action))
19641         ;
19642       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19643                          &exceed_action))
19644         ;
19645       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19646                          &violate_action))
19647         ;
19648       else if (unformat (i, "color-aware"))
19649         color_aware = 1;
19650       else
19651         break;
19652     }
19653
19654   if (!vec_len (name))
19655     {
19656       errmsg ("policer name must be specified");
19657       return -99;
19658     }
19659
19660   if (vec_len (name) > 64)
19661     {
19662       errmsg ("policer name too long");
19663       return -99;
19664     }
19665
19666   M (POLICER_ADD_DEL, mp);
19667
19668   clib_memcpy (mp->name, name, vec_len (name));
19669   vec_free (name);
19670   mp->is_add = is_add;
19671   mp->cir = ntohl (cir);
19672   mp->eir = ntohl (eir);
19673   mp->cb = clib_net_to_host_u64 (cb);
19674   mp->eb = clib_net_to_host_u64 (eb);
19675   mp->rate_type = rate_type;
19676   mp->round_type = round_type;
19677   mp->type = type;
19678   mp->conform_action_type = conform_action.action_type;
19679   mp->conform_dscp = conform_action.dscp;
19680   mp->exceed_action_type = exceed_action.action_type;
19681   mp->exceed_dscp = exceed_action.dscp;
19682   mp->violate_action_type = violate_action.action_type;
19683   mp->violate_dscp = violate_action.dscp;
19684   mp->color_aware = color_aware;
19685
19686   S (mp);
19687   W (ret);
19688   return ret;
19689 }
19690
19691 static int
19692 api_policer_dump (vat_main_t * vam)
19693 {
19694   unformat_input_t *i = vam->input;
19695   vl_api_policer_dump_t *mp;
19696   vl_api_control_ping_t *mp_ping;
19697   u8 *match_name = 0;
19698   u8 match_name_valid = 0;
19699   int ret;
19700
19701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19702     {
19703       if (unformat (i, "name %s", &match_name))
19704         {
19705           vec_add1 (match_name, 0);
19706           match_name_valid = 1;
19707         }
19708       else
19709         break;
19710     }
19711
19712   M (POLICER_DUMP, mp);
19713   mp->match_name_valid = match_name_valid;
19714   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19715   vec_free (match_name);
19716   /* send it... */
19717   S (mp);
19718
19719   /* Use a control ping for synchronization */
19720   MPING (CONTROL_PING, mp_ping);
19721   S (mp_ping);
19722
19723   /* Wait for a reply... */
19724   W (ret);
19725   return ret;
19726 }
19727
19728 static int
19729 api_policer_classify_set_interface (vat_main_t * vam)
19730 {
19731   unformat_input_t *i = vam->input;
19732   vl_api_policer_classify_set_interface_t *mp;
19733   u32 sw_if_index;
19734   int sw_if_index_set;
19735   u32 ip4_table_index = ~0;
19736   u32 ip6_table_index = ~0;
19737   u32 l2_table_index = ~0;
19738   u8 is_add = 1;
19739   int ret;
19740
19741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19742     {
19743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19744         sw_if_index_set = 1;
19745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19746         sw_if_index_set = 1;
19747       else if (unformat (i, "del"))
19748         is_add = 0;
19749       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19750         ;
19751       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19752         ;
19753       else if (unformat (i, "l2-table %d", &l2_table_index))
19754         ;
19755       else
19756         {
19757           clib_warning ("parse error '%U'", format_unformat_error, i);
19758           return -99;
19759         }
19760     }
19761
19762   if (sw_if_index_set == 0)
19763     {
19764       errmsg ("missing interface name or sw_if_index");
19765       return -99;
19766     }
19767
19768   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19769
19770   mp->sw_if_index = ntohl (sw_if_index);
19771   mp->ip4_table_index = ntohl (ip4_table_index);
19772   mp->ip6_table_index = ntohl (ip6_table_index);
19773   mp->l2_table_index = ntohl (l2_table_index);
19774   mp->is_add = is_add;
19775
19776   S (mp);
19777   W (ret);
19778   return ret;
19779 }
19780
19781 static int
19782 api_policer_classify_dump (vat_main_t * vam)
19783 {
19784   unformat_input_t *i = vam->input;
19785   vl_api_policer_classify_dump_t *mp;
19786   vl_api_control_ping_t *mp_ping;
19787   u8 type = POLICER_CLASSIFY_N_TABLES;
19788   int ret;
19789
19790   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19791     ;
19792   else
19793     {
19794       errmsg ("classify table type must be specified");
19795       return -99;
19796     }
19797
19798   if (!vam->json_output)
19799     {
19800       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19801     }
19802
19803   M (POLICER_CLASSIFY_DUMP, mp);
19804   mp->type = type;
19805   /* send it... */
19806   S (mp);
19807
19808   /* Use a control ping for synchronization */
19809   MPING (CONTROL_PING, mp_ping);
19810   S (mp_ping);
19811
19812   /* Wait for a reply... */
19813   W (ret);
19814   return ret;
19815 }
19816
19817 static int
19818 api_netmap_create (vat_main_t * vam)
19819 {
19820   unformat_input_t *i = vam->input;
19821   vl_api_netmap_create_t *mp;
19822   u8 *if_name = 0;
19823   u8 hw_addr[6];
19824   u8 random_hw_addr = 1;
19825   u8 is_pipe = 0;
19826   u8 is_master = 0;
19827   int ret;
19828
19829   clib_memset (hw_addr, 0, sizeof (hw_addr));
19830
19831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19832     {
19833       if (unformat (i, "name %s", &if_name))
19834         vec_add1 (if_name, 0);
19835       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19836         random_hw_addr = 0;
19837       else if (unformat (i, "pipe"))
19838         is_pipe = 1;
19839       else if (unformat (i, "master"))
19840         is_master = 1;
19841       else if (unformat (i, "slave"))
19842         is_master = 0;
19843       else
19844         break;
19845     }
19846
19847   if (!vec_len (if_name))
19848     {
19849       errmsg ("interface name must be specified");
19850       return -99;
19851     }
19852
19853   if (vec_len (if_name) > 64)
19854     {
19855       errmsg ("interface name too long");
19856       return -99;
19857     }
19858
19859   M (NETMAP_CREATE, mp);
19860
19861   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19862   clib_memcpy (mp->hw_addr, hw_addr, 6);
19863   mp->use_random_hw_addr = random_hw_addr;
19864   mp->is_pipe = is_pipe;
19865   mp->is_master = is_master;
19866   vec_free (if_name);
19867
19868   S (mp);
19869   W (ret);
19870   return ret;
19871 }
19872
19873 static int
19874 api_netmap_delete (vat_main_t * vam)
19875 {
19876   unformat_input_t *i = vam->input;
19877   vl_api_netmap_delete_t *mp;
19878   u8 *if_name = 0;
19879   int ret;
19880
19881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19882     {
19883       if (unformat (i, "name %s", &if_name))
19884         vec_add1 (if_name, 0);
19885       else
19886         break;
19887     }
19888
19889   if (!vec_len (if_name))
19890     {
19891       errmsg ("interface name must be specified");
19892       return -99;
19893     }
19894
19895   if (vec_len (if_name) > 64)
19896     {
19897       errmsg ("interface name too long");
19898       return -99;
19899     }
19900
19901   M (NETMAP_DELETE, mp);
19902
19903   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19904   vec_free (if_name);
19905
19906   S (mp);
19907   W (ret);
19908   return ret;
19909 }
19910
19911 static void
19912 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19913 {
19914   if (fp->afi == IP46_TYPE_IP6)
19915     print (vam->ofp,
19916            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19917            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19918            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19919            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19920            format_ip6_address, fp->next_hop);
19921   else if (fp->afi == IP46_TYPE_IP4)
19922     print (vam->ofp,
19923            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19924            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19925            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19926            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19927            format_ip4_address, fp->next_hop);
19928 }
19929
19930 static void
19931 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19932                                  vl_api_fib_path_t * fp)
19933 {
19934   struct in_addr ip4;
19935   struct in6_addr ip6;
19936
19937   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19938   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19939   vat_json_object_add_uint (node, "is_local", fp->is_local);
19940   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19941   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19942   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19943   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19944   if (fp->afi == IP46_TYPE_IP4)
19945     {
19946       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19947       vat_json_object_add_ip4 (node, "next_hop", ip4);
19948     }
19949   else if (fp->afi == IP46_TYPE_IP6)
19950     {
19951       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19952       vat_json_object_add_ip6 (node, "next_hop", ip6);
19953     }
19954 }
19955
19956 static void
19957 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19958 {
19959   vat_main_t *vam = &vat_main;
19960   int count = ntohl (mp->mt_count);
19961   vl_api_fib_path_t *fp;
19962   i32 i;
19963
19964   print (vam->ofp, "[%d]: sw_if_index %d via:",
19965          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19966   fp = mp->mt_paths;
19967   for (i = 0; i < count; i++)
19968     {
19969       vl_api_mpls_fib_path_print (vam, fp);
19970       fp++;
19971     }
19972
19973   print (vam->ofp, "");
19974 }
19975
19976 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19977 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19978
19979 static void
19980 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19981 {
19982   vat_main_t *vam = &vat_main;
19983   vat_json_node_t *node = NULL;
19984   int count = ntohl (mp->mt_count);
19985   vl_api_fib_path_t *fp;
19986   i32 i;
19987
19988   if (VAT_JSON_ARRAY != vam->json_tree.type)
19989     {
19990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19991       vat_json_init_array (&vam->json_tree);
19992     }
19993   node = vat_json_array_add (&vam->json_tree);
19994
19995   vat_json_init_object (node);
19996   vat_json_object_add_uint (node, "tunnel_index",
19997                             ntohl (mp->mt_tunnel_index));
19998   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19999
20000   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20001
20002   fp = mp->mt_paths;
20003   for (i = 0; i < count; i++)
20004     {
20005       vl_api_mpls_fib_path_json_print (node, fp);
20006       fp++;
20007     }
20008 }
20009
20010 static int
20011 api_mpls_tunnel_dump (vat_main_t * vam)
20012 {
20013   vl_api_mpls_tunnel_dump_t *mp;
20014   vl_api_control_ping_t *mp_ping;
20015   u32 sw_if_index = ~0;
20016   int ret;
20017
20018   /* Parse args required to build the message */
20019   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20020     {
20021       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20022         ;
20023     }
20024
20025   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20026
20027   M (MPLS_TUNNEL_DUMP, mp);
20028   mp->sw_if_index = htonl (sw_if_index);
20029   S (mp);
20030
20031   /* Use a control ping for synchronization */
20032   MPING (CONTROL_PING, mp_ping);
20033   S (mp_ping);
20034
20035   W (ret);
20036   return ret;
20037 }
20038
20039 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20040 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20041
20042
20043 static void
20044 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20045 {
20046   vat_main_t *vam = &vat_main;
20047   int count = ntohl (mp->count);
20048   vl_api_fib_path_t *fp;
20049   int i;
20050
20051   print (vam->ofp,
20052          "table-id %d, label %u, ess_bit %u",
20053          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20054   fp = mp->path;
20055   for (i = 0; i < count; i++)
20056     {
20057       vl_api_mpls_fib_path_print (vam, fp);
20058       fp++;
20059     }
20060 }
20061
20062 static void vl_api_mpls_fib_details_t_handler_json
20063   (vl_api_mpls_fib_details_t * mp)
20064 {
20065   vat_main_t *vam = &vat_main;
20066   int count = ntohl (mp->count);
20067   vat_json_node_t *node = NULL;
20068   vl_api_fib_path_t *fp;
20069   int i;
20070
20071   if (VAT_JSON_ARRAY != vam->json_tree.type)
20072     {
20073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20074       vat_json_init_array (&vam->json_tree);
20075     }
20076   node = vat_json_array_add (&vam->json_tree);
20077
20078   vat_json_init_object (node);
20079   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20080   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20081   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20082   vat_json_object_add_uint (node, "path_count", count);
20083   fp = mp->path;
20084   for (i = 0; i < count; i++)
20085     {
20086       vl_api_mpls_fib_path_json_print (node, fp);
20087       fp++;
20088     }
20089 }
20090
20091 static int
20092 api_mpls_fib_dump (vat_main_t * vam)
20093 {
20094   vl_api_mpls_fib_dump_t *mp;
20095   vl_api_control_ping_t *mp_ping;
20096   int ret;
20097
20098   M (MPLS_FIB_DUMP, mp);
20099   S (mp);
20100
20101   /* Use a control ping for synchronization */
20102   MPING (CONTROL_PING, mp_ping);
20103   S (mp_ping);
20104
20105   W (ret);
20106   return ret;
20107 }
20108
20109 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20110 #define vl_api_ip_fib_details_t_print vl_noop_handler
20111
20112 static void
20113 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20114 {
20115   vat_main_t *vam = &vat_main;
20116   int count = ntohl (mp->count);
20117   vl_api_fib_path_t *fp;
20118   int i;
20119
20120   print (vam->ofp,
20121          "table-id %d, prefix %U/%d stats-index %d",
20122          ntohl (mp->table_id), format_ip4_address, mp->address,
20123          mp->address_length, ntohl (mp->stats_index));
20124   fp = mp->path;
20125   for (i = 0; i < count; i++)
20126     {
20127       if (fp->afi == IP46_TYPE_IP6)
20128         print (vam->ofp,
20129                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20130                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20131                "next_hop_table %d",
20132                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20133                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20134                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20135       else if (fp->afi == IP46_TYPE_IP4)
20136         print (vam->ofp,
20137                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20138                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20139                "next_hop_table %d",
20140                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20141                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20142                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20143       fp++;
20144     }
20145 }
20146
20147 static void vl_api_ip_fib_details_t_handler_json
20148   (vl_api_ip_fib_details_t * mp)
20149 {
20150   vat_main_t *vam = &vat_main;
20151   int count = ntohl (mp->count);
20152   vat_json_node_t *node = NULL;
20153   struct in_addr ip4;
20154   struct in6_addr ip6;
20155   vl_api_fib_path_t *fp;
20156   int i;
20157
20158   if (VAT_JSON_ARRAY != vam->json_tree.type)
20159     {
20160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20161       vat_json_init_array (&vam->json_tree);
20162     }
20163   node = vat_json_array_add (&vam->json_tree);
20164
20165   vat_json_init_object (node);
20166   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20167   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20168   vat_json_object_add_ip4 (node, "prefix", ip4);
20169   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20170   vat_json_object_add_uint (node, "path_count", count);
20171   fp = mp->path;
20172   for (i = 0; i < count; i++)
20173     {
20174       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20175       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20176       vat_json_object_add_uint (node, "is_local", fp->is_local);
20177       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20178       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20179       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20180       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20181       if (fp->afi == IP46_TYPE_IP4)
20182         {
20183           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20184           vat_json_object_add_ip4 (node, "next_hop", ip4);
20185         }
20186       else if (fp->afi == IP46_TYPE_IP6)
20187         {
20188           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20189           vat_json_object_add_ip6 (node, "next_hop", ip6);
20190         }
20191     }
20192 }
20193
20194 static int
20195 api_ip_fib_dump (vat_main_t * vam)
20196 {
20197   vl_api_ip_fib_dump_t *mp;
20198   vl_api_control_ping_t *mp_ping;
20199   int ret;
20200
20201   M (IP_FIB_DUMP, mp);
20202   S (mp);
20203
20204   /* Use a control ping for synchronization */
20205   MPING (CONTROL_PING, mp_ping);
20206   S (mp_ping);
20207
20208   W (ret);
20209   return ret;
20210 }
20211
20212 static int
20213 api_ip_mfib_dump (vat_main_t * vam)
20214 {
20215   vl_api_ip_mfib_dump_t *mp;
20216   vl_api_control_ping_t *mp_ping;
20217   int ret;
20218
20219   M (IP_MFIB_DUMP, mp);
20220   S (mp);
20221
20222   /* Use a control ping for synchronization */
20223   MPING (CONTROL_PING, mp_ping);
20224   S (mp_ping);
20225
20226   W (ret);
20227   return ret;
20228 }
20229
20230 static void vl_api_ip_neighbor_details_t_handler
20231   (vl_api_ip_neighbor_details_t * mp)
20232 {
20233   vat_main_t *vam = &vat_main;
20234
20235   print (vam->ofp, "%c %U %U",
20236          (mp->is_static) ? 'S' : 'D',
20237          format_ethernet_address, &mp->mac_address,
20238          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20239          &mp->ip_address);
20240 }
20241
20242 static void vl_api_ip_neighbor_details_t_handler_json
20243   (vl_api_ip_neighbor_details_t * mp)
20244 {
20245
20246   vat_main_t *vam = &vat_main;
20247   vat_json_node_t *node;
20248   struct in_addr ip4;
20249   struct in6_addr ip6;
20250
20251   if (VAT_JSON_ARRAY != vam->json_tree.type)
20252     {
20253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20254       vat_json_init_array (&vam->json_tree);
20255     }
20256   node = vat_json_array_add (&vam->json_tree);
20257
20258   vat_json_init_object (node);
20259   vat_json_object_add_string_copy (node, "flag",
20260                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20261                                    "dynamic");
20262
20263   vat_json_object_add_string_copy (node, "link_layer",
20264                                    format (0, "%U", format_ethernet_address,
20265                                            &mp->mac_address));
20266
20267   if (mp->is_ipv6)
20268     {
20269       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20270       vat_json_object_add_ip6 (node, "ip_address", ip6);
20271     }
20272   else
20273     {
20274       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20275       vat_json_object_add_ip4 (node, "ip_address", ip4);
20276     }
20277 }
20278
20279 static int
20280 api_ip_neighbor_dump (vat_main_t * vam)
20281 {
20282   unformat_input_t *i = vam->input;
20283   vl_api_ip_neighbor_dump_t *mp;
20284   vl_api_control_ping_t *mp_ping;
20285   u8 is_ipv6 = 0;
20286   u32 sw_if_index = ~0;
20287   int ret;
20288
20289   /* Parse args required to build the message */
20290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20291     {
20292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20293         ;
20294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20295         ;
20296       else if (unformat (i, "ip6"))
20297         is_ipv6 = 1;
20298       else
20299         break;
20300     }
20301
20302   if (sw_if_index == ~0)
20303     {
20304       errmsg ("missing interface name or sw_if_index");
20305       return -99;
20306     }
20307
20308   M (IP_NEIGHBOR_DUMP, mp);
20309   mp->is_ipv6 = (u8) is_ipv6;
20310   mp->sw_if_index = ntohl (sw_if_index);
20311   S (mp);
20312
20313   /* Use a control ping for synchronization */
20314   MPING (CONTROL_PING, mp_ping);
20315   S (mp_ping);
20316
20317   W (ret);
20318   return ret;
20319 }
20320
20321 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20322 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20323
20324 static void
20325 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20326 {
20327   vat_main_t *vam = &vat_main;
20328   int count = ntohl (mp->count);
20329   vl_api_fib_path_t *fp;
20330   int i;
20331
20332   print (vam->ofp,
20333          "table-id %d, prefix %U/%d stats-index %d",
20334          ntohl (mp->table_id), format_ip6_address, mp->address,
20335          mp->address_length, ntohl (mp->stats_index));
20336   fp = mp->path;
20337   for (i = 0; i < count; i++)
20338     {
20339       if (fp->afi == IP46_TYPE_IP6)
20340         print (vam->ofp,
20341                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20342                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20343                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20344                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20345                format_ip6_address, fp->next_hop);
20346       else if (fp->afi == IP46_TYPE_IP4)
20347         print (vam->ofp,
20348                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20349                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20350                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20351                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20352                format_ip4_address, fp->next_hop);
20353       fp++;
20354     }
20355 }
20356
20357 static void vl_api_ip6_fib_details_t_handler_json
20358   (vl_api_ip6_fib_details_t * mp)
20359 {
20360   vat_main_t *vam = &vat_main;
20361   int count = ntohl (mp->count);
20362   vat_json_node_t *node = NULL;
20363   struct in_addr ip4;
20364   struct in6_addr ip6;
20365   vl_api_fib_path_t *fp;
20366   int i;
20367
20368   if (VAT_JSON_ARRAY != vam->json_tree.type)
20369     {
20370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20371       vat_json_init_array (&vam->json_tree);
20372     }
20373   node = vat_json_array_add (&vam->json_tree);
20374
20375   vat_json_init_object (node);
20376   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20377   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20378   vat_json_object_add_ip6 (node, "prefix", ip6);
20379   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20380   vat_json_object_add_uint (node, "path_count", count);
20381   fp = mp->path;
20382   for (i = 0; i < count; i++)
20383     {
20384       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20385       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20386       vat_json_object_add_uint (node, "is_local", fp->is_local);
20387       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20388       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20389       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20390       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20391       if (fp->afi == IP46_TYPE_IP4)
20392         {
20393           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20394           vat_json_object_add_ip4 (node, "next_hop", ip4);
20395         }
20396       else if (fp->afi == IP46_TYPE_IP6)
20397         {
20398           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20399           vat_json_object_add_ip6 (node, "next_hop", ip6);
20400         }
20401     }
20402 }
20403
20404 static int
20405 api_ip6_fib_dump (vat_main_t * vam)
20406 {
20407   vl_api_ip6_fib_dump_t *mp;
20408   vl_api_control_ping_t *mp_ping;
20409   int ret;
20410
20411   M (IP6_FIB_DUMP, mp);
20412   S (mp);
20413
20414   /* Use a control ping for synchronization */
20415   MPING (CONTROL_PING, mp_ping);
20416   S (mp_ping);
20417
20418   W (ret);
20419   return ret;
20420 }
20421
20422 static int
20423 api_ip6_mfib_dump (vat_main_t * vam)
20424 {
20425   vl_api_ip6_mfib_dump_t *mp;
20426   vl_api_control_ping_t *mp_ping;
20427   int ret;
20428
20429   M (IP6_MFIB_DUMP, mp);
20430   S (mp);
20431
20432   /* Use a control ping for synchronization */
20433   MPING (CONTROL_PING, mp_ping);
20434   S (mp_ping);
20435
20436   W (ret);
20437   return ret;
20438 }
20439
20440 int
20441 api_classify_table_ids (vat_main_t * vam)
20442 {
20443   vl_api_classify_table_ids_t *mp;
20444   int ret;
20445
20446   /* Construct the API message */
20447   M (CLASSIFY_TABLE_IDS, mp);
20448   mp->context = 0;
20449
20450   S (mp);
20451   W (ret);
20452   return ret;
20453 }
20454
20455 int
20456 api_classify_table_by_interface (vat_main_t * vam)
20457 {
20458   unformat_input_t *input = vam->input;
20459   vl_api_classify_table_by_interface_t *mp;
20460
20461   u32 sw_if_index = ~0;
20462   int ret;
20463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20464     {
20465       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20466         ;
20467       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20468         ;
20469       else
20470         break;
20471     }
20472   if (sw_if_index == ~0)
20473     {
20474       errmsg ("missing interface name or sw_if_index");
20475       return -99;
20476     }
20477
20478   /* Construct the API message */
20479   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20480   mp->context = 0;
20481   mp->sw_if_index = ntohl (sw_if_index);
20482
20483   S (mp);
20484   W (ret);
20485   return ret;
20486 }
20487
20488 int
20489 api_classify_table_info (vat_main_t * vam)
20490 {
20491   unformat_input_t *input = vam->input;
20492   vl_api_classify_table_info_t *mp;
20493
20494   u32 table_id = ~0;
20495   int ret;
20496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20497     {
20498       if (unformat (input, "table_id %d", &table_id))
20499         ;
20500       else
20501         break;
20502     }
20503   if (table_id == ~0)
20504     {
20505       errmsg ("missing table id");
20506       return -99;
20507     }
20508
20509   /* Construct the API message */
20510   M (CLASSIFY_TABLE_INFO, mp);
20511   mp->context = 0;
20512   mp->table_id = ntohl (table_id);
20513
20514   S (mp);
20515   W (ret);
20516   return ret;
20517 }
20518
20519 int
20520 api_classify_session_dump (vat_main_t * vam)
20521 {
20522   unformat_input_t *input = vam->input;
20523   vl_api_classify_session_dump_t *mp;
20524   vl_api_control_ping_t *mp_ping;
20525
20526   u32 table_id = ~0;
20527   int ret;
20528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20529     {
20530       if (unformat (input, "table_id %d", &table_id))
20531         ;
20532       else
20533         break;
20534     }
20535   if (table_id == ~0)
20536     {
20537       errmsg ("missing table id");
20538       return -99;
20539     }
20540
20541   /* Construct the API message */
20542   M (CLASSIFY_SESSION_DUMP, mp);
20543   mp->context = 0;
20544   mp->table_id = ntohl (table_id);
20545   S (mp);
20546
20547   /* Use a control ping for synchronization */
20548   MPING (CONTROL_PING, mp_ping);
20549   S (mp_ping);
20550
20551   W (ret);
20552   return ret;
20553 }
20554
20555 static void
20556 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20557 {
20558   vat_main_t *vam = &vat_main;
20559
20560   print (vam->ofp, "collector_address %U, collector_port %d, "
20561          "src_address %U, vrf_id %d, path_mtu %u, "
20562          "template_interval %u, udp_checksum %d",
20563          format_ip4_address, mp->collector_address,
20564          ntohs (mp->collector_port),
20565          format_ip4_address, mp->src_address,
20566          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20567          ntohl (mp->template_interval), mp->udp_checksum);
20568
20569   vam->retval = 0;
20570   vam->result_ready = 1;
20571 }
20572
20573 static void
20574   vl_api_ipfix_exporter_details_t_handler_json
20575   (vl_api_ipfix_exporter_details_t * mp)
20576 {
20577   vat_main_t *vam = &vat_main;
20578   vat_json_node_t node;
20579   struct in_addr collector_address;
20580   struct in_addr src_address;
20581
20582   vat_json_init_object (&node);
20583   clib_memcpy (&collector_address, &mp->collector_address,
20584                sizeof (collector_address));
20585   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20586   vat_json_object_add_uint (&node, "collector_port",
20587                             ntohs (mp->collector_port));
20588   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20589   vat_json_object_add_ip4 (&node, "src_address", src_address);
20590   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20591   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20592   vat_json_object_add_uint (&node, "template_interval",
20593                             ntohl (mp->template_interval));
20594   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20595
20596   vat_json_print (vam->ofp, &node);
20597   vat_json_free (&node);
20598   vam->retval = 0;
20599   vam->result_ready = 1;
20600 }
20601
20602 int
20603 api_ipfix_exporter_dump (vat_main_t * vam)
20604 {
20605   vl_api_ipfix_exporter_dump_t *mp;
20606   int ret;
20607
20608   /* Construct the API message */
20609   M (IPFIX_EXPORTER_DUMP, mp);
20610   mp->context = 0;
20611
20612   S (mp);
20613   W (ret);
20614   return ret;
20615 }
20616
20617 static int
20618 api_ipfix_classify_stream_dump (vat_main_t * vam)
20619 {
20620   vl_api_ipfix_classify_stream_dump_t *mp;
20621   int ret;
20622
20623   /* Construct the API message */
20624   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20625   mp->context = 0;
20626
20627   S (mp);
20628   W (ret);
20629   return ret;
20630   /* NOTREACHED */
20631   return 0;
20632 }
20633
20634 static void
20635   vl_api_ipfix_classify_stream_details_t_handler
20636   (vl_api_ipfix_classify_stream_details_t * mp)
20637 {
20638   vat_main_t *vam = &vat_main;
20639   print (vam->ofp, "domain_id %d, src_port %d",
20640          ntohl (mp->domain_id), ntohs (mp->src_port));
20641   vam->retval = 0;
20642   vam->result_ready = 1;
20643 }
20644
20645 static void
20646   vl_api_ipfix_classify_stream_details_t_handler_json
20647   (vl_api_ipfix_classify_stream_details_t * mp)
20648 {
20649   vat_main_t *vam = &vat_main;
20650   vat_json_node_t node;
20651
20652   vat_json_init_object (&node);
20653   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20654   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20655
20656   vat_json_print (vam->ofp, &node);
20657   vat_json_free (&node);
20658   vam->retval = 0;
20659   vam->result_ready = 1;
20660 }
20661
20662 static int
20663 api_ipfix_classify_table_dump (vat_main_t * vam)
20664 {
20665   vl_api_ipfix_classify_table_dump_t *mp;
20666   vl_api_control_ping_t *mp_ping;
20667   int ret;
20668
20669   if (!vam->json_output)
20670     {
20671       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20672              "transport_protocol");
20673     }
20674
20675   /* Construct the API message */
20676   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20677
20678   /* send it... */
20679   S (mp);
20680
20681   /* Use a control ping for synchronization */
20682   MPING (CONTROL_PING, mp_ping);
20683   S (mp_ping);
20684
20685   W (ret);
20686   return ret;
20687 }
20688
20689 static void
20690   vl_api_ipfix_classify_table_details_t_handler
20691   (vl_api_ipfix_classify_table_details_t * mp)
20692 {
20693   vat_main_t *vam = &vat_main;
20694   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20695          mp->transport_protocol);
20696 }
20697
20698 static void
20699   vl_api_ipfix_classify_table_details_t_handler_json
20700   (vl_api_ipfix_classify_table_details_t * mp)
20701 {
20702   vat_json_node_t *node = NULL;
20703   vat_main_t *vam = &vat_main;
20704
20705   if (VAT_JSON_ARRAY != vam->json_tree.type)
20706     {
20707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20708       vat_json_init_array (&vam->json_tree);
20709     }
20710
20711   node = vat_json_array_add (&vam->json_tree);
20712   vat_json_init_object (node);
20713
20714   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20715   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20716   vat_json_object_add_uint (node, "transport_protocol",
20717                             mp->transport_protocol);
20718 }
20719
20720 static int
20721 api_sw_interface_span_enable_disable (vat_main_t * vam)
20722 {
20723   unformat_input_t *i = vam->input;
20724   vl_api_sw_interface_span_enable_disable_t *mp;
20725   u32 src_sw_if_index = ~0;
20726   u32 dst_sw_if_index = ~0;
20727   u8 state = 3;
20728   int ret;
20729   u8 is_l2 = 0;
20730
20731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20732     {
20733       if (unformat
20734           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20735         ;
20736       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20737         ;
20738       else
20739         if (unformat
20740             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20741         ;
20742       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20743         ;
20744       else if (unformat (i, "disable"))
20745         state = 0;
20746       else if (unformat (i, "rx"))
20747         state = 1;
20748       else if (unformat (i, "tx"))
20749         state = 2;
20750       else if (unformat (i, "both"))
20751         state = 3;
20752       else if (unformat (i, "l2"))
20753         is_l2 = 1;
20754       else
20755         break;
20756     }
20757
20758   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20759
20760   mp->sw_if_index_from = htonl (src_sw_if_index);
20761   mp->sw_if_index_to = htonl (dst_sw_if_index);
20762   mp->state = state;
20763   mp->is_l2 = is_l2;
20764
20765   S (mp);
20766   W (ret);
20767   return ret;
20768 }
20769
20770 static void
20771 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20772                                             * mp)
20773 {
20774   vat_main_t *vam = &vat_main;
20775   u8 *sw_if_from_name = 0;
20776   u8 *sw_if_to_name = 0;
20777   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20778   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20779   char *states[] = { "none", "rx", "tx", "both" };
20780   hash_pair_t *p;
20781
20782   /* *INDENT-OFF* */
20783   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20784   ({
20785     if ((u32) p->value[0] == sw_if_index_from)
20786       {
20787         sw_if_from_name = (u8 *)(p->key);
20788         if (sw_if_to_name)
20789           break;
20790       }
20791     if ((u32) p->value[0] == sw_if_index_to)
20792       {
20793         sw_if_to_name = (u8 *)(p->key);
20794         if (sw_if_from_name)
20795           break;
20796       }
20797   }));
20798   /* *INDENT-ON* */
20799   print (vam->ofp, "%20s => %20s (%s) %s",
20800          sw_if_from_name, sw_if_to_name, states[mp->state],
20801          mp->is_l2 ? "l2" : "device");
20802 }
20803
20804 static void
20805   vl_api_sw_interface_span_details_t_handler_json
20806   (vl_api_sw_interface_span_details_t * mp)
20807 {
20808   vat_main_t *vam = &vat_main;
20809   vat_json_node_t *node = NULL;
20810   u8 *sw_if_from_name = 0;
20811   u8 *sw_if_to_name = 0;
20812   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20813   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20814   hash_pair_t *p;
20815
20816   /* *INDENT-OFF* */
20817   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20818   ({
20819     if ((u32) p->value[0] == sw_if_index_from)
20820       {
20821         sw_if_from_name = (u8 *)(p->key);
20822         if (sw_if_to_name)
20823           break;
20824       }
20825     if ((u32) p->value[0] == sw_if_index_to)
20826       {
20827         sw_if_to_name = (u8 *)(p->key);
20828         if (sw_if_from_name)
20829           break;
20830       }
20831   }));
20832   /* *INDENT-ON* */
20833
20834   if (VAT_JSON_ARRAY != vam->json_tree.type)
20835     {
20836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20837       vat_json_init_array (&vam->json_tree);
20838     }
20839   node = vat_json_array_add (&vam->json_tree);
20840
20841   vat_json_init_object (node);
20842   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20843   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20844   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20845   if (0 != sw_if_to_name)
20846     {
20847       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20848     }
20849   vat_json_object_add_uint (node, "state", mp->state);
20850   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20851 }
20852
20853 static int
20854 api_sw_interface_span_dump (vat_main_t * vam)
20855 {
20856   unformat_input_t *input = vam->input;
20857   vl_api_sw_interface_span_dump_t *mp;
20858   vl_api_control_ping_t *mp_ping;
20859   u8 is_l2 = 0;
20860   int ret;
20861
20862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20863     {
20864       if (unformat (input, "l2"))
20865         is_l2 = 1;
20866       else
20867         break;
20868     }
20869
20870   M (SW_INTERFACE_SPAN_DUMP, mp);
20871   mp->is_l2 = is_l2;
20872   S (mp);
20873
20874   /* Use a control ping for synchronization */
20875   MPING (CONTROL_PING, mp_ping);
20876   S (mp_ping);
20877
20878   W (ret);
20879   return ret;
20880 }
20881
20882 int
20883 api_pg_create_interface (vat_main_t * vam)
20884 {
20885   unformat_input_t *input = vam->input;
20886   vl_api_pg_create_interface_t *mp;
20887
20888   u32 if_id = ~0;
20889   int ret;
20890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20891     {
20892       if (unformat (input, "if_id %d", &if_id))
20893         ;
20894       else
20895         break;
20896     }
20897   if (if_id == ~0)
20898     {
20899       errmsg ("missing pg interface index");
20900       return -99;
20901     }
20902
20903   /* Construct the API message */
20904   M (PG_CREATE_INTERFACE, mp);
20905   mp->context = 0;
20906   mp->interface_id = ntohl (if_id);
20907
20908   S (mp);
20909   W (ret);
20910   return ret;
20911 }
20912
20913 int
20914 api_pg_capture (vat_main_t * vam)
20915 {
20916   unformat_input_t *input = vam->input;
20917   vl_api_pg_capture_t *mp;
20918
20919   u32 if_id = ~0;
20920   u8 enable = 1;
20921   u32 count = 1;
20922   u8 pcap_file_set = 0;
20923   u8 *pcap_file = 0;
20924   int ret;
20925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20926     {
20927       if (unformat (input, "if_id %d", &if_id))
20928         ;
20929       else if (unformat (input, "pcap %s", &pcap_file))
20930         pcap_file_set = 1;
20931       else if (unformat (input, "count %d", &count))
20932         ;
20933       else if (unformat (input, "disable"))
20934         enable = 0;
20935       else
20936         break;
20937     }
20938   if (if_id == ~0)
20939     {
20940       errmsg ("missing pg interface index");
20941       return -99;
20942     }
20943   if (pcap_file_set > 0)
20944     {
20945       if (vec_len (pcap_file) > 255)
20946         {
20947           errmsg ("pcap file name is too long");
20948           return -99;
20949         }
20950     }
20951
20952   u32 name_len = vec_len (pcap_file);
20953   /* Construct the API message */
20954   M (PG_CAPTURE, mp);
20955   mp->context = 0;
20956   mp->interface_id = ntohl (if_id);
20957   mp->is_enabled = enable;
20958   mp->count = ntohl (count);
20959   mp->pcap_name_length = ntohl (name_len);
20960   if (pcap_file_set != 0)
20961     {
20962       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20963     }
20964   vec_free (pcap_file);
20965
20966   S (mp);
20967   W (ret);
20968   return ret;
20969 }
20970
20971 int
20972 api_pg_enable_disable (vat_main_t * vam)
20973 {
20974   unformat_input_t *input = vam->input;
20975   vl_api_pg_enable_disable_t *mp;
20976
20977   u8 enable = 1;
20978   u8 stream_name_set = 0;
20979   u8 *stream_name = 0;
20980   int ret;
20981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20982     {
20983       if (unformat (input, "stream %s", &stream_name))
20984         stream_name_set = 1;
20985       else if (unformat (input, "disable"))
20986         enable = 0;
20987       else
20988         break;
20989     }
20990
20991   if (stream_name_set > 0)
20992     {
20993       if (vec_len (stream_name) > 255)
20994         {
20995           errmsg ("stream name too long");
20996           return -99;
20997         }
20998     }
20999
21000   u32 name_len = vec_len (stream_name);
21001   /* Construct the API message */
21002   M (PG_ENABLE_DISABLE, mp);
21003   mp->context = 0;
21004   mp->is_enabled = enable;
21005   if (stream_name_set != 0)
21006     {
21007       mp->stream_name_length = ntohl (name_len);
21008       clib_memcpy (mp->stream_name, stream_name, name_len);
21009     }
21010   vec_free (stream_name);
21011
21012   S (mp);
21013   W (ret);
21014   return ret;
21015 }
21016
21017 int
21018 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21019 {
21020   unformat_input_t *input = vam->input;
21021   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21022
21023   u16 *low_ports = 0;
21024   u16 *high_ports = 0;
21025   u16 this_low;
21026   u16 this_hi;
21027   ip4_address_t ip4_addr;
21028   ip6_address_t ip6_addr;
21029   u32 length;
21030   u32 tmp, tmp2;
21031   u8 prefix_set = 0;
21032   u32 vrf_id = ~0;
21033   u8 is_add = 1;
21034   u8 is_ipv6 = 0;
21035   int ret;
21036
21037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21038     {
21039       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21040         {
21041           prefix_set = 1;
21042         }
21043       else
21044         if (unformat
21045             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21046         {
21047           prefix_set = 1;
21048           is_ipv6 = 1;
21049         }
21050       else if (unformat (input, "vrf %d", &vrf_id))
21051         ;
21052       else if (unformat (input, "del"))
21053         is_add = 0;
21054       else if (unformat (input, "port %d", &tmp))
21055         {
21056           if (tmp == 0 || tmp > 65535)
21057             {
21058               errmsg ("port %d out of range", tmp);
21059               return -99;
21060             }
21061           this_low = tmp;
21062           this_hi = this_low + 1;
21063           vec_add1 (low_ports, this_low);
21064           vec_add1 (high_ports, this_hi);
21065         }
21066       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21067         {
21068           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21069             {
21070               errmsg ("incorrect range parameters");
21071               return -99;
21072             }
21073           this_low = tmp;
21074           /* Note: in debug CLI +1 is added to high before
21075              passing to real fn that does "the work"
21076              (ip_source_and_port_range_check_add_del).
21077              This fn is a wrapper around the binary API fn a
21078              control plane will call, which expects this increment
21079              to have occurred. Hence letting the binary API control
21080              plane fn do the increment for consistency between VAT
21081              and other control planes.
21082            */
21083           this_hi = tmp2;
21084           vec_add1 (low_ports, this_low);
21085           vec_add1 (high_ports, this_hi);
21086         }
21087       else
21088         break;
21089     }
21090
21091   if (prefix_set == 0)
21092     {
21093       errmsg ("<address>/<mask> not specified");
21094       return -99;
21095     }
21096
21097   if (vrf_id == ~0)
21098     {
21099       errmsg ("VRF ID required, not specified");
21100       return -99;
21101     }
21102
21103   if (vrf_id == 0)
21104     {
21105       errmsg
21106         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21107       return -99;
21108     }
21109
21110   if (vec_len (low_ports) == 0)
21111     {
21112       errmsg ("At least one port or port range required");
21113       return -99;
21114     }
21115
21116   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21117
21118   mp->is_add = is_add;
21119
21120   if (is_ipv6)
21121     {
21122       mp->is_ipv6 = 1;
21123       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21124     }
21125   else
21126     {
21127       mp->is_ipv6 = 0;
21128       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21129     }
21130
21131   mp->mask_length = length;
21132   mp->number_of_ranges = vec_len (low_ports);
21133
21134   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21135   vec_free (low_ports);
21136
21137   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21138   vec_free (high_ports);
21139
21140   mp->vrf_id = ntohl (vrf_id);
21141
21142   S (mp);
21143   W (ret);
21144   return ret;
21145 }
21146
21147 int
21148 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21149 {
21150   unformat_input_t *input = vam->input;
21151   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21152   u32 sw_if_index = ~0;
21153   int vrf_set = 0;
21154   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21155   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21156   u8 is_add = 1;
21157   int ret;
21158
21159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21160     {
21161       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21162         ;
21163       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21164         ;
21165       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21166         vrf_set = 1;
21167       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21168         vrf_set = 1;
21169       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21170         vrf_set = 1;
21171       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21172         vrf_set = 1;
21173       else if (unformat (input, "del"))
21174         is_add = 0;
21175       else
21176         break;
21177     }
21178
21179   if (sw_if_index == ~0)
21180     {
21181       errmsg ("Interface required but not specified");
21182       return -99;
21183     }
21184
21185   if (vrf_set == 0)
21186     {
21187       errmsg ("VRF ID required but not specified");
21188       return -99;
21189     }
21190
21191   if (tcp_out_vrf_id == 0
21192       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21193     {
21194       errmsg
21195         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21196       return -99;
21197     }
21198
21199   /* Construct the API message */
21200   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21201
21202   mp->sw_if_index = ntohl (sw_if_index);
21203   mp->is_add = is_add;
21204   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21205   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21206   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21207   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21208
21209   /* send it... */
21210   S (mp);
21211
21212   /* Wait for a reply... */
21213   W (ret);
21214   return ret;
21215 }
21216
21217 static int
21218 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21219 {
21220   unformat_input_t *i = vam->input;
21221   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21222   u32 local_sa_id = 0;
21223   u32 remote_sa_id = 0;
21224   ip4_address_t src_address;
21225   ip4_address_t dst_address;
21226   u8 is_add = 1;
21227   int ret;
21228
21229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21230     {
21231       if (unformat (i, "local_sa %d", &local_sa_id))
21232         ;
21233       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21234         ;
21235       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21236         ;
21237       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21238         ;
21239       else if (unformat (i, "del"))
21240         is_add = 0;
21241       else
21242         {
21243           clib_warning ("parse error '%U'", format_unformat_error, i);
21244           return -99;
21245         }
21246     }
21247
21248   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21249
21250   mp->local_sa_id = ntohl (local_sa_id);
21251   mp->remote_sa_id = ntohl (remote_sa_id);
21252   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21253   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21254   mp->is_add = is_add;
21255
21256   S (mp);
21257   W (ret);
21258   return ret;
21259 }
21260
21261 static int
21262 api_set_punt (vat_main_t * vam)
21263 {
21264   unformat_input_t *i = vam->input;
21265   vl_api_set_punt_t *mp;
21266   u32 ipv = ~0;
21267   u32 protocol = ~0;
21268   u32 port = ~0;
21269   int is_add = 1;
21270   int ret;
21271
21272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21273     {
21274       if (unformat (i, "ip %d", &ipv))
21275         ;
21276       else if (unformat (i, "protocol %d", &protocol))
21277         ;
21278       else if (unformat (i, "port %d", &port))
21279         ;
21280       else if (unformat (i, "del"))
21281         is_add = 0;
21282       else
21283         {
21284           clib_warning ("parse error '%U'", format_unformat_error, i);
21285           return -99;
21286         }
21287     }
21288
21289   M (SET_PUNT, mp);
21290
21291   mp->is_add = (u8) is_add;
21292   mp->punt.ipv = (u8) ipv;
21293   mp->punt.l4_protocol = (u8) protocol;
21294   mp->punt.l4_port = htons ((u16) port);
21295
21296   S (mp);
21297   W (ret);
21298   return ret;
21299 }
21300
21301 static void vl_api_ipsec_gre_tunnel_details_t_handler
21302   (vl_api_ipsec_gre_tunnel_details_t * mp)
21303 {
21304   vat_main_t *vam = &vat_main;
21305
21306   print (vam->ofp, "%11d%15U%15U%14d%14d",
21307          ntohl (mp->sw_if_index),
21308          format_ip4_address, &mp->src_address,
21309          format_ip4_address, &mp->dst_address,
21310          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21311 }
21312
21313 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21314   (vl_api_ipsec_gre_tunnel_details_t * mp)
21315 {
21316   vat_main_t *vam = &vat_main;
21317   vat_json_node_t *node = NULL;
21318   struct in_addr ip4;
21319
21320   if (VAT_JSON_ARRAY != vam->json_tree.type)
21321     {
21322       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21323       vat_json_init_array (&vam->json_tree);
21324     }
21325   node = vat_json_array_add (&vam->json_tree);
21326
21327   vat_json_init_object (node);
21328   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21329   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21330   vat_json_object_add_ip4 (node, "src_address", ip4);
21331   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21332   vat_json_object_add_ip4 (node, "dst_address", ip4);
21333   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21334   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21335 }
21336
21337 static int
21338 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21339 {
21340   unformat_input_t *i = vam->input;
21341   vl_api_ipsec_gre_tunnel_dump_t *mp;
21342   vl_api_control_ping_t *mp_ping;
21343   u32 sw_if_index;
21344   u8 sw_if_index_set = 0;
21345   int ret;
21346
21347   /* Parse args required to build the message */
21348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21349     {
21350       if (unformat (i, "sw_if_index %d", &sw_if_index))
21351         sw_if_index_set = 1;
21352       else
21353         break;
21354     }
21355
21356   if (sw_if_index_set == 0)
21357     {
21358       sw_if_index = ~0;
21359     }
21360
21361   if (!vam->json_output)
21362     {
21363       print (vam->ofp, "%11s%15s%15s%14s%14s",
21364              "sw_if_index", "src_address", "dst_address",
21365              "local_sa_id", "remote_sa_id");
21366     }
21367
21368   /* Get list of gre-tunnel interfaces */
21369   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21370
21371   mp->sw_if_index = htonl (sw_if_index);
21372
21373   S (mp);
21374
21375   /* Use a control ping for synchronization */
21376   MPING (CONTROL_PING, mp_ping);
21377   S (mp_ping);
21378
21379   W (ret);
21380   return ret;
21381 }
21382
21383 static int
21384 api_delete_subif (vat_main_t * vam)
21385 {
21386   unformat_input_t *i = vam->input;
21387   vl_api_delete_subif_t *mp;
21388   u32 sw_if_index = ~0;
21389   int ret;
21390
21391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21392     {
21393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21394         ;
21395       if (unformat (i, "sw_if_index %d", &sw_if_index))
21396         ;
21397       else
21398         break;
21399     }
21400
21401   if (sw_if_index == ~0)
21402     {
21403       errmsg ("missing sw_if_index");
21404       return -99;
21405     }
21406
21407   /* Construct the API message */
21408   M (DELETE_SUBIF, mp);
21409   mp->sw_if_index = ntohl (sw_if_index);
21410
21411   S (mp);
21412   W (ret);
21413   return ret;
21414 }
21415
21416 #define foreach_pbb_vtr_op      \
21417 _("disable",  L2_VTR_DISABLED)  \
21418 _("pop",  L2_VTR_POP_2)         \
21419 _("push",  L2_VTR_PUSH_2)
21420
21421 static int
21422 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21423 {
21424   unformat_input_t *i = vam->input;
21425   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21426   u32 sw_if_index = ~0, vtr_op = ~0;
21427   u16 outer_tag = ~0;
21428   u8 dmac[6], smac[6];
21429   u8 dmac_set = 0, smac_set = 0;
21430   u16 vlanid = 0;
21431   u32 sid = ~0;
21432   u32 tmp;
21433   int ret;
21434
21435   /* Shut up coverity */
21436   clib_memset (dmac, 0, sizeof (dmac));
21437   clib_memset (smac, 0, sizeof (smac));
21438
21439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21440     {
21441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21442         ;
21443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21444         ;
21445       else if (unformat (i, "vtr_op %d", &vtr_op))
21446         ;
21447 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21448       foreach_pbb_vtr_op
21449 #undef _
21450         else if (unformat (i, "translate_pbb_stag"))
21451         {
21452           if (unformat (i, "%d", &tmp))
21453             {
21454               vtr_op = L2_VTR_TRANSLATE_2_1;
21455               outer_tag = tmp;
21456             }
21457           else
21458             {
21459               errmsg
21460                 ("translate_pbb_stag operation requires outer tag definition");
21461               return -99;
21462             }
21463         }
21464       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21465         dmac_set++;
21466       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21467         smac_set++;
21468       else if (unformat (i, "sid %d", &sid))
21469         ;
21470       else if (unformat (i, "vlanid %d", &tmp))
21471         vlanid = tmp;
21472       else
21473         {
21474           clib_warning ("parse error '%U'", format_unformat_error, i);
21475           return -99;
21476         }
21477     }
21478
21479   if ((sw_if_index == ~0) || (vtr_op == ~0))
21480     {
21481       errmsg ("missing sw_if_index or vtr operation");
21482       return -99;
21483     }
21484   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21485       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21486     {
21487       errmsg
21488         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21489       return -99;
21490     }
21491
21492   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21493   mp->sw_if_index = ntohl (sw_if_index);
21494   mp->vtr_op = ntohl (vtr_op);
21495   mp->outer_tag = ntohs (outer_tag);
21496   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21497   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21498   mp->b_vlanid = ntohs (vlanid);
21499   mp->i_sid = ntohl (sid);
21500
21501   S (mp);
21502   W (ret);
21503   return ret;
21504 }
21505
21506 static int
21507 api_flow_classify_set_interface (vat_main_t * vam)
21508 {
21509   unformat_input_t *i = vam->input;
21510   vl_api_flow_classify_set_interface_t *mp;
21511   u32 sw_if_index;
21512   int sw_if_index_set;
21513   u32 ip4_table_index = ~0;
21514   u32 ip6_table_index = ~0;
21515   u8 is_add = 1;
21516   int ret;
21517
21518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21519     {
21520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21521         sw_if_index_set = 1;
21522       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21523         sw_if_index_set = 1;
21524       else if (unformat (i, "del"))
21525         is_add = 0;
21526       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21527         ;
21528       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21529         ;
21530       else
21531         {
21532           clib_warning ("parse error '%U'", format_unformat_error, i);
21533           return -99;
21534         }
21535     }
21536
21537   if (sw_if_index_set == 0)
21538     {
21539       errmsg ("missing interface name or sw_if_index");
21540       return -99;
21541     }
21542
21543   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21544
21545   mp->sw_if_index = ntohl (sw_if_index);
21546   mp->ip4_table_index = ntohl (ip4_table_index);
21547   mp->ip6_table_index = ntohl (ip6_table_index);
21548   mp->is_add = is_add;
21549
21550   S (mp);
21551   W (ret);
21552   return ret;
21553 }
21554
21555 static int
21556 api_flow_classify_dump (vat_main_t * vam)
21557 {
21558   unformat_input_t *i = vam->input;
21559   vl_api_flow_classify_dump_t *mp;
21560   vl_api_control_ping_t *mp_ping;
21561   u8 type = FLOW_CLASSIFY_N_TABLES;
21562   int ret;
21563
21564   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21565     ;
21566   else
21567     {
21568       errmsg ("classify table type must be specified");
21569       return -99;
21570     }
21571
21572   if (!vam->json_output)
21573     {
21574       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21575     }
21576
21577   M (FLOW_CLASSIFY_DUMP, mp);
21578   mp->type = type;
21579   /* send it... */
21580   S (mp);
21581
21582   /* Use a control ping for synchronization */
21583   MPING (CONTROL_PING, mp_ping);
21584   S (mp_ping);
21585
21586   /* Wait for a reply... */
21587   W (ret);
21588   return ret;
21589 }
21590
21591 static int
21592 api_feature_enable_disable (vat_main_t * vam)
21593 {
21594   unformat_input_t *i = vam->input;
21595   vl_api_feature_enable_disable_t *mp;
21596   u8 *arc_name = 0;
21597   u8 *feature_name = 0;
21598   u32 sw_if_index = ~0;
21599   u8 enable = 1;
21600   int ret;
21601
21602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21603     {
21604       if (unformat (i, "arc_name %s", &arc_name))
21605         ;
21606       else if (unformat (i, "feature_name %s", &feature_name))
21607         ;
21608       else
21609         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21610         ;
21611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21612         ;
21613       else if (unformat (i, "disable"))
21614         enable = 0;
21615       else
21616         break;
21617     }
21618
21619   if (arc_name == 0)
21620     {
21621       errmsg ("missing arc name");
21622       return -99;
21623     }
21624   if (vec_len (arc_name) > 63)
21625     {
21626       errmsg ("arc name too long");
21627     }
21628
21629   if (feature_name == 0)
21630     {
21631       errmsg ("missing feature name");
21632       return -99;
21633     }
21634   if (vec_len (feature_name) > 63)
21635     {
21636       errmsg ("feature name too long");
21637     }
21638
21639   if (sw_if_index == ~0)
21640     {
21641       errmsg ("missing interface name or sw_if_index");
21642       return -99;
21643     }
21644
21645   /* Construct the API message */
21646   M (FEATURE_ENABLE_DISABLE, mp);
21647   mp->sw_if_index = ntohl (sw_if_index);
21648   mp->enable = enable;
21649   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21650   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21651   vec_free (arc_name);
21652   vec_free (feature_name);
21653
21654   S (mp);
21655   W (ret);
21656   return ret;
21657 }
21658
21659 static int
21660 api_sw_interface_tag_add_del (vat_main_t * vam)
21661 {
21662   unformat_input_t *i = vam->input;
21663   vl_api_sw_interface_tag_add_del_t *mp;
21664   u32 sw_if_index = ~0;
21665   u8 *tag = 0;
21666   u8 enable = 1;
21667   int ret;
21668
21669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21670     {
21671       if (unformat (i, "tag %s", &tag))
21672         ;
21673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21674         ;
21675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21676         ;
21677       else if (unformat (i, "del"))
21678         enable = 0;
21679       else
21680         break;
21681     }
21682
21683   if (sw_if_index == ~0)
21684     {
21685       errmsg ("missing interface name or sw_if_index");
21686       return -99;
21687     }
21688
21689   if (enable && (tag == 0))
21690     {
21691       errmsg ("no tag specified");
21692       return -99;
21693     }
21694
21695   /* Construct the API message */
21696   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21697   mp->sw_if_index = ntohl (sw_if_index);
21698   mp->is_add = enable;
21699   if (enable)
21700     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21701   vec_free (tag);
21702
21703   S (mp);
21704   W (ret);
21705   return ret;
21706 }
21707
21708 static void vl_api_l2_xconnect_details_t_handler
21709   (vl_api_l2_xconnect_details_t * mp)
21710 {
21711   vat_main_t *vam = &vat_main;
21712
21713   print (vam->ofp, "%15d%15d",
21714          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21715 }
21716
21717 static void vl_api_l2_xconnect_details_t_handler_json
21718   (vl_api_l2_xconnect_details_t * mp)
21719 {
21720   vat_main_t *vam = &vat_main;
21721   vat_json_node_t *node = NULL;
21722
21723   if (VAT_JSON_ARRAY != vam->json_tree.type)
21724     {
21725       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21726       vat_json_init_array (&vam->json_tree);
21727     }
21728   node = vat_json_array_add (&vam->json_tree);
21729
21730   vat_json_init_object (node);
21731   vat_json_object_add_uint (node, "rx_sw_if_index",
21732                             ntohl (mp->rx_sw_if_index));
21733   vat_json_object_add_uint (node, "tx_sw_if_index",
21734                             ntohl (mp->tx_sw_if_index));
21735 }
21736
21737 static int
21738 api_l2_xconnect_dump (vat_main_t * vam)
21739 {
21740   vl_api_l2_xconnect_dump_t *mp;
21741   vl_api_control_ping_t *mp_ping;
21742   int ret;
21743
21744   if (!vam->json_output)
21745     {
21746       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21747     }
21748
21749   M (L2_XCONNECT_DUMP, mp);
21750
21751   S (mp);
21752
21753   /* Use a control ping for synchronization */
21754   MPING (CONTROL_PING, mp_ping);
21755   S (mp_ping);
21756
21757   W (ret);
21758   return ret;
21759 }
21760
21761 static int
21762 api_hw_interface_set_mtu (vat_main_t * vam)
21763 {
21764   unformat_input_t *i = vam->input;
21765   vl_api_hw_interface_set_mtu_t *mp;
21766   u32 sw_if_index = ~0;
21767   u32 mtu = 0;
21768   int ret;
21769
21770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21771     {
21772       if (unformat (i, "mtu %d", &mtu))
21773         ;
21774       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21775         ;
21776       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21777         ;
21778       else
21779         break;
21780     }
21781
21782   if (sw_if_index == ~0)
21783     {
21784       errmsg ("missing interface name or sw_if_index");
21785       return -99;
21786     }
21787
21788   if (mtu == 0)
21789     {
21790       errmsg ("no mtu specified");
21791       return -99;
21792     }
21793
21794   /* Construct the API message */
21795   M (HW_INTERFACE_SET_MTU, mp);
21796   mp->sw_if_index = ntohl (sw_if_index);
21797   mp->mtu = ntohs ((u16) mtu);
21798
21799   S (mp);
21800   W (ret);
21801   return ret;
21802 }
21803
21804 static int
21805 api_p2p_ethernet_add (vat_main_t * vam)
21806 {
21807   unformat_input_t *i = vam->input;
21808   vl_api_p2p_ethernet_add_t *mp;
21809   u32 parent_if_index = ~0;
21810   u32 sub_id = ~0;
21811   u8 remote_mac[6];
21812   u8 mac_set = 0;
21813   int ret;
21814
21815   clib_memset (remote_mac, 0, sizeof (remote_mac));
21816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21817     {
21818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21819         ;
21820       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21821         ;
21822       else
21823         if (unformat
21824             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21825         mac_set++;
21826       else if (unformat (i, "sub_id %d", &sub_id))
21827         ;
21828       else
21829         {
21830           clib_warning ("parse error '%U'", format_unformat_error, i);
21831           return -99;
21832         }
21833     }
21834
21835   if (parent_if_index == ~0)
21836     {
21837       errmsg ("missing interface name or sw_if_index");
21838       return -99;
21839     }
21840   if (mac_set == 0)
21841     {
21842       errmsg ("missing remote mac address");
21843       return -99;
21844     }
21845   if (sub_id == ~0)
21846     {
21847       errmsg ("missing sub-interface id");
21848       return -99;
21849     }
21850
21851   M (P2P_ETHERNET_ADD, mp);
21852   mp->parent_if_index = ntohl (parent_if_index);
21853   mp->subif_id = ntohl (sub_id);
21854   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21855
21856   S (mp);
21857   W (ret);
21858   return ret;
21859 }
21860
21861 static int
21862 api_p2p_ethernet_del (vat_main_t * vam)
21863 {
21864   unformat_input_t *i = vam->input;
21865   vl_api_p2p_ethernet_del_t *mp;
21866   u32 parent_if_index = ~0;
21867   u8 remote_mac[6];
21868   u8 mac_set = 0;
21869   int ret;
21870
21871   clib_memset (remote_mac, 0, sizeof (remote_mac));
21872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21873     {
21874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21875         ;
21876       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21877         ;
21878       else
21879         if (unformat
21880             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21881         mac_set++;
21882       else
21883         {
21884           clib_warning ("parse error '%U'", format_unformat_error, i);
21885           return -99;
21886         }
21887     }
21888
21889   if (parent_if_index == ~0)
21890     {
21891       errmsg ("missing interface name or sw_if_index");
21892       return -99;
21893     }
21894   if (mac_set == 0)
21895     {
21896       errmsg ("missing remote mac address");
21897       return -99;
21898     }
21899
21900   M (P2P_ETHERNET_DEL, mp);
21901   mp->parent_if_index = ntohl (parent_if_index);
21902   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21903
21904   S (mp);
21905   W (ret);
21906   return ret;
21907 }
21908
21909 static int
21910 api_lldp_config (vat_main_t * vam)
21911 {
21912   unformat_input_t *i = vam->input;
21913   vl_api_lldp_config_t *mp;
21914   int tx_hold = 0;
21915   int tx_interval = 0;
21916   u8 *sys_name = NULL;
21917   int ret;
21918
21919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21920     {
21921       if (unformat (i, "system-name %s", &sys_name))
21922         ;
21923       else if (unformat (i, "tx-hold %d", &tx_hold))
21924         ;
21925       else if (unformat (i, "tx-interval %d", &tx_interval))
21926         ;
21927       else
21928         {
21929           clib_warning ("parse error '%U'", format_unformat_error, i);
21930           return -99;
21931         }
21932     }
21933
21934   vec_add1 (sys_name, 0);
21935
21936   M (LLDP_CONFIG, mp);
21937   mp->tx_hold = htonl (tx_hold);
21938   mp->tx_interval = htonl (tx_interval);
21939   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21940   vec_free (sys_name);
21941
21942   S (mp);
21943   W (ret);
21944   return ret;
21945 }
21946
21947 static int
21948 api_sw_interface_set_lldp (vat_main_t * vam)
21949 {
21950   unformat_input_t *i = vam->input;
21951   vl_api_sw_interface_set_lldp_t *mp;
21952   u32 sw_if_index = ~0;
21953   u32 enable = 1;
21954   u8 *port_desc = NULL, *mgmt_oid = NULL;
21955   ip4_address_t ip4_addr;
21956   ip6_address_t ip6_addr;
21957   int ret;
21958
21959   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21960   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21961
21962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21963     {
21964       if (unformat (i, "disable"))
21965         enable = 0;
21966       else
21967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21968         ;
21969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21970         ;
21971       else if (unformat (i, "port-desc %s", &port_desc))
21972         ;
21973       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21974         ;
21975       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21976         ;
21977       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21978         ;
21979       else
21980         break;
21981     }
21982
21983   if (sw_if_index == ~0)
21984     {
21985       errmsg ("missing interface name or sw_if_index");
21986       return -99;
21987     }
21988
21989   /* Construct the API message */
21990   vec_add1 (port_desc, 0);
21991   vec_add1 (mgmt_oid, 0);
21992   M (SW_INTERFACE_SET_LLDP, mp);
21993   mp->sw_if_index = ntohl (sw_if_index);
21994   mp->enable = enable;
21995   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21996   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21997   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21998   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21999   vec_free (port_desc);
22000   vec_free (mgmt_oid);
22001
22002   S (mp);
22003   W (ret);
22004   return ret;
22005 }
22006
22007 static int
22008 api_tcp_configure_src_addresses (vat_main_t * vam)
22009 {
22010   vl_api_tcp_configure_src_addresses_t *mp;
22011   unformat_input_t *i = vam->input;
22012   ip4_address_t v4first, v4last;
22013   ip6_address_t v6first, v6last;
22014   u8 range_set = 0;
22015   u32 vrf_id = 0;
22016   int ret;
22017
22018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22019     {
22020       if (unformat (i, "%U - %U",
22021                     unformat_ip4_address, &v4first,
22022                     unformat_ip4_address, &v4last))
22023         {
22024           if (range_set)
22025             {
22026               errmsg ("one range per message (range already set)");
22027               return -99;
22028             }
22029           range_set = 1;
22030         }
22031       else if (unformat (i, "%U - %U",
22032                          unformat_ip6_address, &v6first,
22033                          unformat_ip6_address, &v6last))
22034         {
22035           if (range_set)
22036             {
22037               errmsg ("one range per message (range already set)");
22038               return -99;
22039             }
22040           range_set = 2;
22041         }
22042       else if (unformat (i, "vrf %d", &vrf_id))
22043         ;
22044       else
22045         break;
22046     }
22047
22048   if (range_set == 0)
22049     {
22050       errmsg ("address range not set");
22051       return -99;
22052     }
22053
22054   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22055   mp->vrf_id = ntohl (vrf_id);
22056   /* ipv6? */
22057   if (range_set == 2)
22058     {
22059       mp->is_ipv6 = 1;
22060       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22061       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22062     }
22063   else
22064     {
22065       mp->is_ipv6 = 0;
22066       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22067       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22068     }
22069   S (mp);
22070   W (ret);
22071   return ret;
22072 }
22073
22074 static void vl_api_app_namespace_add_del_reply_t_handler
22075   (vl_api_app_namespace_add_del_reply_t * mp)
22076 {
22077   vat_main_t *vam = &vat_main;
22078   i32 retval = ntohl (mp->retval);
22079   if (vam->async_mode)
22080     {
22081       vam->async_errors += (retval < 0);
22082     }
22083   else
22084     {
22085       vam->retval = retval;
22086       if (retval == 0)
22087         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22088       vam->result_ready = 1;
22089     }
22090 }
22091
22092 static void vl_api_app_namespace_add_del_reply_t_handler_json
22093   (vl_api_app_namespace_add_del_reply_t * mp)
22094 {
22095   vat_main_t *vam = &vat_main;
22096   vat_json_node_t node;
22097
22098   vat_json_init_object (&node);
22099   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22100   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22101
22102   vat_json_print (vam->ofp, &node);
22103   vat_json_free (&node);
22104
22105   vam->retval = ntohl (mp->retval);
22106   vam->result_ready = 1;
22107 }
22108
22109 static int
22110 api_app_namespace_add_del (vat_main_t * vam)
22111 {
22112   vl_api_app_namespace_add_del_t *mp;
22113   unformat_input_t *i = vam->input;
22114   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22115   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22116   u64 secret;
22117   int ret;
22118
22119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22120     {
22121       if (unformat (i, "id %_%v%_", &ns_id))
22122         ;
22123       else if (unformat (i, "secret %lu", &secret))
22124         secret_set = 1;
22125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22126         sw_if_index_set = 1;
22127       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22128         ;
22129       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22130         ;
22131       else
22132         break;
22133     }
22134   if (!ns_id || !secret_set || !sw_if_index_set)
22135     {
22136       errmsg ("namespace id, secret and sw_if_index must be set");
22137       return -99;
22138     }
22139   if (vec_len (ns_id) > 64)
22140     {
22141       errmsg ("namespace id too long");
22142       return -99;
22143     }
22144   M (APP_NAMESPACE_ADD_DEL, mp);
22145
22146   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22147   mp->namespace_id_len = vec_len (ns_id);
22148   mp->secret = clib_host_to_net_u64 (secret);
22149   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22150   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22151   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22152   vec_free (ns_id);
22153   S (mp);
22154   W (ret);
22155   return ret;
22156 }
22157
22158 static int
22159 api_sock_init_shm (vat_main_t * vam)
22160 {
22161 #if VPP_API_TEST_BUILTIN == 0
22162   unformat_input_t *i = vam->input;
22163   vl_api_shm_elem_config_t *config = 0;
22164   u64 size = 64 << 20;
22165   int rv;
22166
22167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22168     {
22169       if (unformat (i, "size %U", unformat_memory_size, &size))
22170         ;
22171       else
22172         break;
22173     }
22174
22175   /*
22176    * Canned custom ring allocator config.
22177    * Should probably parse all of this
22178    */
22179   vec_validate (config, 6);
22180   config[0].type = VL_API_VLIB_RING;
22181   config[0].size = 256;
22182   config[0].count = 32;
22183
22184   config[1].type = VL_API_VLIB_RING;
22185   config[1].size = 1024;
22186   config[1].count = 16;
22187
22188   config[2].type = VL_API_VLIB_RING;
22189   config[2].size = 4096;
22190   config[2].count = 2;
22191
22192   config[3].type = VL_API_CLIENT_RING;
22193   config[3].size = 256;
22194   config[3].count = 32;
22195
22196   config[4].type = VL_API_CLIENT_RING;
22197   config[4].size = 1024;
22198   config[4].count = 16;
22199
22200   config[5].type = VL_API_CLIENT_RING;
22201   config[5].size = 4096;
22202   config[5].count = 2;
22203
22204   config[6].type = VL_API_QUEUE;
22205   config[6].count = 128;
22206   config[6].size = sizeof (uword);
22207
22208   rv = vl_socket_client_init_shm (config);
22209   if (!rv)
22210     vam->client_index_invalid = 1;
22211   return rv;
22212 #else
22213   return -99;
22214 #endif
22215 }
22216
22217 static int
22218 api_dns_enable_disable (vat_main_t * vam)
22219 {
22220   unformat_input_t *line_input = vam->input;
22221   vl_api_dns_enable_disable_t *mp;
22222   u8 enable_disable = 1;
22223   int ret;
22224
22225   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22226     {
22227       if (unformat (line_input, "disable"))
22228         enable_disable = 0;
22229       if (unformat (line_input, "enable"))
22230         enable_disable = 1;
22231       else
22232         break;
22233     }
22234
22235   /* Construct the API message */
22236   M (DNS_ENABLE_DISABLE, mp);
22237   mp->enable = enable_disable;
22238
22239   /* send it... */
22240   S (mp);
22241   /* Wait for the reply */
22242   W (ret);
22243   return ret;
22244 }
22245
22246 static int
22247 api_dns_resolve_name (vat_main_t * vam)
22248 {
22249   unformat_input_t *line_input = vam->input;
22250   vl_api_dns_resolve_name_t *mp;
22251   u8 *name = 0;
22252   int ret;
22253
22254   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22255     {
22256       if (unformat (line_input, "%s", &name))
22257         ;
22258       else
22259         break;
22260     }
22261
22262   if (vec_len (name) > 127)
22263     {
22264       errmsg ("name too long");
22265       return -99;
22266     }
22267
22268   /* Construct the API message */
22269   M (DNS_RESOLVE_NAME, mp);
22270   memcpy (mp->name, name, vec_len (name));
22271   vec_free (name);
22272
22273   /* send it... */
22274   S (mp);
22275   /* Wait for the reply */
22276   W (ret);
22277   return ret;
22278 }
22279
22280 static int
22281 api_dns_resolve_ip (vat_main_t * vam)
22282 {
22283   unformat_input_t *line_input = vam->input;
22284   vl_api_dns_resolve_ip_t *mp;
22285   int is_ip6 = -1;
22286   ip4_address_t addr4;
22287   ip6_address_t addr6;
22288   int ret;
22289
22290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22291     {
22292       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22293         is_ip6 = 1;
22294       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22295         is_ip6 = 0;
22296       else
22297         break;
22298     }
22299
22300   if (is_ip6 == -1)
22301     {
22302       errmsg ("missing address");
22303       return -99;
22304     }
22305
22306   /* Construct the API message */
22307   M (DNS_RESOLVE_IP, mp);
22308   mp->is_ip6 = is_ip6;
22309   if (is_ip6)
22310     memcpy (mp->address, &addr6, sizeof (addr6));
22311   else
22312     memcpy (mp->address, &addr4, sizeof (addr4));
22313
22314   /* send it... */
22315   S (mp);
22316   /* Wait for the reply */
22317   W (ret);
22318   return ret;
22319 }
22320
22321 static int
22322 api_dns_name_server_add_del (vat_main_t * vam)
22323 {
22324   unformat_input_t *i = vam->input;
22325   vl_api_dns_name_server_add_del_t *mp;
22326   u8 is_add = 1;
22327   ip6_address_t ip6_server;
22328   ip4_address_t ip4_server;
22329   int ip6_set = 0;
22330   int ip4_set = 0;
22331   int ret = 0;
22332
22333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22334     {
22335       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22336         ip6_set = 1;
22337       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22338         ip4_set = 1;
22339       else if (unformat (i, "del"))
22340         is_add = 0;
22341       else
22342         {
22343           clib_warning ("parse error '%U'", format_unformat_error, i);
22344           return -99;
22345         }
22346     }
22347
22348   if (ip4_set && ip6_set)
22349     {
22350       errmsg ("Only one server address allowed per message");
22351       return -99;
22352     }
22353   if ((ip4_set + ip6_set) == 0)
22354     {
22355       errmsg ("Server address required");
22356       return -99;
22357     }
22358
22359   /* Construct the API message */
22360   M (DNS_NAME_SERVER_ADD_DEL, mp);
22361
22362   if (ip6_set)
22363     {
22364       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22365       mp->is_ip6 = 1;
22366     }
22367   else
22368     {
22369       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22370       mp->is_ip6 = 0;
22371     }
22372
22373   mp->is_add = is_add;
22374
22375   /* send it... */
22376   S (mp);
22377
22378   /* Wait for a reply, return good/bad news  */
22379   W (ret);
22380   return ret;
22381 }
22382
22383 static void
22384 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22385 {
22386   vat_main_t *vam = &vat_main;
22387
22388   if (mp->is_ip4)
22389     {
22390       print (vam->ofp,
22391              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22392              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22393              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22394              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22395              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22396              clib_net_to_host_u32 (mp->action_index), mp->tag);
22397     }
22398   else
22399     {
22400       print (vam->ofp,
22401              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22402              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22403              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22404              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22405              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22406              clib_net_to_host_u32 (mp->action_index), mp->tag);
22407     }
22408 }
22409
22410 static void
22411 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22412                                              mp)
22413 {
22414   vat_main_t *vam = &vat_main;
22415   vat_json_node_t *node = NULL;
22416   struct in6_addr ip6;
22417   struct in_addr ip4;
22418
22419   if (VAT_JSON_ARRAY != vam->json_tree.type)
22420     {
22421       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22422       vat_json_init_array (&vam->json_tree);
22423     }
22424   node = vat_json_array_add (&vam->json_tree);
22425   vat_json_init_object (node);
22426
22427   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22428   vat_json_object_add_uint (node, "appns_index",
22429                             clib_net_to_host_u32 (mp->appns_index));
22430   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22431   vat_json_object_add_uint (node, "scope", mp->scope);
22432   vat_json_object_add_uint (node, "action_index",
22433                             clib_net_to_host_u32 (mp->action_index));
22434   vat_json_object_add_uint (node, "lcl_port",
22435                             clib_net_to_host_u16 (mp->lcl_port));
22436   vat_json_object_add_uint (node, "rmt_port",
22437                             clib_net_to_host_u16 (mp->rmt_port));
22438   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22439   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22440   vat_json_object_add_string_copy (node, "tag", mp->tag);
22441   if (mp->is_ip4)
22442     {
22443       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22444       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22445       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22446       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22447     }
22448   else
22449     {
22450       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22451       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22452       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22453       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22454     }
22455 }
22456
22457 static int
22458 api_session_rule_add_del (vat_main_t * vam)
22459 {
22460   vl_api_session_rule_add_del_t *mp;
22461   unformat_input_t *i = vam->input;
22462   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22463   u32 appns_index = 0, scope = 0;
22464   ip4_address_t lcl_ip4, rmt_ip4;
22465   ip6_address_t lcl_ip6, rmt_ip6;
22466   u8 is_ip4 = 1, conn_set = 0;
22467   u8 is_add = 1, *tag = 0;
22468   int ret;
22469
22470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22471     {
22472       if (unformat (i, "del"))
22473         is_add = 0;
22474       else if (unformat (i, "add"))
22475         ;
22476       else if (unformat (i, "proto tcp"))
22477         proto = 0;
22478       else if (unformat (i, "proto udp"))
22479         proto = 1;
22480       else if (unformat (i, "appns %d", &appns_index))
22481         ;
22482       else if (unformat (i, "scope %d", &scope))
22483         ;
22484       else if (unformat (i, "tag %_%v%_", &tag))
22485         ;
22486       else
22487         if (unformat
22488             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22489              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22490              &rmt_port))
22491         {
22492           is_ip4 = 1;
22493           conn_set = 1;
22494         }
22495       else
22496         if (unformat
22497             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22498              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22499              &rmt_port))
22500         {
22501           is_ip4 = 0;
22502           conn_set = 1;
22503         }
22504       else if (unformat (i, "action %d", &action))
22505         ;
22506       else
22507         break;
22508     }
22509   if (proto == ~0 || !conn_set || action == ~0)
22510     {
22511       errmsg ("transport proto, connection and action must be set");
22512       return -99;
22513     }
22514
22515   if (scope > 3)
22516     {
22517       errmsg ("scope should be 0-3");
22518       return -99;
22519     }
22520
22521   M (SESSION_RULE_ADD_DEL, mp);
22522
22523   mp->is_ip4 = is_ip4;
22524   mp->transport_proto = proto;
22525   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22526   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22527   mp->lcl_plen = lcl_plen;
22528   mp->rmt_plen = rmt_plen;
22529   mp->action_index = clib_host_to_net_u32 (action);
22530   mp->appns_index = clib_host_to_net_u32 (appns_index);
22531   mp->scope = scope;
22532   mp->is_add = is_add;
22533   if (is_ip4)
22534     {
22535       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22536       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22537     }
22538   else
22539     {
22540       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22541       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22542     }
22543   if (tag)
22544     {
22545       clib_memcpy (mp->tag, tag, vec_len (tag));
22546       vec_free (tag);
22547     }
22548
22549   S (mp);
22550   W (ret);
22551   return ret;
22552 }
22553
22554 static int
22555 api_session_rules_dump (vat_main_t * vam)
22556 {
22557   vl_api_session_rules_dump_t *mp;
22558   vl_api_control_ping_t *mp_ping;
22559   int ret;
22560
22561   if (!vam->json_output)
22562     {
22563       print (vam->ofp, "%=20s", "Session Rules");
22564     }
22565
22566   M (SESSION_RULES_DUMP, mp);
22567   /* send it... */
22568   S (mp);
22569
22570   /* Use a control ping for synchronization */
22571   MPING (CONTROL_PING, mp_ping);
22572   S (mp_ping);
22573
22574   /* Wait for a reply... */
22575   W (ret);
22576   return ret;
22577 }
22578
22579 static int
22580 api_ip_container_proxy_add_del (vat_main_t * vam)
22581 {
22582   vl_api_ip_container_proxy_add_del_t *mp;
22583   unformat_input_t *i = vam->input;
22584   u32 plen = ~0, sw_if_index = ~0;
22585   ip4_address_t ip4;
22586   ip6_address_t ip6;
22587   u8 is_ip4 = 1;
22588   u8 is_add = 1;
22589   int ret;
22590
22591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22592     {
22593       if (unformat (i, "del"))
22594         is_add = 0;
22595       else if (unformat (i, "add"))
22596         ;
22597       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22598         {
22599           is_ip4 = 1;
22600           plen = 32;
22601         }
22602       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22603         {
22604           is_ip4 = 0;
22605           plen = 128;
22606         }
22607       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22608         ;
22609       else
22610         break;
22611     }
22612   if (sw_if_index == ~0 || plen == ~0)
22613     {
22614       errmsg ("address and sw_if_index must be set");
22615       return -99;
22616     }
22617
22618   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22619
22620   mp->is_ip4 = is_ip4;
22621   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22622   mp->plen = plen;
22623   mp->is_add = is_add;
22624   if (is_ip4)
22625     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22626   else
22627     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22628
22629   S (mp);
22630   W (ret);
22631   return ret;
22632 }
22633
22634 static int
22635 api_qos_record_enable_disable (vat_main_t * vam)
22636 {
22637   unformat_input_t *i = vam->input;
22638   vl_api_qos_record_enable_disable_t *mp;
22639   u32 sw_if_index, qs = 0xff;
22640   u8 sw_if_index_set = 0;
22641   u8 enable = 1;
22642   int ret;
22643
22644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22645     {
22646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22647         sw_if_index_set = 1;
22648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22649         sw_if_index_set = 1;
22650       else if (unformat (i, "%U", unformat_qos_source, &qs))
22651         ;
22652       else if (unformat (i, "disable"))
22653         enable = 0;
22654       else
22655         {
22656           clib_warning ("parse error '%U'", format_unformat_error, i);
22657           return -99;
22658         }
22659     }
22660
22661   if (sw_if_index_set == 0)
22662     {
22663       errmsg ("missing interface name or sw_if_index");
22664       return -99;
22665     }
22666   if (qs == 0xff)
22667     {
22668       errmsg ("input location must be specified");
22669       return -99;
22670     }
22671
22672   M (QOS_RECORD_ENABLE_DISABLE, mp);
22673
22674   mp->sw_if_index = ntohl (sw_if_index);
22675   mp->input_source = qs;
22676   mp->enable = enable;
22677
22678   S (mp);
22679   W (ret);
22680   return ret;
22681 }
22682
22683
22684 static int
22685 q_or_quit (vat_main_t * vam)
22686 {
22687 #if VPP_API_TEST_BUILTIN == 0
22688   longjmp (vam->jump_buf, 1);
22689 #endif
22690   return 0;                     /* not so much */
22691 }
22692
22693 static int
22694 q (vat_main_t * vam)
22695 {
22696   return q_or_quit (vam);
22697 }
22698
22699 static int
22700 quit (vat_main_t * vam)
22701 {
22702   return q_or_quit (vam);
22703 }
22704
22705 static int
22706 comment (vat_main_t * vam)
22707 {
22708   return 0;
22709 }
22710
22711 static int
22712 statseg (vat_main_t * vam)
22713 {
22714   ssvm_private_t *ssvmp = &vam->stat_segment;
22715   ssvm_shared_header_t *shared_header = ssvmp->sh;
22716   vlib_counter_t **counters;
22717   u64 thread0_index1_packets;
22718   u64 thread0_index1_bytes;
22719   f64 vector_rate, input_rate;
22720   uword *p;
22721
22722   uword *counter_vector_by_name;
22723   if (vam->stat_segment_lockp == 0)
22724     {
22725       errmsg ("Stat segment not mapped...");
22726       return -99;
22727     }
22728
22729   /* look up "/if/rx for sw_if_index 1 as a test */
22730
22731   clib_spinlock_lock (vam->stat_segment_lockp);
22732
22733   counter_vector_by_name = (uword *) shared_header->opaque[1];
22734
22735   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22736   if (p == 0)
22737     {
22738       clib_spinlock_unlock (vam->stat_segment_lockp);
22739       errmsg ("/if/tx not found?");
22740       return -99;
22741     }
22742
22743   /* Fish per-thread vector of combined counters from shared memory */
22744   counters = (vlib_counter_t **) p[0];
22745
22746   if (vec_len (counters[0]) < 2)
22747     {
22748       clib_spinlock_unlock (vam->stat_segment_lockp);
22749       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22750       return -99;
22751     }
22752
22753   /* Read thread 0 sw_if_index 1 counter */
22754   thread0_index1_packets = counters[0][1].packets;
22755   thread0_index1_bytes = counters[0][1].bytes;
22756
22757   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22758   if (p == 0)
22759     {
22760       clib_spinlock_unlock (vam->stat_segment_lockp);
22761       errmsg ("vector_rate not found?");
22762       return -99;
22763     }
22764
22765   vector_rate = *(f64 *) (p[0]);
22766   p = hash_get_mem (counter_vector_by_name, "input_rate");
22767   if (p == 0)
22768     {
22769       clib_spinlock_unlock (vam->stat_segment_lockp);
22770       errmsg ("input_rate not found?");
22771       return -99;
22772     }
22773   input_rate = *(f64 *) (p[0]);
22774
22775   clib_spinlock_unlock (vam->stat_segment_lockp);
22776
22777   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22778          vector_rate, input_rate);
22779   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22780          thread0_index1_packets, thread0_index1_bytes);
22781
22782   return 0;
22783 }
22784
22785 static int
22786 cmd_cmp (void *a1, void *a2)
22787 {
22788   u8 **c1 = a1;
22789   u8 **c2 = a2;
22790
22791   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22792 }
22793
22794 static int
22795 help (vat_main_t * vam)
22796 {
22797   u8 **cmds = 0;
22798   u8 *name = 0;
22799   hash_pair_t *p;
22800   unformat_input_t *i = vam->input;
22801   int j;
22802
22803   if (unformat (i, "%s", &name))
22804     {
22805       uword *hs;
22806
22807       vec_add1 (name, 0);
22808
22809       hs = hash_get_mem (vam->help_by_name, name);
22810       if (hs)
22811         print (vam->ofp, "usage: %s %s", name, hs[0]);
22812       else
22813         print (vam->ofp, "No such msg / command '%s'", name);
22814       vec_free (name);
22815       return 0;
22816     }
22817
22818   print (vam->ofp, "Help is available for the following:");
22819
22820     /* *INDENT-OFF* */
22821     hash_foreach_pair (p, vam->function_by_name,
22822     ({
22823       vec_add1 (cmds, (u8 *)(p->key));
22824     }));
22825     /* *INDENT-ON* */
22826
22827   vec_sort_with_function (cmds, cmd_cmp);
22828
22829   for (j = 0; j < vec_len (cmds); j++)
22830     print (vam->ofp, "%s", cmds[j]);
22831
22832   vec_free (cmds);
22833   return 0;
22834 }
22835
22836 static int
22837 set (vat_main_t * vam)
22838 {
22839   u8 *name = 0, *value = 0;
22840   unformat_input_t *i = vam->input;
22841
22842   if (unformat (i, "%s", &name))
22843     {
22844       /* The input buffer is a vector, not a string. */
22845       value = vec_dup (i->buffer);
22846       vec_delete (value, i->index, 0);
22847       /* Almost certainly has a trailing newline */
22848       if (value[vec_len (value) - 1] == '\n')
22849         value[vec_len (value) - 1] = 0;
22850       /* Make sure it's a proper string, one way or the other */
22851       vec_add1 (value, 0);
22852       (void) clib_macro_set_value (&vam->macro_main,
22853                                    (char *) name, (char *) value);
22854     }
22855   else
22856     errmsg ("usage: set <name> <value>");
22857
22858   vec_free (name);
22859   vec_free (value);
22860   return 0;
22861 }
22862
22863 static int
22864 unset (vat_main_t * vam)
22865 {
22866   u8 *name = 0;
22867
22868   if (unformat (vam->input, "%s", &name))
22869     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22870       errmsg ("unset: %s wasn't set", name);
22871   vec_free (name);
22872   return 0;
22873 }
22874
22875 typedef struct
22876 {
22877   u8 *name;
22878   u8 *value;
22879 } macro_sort_t;
22880
22881
22882 static int
22883 macro_sort_cmp (void *a1, void *a2)
22884 {
22885   macro_sort_t *s1 = a1;
22886   macro_sort_t *s2 = a2;
22887
22888   return strcmp ((char *) (s1->name), (char *) (s2->name));
22889 }
22890
22891 static int
22892 dump_macro_table (vat_main_t * vam)
22893 {
22894   macro_sort_t *sort_me = 0, *sm;
22895   int i;
22896   hash_pair_t *p;
22897
22898     /* *INDENT-OFF* */
22899     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22900     ({
22901       vec_add2 (sort_me, sm, 1);
22902       sm->name = (u8 *)(p->key);
22903       sm->value = (u8 *) (p->value[0]);
22904     }));
22905     /* *INDENT-ON* */
22906
22907   vec_sort_with_function (sort_me, macro_sort_cmp);
22908
22909   if (vec_len (sort_me))
22910     print (vam->ofp, "%-15s%s", "Name", "Value");
22911   else
22912     print (vam->ofp, "The macro table is empty...");
22913
22914   for (i = 0; i < vec_len (sort_me); i++)
22915     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22916   return 0;
22917 }
22918
22919 static int
22920 dump_node_table (vat_main_t * vam)
22921 {
22922   int i, j;
22923   vlib_node_t *node, *next_node;
22924
22925   if (vec_len (vam->graph_nodes) == 0)
22926     {
22927       print (vam->ofp, "Node table empty, issue get_node_graph...");
22928       return 0;
22929     }
22930
22931   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22932     {
22933       node = vam->graph_nodes[0][i];
22934       print (vam->ofp, "[%d] %s", i, node->name);
22935       for (j = 0; j < vec_len (node->next_nodes); j++)
22936         {
22937           if (node->next_nodes[j] != ~0)
22938             {
22939               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22940               print (vam->ofp, "  [%d] %s", j, next_node->name);
22941             }
22942         }
22943     }
22944   return 0;
22945 }
22946
22947 static int
22948 value_sort_cmp (void *a1, void *a2)
22949 {
22950   name_sort_t *n1 = a1;
22951   name_sort_t *n2 = a2;
22952
22953   if (n1->value < n2->value)
22954     return -1;
22955   if (n1->value > n2->value)
22956     return 1;
22957   return 0;
22958 }
22959
22960
22961 static int
22962 dump_msg_api_table (vat_main_t * vam)
22963 {
22964   api_main_t *am = &api_main;
22965   name_sort_t *nses = 0, *ns;
22966   hash_pair_t *hp;
22967   int i;
22968
22969   /* *INDENT-OFF* */
22970   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22971   ({
22972     vec_add2 (nses, ns, 1);
22973     ns->name = (u8 *)(hp->key);
22974     ns->value = (u32) hp->value[0];
22975   }));
22976   /* *INDENT-ON* */
22977
22978   vec_sort_with_function (nses, value_sort_cmp);
22979
22980   for (i = 0; i < vec_len (nses); i++)
22981     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22982   vec_free (nses);
22983   return 0;
22984 }
22985
22986 static int
22987 get_msg_id (vat_main_t * vam)
22988 {
22989   u8 *name_and_crc;
22990   u32 message_index;
22991
22992   if (unformat (vam->input, "%s", &name_and_crc))
22993     {
22994       message_index = vl_msg_api_get_msg_index (name_and_crc);
22995       if (message_index == ~0)
22996         {
22997           print (vam->ofp, " '%s' not found", name_and_crc);
22998           return 0;
22999         }
23000       print (vam->ofp, " '%s' has message index %d",
23001              name_and_crc, message_index);
23002       return 0;
23003     }
23004   errmsg ("name_and_crc required...");
23005   return 0;
23006 }
23007
23008 static int
23009 search_node_table (vat_main_t * vam)
23010 {
23011   unformat_input_t *line_input = vam->input;
23012   u8 *node_to_find;
23013   int j;
23014   vlib_node_t *node, *next_node;
23015   uword *p;
23016
23017   if (vam->graph_node_index_by_name == 0)
23018     {
23019       print (vam->ofp, "Node table empty, issue get_node_graph...");
23020       return 0;
23021     }
23022
23023   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23024     {
23025       if (unformat (line_input, "%s", &node_to_find))
23026         {
23027           vec_add1 (node_to_find, 0);
23028           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23029           if (p == 0)
23030             {
23031               print (vam->ofp, "%s not found...", node_to_find);
23032               goto out;
23033             }
23034           node = vam->graph_nodes[0][p[0]];
23035           print (vam->ofp, "[%d] %s", p[0], node->name);
23036           for (j = 0; j < vec_len (node->next_nodes); j++)
23037             {
23038               if (node->next_nodes[j] != ~0)
23039                 {
23040                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23041                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23042                 }
23043             }
23044         }
23045
23046       else
23047         {
23048           clib_warning ("parse error '%U'", format_unformat_error,
23049                         line_input);
23050           return -99;
23051         }
23052
23053     out:
23054       vec_free (node_to_find);
23055
23056     }
23057
23058   return 0;
23059 }
23060
23061
23062 static int
23063 script (vat_main_t * vam)
23064 {
23065 #if (VPP_API_TEST_BUILTIN==0)
23066   u8 *s = 0;
23067   char *save_current_file;
23068   unformat_input_t save_input;
23069   jmp_buf save_jump_buf;
23070   u32 save_line_number;
23071
23072   FILE *new_fp, *save_ifp;
23073
23074   if (unformat (vam->input, "%s", &s))
23075     {
23076       new_fp = fopen ((char *) s, "r");
23077       if (new_fp == 0)
23078         {
23079           errmsg ("Couldn't open script file %s", s);
23080           vec_free (s);
23081           return -99;
23082         }
23083     }
23084   else
23085     {
23086       errmsg ("Missing script name");
23087       return -99;
23088     }
23089
23090   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23091   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23092   save_ifp = vam->ifp;
23093   save_line_number = vam->input_line_number;
23094   save_current_file = (char *) vam->current_file;
23095
23096   vam->input_line_number = 0;
23097   vam->ifp = new_fp;
23098   vam->current_file = s;
23099   do_one_file (vam);
23100
23101   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23102   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23103   vam->ifp = save_ifp;
23104   vam->input_line_number = save_line_number;
23105   vam->current_file = (u8 *) save_current_file;
23106   vec_free (s);
23107
23108   return 0;
23109 #else
23110   clib_warning ("use the exec command...");
23111   return -99;
23112 #endif
23113 }
23114
23115 static int
23116 echo (vat_main_t * vam)
23117 {
23118   print (vam->ofp, "%v", vam->input->buffer);
23119   return 0;
23120 }
23121
23122 /* List of API message constructors, CLI names map to api_xxx */
23123 #define foreach_vpe_api_msg                                             \
23124 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23125 _(sw_interface_dump,"")                                                 \
23126 _(sw_interface_set_flags,                                               \
23127   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23128 _(sw_interface_add_del_address,                                         \
23129   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23130 _(sw_interface_set_rx_mode,                                             \
23131   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23132 _(sw_interface_set_rx_placement,                                        \
23133   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23134 _(sw_interface_rx_placement_dump,                                       \
23135   "[<intfc> | sw_if_index <id>]")                                         \
23136 _(sw_interface_set_table,                                               \
23137   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23138 _(sw_interface_set_mpls_enable,                                         \
23139   "<intfc> | sw_if_index [disable | dis]")                              \
23140 _(sw_interface_set_vpath,                                               \
23141   "<intfc> | sw_if_index <id> enable | disable")                        \
23142 _(sw_interface_set_vxlan_bypass,                                        \
23143   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23144 _(sw_interface_set_geneve_bypass,                                       \
23145   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23146 _(sw_interface_set_l2_xconnect,                                         \
23147   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23148   "enable | disable")                                                   \
23149 _(sw_interface_set_l2_bridge,                                           \
23150   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23151   "[shg <split-horizon-group>] [bvi]\n"                                 \
23152   "enable | disable")                                                   \
23153 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23154 _(bridge_domain_add_del,                                                \
23155   "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") \
23156 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23157 _(l2fib_add_del,                                                        \
23158   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23159 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23160 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23161 _(l2_flags,                                                             \
23162   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23163 _(bridge_flags,                                                         \
23164   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23165 _(tap_connect,                                                          \
23166   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23167 _(tap_modify,                                                           \
23168   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23169 _(tap_delete,                                                           \
23170   "<vpp-if-name> | sw_if_index <id>")                                   \
23171 _(sw_interface_tap_dump, "")                                            \
23172 _(tap_create_v2,                                                        \
23173   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23174 _(tap_delete_v2,                                                        \
23175   "<vpp-if-name> | sw_if_index <id>")                                   \
23176 _(sw_interface_tap_v2_dump, "")                                         \
23177 _(bond_create,                                                          \
23178   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23179   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23180 _(bond_delete,                                                          \
23181   "<vpp-if-name> | sw_if_index <id>")                                   \
23182 _(bond_enslave,                                                         \
23183   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23184 _(bond_detach_slave,                                                    \
23185   "sw_if_index <n>")                                                    \
23186 _(sw_interface_bond_dump, "")                                           \
23187 _(sw_interface_slave_dump,                                              \
23188   "<vpp-if-name> | sw_if_index <id>")                                   \
23189 _(ip_table_add_del,                                                     \
23190   "table <n> [ipv6] [add | del]\n")                                     \
23191 _(ip_add_del_route,                                                     \
23192   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23193   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23194   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23195   "[multipath] [count <n>] [del]")                                      \
23196 _(ip_mroute_add_del,                                                    \
23197   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23198   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23199 _(mpls_table_add_del,                                                   \
23200   "table <n> [add | del]\n")                                            \
23201 _(mpls_route_add_del,                                                   \
23202   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23203   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23204   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23205   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23206   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23207   "[count <n>] [del]")                                                  \
23208 _(mpls_ip_bind_unbind,                                                  \
23209   "<label> <addr/len>")                                                 \
23210 _(mpls_tunnel_add_del,                                                  \
23211   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23212   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23213   "[l2-only]  [out-label <n>]")                                         \
23214 _(sr_mpls_policy_add,                                                   \
23215   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23216 _(sr_mpls_policy_del,                                                   \
23217   "bsid <id>")                                                          \
23218 _(bier_table_add_del,                                                   \
23219   "<label> <sub-domain> <set> <bsl> [del]")                             \
23220 _(bier_route_add_del,                                                   \
23221   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23222   "[<intfc> | sw_if_index <id>]"                                        \
23223   "[weight <n>] [del] [multipath]")                                     \
23224 _(proxy_arp_add_del,                                                    \
23225   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23226 _(proxy_arp_intfc_enable_disable,                                       \
23227   "<intfc> | sw_if_index <id> enable | disable")                        \
23228 _(sw_interface_set_unnumbered,                                          \
23229   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23230 _(ip_neighbor_add_del,                                                  \
23231   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23232   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23233 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23234 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23235   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23236   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23237   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23238 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23239 _(reset_fib, "vrf <n> [ipv6]")                                          \
23240 _(dhcp_proxy_config,                                                    \
23241   "svr <v46-address> src <v46-address>\n"                               \
23242    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23243 _(dhcp_proxy_set_vss,                                                   \
23244   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23245 _(dhcp_proxy_dump, "ip6")                                               \
23246 _(dhcp_client_config,                                                   \
23247   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23248 _(set_ip_flow_hash,                                                     \
23249   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23250 _(sw_interface_ip6_enable_disable,                                      \
23251   "<intfc> | sw_if_index <id> enable | disable")                        \
23252 _(ip6nd_proxy_add_del,                                                  \
23253   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23254 _(ip6nd_proxy_dump, "")                                                 \
23255 _(sw_interface_ip6nd_ra_prefix,                                         \
23256   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23257   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23258   "[nolink] [isno]")                                                    \
23259 _(sw_interface_ip6nd_ra_config,                                         \
23260   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23261   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23262   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23263 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23264 _(l2_patch_add_del,                                                     \
23265   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23266   "enable | disable")                                                   \
23267 _(sr_localsid_add_del,                                                  \
23268   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23269   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23270 _(classify_add_del_table,                                               \
23271   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23272   " [del] [del-chain] mask <mask-value>\n"                              \
23273   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23274   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23275 _(classify_add_del_session,                                             \
23276   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23277   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23278   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23279   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23280 _(classify_set_interface_ip_table,                                      \
23281   "<intfc> | sw_if_index <nn> table <nn>")                              \
23282 _(classify_set_interface_l2_tables,                                     \
23283   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23284   "  [other-table <nn>]")                                               \
23285 _(get_node_index, "node <node-name")                                    \
23286 _(add_node_next, "node <node-name> next <next-node-name>")              \
23287 _(l2tpv3_create_tunnel,                                                 \
23288   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23289   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23290   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23291 _(l2tpv3_set_tunnel_cookies,                                            \
23292   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23293   "[new_remote_cookie <nn>]\n")                                         \
23294 _(l2tpv3_interface_enable_disable,                                      \
23295   "<intfc> | sw_if_index <nn> enable | disable")                        \
23296 _(l2tpv3_set_lookup_key,                                                \
23297   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23298 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23299 _(vxlan_offload_rx,                                                     \
23300   "hw { <interface name> | hw_if_index <nn>} "                          \
23301   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23302 _(vxlan_add_del_tunnel,                                                 \
23303   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23304   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23305   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23306 _(geneve_add_del_tunnel,                                                \
23307   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23308   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23309   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23310 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23311 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23312 _(gre_add_del_tunnel,                                                   \
23313   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23314   "[teb | erspan <session-id>] [del]")                                  \
23315 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23316 _(l2_fib_clear_table, "")                                               \
23317 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23318 _(l2_interface_vlan_tag_rewrite,                                        \
23319   "<intfc> | sw_if_index <nn> \n"                                       \
23320   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23321   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23322 _(create_vhost_user_if,                                                 \
23323         "socket <filename> [server] [renumber <dev_instance>] "         \
23324         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23325         "[mac <mac_address>]")                                          \
23326 _(modify_vhost_user_if,                                                 \
23327         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23328         "[server] [renumber <dev_instance>]")                           \
23329 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23330 _(sw_interface_vhost_user_dump, "")                                     \
23331 _(show_version, "")                                                     \
23332 _(show_threads, "")                                                     \
23333 _(vxlan_gpe_add_del_tunnel,                                             \
23334   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23335   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23336   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23337   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23338 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23339 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23340 _(interface_name_renumber,                                              \
23341   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23342 _(input_acl_set_interface,                                              \
23343   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23344   "  [l2-table <nn>] [del]")                                            \
23345 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23346 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23347   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23348 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23349 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23350 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23351 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23352 _(ip_dump, "ipv4 | ipv6")                                               \
23353 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23354 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23355   "  spid_id <n> ")                                                     \
23356 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23357   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23358   "  integ_alg <alg> integ_key <hex>")                                  \
23359 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23360   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23361   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23362   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23363 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23364 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23365   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23366   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23367   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23368   "  [instance <n>]")     \
23369 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23370 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23371   "  <alg> <hex>\n")                                                    \
23372 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23373 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23374 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23375   "(auth_data 0x<data> | auth_data <data>)")                            \
23376 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23377   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23378 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23379   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23380   "(local|remote)")                                                     \
23381 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23382 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23383 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23384 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23385 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23386 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23387 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23388 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23389 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23390 _(delete_loopback,"sw_if_index <nn>")                                   \
23391 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23392 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23393 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23394 _(want_interface_events,  "enable|disable")                             \
23395 _(get_first_msg_id, "client <name>")                                    \
23396 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23397 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23398   "fib-id <nn> [ip4][ip6][default]")                                    \
23399 _(get_node_graph, " ")                                                  \
23400 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23401 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23402 _(ioam_disable, "")                                                     \
23403 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23404                             " sw_if_index <sw_if_index> p <priority> "  \
23405                             "w <weight>] [del]")                        \
23406 _(one_add_del_locator, "locator-set <locator_name> "                    \
23407                         "iface <intf> | sw_if_index <sw_if_index> "     \
23408                         "p <priority> w <weight> [del]")                \
23409 _(one_add_del_local_eid,"vni <vni> eid "                                \
23410                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23411                          "locator-set <locator_name> [del]"             \
23412                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23413 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23414 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23415 _(one_enable_disable, "enable|disable")                                 \
23416 _(one_map_register_enable_disable, "enable|disable")                    \
23417 _(one_map_register_fallback_threshold, "<value>")                       \
23418 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23419 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23420                                "[seid <seid>] "                         \
23421                                "rloc <locator> p <prio> "               \
23422                                "w <weight> [rloc <loc> ... ] "          \
23423                                "action <action> [del-all]")             \
23424 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23425                           "<local-eid>")                                \
23426 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23427 _(one_use_petr, "ip-address> | disable")                                \
23428 _(one_map_request_mode, "src-dst|dst-only")                             \
23429 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23430 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23431 _(one_locator_set_dump, "[local | remote]")                             \
23432 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23433 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23434                        "[local] | [remote]")                            \
23435 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23436 _(one_ndp_bd_get, "")                                                   \
23437 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23438 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23439 _(one_l2_arp_bd_get, "")                                                \
23440 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23441 _(one_stats_enable_disable, "enable|disable")                           \
23442 _(show_one_stats_enable_disable, "")                                    \
23443 _(one_eid_table_vni_dump, "")                                           \
23444 _(one_eid_table_map_dump, "l2|l3")                                      \
23445 _(one_map_resolver_dump, "")                                            \
23446 _(one_map_server_dump, "")                                              \
23447 _(one_adjacencies_get, "vni <vni>")                                     \
23448 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23449 _(show_one_rloc_probe_state, "")                                        \
23450 _(show_one_map_register_state, "")                                      \
23451 _(show_one_status, "")                                                  \
23452 _(one_stats_dump, "")                                                   \
23453 _(one_stats_flush, "")                                                  \
23454 _(one_get_map_request_itr_rlocs, "")                                    \
23455 _(one_map_register_set_ttl, "<ttl>")                                    \
23456 _(one_set_transport_protocol, "udp|api")                                \
23457 _(one_get_transport_protocol, "")                                       \
23458 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23459 _(one_show_xtr_mode, "")                                                \
23460 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23461 _(one_show_pitr_mode, "")                                               \
23462 _(one_enable_disable_petr_mode, "enable|disable")                       \
23463 _(one_show_petr_mode, "")                                               \
23464 _(show_one_nsh_mapping, "")                                             \
23465 _(show_one_pitr, "")                                                    \
23466 _(show_one_use_petr, "")                                                \
23467 _(show_one_map_request_mode, "")                                        \
23468 _(show_one_map_register_ttl, "")                                        \
23469 _(show_one_map_register_fallback_threshold, "")                         \
23470 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23471                             " sw_if_index <sw_if_index> p <priority> "  \
23472                             "w <weight>] [del]")                        \
23473 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23474                         "iface <intf> | sw_if_index <sw_if_index> "     \
23475                         "p <priority> w <weight> [del]")                \
23476 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23477                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23478                          "locator-set <locator_name> [del]"             \
23479                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23480 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23481 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23482 _(lisp_enable_disable, "enable|disable")                                \
23483 _(lisp_map_register_enable_disable, "enable|disable")                   \
23484 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23485 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23486                                "[seid <seid>] "                         \
23487                                "rloc <locator> p <prio> "               \
23488                                "w <weight> [rloc <loc> ... ] "          \
23489                                "action <action> [del-all]")             \
23490 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23491                           "<local-eid>")                                \
23492 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23493 _(lisp_use_petr, "<ip-address> | disable")                              \
23494 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23495 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23496 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23497 _(lisp_locator_set_dump, "[local | remote]")                            \
23498 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23499 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23500                        "[local] | [remote]")                            \
23501 _(lisp_eid_table_vni_dump, "")                                          \
23502 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23503 _(lisp_map_resolver_dump, "")                                           \
23504 _(lisp_map_server_dump, "")                                             \
23505 _(lisp_adjacencies_get, "vni <vni>")                                    \
23506 _(gpe_fwd_entry_vnis_get, "")                                           \
23507 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23508 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23509                                 "[table <table-id>]")                   \
23510 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23511 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23512 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23513 _(gpe_get_encap_mode, "")                                               \
23514 _(lisp_gpe_add_del_iface, "up|down")                                    \
23515 _(lisp_gpe_enable_disable, "enable|disable")                            \
23516 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23517   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23518 _(show_lisp_rloc_probe_state, "")                                       \
23519 _(show_lisp_map_register_state, "")                                     \
23520 _(show_lisp_status, "")                                                 \
23521 _(lisp_get_map_request_itr_rlocs, "")                                   \
23522 _(show_lisp_pitr, "")                                                   \
23523 _(show_lisp_use_petr, "")                                               \
23524 _(show_lisp_map_request_mode, "")                                       \
23525 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23526 _(af_packet_delete, "name <host interface name>")                       \
23527 _(af_packet_dump, "")                                                   \
23528 _(policer_add_del, "name <policer name> <params> [del]")                \
23529 _(policer_dump, "[name <policer name>]")                                \
23530 _(policer_classify_set_interface,                                       \
23531   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23532   "  [l2-table <nn>] [del]")                                            \
23533 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23534 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23535     "[master|slave]")                                                   \
23536 _(netmap_delete, "name <interface name>")                               \
23537 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23538 _(mpls_fib_dump, "")                                                    \
23539 _(classify_table_ids, "")                                               \
23540 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23541 _(classify_table_info, "table_id <nn>")                                 \
23542 _(classify_session_dump, "table_id <nn>")                               \
23543 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23544     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23545     "[template_interval <nn>] [udp_checksum]")                          \
23546 _(ipfix_exporter_dump, "")                                              \
23547 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23548 _(ipfix_classify_stream_dump, "")                                       \
23549 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23550 _(ipfix_classify_table_dump, "")                                        \
23551 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23552 _(sw_interface_span_dump, "[l2]")                                           \
23553 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23554 _(pg_create_interface, "if_id <nn>")                                    \
23555 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23556 _(pg_enable_disable, "[stream <id>] disable")                           \
23557 _(ip_source_and_port_range_check_add_del,                               \
23558   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23559 _(ip_source_and_port_range_check_interface_add_del,                     \
23560   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23561   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23562 _(ipsec_gre_add_del_tunnel,                                             \
23563   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23564 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23565 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23566 _(l2_interface_pbb_tag_rewrite,                                         \
23567   "<intfc> | sw_if_index <nn> \n"                                       \
23568   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23569   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23570 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23571 _(flow_classify_set_interface,                                          \
23572   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23573 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23574 _(ip_fib_dump, "")                                                      \
23575 _(ip_mfib_dump, "")                                                     \
23576 _(ip6_fib_dump, "")                                                     \
23577 _(ip6_mfib_dump, "")                                                    \
23578 _(feature_enable_disable, "arc_name <arc_name> "                        \
23579   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23580 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23581 "[disable]")                                                            \
23582 _(l2_xconnect_dump, "")                                                 \
23583 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23584 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23585 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23586 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23587 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23588 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23589 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23590   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23591 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23592 _(sock_init_shm, "size <nnn>")                                          \
23593 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23594 _(dns_enable_disable, "[enable][disable]")                              \
23595 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23596 _(dns_resolve_name, "<hostname>")                                       \
23597 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23598 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23599 _(dns_resolve_name, "<hostname>")                                       \
23600 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23601   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23602 _(session_rules_dump, "")                                               \
23603 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23604 _(output_acl_set_interface,                                             \
23605   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23606   "  [l2-table <nn>] [del]")                                            \
23607 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23608
23609 /* List of command functions, CLI names map directly to functions */
23610 #define foreach_cli_function                                    \
23611 _(comment, "usage: comment <ignore-rest-of-line>")              \
23612 _(dump_interface_table, "usage: dump_interface_table")          \
23613 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23614 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23615 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23616 _(dump_macro_table, "usage: dump_macro_table ")                 \
23617 _(dump_node_table, "usage: dump_node_table")                    \
23618 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23619 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23620 _(echo, "usage: echo <message>")                                \
23621 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23622 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23623 _(help, "usage: help")                                          \
23624 _(q, "usage: quit")                                             \
23625 _(quit, "usage: quit")                                          \
23626 _(search_node_table, "usage: search_node_table <name>...")      \
23627 _(set, "usage: set <variable-name> <value>")                    \
23628 _(script, "usage: script <file-name>")                          \
23629 _(statseg, "usage: statseg");                                   \
23630 _(unset, "usage: unset <variable-name>")
23631
23632 #define _(N,n)                                  \
23633     static void vl_api_##n##_t_handler_uni      \
23634     (vl_api_##n##_t * mp)                       \
23635     {                                           \
23636         vat_main_t * vam = &vat_main;           \
23637         if (vam->json_output) {                 \
23638             vl_api_##n##_t_handler_json(mp);    \
23639         } else {                                \
23640             vl_api_##n##_t_handler(mp);         \
23641         }                                       \
23642     }
23643 foreach_vpe_api_reply_msg;
23644 #if VPP_API_TEST_BUILTIN == 0
23645 foreach_standalone_reply_msg;
23646 #endif
23647 #undef _
23648
23649 void
23650 vat_api_hookup (vat_main_t * vam)
23651 {
23652 #define _(N,n)                                                  \
23653     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23654                            vl_api_##n##_t_handler_uni,          \
23655                            vl_noop_handler,                     \
23656                            vl_api_##n##_t_endian,               \
23657                            vl_api_##n##_t_print,                \
23658                            sizeof(vl_api_##n##_t), 1);
23659   foreach_vpe_api_reply_msg;
23660 #if VPP_API_TEST_BUILTIN == 0
23661   foreach_standalone_reply_msg;
23662 #endif
23663 #undef _
23664
23665 #if (VPP_API_TEST_BUILTIN==0)
23666   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23667
23668   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23669
23670   vam->function_by_name = hash_create_string (0, sizeof (uword));
23671
23672   vam->help_by_name = hash_create_string (0, sizeof (uword));
23673 #endif
23674
23675   /* API messages we can send */
23676 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23677   foreach_vpe_api_msg;
23678 #undef _
23679
23680   /* Help strings */
23681 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23682   foreach_vpe_api_msg;
23683 #undef _
23684
23685   /* CLI functions */
23686 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23687   foreach_cli_function;
23688 #undef _
23689
23690   /* Help strings */
23691 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23692   foreach_cli_function;
23693 #undef _
23694 }
23695
23696 #if VPP_API_TEST_BUILTIN
23697 static clib_error_t *
23698 vat_api_hookup_shim (vlib_main_t * vm)
23699 {
23700   vat_api_hookup (&vat_main);
23701   return 0;
23702 }
23703
23704 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23705 #endif
23706
23707 /*
23708  * fd.io coding-style-patch-verification: ON
23709  *
23710  * Local Variables:
23711  * eval: (c-set-style "gnu")
23712  * End:
23713  */