L2 BD API to flush all IP-MAC entries in the specified BD
[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",
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);
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_string_copy (node, "dev_name", mp->dev_name);
12743   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12744   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12745   vat_json_object_add_string_copy (node, "host_mac_addr",
12746                                    format (0, "%U", format_ethernet_address,
12747                                            &mp->host_mac_addr));
12748   vat_json_object_add_string_copy (node, "host_namespace",
12749                                    mp->host_namespace);
12750   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12751   vat_json_object_add_string_copy (node, "host_ip4_addr",
12752                                    format (0, "%U/%d", format_ip4_address,
12753                                            mp->host_ip4_addr,
12754                                            mp->host_ip4_prefix_len));
12755   vat_json_object_add_string_copy (node, "host_ip6_addr",
12756                                    format (0, "%U/%d", format_ip6_address,
12757                                            mp->host_ip6_addr,
12758                                            mp->host_ip6_prefix_len));
12759
12760 }
12761
12762 static int
12763 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12764 {
12765   vl_api_sw_interface_tap_v2_dump_t *mp;
12766   vl_api_control_ping_t *mp_ping;
12767   int ret;
12768
12769   print (vam->ofp,
12770          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12771          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12772          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12773          "host_ip6_addr");
12774
12775   /* Get list of tap interfaces */
12776   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12777   S (mp);
12778
12779   /* Use a control ping for synchronization */
12780   MPING (CONTROL_PING, mp_ping);
12781   S (mp_ping);
12782
12783   W (ret);
12784   return ret;
12785 }
12786
12787 static int
12788 api_vxlan_offload_rx (vat_main_t * vam)
12789 {
12790   unformat_input_t *line_input = vam->input;
12791   vl_api_vxlan_offload_rx_t *mp;
12792   u32 hw_if_index = ~0, rx_if_index = ~0;
12793   u8 is_add = 1;
12794   int ret;
12795
12796   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12797     {
12798       if (unformat (line_input, "del"))
12799         is_add = 0;
12800       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12801                          &hw_if_index))
12802         ;
12803       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12804         ;
12805       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12806                          &rx_if_index))
12807         ;
12808       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12809         ;
12810       else
12811         {
12812           errmsg ("parse error '%U'", format_unformat_error, line_input);
12813           return -99;
12814         }
12815     }
12816
12817   if (hw_if_index == ~0)
12818     {
12819       errmsg ("no hw interface");
12820       return -99;
12821     }
12822
12823   if (rx_if_index == ~0)
12824     {
12825       errmsg ("no rx tunnel");
12826       return -99;
12827     }
12828
12829   M (VXLAN_OFFLOAD_RX, mp);
12830
12831   mp->hw_if_index = ntohl (hw_if_index);
12832   mp->sw_if_index = ntohl (rx_if_index);
12833   mp->enable = is_add;
12834
12835   S (mp);
12836   W (ret);
12837   return ret;
12838 }
12839
12840 static uword unformat_vxlan_decap_next
12841   (unformat_input_t * input, va_list * args)
12842 {
12843   u32 *result = va_arg (*args, u32 *);
12844   u32 tmp;
12845
12846   if (unformat (input, "l2"))
12847     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12848   else if (unformat (input, "%d", &tmp))
12849     *result = tmp;
12850   else
12851     return 0;
12852   return 1;
12853 }
12854
12855 static int
12856 api_vxlan_add_del_tunnel (vat_main_t * vam)
12857 {
12858   unformat_input_t *line_input = vam->input;
12859   vl_api_vxlan_add_del_tunnel_t *mp;
12860   ip46_address_t src, dst;
12861   u8 is_add = 1;
12862   u8 ipv4_set = 0, ipv6_set = 0;
12863   u8 src_set = 0;
12864   u8 dst_set = 0;
12865   u8 grp_set = 0;
12866   u32 instance = ~0;
12867   u32 mcast_sw_if_index = ~0;
12868   u32 encap_vrf_id = 0;
12869   u32 decap_next_index = ~0;
12870   u32 vni = 0;
12871   int ret;
12872
12873   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12874   clib_memset (&src, 0, sizeof src);
12875   clib_memset (&dst, 0, sizeof dst);
12876
12877   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12878     {
12879       if (unformat (line_input, "del"))
12880         is_add = 0;
12881       else if (unformat (line_input, "instance %d", &instance))
12882         ;
12883       else
12884         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12885         {
12886           ipv4_set = 1;
12887           src_set = 1;
12888         }
12889       else
12890         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12891         {
12892           ipv4_set = 1;
12893           dst_set = 1;
12894         }
12895       else
12896         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12897         {
12898           ipv6_set = 1;
12899           src_set = 1;
12900         }
12901       else
12902         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12903         {
12904           ipv6_set = 1;
12905           dst_set = 1;
12906         }
12907       else if (unformat (line_input, "group %U %U",
12908                          unformat_ip4_address, &dst.ip4,
12909                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12910         {
12911           grp_set = dst_set = 1;
12912           ipv4_set = 1;
12913         }
12914       else if (unformat (line_input, "group %U",
12915                          unformat_ip4_address, &dst.ip4))
12916         {
12917           grp_set = dst_set = 1;
12918           ipv4_set = 1;
12919         }
12920       else if (unformat (line_input, "group %U %U",
12921                          unformat_ip6_address, &dst.ip6,
12922                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12923         {
12924           grp_set = dst_set = 1;
12925           ipv6_set = 1;
12926         }
12927       else if (unformat (line_input, "group %U",
12928                          unformat_ip6_address, &dst.ip6))
12929         {
12930           grp_set = dst_set = 1;
12931           ipv6_set = 1;
12932         }
12933       else
12934         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12935         ;
12936       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12937         ;
12938       else if (unformat (line_input, "decap-next %U",
12939                          unformat_vxlan_decap_next, &decap_next_index))
12940         ;
12941       else if (unformat (line_input, "vni %d", &vni))
12942         ;
12943       else
12944         {
12945           errmsg ("parse error '%U'", format_unformat_error, line_input);
12946           return -99;
12947         }
12948     }
12949
12950   if (src_set == 0)
12951     {
12952       errmsg ("tunnel src address not specified");
12953       return -99;
12954     }
12955   if (dst_set == 0)
12956     {
12957       errmsg ("tunnel dst address not specified");
12958       return -99;
12959     }
12960
12961   if (grp_set && !ip46_address_is_multicast (&dst))
12962     {
12963       errmsg ("tunnel group address not multicast");
12964       return -99;
12965     }
12966   if (grp_set && mcast_sw_if_index == ~0)
12967     {
12968       errmsg ("tunnel nonexistent multicast device");
12969       return -99;
12970     }
12971   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12972     {
12973       errmsg ("tunnel dst address must be unicast");
12974       return -99;
12975     }
12976
12977
12978   if (ipv4_set && ipv6_set)
12979     {
12980       errmsg ("both IPv4 and IPv6 addresses specified");
12981       return -99;
12982     }
12983
12984   if ((vni == 0) || (vni >> 24))
12985     {
12986       errmsg ("vni not specified or out of range");
12987       return -99;
12988     }
12989
12990   M (VXLAN_ADD_DEL_TUNNEL, mp);
12991
12992   if (ipv6_set)
12993     {
12994       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12995       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12996     }
12997   else
12998     {
12999       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13000       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13001     }
13002
13003   mp->instance = htonl (instance);
13004   mp->encap_vrf_id = ntohl (encap_vrf_id);
13005   mp->decap_next_index = ntohl (decap_next_index);
13006   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13007   mp->vni = ntohl (vni);
13008   mp->is_add = is_add;
13009   mp->is_ipv6 = ipv6_set;
13010
13011   S (mp);
13012   W (ret);
13013   return ret;
13014 }
13015
13016 static void vl_api_vxlan_tunnel_details_t_handler
13017   (vl_api_vxlan_tunnel_details_t * mp)
13018 {
13019   vat_main_t *vam = &vat_main;
13020   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13021   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13022
13023   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13024          ntohl (mp->sw_if_index),
13025          ntohl (mp->instance),
13026          format_ip46_address, &src, IP46_TYPE_ANY,
13027          format_ip46_address, &dst, IP46_TYPE_ANY,
13028          ntohl (mp->encap_vrf_id),
13029          ntohl (mp->decap_next_index), ntohl (mp->vni),
13030          ntohl (mp->mcast_sw_if_index));
13031 }
13032
13033 static void vl_api_vxlan_tunnel_details_t_handler_json
13034   (vl_api_vxlan_tunnel_details_t * mp)
13035 {
13036   vat_main_t *vam = &vat_main;
13037   vat_json_node_t *node = NULL;
13038
13039   if (VAT_JSON_ARRAY != vam->json_tree.type)
13040     {
13041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13042       vat_json_init_array (&vam->json_tree);
13043     }
13044   node = vat_json_array_add (&vam->json_tree);
13045
13046   vat_json_init_object (node);
13047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13048
13049   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13050
13051   if (mp->is_ipv6)
13052     {
13053       struct in6_addr ip6;
13054
13055       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13056       vat_json_object_add_ip6 (node, "src_address", ip6);
13057       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13058       vat_json_object_add_ip6 (node, "dst_address", ip6);
13059     }
13060   else
13061     {
13062       struct in_addr ip4;
13063
13064       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13065       vat_json_object_add_ip4 (node, "src_address", ip4);
13066       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13067       vat_json_object_add_ip4 (node, "dst_address", ip4);
13068     }
13069   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13070   vat_json_object_add_uint (node, "decap_next_index",
13071                             ntohl (mp->decap_next_index));
13072   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13073   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13074   vat_json_object_add_uint (node, "mcast_sw_if_index",
13075                             ntohl (mp->mcast_sw_if_index));
13076 }
13077
13078 static int
13079 api_vxlan_tunnel_dump (vat_main_t * vam)
13080 {
13081   unformat_input_t *i = vam->input;
13082   vl_api_vxlan_tunnel_dump_t *mp;
13083   vl_api_control_ping_t *mp_ping;
13084   u32 sw_if_index;
13085   u8 sw_if_index_set = 0;
13086   int ret;
13087
13088   /* Parse args required to build the message */
13089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13090     {
13091       if (unformat (i, "sw_if_index %d", &sw_if_index))
13092         sw_if_index_set = 1;
13093       else
13094         break;
13095     }
13096
13097   if (sw_if_index_set == 0)
13098     {
13099       sw_if_index = ~0;
13100     }
13101
13102   if (!vam->json_output)
13103     {
13104       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13105              "sw_if_index", "instance", "src_address", "dst_address",
13106              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13107     }
13108
13109   /* Get list of vxlan-tunnel interfaces */
13110   M (VXLAN_TUNNEL_DUMP, mp);
13111
13112   mp->sw_if_index = htonl (sw_if_index);
13113
13114   S (mp);
13115
13116   /* Use a control ping for synchronization */
13117   MPING (CONTROL_PING, mp_ping);
13118   S (mp_ping);
13119
13120   W (ret);
13121   return ret;
13122 }
13123
13124 static uword unformat_geneve_decap_next
13125   (unformat_input_t * input, va_list * args)
13126 {
13127   u32 *result = va_arg (*args, u32 *);
13128   u32 tmp;
13129
13130   if (unformat (input, "l2"))
13131     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13132   else if (unformat (input, "%d", &tmp))
13133     *result = tmp;
13134   else
13135     return 0;
13136   return 1;
13137 }
13138
13139 static int
13140 api_geneve_add_del_tunnel (vat_main_t * vam)
13141 {
13142   unformat_input_t *line_input = vam->input;
13143   vl_api_geneve_add_del_tunnel_t *mp;
13144   ip46_address_t src, dst;
13145   u8 is_add = 1;
13146   u8 ipv4_set = 0, ipv6_set = 0;
13147   u8 src_set = 0;
13148   u8 dst_set = 0;
13149   u8 grp_set = 0;
13150   u32 mcast_sw_if_index = ~0;
13151   u32 encap_vrf_id = 0;
13152   u32 decap_next_index = ~0;
13153   u32 vni = 0;
13154   int ret;
13155
13156   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13157   clib_memset (&src, 0, sizeof src);
13158   clib_memset (&dst, 0, sizeof dst);
13159
13160   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13161     {
13162       if (unformat (line_input, "del"))
13163         is_add = 0;
13164       else
13165         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13166         {
13167           ipv4_set = 1;
13168           src_set = 1;
13169         }
13170       else
13171         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13172         {
13173           ipv4_set = 1;
13174           dst_set = 1;
13175         }
13176       else
13177         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13178         {
13179           ipv6_set = 1;
13180           src_set = 1;
13181         }
13182       else
13183         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13184         {
13185           ipv6_set = 1;
13186           dst_set = 1;
13187         }
13188       else if (unformat (line_input, "group %U %U",
13189                          unformat_ip4_address, &dst.ip4,
13190                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13191         {
13192           grp_set = dst_set = 1;
13193           ipv4_set = 1;
13194         }
13195       else if (unformat (line_input, "group %U",
13196                          unformat_ip4_address, &dst.ip4))
13197         {
13198           grp_set = dst_set = 1;
13199           ipv4_set = 1;
13200         }
13201       else if (unformat (line_input, "group %U %U",
13202                          unformat_ip6_address, &dst.ip6,
13203                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13204         {
13205           grp_set = dst_set = 1;
13206           ipv6_set = 1;
13207         }
13208       else if (unformat (line_input, "group %U",
13209                          unformat_ip6_address, &dst.ip6))
13210         {
13211           grp_set = dst_set = 1;
13212           ipv6_set = 1;
13213         }
13214       else
13215         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13216         ;
13217       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13218         ;
13219       else if (unformat (line_input, "decap-next %U",
13220                          unformat_geneve_decap_next, &decap_next_index))
13221         ;
13222       else if (unformat (line_input, "vni %d", &vni))
13223         ;
13224       else
13225         {
13226           errmsg ("parse error '%U'", format_unformat_error, line_input);
13227           return -99;
13228         }
13229     }
13230
13231   if (src_set == 0)
13232     {
13233       errmsg ("tunnel src address not specified");
13234       return -99;
13235     }
13236   if (dst_set == 0)
13237     {
13238       errmsg ("tunnel dst address not specified");
13239       return -99;
13240     }
13241
13242   if (grp_set && !ip46_address_is_multicast (&dst))
13243     {
13244       errmsg ("tunnel group address not multicast");
13245       return -99;
13246     }
13247   if (grp_set && mcast_sw_if_index == ~0)
13248     {
13249       errmsg ("tunnel nonexistent multicast device");
13250       return -99;
13251     }
13252   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13253     {
13254       errmsg ("tunnel dst address must be unicast");
13255       return -99;
13256     }
13257
13258
13259   if (ipv4_set && ipv6_set)
13260     {
13261       errmsg ("both IPv4 and IPv6 addresses specified");
13262       return -99;
13263     }
13264
13265   if ((vni == 0) || (vni >> 24))
13266     {
13267       errmsg ("vni not specified or out of range");
13268       return -99;
13269     }
13270
13271   M (GENEVE_ADD_DEL_TUNNEL, mp);
13272
13273   if (ipv6_set)
13274     {
13275       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13276       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13277     }
13278   else
13279     {
13280       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13281       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13282     }
13283   mp->encap_vrf_id = ntohl (encap_vrf_id);
13284   mp->decap_next_index = ntohl (decap_next_index);
13285   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13286   mp->vni = ntohl (vni);
13287   mp->is_add = is_add;
13288   mp->is_ipv6 = ipv6_set;
13289
13290   S (mp);
13291   W (ret);
13292   return ret;
13293 }
13294
13295 static void vl_api_geneve_tunnel_details_t_handler
13296   (vl_api_geneve_tunnel_details_t * mp)
13297 {
13298   vat_main_t *vam = &vat_main;
13299   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13300   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13301
13302   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13303          ntohl (mp->sw_if_index),
13304          format_ip46_address, &src, IP46_TYPE_ANY,
13305          format_ip46_address, &dst, IP46_TYPE_ANY,
13306          ntohl (mp->encap_vrf_id),
13307          ntohl (mp->decap_next_index), ntohl (mp->vni),
13308          ntohl (mp->mcast_sw_if_index));
13309 }
13310
13311 static void vl_api_geneve_tunnel_details_t_handler_json
13312   (vl_api_geneve_tunnel_details_t * mp)
13313 {
13314   vat_main_t *vam = &vat_main;
13315   vat_json_node_t *node = NULL;
13316
13317   if (VAT_JSON_ARRAY != vam->json_tree.type)
13318     {
13319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13320       vat_json_init_array (&vam->json_tree);
13321     }
13322   node = vat_json_array_add (&vam->json_tree);
13323
13324   vat_json_init_object (node);
13325   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13326   if (mp->is_ipv6)
13327     {
13328       struct in6_addr ip6;
13329
13330       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13331       vat_json_object_add_ip6 (node, "src_address", ip6);
13332       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13333       vat_json_object_add_ip6 (node, "dst_address", ip6);
13334     }
13335   else
13336     {
13337       struct in_addr ip4;
13338
13339       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13340       vat_json_object_add_ip4 (node, "src_address", ip4);
13341       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13342       vat_json_object_add_ip4 (node, "dst_address", ip4);
13343     }
13344   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13345   vat_json_object_add_uint (node, "decap_next_index",
13346                             ntohl (mp->decap_next_index));
13347   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13348   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13349   vat_json_object_add_uint (node, "mcast_sw_if_index",
13350                             ntohl (mp->mcast_sw_if_index));
13351 }
13352
13353 static int
13354 api_geneve_tunnel_dump (vat_main_t * vam)
13355 {
13356   unformat_input_t *i = vam->input;
13357   vl_api_geneve_tunnel_dump_t *mp;
13358   vl_api_control_ping_t *mp_ping;
13359   u32 sw_if_index;
13360   u8 sw_if_index_set = 0;
13361   int ret;
13362
13363   /* Parse args required to build the message */
13364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13365     {
13366       if (unformat (i, "sw_if_index %d", &sw_if_index))
13367         sw_if_index_set = 1;
13368       else
13369         break;
13370     }
13371
13372   if (sw_if_index_set == 0)
13373     {
13374       sw_if_index = ~0;
13375     }
13376
13377   if (!vam->json_output)
13378     {
13379       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13380              "sw_if_index", "local_address", "remote_address",
13381              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13382     }
13383
13384   /* Get list of geneve-tunnel interfaces */
13385   M (GENEVE_TUNNEL_DUMP, mp);
13386
13387   mp->sw_if_index = htonl (sw_if_index);
13388
13389   S (mp);
13390
13391   /* Use a control ping for synchronization */
13392   M (CONTROL_PING, mp_ping);
13393   S (mp_ping);
13394
13395   W (ret);
13396   return ret;
13397 }
13398
13399 static int
13400 api_gre_add_del_tunnel (vat_main_t * vam)
13401 {
13402   unformat_input_t *line_input = vam->input;
13403   vl_api_gre_add_del_tunnel_t *mp;
13404   ip4_address_t src4, dst4;
13405   ip6_address_t src6, dst6;
13406   u8 is_add = 1;
13407   u8 ipv4_set = 0;
13408   u8 ipv6_set = 0;
13409   u8 t_type = GRE_TUNNEL_TYPE_L3;
13410   u8 src_set = 0;
13411   u8 dst_set = 0;
13412   u32 outer_fib_id = 0;
13413   u32 session_id = 0;
13414   u32 instance = ~0;
13415   int ret;
13416
13417   clib_memset (&src4, 0, sizeof src4);
13418   clib_memset (&dst4, 0, sizeof dst4);
13419   clib_memset (&src6, 0, sizeof src6);
13420   clib_memset (&dst6, 0, sizeof dst6);
13421
13422   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13423     {
13424       if (unformat (line_input, "del"))
13425         is_add = 0;
13426       else if (unformat (line_input, "instance %d", &instance))
13427         ;
13428       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13429         {
13430           src_set = 1;
13431           ipv4_set = 1;
13432         }
13433       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13434         {
13435           dst_set = 1;
13436           ipv4_set = 1;
13437         }
13438       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13439         {
13440           src_set = 1;
13441           ipv6_set = 1;
13442         }
13443       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13444         {
13445           dst_set = 1;
13446           ipv6_set = 1;
13447         }
13448       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13449         ;
13450       else if (unformat (line_input, "teb"))
13451         t_type = GRE_TUNNEL_TYPE_TEB;
13452       else if (unformat (line_input, "erspan %d", &session_id))
13453         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13454       else
13455         {
13456           errmsg ("parse error '%U'", format_unformat_error, line_input);
13457           return -99;
13458         }
13459     }
13460
13461   if (src_set == 0)
13462     {
13463       errmsg ("tunnel src address not specified");
13464       return -99;
13465     }
13466   if (dst_set == 0)
13467     {
13468       errmsg ("tunnel dst address not specified");
13469       return -99;
13470     }
13471   if (ipv4_set && ipv6_set)
13472     {
13473       errmsg ("both IPv4 and IPv6 addresses specified");
13474       return -99;
13475     }
13476
13477
13478   M (GRE_ADD_DEL_TUNNEL, mp);
13479
13480   if (ipv4_set)
13481     {
13482       clib_memcpy (&mp->src_address, &src4, 4);
13483       clib_memcpy (&mp->dst_address, &dst4, 4);
13484     }
13485   else
13486     {
13487       clib_memcpy (&mp->src_address, &src6, 16);
13488       clib_memcpy (&mp->dst_address, &dst6, 16);
13489     }
13490   mp->instance = htonl (instance);
13491   mp->outer_fib_id = htonl (outer_fib_id);
13492   mp->is_add = is_add;
13493   mp->session_id = htons ((u16) session_id);
13494   mp->tunnel_type = t_type;
13495   mp->is_ipv6 = ipv6_set;
13496
13497   S (mp);
13498   W (ret);
13499   return ret;
13500 }
13501
13502 static void vl_api_gre_tunnel_details_t_handler
13503   (vl_api_gre_tunnel_details_t * mp)
13504 {
13505   vat_main_t *vam = &vat_main;
13506   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13507   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13508
13509   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13510          ntohl (mp->sw_if_index),
13511          ntohl (mp->instance),
13512          format_ip46_address, &src, IP46_TYPE_ANY,
13513          format_ip46_address, &dst, IP46_TYPE_ANY,
13514          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13515 }
13516
13517 static void vl_api_gre_tunnel_details_t_handler_json
13518   (vl_api_gre_tunnel_details_t * mp)
13519 {
13520   vat_main_t *vam = &vat_main;
13521   vat_json_node_t *node = NULL;
13522   struct in_addr ip4;
13523   struct in6_addr ip6;
13524
13525   if (VAT_JSON_ARRAY != vam->json_tree.type)
13526     {
13527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13528       vat_json_init_array (&vam->json_tree);
13529     }
13530   node = vat_json_array_add (&vam->json_tree);
13531
13532   vat_json_init_object (node);
13533   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13534   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13535   if (!mp->is_ipv6)
13536     {
13537       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13538       vat_json_object_add_ip4 (node, "src_address", ip4);
13539       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13540       vat_json_object_add_ip4 (node, "dst_address", ip4);
13541     }
13542   else
13543     {
13544       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13545       vat_json_object_add_ip6 (node, "src_address", ip6);
13546       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13547       vat_json_object_add_ip6 (node, "dst_address", ip6);
13548     }
13549   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13550   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13551   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13552   vat_json_object_add_uint (node, "session_id", mp->session_id);
13553 }
13554
13555 static int
13556 api_gre_tunnel_dump (vat_main_t * vam)
13557 {
13558   unformat_input_t *i = vam->input;
13559   vl_api_gre_tunnel_dump_t *mp;
13560   vl_api_control_ping_t *mp_ping;
13561   u32 sw_if_index;
13562   u8 sw_if_index_set = 0;
13563   int ret;
13564
13565   /* Parse args required to build the message */
13566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13567     {
13568       if (unformat (i, "sw_if_index %d", &sw_if_index))
13569         sw_if_index_set = 1;
13570       else
13571         break;
13572     }
13573
13574   if (sw_if_index_set == 0)
13575     {
13576       sw_if_index = ~0;
13577     }
13578
13579   if (!vam->json_output)
13580     {
13581       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13582              "sw_if_index", "instance", "src_address", "dst_address",
13583              "tunnel_type", "outer_fib_id", "session_id");
13584     }
13585
13586   /* Get list of gre-tunnel interfaces */
13587   M (GRE_TUNNEL_DUMP, mp);
13588
13589   mp->sw_if_index = htonl (sw_if_index);
13590
13591   S (mp);
13592
13593   /* Use a control ping for synchronization */
13594   MPING (CONTROL_PING, mp_ping);
13595   S (mp_ping);
13596
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_l2_fib_clear_table (vat_main_t * vam)
13603 {
13604 //  unformat_input_t * i = vam->input;
13605   vl_api_l2_fib_clear_table_t *mp;
13606   int ret;
13607
13608   M (L2_FIB_CLEAR_TABLE, mp);
13609
13610   S (mp);
13611   W (ret);
13612   return ret;
13613 }
13614
13615 static int
13616 api_l2_interface_efp_filter (vat_main_t * vam)
13617 {
13618   unformat_input_t *i = vam->input;
13619   vl_api_l2_interface_efp_filter_t *mp;
13620   u32 sw_if_index;
13621   u8 enable = 1;
13622   u8 sw_if_index_set = 0;
13623   int ret;
13624
13625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13626     {
13627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13628         sw_if_index_set = 1;
13629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13630         sw_if_index_set = 1;
13631       else if (unformat (i, "enable"))
13632         enable = 1;
13633       else if (unformat (i, "disable"))
13634         enable = 0;
13635       else
13636         {
13637           clib_warning ("parse error '%U'", format_unformat_error, i);
13638           return -99;
13639         }
13640     }
13641
13642   if (sw_if_index_set == 0)
13643     {
13644       errmsg ("missing sw_if_index");
13645       return -99;
13646     }
13647
13648   M (L2_INTERFACE_EFP_FILTER, mp);
13649
13650   mp->sw_if_index = ntohl (sw_if_index);
13651   mp->enable_disable = enable;
13652
13653   S (mp);
13654   W (ret);
13655   return ret;
13656 }
13657
13658 #define foreach_vtr_op                          \
13659 _("disable",  L2_VTR_DISABLED)                  \
13660 _("push-1",  L2_VTR_PUSH_1)                     \
13661 _("push-2",  L2_VTR_PUSH_2)                     \
13662 _("pop-1",  L2_VTR_POP_1)                       \
13663 _("pop-2",  L2_VTR_POP_2)                       \
13664 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13665 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13666 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13667 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13668
13669 static int
13670 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13671 {
13672   unformat_input_t *i = vam->input;
13673   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13674   u32 sw_if_index;
13675   u8 sw_if_index_set = 0;
13676   u8 vtr_op_set = 0;
13677   u32 vtr_op = 0;
13678   u32 push_dot1q = 1;
13679   u32 tag1 = ~0;
13680   u32 tag2 = ~0;
13681   int ret;
13682
13683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13684     {
13685       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13686         sw_if_index_set = 1;
13687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13688         sw_if_index_set = 1;
13689       else if (unformat (i, "vtr_op %d", &vtr_op))
13690         vtr_op_set = 1;
13691 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13692       foreach_vtr_op
13693 #undef _
13694         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13695         ;
13696       else if (unformat (i, "tag1 %d", &tag1))
13697         ;
13698       else if (unformat (i, "tag2 %d", &tag2))
13699         ;
13700       else
13701         {
13702           clib_warning ("parse error '%U'", format_unformat_error, i);
13703           return -99;
13704         }
13705     }
13706
13707   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13708     {
13709       errmsg ("missing vtr operation or sw_if_index");
13710       return -99;
13711     }
13712
13713   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13714   mp->sw_if_index = ntohl (sw_if_index);
13715   mp->vtr_op = ntohl (vtr_op);
13716   mp->push_dot1q = ntohl (push_dot1q);
13717   mp->tag1 = ntohl (tag1);
13718   mp->tag2 = ntohl (tag2);
13719
13720   S (mp);
13721   W (ret);
13722   return ret;
13723 }
13724
13725 static int
13726 api_create_vhost_user_if (vat_main_t * vam)
13727 {
13728   unformat_input_t *i = vam->input;
13729   vl_api_create_vhost_user_if_t *mp;
13730   u8 *file_name;
13731   u8 is_server = 0;
13732   u8 file_name_set = 0;
13733   u32 custom_dev_instance = ~0;
13734   u8 hwaddr[6];
13735   u8 use_custom_mac = 0;
13736   u8 disable_mrg_rxbuf = 0;
13737   u8 disable_indirect_desc = 0;
13738   u8 *tag = 0;
13739   int ret;
13740
13741   /* Shut up coverity */
13742   clib_memset (hwaddr, 0, sizeof (hwaddr));
13743
13744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13745     {
13746       if (unformat (i, "socket %s", &file_name))
13747         {
13748           file_name_set = 1;
13749         }
13750       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13751         ;
13752       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13753         use_custom_mac = 1;
13754       else if (unformat (i, "server"))
13755         is_server = 1;
13756       else if (unformat (i, "disable_mrg_rxbuf"))
13757         disable_mrg_rxbuf = 1;
13758       else if (unformat (i, "disable_indirect_desc"))
13759         disable_indirect_desc = 1;
13760       else if (unformat (i, "tag %s", &tag))
13761         ;
13762       else
13763         break;
13764     }
13765
13766   if (file_name_set == 0)
13767     {
13768       errmsg ("missing socket file name");
13769       return -99;
13770     }
13771
13772   if (vec_len (file_name) > 255)
13773     {
13774       errmsg ("socket file name too long");
13775       return -99;
13776     }
13777   vec_add1 (file_name, 0);
13778
13779   M (CREATE_VHOST_USER_IF, mp);
13780
13781   mp->is_server = is_server;
13782   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13783   mp->disable_indirect_desc = disable_indirect_desc;
13784   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13785   vec_free (file_name);
13786   if (custom_dev_instance != ~0)
13787     {
13788       mp->renumber = 1;
13789       mp->custom_dev_instance = ntohl (custom_dev_instance);
13790     }
13791
13792   mp->use_custom_mac = use_custom_mac;
13793   clib_memcpy (mp->mac_address, hwaddr, 6);
13794   if (tag)
13795     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13796   vec_free (tag);
13797
13798   S (mp);
13799   W (ret);
13800   return ret;
13801 }
13802
13803 static int
13804 api_modify_vhost_user_if (vat_main_t * vam)
13805 {
13806   unformat_input_t *i = vam->input;
13807   vl_api_modify_vhost_user_if_t *mp;
13808   u8 *file_name;
13809   u8 is_server = 0;
13810   u8 file_name_set = 0;
13811   u32 custom_dev_instance = ~0;
13812   u8 sw_if_index_set = 0;
13813   u32 sw_if_index = (u32) ~ 0;
13814   int ret;
13815
13816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13817     {
13818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13819         sw_if_index_set = 1;
13820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13821         sw_if_index_set = 1;
13822       else if (unformat (i, "socket %s", &file_name))
13823         {
13824           file_name_set = 1;
13825         }
13826       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13827         ;
13828       else if (unformat (i, "server"))
13829         is_server = 1;
13830       else
13831         break;
13832     }
13833
13834   if (sw_if_index_set == 0)
13835     {
13836       errmsg ("missing sw_if_index or interface name");
13837       return -99;
13838     }
13839
13840   if (file_name_set == 0)
13841     {
13842       errmsg ("missing socket file name");
13843       return -99;
13844     }
13845
13846   if (vec_len (file_name) > 255)
13847     {
13848       errmsg ("socket file name too long");
13849       return -99;
13850     }
13851   vec_add1 (file_name, 0);
13852
13853   M (MODIFY_VHOST_USER_IF, mp);
13854
13855   mp->sw_if_index = ntohl (sw_if_index);
13856   mp->is_server = is_server;
13857   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13858   vec_free (file_name);
13859   if (custom_dev_instance != ~0)
13860     {
13861       mp->renumber = 1;
13862       mp->custom_dev_instance = ntohl (custom_dev_instance);
13863     }
13864
13865   S (mp);
13866   W (ret);
13867   return ret;
13868 }
13869
13870 static int
13871 api_delete_vhost_user_if (vat_main_t * vam)
13872 {
13873   unformat_input_t *i = vam->input;
13874   vl_api_delete_vhost_user_if_t *mp;
13875   u32 sw_if_index = ~0;
13876   u8 sw_if_index_set = 0;
13877   int ret;
13878
13879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13880     {
13881       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13882         sw_if_index_set = 1;
13883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13884         sw_if_index_set = 1;
13885       else
13886         break;
13887     }
13888
13889   if (sw_if_index_set == 0)
13890     {
13891       errmsg ("missing sw_if_index or interface name");
13892       return -99;
13893     }
13894
13895
13896   M (DELETE_VHOST_USER_IF, mp);
13897
13898   mp->sw_if_index = ntohl (sw_if_index);
13899
13900   S (mp);
13901   W (ret);
13902   return ret;
13903 }
13904
13905 static void vl_api_sw_interface_vhost_user_details_t_handler
13906   (vl_api_sw_interface_vhost_user_details_t * mp)
13907 {
13908   vat_main_t *vam = &vat_main;
13909
13910   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13911          (char *) mp->interface_name,
13912          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13913          clib_net_to_host_u64 (mp->features), mp->is_server,
13914          ntohl (mp->num_regions), (char *) mp->sock_filename);
13915   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13916 }
13917
13918 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13919   (vl_api_sw_interface_vhost_user_details_t * mp)
13920 {
13921   vat_main_t *vam = &vat_main;
13922   vat_json_node_t *node = NULL;
13923
13924   if (VAT_JSON_ARRAY != vam->json_tree.type)
13925     {
13926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13927       vat_json_init_array (&vam->json_tree);
13928     }
13929   node = vat_json_array_add (&vam->json_tree);
13930
13931   vat_json_init_object (node);
13932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13933   vat_json_object_add_string_copy (node, "interface_name",
13934                                    mp->interface_name);
13935   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13936                             ntohl (mp->virtio_net_hdr_sz));
13937   vat_json_object_add_uint (node, "features",
13938                             clib_net_to_host_u64 (mp->features));
13939   vat_json_object_add_uint (node, "is_server", mp->is_server);
13940   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13941   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13942   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13943 }
13944
13945 static int
13946 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13947 {
13948   vl_api_sw_interface_vhost_user_dump_t *mp;
13949   vl_api_control_ping_t *mp_ping;
13950   int ret;
13951   print (vam->ofp,
13952          "Interface name            idx hdr_sz features server regions filename");
13953
13954   /* Get list of vhost-user interfaces */
13955   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13956   S (mp);
13957
13958   /* Use a control ping for synchronization */
13959   MPING (CONTROL_PING, mp_ping);
13960   S (mp_ping);
13961
13962   W (ret);
13963   return ret;
13964 }
13965
13966 static int
13967 api_show_version (vat_main_t * vam)
13968 {
13969   vl_api_show_version_t *mp;
13970   int ret;
13971
13972   M (SHOW_VERSION, mp);
13973
13974   S (mp);
13975   W (ret);
13976   return ret;
13977 }
13978
13979
13980 static int
13981 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13982 {
13983   unformat_input_t *line_input = vam->input;
13984   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13985   ip4_address_t local4, remote4;
13986   ip6_address_t local6, remote6;
13987   u8 is_add = 1;
13988   u8 ipv4_set = 0, ipv6_set = 0;
13989   u8 local_set = 0;
13990   u8 remote_set = 0;
13991   u8 grp_set = 0;
13992   u32 mcast_sw_if_index = ~0;
13993   u32 encap_vrf_id = 0;
13994   u32 decap_vrf_id = 0;
13995   u8 protocol = ~0;
13996   u32 vni;
13997   u8 vni_set = 0;
13998   int ret;
13999
14000   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14001   clib_memset (&local4, 0, sizeof local4);
14002   clib_memset (&remote4, 0, sizeof remote4);
14003   clib_memset (&local6, 0, sizeof local6);
14004   clib_memset (&remote6, 0, sizeof remote6);
14005
14006   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (line_input, "del"))
14009         is_add = 0;
14010       else if (unformat (line_input, "local %U",
14011                          unformat_ip4_address, &local4))
14012         {
14013           local_set = 1;
14014           ipv4_set = 1;
14015         }
14016       else if (unformat (line_input, "remote %U",
14017                          unformat_ip4_address, &remote4))
14018         {
14019           remote_set = 1;
14020           ipv4_set = 1;
14021         }
14022       else if (unformat (line_input, "local %U",
14023                          unformat_ip6_address, &local6))
14024         {
14025           local_set = 1;
14026           ipv6_set = 1;
14027         }
14028       else if (unformat (line_input, "remote %U",
14029                          unformat_ip6_address, &remote6))
14030         {
14031           remote_set = 1;
14032           ipv6_set = 1;
14033         }
14034       else if (unformat (line_input, "group %U %U",
14035                          unformat_ip4_address, &remote4,
14036                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14037         {
14038           grp_set = remote_set = 1;
14039           ipv4_set = 1;
14040         }
14041       else if (unformat (line_input, "group %U",
14042                          unformat_ip4_address, &remote4))
14043         {
14044           grp_set = remote_set = 1;
14045           ipv4_set = 1;
14046         }
14047       else if (unformat (line_input, "group %U %U",
14048                          unformat_ip6_address, &remote6,
14049                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14050         {
14051           grp_set = remote_set = 1;
14052           ipv6_set = 1;
14053         }
14054       else if (unformat (line_input, "group %U",
14055                          unformat_ip6_address, &remote6))
14056         {
14057           grp_set = remote_set = 1;
14058           ipv6_set = 1;
14059         }
14060       else
14061         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14062         ;
14063       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14064         ;
14065       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14066         ;
14067       else if (unformat (line_input, "vni %d", &vni))
14068         vni_set = 1;
14069       else if (unformat (line_input, "next-ip4"))
14070         protocol = 1;
14071       else if (unformat (line_input, "next-ip6"))
14072         protocol = 2;
14073       else if (unformat (line_input, "next-ethernet"))
14074         protocol = 3;
14075       else if (unformat (line_input, "next-nsh"))
14076         protocol = 4;
14077       else
14078         {
14079           errmsg ("parse error '%U'", format_unformat_error, line_input);
14080           return -99;
14081         }
14082     }
14083
14084   if (local_set == 0)
14085     {
14086       errmsg ("tunnel local address not specified");
14087       return -99;
14088     }
14089   if (remote_set == 0)
14090     {
14091       errmsg ("tunnel remote address not specified");
14092       return -99;
14093     }
14094   if (grp_set && mcast_sw_if_index == ~0)
14095     {
14096       errmsg ("tunnel nonexistent multicast device");
14097       return -99;
14098     }
14099   if (ipv4_set && ipv6_set)
14100     {
14101       errmsg ("both IPv4 and IPv6 addresses specified");
14102       return -99;
14103     }
14104
14105   if (vni_set == 0)
14106     {
14107       errmsg ("vni not specified");
14108       return -99;
14109     }
14110
14111   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14112
14113
14114   if (ipv6_set)
14115     {
14116       clib_memcpy (&mp->local, &local6, sizeof (local6));
14117       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14118     }
14119   else
14120     {
14121       clib_memcpy (&mp->local, &local4, sizeof (local4));
14122       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14123     }
14124
14125   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14126   mp->encap_vrf_id = ntohl (encap_vrf_id);
14127   mp->decap_vrf_id = ntohl (decap_vrf_id);
14128   mp->protocol = protocol;
14129   mp->vni = ntohl (vni);
14130   mp->is_add = is_add;
14131   mp->is_ipv6 = ipv6_set;
14132
14133   S (mp);
14134   W (ret);
14135   return ret;
14136 }
14137
14138 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14139   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14140 {
14141   vat_main_t *vam = &vat_main;
14142   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14143   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14144
14145   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14146          ntohl (mp->sw_if_index),
14147          format_ip46_address, &local, IP46_TYPE_ANY,
14148          format_ip46_address, &remote, IP46_TYPE_ANY,
14149          ntohl (mp->vni), mp->protocol,
14150          ntohl (mp->mcast_sw_if_index),
14151          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14152 }
14153
14154
14155 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14156   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14157 {
14158   vat_main_t *vam = &vat_main;
14159   vat_json_node_t *node = NULL;
14160   struct in_addr ip4;
14161   struct in6_addr ip6;
14162
14163   if (VAT_JSON_ARRAY != vam->json_tree.type)
14164     {
14165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14166       vat_json_init_array (&vam->json_tree);
14167     }
14168   node = vat_json_array_add (&vam->json_tree);
14169
14170   vat_json_init_object (node);
14171   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14172   if (mp->is_ipv6)
14173     {
14174       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14175       vat_json_object_add_ip6 (node, "local", ip6);
14176       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14177       vat_json_object_add_ip6 (node, "remote", ip6);
14178     }
14179   else
14180     {
14181       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14182       vat_json_object_add_ip4 (node, "local", ip4);
14183       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14184       vat_json_object_add_ip4 (node, "remote", ip4);
14185     }
14186   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14187   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14188   vat_json_object_add_uint (node, "mcast_sw_if_index",
14189                             ntohl (mp->mcast_sw_if_index));
14190   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14191   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14192   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14193 }
14194
14195 static int
14196 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14197 {
14198   unformat_input_t *i = vam->input;
14199   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14200   vl_api_control_ping_t *mp_ping;
14201   u32 sw_if_index;
14202   u8 sw_if_index_set = 0;
14203   int ret;
14204
14205   /* Parse args required to build the message */
14206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14207     {
14208       if (unformat (i, "sw_if_index %d", &sw_if_index))
14209         sw_if_index_set = 1;
14210       else
14211         break;
14212     }
14213
14214   if (sw_if_index_set == 0)
14215     {
14216       sw_if_index = ~0;
14217     }
14218
14219   if (!vam->json_output)
14220     {
14221       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14222              "sw_if_index", "local", "remote", "vni",
14223              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14224     }
14225
14226   /* Get list of vxlan-tunnel interfaces */
14227   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14228
14229   mp->sw_if_index = htonl (sw_if_index);
14230
14231   S (mp);
14232
14233   /* Use a control ping for synchronization */
14234   MPING (CONTROL_PING, mp_ping);
14235   S (mp_ping);
14236
14237   W (ret);
14238   return ret;
14239 }
14240
14241 static void vl_api_l2_fib_table_details_t_handler
14242   (vl_api_l2_fib_table_details_t * mp)
14243 {
14244   vat_main_t *vam = &vat_main;
14245
14246   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14247          "       %d       %d     %d",
14248          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14249          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14250          mp->bvi_mac);
14251 }
14252
14253 static void vl_api_l2_fib_table_details_t_handler_json
14254   (vl_api_l2_fib_table_details_t * mp)
14255 {
14256   vat_main_t *vam = &vat_main;
14257   vat_json_node_t *node = NULL;
14258
14259   if (VAT_JSON_ARRAY != vam->json_tree.type)
14260     {
14261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14262       vat_json_init_array (&vam->json_tree);
14263     }
14264   node = vat_json_array_add (&vam->json_tree);
14265
14266   vat_json_init_object (node);
14267   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14268   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14269   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14270   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14271   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14272   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14273 }
14274
14275 static int
14276 api_l2_fib_table_dump (vat_main_t * vam)
14277 {
14278   unformat_input_t *i = vam->input;
14279   vl_api_l2_fib_table_dump_t *mp;
14280   vl_api_control_ping_t *mp_ping;
14281   u32 bd_id;
14282   u8 bd_id_set = 0;
14283   int ret;
14284
14285   /* Parse args required to build the message */
14286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14287     {
14288       if (unformat (i, "bd_id %d", &bd_id))
14289         bd_id_set = 1;
14290       else
14291         break;
14292     }
14293
14294   if (bd_id_set == 0)
14295     {
14296       errmsg ("missing bridge domain");
14297       return -99;
14298     }
14299
14300   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14301
14302   /* Get list of l2 fib entries */
14303   M (L2_FIB_TABLE_DUMP, mp);
14304
14305   mp->bd_id = ntohl (bd_id);
14306   S (mp);
14307
14308   /* Use a control ping for synchronization */
14309   MPING (CONTROL_PING, mp_ping);
14310   S (mp_ping);
14311
14312   W (ret);
14313   return ret;
14314 }
14315
14316
14317 static int
14318 api_interface_name_renumber (vat_main_t * vam)
14319 {
14320   unformat_input_t *line_input = vam->input;
14321   vl_api_interface_name_renumber_t *mp;
14322   u32 sw_if_index = ~0;
14323   u32 new_show_dev_instance = ~0;
14324   int ret;
14325
14326   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14327     {
14328       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14329                     &sw_if_index))
14330         ;
14331       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14332         ;
14333       else if (unformat (line_input, "new_show_dev_instance %d",
14334                          &new_show_dev_instance))
14335         ;
14336       else
14337         break;
14338     }
14339
14340   if (sw_if_index == ~0)
14341     {
14342       errmsg ("missing interface name or sw_if_index");
14343       return -99;
14344     }
14345
14346   if (new_show_dev_instance == ~0)
14347     {
14348       errmsg ("missing new_show_dev_instance");
14349       return -99;
14350     }
14351
14352   M (INTERFACE_NAME_RENUMBER, mp);
14353
14354   mp->sw_if_index = ntohl (sw_if_index);
14355   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14356
14357   S (mp);
14358   W (ret);
14359   return ret;
14360 }
14361
14362 static int
14363 api_ip_probe_neighbor (vat_main_t * vam)
14364 {
14365   unformat_input_t *i = vam->input;
14366   vl_api_ip_probe_neighbor_t *mp;
14367   u8 int_set = 0;
14368   u8 adr_set = 0;
14369   u8 is_ipv6 = 0;
14370   u8 dst_adr[16];
14371   u32 sw_if_index;
14372   int ret;
14373
14374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14375     {
14376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14377         int_set = 1;
14378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14379         int_set = 1;
14380       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14381         adr_set = 1;
14382       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14383         {
14384           adr_set = 1;
14385           is_ipv6 = 1;
14386         }
14387       else
14388         break;
14389     }
14390
14391   if (int_set == 0)
14392     {
14393       errmsg ("missing interface");
14394       return -99;
14395     }
14396
14397   if (adr_set == 0)
14398     {
14399       errmsg ("missing addresses");
14400       return -99;
14401     }
14402
14403   M (IP_PROBE_NEIGHBOR, mp);
14404
14405   mp->sw_if_index = ntohl (sw_if_index);
14406   mp->is_ipv6 = is_ipv6;
14407   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14408
14409   S (mp);
14410   W (ret);
14411   return ret;
14412 }
14413
14414 static int
14415 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14416 {
14417   unformat_input_t *i = vam->input;
14418   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14419   u8 mode = IP_SCAN_V46_NEIGHBORS;
14420   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14421   int ret;
14422
14423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14424     {
14425       if (unformat (i, "ip4"))
14426         mode = IP_SCAN_V4_NEIGHBORS;
14427       else if (unformat (i, "ip6"))
14428         mode = IP_SCAN_V6_NEIGHBORS;
14429       if (unformat (i, "both"))
14430         mode = IP_SCAN_V46_NEIGHBORS;
14431       else if (unformat (i, "disable"))
14432         mode = IP_SCAN_DISABLED;
14433       else if (unformat (i, "interval %d", &interval))
14434         ;
14435       else if (unformat (i, "max-time %d", &time))
14436         ;
14437       else if (unformat (i, "max-update %d", &update))
14438         ;
14439       else if (unformat (i, "delay %d", &delay))
14440         ;
14441       else if (unformat (i, "stale %d", &stale))
14442         ;
14443       else
14444         break;
14445     }
14446
14447   if (interval > 255)
14448     {
14449       errmsg ("interval cannot exceed 255 minutes.");
14450       return -99;
14451     }
14452   if (time > 255)
14453     {
14454       errmsg ("max-time cannot exceed 255 usec.");
14455       return -99;
14456     }
14457   if (update > 255)
14458     {
14459       errmsg ("max-update cannot exceed 255.");
14460       return -99;
14461     }
14462   if (delay > 255)
14463     {
14464       errmsg ("delay cannot exceed 255 msec.");
14465       return -99;
14466     }
14467   if (stale > 255)
14468     {
14469       errmsg ("stale cannot exceed 255 minutes.");
14470       return -99;
14471     }
14472
14473   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14474   mp->mode = mode;
14475   mp->scan_interval = interval;
14476   mp->max_proc_time = time;
14477   mp->max_update = update;
14478   mp->scan_int_delay = delay;
14479   mp->stale_threshold = stale;
14480
14481   S (mp);
14482   W (ret);
14483   return ret;
14484 }
14485
14486 static int
14487 api_want_ip4_arp_events (vat_main_t * vam)
14488 {
14489   unformat_input_t *line_input = vam->input;
14490   vl_api_want_ip4_arp_events_t *mp;
14491   ip4_address_t address;
14492   int address_set = 0;
14493   u32 enable_disable = 1;
14494   int ret;
14495
14496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14497     {
14498       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14499         address_set = 1;
14500       else if (unformat (line_input, "del"))
14501         enable_disable = 0;
14502       else
14503         break;
14504     }
14505
14506   if (address_set == 0)
14507     {
14508       errmsg ("missing addresses");
14509       return -99;
14510     }
14511
14512   M (WANT_IP4_ARP_EVENTS, mp);
14513   mp->enable_disable = enable_disable;
14514   mp->pid = htonl (getpid ());
14515   mp->address = address.as_u32;
14516
14517   S (mp);
14518   W (ret);
14519   return ret;
14520 }
14521
14522 static int
14523 api_want_ip6_nd_events (vat_main_t * vam)
14524 {
14525   unformat_input_t *line_input = vam->input;
14526   vl_api_want_ip6_nd_events_t *mp;
14527   ip6_address_t address;
14528   int address_set = 0;
14529   u32 enable_disable = 1;
14530   int ret;
14531
14532   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14533     {
14534       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14535         address_set = 1;
14536       else if (unformat (line_input, "del"))
14537         enable_disable = 0;
14538       else
14539         break;
14540     }
14541
14542   if (address_set == 0)
14543     {
14544       errmsg ("missing addresses");
14545       return -99;
14546     }
14547
14548   M (WANT_IP6_ND_EVENTS, mp);
14549   mp->enable_disable = enable_disable;
14550   mp->pid = htonl (getpid ());
14551   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14552
14553   S (mp);
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_want_l2_macs_events (vat_main_t * vam)
14560 {
14561   unformat_input_t *line_input = vam->input;
14562   vl_api_want_l2_macs_events_t *mp;
14563   u8 enable_disable = 1;
14564   u32 scan_delay = 0;
14565   u32 max_macs_in_event = 0;
14566   u32 learn_limit = 0;
14567   int ret;
14568
14569   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14570     {
14571       if (unformat (line_input, "learn-limit %d", &learn_limit))
14572         ;
14573       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14574         ;
14575       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14576         ;
14577       else if (unformat (line_input, "disable"))
14578         enable_disable = 0;
14579       else
14580         break;
14581     }
14582
14583   M (WANT_L2_MACS_EVENTS, mp);
14584   mp->enable_disable = enable_disable;
14585   mp->pid = htonl (getpid ());
14586   mp->learn_limit = htonl (learn_limit);
14587   mp->scan_delay = (u8) scan_delay;
14588   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14589   S (mp);
14590   W (ret);
14591   return ret;
14592 }
14593
14594 static int
14595 api_input_acl_set_interface (vat_main_t * vam)
14596 {
14597   unformat_input_t *i = vam->input;
14598   vl_api_input_acl_set_interface_t *mp;
14599   u32 sw_if_index;
14600   int sw_if_index_set;
14601   u32 ip4_table_index = ~0;
14602   u32 ip6_table_index = ~0;
14603   u32 l2_table_index = ~0;
14604   u8 is_add = 1;
14605   int ret;
14606
14607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14608     {
14609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14610         sw_if_index_set = 1;
14611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14612         sw_if_index_set = 1;
14613       else if (unformat (i, "del"))
14614         is_add = 0;
14615       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14616         ;
14617       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14618         ;
14619       else if (unformat (i, "l2-table %d", &l2_table_index))
14620         ;
14621       else
14622         {
14623           clib_warning ("parse error '%U'", format_unformat_error, i);
14624           return -99;
14625         }
14626     }
14627
14628   if (sw_if_index_set == 0)
14629     {
14630       errmsg ("missing interface name or sw_if_index");
14631       return -99;
14632     }
14633
14634   M (INPUT_ACL_SET_INTERFACE, mp);
14635
14636   mp->sw_if_index = ntohl (sw_if_index);
14637   mp->ip4_table_index = ntohl (ip4_table_index);
14638   mp->ip6_table_index = ntohl (ip6_table_index);
14639   mp->l2_table_index = ntohl (l2_table_index);
14640   mp->is_add = is_add;
14641
14642   S (mp);
14643   W (ret);
14644   return ret;
14645 }
14646
14647 static int
14648 api_output_acl_set_interface (vat_main_t * vam)
14649 {
14650   unformat_input_t *i = vam->input;
14651   vl_api_output_acl_set_interface_t *mp;
14652   u32 sw_if_index;
14653   int sw_if_index_set;
14654   u32 ip4_table_index = ~0;
14655   u32 ip6_table_index = ~0;
14656   u32 l2_table_index = ~0;
14657   u8 is_add = 1;
14658   int ret;
14659
14660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14661     {
14662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14663         sw_if_index_set = 1;
14664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14665         sw_if_index_set = 1;
14666       else if (unformat (i, "del"))
14667         is_add = 0;
14668       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14669         ;
14670       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14671         ;
14672       else if (unformat (i, "l2-table %d", &l2_table_index))
14673         ;
14674       else
14675         {
14676           clib_warning ("parse error '%U'", format_unformat_error, i);
14677           return -99;
14678         }
14679     }
14680
14681   if (sw_if_index_set == 0)
14682     {
14683       errmsg ("missing interface name or sw_if_index");
14684       return -99;
14685     }
14686
14687   M (OUTPUT_ACL_SET_INTERFACE, mp);
14688
14689   mp->sw_if_index = ntohl (sw_if_index);
14690   mp->ip4_table_index = ntohl (ip4_table_index);
14691   mp->ip6_table_index = ntohl (ip6_table_index);
14692   mp->l2_table_index = ntohl (l2_table_index);
14693   mp->is_add = is_add;
14694
14695   S (mp);
14696   W (ret);
14697   return ret;
14698 }
14699
14700 static int
14701 api_ip_address_dump (vat_main_t * vam)
14702 {
14703   unformat_input_t *i = vam->input;
14704   vl_api_ip_address_dump_t *mp;
14705   vl_api_control_ping_t *mp_ping;
14706   u32 sw_if_index = ~0;
14707   u8 sw_if_index_set = 0;
14708   u8 ipv4_set = 0;
14709   u8 ipv6_set = 0;
14710   int ret;
14711
14712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14713     {
14714       if (unformat (i, "sw_if_index %d", &sw_if_index))
14715         sw_if_index_set = 1;
14716       else
14717         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14718         sw_if_index_set = 1;
14719       else if (unformat (i, "ipv4"))
14720         ipv4_set = 1;
14721       else if (unformat (i, "ipv6"))
14722         ipv6_set = 1;
14723       else
14724         break;
14725     }
14726
14727   if (ipv4_set && ipv6_set)
14728     {
14729       errmsg ("ipv4 and ipv6 flags cannot be both set");
14730       return -99;
14731     }
14732
14733   if ((!ipv4_set) && (!ipv6_set))
14734     {
14735       errmsg ("no ipv4 nor ipv6 flag set");
14736       return -99;
14737     }
14738
14739   if (sw_if_index_set == 0)
14740     {
14741       errmsg ("missing interface name or sw_if_index");
14742       return -99;
14743     }
14744
14745   vam->current_sw_if_index = sw_if_index;
14746   vam->is_ipv6 = ipv6_set;
14747
14748   M (IP_ADDRESS_DUMP, mp);
14749   mp->sw_if_index = ntohl (sw_if_index);
14750   mp->is_ipv6 = ipv6_set;
14751   S (mp);
14752
14753   /* Use a control ping for synchronization */
14754   MPING (CONTROL_PING, mp_ping);
14755   S (mp_ping);
14756
14757   W (ret);
14758   return ret;
14759 }
14760
14761 static int
14762 api_ip_dump (vat_main_t * vam)
14763 {
14764   vl_api_ip_dump_t *mp;
14765   vl_api_control_ping_t *mp_ping;
14766   unformat_input_t *in = vam->input;
14767   int ipv4_set = 0;
14768   int ipv6_set = 0;
14769   int is_ipv6;
14770   int i;
14771   int ret;
14772
14773   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14774     {
14775       if (unformat (in, "ipv4"))
14776         ipv4_set = 1;
14777       else if (unformat (in, "ipv6"))
14778         ipv6_set = 1;
14779       else
14780         break;
14781     }
14782
14783   if (ipv4_set && ipv6_set)
14784     {
14785       errmsg ("ipv4 and ipv6 flags cannot be both set");
14786       return -99;
14787     }
14788
14789   if ((!ipv4_set) && (!ipv6_set))
14790     {
14791       errmsg ("no ipv4 nor ipv6 flag set");
14792       return -99;
14793     }
14794
14795   is_ipv6 = ipv6_set;
14796   vam->is_ipv6 = is_ipv6;
14797
14798   /* free old data */
14799   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14800     {
14801       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14802     }
14803   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14804
14805   M (IP_DUMP, mp);
14806   mp->is_ipv6 = ipv6_set;
14807   S (mp);
14808
14809   /* Use a control ping for synchronization */
14810   MPING (CONTROL_PING, mp_ping);
14811   S (mp_ping);
14812
14813   W (ret);
14814   return ret;
14815 }
14816
14817 static int
14818 api_ipsec_spd_add_del (vat_main_t * vam)
14819 {
14820   unformat_input_t *i = vam->input;
14821   vl_api_ipsec_spd_add_del_t *mp;
14822   u32 spd_id = ~0;
14823   u8 is_add = 1;
14824   int ret;
14825
14826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14827     {
14828       if (unformat (i, "spd_id %d", &spd_id))
14829         ;
14830       else if (unformat (i, "del"))
14831         is_add = 0;
14832       else
14833         {
14834           clib_warning ("parse error '%U'", format_unformat_error, i);
14835           return -99;
14836         }
14837     }
14838   if (spd_id == ~0)
14839     {
14840       errmsg ("spd_id must be set");
14841       return -99;
14842     }
14843
14844   M (IPSEC_SPD_ADD_DEL, mp);
14845
14846   mp->spd_id = ntohl (spd_id);
14847   mp->is_add = is_add;
14848
14849   S (mp);
14850   W (ret);
14851   return ret;
14852 }
14853
14854 static int
14855 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14856 {
14857   unformat_input_t *i = vam->input;
14858   vl_api_ipsec_interface_add_del_spd_t *mp;
14859   u32 sw_if_index;
14860   u8 sw_if_index_set = 0;
14861   u32 spd_id = (u32) ~ 0;
14862   u8 is_add = 1;
14863   int ret;
14864
14865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14866     {
14867       if (unformat (i, "del"))
14868         is_add = 0;
14869       else if (unformat (i, "spd_id %d", &spd_id))
14870         ;
14871       else
14872         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14873         sw_if_index_set = 1;
14874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14875         sw_if_index_set = 1;
14876       else
14877         {
14878           clib_warning ("parse error '%U'", format_unformat_error, i);
14879           return -99;
14880         }
14881
14882     }
14883
14884   if (spd_id == (u32) ~ 0)
14885     {
14886       errmsg ("spd_id must be set");
14887       return -99;
14888     }
14889
14890   if (sw_if_index_set == 0)
14891     {
14892       errmsg ("missing interface name or sw_if_index");
14893       return -99;
14894     }
14895
14896   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14897
14898   mp->spd_id = ntohl (spd_id);
14899   mp->sw_if_index = ntohl (sw_if_index);
14900   mp->is_add = is_add;
14901
14902   S (mp);
14903   W (ret);
14904   return ret;
14905 }
14906
14907 static int
14908 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14909 {
14910   unformat_input_t *i = vam->input;
14911   vl_api_ipsec_spd_add_del_entry_t *mp;
14912   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14913   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14914   i32 priority = 0;
14915   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14916   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14917   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14918   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14919   int ret;
14920
14921   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14922   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14923   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14924   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14925   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14926   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14927
14928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14929     {
14930       if (unformat (i, "del"))
14931         is_add = 0;
14932       if (unformat (i, "outbound"))
14933         is_outbound = 1;
14934       if (unformat (i, "inbound"))
14935         is_outbound = 0;
14936       else if (unformat (i, "spd_id %d", &spd_id))
14937         ;
14938       else if (unformat (i, "sa_id %d", &sa_id))
14939         ;
14940       else if (unformat (i, "priority %d", &priority))
14941         ;
14942       else if (unformat (i, "protocol %d", &protocol))
14943         ;
14944       else if (unformat (i, "lport_start %d", &lport_start))
14945         ;
14946       else if (unformat (i, "lport_stop %d", &lport_stop))
14947         ;
14948       else if (unformat (i, "rport_start %d", &rport_start))
14949         ;
14950       else if (unformat (i, "rport_stop %d", &rport_stop))
14951         ;
14952       else
14953         if (unformat
14954             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14955         {
14956           is_ipv6 = 0;
14957           is_ip_any = 0;
14958         }
14959       else
14960         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14961         {
14962           is_ipv6 = 0;
14963           is_ip_any = 0;
14964         }
14965       else
14966         if (unformat
14967             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14968         {
14969           is_ipv6 = 0;
14970           is_ip_any = 0;
14971         }
14972       else
14973         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14974         {
14975           is_ipv6 = 0;
14976           is_ip_any = 0;
14977         }
14978       else
14979         if (unformat
14980             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14981         {
14982           is_ipv6 = 1;
14983           is_ip_any = 0;
14984         }
14985       else
14986         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14987         {
14988           is_ipv6 = 1;
14989           is_ip_any = 0;
14990         }
14991       else
14992         if (unformat
14993             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14994         {
14995           is_ipv6 = 1;
14996           is_ip_any = 0;
14997         }
14998       else
14999         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15000         {
15001           is_ipv6 = 1;
15002           is_ip_any = 0;
15003         }
15004       else
15005         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15006         {
15007           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15008             {
15009               clib_warning ("unsupported action: 'resolve'");
15010               return -99;
15011             }
15012         }
15013       else
15014         {
15015           clib_warning ("parse error '%U'", format_unformat_error, i);
15016           return -99;
15017         }
15018
15019     }
15020
15021   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15022
15023   mp->spd_id = ntohl (spd_id);
15024   mp->priority = ntohl (priority);
15025   mp->is_outbound = is_outbound;
15026
15027   mp->is_ipv6 = is_ipv6;
15028   if (is_ipv6 || is_ip_any)
15029     {
15030       clib_memcpy (mp->remote_address_start, &raddr6_start,
15031                    sizeof (ip6_address_t));
15032       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15033                    sizeof (ip6_address_t));
15034       clib_memcpy (mp->local_address_start, &laddr6_start,
15035                    sizeof (ip6_address_t));
15036       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15037                    sizeof (ip6_address_t));
15038     }
15039   else
15040     {
15041       clib_memcpy (mp->remote_address_start, &raddr4_start,
15042                    sizeof (ip4_address_t));
15043       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15044                    sizeof (ip4_address_t));
15045       clib_memcpy (mp->local_address_start, &laddr4_start,
15046                    sizeof (ip4_address_t));
15047       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15048                    sizeof (ip4_address_t));
15049     }
15050   mp->protocol = (u8) protocol;
15051   mp->local_port_start = ntohs ((u16) lport_start);
15052   mp->local_port_stop = ntohs ((u16) lport_stop);
15053   mp->remote_port_start = ntohs ((u16) rport_start);
15054   mp->remote_port_stop = ntohs ((u16) rport_stop);
15055   mp->policy = (u8) policy;
15056   mp->sa_id = ntohl (sa_id);
15057   mp->is_add = is_add;
15058   mp->is_ip_any = is_ip_any;
15059   S (mp);
15060   W (ret);
15061   return ret;
15062 }
15063
15064 static int
15065 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15066 {
15067   unformat_input_t *i = vam->input;
15068   vl_api_ipsec_sad_add_del_entry_t *mp;
15069   u32 sad_id = 0, spi = 0;
15070   u8 *ck = 0, *ik = 0;
15071   u8 is_add = 1;
15072
15073   u8 protocol = IPSEC_PROTOCOL_AH;
15074   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15075   u32 crypto_alg = 0, integ_alg = 0;
15076   ip4_address_t tun_src4;
15077   ip4_address_t tun_dst4;
15078   ip6_address_t tun_src6;
15079   ip6_address_t tun_dst6;
15080   int ret;
15081
15082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15083     {
15084       if (unformat (i, "del"))
15085         is_add = 0;
15086       else if (unformat (i, "sad_id %d", &sad_id))
15087         ;
15088       else if (unformat (i, "spi %d", &spi))
15089         ;
15090       else if (unformat (i, "esp"))
15091         protocol = IPSEC_PROTOCOL_ESP;
15092       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15093         {
15094           is_tunnel = 1;
15095           is_tunnel_ipv6 = 0;
15096         }
15097       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15098         {
15099           is_tunnel = 1;
15100           is_tunnel_ipv6 = 0;
15101         }
15102       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15103         {
15104           is_tunnel = 1;
15105           is_tunnel_ipv6 = 1;
15106         }
15107       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15108         {
15109           is_tunnel = 1;
15110           is_tunnel_ipv6 = 1;
15111         }
15112       else
15113         if (unformat
15114             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15115         {
15116           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15117             {
15118               clib_warning ("unsupported crypto-alg: '%U'",
15119                             format_ipsec_crypto_alg, crypto_alg);
15120               return -99;
15121             }
15122         }
15123       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15124         ;
15125       else
15126         if (unformat
15127             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15128         {
15129           if (integ_alg >= IPSEC_INTEG_N_ALG)
15130             {
15131               clib_warning ("unsupported integ-alg: '%U'",
15132                             format_ipsec_integ_alg, integ_alg);
15133               return -99;
15134             }
15135         }
15136       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15137         ;
15138       else
15139         {
15140           clib_warning ("parse error '%U'", format_unformat_error, i);
15141           return -99;
15142         }
15143
15144     }
15145
15146   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15147
15148   mp->sad_id = ntohl (sad_id);
15149   mp->is_add = is_add;
15150   mp->protocol = protocol;
15151   mp->spi = ntohl (spi);
15152   mp->is_tunnel = is_tunnel;
15153   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15154   mp->crypto_algorithm = crypto_alg;
15155   mp->integrity_algorithm = integ_alg;
15156   mp->crypto_key_length = vec_len (ck);
15157   mp->integrity_key_length = vec_len (ik);
15158
15159   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15160     mp->crypto_key_length = sizeof (mp->crypto_key);
15161
15162   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15163     mp->integrity_key_length = sizeof (mp->integrity_key);
15164
15165   if (ck)
15166     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15167   if (ik)
15168     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15169
15170   if (is_tunnel)
15171     {
15172       if (is_tunnel_ipv6)
15173         {
15174           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15175                        sizeof (ip6_address_t));
15176           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15177                        sizeof (ip6_address_t));
15178         }
15179       else
15180         {
15181           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15182                        sizeof (ip4_address_t));
15183           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15184                        sizeof (ip4_address_t));
15185         }
15186     }
15187
15188   S (mp);
15189   W (ret);
15190   return ret;
15191 }
15192
15193 static int
15194 api_ipsec_sa_set_key (vat_main_t * vam)
15195 {
15196   unformat_input_t *i = vam->input;
15197   vl_api_ipsec_sa_set_key_t *mp;
15198   u32 sa_id;
15199   u8 *ck = 0, *ik = 0;
15200   int ret;
15201
15202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15203     {
15204       if (unformat (i, "sa_id %d", &sa_id))
15205         ;
15206       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15207         ;
15208       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15209         ;
15210       else
15211         {
15212           clib_warning ("parse error '%U'", format_unformat_error, i);
15213           return -99;
15214         }
15215     }
15216
15217   M (IPSEC_SA_SET_KEY, mp);
15218
15219   mp->sa_id = ntohl (sa_id);
15220   mp->crypto_key_length = vec_len (ck);
15221   mp->integrity_key_length = vec_len (ik);
15222
15223   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15224     mp->crypto_key_length = sizeof (mp->crypto_key);
15225
15226   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15227     mp->integrity_key_length = sizeof (mp->integrity_key);
15228
15229   if (ck)
15230     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15231   if (ik)
15232     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15233
15234   S (mp);
15235   W (ret);
15236   return ret;
15237 }
15238
15239 static int
15240 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15241 {
15242   unformat_input_t *i = vam->input;
15243   vl_api_ipsec_tunnel_if_add_del_t *mp;
15244   u32 local_spi = 0, remote_spi = 0;
15245   u32 crypto_alg = 0, integ_alg = 0;
15246   u8 *lck = NULL, *rck = NULL;
15247   u8 *lik = NULL, *rik = NULL;
15248   ip4_address_t local_ip = { {0} };
15249   ip4_address_t remote_ip = { {0} };
15250   u8 is_add = 1;
15251   u8 esn = 0;
15252   u8 anti_replay = 0;
15253   u8 renumber = 0;
15254   u32 instance = ~0;
15255   int ret;
15256
15257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15258     {
15259       if (unformat (i, "del"))
15260         is_add = 0;
15261       else if (unformat (i, "esn"))
15262         esn = 1;
15263       else if (unformat (i, "anti_replay"))
15264         anti_replay = 1;
15265       else if (unformat (i, "local_spi %d", &local_spi))
15266         ;
15267       else if (unformat (i, "remote_spi %d", &remote_spi))
15268         ;
15269       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15270         ;
15271       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15272         ;
15273       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15274         ;
15275       else
15276         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15277         ;
15278       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15279         ;
15280       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15281         ;
15282       else
15283         if (unformat
15284             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15285         {
15286           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15287             {
15288               errmsg ("unsupported crypto-alg: '%U'\n",
15289                       format_ipsec_crypto_alg, crypto_alg);
15290               return -99;
15291             }
15292         }
15293       else
15294         if (unformat
15295             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15296         {
15297           if (integ_alg >= IPSEC_INTEG_N_ALG)
15298             {
15299               errmsg ("unsupported integ-alg: '%U'\n",
15300                       format_ipsec_integ_alg, integ_alg);
15301               return -99;
15302             }
15303         }
15304       else if (unformat (i, "instance %u", &instance))
15305         renumber = 1;
15306       else
15307         {
15308           errmsg ("parse error '%U'\n", format_unformat_error, i);
15309           return -99;
15310         }
15311     }
15312
15313   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15314
15315   mp->is_add = is_add;
15316   mp->esn = esn;
15317   mp->anti_replay = anti_replay;
15318
15319   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15320   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15321
15322   mp->local_spi = htonl (local_spi);
15323   mp->remote_spi = htonl (remote_spi);
15324   mp->crypto_alg = (u8) crypto_alg;
15325
15326   mp->local_crypto_key_len = 0;
15327   if (lck)
15328     {
15329       mp->local_crypto_key_len = vec_len (lck);
15330       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15331         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15332       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15333     }
15334
15335   mp->remote_crypto_key_len = 0;
15336   if (rck)
15337     {
15338       mp->remote_crypto_key_len = vec_len (rck);
15339       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15340         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15341       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15342     }
15343
15344   mp->integ_alg = (u8) integ_alg;
15345
15346   mp->local_integ_key_len = 0;
15347   if (lik)
15348     {
15349       mp->local_integ_key_len = vec_len (lik);
15350       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15351         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15352       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15353     }
15354
15355   mp->remote_integ_key_len = 0;
15356   if (rik)
15357     {
15358       mp->remote_integ_key_len = vec_len (rik);
15359       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15360         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15361       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15362     }
15363
15364   if (renumber)
15365     {
15366       mp->renumber = renumber;
15367       mp->show_instance = ntohl (instance);
15368     }
15369
15370   S (mp);
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static void
15376 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15377 {
15378   vat_main_t *vam = &vat_main;
15379
15380   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15381          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15382          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15383          "tunnel_src_addr %U tunnel_dst_addr %U "
15384          "salt %u seq_outbound %lu last_seq_inbound %lu "
15385          "replay_window %lu total_data_size %lu\n",
15386          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15387          mp->protocol,
15388          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15389          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15390          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15391          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15392          mp->tunnel_src_addr,
15393          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15394          mp->tunnel_dst_addr,
15395          ntohl (mp->salt),
15396          clib_net_to_host_u64 (mp->seq_outbound),
15397          clib_net_to_host_u64 (mp->last_seq_inbound),
15398          clib_net_to_host_u64 (mp->replay_window),
15399          clib_net_to_host_u64 (mp->total_data_size));
15400 }
15401
15402 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15403 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15404
15405 static void vl_api_ipsec_sa_details_t_handler_json
15406   (vl_api_ipsec_sa_details_t * mp)
15407 {
15408   vat_main_t *vam = &vat_main;
15409   vat_json_node_t *node = NULL;
15410   struct in_addr src_ip4, dst_ip4;
15411   struct in6_addr src_ip6, dst_ip6;
15412
15413   if (VAT_JSON_ARRAY != vam->json_tree.type)
15414     {
15415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15416       vat_json_init_array (&vam->json_tree);
15417     }
15418   node = vat_json_array_add (&vam->json_tree);
15419
15420   vat_json_init_object (node);
15421   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15422   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15423   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15424   vat_json_object_add_uint (node, "proto", mp->protocol);
15425   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15426   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15427   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15428   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15429   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15430   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15431   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15432                              mp->crypto_key_len);
15433   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15434                              mp->integ_key_len);
15435   if (mp->is_tunnel_ip6)
15436     {
15437       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15438       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15439       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15440       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15441     }
15442   else
15443     {
15444       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15445       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15446       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15447       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15448     }
15449   vat_json_object_add_uint (node, "replay_window",
15450                             clib_net_to_host_u64 (mp->replay_window));
15451   vat_json_object_add_uint (node, "total_data_size",
15452                             clib_net_to_host_u64 (mp->total_data_size));
15453
15454 }
15455
15456 static int
15457 api_ipsec_sa_dump (vat_main_t * vam)
15458 {
15459   unformat_input_t *i = vam->input;
15460   vl_api_ipsec_sa_dump_t *mp;
15461   vl_api_control_ping_t *mp_ping;
15462   u32 sa_id = ~0;
15463   int ret;
15464
15465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (i, "sa_id %d", &sa_id))
15468         ;
15469       else
15470         {
15471           clib_warning ("parse error '%U'", format_unformat_error, i);
15472           return -99;
15473         }
15474     }
15475
15476   M (IPSEC_SA_DUMP, mp);
15477
15478   mp->sa_id = ntohl (sa_id);
15479
15480   S (mp);
15481
15482   /* Use a control ping for synchronization */
15483   M (CONTROL_PING, mp_ping);
15484   S (mp_ping);
15485
15486   W (ret);
15487   return ret;
15488 }
15489
15490 static int
15491 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15492 {
15493   unformat_input_t *i = vam->input;
15494   vl_api_ipsec_tunnel_if_set_key_t *mp;
15495   u32 sw_if_index = ~0;
15496   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15497   u8 *key = 0;
15498   u32 alg = ~0;
15499   int ret;
15500
15501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15502     {
15503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15504         ;
15505       else
15506         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15507         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15508       else
15509         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15510         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15511       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15512         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15513       else
15514         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15515         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15516       else if (unformat (i, "%U", unformat_hex_string, &key))
15517         ;
15518       else
15519         {
15520           clib_warning ("parse error '%U'", format_unformat_error, i);
15521           return -99;
15522         }
15523     }
15524
15525   if (sw_if_index == ~0)
15526     {
15527       errmsg ("interface must be specified");
15528       return -99;
15529     }
15530
15531   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15532     {
15533       errmsg ("key type must be specified");
15534       return -99;
15535     }
15536
15537   if (alg == ~0)
15538     {
15539       errmsg ("algorithm must be specified");
15540       return -99;
15541     }
15542
15543   if (vec_len (key) == 0)
15544     {
15545       errmsg ("key must be specified");
15546       return -99;
15547     }
15548
15549   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15550
15551   mp->sw_if_index = htonl (sw_if_index);
15552   mp->alg = alg;
15553   mp->key_type = key_type;
15554   mp->key_len = vec_len (key);
15555   clib_memcpy (mp->key, key, vec_len (key));
15556
15557   S (mp);
15558   W (ret);
15559
15560   return ret;
15561 }
15562
15563 static int
15564 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15565 {
15566   unformat_input_t *i = vam->input;
15567   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15568   u32 sw_if_index = ~0;
15569   u32 sa_id = ~0;
15570   u8 is_outbound = (u8) ~ 0;
15571   int ret;
15572
15573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15574     {
15575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15576         ;
15577       else if (unformat (i, "sa_id %d", &sa_id))
15578         ;
15579       else if (unformat (i, "outbound"))
15580         is_outbound = 1;
15581       else if (unformat (i, "inbound"))
15582         is_outbound = 0;
15583       else
15584         {
15585           clib_warning ("parse error '%U'", format_unformat_error, i);
15586           return -99;
15587         }
15588     }
15589
15590   if (sw_if_index == ~0)
15591     {
15592       errmsg ("interface must be specified");
15593       return -99;
15594     }
15595
15596   if (sa_id == ~0)
15597     {
15598       errmsg ("SA ID must be specified");
15599       return -99;
15600     }
15601
15602   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15603
15604   mp->sw_if_index = htonl (sw_if_index);
15605   mp->sa_id = htonl (sa_id);
15606   mp->is_outbound = is_outbound;
15607
15608   S (mp);
15609   W (ret);
15610
15611   return ret;
15612 }
15613
15614 static int
15615 api_ikev2_profile_add_del (vat_main_t * vam)
15616 {
15617   unformat_input_t *i = vam->input;
15618   vl_api_ikev2_profile_add_del_t *mp;
15619   u8 is_add = 1;
15620   u8 *name = 0;
15621   int ret;
15622
15623   const char *valid_chars = "a-zA-Z0-9_";
15624
15625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15626     {
15627       if (unformat (i, "del"))
15628         is_add = 0;
15629       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15630         vec_add1 (name, 0);
15631       else
15632         {
15633           errmsg ("parse error '%U'", format_unformat_error, i);
15634           return -99;
15635         }
15636     }
15637
15638   if (!vec_len (name))
15639     {
15640       errmsg ("profile name must be specified");
15641       return -99;
15642     }
15643
15644   if (vec_len (name) > 64)
15645     {
15646       errmsg ("profile name too long");
15647       return -99;
15648     }
15649
15650   M (IKEV2_PROFILE_ADD_DEL, mp);
15651
15652   clib_memcpy (mp->name, name, vec_len (name));
15653   mp->is_add = is_add;
15654   vec_free (name);
15655
15656   S (mp);
15657   W (ret);
15658   return ret;
15659 }
15660
15661 static int
15662 api_ikev2_profile_set_auth (vat_main_t * vam)
15663 {
15664   unformat_input_t *i = vam->input;
15665   vl_api_ikev2_profile_set_auth_t *mp;
15666   u8 *name = 0;
15667   u8 *data = 0;
15668   u32 auth_method = 0;
15669   u8 is_hex = 0;
15670   int ret;
15671
15672   const char *valid_chars = "a-zA-Z0-9_";
15673
15674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15675     {
15676       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15677         vec_add1 (name, 0);
15678       else if (unformat (i, "auth_method %U",
15679                          unformat_ikev2_auth_method, &auth_method))
15680         ;
15681       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15682         is_hex = 1;
15683       else if (unformat (i, "auth_data %v", &data))
15684         ;
15685       else
15686         {
15687           errmsg ("parse error '%U'", format_unformat_error, i);
15688           return -99;
15689         }
15690     }
15691
15692   if (!vec_len (name))
15693     {
15694       errmsg ("profile name must be specified");
15695       return -99;
15696     }
15697
15698   if (vec_len (name) > 64)
15699     {
15700       errmsg ("profile name too long");
15701       return -99;
15702     }
15703
15704   if (!vec_len (data))
15705     {
15706       errmsg ("auth_data must be specified");
15707       return -99;
15708     }
15709
15710   if (!auth_method)
15711     {
15712       errmsg ("auth_method must be specified");
15713       return -99;
15714     }
15715
15716   M (IKEV2_PROFILE_SET_AUTH, mp);
15717
15718   mp->is_hex = is_hex;
15719   mp->auth_method = (u8) auth_method;
15720   mp->data_len = vec_len (data);
15721   clib_memcpy (mp->name, name, vec_len (name));
15722   clib_memcpy (mp->data, data, vec_len (data));
15723   vec_free (name);
15724   vec_free (data);
15725
15726   S (mp);
15727   W (ret);
15728   return ret;
15729 }
15730
15731 static int
15732 api_ikev2_profile_set_id (vat_main_t * vam)
15733 {
15734   unformat_input_t *i = vam->input;
15735   vl_api_ikev2_profile_set_id_t *mp;
15736   u8 *name = 0;
15737   u8 *data = 0;
15738   u8 is_local = 0;
15739   u32 id_type = 0;
15740   ip4_address_t ip4;
15741   int ret;
15742
15743   const char *valid_chars = "a-zA-Z0-9_";
15744
15745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15746     {
15747       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15748         vec_add1 (name, 0);
15749       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15750         ;
15751       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15752         {
15753           data = vec_new (u8, 4);
15754           clib_memcpy (data, ip4.as_u8, 4);
15755         }
15756       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15757         ;
15758       else if (unformat (i, "id_data %v", &data))
15759         ;
15760       else if (unformat (i, "local"))
15761         is_local = 1;
15762       else if (unformat (i, "remote"))
15763         is_local = 0;
15764       else
15765         {
15766           errmsg ("parse error '%U'", format_unformat_error, i);
15767           return -99;
15768         }
15769     }
15770
15771   if (!vec_len (name))
15772     {
15773       errmsg ("profile name must be specified");
15774       return -99;
15775     }
15776
15777   if (vec_len (name) > 64)
15778     {
15779       errmsg ("profile name too long");
15780       return -99;
15781     }
15782
15783   if (!vec_len (data))
15784     {
15785       errmsg ("id_data must be specified");
15786       return -99;
15787     }
15788
15789   if (!id_type)
15790     {
15791       errmsg ("id_type must be specified");
15792       return -99;
15793     }
15794
15795   M (IKEV2_PROFILE_SET_ID, mp);
15796
15797   mp->is_local = is_local;
15798   mp->id_type = (u8) id_type;
15799   mp->data_len = vec_len (data);
15800   clib_memcpy (mp->name, name, vec_len (name));
15801   clib_memcpy (mp->data, data, vec_len (data));
15802   vec_free (name);
15803   vec_free (data);
15804
15805   S (mp);
15806   W (ret);
15807   return ret;
15808 }
15809
15810 static int
15811 api_ikev2_profile_set_ts (vat_main_t * vam)
15812 {
15813   unformat_input_t *i = vam->input;
15814   vl_api_ikev2_profile_set_ts_t *mp;
15815   u8 *name = 0;
15816   u8 is_local = 0;
15817   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15818   ip4_address_t start_addr, end_addr;
15819
15820   const char *valid_chars = "a-zA-Z0-9_";
15821   int ret;
15822
15823   start_addr.as_u32 = 0;
15824   end_addr.as_u32 = (u32) ~ 0;
15825
15826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15827     {
15828       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15829         vec_add1 (name, 0);
15830       else if (unformat (i, "protocol %d", &proto))
15831         ;
15832       else if (unformat (i, "start_port %d", &start_port))
15833         ;
15834       else if (unformat (i, "end_port %d", &end_port))
15835         ;
15836       else
15837         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15838         ;
15839       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15840         ;
15841       else if (unformat (i, "local"))
15842         is_local = 1;
15843       else if (unformat (i, "remote"))
15844         is_local = 0;
15845       else
15846         {
15847           errmsg ("parse error '%U'", format_unformat_error, i);
15848           return -99;
15849         }
15850     }
15851
15852   if (!vec_len (name))
15853     {
15854       errmsg ("profile name must be specified");
15855       return -99;
15856     }
15857
15858   if (vec_len (name) > 64)
15859     {
15860       errmsg ("profile name too long");
15861       return -99;
15862     }
15863
15864   M (IKEV2_PROFILE_SET_TS, mp);
15865
15866   mp->is_local = is_local;
15867   mp->proto = (u8) proto;
15868   mp->start_port = (u16) start_port;
15869   mp->end_port = (u16) end_port;
15870   mp->start_addr = start_addr.as_u32;
15871   mp->end_addr = end_addr.as_u32;
15872   clib_memcpy (mp->name, name, vec_len (name));
15873   vec_free (name);
15874
15875   S (mp);
15876   W (ret);
15877   return ret;
15878 }
15879
15880 static int
15881 api_ikev2_set_local_key (vat_main_t * vam)
15882 {
15883   unformat_input_t *i = vam->input;
15884   vl_api_ikev2_set_local_key_t *mp;
15885   u8 *file = 0;
15886   int ret;
15887
15888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15889     {
15890       if (unformat (i, "file %v", &file))
15891         vec_add1 (file, 0);
15892       else
15893         {
15894           errmsg ("parse error '%U'", format_unformat_error, i);
15895           return -99;
15896         }
15897     }
15898
15899   if (!vec_len (file))
15900     {
15901       errmsg ("RSA key file must be specified");
15902       return -99;
15903     }
15904
15905   if (vec_len (file) > 256)
15906     {
15907       errmsg ("file name too long");
15908       return -99;
15909     }
15910
15911   M (IKEV2_SET_LOCAL_KEY, mp);
15912
15913   clib_memcpy (mp->key_file, file, vec_len (file));
15914   vec_free (file);
15915
15916   S (mp);
15917   W (ret);
15918   return ret;
15919 }
15920
15921 static int
15922 api_ikev2_set_responder (vat_main_t * vam)
15923 {
15924   unformat_input_t *i = vam->input;
15925   vl_api_ikev2_set_responder_t *mp;
15926   int ret;
15927   u8 *name = 0;
15928   u32 sw_if_index = ~0;
15929   ip4_address_t address;
15930
15931   const char *valid_chars = "a-zA-Z0-9_";
15932
15933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15934     {
15935       if (unformat
15936           (i, "%U interface %d address %U", unformat_token, valid_chars,
15937            &name, &sw_if_index, unformat_ip4_address, &address))
15938         vec_add1 (name, 0);
15939       else
15940         {
15941           errmsg ("parse error '%U'", format_unformat_error, i);
15942           return -99;
15943         }
15944     }
15945
15946   if (!vec_len (name))
15947     {
15948       errmsg ("profile name must be specified");
15949       return -99;
15950     }
15951
15952   if (vec_len (name) > 64)
15953     {
15954       errmsg ("profile name too long");
15955       return -99;
15956     }
15957
15958   M (IKEV2_SET_RESPONDER, mp);
15959
15960   clib_memcpy (mp->name, name, vec_len (name));
15961   vec_free (name);
15962
15963   mp->sw_if_index = sw_if_index;
15964   clib_memcpy (mp->address, &address, sizeof (address));
15965
15966   S (mp);
15967   W (ret);
15968   return ret;
15969 }
15970
15971 static int
15972 api_ikev2_set_ike_transforms (vat_main_t * vam)
15973 {
15974   unformat_input_t *i = vam->input;
15975   vl_api_ikev2_set_ike_transforms_t *mp;
15976   int ret;
15977   u8 *name = 0;
15978   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15979
15980   const char *valid_chars = "a-zA-Z0-9_";
15981
15982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15983     {
15984       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15985                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15986         vec_add1 (name, 0);
15987       else
15988         {
15989           errmsg ("parse error '%U'", format_unformat_error, i);
15990           return -99;
15991         }
15992     }
15993
15994   if (!vec_len (name))
15995     {
15996       errmsg ("profile name must be specified");
15997       return -99;
15998     }
15999
16000   if (vec_len (name) > 64)
16001     {
16002       errmsg ("profile name too long");
16003       return -99;
16004     }
16005
16006   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16007
16008   clib_memcpy (mp->name, name, vec_len (name));
16009   vec_free (name);
16010   mp->crypto_alg = crypto_alg;
16011   mp->crypto_key_size = crypto_key_size;
16012   mp->integ_alg = integ_alg;
16013   mp->dh_group = dh_group;
16014
16015   S (mp);
16016   W (ret);
16017   return ret;
16018 }
16019
16020
16021 static int
16022 api_ikev2_set_esp_transforms (vat_main_t * vam)
16023 {
16024   unformat_input_t *i = vam->input;
16025   vl_api_ikev2_set_esp_transforms_t *mp;
16026   int ret;
16027   u8 *name = 0;
16028   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16029
16030   const char *valid_chars = "a-zA-Z0-9_";
16031
16032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16033     {
16034       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16035                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16036         vec_add1 (name, 0);
16037       else
16038         {
16039           errmsg ("parse error '%U'", format_unformat_error, i);
16040           return -99;
16041         }
16042     }
16043
16044   if (!vec_len (name))
16045     {
16046       errmsg ("profile name must be specified");
16047       return -99;
16048     }
16049
16050   if (vec_len (name) > 64)
16051     {
16052       errmsg ("profile name too long");
16053       return -99;
16054     }
16055
16056   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16057
16058   clib_memcpy (mp->name, name, vec_len (name));
16059   vec_free (name);
16060   mp->crypto_alg = crypto_alg;
16061   mp->crypto_key_size = crypto_key_size;
16062   mp->integ_alg = integ_alg;
16063   mp->dh_group = dh_group;
16064
16065   S (mp);
16066   W (ret);
16067   return ret;
16068 }
16069
16070 static int
16071 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16072 {
16073   unformat_input_t *i = vam->input;
16074   vl_api_ikev2_set_sa_lifetime_t *mp;
16075   int ret;
16076   u8 *name = 0;
16077   u64 lifetime, lifetime_maxdata;
16078   u32 lifetime_jitter, handover;
16079
16080   const char *valid_chars = "a-zA-Z0-9_";
16081
16082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16083     {
16084       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16085                     &lifetime, &lifetime_jitter, &handover,
16086                     &lifetime_maxdata))
16087         vec_add1 (name, 0);
16088       else
16089         {
16090           errmsg ("parse error '%U'", format_unformat_error, i);
16091           return -99;
16092         }
16093     }
16094
16095   if (!vec_len (name))
16096     {
16097       errmsg ("profile name must be specified");
16098       return -99;
16099     }
16100
16101   if (vec_len (name) > 64)
16102     {
16103       errmsg ("profile name too long");
16104       return -99;
16105     }
16106
16107   M (IKEV2_SET_SA_LIFETIME, mp);
16108
16109   clib_memcpy (mp->name, name, vec_len (name));
16110   vec_free (name);
16111   mp->lifetime = lifetime;
16112   mp->lifetime_jitter = lifetime_jitter;
16113   mp->handover = handover;
16114   mp->lifetime_maxdata = lifetime_maxdata;
16115
16116   S (mp);
16117   W (ret);
16118   return ret;
16119 }
16120
16121 static int
16122 api_ikev2_initiate_sa_init (vat_main_t * vam)
16123 {
16124   unformat_input_t *i = vam->input;
16125   vl_api_ikev2_initiate_sa_init_t *mp;
16126   int ret;
16127   u8 *name = 0;
16128
16129   const char *valid_chars = "a-zA-Z0-9_";
16130
16131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16132     {
16133       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16134         vec_add1 (name, 0);
16135       else
16136         {
16137           errmsg ("parse error '%U'", format_unformat_error, i);
16138           return -99;
16139         }
16140     }
16141
16142   if (!vec_len (name))
16143     {
16144       errmsg ("profile name must be specified");
16145       return -99;
16146     }
16147
16148   if (vec_len (name) > 64)
16149     {
16150       errmsg ("profile name too long");
16151       return -99;
16152     }
16153
16154   M (IKEV2_INITIATE_SA_INIT, mp);
16155
16156   clib_memcpy (mp->name, name, vec_len (name));
16157   vec_free (name);
16158
16159   S (mp);
16160   W (ret);
16161   return ret;
16162 }
16163
16164 static int
16165 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16166 {
16167   unformat_input_t *i = vam->input;
16168   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16169   int ret;
16170   u64 ispi;
16171
16172
16173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16174     {
16175       if (unformat (i, "%lx", &ispi))
16176         ;
16177       else
16178         {
16179           errmsg ("parse error '%U'", format_unformat_error, i);
16180           return -99;
16181         }
16182     }
16183
16184   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16185
16186   mp->ispi = ispi;
16187
16188   S (mp);
16189   W (ret);
16190   return ret;
16191 }
16192
16193 static int
16194 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16195 {
16196   unformat_input_t *i = vam->input;
16197   vl_api_ikev2_initiate_del_child_sa_t *mp;
16198   int ret;
16199   u32 ispi;
16200
16201
16202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16203     {
16204       if (unformat (i, "%x", &ispi))
16205         ;
16206       else
16207         {
16208           errmsg ("parse error '%U'", format_unformat_error, i);
16209           return -99;
16210         }
16211     }
16212
16213   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16214
16215   mp->ispi = ispi;
16216
16217   S (mp);
16218   W (ret);
16219   return ret;
16220 }
16221
16222 static int
16223 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16224 {
16225   unformat_input_t *i = vam->input;
16226   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16227   int ret;
16228   u32 ispi;
16229
16230
16231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16232     {
16233       if (unformat (i, "%x", &ispi))
16234         ;
16235       else
16236         {
16237           errmsg ("parse error '%U'", format_unformat_error, i);
16238           return -99;
16239         }
16240     }
16241
16242   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16243
16244   mp->ispi = ispi;
16245
16246   S (mp);
16247   W (ret);
16248   return ret;
16249 }
16250
16251 static int
16252 api_get_first_msg_id (vat_main_t * vam)
16253 {
16254   vl_api_get_first_msg_id_t *mp;
16255   unformat_input_t *i = vam->input;
16256   u8 *name;
16257   u8 name_set = 0;
16258   int ret;
16259
16260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16261     {
16262       if (unformat (i, "client %s", &name))
16263         name_set = 1;
16264       else
16265         break;
16266     }
16267
16268   if (name_set == 0)
16269     {
16270       errmsg ("missing client name");
16271       return -99;
16272     }
16273   vec_add1 (name, 0);
16274
16275   if (vec_len (name) > 63)
16276     {
16277       errmsg ("client name too long");
16278       return -99;
16279     }
16280
16281   M (GET_FIRST_MSG_ID, mp);
16282   clib_memcpy (mp->name, name, vec_len (name));
16283   S (mp);
16284   W (ret);
16285   return ret;
16286 }
16287
16288 static int
16289 api_cop_interface_enable_disable (vat_main_t * vam)
16290 {
16291   unformat_input_t *line_input = vam->input;
16292   vl_api_cop_interface_enable_disable_t *mp;
16293   u32 sw_if_index = ~0;
16294   u8 enable_disable = 1;
16295   int ret;
16296
16297   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16298     {
16299       if (unformat (line_input, "disable"))
16300         enable_disable = 0;
16301       if (unformat (line_input, "enable"))
16302         enable_disable = 1;
16303       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16304                          vam, &sw_if_index))
16305         ;
16306       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16307         ;
16308       else
16309         break;
16310     }
16311
16312   if (sw_if_index == ~0)
16313     {
16314       errmsg ("missing interface name or sw_if_index");
16315       return -99;
16316     }
16317
16318   /* Construct the API message */
16319   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16320   mp->sw_if_index = ntohl (sw_if_index);
16321   mp->enable_disable = enable_disable;
16322
16323   /* send it... */
16324   S (mp);
16325   /* Wait for the reply */
16326   W (ret);
16327   return ret;
16328 }
16329
16330 static int
16331 api_cop_whitelist_enable_disable (vat_main_t * vam)
16332 {
16333   unformat_input_t *line_input = vam->input;
16334   vl_api_cop_whitelist_enable_disable_t *mp;
16335   u32 sw_if_index = ~0;
16336   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16337   u32 fib_id = 0;
16338   int ret;
16339
16340   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16341     {
16342       if (unformat (line_input, "ip4"))
16343         ip4 = 1;
16344       else if (unformat (line_input, "ip6"))
16345         ip6 = 1;
16346       else if (unformat (line_input, "default"))
16347         default_cop = 1;
16348       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16349                          vam, &sw_if_index))
16350         ;
16351       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16352         ;
16353       else if (unformat (line_input, "fib-id %d", &fib_id))
16354         ;
16355       else
16356         break;
16357     }
16358
16359   if (sw_if_index == ~0)
16360     {
16361       errmsg ("missing interface name or sw_if_index");
16362       return -99;
16363     }
16364
16365   /* Construct the API message */
16366   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16367   mp->sw_if_index = ntohl (sw_if_index);
16368   mp->fib_id = ntohl (fib_id);
16369   mp->ip4 = ip4;
16370   mp->ip6 = ip6;
16371   mp->default_cop = default_cop;
16372
16373   /* send it... */
16374   S (mp);
16375   /* Wait for the reply */
16376   W (ret);
16377   return ret;
16378 }
16379
16380 static int
16381 api_get_node_graph (vat_main_t * vam)
16382 {
16383   vl_api_get_node_graph_t *mp;
16384   int ret;
16385
16386   M (GET_NODE_GRAPH, mp);
16387
16388   /* send it... */
16389   S (mp);
16390   /* Wait for the reply */
16391   W (ret);
16392   return ret;
16393 }
16394
16395 /* *INDENT-OFF* */
16396 /** Used for parsing LISP eids */
16397 typedef CLIB_PACKED(struct{
16398   u8 addr[16];   /**< eid address */
16399   u32 len;       /**< prefix length if IP */
16400   u8 type;      /**< type of eid */
16401 }) lisp_eid_vat_t;
16402 /* *INDENT-ON* */
16403
16404 static uword
16405 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16406 {
16407   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16408
16409   clib_memset (a, 0, sizeof (a[0]));
16410
16411   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16412     {
16413       a->type = 0;              /* ipv4 type */
16414     }
16415   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16416     {
16417       a->type = 1;              /* ipv6 type */
16418     }
16419   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16420     {
16421       a->type = 2;              /* mac type */
16422     }
16423   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16424     {
16425       a->type = 3;              /* NSH type */
16426       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16427       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16428     }
16429   else
16430     {
16431       return 0;
16432     }
16433
16434   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16435     {
16436       return 0;
16437     }
16438
16439   return 1;
16440 }
16441
16442 static int
16443 lisp_eid_size_vat (u8 type)
16444 {
16445   switch (type)
16446     {
16447     case 0:
16448       return 4;
16449     case 1:
16450       return 16;
16451     case 2:
16452       return 6;
16453     case 3:
16454       return 5;
16455     }
16456   return 0;
16457 }
16458
16459 static void
16460 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16461 {
16462   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16463 }
16464
16465 static int
16466 api_one_add_del_locator_set (vat_main_t * vam)
16467 {
16468   unformat_input_t *input = vam->input;
16469   vl_api_one_add_del_locator_set_t *mp;
16470   u8 is_add = 1;
16471   u8 *locator_set_name = NULL;
16472   u8 locator_set_name_set = 0;
16473   vl_api_local_locator_t locator, *locators = 0;
16474   u32 sw_if_index, priority, weight;
16475   u32 data_len = 0;
16476
16477   int ret;
16478   /* Parse args required to build the message */
16479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16480     {
16481       if (unformat (input, "del"))
16482         {
16483           is_add = 0;
16484         }
16485       else if (unformat (input, "locator-set %s", &locator_set_name))
16486         {
16487           locator_set_name_set = 1;
16488         }
16489       else if (unformat (input, "sw_if_index %u p %u w %u",
16490                          &sw_if_index, &priority, &weight))
16491         {
16492           locator.sw_if_index = htonl (sw_if_index);
16493           locator.priority = priority;
16494           locator.weight = weight;
16495           vec_add1 (locators, locator);
16496         }
16497       else
16498         if (unformat
16499             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16500              &sw_if_index, &priority, &weight))
16501         {
16502           locator.sw_if_index = htonl (sw_if_index);
16503           locator.priority = priority;
16504           locator.weight = weight;
16505           vec_add1 (locators, locator);
16506         }
16507       else
16508         break;
16509     }
16510
16511   if (locator_set_name_set == 0)
16512     {
16513       errmsg ("missing locator-set name");
16514       vec_free (locators);
16515       return -99;
16516     }
16517
16518   if (vec_len (locator_set_name) > 64)
16519     {
16520       errmsg ("locator-set name too long");
16521       vec_free (locator_set_name);
16522       vec_free (locators);
16523       return -99;
16524     }
16525   vec_add1 (locator_set_name, 0);
16526
16527   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16528
16529   /* Construct the API message */
16530   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16531
16532   mp->is_add = is_add;
16533   clib_memcpy (mp->locator_set_name, locator_set_name,
16534                vec_len (locator_set_name));
16535   vec_free (locator_set_name);
16536
16537   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16538   if (locators)
16539     clib_memcpy (mp->locators, locators, data_len);
16540   vec_free (locators);
16541
16542   /* send it... */
16543   S (mp);
16544
16545   /* Wait for a reply... */
16546   W (ret);
16547   return ret;
16548 }
16549
16550 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16551
16552 static int
16553 api_one_add_del_locator (vat_main_t * vam)
16554 {
16555   unformat_input_t *input = vam->input;
16556   vl_api_one_add_del_locator_t *mp;
16557   u32 tmp_if_index = ~0;
16558   u32 sw_if_index = ~0;
16559   u8 sw_if_index_set = 0;
16560   u8 sw_if_index_if_name_set = 0;
16561   u32 priority = ~0;
16562   u8 priority_set = 0;
16563   u32 weight = ~0;
16564   u8 weight_set = 0;
16565   u8 is_add = 1;
16566   u8 *locator_set_name = NULL;
16567   u8 locator_set_name_set = 0;
16568   int ret;
16569
16570   /* Parse args required to build the message */
16571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (input, "del"))
16574         {
16575           is_add = 0;
16576         }
16577       else if (unformat (input, "locator-set %s", &locator_set_name))
16578         {
16579           locator_set_name_set = 1;
16580         }
16581       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16582                          &tmp_if_index))
16583         {
16584           sw_if_index_if_name_set = 1;
16585           sw_if_index = tmp_if_index;
16586         }
16587       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16588         {
16589           sw_if_index_set = 1;
16590           sw_if_index = tmp_if_index;
16591         }
16592       else if (unformat (input, "p %d", &priority))
16593         {
16594           priority_set = 1;
16595         }
16596       else if (unformat (input, "w %d", &weight))
16597         {
16598           weight_set = 1;
16599         }
16600       else
16601         break;
16602     }
16603
16604   if (locator_set_name_set == 0)
16605     {
16606       errmsg ("missing locator-set name");
16607       return -99;
16608     }
16609
16610   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16611     {
16612       errmsg ("missing sw_if_index");
16613       vec_free (locator_set_name);
16614       return -99;
16615     }
16616
16617   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16618     {
16619       errmsg ("cannot use both params interface name and sw_if_index");
16620       vec_free (locator_set_name);
16621       return -99;
16622     }
16623
16624   if (priority_set == 0)
16625     {
16626       errmsg ("missing locator-set priority");
16627       vec_free (locator_set_name);
16628       return -99;
16629     }
16630
16631   if (weight_set == 0)
16632     {
16633       errmsg ("missing locator-set weight");
16634       vec_free (locator_set_name);
16635       return -99;
16636     }
16637
16638   if (vec_len (locator_set_name) > 64)
16639     {
16640       errmsg ("locator-set name too long");
16641       vec_free (locator_set_name);
16642       return -99;
16643     }
16644   vec_add1 (locator_set_name, 0);
16645
16646   /* Construct the API message */
16647   M (ONE_ADD_DEL_LOCATOR, mp);
16648
16649   mp->is_add = is_add;
16650   mp->sw_if_index = ntohl (sw_if_index);
16651   mp->priority = priority;
16652   mp->weight = weight;
16653   clib_memcpy (mp->locator_set_name, locator_set_name,
16654                vec_len (locator_set_name));
16655   vec_free (locator_set_name);
16656
16657   /* send it... */
16658   S (mp);
16659
16660   /* Wait for a reply... */
16661   W (ret);
16662   return ret;
16663 }
16664
16665 #define api_lisp_add_del_locator api_one_add_del_locator
16666
16667 uword
16668 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16669 {
16670   u32 *key_id = va_arg (*args, u32 *);
16671   u8 *s = 0;
16672
16673   if (unformat (input, "%s", &s))
16674     {
16675       if (!strcmp ((char *) s, "sha1"))
16676         key_id[0] = HMAC_SHA_1_96;
16677       else if (!strcmp ((char *) s, "sha256"))
16678         key_id[0] = HMAC_SHA_256_128;
16679       else
16680         {
16681           clib_warning ("invalid key_id: '%s'", s);
16682           key_id[0] = HMAC_NO_KEY;
16683         }
16684     }
16685   else
16686     return 0;
16687
16688   vec_free (s);
16689   return 1;
16690 }
16691
16692 static int
16693 api_one_add_del_local_eid (vat_main_t * vam)
16694 {
16695   unformat_input_t *input = vam->input;
16696   vl_api_one_add_del_local_eid_t *mp;
16697   u8 is_add = 1;
16698   u8 eid_set = 0;
16699   lisp_eid_vat_t _eid, *eid = &_eid;
16700   u8 *locator_set_name = 0;
16701   u8 locator_set_name_set = 0;
16702   u32 vni = 0;
16703   u16 key_id = 0;
16704   u8 *key = 0;
16705   int ret;
16706
16707   /* Parse args required to build the message */
16708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16709     {
16710       if (unformat (input, "del"))
16711         {
16712           is_add = 0;
16713         }
16714       else if (unformat (input, "vni %d", &vni))
16715         {
16716           ;
16717         }
16718       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16719         {
16720           eid_set = 1;
16721         }
16722       else if (unformat (input, "locator-set %s", &locator_set_name))
16723         {
16724           locator_set_name_set = 1;
16725         }
16726       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16727         ;
16728       else if (unformat (input, "secret-key %_%v%_", &key))
16729         ;
16730       else
16731         break;
16732     }
16733
16734   if (locator_set_name_set == 0)
16735     {
16736       errmsg ("missing locator-set name");
16737       return -99;
16738     }
16739
16740   if (0 == eid_set)
16741     {
16742       errmsg ("EID address not set!");
16743       vec_free (locator_set_name);
16744       return -99;
16745     }
16746
16747   if (key && (0 == key_id))
16748     {
16749       errmsg ("invalid key_id!");
16750       return -99;
16751     }
16752
16753   if (vec_len (key) > 64)
16754     {
16755       errmsg ("key too long");
16756       vec_free (key);
16757       return -99;
16758     }
16759
16760   if (vec_len (locator_set_name) > 64)
16761     {
16762       errmsg ("locator-set name too long");
16763       vec_free (locator_set_name);
16764       return -99;
16765     }
16766   vec_add1 (locator_set_name, 0);
16767
16768   /* Construct the API message */
16769   M (ONE_ADD_DEL_LOCAL_EID, mp);
16770
16771   mp->is_add = is_add;
16772   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16773   mp->eid_type = eid->type;
16774   mp->prefix_len = eid->len;
16775   mp->vni = clib_host_to_net_u32 (vni);
16776   mp->key_id = clib_host_to_net_u16 (key_id);
16777   clib_memcpy (mp->locator_set_name, locator_set_name,
16778                vec_len (locator_set_name));
16779   clib_memcpy (mp->key, key, vec_len (key));
16780
16781   vec_free (locator_set_name);
16782   vec_free (key);
16783
16784   /* send it... */
16785   S (mp);
16786
16787   /* Wait for a reply... */
16788   W (ret);
16789   return ret;
16790 }
16791
16792 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16793
16794 static int
16795 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16796 {
16797   u32 dp_table = 0, vni = 0;;
16798   unformat_input_t *input = vam->input;
16799   vl_api_gpe_add_del_fwd_entry_t *mp;
16800   u8 is_add = 1;
16801   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16802   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16803   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16804   u32 action = ~0, w;
16805   ip4_address_t rmt_rloc4, lcl_rloc4;
16806   ip6_address_t rmt_rloc6, lcl_rloc6;
16807   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16808   int ret;
16809
16810   clib_memset (&rloc, 0, sizeof (rloc));
16811
16812   /* Parse args required to build the message */
16813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16814     {
16815       if (unformat (input, "del"))
16816         is_add = 0;
16817       else if (unformat (input, "add"))
16818         is_add = 1;
16819       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16820         {
16821           rmt_eid_set = 1;
16822         }
16823       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16824         {
16825           lcl_eid_set = 1;
16826         }
16827       else if (unformat (input, "vrf %d", &dp_table))
16828         ;
16829       else if (unformat (input, "bd %d", &dp_table))
16830         ;
16831       else if (unformat (input, "vni %d", &vni))
16832         ;
16833       else if (unformat (input, "w %d", &w))
16834         {
16835           if (!curr_rloc)
16836             {
16837               errmsg ("No RLOC configured for setting priority/weight!");
16838               return -99;
16839             }
16840           curr_rloc->weight = w;
16841         }
16842       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16843                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16844         {
16845           rloc.is_ip4 = 1;
16846
16847           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16848           rloc.weight = 0;
16849           vec_add1 (lcl_locs, rloc);
16850
16851           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16852           vec_add1 (rmt_locs, rloc);
16853           /* weight saved in rmt loc */
16854           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16855         }
16856       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16857                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16858         {
16859           rloc.is_ip4 = 0;
16860           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16861           rloc.weight = 0;
16862           vec_add1 (lcl_locs, rloc);
16863
16864           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16865           vec_add1 (rmt_locs, rloc);
16866           /* weight saved in rmt loc */
16867           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16868         }
16869       else if (unformat (input, "action %d", &action))
16870         {
16871           ;
16872         }
16873       else
16874         {
16875           clib_warning ("parse error '%U'", format_unformat_error, input);
16876           return -99;
16877         }
16878     }
16879
16880   if (!rmt_eid_set)
16881     {
16882       errmsg ("remote eid addresses not set");
16883       return -99;
16884     }
16885
16886   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16887     {
16888       errmsg ("eid types don't match");
16889       return -99;
16890     }
16891
16892   if (0 == rmt_locs && (u32) ~ 0 == action)
16893     {
16894       errmsg ("action not set for negative mapping");
16895       return -99;
16896     }
16897
16898   /* Construct the API message */
16899   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16900       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16901
16902   mp->is_add = is_add;
16903   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16904   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16905   mp->eid_type = rmt_eid->type;
16906   mp->dp_table = clib_host_to_net_u32 (dp_table);
16907   mp->vni = clib_host_to_net_u32 (vni);
16908   mp->rmt_len = rmt_eid->len;
16909   mp->lcl_len = lcl_eid->len;
16910   mp->action = action;
16911
16912   if (0 != rmt_locs && 0 != lcl_locs)
16913     {
16914       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16915       clib_memcpy (mp->locs, lcl_locs,
16916                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16917
16918       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16919       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16920                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16921     }
16922   vec_free (lcl_locs);
16923   vec_free (rmt_locs);
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Wait for a reply... */
16929   W (ret);
16930   return ret;
16931 }
16932
16933 static int
16934 api_one_add_del_map_server (vat_main_t * vam)
16935 {
16936   unformat_input_t *input = vam->input;
16937   vl_api_one_add_del_map_server_t *mp;
16938   u8 is_add = 1;
16939   u8 ipv4_set = 0;
16940   u8 ipv6_set = 0;
16941   ip4_address_t ipv4;
16942   ip6_address_t ipv6;
16943   int ret;
16944
16945   /* Parse args required to build the message */
16946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16947     {
16948       if (unformat (input, "del"))
16949         {
16950           is_add = 0;
16951         }
16952       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16953         {
16954           ipv4_set = 1;
16955         }
16956       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16957         {
16958           ipv6_set = 1;
16959         }
16960       else
16961         break;
16962     }
16963
16964   if (ipv4_set && ipv6_set)
16965     {
16966       errmsg ("both eid v4 and v6 addresses set");
16967       return -99;
16968     }
16969
16970   if (!ipv4_set && !ipv6_set)
16971     {
16972       errmsg ("eid addresses not set");
16973       return -99;
16974     }
16975
16976   /* Construct the API message */
16977   M (ONE_ADD_DEL_MAP_SERVER, mp);
16978
16979   mp->is_add = is_add;
16980   if (ipv6_set)
16981     {
16982       mp->is_ipv6 = 1;
16983       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16984     }
16985   else
16986     {
16987       mp->is_ipv6 = 0;
16988       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16989     }
16990
16991   /* send it... */
16992   S (mp);
16993
16994   /* Wait for a reply... */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 #define api_lisp_add_del_map_server api_one_add_del_map_server
17000
17001 static int
17002 api_one_add_del_map_resolver (vat_main_t * vam)
17003 {
17004   unformat_input_t *input = vam->input;
17005   vl_api_one_add_del_map_resolver_t *mp;
17006   u8 is_add = 1;
17007   u8 ipv4_set = 0;
17008   u8 ipv6_set = 0;
17009   ip4_address_t ipv4;
17010   ip6_address_t ipv6;
17011   int ret;
17012
17013   /* Parse args required to build the message */
17014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17015     {
17016       if (unformat (input, "del"))
17017         {
17018           is_add = 0;
17019         }
17020       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17021         {
17022           ipv4_set = 1;
17023         }
17024       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17025         {
17026           ipv6_set = 1;
17027         }
17028       else
17029         break;
17030     }
17031
17032   if (ipv4_set && ipv6_set)
17033     {
17034       errmsg ("both eid v4 and v6 addresses set");
17035       return -99;
17036     }
17037
17038   if (!ipv4_set && !ipv6_set)
17039     {
17040       errmsg ("eid addresses not set");
17041       return -99;
17042     }
17043
17044   /* Construct the API message */
17045   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17046
17047   mp->is_add = is_add;
17048   if (ipv6_set)
17049     {
17050       mp->is_ipv6 = 1;
17051       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17052     }
17053   else
17054     {
17055       mp->is_ipv6 = 0;
17056       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17057     }
17058
17059   /* send it... */
17060   S (mp);
17061
17062   /* Wait for a reply... */
17063   W (ret);
17064   return ret;
17065 }
17066
17067 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17068
17069 static int
17070 api_lisp_gpe_enable_disable (vat_main_t * vam)
17071 {
17072   unformat_input_t *input = vam->input;
17073   vl_api_gpe_enable_disable_t *mp;
17074   u8 is_set = 0;
17075   u8 is_en = 1;
17076   int ret;
17077
17078   /* Parse args required to build the message */
17079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17080     {
17081       if (unformat (input, "enable"))
17082         {
17083           is_set = 1;
17084           is_en = 1;
17085         }
17086       else if (unformat (input, "disable"))
17087         {
17088           is_set = 1;
17089           is_en = 0;
17090         }
17091       else
17092         break;
17093     }
17094
17095   if (is_set == 0)
17096     {
17097       errmsg ("Value not set");
17098       return -99;
17099     }
17100
17101   /* Construct the API message */
17102   M (GPE_ENABLE_DISABLE, mp);
17103
17104   mp->is_en = is_en;
17105
17106   /* send it... */
17107   S (mp);
17108
17109   /* Wait for a reply... */
17110   W (ret);
17111   return ret;
17112 }
17113
17114 static int
17115 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17116 {
17117   unformat_input_t *input = vam->input;
17118   vl_api_one_rloc_probe_enable_disable_t *mp;
17119   u8 is_set = 0;
17120   u8 is_en = 0;
17121   int ret;
17122
17123   /* Parse args required to build the message */
17124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (input, "enable"))
17127         {
17128           is_set = 1;
17129           is_en = 1;
17130         }
17131       else if (unformat (input, "disable"))
17132         is_set = 1;
17133       else
17134         break;
17135     }
17136
17137   if (!is_set)
17138     {
17139       errmsg ("Value not set");
17140       return -99;
17141     }
17142
17143   /* Construct the API message */
17144   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17145
17146   mp->is_enabled = is_en;
17147
17148   /* send it... */
17149   S (mp);
17150
17151   /* Wait for a reply... */
17152   W (ret);
17153   return ret;
17154 }
17155
17156 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17157
17158 static int
17159 api_one_map_register_enable_disable (vat_main_t * vam)
17160 {
17161   unformat_input_t *input = vam->input;
17162   vl_api_one_map_register_enable_disable_t *mp;
17163   u8 is_set = 0;
17164   u8 is_en = 0;
17165   int ret;
17166
17167   /* Parse args required to build the message */
17168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17169     {
17170       if (unformat (input, "enable"))
17171         {
17172           is_set = 1;
17173           is_en = 1;
17174         }
17175       else if (unformat (input, "disable"))
17176         is_set = 1;
17177       else
17178         break;
17179     }
17180
17181   if (!is_set)
17182     {
17183       errmsg ("Value not set");
17184       return -99;
17185     }
17186
17187   /* Construct the API message */
17188   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17189
17190   mp->is_enabled = is_en;
17191
17192   /* send it... */
17193   S (mp);
17194
17195   /* Wait for a reply... */
17196   W (ret);
17197   return ret;
17198 }
17199
17200 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17201
17202 static int
17203 api_one_enable_disable (vat_main_t * vam)
17204 {
17205   unformat_input_t *input = vam->input;
17206   vl_api_one_enable_disable_t *mp;
17207   u8 is_set = 0;
17208   u8 is_en = 0;
17209   int ret;
17210
17211   /* Parse args required to build the message */
17212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17213     {
17214       if (unformat (input, "enable"))
17215         {
17216           is_set = 1;
17217           is_en = 1;
17218         }
17219       else if (unformat (input, "disable"))
17220         {
17221           is_set = 1;
17222         }
17223       else
17224         break;
17225     }
17226
17227   if (!is_set)
17228     {
17229       errmsg ("Value not set");
17230       return -99;
17231     }
17232
17233   /* Construct the API message */
17234   M (ONE_ENABLE_DISABLE, mp);
17235
17236   mp->is_en = is_en;
17237
17238   /* send it... */
17239   S (mp);
17240
17241   /* Wait for a reply... */
17242   W (ret);
17243   return ret;
17244 }
17245
17246 #define api_lisp_enable_disable api_one_enable_disable
17247
17248 static int
17249 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17250 {
17251   unformat_input_t *input = vam->input;
17252   vl_api_one_enable_disable_xtr_mode_t *mp;
17253   u8 is_set = 0;
17254   u8 is_en = 0;
17255   int ret;
17256
17257   /* Parse args required to build the message */
17258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17259     {
17260       if (unformat (input, "enable"))
17261         {
17262           is_set = 1;
17263           is_en = 1;
17264         }
17265       else if (unformat (input, "disable"))
17266         {
17267           is_set = 1;
17268         }
17269       else
17270         break;
17271     }
17272
17273   if (!is_set)
17274     {
17275       errmsg ("Value not set");
17276       return -99;
17277     }
17278
17279   /* Construct the API message */
17280   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17281
17282   mp->is_en = is_en;
17283
17284   /* send it... */
17285   S (mp);
17286
17287   /* Wait for a reply... */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 static int
17293 api_one_show_xtr_mode (vat_main_t * vam)
17294 {
17295   vl_api_one_show_xtr_mode_t *mp;
17296   int ret;
17297
17298   /* Construct the API message */
17299   M (ONE_SHOW_XTR_MODE, mp);
17300
17301   /* send it... */
17302   S (mp);
17303
17304   /* Wait for a reply... */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static int
17310 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17311 {
17312   unformat_input_t *input = vam->input;
17313   vl_api_one_enable_disable_pitr_mode_t *mp;
17314   u8 is_set = 0;
17315   u8 is_en = 0;
17316   int ret;
17317
17318   /* Parse args required to build the message */
17319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17320     {
17321       if (unformat (input, "enable"))
17322         {
17323           is_set = 1;
17324           is_en = 1;
17325         }
17326       else if (unformat (input, "disable"))
17327         {
17328           is_set = 1;
17329         }
17330       else
17331         break;
17332     }
17333
17334   if (!is_set)
17335     {
17336       errmsg ("Value not set");
17337       return -99;
17338     }
17339
17340   /* Construct the API message */
17341   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17342
17343   mp->is_en = is_en;
17344
17345   /* send it... */
17346   S (mp);
17347
17348   /* Wait for a reply... */
17349   W (ret);
17350   return ret;
17351 }
17352
17353 static int
17354 api_one_show_pitr_mode (vat_main_t * vam)
17355 {
17356   vl_api_one_show_pitr_mode_t *mp;
17357   int ret;
17358
17359   /* Construct the API message */
17360   M (ONE_SHOW_PITR_MODE, mp);
17361
17362   /* send it... */
17363   S (mp);
17364
17365   /* Wait for a reply... */
17366   W (ret);
17367   return ret;
17368 }
17369
17370 static int
17371 api_one_enable_disable_petr_mode (vat_main_t * vam)
17372 {
17373   unformat_input_t *input = vam->input;
17374   vl_api_one_enable_disable_petr_mode_t *mp;
17375   u8 is_set = 0;
17376   u8 is_en = 0;
17377   int ret;
17378
17379   /* Parse args required to build the message */
17380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17381     {
17382       if (unformat (input, "enable"))
17383         {
17384           is_set = 1;
17385           is_en = 1;
17386         }
17387       else if (unformat (input, "disable"))
17388         {
17389           is_set = 1;
17390         }
17391       else
17392         break;
17393     }
17394
17395   if (!is_set)
17396     {
17397       errmsg ("Value not set");
17398       return -99;
17399     }
17400
17401   /* Construct the API message */
17402   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17403
17404   mp->is_en = is_en;
17405
17406   /* send it... */
17407   S (mp);
17408
17409   /* Wait for a reply... */
17410   W (ret);
17411   return ret;
17412 }
17413
17414 static int
17415 api_one_show_petr_mode (vat_main_t * vam)
17416 {
17417   vl_api_one_show_petr_mode_t *mp;
17418   int ret;
17419
17420   /* Construct the API message */
17421   M (ONE_SHOW_PETR_MODE, mp);
17422
17423   /* send it... */
17424   S (mp);
17425
17426   /* Wait for a reply... */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_show_one_map_register_state (vat_main_t * vam)
17433 {
17434   vl_api_show_one_map_register_state_t *mp;
17435   int ret;
17436
17437   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17438
17439   /* send */
17440   S (mp);
17441
17442   /* wait for reply */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 #define api_show_lisp_map_register_state api_show_one_map_register_state
17448
17449 static int
17450 api_show_one_rloc_probe_state (vat_main_t * vam)
17451 {
17452   vl_api_show_one_rloc_probe_state_t *mp;
17453   int ret;
17454
17455   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17456
17457   /* send */
17458   S (mp);
17459
17460   /* wait for reply */
17461   W (ret);
17462   return ret;
17463 }
17464
17465 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17466
17467 static int
17468 api_one_add_del_ndp_entry (vat_main_t * vam)
17469 {
17470   vl_api_one_add_del_ndp_entry_t *mp;
17471   unformat_input_t *input = vam->input;
17472   u8 is_add = 1;
17473   u8 mac_set = 0;
17474   u8 bd_set = 0;
17475   u8 ip_set = 0;
17476   u8 mac[6] = { 0, };
17477   u8 ip6[16] = { 0, };
17478   u32 bd = ~0;
17479   int ret;
17480
17481   /* Parse args required to build the message */
17482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17483     {
17484       if (unformat (input, "del"))
17485         is_add = 0;
17486       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17487         mac_set = 1;
17488       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17489         ip_set = 1;
17490       else if (unformat (input, "bd %d", &bd))
17491         bd_set = 1;
17492       else
17493         {
17494           errmsg ("parse error '%U'", format_unformat_error, input);
17495           return -99;
17496         }
17497     }
17498
17499   if (!bd_set || !ip_set || (!mac_set && is_add))
17500     {
17501       errmsg ("Missing BD, IP or MAC!");
17502       return -99;
17503     }
17504
17505   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17506   mp->is_add = is_add;
17507   clib_memcpy (mp->mac, mac, 6);
17508   mp->bd = clib_host_to_net_u32 (bd);
17509   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17510
17511   /* send */
17512   S (mp);
17513
17514   /* wait for reply */
17515   W (ret);
17516   return ret;
17517 }
17518
17519 static int
17520 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17521 {
17522   vl_api_one_add_del_l2_arp_entry_t *mp;
17523   unformat_input_t *input = vam->input;
17524   u8 is_add = 1;
17525   u8 mac_set = 0;
17526   u8 bd_set = 0;
17527   u8 ip_set = 0;
17528   u8 mac[6] = { 0, };
17529   u32 ip4 = 0, bd = ~0;
17530   int ret;
17531
17532   /* Parse args required to build the message */
17533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (input, "del"))
17536         is_add = 0;
17537       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17538         mac_set = 1;
17539       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17540         ip_set = 1;
17541       else if (unformat (input, "bd %d", &bd))
17542         bd_set = 1;
17543       else
17544         {
17545           errmsg ("parse error '%U'", format_unformat_error, input);
17546           return -99;
17547         }
17548     }
17549
17550   if (!bd_set || !ip_set || (!mac_set && is_add))
17551     {
17552       errmsg ("Missing BD, IP or MAC!");
17553       return -99;
17554     }
17555
17556   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17557   mp->is_add = is_add;
17558   clib_memcpy (mp->mac, mac, 6);
17559   mp->bd = clib_host_to_net_u32 (bd);
17560   mp->ip4 = ip4;
17561
17562   /* send */
17563   S (mp);
17564
17565   /* wait for reply */
17566   W (ret);
17567   return ret;
17568 }
17569
17570 static int
17571 api_one_ndp_bd_get (vat_main_t * vam)
17572 {
17573   vl_api_one_ndp_bd_get_t *mp;
17574   int ret;
17575
17576   M (ONE_NDP_BD_GET, mp);
17577
17578   /* send */
17579   S (mp);
17580
17581   /* wait for reply */
17582   W (ret);
17583   return ret;
17584 }
17585
17586 static int
17587 api_one_ndp_entries_get (vat_main_t * vam)
17588 {
17589   vl_api_one_ndp_entries_get_t *mp;
17590   unformat_input_t *input = vam->input;
17591   u8 bd_set = 0;
17592   u32 bd = ~0;
17593   int ret;
17594
17595   /* Parse args required to build the message */
17596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17597     {
17598       if (unformat (input, "bd %d", &bd))
17599         bd_set = 1;
17600       else
17601         {
17602           errmsg ("parse error '%U'", format_unformat_error, input);
17603           return -99;
17604         }
17605     }
17606
17607   if (!bd_set)
17608     {
17609       errmsg ("Expected bridge domain!");
17610       return -99;
17611     }
17612
17613   M (ONE_NDP_ENTRIES_GET, mp);
17614   mp->bd = clib_host_to_net_u32 (bd);
17615
17616   /* send */
17617   S (mp);
17618
17619   /* wait for reply */
17620   W (ret);
17621   return ret;
17622 }
17623
17624 static int
17625 api_one_l2_arp_bd_get (vat_main_t * vam)
17626 {
17627   vl_api_one_l2_arp_bd_get_t *mp;
17628   int ret;
17629
17630   M (ONE_L2_ARP_BD_GET, mp);
17631
17632   /* send */
17633   S (mp);
17634
17635   /* wait for reply */
17636   W (ret);
17637   return ret;
17638 }
17639
17640 static int
17641 api_one_l2_arp_entries_get (vat_main_t * vam)
17642 {
17643   vl_api_one_l2_arp_entries_get_t *mp;
17644   unformat_input_t *input = vam->input;
17645   u8 bd_set = 0;
17646   u32 bd = ~0;
17647   int ret;
17648
17649   /* Parse args required to build the message */
17650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17651     {
17652       if (unformat (input, "bd %d", &bd))
17653         bd_set = 1;
17654       else
17655         {
17656           errmsg ("parse error '%U'", format_unformat_error, input);
17657           return -99;
17658         }
17659     }
17660
17661   if (!bd_set)
17662     {
17663       errmsg ("Expected bridge domain!");
17664       return -99;
17665     }
17666
17667   M (ONE_L2_ARP_ENTRIES_GET, mp);
17668   mp->bd = clib_host_to_net_u32 (bd);
17669
17670   /* send */
17671   S (mp);
17672
17673   /* wait for reply */
17674   W (ret);
17675   return ret;
17676 }
17677
17678 static int
17679 api_one_stats_enable_disable (vat_main_t * vam)
17680 {
17681   vl_api_one_stats_enable_disable_t *mp;
17682   unformat_input_t *input = vam->input;
17683   u8 is_set = 0;
17684   u8 is_en = 0;
17685   int ret;
17686
17687   /* Parse args required to build the message */
17688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17689     {
17690       if (unformat (input, "enable"))
17691         {
17692           is_set = 1;
17693           is_en = 1;
17694         }
17695       else if (unformat (input, "disable"))
17696         {
17697           is_set = 1;
17698         }
17699       else
17700         break;
17701     }
17702
17703   if (!is_set)
17704     {
17705       errmsg ("Value not set");
17706       return -99;
17707     }
17708
17709   M (ONE_STATS_ENABLE_DISABLE, mp);
17710   mp->is_en = is_en;
17711
17712   /* send */
17713   S (mp);
17714
17715   /* wait for reply */
17716   W (ret);
17717   return ret;
17718 }
17719
17720 static int
17721 api_show_one_stats_enable_disable (vat_main_t * vam)
17722 {
17723   vl_api_show_one_stats_enable_disable_t *mp;
17724   int ret;
17725
17726   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17727
17728   /* send */
17729   S (mp);
17730
17731   /* wait for reply */
17732   W (ret);
17733   return ret;
17734 }
17735
17736 static int
17737 api_show_one_map_request_mode (vat_main_t * vam)
17738 {
17739   vl_api_show_one_map_request_mode_t *mp;
17740   int ret;
17741
17742   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17743
17744   /* send */
17745   S (mp);
17746
17747   /* wait for reply */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17753
17754 static int
17755 api_one_map_request_mode (vat_main_t * vam)
17756 {
17757   unformat_input_t *input = vam->input;
17758   vl_api_one_map_request_mode_t *mp;
17759   u8 mode = 0;
17760   int ret;
17761
17762   /* Parse args required to build the message */
17763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (input, "dst-only"))
17766         mode = 0;
17767       else if (unformat (input, "src-dst"))
17768         mode = 1;
17769       else
17770         {
17771           errmsg ("parse error '%U'", format_unformat_error, input);
17772           return -99;
17773         }
17774     }
17775
17776   M (ONE_MAP_REQUEST_MODE, mp);
17777
17778   mp->mode = mode;
17779
17780   /* send */
17781   S (mp);
17782
17783   /* wait for reply */
17784   W (ret);
17785   return ret;
17786 }
17787
17788 #define api_lisp_map_request_mode api_one_map_request_mode
17789
17790 /**
17791  * Enable/disable ONE proxy ITR.
17792  *
17793  * @param vam vpp API test context
17794  * @return return code
17795  */
17796 static int
17797 api_one_pitr_set_locator_set (vat_main_t * vam)
17798 {
17799   u8 ls_name_set = 0;
17800   unformat_input_t *input = vam->input;
17801   vl_api_one_pitr_set_locator_set_t *mp;
17802   u8 is_add = 1;
17803   u8 *ls_name = 0;
17804   int ret;
17805
17806   /* Parse args required to build the message */
17807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17808     {
17809       if (unformat (input, "del"))
17810         is_add = 0;
17811       else if (unformat (input, "locator-set %s", &ls_name))
17812         ls_name_set = 1;
17813       else
17814         {
17815           errmsg ("parse error '%U'", format_unformat_error, input);
17816           return -99;
17817         }
17818     }
17819
17820   if (!ls_name_set)
17821     {
17822       errmsg ("locator-set name not set!");
17823       return -99;
17824     }
17825
17826   M (ONE_PITR_SET_LOCATOR_SET, mp);
17827
17828   mp->is_add = is_add;
17829   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17830   vec_free (ls_name);
17831
17832   /* send */
17833   S (mp);
17834
17835   /* wait for reply */
17836   W (ret);
17837   return ret;
17838 }
17839
17840 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17841
17842 static int
17843 api_one_nsh_set_locator_set (vat_main_t * vam)
17844 {
17845   u8 ls_name_set = 0;
17846   unformat_input_t *input = vam->input;
17847   vl_api_one_nsh_set_locator_set_t *mp;
17848   u8 is_add = 1;
17849   u8 *ls_name = 0;
17850   int ret;
17851
17852   /* Parse args required to build the message */
17853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (input, "del"))
17856         is_add = 0;
17857       else if (unformat (input, "ls %s", &ls_name))
17858         ls_name_set = 1;
17859       else
17860         {
17861           errmsg ("parse error '%U'", format_unformat_error, input);
17862           return -99;
17863         }
17864     }
17865
17866   if (!ls_name_set && is_add)
17867     {
17868       errmsg ("locator-set name not set!");
17869       return -99;
17870     }
17871
17872   M (ONE_NSH_SET_LOCATOR_SET, mp);
17873
17874   mp->is_add = is_add;
17875   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17876   vec_free (ls_name);
17877
17878   /* send */
17879   S (mp);
17880
17881   /* wait for reply */
17882   W (ret);
17883   return ret;
17884 }
17885
17886 static int
17887 api_show_one_pitr (vat_main_t * vam)
17888 {
17889   vl_api_show_one_pitr_t *mp;
17890   int ret;
17891
17892   if (!vam->json_output)
17893     {
17894       print (vam->ofp, "%=20s", "lisp status:");
17895     }
17896
17897   M (SHOW_ONE_PITR, mp);
17898   /* send it... */
17899   S (mp);
17900
17901   /* Wait for a reply... */
17902   W (ret);
17903   return ret;
17904 }
17905
17906 #define api_show_lisp_pitr api_show_one_pitr
17907
17908 static int
17909 api_one_use_petr (vat_main_t * vam)
17910 {
17911   unformat_input_t *input = vam->input;
17912   vl_api_one_use_petr_t *mp;
17913   u8 is_add = 0;
17914   ip_address_t ip;
17915   int ret;
17916
17917   clib_memset (&ip, 0, sizeof (ip));
17918
17919   /* Parse args required to build the message */
17920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17921     {
17922       if (unformat (input, "disable"))
17923         is_add = 0;
17924       else
17925         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17926         {
17927           is_add = 1;
17928           ip_addr_version (&ip) = IP4;
17929         }
17930       else
17931         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17932         {
17933           is_add = 1;
17934           ip_addr_version (&ip) = IP6;
17935         }
17936       else
17937         {
17938           errmsg ("parse error '%U'", format_unformat_error, input);
17939           return -99;
17940         }
17941     }
17942
17943   M (ONE_USE_PETR, mp);
17944
17945   mp->is_add = is_add;
17946   if (is_add)
17947     {
17948       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17949       if (mp->is_ip4)
17950         clib_memcpy (mp->address, &ip, 4);
17951       else
17952         clib_memcpy (mp->address, &ip, 16);
17953     }
17954
17955   /* send */
17956   S (mp);
17957
17958   /* wait for reply */
17959   W (ret);
17960   return ret;
17961 }
17962
17963 #define api_lisp_use_petr api_one_use_petr
17964
17965 static int
17966 api_show_one_nsh_mapping (vat_main_t * vam)
17967 {
17968   vl_api_show_one_use_petr_t *mp;
17969   int ret;
17970
17971   if (!vam->json_output)
17972     {
17973       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17974     }
17975
17976   M (SHOW_ONE_NSH_MAPPING, mp);
17977   /* send it... */
17978   S (mp);
17979
17980   /* Wait for a reply... */
17981   W (ret);
17982   return ret;
17983 }
17984
17985 static int
17986 api_show_one_use_petr (vat_main_t * vam)
17987 {
17988   vl_api_show_one_use_petr_t *mp;
17989   int ret;
17990
17991   if (!vam->json_output)
17992     {
17993       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17994     }
17995
17996   M (SHOW_ONE_USE_PETR, mp);
17997   /* send it... */
17998   S (mp);
17999
18000   /* Wait for a reply... */
18001   W (ret);
18002   return ret;
18003 }
18004
18005 #define api_show_lisp_use_petr api_show_one_use_petr
18006
18007 /**
18008  * Add/delete mapping between vni and vrf
18009  */
18010 static int
18011 api_one_eid_table_add_del_map (vat_main_t * vam)
18012 {
18013   unformat_input_t *input = vam->input;
18014   vl_api_one_eid_table_add_del_map_t *mp;
18015   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18016   u32 vni, vrf, bd_index;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "del"))
18023         is_add = 0;
18024       else if (unformat (input, "vrf %d", &vrf))
18025         vrf_set = 1;
18026       else if (unformat (input, "bd_index %d", &bd_index))
18027         bd_index_set = 1;
18028       else if (unformat (input, "vni %d", &vni))
18029         vni_set = 1;
18030       else
18031         break;
18032     }
18033
18034   if (!vni_set || (!vrf_set && !bd_index_set))
18035     {
18036       errmsg ("missing arguments!");
18037       return -99;
18038     }
18039
18040   if (vrf_set && bd_index_set)
18041     {
18042       errmsg ("error: both vrf and bd entered!");
18043       return -99;
18044     }
18045
18046   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18047
18048   mp->is_add = is_add;
18049   mp->vni = htonl (vni);
18050   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18051   mp->is_l2 = bd_index_set;
18052
18053   /* send */
18054   S (mp);
18055
18056   /* wait for reply */
18057   W (ret);
18058   return ret;
18059 }
18060
18061 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18062
18063 uword
18064 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18065 {
18066   u32 *action = va_arg (*args, u32 *);
18067   u8 *s = 0;
18068
18069   if (unformat (input, "%s", &s))
18070     {
18071       if (!strcmp ((char *) s, "no-action"))
18072         action[0] = 0;
18073       else if (!strcmp ((char *) s, "natively-forward"))
18074         action[0] = 1;
18075       else if (!strcmp ((char *) s, "send-map-request"))
18076         action[0] = 2;
18077       else if (!strcmp ((char *) s, "drop"))
18078         action[0] = 3;
18079       else
18080         {
18081           clib_warning ("invalid action: '%s'", s);
18082           action[0] = 3;
18083         }
18084     }
18085   else
18086     return 0;
18087
18088   vec_free (s);
18089   return 1;
18090 }
18091
18092 /**
18093  * Add/del remote mapping to/from ONE control plane
18094  *
18095  * @param vam vpp API test context
18096  * @return return code
18097  */
18098 static int
18099 api_one_add_del_remote_mapping (vat_main_t * vam)
18100 {
18101   unformat_input_t *input = vam->input;
18102   vl_api_one_add_del_remote_mapping_t *mp;
18103   u32 vni = 0;
18104   lisp_eid_vat_t _eid, *eid = &_eid;
18105   lisp_eid_vat_t _seid, *seid = &_seid;
18106   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18107   u32 action = ~0, p, w, data_len;
18108   ip4_address_t rloc4;
18109   ip6_address_t rloc6;
18110   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18111   int ret;
18112
18113   clib_memset (&rloc, 0, sizeof (rloc));
18114
18115   /* Parse args required to build the message */
18116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18117     {
18118       if (unformat (input, "del-all"))
18119         {
18120           del_all = 1;
18121         }
18122       else if (unformat (input, "del"))
18123         {
18124           is_add = 0;
18125         }
18126       else if (unformat (input, "add"))
18127         {
18128           is_add = 1;
18129         }
18130       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18131         {
18132           eid_set = 1;
18133         }
18134       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18135         {
18136           seid_set = 1;
18137         }
18138       else if (unformat (input, "vni %d", &vni))
18139         {
18140           ;
18141         }
18142       else if (unformat (input, "p %d w %d", &p, &w))
18143         {
18144           if (!curr_rloc)
18145             {
18146               errmsg ("No RLOC configured for setting priority/weight!");
18147               return -99;
18148             }
18149           curr_rloc->priority = p;
18150           curr_rloc->weight = w;
18151         }
18152       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18153         {
18154           rloc.is_ip4 = 1;
18155           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18156           vec_add1 (rlocs, rloc);
18157           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18158         }
18159       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18160         {
18161           rloc.is_ip4 = 0;
18162           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18163           vec_add1 (rlocs, rloc);
18164           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18165         }
18166       else if (unformat (input, "action %U",
18167                          unformat_negative_mapping_action, &action))
18168         {
18169           ;
18170         }
18171       else
18172         {
18173           clib_warning ("parse error '%U'", format_unformat_error, input);
18174           return -99;
18175         }
18176     }
18177
18178   if (0 == eid_set)
18179     {
18180       errmsg ("missing params!");
18181       return -99;
18182     }
18183
18184   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18185     {
18186       errmsg ("no action set for negative map-reply!");
18187       return -99;
18188     }
18189
18190   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18191
18192   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18193   mp->is_add = is_add;
18194   mp->vni = htonl (vni);
18195   mp->action = (u8) action;
18196   mp->is_src_dst = seid_set;
18197   mp->eid_len = eid->len;
18198   mp->seid_len = seid->len;
18199   mp->del_all = del_all;
18200   mp->eid_type = eid->type;
18201   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18202   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18203
18204   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18205   clib_memcpy (mp->rlocs, rlocs, data_len);
18206   vec_free (rlocs);
18207
18208   /* send it... */
18209   S (mp);
18210
18211   /* Wait for a reply... */
18212   W (ret);
18213   return ret;
18214 }
18215
18216 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18217
18218 /**
18219  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18220  * forwarding entries in data-plane accordingly.
18221  *
18222  * @param vam vpp API test context
18223  * @return return code
18224  */
18225 static int
18226 api_one_add_del_adjacency (vat_main_t * vam)
18227 {
18228   unformat_input_t *input = vam->input;
18229   vl_api_one_add_del_adjacency_t *mp;
18230   u32 vni = 0;
18231   ip4_address_t leid4, reid4;
18232   ip6_address_t leid6, reid6;
18233   u8 reid_mac[6] = { 0 };
18234   u8 leid_mac[6] = { 0 };
18235   u8 reid_type, leid_type;
18236   u32 leid_len = 0, reid_len = 0, len;
18237   u8 is_add = 1;
18238   int ret;
18239
18240   leid_type = reid_type = (u8) ~ 0;
18241
18242   /* Parse args required to build the message */
18243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18244     {
18245       if (unformat (input, "del"))
18246         {
18247           is_add = 0;
18248         }
18249       else if (unformat (input, "add"))
18250         {
18251           is_add = 1;
18252         }
18253       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18254                          &reid4, &len))
18255         {
18256           reid_type = 0;        /* ipv4 */
18257           reid_len = len;
18258         }
18259       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18260                          &reid6, &len))
18261         {
18262           reid_type = 1;        /* ipv6 */
18263           reid_len = len;
18264         }
18265       else if (unformat (input, "reid %U", unformat_ethernet_address,
18266                          reid_mac))
18267         {
18268           reid_type = 2;        /* mac */
18269         }
18270       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18271                          &leid4, &len))
18272         {
18273           leid_type = 0;        /* ipv4 */
18274           leid_len = len;
18275         }
18276       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18277                          &leid6, &len))
18278         {
18279           leid_type = 1;        /* ipv6 */
18280           leid_len = len;
18281         }
18282       else if (unformat (input, "leid %U", unformat_ethernet_address,
18283                          leid_mac))
18284         {
18285           leid_type = 2;        /* mac */
18286         }
18287       else if (unformat (input, "vni %d", &vni))
18288         {
18289           ;
18290         }
18291       else
18292         {
18293           errmsg ("parse error '%U'", format_unformat_error, input);
18294           return -99;
18295         }
18296     }
18297
18298   if ((u8) ~ 0 == reid_type)
18299     {
18300       errmsg ("missing params!");
18301       return -99;
18302     }
18303
18304   if (leid_type != reid_type)
18305     {
18306       errmsg ("remote and local EIDs are of different types!");
18307       return -99;
18308     }
18309
18310   M (ONE_ADD_DEL_ADJACENCY, mp);
18311   mp->is_add = is_add;
18312   mp->vni = htonl (vni);
18313   mp->leid_len = leid_len;
18314   mp->reid_len = reid_len;
18315   mp->eid_type = reid_type;
18316
18317   switch (mp->eid_type)
18318     {
18319     case 0:
18320       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18321       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18322       break;
18323     case 1:
18324       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18325       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18326       break;
18327     case 2:
18328       clib_memcpy (mp->leid, leid_mac, 6);
18329       clib_memcpy (mp->reid, reid_mac, 6);
18330       break;
18331     default:
18332       errmsg ("unknown EID type %d!", mp->eid_type);
18333       return 0;
18334     }
18335
18336   /* send it... */
18337   S (mp);
18338
18339   /* Wait for a reply... */
18340   W (ret);
18341   return ret;
18342 }
18343
18344 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18345
18346 uword
18347 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18348 {
18349   u32 *mode = va_arg (*args, u32 *);
18350
18351   if (unformat (input, "lisp"))
18352     *mode = 0;
18353   else if (unformat (input, "vxlan"))
18354     *mode = 1;
18355   else
18356     return 0;
18357
18358   return 1;
18359 }
18360
18361 static int
18362 api_gpe_get_encap_mode (vat_main_t * vam)
18363 {
18364   vl_api_gpe_get_encap_mode_t *mp;
18365   int ret;
18366
18367   /* Construct the API message */
18368   M (GPE_GET_ENCAP_MODE, mp);
18369
18370   /* send it... */
18371   S (mp);
18372
18373   /* Wait for a reply... */
18374   W (ret);
18375   return ret;
18376 }
18377
18378 static int
18379 api_gpe_set_encap_mode (vat_main_t * vam)
18380 {
18381   unformat_input_t *input = vam->input;
18382   vl_api_gpe_set_encap_mode_t *mp;
18383   int ret;
18384   u32 mode = 0;
18385
18386   /* Parse args required to build the message */
18387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18388     {
18389       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18390         ;
18391       else
18392         break;
18393     }
18394
18395   /* Construct the API message */
18396   M (GPE_SET_ENCAP_MODE, mp);
18397
18398   mp->mode = mode;
18399
18400   /* send it... */
18401   S (mp);
18402
18403   /* Wait for a reply... */
18404   W (ret);
18405   return ret;
18406 }
18407
18408 static int
18409 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18410 {
18411   unformat_input_t *input = vam->input;
18412   vl_api_gpe_add_del_iface_t *mp;
18413   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18414   u32 dp_table = 0, vni = 0;
18415   int ret;
18416
18417   /* Parse args required to build the message */
18418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18419     {
18420       if (unformat (input, "up"))
18421         {
18422           action_set = 1;
18423           is_add = 1;
18424         }
18425       else if (unformat (input, "down"))
18426         {
18427           action_set = 1;
18428           is_add = 0;
18429         }
18430       else if (unformat (input, "table_id %d", &dp_table))
18431         {
18432           dp_table_set = 1;
18433         }
18434       else if (unformat (input, "bd_id %d", &dp_table))
18435         {
18436           dp_table_set = 1;
18437           is_l2 = 1;
18438         }
18439       else if (unformat (input, "vni %d", &vni))
18440         {
18441           vni_set = 1;
18442         }
18443       else
18444         break;
18445     }
18446
18447   if (action_set == 0)
18448     {
18449       errmsg ("Action not set");
18450       return -99;
18451     }
18452   if (dp_table_set == 0 || vni_set == 0)
18453     {
18454       errmsg ("vni and dp_table must be set");
18455       return -99;
18456     }
18457
18458   /* Construct the API message */
18459   M (GPE_ADD_DEL_IFACE, mp);
18460
18461   mp->is_add = is_add;
18462   mp->dp_table = clib_host_to_net_u32 (dp_table);
18463   mp->is_l2 = is_l2;
18464   mp->vni = clib_host_to_net_u32 (vni);
18465
18466   /* send it... */
18467   S (mp);
18468
18469   /* Wait for a reply... */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 static int
18475 api_one_map_register_fallback_threshold (vat_main_t * vam)
18476 {
18477   unformat_input_t *input = vam->input;
18478   vl_api_one_map_register_fallback_threshold_t *mp;
18479   u32 value = 0;
18480   u8 is_set = 0;
18481   int ret;
18482
18483   /* Parse args required to build the message */
18484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18485     {
18486       if (unformat (input, "%u", &value))
18487         is_set = 1;
18488       else
18489         {
18490           clib_warning ("parse error '%U'", format_unformat_error, input);
18491           return -99;
18492         }
18493     }
18494
18495   if (!is_set)
18496     {
18497       errmsg ("fallback threshold value is missing!");
18498       return -99;
18499     }
18500
18501   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18502   mp->value = clib_host_to_net_u32 (value);
18503
18504   /* send it... */
18505   S (mp);
18506
18507   /* Wait for a reply... */
18508   W (ret);
18509   return ret;
18510 }
18511
18512 static int
18513 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18514 {
18515   vl_api_show_one_map_register_fallback_threshold_t *mp;
18516   int ret;
18517
18518   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18519
18520   /* send it... */
18521   S (mp);
18522
18523   /* Wait for a reply... */
18524   W (ret);
18525   return ret;
18526 }
18527
18528 uword
18529 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18530 {
18531   u32 *proto = va_arg (*args, u32 *);
18532
18533   if (unformat (input, "udp"))
18534     *proto = 1;
18535   else if (unformat (input, "api"))
18536     *proto = 2;
18537   else
18538     return 0;
18539
18540   return 1;
18541 }
18542
18543 static int
18544 api_one_set_transport_protocol (vat_main_t * vam)
18545 {
18546   unformat_input_t *input = vam->input;
18547   vl_api_one_set_transport_protocol_t *mp;
18548   u8 is_set = 0;
18549   u32 protocol = 0;
18550   int ret;
18551
18552   /* Parse args required to build the message */
18553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18554     {
18555       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18556         is_set = 1;
18557       else
18558         {
18559           clib_warning ("parse error '%U'", format_unformat_error, input);
18560           return -99;
18561         }
18562     }
18563
18564   if (!is_set)
18565     {
18566       errmsg ("Transport protocol missing!");
18567       return -99;
18568     }
18569
18570   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18571   mp->protocol = (u8) protocol;
18572
18573   /* send it... */
18574   S (mp);
18575
18576   /* Wait for a reply... */
18577   W (ret);
18578   return ret;
18579 }
18580
18581 static int
18582 api_one_get_transport_protocol (vat_main_t * vam)
18583 {
18584   vl_api_one_get_transport_protocol_t *mp;
18585   int ret;
18586
18587   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18588
18589   /* send it... */
18590   S (mp);
18591
18592   /* Wait for a reply... */
18593   W (ret);
18594   return ret;
18595 }
18596
18597 static int
18598 api_one_map_register_set_ttl (vat_main_t * vam)
18599 {
18600   unformat_input_t *input = vam->input;
18601   vl_api_one_map_register_set_ttl_t *mp;
18602   u32 ttl = 0;
18603   u8 is_set = 0;
18604   int ret;
18605
18606   /* Parse args required to build the message */
18607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18608     {
18609       if (unformat (input, "%u", &ttl))
18610         is_set = 1;
18611       else
18612         {
18613           clib_warning ("parse error '%U'", format_unformat_error, input);
18614           return -99;
18615         }
18616     }
18617
18618   if (!is_set)
18619     {
18620       errmsg ("TTL value missing!");
18621       return -99;
18622     }
18623
18624   M (ONE_MAP_REGISTER_SET_TTL, mp);
18625   mp->ttl = clib_host_to_net_u32 (ttl);
18626
18627   /* send it... */
18628   S (mp);
18629
18630   /* Wait for a reply... */
18631   W (ret);
18632   return ret;
18633 }
18634
18635 static int
18636 api_show_one_map_register_ttl (vat_main_t * vam)
18637 {
18638   vl_api_show_one_map_register_ttl_t *mp;
18639   int ret;
18640
18641   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18642
18643   /* send it... */
18644   S (mp);
18645
18646   /* Wait for a reply... */
18647   W (ret);
18648   return ret;
18649 }
18650
18651 /**
18652  * Add/del map request itr rlocs from ONE control plane and updates
18653  *
18654  * @param vam vpp API test context
18655  * @return return code
18656  */
18657 static int
18658 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18659 {
18660   unformat_input_t *input = vam->input;
18661   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18662   u8 *locator_set_name = 0;
18663   u8 locator_set_name_set = 0;
18664   u8 is_add = 1;
18665   int ret;
18666
18667   /* Parse args required to build the message */
18668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18669     {
18670       if (unformat (input, "del"))
18671         {
18672           is_add = 0;
18673         }
18674       else if (unformat (input, "%_%v%_", &locator_set_name))
18675         {
18676           locator_set_name_set = 1;
18677         }
18678       else
18679         {
18680           clib_warning ("parse error '%U'", format_unformat_error, input);
18681           return -99;
18682         }
18683     }
18684
18685   if (is_add && !locator_set_name_set)
18686     {
18687       errmsg ("itr-rloc is not set!");
18688       return -99;
18689     }
18690
18691   if (is_add && vec_len (locator_set_name) > 64)
18692     {
18693       errmsg ("itr-rloc locator-set name too long");
18694       vec_free (locator_set_name);
18695       return -99;
18696     }
18697
18698   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18699   mp->is_add = is_add;
18700   if (is_add)
18701     {
18702       clib_memcpy (mp->locator_set_name, locator_set_name,
18703                    vec_len (locator_set_name));
18704     }
18705   else
18706     {
18707       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18708     }
18709   vec_free (locator_set_name);
18710
18711   /* send it... */
18712   S (mp);
18713
18714   /* Wait for a reply... */
18715   W (ret);
18716   return ret;
18717 }
18718
18719 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18720
18721 static int
18722 api_one_locator_dump (vat_main_t * vam)
18723 {
18724   unformat_input_t *input = vam->input;
18725   vl_api_one_locator_dump_t *mp;
18726   vl_api_control_ping_t *mp_ping;
18727   u8 is_index_set = 0, is_name_set = 0;
18728   u8 *ls_name = 0;
18729   u32 ls_index = ~0;
18730   int ret;
18731
18732   /* Parse args required to build the message */
18733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18734     {
18735       if (unformat (input, "ls_name %_%v%_", &ls_name))
18736         {
18737           is_name_set = 1;
18738         }
18739       else if (unformat (input, "ls_index %d", &ls_index))
18740         {
18741           is_index_set = 1;
18742         }
18743       else
18744         {
18745           errmsg ("parse error '%U'", format_unformat_error, input);
18746           return -99;
18747         }
18748     }
18749
18750   if (!is_index_set && !is_name_set)
18751     {
18752       errmsg ("error: expected one of index or name!");
18753       return -99;
18754     }
18755
18756   if (is_index_set && is_name_set)
18757     {
18758       errmsg ("error: only one param expected!");
18759       return -99;
18760     }
18761
18762   if (vec_len (ls_name) > 62)
18763     {
18764       errmsg ("error: locator set name too long!");
18765       return -99;
18766     }
18767
18768   if (!vam->json_output)
18769     {
18770       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18771     }
18772
18773   M (ONE_LOCATOR_DUMP, mp);
18774   mp->is_index_set = is_index_set;
18775
18776   if (is_index_set)
18777     mp->ls_index = clib_host_to_net_u32 (ls_index);
18778   else
18779     {
18780       vec_add1 (ls_name, 0);
18781       strncpy ((char *) mp->ls_name, (char *) ls_name,
18782                sizeof (mp->ls_name) - 1);
18783     }
18784
18785   /* send it... */
18786   S (mp);
18787
18788   /* Use a control ping for synchronization */
18789   MPING (CONTROL_PING, mp_ping);
18790   S (mp_ping);
18791
18792   /* Wait for a reply... */
18793   W (ret);
18794   return ret;
18795 }
18796
18797 #define api_lisp_locator_dump api_one_locator_dump
18798
18799 static int
18800 api_one_locator_set_dump (vat_main_t * vam)
18801 {
18802   vl_api_one_locator_set_dump_t *mp;
18803   vl_api_control_ping_t *mp_ping;
18804   unformat_input_t *input = vam->input;
18805   u8 filter = 0;
18806   int ret;
18807
18808   /* Parse args required to build the message */
18809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18810     {
18811       if (unformat (input, "local"))
18812         {
18813           filter = 1;
18814         }
18815       else if (unformat (input, "remote"))
18816         {
18817           filter = 2;
18818         }
18819       else
18820         {
18821           errmsg ("parse error '%U'", format_unformat_error, input);
18822           return -99;
18823         }
18824     }
18825
18826   if (!vam->json_output)
18827     {
18828       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18829     }
18830
18831   M (ONE_LOCATOR_SET_DUMP, mp);
18832
18833   mp->filter = filter;
18834
18835   /* send it... */
18836   S (mp);
18837
18838   /* Use a control ping for synchronization */
18839   MPING (CONTROL_PING, mp_ping);
18840   S (mp_ping);
18841
18842   /* Wait for a reply... */
18843   W (ret);
18844   return ret;
18845 }
18846
18847 #define api_lisp_locator_set_dump api_one_locator_set_dump
18848
18849 static int
18850 api_one_eid_table_map_dump (vat_main_t * vam)
18851 {
18852   u8 is_l2 = 0;
18853   u8 mode_set = 0;
18854   unformat_input_t *input = vam->input;
18855   vl_api_one_eid_table_map_dump_t *mp;
18856   vl_api_control_ping_t *mp_ping;
18857   int ret;
18858
18859   /* Parse args required to build the message */
18860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18861     {
18862       if (unformat (input, "l2"))
18863         {
18864           is_l2 = 1;
18865           mode_set = 1;
18866         }
18867       else if (unformat (input, "l3"))
18868         {
18869           is_l2 = 0;
18870           mode_set = 1;
18871         }
18872       else
18873         {
18874           errmsg ("parse error '%U'", format_unformat_error, input);
18875           return -99;
18876         }
18877     }
18878
18879   if (!mode_set)
18880     {
18881       errmsg ("expected one of 'l2' or 'l3' parameter!");
18882       return -99;
18883     }
18884
18885   if (!vam->json_output)
18886     {
18887       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18888     }
18889
18890   M (ONE_EID_TABLE_MAP_DUMP, mp);
18891   mp->is_l2 = is_l2;
18892
18893   /* send it... */
18894   S (mp);
18895
18896   /* Use a control ping for synchronization */
18897   MPING (CONTROL_PING, mp_ping);
18898   S (mp_ping);
18899
18900   /* Wait for a reply... */
18901   W (ret);
18902   return ret;
18903 }
18904
18905 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18906
18907 static int
18908 api_one_eid_table_vni_dump (vat_main_t * vam)
18909 {
18910   vl_api_one_eid_table_vni_dump_t *mp;
18911   vl_api_control_ping_t *mp_ping;
18912   int ret;
18913
18914   if (!vam->json_output)
18915     {
18916       print (vam->ofp, "VNI");
18917     }
18918
18919   M (ONE_EID_TABLE_VNI_DUMP, mp);
18920
18921   /* send it... */
18922   S (mp);
18923
18924   /* Use a control ping for synchronization */
18925   MPING (CONTROL_PING, mp_ping);
18926   S (mp_ping);
18927
18928   /* Wait for a reply... */
18929   W (ret);
18930   return ret;
18931 }
18932
18933 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18934
18935 static int
18936 api_one_eid_table_dump (vat_main_t * vam)
18937 {
18938   unformat_input_t *i = vam->input;
18939   vl_api_one_eid_table_dump_t *mp;
18940   vl_api_control_ping_t *mp_ping;
18941   struct in_addr ip4;
18942   struct in6_addr ip6;
18943   u8 mac[6];
18944   u8 eid_type = ~0, eid_set = 0;
18945   u32 prefix_length = ~0, t, vni = 0;
18946   u8 filter = 0;
18947   int ret;
18948   lisp_nsh_api_t nsh;
18949
18950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18951     {
18952       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18953         {
18954           eid_set = 1;
18955           eid_type = 0;
18956           prefix_length = t;
18957         }
18958       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18959         {
18960           eid_set = 1;
18961           eid_type = 1;
18962           prefix_length = t;
18963         }
18964       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18965         {
18966           eid_set = 1;
18967           eid_type = 2;
18968         }
18969       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18970         {
18971           eid_set = 1;
18972           eid_type = 3;
18973         }
18974       else if (unformat (i, "vni %d", &t))
18975         {
18976           vni = t;
18977         }
18978       else if (unformat (i, "local"))
18979         {
18980           filter = 1;
18981         }
18982       else if (unformat (i, "remote"))
18983         {
18984           filter = 2;
18985         }
18986       else
18987         {
18988           errmsg ("parse error '%U'", format_unformat_error, i);
18989           return -99;
18990         }
18991     }
18992
18993   if (!vam->json_output)
18994     {
18995       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18996              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18997     }
18998
18999   M (ONE_EID_TABLE_DUMP, mp);
19000
19001   mp->filter = filter;
19002   if (eid_set)
19003     {
19004       mp->eid_set = 1;
19005       mp->vni = htonl (vni);
19006       mp->eid_type = eid_type;
19007       switch (eid_type)
19008         {
19009         case 0:
19010           mp->prefix_length = prefix_length;
19011           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19012           break;
19013         case 1:
19014           mp->prefix_length = prefix_length;
19015           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19016           break;
19017         case 2:
19018           clib_memcpy (mp->eid, mac, sizeof (mac));
19019           break;
19020         case 3:
19021           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19022           break;
19023         default:
19024           errmsg ("unknown EID type %d!", eid_type);
19025           return -99;
19026         }
19027     }
19028
19029   /* send it... */
19030   S (mp);
19031
19032   /* Use a control ping for synchronization */
19033   MPING (CONTROL_PING, mp_ping);
19034   S (mp_ping);
19035
19036   /* Wait for a reply... */
19037   W (ret);
19038   return ret;
19039 }
19040
19041 #define api_lisp_eid_table_dump api_one_eid_table_dump
19042
19043 static int
19044 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19045 {
19046   unformat_input_t *i = vam->input;
19047   vl_api_gpe_fwd_entries_get_t *mp;
19048   u8 vni_set = 0;
19049   u32 vni = ~0;
19050   int ret;
19051
19052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19053     {
19054       if (unformat (i, "vni %d", &vni))
19055         {
19056           vni_set = 1;
19057         }
19058       else
19059         {
19060           errmsg ("parse error '%U'", format_unformat_error, i);
19061           return -99;
19062         }
19063     }
19064
19065   if (!vni_set)
19066     {
19067       errmsg ("vni not set!");
19068       return -99;
19069     }
19070
19071   if (!vam->json_output)
19072     {
19073       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19074              "leid", "reid");
19075     }
19076
19077   M (GPE_FWD_ENTRIES_GET, mp);
19078   mp->vni = clib_host_to_net_u32 (vni);
19079
19080   /* send it... */
19081   S (mp);
19082
19083   /* Wait for a reply... */
19084   W (ret);
19085   return ret;
19086 }
19087
19088 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19089 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19090 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19091 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19092 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19093 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19094 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19095 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19096
19097 static int
19098 api_one_adjacencies_get (vat_main_t * vam)
19099 {
19100   unformat_input_t *i = vam->input;
19101   vl_api_one_adjacencies_get_t *mp;
19102   u8 vni_set = 0;
19103   u32 vni = ~0;
19104   int ret;
19105
19106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19107     {
19108       if (unformat (i, "vni %d", &vni))
19109         {
19110           vni_set = 1;
19111         }
19112       else
19113         {
19114           errmsg ("parse error '%U'", format_unformat_error, i);
19115           return -99;
19116         }
19117     }
19118
19119   if (!vni_set)
19120     {
19121       errmsg ("vni not set!");
19122       return -99;
19123     }
19124
19125   if (!vam->json_output)
19126     {
19127       print (vam->ofp, "%s %40s", "leid", "reid");
19128     }
19129
19130   M (ONE_ADJACENCIES_GET, mp);
19131   mp->vni = clib_host_to_net_u32 (vni);
19132
19133   /* send it... */
19134   S (mp);
19135
19136   /* Wait for a reply... */
19137   W (ret);
19138   return ret;
19139 }
19140
19141 #define api_lisp_adjacencies_get api_one_adjacencies_get
19142
19143 static int
19144 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19145 {
19146   unformat_input_t *i = vam->input;
19147   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19148   int ret;
19149   u8 ip_family_set = 0, is_ip4 = 1;
19150
19151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19152     {
19153       if (unformat (i, "ip4"))
19154         {
19155           ip_family_set = 1;
19156           is_ip4 = 1;
19157         }
19158       else if (unformat (i, "ip6"))
19159         {
19160           ip_family_set = 1;
19161           is_ip4 = 0;
19162         }
19163       else
19164         {
19165           errmsg ("parse error '%U'", format_unformat_error, i);
19166           return -99;
19167         }
19168     }
19169
19170   if (!ip_family_set)
19171     {
19172       errmsg ("ip family not set!");
19173       return -99;
19174     }
19175
19176   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19177   mp->is_ip4 = is_ip4;
19178
19179   /* send it... */
19180   S (mp);
19181
19182   /* Wait for a reply... */
19183   W (ret);
19184   return ret;
19185 }
19186
19187 static int
19188 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19189 {
19190   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19191   int ret;
19192
19193   if (!vam->json_output)
19194     {
19195       print (vam->ofp, "VNIs");
19196     }
19197
19198   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19199
19200   /* send it... */
19201   S (mp);
19202
19203   /* Wait for a reply... */
19204   W (ret);
19205   return ret;
19206 }
19207
19208 static int
19209 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19210 {
19211   unformat_input_t *i = vam->input;
19212   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19213   int ret = 0;
19214   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19215   struct in_addr ip4;
19216   struct in6_addr ip6;
19217   u32 table_id = 0, nh_sw_if_index = ~0;
19218
19219   clib_memset (&ip4, 0, sizeof (ip4));
19220   clib_memset (&ip6, 0, sizeof (ip6));
19221
19222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19223     {
19224       if (unformat (i, "del"))
19225         is_add = 0;
19226       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19227                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19228         {
19229           ip_set = 1;
19230           is_ip4 = 1;
19231         }
19232       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19233                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19234         {
19235           ip_set = 1;
19236           is_ip4 = 0;
19237         }
19238       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19239         {
19240           ip_set = 1;
19241           is_ip4 = 1;
19242           nh_sw_if_index = ~0;
19243         }
19244       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19245         {
19246           ip_set = 1;
19247           is_ip4 = 0;
19248           nh_sw_if_index = ~0;
19249         }
19250       else if (unformat (i, "table %d", &table_id))
19251         ;
19252       else
19253         {
19254           errmsg ("parse error '%U'", format_unformat_error, i);
19255           return -99;
19256         }
19257     }
19258
19259   if (!ip_set)
19260     {
19261       errmsg ("nh addr not set!");
19262       return -99;
19263     }
19264
19265   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19266   mp->is_add = is_add;
19267   mp->table_id = clib_host_to_net_u32 (table_id);
19268   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19269   mp->is_ip4 = is_ip4;
19270   if (is_ip4)
19271     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19272   else
19273     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19274
19275   /* send it... */
19276   S (mp);
19277
19278   /* Wait for a reply... */
19279   W (ret);
19280   return ret;
19281 }
19282
19283 static int
19284 api_one_map_server_dump (vat_main_t * vam)
19285 {
19286   vl_api_one_map_server_dump_t *mp;
19287   vl_api_control_ping_t *mp_ping;
19288   int ret;
19289
19290   if (!vam->json_output)
19291     {
19292       print (vam->ofp, "%=20s", "Map server");
19293     }
19294
19295   M (ONE_MAP_SERVER_DUMP, mp);
19296   /* send it... */
19297   S (mp);
19298
19299   /* Use a control ping for synchronization */
19300   MPING (CONTROL_PING, mp_ping);
19301   S (mp_ping);
19302
19303   /* Wait for a reply... */
19304   W (ret);
19305   return ret;
19306 }
19307
19308 #define api_lisp_map_server_dump api_one_map_server_dump
19309
19310 static int
19311 api_one_map_resolver_dump (vat_main_t * vam)
19312 {
19313   vl_api_one_map_resolver_dump_t *mp;
19314   vl_api_control_ping_t *mp_ping;
19315   int ret;
19316
19317   if (!vam->json_output)
19318     {
19319       print (vam->ofp, "%=20s", "Map resolver");
19320     }
19321
19322   M (ONE_MAP_RESOLVER_DUMP, mp);
19323   /* send it... */
19324   S (mp);
19325
19326   /* Use a control ping for synchronization */
19327   MPING (CONTROL_PING, mp_ping);
19328   S (mp_ping);
19329
19330   /* Wait for a reply... */
19331   W (ret);
19332   return ret;
19333 }
19334
19335 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19336
19337 static int
19338 api_one_stats_flush (vat_main_t * vam)
19339 {
19340   vl_api_one_stats_flush_t *mp;
19341   int ret = 0;
19342
19343   M (ONE_STATS_FLUSH, mp);
19344   S (mp);
19345   W (ret);
19346   return ret;
19347 }
19348
19349 static int
19350 api_one_stats_dump (vat_main_t * vam)
19351 {
19352   vl_api_one_stats_dump_t *mp;
19353   vl_api_control_ping_t *mp_ping;
19354   int ret;
19355
19356   M (ONE_STATS_DUMP, mp);
19357   /* send it... */
19358   S (mp);
19359
19360   /* Use a control ping for synchronization */
19361   MPING (CONTROL_PING, mp_ping);
19362   S (mp_ping);
19363
19364   /* Wait for a reply... */
19365   W (ret);
19366   return ret;
19367 }
19368
19369 static int
19370 api_show_one_status (vat_main_t * vam)
19371 {
19372   vl_api_show_one_status_t *mp;
19373   int ret;
19374
19375   if (!vam->json_output)
19376     {
19377       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19378     }
19379
19380   M (SHOW_ONE_STATUS, mp);
19381   /* send it... */
19382   S (mp);
19383   /* Wait for a reply... */
19384   W (ret);
19385   return ret;
19386 }
19387
19388 #define api_show_lisp_status api_show_one_status
19389
19390 static int
19391 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19392 {
19393   vl_api_gpe_fwd_entry_path_dump_t *mp;
19394   vl_api_control_ping_t *mp_ping;
19395   unformat_input_t *i = vam->input;
19396   u32 fwd_entry_index = ~0;
19397   int ret;
19398
19399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19400     {
19401       if (unformat (i, "index %d", &fwd_entry_index))
19402         ;
19403       else
19404         break;
19405     }
19406
19407   if (~0 == fwd_entry_index)
19408     {
19409       errmsg ("no index specified!");
19410       return -99;
19411     }
19412
19413   if (!vam->json_output)
19414     {
19415       print (vam->ofp, "first line");
19416     }
19417
19418   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19419
19420   /* send it... */
19421   S (mp);
19422   /* Use a control ping for synchronization */
19423   MPING (CONTROL_PING, mp_ping);
19424   S (mp_ping);
19425
19426   /* Wait for a reply... */
19427   W (ret);
19428   return ret;
19429 }
19430
19431 static int
19432 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19433 {
19434   vl_api_one_get_map_request_itr_rlocs_t *mp;
19435   int ret;
19436
19437   if (!vam->json_output)
19438     {
19439       print (vam->ofp, "%=20s", "itr-rlocs:");
19440     }
19441
19442   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19443   /* send it... */
19444   S (mp);
19445   /* Wait for a reply... */
19446   W (ret);
19447   return ret;
19448 }
19449
19450 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19451
19452 static int
19453 api_af_packet_create (vat_main_t * vam)
19454 {
19455   unformat_input_t *i = vam->input;
19456   vl_api_af_packet_create_t *mp;
19457   u8 *host_if_name = 0;
19458   u8 hw_addr[6];
19459   u8 random_hw_addr = 1;
19460   int ret;
19461
19462   clib_memset (hw_addr, 0, sizeof (hw_addr));
19463
19464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19465     {
19466       if (unformat (i, "name %s", &host_if_name))
19467         vec_add1 (host_if_name, 0);
19468       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19469         random_hw_addr = 0;
19470       else
19471         break;
19472     }
19473
19474   if (!vec_len (host_if_name))
19475     {
19476       errmsg ("host-interface name must be specified");
19477       return -99;
19478     }
19479
19480   if (vec_len (host_if_name) > 64)
19481     {
19482       errmsg ("host-interface name too long");
19483       return -99;
19484     }
19485
19486   M (AF_PACKET_CREATE, mp);
19487
19488   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19489   clib_memcpy (mp->hw_addr, hw_addr, 6);
19490   mp->use_random_hw_addr = random_hw_addr;
19491   vec_free (host_if_name);
19492
19493   S (mp);
19494
19495   /* *INDENT-OFF* */
19496   W2 (ret,
19497       ({
19498         if (ret == 0)
19499           fprintf (vam->ofp ? vam->ofp : stderr,
19500                    " new sw_if_index = %d\n", vam->sw_if_index);
19501       }));
19502   /* *INDENT-ON* */
19503   return ret;
19504 }
19505
19506 static int
19507 api_af_packet_delete (vat_main_t * vam)
19508 {
19509   unformat_input_t *i = vam->input;
19510   vl_api_af_packet_delete_t *mp;
19511   u8 *host_if_name = 0;
19512   int ret;
19513
19514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19515     {
19516       if (unformat (i, "name %s", &host_if_name))
19517         vec_add1 (host_if_name, 0);
19518       else
19519         break;
19520     }
19521
19522   if (!vec_len (host_if_name))
19523     {
19524       errmsg ("host-interface name must be specified");
19525       return -99;
19526     }
19527
19528   if (vec_len (host_if_name) > 64)
19529     {
19530       errmsg ("host-interface name too long");
19531       return -99;
19532     }
19533
19534   M (AF_PACKET_DELETE, mp);
19535
19536   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19537   vec_free (host_if_name);
19538
19539   S (mp);
19540   W (ret);
19541   return ret;
19542 }
19543
19544 static void vl_api_af_packet_details_t_handler
19545   (vl_api_af_packet_details_t * mp)
19546 {
19547   vat_main_t *vam = &vat_main;
19548
19549   print (vam->ofp, "%-16s %d",
19550          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19551 }
19552
19553 static void vl_api_af_packet_details_t_handler_json
19554   (vl_api_af_packet_details_t * mp)
19555 {
19556   vat_main_t *vam = &vat_main;
19557   vat_json_node_t *node = NULL;
19558
19559   if (VAT_JSON_ARRAY != vam->json_tree.type)
19560     {
19561       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19562       vat_json_init_array (&vam->json_tree);
19563     }
19564   node = vat_json_array_add (&vam->json_tree);
19565
19566   vat_json_init_object (node);
19567   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19568   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19569 }
19570
19571 static int
19572 api_af_packet_dump (vat_main_t * vam)
19573 {
19574   vl_api_af_packet_dump_t *mp;
19575   vl_api_control_ping_t *mp_ping;
19576   int ret;
19577
19578   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19579   /* Get list of tap interfaces */
19580   M (AF_PACKET_DUMP, mp);
19581   S (mp);
19582
19583   /* Use a control ping for synchronization */
19584   MPING (CONTROL_PING, mp_ping);
19585   S (mp_ping);
19586
19587   W (ret);
19588   return ret;
19589 }
19590
19591 static int
19592 api_policer_add_del (vat_main_t * vam)
19593 {
19594   unformat_input_t *i = vam->input;
19595   vl_api_policer_add_del_t *mp;
19596   u8 is_add = 1;
19597   u8 *name = 0;
19598   u32 cir = 0;
19599   u32 eir = 0;
19600   u64 cb = 0;
19601   u64 eb = 0;
19602   u8 rate_type = 0;
19603   u8 round_type = 0;
19604   u8 type = 0;
19605   u8 color_aware = 0;
19606   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19607   int ret;
19608
19609   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19610   conform_action.dscp = 0;
19611   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19612   exceed_action.dscp = 0;
19613   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19614   violate_action.dscp = 0;
19615
19616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19617     {
19618       if (unformat (i, "del"))
19619         is_add = 0;
19620       else if (unformat (i, "name %s", &name))
19621         vec_add1 (name, 0);
19622       else if (unformat (i, "cir %u", &cir))
19623         ;
19624       else if (unformat (i, "eir %u", &eir))
19625         ;
19626       else if (unformat (i, "cb %u", &cb))
19627         ;
19628       else if (unformat (i, "eb %u", &eb))
19629         ;
19630       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19631                          &rate_type))
19632         ;
19633       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19634                          &round_type))
19635         ;
19636       else if (unformat (i, "type %U", unformat_policer_type, &type))
19637         ;
19638       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19639                          &conform_action))
19640         ;
19641       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19642                          &exceed_action))
19643         ;
19644       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19645                          &violate_action))
19646         ;
19647       else if (unformat (i, "color-aware"))
19648         color_aware = 1;
19649       else
19650         break;
19651     }
19652
19653   if (!vec_len (name))
19654     {
19655       errmsg ("policer name must be specified");
19656       return -99;
19657     }
19658
19659   if (vec_len (name) > 64)
19660     {
19661       errmsg ("policer name too long");
19662       return -99;
19663     }
19664
19665   M (POLICER_ADD_DEL, mp);
19666
19667   clib_memcpy (mp->name, name, vec_len (name));
19668   vec_free (name);
19669   mp->is_add = is_add;
19670   mp->cir = ntohl (cir);
19671   mp->eir = ntohl (eir);
19672   mp->cb = clib_net_to_host_u64 (cb);
19673   mp->eb = clib_net_to_host_u64 (eb);
19674   mp->rate_type = rate_type;
19675   mp->round_type = round_type;
19676   mp->type = type;
19677   mp->conform_action_type = conform_action.action_type;
19678   mp->conform_dscp = conform_action.dscp;
19679   mp->exceed_action_type = exceed_action.action_type;
19680   mp->exceed_dscp = exceed_action.dscp;
19681   mp->violate_action_type = violate_action.action_type;
19682   mp->violate_dscp = violate_action.dscp;
19683   mp->color_aware = color_aware;
19684
19685   S (mp);
19686   W (ret);
19687   return ret;
19688 }
19689
19690 static int
19691 api_policer_dump (vat_main_t * vam)
19692 {
19693   unformat_input_t *i = vam->input;
19694   vl_api_policer_dump_t *mp;
19695   vl_api_control_ping_t *mp_ping;
19696   u8 *match_name = 0;
19697   u8 match_name_valid = 0;
19698   int ret;
19699
19700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19701     {
19702       if (unformat (i, "name %s", &match_name))
19703         {
19704           vec_add1 (match_name, 0);
19705           match_name_valid = 1;
19706         }
19707       else
19708         break;
19709     }
19710
19711   M (POLICER_DUMP, mp);
19712   mp->match_name_valid = match_name_valid;
19713   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19714   vec_free (match_name);
19715   /* send it... */
19716   S (mp);
19717
19718   /* Use a control ping for synchronization */
19719   MPING (CONTROL_PING, mp_ping);
19720   S (mp_ping);
19721
19722   /* Wait for a reply... */
19723   W (ret);
19724   return ret;
19725 }
19726
19727 static int
19728 api_policer_classify_set_interface (vat_main_t * vam)
19729 {
19730   unformat_input_t *i = vam->input;
19731   vl_api_policer_classify_set_interface_t *mp;
19732   u32 sw_if_index;
19733   int sw_if_index_set;
19734   u32 ip4_table_index = ~0;
19735   u32 ip6_table_index = ~0;
19736   u32 l2_table_index = ~0;
19737   u8 is_add = 1;
19738   int ret;
19739
19740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19741     {
19742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19743         sw_if_index_set = 1;
19744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19745         sw_if_index_set = 1;
19746       else if (unformat (i, "del"))
19747         is_add = 0;
19748       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19749         ;
19750       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19751         ;
19752       else if (unformat (i, "l2-table %d", &l2_table_index))
19753         ;
19754       else
19755         {
19756           clib_warning ("parse error '%U'", format_unformat_error, i);
19757           return -99;
19758         }
19759     }
19760
19761   if (sw_if_index_set == 0)
19762     {
19763       errmsg ("missing interface name or sw_if_index");
19764       return -99;
19765     }
19766
19767   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19768
19769   mp->sw_if_index = ntohl (sw_if_index);
19770   mp->ip4_table_index = ntohl (ip4_table_index);
19771   mp->ip6_table_index = ntohl (ip6_table_index);
19772   mp->l2_table_index = ntohl (l2_table_index);
19773   mp->is_add = is_add;
19774
19775   S (mp);
19776   W (ret);
19777   return ret;
19778 }
19779
19780 static int
19781 api_policer_classify_dump (vat_main_t * vam)
19782 {
19783   unformat_input_t *i = vam->input;
19784   vl_api_policer_classify_dump_t *mp;
19785   vl_api_control_ping_t *mp_ping;
19786   u8 type = POLICER_CLASSIFY_N_TABLES;
19787   int ret;
19788
19789   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19790     ;
19791   else
19792     {
19793       errmsg ("classify table type must be specified");
19794       return -99;
19795     }
19796
19797   if (!vam->json_output)
19798     {
19799       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19800     }
19801
19802   M (POLICER_CLASSIFY_DUMP, mp);
19803   mp->type = type;
19804   /* send it... */
19805   S (mp);
19806
19807   /* Use a control ping for synchronization */
19808   MPING (CONTROL_PING, mp_ping);
19809   S (mp_ping);
19810
19811   /* Wait for a reply... */
19812   W (ret);
19813   return ret;
19814 }
19815
19816 static int
19817 api_netmap_create (vat_main_t * vam)
19818 {
19819   unformat_input_t *i = vam->input;
19820   vl_api_netmap_create_t *mp;
19821   u8 *if_name = 0;
19822   u8 hw_addr[6];
19823   u8 random_hw_addr = 1;
19824   u8 is_pipe = 0;
19825   u8 is_master = 0;
19826   int ret;
19827
19828   clib_memset (hw_addr, 0, sizeof (hw_addr));
19829
19830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19831     {
19832       if (unformat (i, "name %s", &if_name))
19833         vec_add1 (if_name, 0);
19834       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19835         random_hw_addr = 0;
19836       else if (unformat (i, "pipe"))
19837         is_pipe = 1;
19838       else if (unformat (i, "master"))
19839         is_master = 1;
19840       else if (unformat (i, "slave"))
19841         is_master = 0;
19842       else
19843         break;
19844     }
19845
19846   if (!vec_len (if_name))
19847     {
19848       errmsg ("interface name must be specified");
19849       return -99;
19850     }
19851
19852   if (vec_len (if_name) > 64)
19853     {
19854       errmsg ("interface name too long");
19855       return -99;
19856     }
19857
19858   M (NETMAP_CREATE, mp);
19859
19860   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19861   clib_memcpy (mp->hw_addr, hw_addr, 6);
19862   mp->use_random_hw_addr = random_hw_addr;
19863   mp->is_pipe = is_pipe;
19864   mp->is_master = is_master;
19865   vec_free (if_name);
19866
19867   S (mp);
19868   W (ret);
19869   return ret;
19870 }
19871
19872 static int
19873 api_netmap_delete (vat_main_t * vam)
19874 {
19875   unformat_input_t *i = vam->input;
19876   vl_api_netmap_delete_t *mp;
19877   u8 *if_name = 0;
19878   int ret;
19879
19880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19881     {
19882       if (unformat (i, "name %s", &if_name))
19883         vec_add1 (if_name, 0);
19884       else
19885         break;
19886     }
19887
19888   if (!vec_len (if_name))
19889     {
19890       errmsg ("interface name must be specified");
19891       return -99;
19892     }
19893
19894   if (vec_len (if_name) > 64)
19895     {
19896       errmsg ("interface name too long");
19897       return -99;
19898     }
19899
19900   M (NETMAP_DELETE, mp);
19901
19902   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19903   vec_free (if_name);
19904
19905   S (mp);
19906   W (ret);
19907   return ret;
19908 }
19909
19910 static void
19911 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19912 {
19913   if (fp->afi == IP46_TYPE_IP6)
19914     print (vam->ofp,
19915            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19916            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19917            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19918            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19919            format_ip6_address, fp->next_hop);
19920   else if (fp->afi == IP46_TYPE_IP4)
19921     print (vam->ofp,
19922            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19923            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19924            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19925            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19926            format_ip4_address, fp->next_hop);
19927 }
19928
19929 static void
19930 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19931                                  vl_api_fib_path_t * fp)
19932 {
19933   struct in_addr ip4;
19934   struct in6_addr ip6;
19935
19936   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19937   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19938   vat_json_object_add_uint (node, "is_local", fp->is_local);
19939   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19940   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19941   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19942   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19943   if (fp->afi == IP46_TYPE_IP4)
19944     {
19945       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19946       vat_json_object_add_ip4 (node, "next_hop", ip4);
19947     }
19948   else if (fp->afi == IP46_TYPE_IP6)
19949     {
19950       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19951       vat_json_object_add_ip6 (node, "next_hop", ip6);
19952     }
19953 }
19954
19955 static void
19956 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19957 {
19958   vat_main_t *vam = &vat_main;
19959   int count = ntohl (mp->mt_count);
19960   vl_api_fib_path_t *fp;
19961   i32 i;
19962
19963   print (vam->ofp, "[%d]: sw_if_index %d via:",
19964          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19965   fp = mp->mt_paths;
19966   for (i = 0; i < count; i++)
19967     {
19968       vl_api_mpls_fib_path_print (vam, fp);
19969       fp++;
19970     }
19971
19972   print (vam->ofp, "");
19973 }
19974
19975 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19976 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19977
19978 static void
19979 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19980 {
19981   vat_main_t *vam = &vat_main;
19982   vat_json_node_t *node = NULL;
19983   int count = ntohl (mp->mt_count);
19984   vl_api_fib_path_t *fp;
19985   i32 i;
19986
19987   if (VAT_JSON_ARRAY != vam->json_tree.type)
19988     {
19989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19990       vat_json_init_array (&vam->json_tree);
19991     }
19992   node = vat_json_array_add (&vam->json_tree);
19993
19994   vat_json_init_object (node);
19995   vat_json_object_add_uint (node, "tunnel_index",
19996                             ntohl (mp->mt_tunnel_index));
19997   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19998
19999   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20000
20001   fp = mp->mt_paths;
20002   for (i = 0; i < count; i++)
20003     {
20004       vl_api_mpls_fib_path_json_print (node, fp);
20005       fp++;
20006     }
20007 }
20008
20009 static int
20010 api_mpls_tunnel_dump (vat_main_t * vam)
20011 {
20012   vl_api_mpls_tunnel_dump_t *mp;
20013   vl_api_control_ping_t *mp_ping;
20014   u32 sw_if_index = ~0;
20015   int ret;
20016
20017   /* Parse args required to build the message */
20018   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20019     {
20020       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20021         ;
20022     }
20023
20024   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20025
20026   M (MPLS_TUNNEL_DUMP, mp);
20027   mp->sw_if_index = htonl (sw_if_index);
20028   S (mp);
20029
20030   /* Use a control ping for synchronization */
20031   MPING (CONTROL_PING, mp_ping);
20032   S (mp_ping);
20033
20034   W (ret);
20035   return ret;
20036 }
20037
20038 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20039 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20040
20041
20042 static void
20043 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20044 {
20045   vat_main_t *vam = &vat_main;
20046   int count = ntohl (mp->count);
20047   vl_api_fib_path_t *fp;
20048   int i;
20049
20050   print (vam->ofp,
20051          "table-id %d, label %u, ess_bit %u",
20052          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20053   fp = mp->path;
20054   for (i = 0; i < count; i++)
20055     {
20056       vl_api_mpls_fib_path_print (vam, fp);
20057       fp++;
20058     }
20059 }
20060
20061 static void vl_api_mpls_fib_details_t_handler_json
20062   (vl_api_mpls_fib_details_t * mp)
20063 {
20064   vat_main_t *vam = &vat_main;
20065   int count = ntohl (mp->count);
20066   vat_json_node_t *node = NULL;
20067   vl_api_fib_path_t *fp;
20068   int i;
20069
20070   if (VAT_JSON_ARRAY != vam->json_tree.type)
20071     {
20072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20073       vat_json_init_array (&vam->json_tree);
20074     }
20075   node = vat_json_array_add (&vam->json_tree);
20076
20077   vat_json_init_object (node);
20078   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20079   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20080   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20081   vat_json_object_add_uint (node, "path_count", count);
20082   fp = mp->path;
20083   for (i = 0; i < count; i++)
20084     {
20085       vl_api_mpls_fib_path_json_print (node, fp);
20086       fp++;
20087     }
20088 }
20089
20090 static int
20091 api_mpls_fib_dump (vat_main_t * vam)
20092 {
20093   vl_api_mpls_fib_dump_t *mp;
20094   vl_api_control_ping_t *mp_ping;
20095   int ret;
20096
20097   M (MPLS_FIB_DUMP, mp);
20098   S (mp);
20099
20100   /* Use a control ping for synchronization */
20101   MPING (CONTROL_PING, mp_ping);
20102   S (mp_ping);
20103
20104   W (ret);
20105   return ret;
20106 }
20107
20108 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20109 #define vl_api_ip_fib_details_t_print vl_noop_handler
20110
20111 static void
20112 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20113 {
20114   vat_main_t *vam = &vat_main;
20115   int count = ntohl (mp->count);
20116   vl_api_fib_path_t *fp;
20117   int i;
20118
20119   print (vam->ofp,
20120          "table-id %d, prefix %U/%d stats-index %d",
20121          ntohl (mp->table_id), format_ip4_address, mp->address,
20122          mp->address_length, ntohl (mp->stats_index));
20123   fp = mp->path;
20124   for (i = 0; i < count; i++)
20125     {
20126       if (fp->afi == IP46_TYPE_IP6)
20127         print (vam->ofp,
20128                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20129                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20130                "next_hop_table %d",
20131                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20132                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20133                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20134       else if (fp->afi == IP46_TYPE_IP4)
20135         print (vam->ofp,
20136                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20137                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20138                "next_hop_table %d",
20139                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20140                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20141                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20142       fp++;
20143     }
20144 }
20145
20146 static void vl_api_ip_fib_details_t_handler_json
20147   (vl_api_ip_fib_details_t * mp)
20148 {
20149   vat_main_t *vam = &vat_main;
20150   int count = ntohl (mp->count);
20151   vat_json_node_t *node = NULL;
20152   struct in_addr ip4;
20153   struct in6_addr ip6;
20154   vl_api_fib_path_t *fp;
20155   int i;
20156
20157   if (VAT_JSON_ARRAY != vam->json_tree.type)
20158     {
20159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20160       vat_json_init_array (&vam->json_tree);
20161     }
20162   node = vat_json_array_add (&vam->json_tree);
20163
20164   vat_json_init_object (node);
20165   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20166   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20167   vat_json_object_add_ip4 (node, "prefix", ip4);
20168   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20169   vat_json_object_add_uint (node, "path_count", count);
20170   fp = mp->path;
20171   for (i = 0; i < count; i++)
20172     {
20173       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20174       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20175       vat_json_object_add_uint (node, "is_local", fp->is_local);
20176       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20177       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20178       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20179       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20180       if (fp->afi == IP46_TYPE_IP4)
20181         {
20182           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20183           vat_json_object_add_ip4 (node, "next_hop", ip4);
20184         }
20185       else if (fp->afi == IP46_TYPE_IP6)
20186         {
20187           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20188           vat_json_object_add_ip6 (node, "next_hop", ip6);
20189         }
20190     }
20191 }
20192
20193 static int
20194 api_ip_fib_dump (vat_main_t * vam)
20195 {
20196   vl_api_ip_fib_dump_t *mp;
20197   vl_api_control_ping_t *mp_ping;
20198   int ret;
20199
20200   M (IP_FIB_DUMP, mp);
20201   S (mp);
20202
20203   /* Use a control ping for synchronization */
20204   MPING (CONTROL_PING, mp_ping);
20205   S (mp_ping);
20206
20207   W (ret);
20208   return ret;
20209 }
20210
20211 static int
20212 api_ip_mfib_dump (vat_main_t * vam)
20213 {
20214   vl_api_ip_mfib_dump_t *mp;
20215   vl_api_control_ping_t *mp_ping;
20216   int ret;
20217
20218   M (IP_MFIB_DUMP, mp);
20219   S (mp);
20220
20221   /* Use a control ping for synchronization */
20222   MPING (CONTROL_PING, mp_ping);
20223   S (mp_ping);
20224
20225   W (ret);
20226   return ret;
20227 }
20228
20229 static void vl_api_ip_neighbor_details_t_handler
20230   (vl_api_ip_neighbor_details_t * mp)
20231 {
20232   vat_main_t *vam = &vat_main;
20233
20234   print (vam->ofp, "%c %U %U",
20235          (mp->is_static) ? 'S' : 'D',
20236          format_ethernet_address, &mp->mac_address,
20237          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20238          &mp->ip_address);
20239 }
20240
20241 static void vl_api_ip_neighbor_details_t_handler_json
20242   (vl_api_ip_neighbor_details_t * mp)
20243 {
20244
20245   vat_main_t *vam = &vat_main;
20246   vat_json_node_t *node;
20247   struct in_addr ip4;
20248   struct in6_addr ip6;
20249
20250   if (VAT_JSON_ARRAY != vam->json_tree.type)
20251     {
20252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20253       vat_json_init_array (&vam->json_tree);
20254     }
20255   node = vat_json_array_add (&vam->json_tree);
20256
20257   vat_json_init_object (node);
20258   vat_json_object_add_string_copy (node, "flag",
20259                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20260                                    "dynamic");
20261
20262   vat_json_object_add_string_copy (node, "link_layer",
20263                                    format (0, "%U", format_ethernet_address,
20264                                            &mp->mac_address));
20265
20266   if (mp->is_ipv6)
20267     {
20268       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20269       vat_json_object_add_ip6 (node, "ip_address", ip6);
20270     }
20271   else
20272     {
20273       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20274       vat_json_object_add_ip4 (node, "ip_address", ip4);
20275     }
20276 }
20277
20278 static int
20279 api_ip_neighbor_dump (vat_main_t * vam)
20280 {
20281   unformat_input_t *i = vam->input;
20282   vl_api_ip_neighbor_dump_t *mp;
20283   vl_api_control_ping_t *mp_ping;
20284   u8 is_ipv6 = 0;
20285   u32 sw_if_index = ~0;
20286   int ret;
20287
20288   /* Parse args required to build the message */
20289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20290     {
20291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20292         ;
20293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20294         ;
20295       else if (unformat (i, "ip6"))
20296         is_ipv6 = 1;
20297       else
20298         break;
20299     }
20300
20301   if (sw_if_index == ~0)
20302     {
20303       errmsg ("missing interface name or sw_if_index");
20304       return -99;
20305     }
20306
20307   M (IP_NEIGHBOR_DUMP, mp);
20308   mp->is_ipv6 = (u8) is_ipv6;
20309   mp->sw_if_index = ntohl (sw_if_index);
20310   S (mp);
20311
20312   /* Use a control ping for synchronization */
20313   MPING (CONTROL_PING, mp_ping);
20314   S (mp_ping);
20315
20316   W (ret);
20317   return ret;
20318 }
20319
20320 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20321 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20322
20323 static void
20324 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20325 {
20326   vat_main_t *vam = &vat_main;
20327   int count = ntohl (mp->count);
20328   vl_api_fib_path_t *fp;
20329   int i;
20330
20331   print (vam->ofp,
20332          "table-id %d, prefix %U/%d stats-index %d",
20333          ntohl (mp->table_id), format_ip6_address, mp->address,
20334          mp->address_length, ntohl (mp->stats_index));
20335   fp = mp->path;
20336   for (i = 0; i < count; i++)
20337     {
20338       if (fp->afi == IP46_TYPE_IP6)
20339         print (vam->ofp,
20340                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20341                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20342                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20343                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20344                format_ip6_address, fp->next_hop);
20345       else if (fp->afi == IP46_TYPE_IP4)
20346         print (vam->ofp,
20347                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20348                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20349                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20350                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20351                format_ip4_address, fp->next_hop);
20352       fp++;
20353     }
20354 }
20355
20356 static void vl_api_ip6_fib_details_t_handler_json
20357   (vl_api_ip6_fib_details_t * mp)
20358 {
20359   vat_main_t *vam = &vat_main;
20360   int count = ntohl (mp->count);
20361   vat_json_node_t *node = NULL;
20362   struct in_addr ip4;
20363   struct in6_addr ip6;
20364   vl_api_fib_path_t *fp;
20365   int i;
20366
20367   if (VAT_JSON_ARRAY != vam->json_tree.type)
20368     {
20369       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20370       vat_json_init_array (&vam->json_tree);
20371     }
20372   node = vat_json_array_add (&vam->json_tree);
20373
20374   vat_json_init_object (node);
20375   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20376   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20377   vat_json_object_add_ip6 (node, "prefix", ip6);
20378   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20379   vat_json_object_add_uint (node, "path_count", count);
20380   fp = mp->path;
20381   for (i = 0; i < count; i++)
20382     {
20383       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20384       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20385       vat_json_object_add_uint (node, "is_local", fp->is_local);
20386       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20387       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20388       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20389       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20390       if (fp->afi == IP46_TYPE_IP4)
20391         {
20392           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20393           vat_json_object_add_ip4 (node, "next_hop", ip4);
20394         }
20395       else if (fp->afi == IP46_TYPE_IP6)
20396         {
20397           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20398           vat_json_object_add_ip6 (node, "next_hop", ip6);
20399         }
20400     }
20401 }
20402
20403 static int
20404 api_ip6_fib_dump (vat_main_t * vam)
20405 {
20406   vl_api_ip6_fib_dump_t *mp;
20407   vl_api_control_ping_t *mp_ping;
20408   int ret;
20409
20410   M (IP6_FIB_DUMP, mp);
20411   S (mp);
20412
20413   /* Use a control ping for synchronization */
20414   MPING (CONTROL_PING, mp_ping);
20415   S (mp_ping);
20416
20417   W (ret);
20418   return ret;
20419 }
20420
20421 static int
20422 api_ip6_mfib_dump (vat_main_t * vam)
20423 {
20424   vl_api_ip6_mfib_dump_t *mp;
20425   vl_api_control_ping_t *mp_ping;
20426   int ret;
20427
20428   M (IP6_MFIB_DUMP, mp);
20429   S (mp);
20430
20431   /* Use a control ping for synchronization */
20432   MPING (CONTROL_PING, mp_ping);
20433   S (mp_ping);
20434
20435   W (ret);
20436   return ret;
20437 }
20438
20439 int
20440 api_classify_table_ids (vat_main_t * vam)
20441 {
20442   vl_api_classify_table_ids_t *mp;
20443   int ret;
20444
20445   /* Construct the API message */
20446   M (CLASSIFY_TABLE_IDS, mp);
20447   mp->context = 0;
20448
20449   S (mp);
20450   W (ret);
20451   return ret;
20452 }
20453
20454 int
20455 api_classify_table_by_interface (vat_main_t * vam)
20456 {
20457   unformat_input_t *input = vam->input;
20458   vl_api_classify_table_by_interface_t *mp;
20459
20460   u32 sw_if_index = ~0;
20461   int ret;
20462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20463     {
20464       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20465         ;
20466       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20467         ;
20468       else
20469         break;
20470     }
20471   if (sw_if_index == ~0)
20472     {
20473       errmsg ("missing interface name or sw_if_index");
20474       return -99;
20475     }
20476
20477   /* Construct the API message */
20478   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20479   mp->context = 0;
20480   mp->sw_if_index = ntohl (sw_if_index);
20481
20482   S (mp);
20483   W (ret);
20484   return ret;
20485 }
20486
20487 int
20488 api_classify_table_info (vat_main_t * vam)
20489 {
20490   unformat_input_t *input = vam->input;
20491   vl_api_classify_table_info_t *mp;
20492
20493   u32 table_id = ~0;
20494   int ret;
20495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20496     {
20497       if (unformat (input, "table_id %d", &table_id))
20498         ;
20499       else
20500         break;
20501     }
20502   if (table_id == ~0)
20503     {
20504       errmsg ("missing table id");
20505       return -99;
20506     }
20507
20508   /* Construct the API message */
20509   M (CLASSIFY_TABLE_INFO, mp);
20510   mp->context = 0;
20511   mp->table_id = ntohl (table_id);
20512
20513   S (mp);
20514   W (ret);
20515   return ret;
20516 }
20517
20518 int
20519 api_classify_session_dump (vat_main_t * vam)
20520 {
20521   unformat_input_t *input = vam->input;
20522   vl_api_classify_session_dump_t *mp;
20523   vl_api_control_ping_t *mp_ping;
20524
20525   u32 table_id = ~0;
20526   int ret;
20527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20528     {
20529       if (unformat (input, "table_id %d", &table_id))
20530         ;
20531       else
20532         break;
20533     }
20534   if (table_id == ~0)
20535     {
20536       errmsg ("missing table id");
20537       return -99;
20538     }
20539
20540   /* Construct the API message */
20541   M (CLASSIFY_SESSION_DUMP, mp);
20542   mp->context = 0;
20543   mp->table_id = ntohl (table_id);
20544   S (mp);
20545
20546   /* Use a control ping for synchronization */
20547   MPING (CONTROL_PING, mp_ping);
20548   S (mp_ping);
20549
20550   W (ret);
20551   return ret;
20552 }
20553
20554 static void
20555 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20556 {
20557   vat_main_t *vam = &vat_main;
20558
20559   print (vam->ofp, "collector_address %U, collector_port %d, "
20560          "src_address %U, vrf_id %d, path_mtu %u, "
20561          "template_interval %u, udp_checksum %d",
20562          format_ip4_address, mp->collector_address,
20563          ntohs (mp->collector_port),
20564          format_ip4_address, mp->src_address,
20565          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20566          ntohl (mp->template_interval), mp->udp_checksum);
20567
20568   vam->retval = 0;
20569   vam->result_ready = 1;
20570 }
20571
20572 static void
20573   vl_api_ipfix_exporter_details_t_handler_json
20574   (vl_api_ipfix_exporter_details_t * mp)
20575 {
20576   vat_main_t *vam = &vat_main;
20577   vat_json_node_t node;
20578   struct in_addr collector_address;
20579   struct in_addr src_address;
20580
20581   vat_json_init_object (&node);
20582   clib_memcpy (&collector_address, &mp->collector_address,
20583                sizeof (collector_address));
20584   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20585   vat_json_object_add_uint (&node, "collector_port",
20586                             ntohs (mp->collector_port));
20587   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20588   vat_json_object_add_ip4 (&node, "src_address", src_address);
20589   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20590   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20591   vat_json_object_add_uint (&node, "template_interval",
20592                             ntohl (mp->template_interval));
20593   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20594
20595   vat_json_print (vam->ofp, &node);
20596   vat_json_free (&node);
20597   vam->retval = 0;
20598   vam->result_ready = 1;
20599 }
20600
20601 int
20602 api_ipfix_exporter_dump (vat_main_t * vam)
20603 {
20604   vl_api_ipfix_exporter_dump_t *mp;
20605   int ret;
20606
20607   /* Construct the API message */
20608   M (IPFIX_EXPORTER_DUMP, mp);
20609   mp->context = 0;
20610
20611   S (mp);
20612   W (ret);
20613   return ret;
20614 }
20615
20616 static int
20617 api_ipfix_classify_stream_dump (vat_main_t * vam)
20618 {
20619   vl_api_ipfix_classify_stream_dump_t *mp;
20620   int ret;
20621
20622   /* Construct the API message */
20623   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20624   mp->context = 0;
20625
20626   S (mp);
20627   W (ret);
20628   return ret;
20629   /* NOTREACHED */
20630   return 0;
20631 }
20632
20633 static void
20634   vl_api_ipfix_classify_stream_details_t_handler
20635   (vl_api_ipfix_classify_stream_details_t * mp)
20636 {
20637   vat_main_t *vam = &vat_main;
20638   print (vam->ofp, "domain_id %d, src_port %d",
20639          ntohl (mp->domain_id), ntohs (mp->src_port));
20640   vam->retval = 0;
20641   vam->result_ready = 1;
20642 }
20643
20644 static void
20645   vl_api_ipfix_classify_stream_details_t_handler_json
20646   (vl_api_ipfix_classify_stream_details_t * mp)
20647 {
20648   vat_main_t *vam = &vat_main;
20649   vat_json_node_t node;
20650
20651   vat_json_init_object (&node);
20652   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20653   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20654
20655   vat_json_print (vam->ofp, &node);
20656   vat_json_free (&node);
20657   vam->retval = 0;
20658   vam->result_ready = 1;
20659 }
20660
20661 static int
20662 api_ipfix_classify_table_dump (vat_main_t * vam)
20663 {
20664   vl_api_ipfix_classify_table_dump_t *mp;
20665   vl_api_control_ping_t *mp_ping;
20666   int ret;
20667
20668   if (!vam->json_output)
20669     {
20670       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20671              "transport_protocol");
20672     }
20673
20674   /* Construct the API message */
20675   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20676
20677   /* send it... */
20678   S (mp);
20679
20680   /* Use a control ping for synchronization */
20681   MPING (CONTROL_PING, mp_ping);
20682   S (mp_ping);
20683
20684   W (ret);
20685   return ret;
20686 }
20687
20688 static void
20689   vl_api_ipfix_classify_table_details_t_handler
20690   (vl_api_ipfix_classify_table_details_t * mp)
20691 {
20692   vat_main_t *vam = &vat_main;
20693   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20694          mp->transport_protocol);
20695 }
20696
20697 static void
20698   vl_api_ipfix_classify_table_details_t_handler_json
20699   (vl_api_ipfix_classify_table_details_t * mp)
20700 {
20701   vat_json_node_t *node = NULL;
20702   vat_main_t *vam = &vat_main;
20703
20704   if (VAT_JSON_ARRAY != vam->json_tree.type)
20705     {
20706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20707       vat_json_init_array (&vam->json_tree);
20708     }
20709
20710   node = vat_json_array_add (&vam->json_tree);
20711   vat_json_init_object (node);
20712
20713   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20714   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20715   vat_json_object_add_uint (node, "transport_protocol",
20716                             mp->transport_protocol);
20717 }
20718
20719 static int
20720 api_sw_interface_span_enable_disable (vat_main_t * vam)
20721 {
20722   unformat_input_t *i = vam->input;
20723   vl_api_sw_interface_span_enable_disable_t *mp;
20724   u32 src_sw_if_index = ~0;
20725   u32 dst_sw_if_index = ~0;
20726   u8 state = 3;
20727   int ret;
20728   u8 is_l2 = 0;
20729
20730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20731     {
20732       if (unformat
20733           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20734         ;
20735       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20736         ;
20737       else
20738         if (unformat
20739             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20740         ;
20741       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20742         ;
20743       else if (unformat (i, "disable"))
20744         state = 0;
20745       else if (unformat (i, "rx"))
20746         state = 1;
20747       else if (unformat (i, "tx"))
20748         state = 2;
20749       else if (unformat (i, "both"))
20750         state = 3;
20751       else if (unformat (i, "l2"))
20752         is_l2 = 1;
20753       else
20754         break;
20755     }
20756
20757   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20758
20759   mp->sw_if_index_from = htonl (src_sw_if_index);
20760   mp->sw_if_index_to = htonl (dst_sw_if_index);
20761   mp->state = state;
20762   mp->is_l2 = is_l2;
20763
20764   S (mp);
20765   W (ret);
20766   return ret;
20767 }
20768
20769 static void
20770 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20771                                             * mp)
20772 {
20773   vat_main_t *vam = &vat_main;
20774   u8 *sw_if_from_name = 0;
20775   u8 *sw_if_to_name = 0;
20776   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20777   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20778   char *states[] = { "none", "rx", "tx", "both" };
20779   hash_pair_t *p;
20780
20781   /* *INDENT-OFF* */
20782   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20783   ({
20784     if ((u32) p->value[0] == sw_if_index_from)
20785       {
20786         sw_if_from_name = (u8 *)(p->key);
20787         if (sw_if_to_name)
20788           break;
20789       }
20790     if ((u32) p->value[0] == sw_if_index_to)
20791       {
20792         sw_if_to_name = (u8 *)(p->key);
20793         if (sw_if_from_name)
20794           break;
20795       }
20796   }));
20797   /* *INDENT-ON* */
20798   print (vam->ofp, "%20s => %20s (%s) %s",
20799          sw_if_from_name, sw_if_to_name, states[mp->state],
20800          mp->is_l2 ? "l2" : "device");
20801 }
20802
20803 static void
20804   vl_api_sw_interface_span_details_t_handler_json
20805   (vl_api_sw_interface_span_details_t * mp)
20806 {
20807   vat_main_t *vam = &vat_main;
20808   vat_json_node_t *node = NULL;
20809   u8 *sw_if_from_name = 0;
20810   u8 *sw_if_to_name = 0;
20811   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20812   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20813   hash_pair_t *p;
20814
20815   /* *INDENT-OFF* */
20816   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20817   ({
20818     if ((u32) p->value[0] == sw_if_index_from)
20819       {
20820         sw_if_from_name = (u8 *)(p->key);
20821         if (sw_if_to_name)
20822           break;
20823       }
20824     if ((u32) p->value[0] == sw_if_index_to)
20825       {
20826         sw_if_to_name = (u8 *)(p->key);
20827         if (sw_if_from_name)
20828           break;
20829       }
20830   }));
20831   /* *INDENT-ON* */
20832
20833   if (VAT_JSON_ARRAY != vam->json_tree.type)
20834     {
20835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20836       vat_json_init_array (&vam->json_tree);
20837     }
20838   node = vat_json_array_add (&vam->json_tree);
20839
20840   vat_json_init_object (node);
20841   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20842   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20843   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20844   if (0 != sw_if_to_name)
20845     {
20846       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20847     }
20848   vat_json_object_add_uint (node, "state", mp->state);
20849   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20850 }
20851
20852 static int
20853 api_sw_interface_span_dump (vat_main_t * vam)
20854 {
20855   unformat_input_t *input = vam->input;
20856   vl_api_sw_interface_span_dump_t *mp;
20857   vl_api_control_ping_t *mp_ping;
20858   u8 is_l2 = 0;
20859   int ret;
20860
20861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20862     {
20863       if (unformat (input, "l2"))
20864         is_l2 = 1;
20865       else
20866         break;
20867     }
20868
20869   M (SW_INTERFACE_SPAN_DUMP, mp);
20870   mp->is_l2 = is_l2;
20871   S (mp);
20872
20873   /* Use a control ping for synchronization */
20874   MPING (CONTROL_PING, mp_ping);
20875   S (mp_ping);
20876
20877   W (ret);
20878   return ret;
20879 }
20880
20881 int
20882 api_pg_create_interface (vat_main_t * vam)
20883 {
20884   unformat_input_t *input = vam->input;
20885   vl_api_pg_create_interface_t *mp;
20886
20887   u32 if_id = ~0;
20888   int ret;
20889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20890     {
20891       if (unformat (input, "if_id %d", &if_id))
20892         ;
20893       else
20894         break;
20895     }
20896   if (if_id == ~0)
20897     {
20898       errmsg ("missing pg interface index");
20899       return -99;
20900     }
20901
20902   /* Construct the API message */
20903   M (PG_CREATE_INTERFACE, mp);
20904   mp->context = 0;
20905   mp->interface_id = ntohl (if_id);
20906
20907   S (mp);
20908   W (ret);
20909   return ret;
20910 }
20911
20912 int
20913 api_pg_capture (vat_main_t * vam)
20914 {
20915   unformat_input_t *input = vam->input;
20916   vl_api_pg_capture_t *mp;
20917
20918   u32 if_id = ~0;
20919   u8 enable = 1;
20920   u32 count = 1;
20921   u8 pcap_file_set = 0;
20922   u8 *pcap_file = 0;
20923   int ret;
20924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20925     {
20926       if (unformat (input, "if_id %d", &if_id))
20927         ;
20928       else if (unformat (input, "pcap %s", &pcap_file))
20929         pcap_file_set = 1;
20930       else if (unformat (input, "count %d", &count))
20931         ;
20932       else if (unformat (input, "disable"))
20933         enable = 0;
20934       else
20935         break;
20936     }
20937   if (if_id == ~0)
20938     {
20939       errmsg ("missing pg interface index");
20940       return -99;
20941     }
20942   if (pcap_file_set > 0)
20943     {
20944       if (vec_len (pcap_file) > 255)
20945         {
20946           errmsg ("pcap file name is too long");
20947           return -99;
20948         }
20949     }
20950
20951   u32 name_len = vec_len (pcap_file);
20952   /* Construct the API message */
20953   M (PG_CAPTURE, mp);
20954   mp->context = 0;
20955   mp->interface_id = ntohl (if_id);
20956   mp->is_enabled = enable;
20957   mp->count = ntohl (count);
20958   mp->pcap_name_length = ntohl (name_len);
20959   if (pcap_file_set != 0)
20960     {
20961       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20962     }
20963   vec_free (pcap_file);
20964
20965   S (mp);
20966   W (ret);
20967   return ret;
20968 }
20969
20970 int
20971 api_pg_enable_disable (vat_main_t * vam)
20972 {
20973   unformat_input_t *input = vam->input;
20974   vl_api_pg_enable_disable_t *mp;
20975
20976   u8 enable = 1;
20977   u8 stream_name_set = 0;
20978   u8 *stream_name = 0;
20979   int ret;
20980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20981     {
20982       if (unformat (input, "stream %s", &stream_name))
20983         stream_name_set = 1;
20984       else if (unformat (input, "disable"))
20985         enable = 0;
20986       else
20987         break;
20988     }
20989
20990   if (stream_name_set > 0)
20991     {
20992       if (vec_len (stream_name) > 255)
20993         {
20994           errmsg ("stream name too long");
20995           return -99;
20996         }
20997     }
20998
20999   u32 name_len = vec_len (stream_name);
21000   /* Construct the API message */
21001   M (PG_ENABLE_DISABLE, mp);
21002   mp->context = 0;
21003   mp->is_enabled = enable;
21004   if (stream_name_set != 0)
21005     {
21006       mp->stream_name_length = ntohl (name_len);
21007       clib_memcpy (mp->stream_name, stream_name, name_len);
21008     }
21009   vec_free (stream_name);
21010
21011   S (mp);
21012   W (ret);
21013   return ret;
21014 }
21015
21016 int
21017 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21018 {
21019   unformat_input_t *input = vam->input;
21020   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21021
21022   u16 *low_ports = 0;
21023   u16 *high_ports = 0;
21024   u16 this_low;
21025   u16 this_hi;
21026   ip4_address_t ip4_addr;
21027   ip6_address_t ip6_addr;
21028   u32 length;
21029   u32 tmp, tmp2;
21030   u8 prefix_set = 0;
21031   u32 vrf_id = ~0;
21032   u8 is_add = 1;
21033   u8 is_ipv6 = 0;
21034   int ret;
21035
21036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21037     {
21038       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21039         {
21040           prefix_set = 1;
21041         }
21042       else
21043         if (unformat
21044             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21045         {
21046           prefix_set = 1;
21047           is_ipv6 = 1;
21048         }
21049       else if (unformat (input, "vrf %d", &vrf_id))
21050         ;
21051       else if (unformat (input, "del"))
21052         is_add = 0;
21053       else if (unformat (input, "port %d", &tmp))
21054         {
21055           if (tmp == 0 || tmp > 65535)
21056             {
21057               errmsg ("port %d out of range", tmp);
21058               return -99;
21059             }
21060           this_low = tmp;
21061           this_hi = this_low + 1;
21062           vec_add1 (low_ports, this_low);
21063           vec_add1 (high_ports, this_hi);
21064         }
21065       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21066         {
21067           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21068             {
21069               errmsg ("incorrect range parameters");
21070               return -99;
21071             }
21072           this_low = tmp;
21073           /* Note: in debug CLI +1 is added to high before
21074              passing to real fn that does "the work"
21075              (ip_source_and_port_range_check_add_del).
21076              This fn is a wrapper around the binary API fn a
21077              control plane will call, which expects this increment
21078              to have occurred. Hence letting the binary API control
21079              plane fn do the increment for consistency between VAT
21080              and other control planes.
21081            */
21082           this_hi = tmp2;
21083           vec_add1 (low_ports, this_low);
21084           vec_add1 (high_ports, this_hi);
21085         }
21086       else
21087         break;
21088     }
21089
21090   if (prefix_set == 0)
21091     {
21092       errmsg ("<address>/<mask> not specified");
21093       return -99;
21094     }
21095
21096   if (vrf_id == ~0)
21097     {
21098       errmsg ("VRF ID required, not specified");
21099       return -99;
21100     }
21101
21102   if (vrf_id == 0)
21103     {
21104       errmsg
21105         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21106       return -99;
21107     }
21108
21109   if (vec_len (low_ports) == 0)
21110     {
21111       errmsg ("At least one port or port range required");
21112       return -99;
21113     }
21114
21115   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21116
21117   mp->is_add = is_add;
21118
21119   if (is_ipv6)
21120     {
21121       mp->is_ipv6 = 1;
21122       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21123     }
21124   else
21125     {
21126       mp->is_ipv6 = 0;
21127       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21128     }
21129
21130   mp->mask_length = length;
21131   mp->number_of_ranges = vec_len (low_ports);
21132
21133   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21134   vec_free (low_ports);
21135
21136   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21137   vec_free (high_ports);
21138
21139   mp->vrf_id = ntohl (vrf_id);
21140
21141   S (mp);
21142   W (ret);
21143   return ret;
21144 }
21145
21146 int
21147 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21148 {
21149   unformat_input_t *input = vam->input;
21150   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21151   u32 sw_if_index = ~0;
21152   int vrf_set = 0;
21153   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21154   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21155   u8 is_add = 1;
21156   int ret;
21157
21158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21159     {
21160       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21161         ;
21162       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21163         ;
21164       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21165         vrf_set = 1;
21166       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21167         vrf_set = 1;
21168       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21169         vrf_set = 1;
21170       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21171         vrf_set = 1;
21172       else if (unformat (input, "del"))
21173         is_add = 0;
21174       else
21175         break;
21176     }
21177
21178   if (sw_if_index == ~0)
21179     {
21180       errmsg ("Interface required but not specified");
21181       return -99;
21182     }
21183
21184   if (vrf_set == 0)
21185     {
21186       errmsg ("VRF ID required but not specified");
21187       return -99;
21188     }
21189
21190   if (tcp_out_vrf_id == 0
21191       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21192     {
21193       errmsg
21194         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21195       return -99;
21196     }
21197
21198   /* Construct the API message */
21199   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21200
21201   mp->sw_if_index = ntohl (sw_if_index);
21202   mp->is_add = is_add;
21203   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21204   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21205   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21206   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21207
21208   /* send it... */
21209   S (mp);
21210
21211   /* Wait for a reply... */
21212   W (ret);
21213   return ret;
21214 }
21215
21216 static int
21217 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21218 {
21219   unformat_input_t *i = vam->input;
21220   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21221   u32 local_sa_id = 0;
21222   u32 remote_sa_id = 0;
21223   ip4_address_t src_address;
21224   ip4_address_t dst_address;
21225   u8 is_add = 1;
21226   int ret;
21227
21228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21229     {
21230       if (unformat (i, "local_sa %d", &local_sa_id))
21231         ;
21232       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21233         ;
21234       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21235         ;
21236       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21237         ;
21238       else if (unformat (i, "del"))
21239         is_add = 0;
21240       else
21241         {
21242           clib_warning ("parse error '%U'", format_unformat_error, i);
21243           return -99;
21244         }
21245     }
21246
21247   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21248
21249   mp->local_sa_id = ntohl (local_sa_id);
21250   mp->remote_sa_id = ntohl (remote_sa_id);
21251   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21252   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21253   mp->is_add = is_add;
21254
21255   S (mp);
21256   W (ret);
21257   return ret;
21258 }
21259
21260 static int
21261 api_set_punt (vat_main_t * vam)
21262 {
21263   unformat_input_t *i = vam->input;
21264   vl_api_set_punt_t *mp;
21265   u32 ipv = ~0;
21266   u32 protocol = ~0;
21267   u32 port = ~0;
21268   int is_add = 1;
21269   int ret;
21270
21271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21272     {
21273       if (unformat (i, "ip %d", &ipv))
21274         ;
21275       else if (unformat (i, "protocol %d", &protocol))
21276         ;
21277       else if (unformat (i, "port %d", &port))
21278         ;
21279       else if (unformat (i, "del"))
21280         is_add = 0;
21281       else
21282         {
21283           clib_warning ("parse error '%U'", format_unformat_error, i);
21284           return -99;
21285         }
21286     }
21287
21288   M (SET_PUNT, mp);
21289
21290   mp->is_add = (u8) is_add;
21291   mp->punt.ipv = (u8) ipv;
21292   mp->punt.l4_protocol = (u8) protocol;
21293   mp->punt.l4_port = htons ((u16) port);
21294
21295   S (mp);
21296   W (ret);
21297   return ret;
21298 }
21299
21300 static void vl_api_ipsec_gre_tunnel_details_t_handler
21301   (vl_api_ipsec_gre_tunnel_details_t * mp)
21302 {
21303   vat_main_t *vam = &vat_main;
21304
21305   print (vam->ofp, "%11d%15U%15U%14d%14d",
21306          ntohl (mp->sw_if_index),
21307          format_ip4_address, &mp->src_address,
21308          format_ip4_address, &mp->dst_address,
21309          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21310 }
21311
21312 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21313   (vl_api_ipsec_gre_tunnel_details_t * mp)
21314 {
21315   vat_main_t *vam = &vat_main;
21316   vat_json_node_t *node = NULL;
21317   struct in_addr ip4;
21318
21319   if (VAT_JSON_ARRAY != vam->json_tree.type)
21320     {
21321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21322       vat_json_init_array (&vam->json_tree);
21323     }
21324   node = vat_json_array_add (&vam->json_tree);
21325
21326   vat_json_init_object (node);
21327   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21328   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21329   vat_json_object_add_ip4 (node, "src_address", ip4);
21330   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21331   vat_json_object_add_ip4 (node, "dst_address", ip4);
21332   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21333   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21334 }
21335
21336 static int
21337 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21338 {
21339   unformat_input_t *i = vam->input;
21340   vl_api_ipsec_gre_tunnel_dump_t *mp;
21341   vl_api_control_ping_t *mp_ping;
21342   u32 sw_if_index;
21343   u8 sw_if_index_set = 0;
21344   int ret;
21345
21346   /* Parse args required to build the message */
21347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21348     {
21349       if (unformat (i, "sw_if_index %d", &sw_if_index))
21350         sw_if_index_set = 1;
21351       else
21352         break;
21353     }
21354
21355   if (sw_if_index_set == 0)
21356     {
21357       sw_if_index = ~0;
21358     }
21359
21360   if (!vam->json_output)
21361     {
21362       print (vam->ofp, "%11s%15s%15s%14s%14s",
21363              "sw_if_index", "src_address", "dst_address",
21364              "local_sa_id", "remote_sa_id");
21365     }
21366
21367   /* Get list of gre-tunnel interfaces */
21368   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21369
21370   mp->sw_if_index = htonl (sw_if_index);
21371
21372   S (mp);
21373
21374   /* Use a control ping for synchronization */
21375   MPING (CONTROL_PING, mp_ping);
21376   S (mp_ping);
21377
21378   W (ret);
21379   return ret;
21380 }
21381
21382 static int
21383 api_delete_subif (vat_main_t * vam)
21384 {
21385   unformat_input_t *i = vam->input;
21386   vl_api_delete_subif_t *mp;
21387   u32 sw_if_index = ~0;
21388   int ret;
21389
21390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21391     {
21392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21393         ;
21394       if (unformat (i, "sw_if_index %d", &sw_if_index))
21395         ;
21396       else
21397         break;
21398     }
21399
21400   if (sw_if_index == ~0)
21401     {
21402       errmsg ("missing sw_if_index");
21403       return -99;
21404     }
21405
21406   /* Construct the API message */
21407   M (DELETE_SUBIF, mp);
21408   mp->sw_if_index = ntohl (sw_if_index);
21409
21410   S (mp);
21411   W (ret);
21412   return ret;
21413 }
21414
21415 #define foreach_pbb_vtr_op      \
21416 _("disable",  L2_VTR_DISABLED)  \
21417 _("pop",  L2_VTR_POP_2)         \
21418 _("push",  L2_VTR_PUSH_2)
21419
21420 static int
21421 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21422 {
21423   unformat_input_t *i = vam->input;
21424   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21425   u32 sw_if_index = ~0, vtr_op = ~0;
21426   u16 outer_tag = ~0;
21427   u8 dmac[6], smac[6];
21428   u8 dmac_set = 0, smac_set = 0;
21429   u16 vlanid = 0;
21430   u32 sid = ~0;
21431   u32 tmp;
21432   int ret;
21433
21434   /* Shut up coverity */
21435   clib_memset (dmac, 0, sizeof (dmac));
21436   clib_memset (smac, 0, sizeof (smac));
21437
21438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21439     {
21440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21441         ;
21442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21443         ;
21444       else if (unformat (i, "vtr_op %d", &vtr_op))
21445         ;
21446 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21447       foreach_pbb_vtr_op
21448 #undef _
21449         else if (unformat (i, "translate_pbb_stag"))
21450         {
21451           if (unformat (i, "%d", &tmp))
21452             {
21453               vtr_op = L2_VTR_TRANSLATE_2_1;
21454               outer_tag = tmp;
21455             }
21456           else
21457             {
21458               errmsg
21459                 ("translate_pbb_stag operation requires outer tag definition");
21460               return -99;
21461             }
21462         }
21463       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21464         dmac_set++;
21465       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21466         smac_set++;
21467       else if (unformat (i, "sid %d", &sid))
21468         ;
21469       else if (unformat (i, "vlanid %d", &tmp))
21470         vlanid = tmp;
21471       else
21472         {
21473           clib_warning ("parse error '%U'", format_unformat_error, i);
21474           return -99;
21475         }
21476     }
21477
21478   if ((sw_if_index == ~0) || (vtr_op == ~0))
21479     {
21480       errmsg ("missing sw_if_index or vtr operation");
21481       return -99;
21482     }
21483   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21484       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21485     {
21486       errmsg
21487         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21488       return -99;
21489     }
21490
21491   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21492   mp->sw_if_index = ntohl (sw_if_index);
21493   mp->vtr_op = ntohl (vtr_op);
21494   mp->outer_tag = ntohs (outer_tag);
21495   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21496   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21497   mp->b_vlanid = ntohs (vlanid);
21498   mp->i_sid = ntohl (sid);
21499
21500   S (mp);
21501   W (ret);
21502   return ret;
21503 }
21504
21505 static int
21506 api_flow_classify_set_interface (vat_main_t * vam)
21507 {
21508   unformat_input_t *i = vam->input;
21509   vl_api_flow_classify_set_interface_t *mp;
21510   u32 sw_if_index;
21511   int sw_if_index_set;
21512   u32 ip4_table_index = ~0;
21513   u32 ip6_table_index = ~0;
21514   u8 is_add = 1;
21515   int ret;
21516
21517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21518     {
21519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21520         sw_if_index_set = 1;
21521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21522         sw_if_index_set = 1;
21523       else if (unformat (i, "del"))
21524         is_add = 0;
21525       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21526         ;
21527       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21528         ;
21529       else
21530         {
21531           clib_warning ("parse error '%U'", format_unformat_error, i);
21532           return -99;
21533         }
21534     }
21535
21536   if (sw_if_index_set == 0)
21537     {
21538       errmsg ("missing interface name or sw_if_index");
21539       return -99;
21540     }
21541
21542   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21543
21544   mp->sw_if_index = ntohl (sw_if_index);
21545   mp->ip4_table_index = ntohl (ip4_table_index);
21546   mp->ip6_table_index = ntohl (ip6_table_index);
21547   mp->is_add = is_add;
21548
21549   S (mp);
21550   W (ret);
21551   return ret;
21552 }
21553
21554 static int
21555 api_flow_classify_dump (vat_main_t * vam)
21556 {
21557   unformat_input_t *i = vam->input;
21558   vl_api_flow_classify_dump_t *mp;
21559   vl_api_control_ping_t *mp_ping;
21560   u8 type = FLOW_CLASSIFY_N_TABLES;
21561   int ret;
21562
21563   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21564     ;
21565   else
21566     {
21567       errmsg ("classify table type must be specified");
21568       return -99;
21569     }
21570
21571   if (!vam->json_output)
21572     {
21573       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21574     }
21575
21576   M (FLOW_CLASSIFY_DUMP, mp);
21577   mp->type = type;
21578   /* send it... */
21579   S (mp);
21580
21581   /* Use a control ping for synchronization */
21582   MPING (CONTROL_PING, mp_ping);
21583   S (mp_ping);
21584
21585   /* Wait for a reply... */
21586   W (ret);
21587   return ret;
21588 }
21589
21590 static int
21591 api_feature_enable_disable (vat_main_t * vam)
21592 {
21593   unformat_input_t *i = vam->input;
21594   vl_api_feature_enable_disable_t *mp;
21595   u8 *arc_name = 0;
21596   u8 *feature_name = 0;
21597   u32 sw_if_index = ~0;
21598   u8 enable = 1;
21599   int ret;
21600
21601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21602     {
21603       if (unformat (i, "arc_name %s", &arc_name))
21604         ;
21605       else if (unformat (i, "feature_name %s", &feature_name))
21606         ;
21607       else
21608         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21609         ;
21610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21611         ;
21612       else if (unformat (i, "disable"))
21613         enable = 0;
21614       else
21615         break;
21616     }
21617
21618   if (arc_name == 0)
21619     {
21620       errmsg ("missing arc name");
21621       return -99;
21622     }
21623   if (vec_len (arc_name) > 63)
21624     {
21625       errmsg ("arc name too long");
21626     }
21627
21628   if (feature_name == 0)
21629     {
21630       errmsg ("missing feature name");
21631       return -99;
21632     }
21633   if (vec_len (feature_name) > 63)
21634     {
21635       errmsg ("feature name too long");
21636     }
21637
21638   if (sw_if_index == ~0)
21639     {
21640       errmsg ("missing interface name or sw_if_index");
21641       return -99;
21642     }
21643
21644   /* Construct the API message */
21645   M (FEATURE_ENABLE_DISABLE, mp);
21646   mp->sw_if_index = ntohl (sw_if_index);
21647   mp->enable = enable;
21648   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21649   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21650   vec_free (arc_name);
21651   vec_free (feature_name);
21652
21653   S (mp);
21654   W (ret);
21655   return ret;
21656 }
21657
21658 static int
21659 api_sw_interface_tag_add_del (vat_main_t * vam)
21660 {
21661   unformat_input_t *i = vam->input;
21662   vl_api_sw_interface_tag_add_del_t *mp;
21663   u32 sw_if_index = ~0;
21664   u8 *tag = 0;
21665   u8 enable = 1;
21666   int ret;
21667
21668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21669     {
21670       if (unformat (i, "tag %s", &tag))
21671         ;
21672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21673         ;
21674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21675         ;
21676       else if (unformat (i, "del"))
21677         enable = 0;
21678       else
21679         break;
21680     }
21681
21682   if (sw_if_index == ~0)
21683     {
21684       errmsg ("missing interface name or sw_if_index");
21685       return -99;
21686     }
21687
21688   if (enable && (tag == 0))
21689     {
21690       errmsg ("no tag specified");
21691       return -99;
21692     }
21693
21694   /* Construct the API message */
21695   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21696   mp->sw_if_index = ntohl (sw_if_index);
21697   mp->is_add = enable;
21698   if (enable)
21699     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21700   vec_free (tag);
21701
21702   S (mp);
21703   W (ret);
21704   return ret;
21705 }
21706
21707 static void vl_api_l2_xconnect_details_t_handler
21708   (vl_api_l2_xconnect_details_t * mp)
21709 {
21710   vat_main_t *vam = &vat_main;
21711
21712   print (vam->ofp, "%15d%15d",
21713          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21714 }
21715
21716 static void vl_api_l2_xconnect_details_t_handler_json
21717   (vl_api_l2_xconnect_details_t * mp)
21718 {
21719   vat_main_t *vam = &vat_main;
21720   vat_json_node_t *node = NULL;
21721
21722   if (VAT_JSON_ARRAY != vam->json_tree.type)
21723     {
21724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21725       vat_json_init_array (&vam->json_tree);
21726     }
21727   node = vat_json_array_add (&vam->json_tree);
21728
21729   vat_json_init_object (node);
21730   vat_json_object_add_uint (node, "rx_sw_if_index",
21731                             ntohl (mp->rx_sw_if_index));
21732   vat_json_object_add_uint (node, "tx_sw_if_index",
21733                             ntohl (mp->tx_sw_if_index));
21734 }
21735
21736 static int
21737 api_l2_xconnect_dump (vat_main_t * vam)
21738 {
21739   vl_api_l2_xconnect_dump_t *mp;
21740   vl_api_control_ping_t *mp_ping;
21741   int ret;
21742
21743   if (!vam->json_output)
21744     {
21745       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21746     }
21747
21748   M (L2_XCONNECT_DUMP, mp);
21749
21750   S (mp);
21751
21752   /* Use a control ping for synchronization */
21753   MPING (CONTROL_PING, mp_ping);
21754   S (mp_ping);
21755
21756   W (ret);
21757   return ret;
21758 }
21759
21760 static int
21761 api_hw_interface_set_mtu (vat_main_t * vam)
21762 {
21763   unformat_input_t *i = vam->input;
21764   vl_api_hw_interface_set_mtu_t *mp;
21765   u32 sw_if_index = ~0;
21766   u32 mtu = 0;
21767   int ret;
21768
21769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21770     {
21771       if (unformat (i, "mtu %d", &mtu))
21772         ;
21773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21774         ;
21775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21776         ;
21777       else
21778         break;
21779     }
21780
21781   if (sw_if_index == ~0)
21782     {
21783       errmsg ("missing interface name or sw_if_index");
21784       return -99;
21785     }
21786
21787   if (mtu == 0)
21788     {
21789       errmsg ("no mtu specified");
21790       return -99;
21791     }
21792
21793   /* Construct the API message */
21794   M (HW_INTERFACE_SET_MTU, mp);
21795   mp->sw_if_index = ntohl (sw_if_index);
21796   mp->mtu = ntohs ((u16) mtu);
21797
21798   S (mp);
21799   W (ret);
21800   return ret;
21801 }
21802
21803 static int
21804 api_p2p_ethernet_add (vat_main_t * vam)
21805 {
21806   unformat_input_t *i = vam->input;
21807   vl_api_p2p_ethernet_add_t *mp;
21808   u32 parent_if_index = ~0;
21809   u32 sub_id = ~0;
21810   u8 remote_mac[6];
21811   u8 mac_set = 0;
21812   int ret;
21813
21814   clib_memset (remote_mac, 0, sizeof (remote_mac));
21815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21816     {
21817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21818         ;
21819       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21820         ;
21821       else
21822         if (unformat
21823             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21824         mac_set++;
21825       else if (unformat (i, "sub_id %d", &sub_id))
21826         ;
21827       else
21828         {
21829           clib_warning ("parse error '%U'", format_unformat_error, i);
21830           return -99;
21831         }
21832     }
21833
21834   if (parent_if_index == ~0)
21835     {
21836       errmsg ("missing interface name or sw_if_index");
21837       return -99;
21838     }
21839   if (mac_set == 0)
21840     {
21841       errmsg ("missing remote mac address");
21842       return -99;
21843     }
21844   if (sub_id == ~0)
21845     {
21846       errmsg ("missing sub-interface id");
21847       return -99;
21848     }
21849
21850   M (P2P_ETHERNET_ADD, mp);
21851   mp->parent_if_index = ntohl (parent_if_index);
21852   mp->subif_id = ntohl (sub_id);
21853   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21854
21855   S (mp);
21856   W (ret);
21857   return ret;
21858 }
21859
21860 static int
21861 api_p2p_ethernet_del (vat_main_t * vam)
21862 {
21863   unformat_input_t *i = vam->input;
21864   vl_api_p2p_ethernet_del_t *mp;
21865   u32 parent_if_index = ~0;
21866   u8 remote_mac[6];
21867   u8 mac_set = 0;
21868   int ret;
21869
21870   clib_memset (remote_mac, 0, sizeof (remote_mac));
21871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21872     {
21873       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21874         ;
21875       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21876         ;
21877       else
21878         if (unformat
21879             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21880         mac_set++;
21881       else
21882         {
21883           clib_warning ("parse error '%U'", format_unformat_error, i);
21884           return -99;
21885         }
21886     }
21887
21888   if (parent_if_index == ~0)
21889     {
21890       errmsg ("missing interface name or sw_if_index");
21891       return -99;
21892     }
21893   if (mac_set == 0)
21894     {
21895       errmsg ("missing remote mac address");
21896       return -99;
21897     }
21898
21899   M (P2P_ETHERNET_DEL, mp);
21900   mp->parent_if_index = ntohl (parent_if_index);
21901   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21902
21903   S (mp);
21904   W (ret);
21905   return ret;
21906 }
21907
21908 static int
21909 api_lldp_config (vat_main_t * vam)
21910 {
21911   unformat_input_t *i = vam->input;
21912   vl_api_lldp_config_t *mp;
21913   int tx_hold = 0;
21914   int tx_interval = 0;
21915   u8 *sys_name = NULL;
21916   int ret;
21917
21918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21919     {
21920       if (unformat (i, "system-name %s", &sys_name))
21921         ;
21922       else if (unformat (i, "tx-hold %d", &tx_hold))
21923         ;
21924       else if (unformat (i, "tx-interval %d", &tx_interval))
21925         ;
21926       else
21927         {
21928           clib_warning ("parse error '%U'", format_unformat_error, i);
21929           return -99;
21930         }
21931     }
21932
21933   vec_add1 (sys_name, 0);
21934
21935   M (LLDP_CONFIG, mp);
21936   mp->tx_hold = htonl (tx_hold);
21937   mp->tx_interval = htonl (tx_interval);
21938   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21939   vec_free (sys_name);
21940
21941   S (mp);
21942   W (ret);
21943   return ret;
21944 }
21945
21946 static int
21947 api_sw_interface_set_lldp (vat_main_t * vam)
21948 {
21949   unformat_input_t *i = vam->input;
21950   vl_api_sw_interface_set_lldp_t *mp;
21951   u32 sw_if_index = ~0;
21952   u32 enable = 1;
21953   u8 *port_desc = NULL, *mgmt_oid = NULL;
21954   ip4_address_t ip4_addr;
21955   ip6_address_t ip6_addr;
21956   int ret;
21957
21958   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21959   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21960
21961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21962     {
21963       if (unformat (i, "disable"))
21964         enable = 0;
21965       else
21966         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21967         ;
21968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21969         ;
21970       else if (unformat (i, "port-desc %s", &port_desc))
21971         ;
21972       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21973         ;
21974       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21975         ;
21976       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21977         ;
21978       else
21979         break;
21980     }
21981
21982   if (sw_if_index == ~0)
21983     {
21984       errmsg ("missing interface name or sw_if_index");
21985       return -99;
21986     }
21987
21988   /* Construct the API message */
21989   vec_add1 (port_desc, 0);
21990   vec_add1 (mgmt_oid, 0);
21991   M (SW_INTERFACE_SET_LLDP, mp);
21992   mp->sw_if_index = ntohl (sw_if_index);
21993   mp->enable = enable;
21994   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21995   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21996   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21997   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21998   vec_free (port_desc);
21999   vec_free (mgmt_oid);
22000
22001   S (mp);
22002   W (ret);
22003   return ret;
22004 }
22005
22006 static int
22007 api_tcp_configure_src_addresses (vat_main_t * vam)
22008 {
22009   vl_api_tcp_configure_src_addresses_t *mp;
22010   unformat_input_t *i = vam->input;
22011   ip4_address_t v4first, v4last;
22012   ip6_address_t v6first, v6last;
22013   u8 range_set = 0;
22014   u32 vrf_id = 0;
22015   int ret;
22016
22017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22018     {
22019       if (unformat (i, "%U - %U",
22020                     unformat_ip4_address, &v4first,
22021                     unformat_ip4_address, &v4last))
22022         {
22023           if (range_set)
22024             {
22025               errmsg ("one range per message (range already set)");
22026               return -99;
22027             }
22028           range_set = 1;
22029         }
22030       else if (unformat (i, "%U - %U",
22031                          unformat_ip6_address, &v6first,
22032                          unformat_ip6_address, &v6last))
22033         {
22034           if (range_set)
22035             {
22036               errmsg ("one range per message (range already set)");
22037               return -99;
22038             }
22039           range_set = 2;
22040         }
22041       else if (unformat (i, "vrf %d", &vrf_id))
22042         ;
22043       else
22044         break;
22045     }
22046
22047   if (range_set == 0)
22048     {
22049       errmsg ("address range not set");
22050       return -99;
22051     }
22052
22053   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22054   mp->vrf_id = ntohl (vrf_id);
22055   /* ipv6? */
22056   if (range_set == 2)
22057     {
22058       mp->is_ipv6 = 1;
22059       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22060       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22061     }
22062   else
22063     {
22064       mp->is_ipv6 = 0;
22065       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22066       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22067     }
22068   S (mp);
22069   W (ret);
22070   return ret;
22071 }
22072
22073 static void vl_api_app_namespace_add_del_reply_t_handler
22074   (vl_api_app_namespace_add_del_reply_t * mp)
22075 {
22076   vat_main_t *vam = &vat_main;
22077   i32 retval = ntohl (mp->retval);
22078   if (vam->async_mode)
22079     {
22080       vam->async_errors += (retval < 0);
22081     }
22082   else
22083     {
22084       vam->retval = retval;
22085       if (retval == 0)
22086         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22087       vam->result_ready = 1;
22088     }
22089 }
22090
22091 static void vl_api_app_namespace_add_del_reply_t_handler_json
22092   (vl_api_app_namespace_add_del_reply_t * mp)
22093 {
22094   vat_main_t *vam = &vat_main;
22095   vat_json_node_t node;
22096
22097   vat_json_init_object (&node);
22098   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22099   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22100
22101   vat_json_print (vam->ofp, &node);
22102   vat_json_free (&node);
22103
22104   vam->retval = ntohl (mp->retval);
22105   vam->result_ready = 1;
22106 }
22107
22108 static int
22109 api_app_namespace_add_del (vat_main_t * vam)
22110 {
22111   vl_api_app_namespace_add_del_t *mp;
22112   unformat_input_t *i = vam->input;
22113   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22114   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22115   u64 secret;
22116   int ret;
22117
22118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22119     {
22120       if (unformat (i, "id %_%v%_", &ns_id))
22121         ;
22122       else if (unformat (i, "secret %lu", &secret))
22123         secret_set = 1;
22124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22125         sw_if_index_set = 1;
22126       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22127         ;
22128       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22129         ;
22130       else
22131         break;
22132     }
22133   if (!ns_id || !secret_set || !sw_if_index_set)
22134     {
22135       errmsg ("namespace id, secret and sw_if_index must be set");
22136       return -99;
22137     }
22138   if (vec_len (ns_id) > 64)
22139     {
22140       errmsg ("namespace id too long");
22141       return -99;
22142     }
22143   M (APP_NAMESPACE_ADD_DEL, mp);
22144
22145   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22146   mp->namespace_id_len = vec_len (ns_id);
22147   mp->secret = clib_host_to_net_u64 (secret);
22148   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22149   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22150   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22151   vec_free (ns_id);
22152   S (mp);
22153   W (ret);
22154   return ret;
22155 }
22156
22157 static int
22158 api_sock_init_shm (vat_main_t * vam)
22159 {
22160 #if VPP_API_TEST_BUILTIN == 0
22161   unformat_input_t *i = vam->input;
22162   vl_api_shm_elem_config_t *config = 0;
22163   u64 size = 64 << 20;
22164   int rv;
22165
22166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22167     {
22168       if (unformat (i, "size %U", unformat_memory_size, &size))
22169         ;
22170       else
22171         break;
22172     }
22173
22174   /*
22175    * Canned custom ring allocator config.
22176    * Should probably parse all of this
22177    */
22178   vec_validate (config, 6);
22179   config[0].type = VL_API_VLIB_RING;
22180   config[0].size = 256;
22181   config[0].count = 32;
22182
22183   config[1].type = VL_API_VLIB_RING;
22184   config[1].size = 1024;
22185   config[1].count = 16;
22186
22187   config[2].type = VL_API_VLIB_RING;
22188   config[2].size = 4096;
22189   config[2].count = 2;
22190
22191   config[3].type = VL_API_CLIENT_RING;
22192   config[3].size = 256;
22193   config[3].count = 32;
22194
22195   config[4].type = VL_API_CLIENT_RING;
22196   config[4].size = 1024;
22197   config[4].count = 16;
22198
22199   config[5].type = VL_API_CLIENT_RING;
22200   config[5].size = 4096;
22201   config[5].count = 2;
22202
22203   config[6].type = VL_API_QUEUE;
22204   config[6].count = 128;
22205   config[6].size = sizeof (uword);
22206
22207   rv = vl_socket_client_init_shm (config);
22208   if (!rv)
22209     vam->client_index_invalid = 1;
22210   return rv;
22211 #else
22212   return -99;
22213 #endif
22214 }
22215
22216 static int
22217 api_dns_enable_disable (vat_main_t * vam)
22218 {
22219   unformat_input_t *line_input = vam->input;
22220   vl_api_dns_enable_disable_t *mp;
22221   u8 enable_disable = 1;
22222   int ret;
22223
22224   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22225     {
22226       if (unformat (line_input, "disable"))
22227         enable_disable = 0;
22228       if (unformat (line_input, "enable"))
22229         enable_disable = 1;
22230       else
22231         break;
22232     }
22233
22234   /* Construct the API message */
22235   M (DNS_ENABLE_DISABLE, mp);
22236   mp->enable = enable_disable;
22237
22238   /* send it... */
22239   S (mp);
22240   /* Wait for the reply */
22241   W (ret);
22242   return ret;
22243 }
22244
22245 static int
22246 api_dns_resolve_name (vat_main_t * vam)
22247 {
22248   unformat_input_t *line_input = vam->input;
22249   vl_api_dns_resolve_name_t *mp;
22250   u8 *name = 0;
22251   int ret;
22252
22253   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22254     {
22255       if (unformat (line_input, "%s", &name))
22256         ;
22257       else
22258         break;
22259     }
22260
22261   if (vec_len (name) > 127)
22262     {
22263       errmsg ("name too long");
22264       return -99;
22265     }
22266
22267   /* Construct the API message */
22268   M (DNS_RESOLVE_NAME, mp);
22269   memcpy (mp->name, name, vec_len (name));
22270   vec_free (name);
22271
22272   /* send it... */
22273   S (mp);
22274   /* Wait for the reply */
22275   W (ret);
22276   return ret;
22277 }
22278
22279 static int
22280 api_dns_resolve_ip (vat_main_t * vam)
22281 {
22282   unformat_input_t *line_input = vam->input;
22283   vl_api_dns_resolve_ip_t *mp;
22284   int is_ip6 = -1;
22285   ip4_address_t addr4;
22286   ip6_address_t addr6;
22287   int ret;
22288
22289   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22290     {
22291       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22292         is_ip6 = 1;
22293       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22294         is_ip6 = 0;
22295       else
22296         break;
22297     }
22298
22299   if (is_ip6 == -1)
22300     {
22301       errmsg ("missing address");
22302       return -99;
22303     }
22304
22305   /* Construct the API message */
22306   M (DNS_RESOLVE_IP, mp);
22307   mp->is_ip6 = is_ip6;
22308   if (is_ip6)
22309     memcpy (mp->address, &addr6, sizeof (addr6));
22310   else
22311     memcpy (mp->address, &addr4, sizeof (addr4));
22312
22313   /* send it... */
22314   S (mp);
22315   /* Wait for the reply */
22316   W (ret);
22317   return ret;
22318 }
22319
22320 static int
22321 api_dns_name_server_add_del (vat_main_t * vam)
22322 {
22323   unformat_input_t *i = vam->input;
22324   vl_api_dns_name_server_add_del_t *mp;
22325   u8 is_add = 1;
22326   ip6_address_t ip6_server;
22327   ip4_address_t ip4_server;
22328   int ip6_set = 0;
22329   int ip4_set = 0;
22330   int ret = 0;
22331
22332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22333     {
22334       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22335         ip6_set = 1;
22336       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22337         ip4_set = 1;
22338       else if (unformat (i, "del"))
22339         is_add = 0;
22340       else
22341         {
22342           clib_warning ("parse error '%U'", format_unformat_error, i);
22343           return -99;
22344         }
22345     }
22346
22347   if (ip4_set && ip6_set)
22348     {
22349       errmsg ("Only one server address allowed per message");
22350       return -99;
22351     }
22352   if ((ip4_set + ip6_set) == 0)
22353     {
22354       errmsg ("Server address required");
22355       return -99;
22356     }
22357
22358   /* Construct the API message */
22359   M (DNS_NAME_SERVER_ADD_DEL, mp);
22360
22361   if (ip6_set)
22362     {
22363       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22364       mp->is_ip6 = 1;
22365     }
22366   else
22367     {
22368       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22369       mp->is_ip6 = 0;
22370     }
22371
22372   mp->is_add = is_add;
22373
22374   /* send it... */
22375   S (mp);
22376
22377   /* Wait for a reply, return good/bad news  */
22378   W (ret);
22379   return ret;
22380 }
22381
22382 static void
22383 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22384 {
22385   vat_main_t *vam = &vat_main;
22386
22387   if (mp->is_ip4)
22388     {
22389       print (vam->ofp,
22390              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22391              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22392              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22393              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22394              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22395              clib_net_to_host_u32 (mp->action_index), mp->tag);
22396     }
22397   else
22398     {
22399       print (vam->ofp,
22400              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22401              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22402              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22403              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22404              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22405              clib_net_to_host_u32 (mp->action_index), mp->tag);
22406     }
22407 }
22408
22409 static void
22410 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22411                                              mp)
22412 {
22413   vat_main_t *vam = &vat_main;
22414   vat_json_node_t *node = NULL;
22415   struct in6_addr ip6;
22416   struct in_addr ip4;
22417
22418   if (VAT_JSON_ARRAY != vam->json_tree.type)
22419     {
22420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22421       vat_json_init_array (&vam->json_tree);
22422     }
22423   node = vat_json_array_add (&vam->json_tree);
22424   vat_json_init_object (node);
22425
22426   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22427   vat_json_object_add_uint (node, "appns_index",
22428                             clib_net_to_host_u32 (mp->appns_index));
22429   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22430   vat_json_object_add_uint (node, "scope", mp->scope);
22431   vat_json_object_add_uint (node, "action_index",
22432                             clib_net_to_host_u32 (mp->action_index));
22433   vat_json_object_add_uint (node, "lcl_port",
22434                             clib_net_to_host_u16 (mp->lcl_port));
22435   vat_json_object_add_uint (node, "rmt_port",
22436                             clib_net_to_host_u16 (mp->rmt_port));
22437   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22438   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22439   vat_json_object_add_string_copy (node, "tag", mp->tag);
22440   if (mp->is_ip4)
22441     {
22442       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22443       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22444       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22445       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22446     }
22447   else
22448     {
22449       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22450       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22451       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22452       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22453     }
22454 }
22455
22456 static int
22457 api_session_rule_add_del (vat_main_t * vam)
22458 {
22459   vl_api_session_rule_add_del_t *mp;
22460   unformat_input_t *i = vam->input;
22461   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22462   u32 appns_index = 0, scope = 0;
22463   ip4_address_t lcl_ip4, rmt_ip4;
22464   ip6_address_t lcl_ip6, rmt_ip6;
22465   u8 is_ip4 = 1, conn_set = 0;
22466   u8 is_add = 1, *tag = 0;
22467   int ret;
22468
22469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22470     {
22471       if (unformat (i, "del"))
22472         is_add = 0;
22473       else if (unformat (i, "add"))
22474         ;
22475       else if (unformat (i, "proto tcp"))
22476         proto = 0;
22477       else if (unformat (i, "proto udp"))
22478         proto = 1;
22479       else if (unformat (i, "appns %d", &appns_index))
22480         ;
22481       else if (unformat (i, "scope %d", &scope))
22482         ;
22483       else if (unformat (i, "tag %_%v%_", &tag))
22484         ;
22485       else
22486         if (unformat
22487             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22488              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22489              &rmt_port))
22490         {
22491           is_ip4 = 1;
22492           conn_set = 1;
22493         }
22494       else
22495         if (unformat
22496             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22497              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22498              &rmt_port))
22499         {
22500           is_ip4 = 0;
22501           conn_set = 1;
22502         }
22503       else if (unformat (i, "action %d", &action))
22504         ;
22505       else
22506         break;
22507     }
22508   if (proto == ~0 || !conn_set || action == ~0)
22509     {
22510       errmsg ("transport proto, connection and action must be set");
22511       return -99;
22512     }
22513
22514   if (scope > 3)
22515     {
22516       errmsg ("scope should be 0-3");
22517       return -99;
22518     }
22519
22520   M (SESSION_RULE_ADD_DEL, mp);
22521
22522   mp->is_ip4 = is_ip4;
22523   mp->transport_proto = proto;
22524   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22525   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22526   mp->lcl_plen = lcl_plen;
22527   mp->rmt_plen = rmt_plen;
22528   mp->action_index = clib_host_to_net_u32 (action);
22529   mp->appns_index = clib_host_to_net_u32 (appns_index);
22530   mp->scope = scope;
22531   mp->is_add = is_add;
22532   if (is_ip4)
22533     {
22534       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22535       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22536     }
22537   else
22538     {
22539       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22540       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22541     }
22542   if (tag)
22543     {
22544       clib_memcpy (mp->tag, tag, vec_len (tag));
22545       vec_free (tag);
22546     }
22547
22548   S (mp);
22549   W (ret);
22550   return ret;
22551 }
22552
22553 static int
22554 api_session_rules_dump (vat_main_t * vam)
22555 {
22556   vl_api_session_rules_dump_t *mp;
22557   vl_api_control_ping_t *mp_ping;
22558   int ret;
22559
22560   if (!vam->json_output)
22561     {
22562       print (vam->ofp, "%=20s", "Session Rules");
22563     }
22564
22565   M (SESSION_RULES_DUMP, mp);
22566   /* send it... */
22567   S (mp);
22568
22569   /* Use a control ping for synchronization */
22570   MPING (CONTROL_PING, mp_ping);
22571   S (mp_ping);
22572
22573   /* Wait for a reply... */
22574   W (ret);
22575   return ret;
22576 }
22577
22578 static int
22579 api_ip_container_proxy_add_del (vat_main_t * vam)
22580 {
22581   vl_api_ip_container_proxy_add_del_t *mp;
22582   unformat_input_t *i = vam->input;
22583   u32 plen = ~0, sw_if_index = ~0;
22584   ip4_address_t ip4;
22585   ip6_address_t ip6;
22586   u8 is_ip4 = 1;
22587   u8 is_add = 1;
22588   int ret;
22589
22590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22591     {
22592       if (unformat (i, "del"))
22593         is_add = 0;
22594       else if (unformat (i, "add"))
22595         ;
22596       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22597         {
22598           is_ip4 = 1;
22599           plen = 32;
22600         }
22601       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22602         {
22603           is_ip4 = 0;
22604           plen = 128;
22605         }
22606       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22607         ;
22608       else
22609         break;
22610     }
22611   if (sw_if_index == ~0 || plen == ~0)
22612     {
22613       errmsg ("address and sw_if_index must be set");
22614       return -99;
22615     }
22616
22617   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22618
22619   mp->is_ip4 = is_ip4;
22620   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22621   mp->plen = plen;
22622   mp->is_add = is_add;
22623   if (is_ip4)
22624     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22625   else
22626     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22627
22628   S (mp);
22629   W (ret);
22630   return ret;
22631 }
22632
22633 static int
22634 api_qos_record_enable_disable (vat_main_t * vam)
22635 {
22636   unformat_input_t *i = vam->input;
22637   vl_api_qos_record_enable_disable_t *mp;
22638   u32 sw_if_index, qs = 0xff;
22639   u8 sw_if_index_set = 0;
22640   u8 enable = 1;
22641   int ret;
22642
22643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22644     {
22645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22646         sw_if_index_set = 1;
22647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22648         sw_if_index_set = 1;
22649       else if (unformat (i, "%U", unformat_qos_source, &qs))
22650         ;
22651       else if (unformat (i, "disable"))
22652         enable = 0;
22653       else
22654         {
22655           clib_warning ("parse error '%U'", format_unformat_error, i);
22656           return -99;
22657         }
22658     }
22659
22660   if (sw_if_index_set == 0)
22661     {
22662       errmsg ("missing interface name or sw_if_index");
22663       return -99;
22664     }
22665   if (qs == 0xff)
22666     {
22667       errmsg ("input location must be specified");
22668       return -99;
22669     }
22670
22671   M (QOS_RECORD_ENABLE_DISABLE, mp);
22672
22673   mp->sw_if_index = ntohl (sw_if_index);
22674   mp->input_source = qs;
22675   mp->enable = enable;
22676
22677   S (mp);
22678   W (ret);
22679   return ret;
22680 }
22681
22682
22683 static int
22684 q_or_quit (vat_main_t * vam)
22685 {
22686 #if VPP_API_TEST_BUILTIN == 0
22687   longjmp (vam->jump_buf, 1);
22688 #endif
22689   return 0;                     /* not so much */
22690 }
22691
22692 static int
22693 q (vat_main_t * vam)
22694 {
22695   return q_or_quit (vam);
22696 }
22697
22698 static int
22699 quit (vat_main_t * vam)
22700 {
22701   return q_or_quit (vam);
22702 }
22703
22704 static int
22705 comment (vat_main_t * vam)
22706 {
22707   return 0;
22708 }
22709
22710 static int
22711 statseg (vat_main_t * vam)
22712 {
22713   ssvm_private_t *ssvmp = &vam->stat_segment;
22714   ssvm_shared_header_t *shared_header = ssvmp->sh;
22715   vlib_counter_t **counters;
22716   u64 thread0_index1_packets;
22717   u64 thread0_index1_bytes;
22718   f64 vector_rate, input_rate;
22719   uword *p;
22720
22721   uword *counter_vector_by_name;
22722   if (vam->stat_segment_lockp == 0)
22723     {
22724       errmsg ("Stat segment not mapped...");
22725       return -99;
22726     }
22727
22728   /* look up "/if/rx for sw_if_index 1 as a test */
22729
22730   clib_spinlock_lock (vam->stat_segment_lockp);
22731
22732   counter_vector_by_name = (uword *) shared_header->opaque[1];
22733
22734   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22735   if (p == 0)
22736     {
22737       clib_spinlock_unlock (vam->stat_segment_lockp);
22738       errmsg ("/if/tx not found?");
22739       return -99;
22740     }
22741
22742   /* Fish per-thread vector of combined counters from shared memory */
22743   counters = (vlib_counter_t **) p[0];
22744
22745   if (vec_len (counters[0]) < 2)
22746     {
22747       clib_spinlock_unlock (vam->stat_segment_lockp);
22748       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22749       return -99;
22750     }
22751
22752   /* Read thread 0 sw_if_index 1 counter */
22753   thread0_index1_packets = counters[0][1].packets;
22754   thread0_index1_bytes = counters[0][1].bytes;
22755
22756   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22757   if (p == 0)
22758     {
22759       clib_spinlock_unlock (vam->stat_segment_lockp);
22760       errmsg ("vector_rate not found?");
22761       return -99;
22762     }
22763
22764   vector_rate = *(f64 *) (p[0]);
22765   p = hash_get_mem (counter_vector_by_name, "input_rate");
22766   if (p == 0)
22767     {
22768       clib_spinlock_unlock (vam->stat_segment_lockp);
22769       errmsg ("input_rate not found?");
22770       return -99;
22771     }
22772   input_rate = *(f64 *) (p[0]);
22773
22774   clib_spinlock_unlock (vam->stat_segment_lockp);
22775
22776   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22777          vector_rate, input_rate);
22778   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22779          thread0_index1_packets, thread0_index1_bytes);
22780
22781   return 0;
22782 }
22783
22784 static int
22785 cmd_cmp (void *a1, void *a2)
22786 {
22787   u8 **c1 = a1;
22788   u8 **c2 = a2;
22789
22790   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22791 }
22792
22793 static int
22794 help (vat_main_t * vam)
22795 {
22796   u8 **cmds = 0;
22797   u8 *name = 0;
22798   hash_pair_t *p;
22799   unformat_input_t *i = vam->input;
22800   int j;
22801
22802   if (unformat (i, "%s", &name))
22803     {
22804       uword *hs;
22805
22806       vec_add1 (name, 0);
22807
22808       hs = hash_get_mem (vam->help_by_name, name);
22809       if (hs)
22810         print (vam->ofp, "usage: %s %s", name, hs[0]);
22811       else
22812         print (vam->ofp, "No such msg / command '%s'", name);
22813       vec_free (name);
22814       return 0;
22815     }
22816
22817   print (vam->ofp, "Help is available for the following:");
22818
22819     /* *INDENT-OFF* */
22820     hash_foreach_pair (p, vam->function_by_name,
22821     ({
22822       vec_add1 (cmds, (u8 *)(p->key));
22823     }));
22824     /* *INDENT-ON* */
22825
22826   vec_sort_with_function (cmds, cmd_cmp);
22827
22828   for (j = 0; j < vec_len (cmds); j++)
22829     print (vam->ofp, "%s", cmds[j]);
22830
22831   vec_free (cmds);
22832   return 0;
22833 }
22834
22835 static int
22836 set (vat_main_t * vam)
22837 {
22838   u8 *name = 0, *value = 0;
22839   unformat_input_t *i = vam->input;
22840
22841   if (unformat (i, "%s", &name))
22842     {
22843       /* The input buffer is a vector, not a string. */
22844       value = vec_dup (i->buffer);
22845       vec_delete (value, i->index, 0);
22846       /* Almost certainly has a trailing newline */
22847       if (value[vec_len (value) - 1] == '\n')
22848         value[vec_len (value) - 1] = 0;
22849       /* Make sure it's a proper string, one way or the other */
22850       vec_add1 (value, 0);
22851       (void) clib_macro_set_value (&vam->macro_main,
22852                                    (char *) name, (char *) value);
22853     }
22854   else
22855     errmsg ("usage: set <name> <value>");
22856
22857   vec_free (name);
22858   vec_free (value);
22859   return 0;
22860 }
22861
22862 static int
22863 unset (vat_main_t * vam)
22864 {
22865   u8 *name = 0;
22866
22867   if (unformat (vam->input, "%s", &name))
22868     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22869       errmsg ("unset: %s wasn't set", name);
22870   vec_free (name);
22871   return 0;
22872 }
22873
22874 typedef struct
22875 {
22876   u8 *name;
22877   u8 *value;
22878 } macro_sort_t;
22879
22880
22881 static int
22882 macro_sort_cmp (void *a1, void *a2)
22883 {
22884   macro_sort_t *s1 = a1;
22885   macro_sort_t *s2 = a2;
22886
22887   return strcmp ((char *) (s1->name), (char *) (s2->name));
22888 }
22889
22890 static int
22891 dump_macro_table (vat_main_t * vam)
22892 {
22893   macro_sort_t *sort_me = 0, *sm;
22894   int i;
22895   hash_pair_t *p;
22896
22897     /* *INDENT-OFF* */
22898     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22899     ({
22900       vec_add2 (sort_me, sm, 1);
22901       sm->name = (u8 *)(p->key);
22902       sm->value = (u8 *) (p->value[0]);
22903     }));
22904     /* *INDENT-ON* */
22905
22906   vec_sort_with_function (sort_me, macro_sort_cmp);
22907
22908   if (vec_len (sort_me))
22909     print (vam->ofp, "%-15s%s", "Name", "Value");
22910   else
22911     print (vam->ofp, "The macro table is empty...");
22912
22913   for (i = 0; i < vec_len (sort_me); i++)
22914     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22915   return 0;
22916 }
22917
22918 static int
22919 dump_node_table (vat_main_t * vam)
22920 {
22921   int i, j;
22922   vlib_node_t *node, *next_node;
22923
22924   if (vec_len (vam->graph_nodes) == 0)
22925     {
22926       print (vam->ofp, "Node table empty, issue get_node_graph...");
22927       return 0;
22928     }
22929
22930   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22931     {
22932       node = vam->graph_nodes[0][i];
22933       print (vam->ofp, "[%d] %s", i, node->name);
22934       for (j = 0; j < vec_len (node->next_nodes); j++)
22935         {
22936           if (node->next_nodes[j] != ~0)
22937             {
22938               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22939               print (vam->ofp, "  [%d] %s", j, next_node->name);
22940             }
22941         }
22942     }
22943   return 0;
22944 }
22945
22946 static int
22947 value_sort_cmp (void *a1, void *a2)
22948 {
22949   name_sort_t *n1 = a1;
22950   name_sort_t *n2 = a2;
22951
22952   if (n1->value < n2->value)
22953     return -1;
22954   if (n1->value > n2->value)
22955     return 1;
22956   return 0;
22957 }
22958
22959
22960 static int
22961 dump_msg_api_table (vat_main_t * vam)
22962 {
22963   api_main_t *am = &api_main;
22964   name_sort_t *nses = 0, *ns;
22965   hash_pair_t *hp;
22966   int i;
22967
22968   /* *INDENT-OFF* */
22969   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22970   ({
22971     vec_add2 (nses, ns, 1);
22972     ns->name = (u8 *)(hp->key);
22973     ns->value = (u32) hp->value[0];
22974   }));
22975   /* *INDENT-ON* */
22976
22977   vec_sort_with_function (nses, value_sort_cmp);
22978
22979   for (i = 0; i < vec_len (nses); i++)
22980     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22981   vec_free (nses);
22982   return 0;
22983 }
22984
22985 static int
22986 get_msg_id (vat_main_t * vam)
22987 {
22988   u8 *name_and_crc;
22989   u32 message_index;
22990
22991   if (unformat (vam->input, "%s", &name_and_crc))
22992     {
22993       message_index = vl_msg_api_get_msg_index (name_and_crc);
22994       if (message_index == ~0)
22995         {
22996           print (vam->ofp, " '%s' not found", name_and_crc);
22997           return 0;
22998         }
22999       print (vam->ofp, " '%s' has message index %d",
23000              name_and_crc, message_index);
23001       return 0;
23002     }
23003   errmsg ("name_and_crc required...");
23004   return 0;
23005 }
23006
23007 static int
23008 search_node_table (vat_main_t * vam)
23009 {
23010   unformat_input_t *line_input = vam->input;
23011   u8 *node_to_find;
23012   int j;
23013   vlib_node_t *node, *next_node;
23014   uword *p;
23015
23016   if (vam->graph_node_index_by_name == 0)
23017     {
23018       print (vam->ofp, "Node table empty, issue get_node_graph...");
23019       return 0;
23020     }
23021
23022   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23023     {
23024       if (unformat (line_input, "%s", &node_to_find))
23025         {
23026           vec_add1 (node_to_find, 0);
23027           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23028           if (p == 0)
23029             {
23030               print (vam->ofp, "%s not found...", node_to_find);
23031               goto out;
23032             }
23033           node = vam->graph_nodes[0][p[0]];
23034           print (vam->ofp, "[%d] %s", p[0], node->name);
23035           for (j = 0; j < vec_len (node->next_nodes); j++)
23036             {
23037               if (node->next_nodes[j] != ~0)
23038                 {
23039                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23040                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23041                 }
23042             }
23043         }
23044
23045       else
23046         {
23047           clib_warning ("parse error '%U'", format_unformat_error,
23048                         line_input);
23049           return -99;
23050         }
23051
23052     out:
23053       vec_free (node_to_find);
23054
23055     }
23056
23057   return 0;
23058 }
23059
23060
23061 static int
23062 script (vat_main_t * vam)
23063 {
23064 #if (VPP_API_TEST_BUILTIN==0)
23065   u8 *s = 0;
23066   char *save_current_file;
23067   unformat_input_t save_input;
23068   jmp_buf save_jump_buf;
23069   u32 save_line_number;
23070
23071   FILE *new_fp, *save_ifp;
23072
23073   if (unformat (vam->input, "%s", &s))
23074     {
23075       new_fp = fopen ((char *) s, "r");
23076       if (new_fp == 0)
23077         {
23078           errmsg ("Couldn't open script file %s", s);
23079           vec_free (s);
23080           return -99;
23081         }
23082     }
23083   else
23084     {
23085       errmsg ("Missing script name");
23086       return -99;
23087     }
23088
23089   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23090   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23091   save_ifp = vam->ifp;
23092   save_line_number = vam->input_line_number;
23093   save_current_file = (char *) vam->current_file;
23094
23095   vam->input_line_number = 0;
23096   vam->ifp = new_fp;
23097   vam->current_file = s;
23098   do_one_file (vam);
23099
23100   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23101   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23102   vam->ifp = save_ifp;
23103   vam->input_line_number = save_line_number;
23104   vam->current_file = (u8 *) save_current_file;
23105   vec_free (s);
23106
23107   return 0;
23108 #else
23109   clib_warning ("use the exec command...");
23110   return -99;
23111 #endif
23112 }
23113
23114 static int
23115 echo (vat_main_t * vam)
23116 {
23117   print (vam->ofp, "%v", vam->input->buffer);
23118   return 0;
23119 }
23120
23121 /* List of API message constructors, CLI names map to api_xxx */
23122 #define foreach_vpe_api_msg                                             \
23123 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23124 _(sw_interface_dump,"")                                                 \
23125 _(sw_interface_set_flags,                                               \
23126   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23127 _(sw_interface_add_del_address,                                         \
23128   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23129 _(sw_interface_set_rx_mode,                                             \
23130   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23131 _(sw_interface_set_rx_placement,                                        \
23132   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23133 _(sw_interface_rx_placement_dump,                                       \
23134   "[<intfc> | sw_if_index <id>]")                                         \
23135 _(sw_interface_set_table,                                               \
23136   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23137 _(sw_interface_set_mpls_enable,                                         \
23138   "<intfc> | sw_if_index [disable | dis]")                              \
23139 _(sw_interface_set_vpath,                                               \
23140   "<intfc> | sw_if_index <id> enable | disable")                        \
23141 _(sw_interface_set_vxlan_bypass,                                        \
23142   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23143 _(sw_interface_set_geneve_bypass,                                       \
23144   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23145 _(sw_interface_set_l2_xconnect,                                         \
23146   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23147   "enable | disable")                                                   \
23148 _(sw_interface_set_l2_bridge,                                           \
23149   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23150   "[shg <split-horizon-group>] [bvi]\n"                                 \
23151   "enable | disable")                                                   \
23152 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23153 _(bridge_domain_add_del,                                                \
23154   "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") \
23155 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23156 _(l2fib_add_del,                                                        \
23157   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23158 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23159 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23160 _(l2_flags,                                                             \
23161   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23162 _(bridge_flags,                                                         \
23163   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23164 _(tap_connect,                                                          \
23165   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23166 _(tap_modify,                                                           \
23167   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23168 _(tap_delete,                                                           \
23169   "<vpp-if-name> | sw_if_index <id>")                                   \
23170 _(sw_interface_tap_dump, "")                                            \
23171 _(tap_create_v2,                                                        \
23172   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23173 _(tap_delete_v2,                                                        \
23174   "<vpp-if-name> | sw_if_index <id>")                                   \
23175 _(sw_interface_tap_v2_dump, "")                                         \
23176 _(bond_create,                                                          \
23177   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23178   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23179 _(bond_delete,                                                          \
23180   "<vpp-if-name> | sw_if_index <id>")                                   \
23181 _(bond_enslave,                                                         \
23182   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23183 _(bond_detach_slave,                                                    \
23184   "sw_if_index <n>")                                                    \
23185 _(sw_interface_bond_dump, "")                                           \
23186 _(sw_interface_slave_dump,                                              \
23187   "<vpp-if-name> | sw_if_index <id>")                                   \
23188 _(ip_table_add_del,                                                     \
23189   "table <n> [ipv6] [add | del]\n")                                     \
23190 _(ip_add_del_route,                                                     \
23191   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23192   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23193   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23194   "[multipath] [count <n>] [del]")                                      \
23195 _(ip_mroute_add_del,                                                    \
23196   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23197   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23198 _(mpls_table_add_del,                                                   \
23199   "table <n> [add | del]\n")                                            \
23200 _(mpls_route_add_del,                                                   \
23201   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23202   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23203   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23204   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23205   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23206   "[count <n>] [del]")                                                  \
23207 _(mpls_ip_bind_unbind,                                                  \
23208   "<label> <addr/len>")                                                 \
23209 _(mpls_tunnel_add_del,                                                  \
23210   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23211   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23212   "[l2-only]  [out-label <n>]")                                         \
23213 _(sr_mpls_policy_add,                                                   \
23214   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23215 _(sr_mpls_policy_del,                                                   \
23216   "bsid <id>")                                                          \
23217 _(bier_table_add_del,                                                   \
23218   "<label> <sub-domain> <set> <bsl> [del]")                             \
23219 _(bier_route_add_del,                                                   \
23220   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23221   "[<intfc> | sw_if_index <id>]"                                        \
23222   "[weight <n>] [del] [multipath]")                                     \
23223 _(proxy_arp_add_del,                                                    \
23224   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23225 _(proxy_arp_intfc_enable_disable,                                       \
23226   "<intfc> | sw_if_index <id> enable | disable")                        \
23227 _(sw_interface_set_unnumbered,                                          \
23228   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23229 _(ip_neighbor_add_del,                                                  \
23230   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23231   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23232 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23233 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23234   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23235   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23236   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23237 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23238 _(reset_fib, "vrf <n> [ipv6]")                                          \
23239 _(dhcp_proxy_config,                                                    \
23240   "svr <v46-address> src <v46-address>\n"                               \
23241    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23242 _(dhcp_proxy_set_vss,                                                   \
23243   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23244 _(dhcp_proxy_dump, "ip6")                                               \
23245 _(dhcp_client_config,                                                   \
23246   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23247 _(set_ip_flow_hash,                                                     \
23248   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23249 _(sw_interface_ip6_enable_disable,                                      \
23250   "<intfc> | sw_if_index <id> enable | disable")                        \
23251 _(ip6nd_proxy_add_del,                                                  \
23252   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23253 _(ip6nd_proxy_dump, "")                                                 \
23254 _(sw_interface_ip6nd_ra_prefix,                                         \
23255   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23256   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23257   "[nolink] [isno]")                                                    \
23258 _(sw_interface_ip6nd_ra_config,                                         \
23259   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23260   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23261   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23262 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23263 _(l2_patch_add_del,                                                     \
23264   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23265   "enable | disable")                                                   \
23266 _(sr_localsid_add_del,                                                  \
23267   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23268   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23269 _(classify_add_del_table,                                               \
23270   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23271   " [del] [del-chain] mask <mask-value>\n"                              \
23272   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23273   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23274 _(classify_add_del_session,                                             \
23275   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23276   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23277   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23278   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23279 _(classify_set_interface_ip_table,                                      \
23280   "<intfc> | sw_if_index <nn> table <nn>")                              \
23281 _(classify_set_interface_l2_tables,                                     \
23282   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23283   "  [other-table <nn>]")                                               \
23284 _(get_node_index, "node <node-name")                                    \
23285 _(add_node_next, "node <node-name> next <next-node-name>")              \
23286 _(l2tpv3_create_tunnel,                                                 \
23287   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23288   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23289   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23290 _(l2tpv3_set_tunnel_cookies,                                            \
23291   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23292   "[new_remote_cookie <nn>]\n")                                         \
23293 _(l2tpv3_interface_enable_disable,                                      \
23294   "<intfc> | sw_if_index <nn> enable | disable")                        \
23295 _(l2tpv3_set_lookup_key,                                                \
23296   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23297 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23298 _(vxlan_offload_rx,                                                     \
23299   "hw { <interface name> | hw_if_index <nn>} "                          \
23300   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23301 _(vxlan_add_del_tunnel,                                                 \
23302   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23303   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23304   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23305 _(geneve_add_del_tunnel,                                                \
23306   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23307   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23308   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23309 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23310 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23311 _(gre_add_del_tunnel,                                                   \
23312   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23313   "[teb | erspan <session-id>] [del]")                                  \
23314 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23315 _(l2_fib_clear_table, "")                                               \
23316 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23317 _(l2_interface_vlan_tag_rewrite,                                        \
23318   "<intfc> | sw_if_index <nn> \n"                                       \
23319   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23320   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23321 _(create_vhost_user_if,                                                 \
23322         "socket <filename> [server] [renumber <dev_instance>] "         \
23323         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23324         "[mac <mac_address>]")                                          \
23325 _(modify_vhost_user_if,                                                 \
23326         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23327         "[server] [renumber <dev_instance>]")                           \
23328 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23329 _(sw_interface_vhost_user_dump, "")                                     \
23330 _(show_version, "")                                                     \
23331 _(show_threads, "")                                                     \
23332 _(vxlan_gpe_add_del_tunnel,                                             \
23333   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23334   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23335   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23336   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23337 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23338 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23339 _(interface_name_renumber,                                              \
23340   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23341 _(input_acl_set_interface,                                              \
23342   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23343   "  [l2-table <nn>] [del]")                                            \
23344 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23345 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23346   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23347 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23348 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23349 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23350 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23351 _(ip_dump, "ipv4 | ipv6")                                               \
23352 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23353 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23354   "  spid_id <n> ")                                                     \
23355 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23356   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23357   "  integ_alg <alg> integ_key <hex>")                                  \
23358 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23359   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23360   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23361   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23362 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23363 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23364   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23365   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23366   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23367   "  [instance <n>]")     \
23368 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23369 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23370   "  <alg> <hex>\n")                                                    \
23371 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23372 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23373 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23374   "(auth_data 0x<data> | auth_data <data>)")                            \
23375 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23376   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23377 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23378   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23379   "(local|remote)")                                                     \
23380 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23381 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23382 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23383 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23384 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23385 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23386 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23387 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23388 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23389 _(delete_loopback,"sw_if_index <nn>")                                   \
23390 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23391 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23392 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23393 _(want_interface_events,  "enable|disable")                             \
23394 _(get_first_msg_id, "client <name>")                                    \
23395 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23396 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23397   "fib-id <nn> [ip4][ip6][default]")                                    \
23398 _(get_node_graph, " ")                                                  \
23399 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23400 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23401 _(ioam_disable, "")                                                     \
23402 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23403                             " sw_if_index <sw_if_index> p <priority> "  \
23404                             "w <weight>] [del]")                        \
23405 _(one_add_del_locator, "locator-set <locator_name> "                    \
23406                         "iface <intf> | sw_if_index <sw_if_index> "     \
23407                         "p <priority> w <weight> [del]")                \
23408 _(one_add_del_local_eid,"vni <vni> eid "                                \
23409                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23410                          "locator-set <locator_name> [del]"             \
23411                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23412 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23413 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23414 _(one_enable_disable, "enable|disable")                                 \
23415 _(one_map_register_enable_disable, "enable|disable")                    \
23416 _(one_map_register_fallback_threshold, "<value>")                       \
23417 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23418 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23419                                "[seid <seid>] "                         \
23420                                "rloc <locator> p <prio> "               \
23421                                "w <weight> [rloc <loc> ... ] "          \
23422                                "action <action> [del-all]")             \
23423 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23424                           "<local-eid>")                                \
23425 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23426 _(one_use_petr, "ip-address> | disable")                                \
23427 _(one_map_request_mode, "src-dst|dst-only")                             \
23428 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23429 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23430 _(one_locator_set_dump, "[local | remote]")                             \
23431 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23432 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23433                        "[local] | [remote]")                            \
23434 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23435 _(one_ndp_bd_get, "")                                                   \
23436 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23437 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23438 _(one_l2_arp_bd_get, "")                                                \
23439 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23440 _(one_stats_enable_disable, "enable|disable")                           \
23441 _(show_one_stats_enable_disable, "")                                    \
23442 _(one_eid_table_vni_dump, "")                                           \
23443 _(one_eid_table_map_dump, "l2|l3")                                      \
23444 _(one_map_resolver_dump, "")                                            \
23445 _(one_map_server_dump, "")                                              \
23446 _(one_adjacencies_get, "vni <vni>")                                     \
23447 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23448 _(show_one_rloc_probe_state, "")                                        \
23449 _(show_one_map_register_state, "")                                      \
23450 _(show_one_status, "")                                                  \
23451 _(one_stats_dump, "")                                                   \
23452 _(one_stats_flush, "")                                                  \
23453 _(one_get_map_request_itr_rlocs, "")                                    \
23454 _(one_map_register_set_ttl, "<ttl>")                                    \
23455 _(one_set_transport_protocol, "udp|api")                                \
23456 _(one_get_transport_protocol, "")                                       \
23457 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23458 _(one_show_xtr_mode, "")                                                \
23459 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23460 _(one_show_pitr_mode, "")                                               \
23461 _(one_enable_disable_petr_mode, "enable|disable")                       \
23462 _(one_show_petr_mode, "")                                               \
23463 _(show_one_nsh_mapping, "")                                             \
23464 _(show_one_pitr, "")                                                    \
23465 _(show_one_use_petr, "")                                                \
23466 _(show_one_map_request_mode, "")                                        \
23467 _(show_one_map_register_ttl, "")                                        \
23468 _(show_one_map_register_fallback_threshold, "")                         \
23469 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23470                             " sw_if_index <sw_if_index> p <priority> "  \
23471                             "w <weight>] [del]")                        \
23472 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23473                         "iface <intf> | sw_if_index <sw_if_index> "     \
23474                         "p <priority> w <weight> [del]")                \
23475 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23476                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23477                          "locator-set <locator_name> [del]"             \
23478                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23479 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23480 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23481 _(lisp_enable_disable, "enable|disable")                                \
23482 _(lisp_map_register_enable_disable, "enable|disable")                   \
23483 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23484 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23485                                "[seid <seid>] "                         \
23486                                "rloc <locator> p <prio> "               \
23487                                "w <weight> [rloc <loc> ... ] "          \
23488                                "action <action> [del-all]")             \
23489 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23490                           "<local-eid>")                                \
23491 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23492 _(lisp_use_petr, "<ip-address> | disable")                              \
23493 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23494 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23495 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23496 _(lisp_locator_set_dump, "[local | remote]")                            \
23497 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23498 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23499                        "[local] | [remote]")                            \
23500 _(lisp_eid_table_vni_dump, "")                                          \
23501 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23502 _(lisp_map_resolver_dump, "")                                           \
23503 _(lisp_map_server_dump, "")                                             \
23504 _(lisp_adjacencies_get, "vni <vni>")                                    \
23505 _(gpe_fwd_entry_vnis_get, "")                                           \
23506 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23507 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23508                                 "[table <table-id>]")                   \
23509 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23510 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23511 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23512 _(gpe_get_encap_mode, "")                                               \
23513 _(lisp_gpe_add_del_iface, "up|down")                                    \
23514 _(lisp_gpe_enable_disable, "enable|disable")                            \
23515 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23516   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23517 _(show_lisp_rloc_probe_state, "")                                       \
23518 _(show_lisp_map_register_state, "")                                     \
23519 _(show_lisp_status, "")                                                 \
23520 _(lisp_get_map_request_itr_rlocs, "")                                   \
23521 _(show_lisp_pitr, "")                                                   \
23522 _(show_lisp_use_petr, "")                                               \
23523 _(show_lisp_map_request_mode, "")                                       \
23524 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23525 _(af_packet_delete, "name <host interface name>")                       \
23526 _(af_packet_dump, "")                                                   \
23527 _(policer_add_del, "name <policer name> <params> [del]")                \
23528 _(policer_dump, "[name <policer name>]")                                \
23529 _(policer_classify_set_interface,                                       \
23530   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23531   "  [l2-table <nn>] [del]")                                            \
23532 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23533 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23534     "[master|slave]")                                                   \
23535 _(netmap_delete, "name <interface name>")                               \
23536 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23537 _(mpls_fib_dump, "")                                                    \
23538 _(classify_table_ids, "")                                               \
23539 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23540 _(classify_table_info, "table_id <nn>")                                 \
23541 _(classify_session_dump, "table_id <nn>")                               \
23542 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23543     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23544     "[template_interval <nn>] [udp_checksum]")                          \
23545 _(ipfix_exporter_dump, "")                                              \
23546 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23547 _(ipfix_classify_stream_dump, "")                                       \
23548 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23549 _(ipfix_classify_table_dump, "")                                        \
23550 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23551 _(sw_interface_span_dump, "[l2]")                                           \
23552 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23553 _(pg_create_interface, "if_id <nn>")                                    \
23554 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23555 _(pg_enable_disable, "[stream <id>] disable")                           \
23556 _(ip_source_and_port_range_check_add_del,                               \
23557   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23558 _(ip_source_and_port_range_check_interface_add_del,                     \
23559   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23560   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23561 _(ipsec_gre_add_del_tunnel,                                             \
23562   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23563 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23564 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23565 _(l2_interface_pbb_tag_rewrite,                                         \
23566   "<intfc> | sw_if_index <nn> \n"                                       \
23567   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23568   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23569 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23570 _(flow_classify_set_interface,                                          \
23571   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23572 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23573 _(ip_fib_dump, "")                                                      \
23574 _(ip_mfib_dump, "")                                                     \
23575 _(ip6_fib_dump, "")                                                     \
23576 _(ip6_mfib_dump, "")                                                    \
23577 _(feature_enable_disable, "arc_name <arc_name> "                        \
23578   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23579 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23580 "[disable]")                                                            \
23581 _(l2_xconnect_dump, "")                                                 \
23582 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23583 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23584 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23585 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23586 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23587 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23588 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23589   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23590 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23591 _(sock_init_shm, "size <nnn>")                                          \
23592 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23593 _(dns_enable_disable, "[enable][disable]")                              \
23594 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23595 _(dns_resolve_name, "<hostname>")                                       \
23596 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23597 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23598 _(dns_resolve_name, "<hostname>")                                       \
23599 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23600   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23601 _(session_rules_dump, "")                                               \
23602 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23603 _(output_acl_set_interface,                                             \
23604   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23605   "  [l2-table <nn>] [del]")                                            \
23606 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23607
23608 /* List of command functions, CLI names map directly to functions */
23609 #define foreach_cli_function                                    \
23610 _(comment, "usage: comment <ignore-rest-of-line>")              \
23611 _(dump_interface_table, "usage: dump_interface_table")          \
23612 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23613 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23614 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23615 _(dump_macro_table, "usage: dump_macro_table ")                 \
23616 _(dump_node_table, "usage: dump_node_table")                    \
23617 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23618 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23619 _(echo, "usage: echo <message>")                                \
23620 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23621 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23622 _(help, "usage: help")                                          \
23623 _(q, "usage: quit")                                             \
23624 _(quit, "usage: quit")                                          \
23625 _(search_node_table, "usage: search_node_table <name>...")      \
23626 _(set, "usage: set <variable-name> <value>")                    \
23627 _(script, "usage: script <file-name>")                          \
23628 _(statseg, "usage: statseg");                                   \
23629 _(unset, "usage: unset <variable-name>")
23630
23631 #define _(N,n)                                  \
23632     static void vl_api_##n##_t_handler_uni      \
23633     (vl_api_##n##_t * mp)                       \
23634     {                                           \
23635         vat_main_t * vam = &vat_main;           \
23636         if (vam->json_output) {                 \
23637             vl_api_##n##_t_handler_json(mp);    \
23638         } else {                                \
23639             vl_api_##n##_t_handler(mp);         \
23640         }                                       \
23641     }
23642 foreach_vpe_api_reply_msg;
23643 #if VPP_API_TEST_BUILTIN == 0
23644 foreach_standalone_reply_msg;
23645 #endif
23646 #undef _
23647
23648 void
23649 vat_api_hookup (vat_main_t * vam)
23650 {
23651 #define _(N,n)                                                  \
23652     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23653                            vl_api_##n##_t_handler_uni,          \
23654                            vl_noop_handler,                     \
23655                            vl_api_##n##_t_endian,               \
23656                            vl_api_##n##_t_print,                \
23657                            sizeof(vl_api_##n##_t), 1);
23658   foreach_vpe_api_reply_msg;
23659 #if VPP_API_TEST_BUILTIN == 0
23660   foreach_standalone_reply_msg;
23661 #endif
23662 #undef _
23663
23664 #if (VPP_API_TEST_BUILTIN==0)
23665   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23666
23667   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23668
23669   vam->function_by_name = hash_create_string (0, sizeof (uword));
23670
23671   vam->help_by_name = hash_create_string (0, sizeof (uword));
23672 #endif
23673
23674   /* API messages we can send */
23675 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23676   foreach_vpe_api_msg;
23677 #undef _
23678
23679   /* Help strings */
23680 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23681   foreach_vpe_api_msg;
23682 #undef _
23683
23684   /* CLI functions */
23685 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23686   foreach_cli_function;
23687 #undef _
23688
23689   /* Help strings */
23690 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23691   foreach_cli_function;
23692 #undef _
23693 }
23694
23695 #if VPP_API_TEST_BUILTIN
23696 static clib_error_t *
23697 vat_api_hookup_shim (vlib_main_t * vm)
23698 {
23699   vat_api_hookup (&vat_main);
23700   return 0;
23701 }
23702
23703 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23704 #endif
23705
23706 /*
23707  * fd.io coding-style-patch-verification: ON
23708  *
23709  * Local Variables:
23710  * eval: (c-set-style "gnu")
23711  * End:
23712  */