deprecate tapcli
[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
1739 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_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_create_v2_reply_t_handler_json
1757   (vl_api_tap_create_v2_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_delete_v2_reply_t_handler (vl_api_tap_delete_v2_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->result_ready = 1;
1787     }
1788 }
1789
1790 static void vl_api_tap_delete_v2_reply_t_handler_json
1791   (vl_api_tap_delete_v2_reply_t * mp)
1792 {
1793   vat_main_t *vam = &vat_main;
1794   vat_json_node_t node;
1795
1796   vat_json_init_object (&node);
1797   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1798
1799   vat_json_print (vam->ofp, &node);
1800   vat_json_free (&node);
1801
1802   vam->retval = ntohl (mp->retval);
1803   vam->result_ready = 1;
1804 }
1805
1806 static void
1807 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1808                                           mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811   i32 retval = ntohl (mp->retval);
1812   if (vam->async_mode)
1813     {
1814       vam->async_errors += (retval < 0);
1815     }
1816   else
1817     {
1818       vam->retval = retval;
1819       vam->sw_if_index = ntohl (mp->sw_if_index);
1820       vam->result_ready = 1;
1821     }
1822 }
1823
1824 static void vl_api_virtio_pci_create_reply_t_handler_json
1825   (vl_api_virtio_pci_create_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1833
1834   vat_json_print (vam->ofp, &node);
1835   vat_json_free (&node);
1836
1837   vam->retval = ntohl (mp->retval);
1838   vam->result_ready = 1;
1839
1840 }
1841
1842 static void
1843 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1844                                           mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   i32 retval = ntohl (mp->retval);
1848   if (vam->async_mode)
1849     {
1850       vam->async_errors += (retval < 0);
1851     }
1852   else
1853     {
1854       vam->retval = retval;
1855       vam->result_ready = 1;
1856     }
1857 }
1858
1859 static void vl_api_virtio_pci_delete_reply_t_handler_json
1860   (vl_api_virtio_pci_delete_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   vat_json_node_t node;
1864
1865   vat_json_init_object (&node);
1866   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 static void
1876 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1877 {
1878   vat_main_t *vam = &vat_main;
1879   i32 retval = ntohl (mp->retval);
1880
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->sw_if_index = ntohl (mp->sw_if_index);
1889       vam->result_ready = 1;
1890     }
1891 }
1892
1893 static void vl_api_bond_create_reply_t_handler_json
1894   (vl_api_bond_create_reply_t * mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   vat_json_node_t node;
1898
1899   vat_json_init_object (&node);
1900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1901   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1902
1903   vat_json_print (vam->ofp, &node);
1904   vat_json_free (&node);
1905
1906   vam->retval = ntohl (mp->retval);
1907   vam->result_ready = 1;
1908 }
1909
1910 static void
1911 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   i32 retval = ntohl (mp->retval);
1915
1916   if (vam->async_mode)
1917     {
1918       vam->async_errors += (retval < 0);
1919     }
1920   else
1921     {
1922       vam->retval = retval;
1923       vam->result_ready = 1;
1924     }
1925 }
1926
1927 static void vl_api_bond_delete_reply_t_handler_json
1928   (vl_api_bond_delete_reply_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   vat_json_node_t node;
1932
1933   vat_json_init_object (&node);
1934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_enslave_reply_t_handler (vl_api_bond_enslave_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_enslave_reply_t_handler_json
1961   (vl_api_bond_enslave_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_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1978                                           mp)
1979 {
1980   vat_main_t *vam = &vat_main;
1981   i32 retval = ntohl (mp->retval);
1982
1983   if (vam->async_mode)
1984     {
1985       vam->async_errors += (retval < 0);
1986     }
1987   else
1988     {
1989       vam->retval = retval;
1990       vam->result_ready = 1;
1991     }
1992 }
1993
1994 static void vl_api_bond_detach_slave_reply_t_handler_json
1995   (vl_api_bond_detach_slave_reply_t * mp)
1996 {
1997   vat_main_t *vam = &vat_main;
1998   vat_json_node_t node;
1999
2000   vat_json_init_object (&node);
2001   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2002
2003   vat_json_print (vam->ofp, &node);
2004   vat_json_free (&node);
2005
2006   vam->retval = ntohl (mp->retval);
2007   vam->result_ready = 1;
2008 }
2009
2010 static void vl_api_sw_interface_bond_details_t_handler
2011   (vl_api_sw_interface_bond_details_t * mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014
2015   print (vam->ofp,
2016          "%-16s %-12d %-12U %-13U %-14u %-14u",
2017          mp->interface_name, ntohl (mp->sw_if_index),
2018          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2019          ntohl (mp->active_slaves), ntohl (mp->slaves));
2020 }
2021
2022 static void vl_api_sw_interface_bond_details_t_handler_json
2023   (vl_api_sw_interface_bond_details_t * mp)
2024 {
2025   vat_main_t *vam = &vat_main;
2026   vat_json_node_t *node = NULL;
2027
2028   if (VAT_JSON_ARRAY != vam->json_tree.type)
2029     {
2030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2031       vat_json_init_array (&vam->json_tree);
2032     }
2033   node = vat_json_array_add (&vam->json_tree);
2034
2035   vat_json_init_object (node);
2036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2037   vat_json_object_add_string_copy (node, "interface_name",
2038                                    mp->interface_name);
2039   vat_json_object_add_uint (node, "mode", mp->mode);
2040   vat_json_object_add_uint (node, "load_balance", mp->lb);
2041   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2042   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2043 }
2044
2045 static int
2046 api_sw_interface_bond_dump (vat_main_t * vam)
2047 {
2048   vl_api_sw_interface_bond_dump_t *mp;
2049   vl_api_control_ping_t *mp_ping;
2050   int ret;
2051
2052   print (vam->ofp,
2053          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2054          "interface name", "sw_if_index", "mode", "load balance",
2055          "active slaves", "slaves");
2056
2057   /* Get list of bond interfaces */
2058   M (SW_INTERFACE_BOND_DUMP, mp);
2059   S (mp);
2060
2061   /* Use a control ping for synchronization */
2062   MPING (CONTROL_PING, mp_ping);
2063   S (mp_ping);
2064
2065   W (ret);
2066   return ret;
2067 }
2068
2069 static void vl_api_sw_interface_slave_details_t_handler
2070   (vl_api_sw_interface_slave_details_t * mp)
2071 {
2072   vat_main_t *vam = &vat_main;
2073
2074   print (vam->ofp,
2075          "%-25s %-12d %-12d %d", mp->interface_name,
2076          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2077 }
2078
2079 static void vl_api_sw_interface_slave_details_t_handler_json
2080   (vl_api_sw_interface_slave_details_t * mp)
2081 {
2082   vat_main_t *vam = &vat_main;
2083   vat_json_node_t *node = NULL;
2084
2085   if (VAT_JSON_ARRAY != vam->json_tree.type)
2086     {
2087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2088       vat_json_init_array (&vam->json_tree);
2089     }
2090   node = vat_json_array_add (&vam->json_tree);
2091
2092   vat_json_init_object (node);
2093   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2094   vat_json_object_add_string_copy (node, "interface_name",
2095                                    mp->interface_name);
2096   vat_json_object_add_uint (node, "passive", mp->is_passive);
2097   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2098 }
2099
2100 static int
2101 api_sw_interface_slave_dump (vat_main_t * vam)
2102 {
2103   unformat_input_t *i = vam->input;
2104   vl_api_sw_interface_slave_dump_t *mp;
2105   vl_api_control_ping_t *mp_ping;
2106   u32 sw_if_index = ~0;
2107   u8 sw_if_index_set = 0;
2108   int ret;
2109
2110   /* Parse args required to build the message */
2111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2112     {
2113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2114         sw_if_index_set = 1;
2115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2116         sw_if_index_set = 1;
2117       else
2118         break;
2119     }
2120
2121   if (sw_if_index_set == 0)
2122     {
2123       errmsg ("missing vpp interface name. ");
2124       return -99;
2125     }
2126
2127   print (vam->ofp,
2128          "\n%-25s %-12s %-12s %s",
2129          "slave interface name", "sw_if_index", "passive", "long_timeout");
2130
2131   /* Get list of bond interfaces */
2132   M (SW_INTERFACE_SLAVE_DUMP, mp);
2133   mp->sw_if_index = ntohl (sw_if_index);
2134   S (mp);
2135
2136   /* Use a control ping for synchronization */
2137   MPING (CONTROL_PING, mp_ping);
2138   S (mp_ping);
2139
2140   W (ret);
2141   return ret;
2142 }
2143
2144 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2145   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   i32 retval = ntohl (mp->retval);
2149   if (vam->async_mode)
2150     {
2151       vam->async_errors += (retval < 0);
2152     }
2153   else
2154     {
2155       vam->retval = retval;
2156       vam->sw_if_index = ntohl (mp->sw_if_index);
2157       vam->result_ready = 1;
2158     }
2159   vam->regenerate_interface_table = 1;
2160 }
2161
2162 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2163   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2164 {
2165   vat_main_t *vam = &vat_main;
2166   vat_json_node_t node;
2167
2168   vat_json_init_object (&node);
2169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2170   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2171                             ntohl (mp->sw_if_index));
2172
2173   vat_json_print (vam->ofp, &node);
2174   vat_json_free (&node);
2175
2176   vam->retval = ntohl (mp->retval);
2177   vam->result_ready = 1;
2178 }
2179
2180 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2181   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184   i32 retval = ntohl (mp->retval);
2185   if (vam->async_mode)
2186     {
2187       vam->async_errors += (retval < 0);
2188     }
2189   else
2190     {
2191       vam->retval = retval;
2192       vam->sw_if_index = ntohl (mp->sw_if_index);
2193       vam->result_ready = 1;
2194     }
2195 }
2196
2197 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2198   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   vat_json_node_t node;
2202
2203   vat_json_init_object (&node);
2204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2205   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2206
2207   vat_json_print (vam->ofp, &node);
2208   vat_json_free (&node);
2209
2210   vam->retval = ntohl (mp->retval);
2211   vam->result_ready = 1;
2212 }
2213
2214 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2215   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   i32 retval = ntohl (mp->retval);
2219   if (vam->async_mode)
2220     {
2221       vam->async_errors += (retval < 0);
2222     }
2223   else
2224     {
2225       vam->retval = retval;
2226       vam->result_ready = 1;
2227     }
2228 }
2229
2230 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2231   (vl_api_gpe_add_del_fwd_entry_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, "fwd_entry_index",
2239                             clib_net_to_host_u32 (mp->fwd_entry_index));
2240
2241   vat_json_print (vam->ofp, &node);
2242   vat_json_free (&node);
2243
2244   vam->retval = ntohl (mp->retval);
2245   vam->result_ready = 1;
2246 }
2247
2248 u8 *
2249 format_lisp_transport_protocol (u8 * s, va_list * args)
2250 {
2251   u32 proto = va_arg (*args, u32);
2252
2253   switch (proto)
2254     {
2255     case 1:
2256       return format (s, "udp");
2257     case 2:
2258       return format (s, "api");
2259     default:
2260       return 0;
2261     }
2262   return 0;
2263 }
2264
2265 static void vl_api_one_get_transport_protocol_reply_t_handler
2266   (vl_api_one_get_transport_protocol_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   i32 retval = ntohl (mp->retval);
2270   if (vam->async_mode)
2271     {
2272       vam->async_errors += (retval < 0);
2273     }
2274   else
2275     {
2276       u32 proto = mp->protocol;
2277       print (vam->ofp, "Transport protocol: %U",
2278              format_lisp_transport_protocol, proto);
2279       vam->retval = retval;
2280       vam->result_ready = 1;
2281     }
2282 }
2283
2284 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2285   (vl_api_one_get_transport_protocol_reply_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   vat_json_node_t node;
2289   u8 *s;
2290
2291   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2292   vec_add1 (s, 0);
2293
2294   vat_json_init_object (&node);
2295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2296   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2297
2298   vec_free (s);
2299   vat_json_print (vam->ofp, &node);
2300   vat_json_free (&node);
2301
2302   vam->retval = ntohl (mp->retval);
2303   vam->result_ready = 1;
2304 }
2305
2306 static void vl_api_one_add_del_locator_set_reply_t_handler
2307   (vl_api_one_add_del_locator_set_reply_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   i32 retval = ntohl (mp->retval);
2311   if (vam->async_mode)
2312     {
2313       vam->async_errors += (retval < 0);
2314     }
2315   else
2316     {
2317       vam->retval = retval;
2318       vam->result_ready = 1;
2319     }
2320 }
2321
2322 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2323   (vl_api_one_add_del_locator_set_reply_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vat_json_node_t node;
2327
2328   vat_json_init_object (&node);
2329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2330   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2331
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_vxlan_add_del_tunnel_reply_t_handler
2340   (vl_api_vxlan_add_del_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
2352       vam->result_ready = 1;
2353     }
2354   vam->regenerate_interface_table = 1;
2355 }
2356
2357 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2358   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2359 {
2360   vat_main_t *vam = &vat_main;
2361   vat_json_node_t node;
2362
2363   vat_json_init_object (&node);
2364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2365   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2366
2367   vat_json_print (vam->ofp, &node);
2368   vat_json_free (&node);
2369
2370   vam->retval = ntohl (mp->retval);
2371   vam->result_ready = 1;
2372 }
2373
2374 static void vl_api_vxlan_offload_rx_reply_t_handler
2375   (vl_api_vxlan_offload_rx_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   i32 retval = ntohl (mp->retval);
2379   if (vam->async_mode)
2380     {
2381       vam->async_errors += (retval < 0);
2382     }
2383   else
2384     {
2385       vam->retval = retval;
2386       vam->result_ready = 1;
2387     }
2388 }
2389
2390 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2391   (vl_api_vxlan_offload_rx_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
2399   vat_json_print (vam->ofp, &node);
2400   vat_json_free (&node);
2401
2402   vam->retval = ntohl (mp->retval);
2403   vam->result_ready = 1;
2404 }
2405
2406 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2407   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   i32 retval = ntohl (mp->retval);
2411   if (vam->async_mode)
2412     {
2413       vam->async_errors += (retval < 0);
2414     }
2415   else
2416     {
2417       vam->retval = retval;
2418       vam->sw_if_index = ntohl (mp->sw_if_index);
2419       vam->result_ready = 1;
2420     }
2421 }
2422
2423 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2424   (vl_api_geneve_add_del_tunnel_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2432
2433   vat_json_print (vam->ofp, &node);
2434   vat_json_free (&node);
2435
2436   vam->retval = ntohl (mp->retval);
2437   vam->result_ready = 1;
2438 }
2439
2440 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2441   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   i32 retval = ntohl (mp->retval);
2445   if (vam->async_mode)
2446     {
2447       vam->async_errors += (retval < 0);
2448     }
2449   else
2450     {
2451       vam->retval = retval;
2452       vam->sw_if_index = ntohl (mp->sw_if_index);
2453       vam->result_ready = 1;
2454     }
2455   vam->regenerate_interface_table = 1;
2456 }
2457
2458 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2459   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t node;
2463
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2467
2468   vat_json_print (vam->ofp, &node);
2469   vat_json_free (&node);
2470
2471   vam->retval = ntohl (mp->retval);
2472   vam->result_ready = 1;
2473 }
2474
2475 static void vl_api_gre_add_del_tunnel_reply_t_handler
2476   (vl_api_gre_add_del_tunnel_reply_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   i32 retval = ntohl (mp->retval);
2480   if (vam->async_mode)
2481     {
2482       vam->async_errors += (retval < 0);
2483     }
2484   else
2485     {
2486       vam->retval = retval;
2487       vam->sw_if_index = ntohl (mp->sw_if_index);
2488       vam->result_ready = 1;
2489     }
2490 }
2491
2492 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2493   (vl_api_gre_add_del_tunnel_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t node;
2497
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2501
2502   vat_json_print (vam->ofp, &node);
2503   vat_json_free (&node);
2504
2505   vam->retval = ntohl (mp->retval);
2506   vam->result_ready = 1;
2507 }
2508
2509 static void vl_api_create_vhost_user_if_reply_t_handler
2510   (vl_api_create_vhost_user_if_reply_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   i32 retval = ntohl (mp->retval);
2514   if (vam->async_mode)
2515     {
2516       vam->async_errors += (retval < 0);
2517     }
2518   else
2519     {
2520       vam->retval = retval;
2521       vam->sw_if_index = ntohl (mp->sw_if_index);
2522       vam->result_ready = 1;
2523     }
2524   vam->regenerate_interface_table = 1;
2525 }
2526
2527 static void vl_api_create_vhost_user_if_reply_t_handler_json
2528   (vl_api_create_vhost_user_if_reply_t * mp)
2529 {
2530   vat_main_t *vam = &vat_main;
2531   vat_json_node_t node;
2532
2533   vat_json_init_object (&node);
2534   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2535   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void vl_api_dns_resolve_name_reply_t_handler
2545   (vl_api_dns_resolve_name_reply_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   i32 retval = ntohl (mp->retval);
2549   if (vam->async_mode)
2550     {
2551       vam->async_errors += (retval < 0);
2552     }
2553   else
2554     {
2555       vam->retval = retval;
2556       vam->result_ready = 1;
2557
2558       if (retval == 0)
2559         {
2560           if (mp->ip4_set)
2561             clib_warning ("ip4 address %U", format_ip4_address,
2562                           (ip4_address_t *) mp->ip4_address);
2563           if (mp->ip6_set)
2564             clib_warning ("ip6 address %U", format_ip6_address,
2565                           (ip6_address_t *) mp->ip6_address);
2566         }
2567       else
2568         clib_warning ("retval %d", retval);
2569     }
2570 }
2571
2572 static void vl_api_dns_resolve_name_reply_t_handler_json
2573   (vl_api_dns_resolve_name_reply_t * mp)
2574 {
2575   clib_warning ("not implemented");
2576 }
2577
2578 static void vl_api_dns_resolve_ip_reply_t_handler
2579   (vl_api_dns_resolve_ip_reply_t * mp)
2580 {
2581   vat_main_t *vam = &vat_main;
2582   i32 retval = ntohl (mp->retval);
2583   if (vam->async_mode)
2584     {
2585       vam->async_errors += (retval < 0);
2586     }
2587   else
2588     {
2589       vam->retval = retval;
2590       vam->result_ready = 1;
2591
2592       if (retval == 0)
2593         {
2594           clib_warning ("canonical name %s", mp->name);
2595         }
2596       else
2597         clib_warning ("retval %d", retval);
2598     }
2599 }
2600
2601 static void vl_api_dns_resolve_ip_reply_t_handler_json
2602   (vl_api_dns_resolve_ip_reply_t * mp)
2603 {
2604   clib_warning ("not implemented");
2605 }
2606
2607
2608 static void vl_api_ip_address_details_t_handler
2609   (vl_api_ip_address_details_t * mp)
2610 {
2611   vat_main_t *vam = &vat_main;
2612   static ip_address_details_t empty_ip_address_details = { {0} };
2613   ip_address_details_t *address = NULL;
2614   ip_details_t *current_ip_details = NULL;
2615   ip_details_t *details = NULL;
2616
2617   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2618
2619   if (!details || vam->current_sw_if_index >= vec_len (details)
2620       || !details[vam->current_sw_if_index].present)
2621     {
2622       errmsg ("ip address details arrived but not stored");
2623       errmsg ("ip_dump should be called first");
2624       return;
2625     }
2626
2627   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2628
2629 #define addresses (current_ip_details->addr)
2630
2631   vec_validate_init_empty (addresses, vec_len (addresses),
2632                            empty_ip_address_details);
2633
2634   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2635
2636   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2637   address->prefix_length = mp->prefix_length;
2638 #undef addresses
2639 }
2640
2641 static void vl_api_ip_address_details_t_handler_json
2642   (vl_api_ip_address_details_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   vat_json_node_t *node = NULL;
2646   struct in6_addr ip6;
2647   struct in_addr ip4;
2648
2649   if (VAT_JSON_ARRAY != vam->json_tree.type)
2650     {
2651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2652       vat_json_init_array (&vam->json_tree);
2653     }
2654   node = vat_json_array_add (&vam->json_tree);
2655
2656   vat_json_init_object (node);
2657   if (vam->is_ipv6)
2658     {
2659       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2660       vat_json_object_add_ip6 (node, "ip", ip6);
2661     }
2662   else
2663     {
2664       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2665       vat_json_object_add_ip4 (node, "ip", ip4);
2666     }
2667   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2668 }
2669
2670 static void
2671 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   static ip_details_t empty_ip_details = { 0 };
2675   ip_details_t *ip = NULL;
2676   u32 sw_if_index = ~0;
2677
2678   sw_if_index = ntohl (mp->sw_if_index);
2679
2680   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2681                            sw_if_index, empty_ip_details);
2682
2683   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2684                          sw_if_index);
2685
2686   ip->present = 1;
2687 }
2688
2689 static void
2690 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693
2694   if (VAT_JSON_ARRAY != vam->json_tree.type)
2695     {
2696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2697       vat_json_init_array (&vam->json_tree);
2698     }
2699   vat_json_array_add_uint (&vam->json_tree,
2700                            clib_net_to_host_u32 (mp->sw_if_index));
2701 }
2702
2703 static void
2704 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2705 {
2706   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2707           "router_addr %U host_mac %U",
2708           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2709           mp->lease.hostname,
2710           format_ip4_address, &mp->lease.host_address,
2711           format_ip4_address, &mp->lease.router_address,
2712           format_ethernet_address, mp->lease.host_mac);
2713 }
2714
2715 static void vl_api_dhcp_compl_event_t_handler_json
2716   (vl_api_dhcp_compl_event_t * mp)
2717 {
2718   /* JSON output not supported */
2719 }
2720
2721 static void vl_api_get_first_msg_id_reply_t_handler
2722   (vl_api_get_first_msg_id_reply_t * mp)
2723 {
2724   vat_main_t *vam = &vat_main;
2725   i32 retval = ntohl (mp->retval);
2726
2727   if (vam->async_mode)
2728     {
2729       vam->async_errors += (retval < 0);
2730     }
2731   else
2732     {
2733       vam->retval = retval;
2734       vam->result_ready = 1;
2735     }
2736   if (retval >= 0)
2737     {
2738       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2739     }
2740 }
2741
2742 static void vl_api_get_first_msg_id_reply_t_handler_json
2743   (vl_api_get_first_msg_id_reply_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   vat_json_node_t node;
2747
2748   vat_json_init_object (&node);
2749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2750   vat_json_object_add_uint (&node, "first_msg_id",
2751                             (uint) ntohs (mp->first_msg_id));
2752
2753   vat_json_print (vam->ofp, &node);
2754   vat_json_free (&node);
2755
2756   vam->retval = ntohl (mp->retval);
2757   vam->result_ready = 1;
2758 }
2759
2760 static void vl_api_get_node_graph_reply_t_handler
2761   (vl_api_get_node_graph_reply_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   api_main_t *am = &api_main;
2765   i32 retval = ntohl (mp->retval);
2766   u8 *pvt_copy, *reply;
2767   void *oldheap;
2768   vlib_node_t *node;
2769   int i;
2770
2771   if (vam->async_mode)
2772     {
2773       vam->async_errors += (retval < 0);
2774     }
2775   else
2776     {
2777       vam->retval = retval;
2778       vam->result_ready = 1;
2779     }
2780
2781   /* "Should never happen..." */
2782   if (retval != 0)
2783     return;
2784
2785   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2786   pvt_copy = vec_dup (reply);
2787
2788   /* Toss the shared-memory original... */
2789   pthread_mutex_lock (&am->vlib_rp->mutex);
2790   oldheap = svm_push_data_heap (am->vlib_rp);
2791
2792   vec_free (reply);
2793
2794   svm_pop_heap (oldheap);
2795   pthread_mutex_unlock (&am->vlib_rp->mutex);
2796
2797   if (vam->graph_nodes)
2798     {
2799       hash_free (vam->graph_node_index_by_name);
2800
2801       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2802         {
2803           node = vam->graph_nodes[0][i];
2804           vec_free (node->name);
2805           vec_free (node->next_nodes);
2806           vec_free (node);
2807         }
2808       vec_free (vam->graph_nodes[0]);
2809       vec_free (vam->graph_nodes);
2810     }
2811
2812   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2813   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2814   vec_free (pvt_copy);
2815
2816   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2817     {
2818       node = vam->graph_nodes[0][i];
2819       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2820     }
2821 }
2822
2823 static void vl_api_get_node_graph_reply_t_handler_json
2824   (vl_api_get_node_graph_reply_t * mp)
2825 {
2826   vat_main_t *vam = &vat_main;
2827   api_main_t *am = &api_main;
2828   void *oldheap;
2829   vat_json_node_t node;
2830   u8 *reply;
2831
2832   /* $$$$ make this real? */
2833   vat_json_init_object (&node);
2834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2835   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2836
2837   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2838
2839   /* Toss the shared-memory original... */
2840   pthread_mutex_lock (&am->vlib_rp->mutex);
2841   oldheap = svm_push_data_heap (am->vlib_rp);
2842
2843   vec_free (reply);
2844
2845   svm_pop_heap (oldheap);
2846   pthread_mutex_unlock (&am->vlib_rp->mutex);
2847
2848   vat_json_print (vam->ofp, &node);
2849   vat_json_free (&node);
2850
2851   vam->retval = ntohl (mp->retval);
2852   vam->result_ready = 1;
2853 }
2854
2855 static void
2856 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   u8 *s = 0;
2860
2861   if (mp->local)
2862     {
2863       s = format (s, "%=16d%=16d%=16d",
2864                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2865     }
2866   else
2867     {
2868       s = format (s, "%=16U%=16d%=16d",
2869                   mp->is_ipv6 ? format_ip6_address :
2870                   format_ip4_address,
2871                   mp->ip_address, mp->priority, mp->weight);
2872     }
2873
2874   print (vam->ofp, "%v", s);
2875   vec_free (s);
2876 }
2877
2878 static void
2879 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2880 {
2881   vat_main_t *vam = &vat_main;
2882   vat_json_node_t *node = NULL;
2883   struct in6_addr ip6;
2884   struct in_addr ip4;
2885
2886   if (VAT_JSON_ARRAY != vam->json_tree.type)
2887     {
2888       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2889       vat_json_init_array (&vam->json_tree);
2890     }
2891   node = vat_json_array_add (&vam->json_tree);
2892   vat_json_init_object (node);
2893
2894   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2895   vat_json_object_add_uint (node, "priority", mp->priority);
2896   vat_json_object_add_uint (node, "weight", mp->weight);
2897
2898   if (mp->local)
2899     vat_json_object_add_uint (node, "sw_if_index",
2900                               clib_net_to_host_u32 (mp->sw_if_index));
2901   else
2902     {
2903       if (mp->is_ipv6)
2904         {
2905           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2906           vat_json_object_add_ip6 (node, "address", ip6);
2907         }
2908       else
2909         {
2910           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2911           vat_json_object_add_ip4 (node, "address", ip4);
2912         }
2913     }
2914 }
2915
2916 static void
2917 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2918                                           mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   u8 *ls_name = 0;
2922
2923   ls_name = format (0, "%s", mp->ls_name);
2924
2925   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2926          ls_name);
2927   vec_free (ls_name);
2928 }
2929
2930 static void
2931   vl_api_one_locator_set_details_t_handler_json
2932   (vl_api_one_locator_set_details_t * mp)
2933 {
2934   vat_main_t *vam = &vat_main;
2935   vat_json_node_t *node = 0;
2936   u8 *ls_name = 0;
2937
2938   ls_name = format (0, "%s", mp->ls_name);
2939   vec_add1 (ls_name, 0);
2940
2941   if (VAT_JSON_ARRAY != vam->json_tree.type)
2942     {
2943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2944       vat_json_init_array (&vam->json_tree);
2945     }
2946   node = vat_json_array_add (&vam->json_tree);
2947
2948   vat_json_init_object (node);
2949   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2950   vat_json_object_add_uint (node, "ls_index",
2951                             clib_net_to_host_u32 (mp->ls_index));
2952   vec_free (ls_name);
2953 }
2954
2955 typedef struct
2956 {
2957   u32 spi;
2958   u8 si;
2959 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2960
2961 uword
2962 unformat_nsh_address (unformat_input_t * input, va_list * args)
2963 {
2964   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2965   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2966 }
2967
2968 u8 *
2969 format_nsh_address_vat (u8 * s, va_list * args)
2970 {
2971   nsh_t *a = va_arg (*args, nsh_t *);
2972   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2973 }
2974
2975 static u8 *
2976 format_lisp_flat_eid (u8 * s, va_list * args)
2977 {
2978   u32 type = va_arg (*args, u32);
2979   u8 *eid = va_arg (*args, u8 *);
2980   u32 eid_len = va_arg (*args, u32);
2981
2982   switch (type)
2983     {
2984     case 0:
2985       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2986     case 1:
2987       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2988     case 2:
2989       return format (s, "%U", format_ethernet_address, eid);
2990     case 3:
2991       return format (s, "%U", format_nsh_address_vat, eid);
2992     }
2993   return 0;
2994 }
2995
2996 static u8 *
2997 format_lisp_eid_vat (u8 * s, va_list * args)
2998 {
2999   u32 type = va_arg (*args, u32);
3000   u8 *eid = va_arg (*args, u8 *);
3001   u32 eid_len = va_arg (*args, u32);
3002   u8 *seid = va_arg (*args, u8 *);
3003   u32 seid_len = va_arg (*args, u32);
3004   u32 is_src_dst = va_arg (*args, u32);
3005
3006   if (is_src_dst)
3007     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3008
3009   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3010
3011   return s;
3012 }
3013
3014 static void
3015 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3016 {
3017   vat_main_t *vam = &vat_main;
3018   u8 *s = 0, *eid = 0;
3019
3020   if (~0 == mp->locator_set_index)
3021     s = format (0, "action: %d", mp->action);
3022   else
3023     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3024
3025   eid = format (0, "%U", format_lisp_eid_vat,
3026                 mp->eid_type,
3027                 mp->eid,
3028                 mp->eid_prefix_len,
3029                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3030   vec_add1 (eid, 0);
3031
3032   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3033          clib_net_to_host_u32 (mp->vni),
3034          eid,
3035          mp->is_local ? "local" : "remote",
3036          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3037          clib_net_to_host_u16 (mp->key_id), mp->key);
3038
3039   vec_free (s);
3040   vec_free (eid);
3041 }
3042
3043 static void
3044 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3045                                              * mp)
3046 {
3047   vat_main_t *vam = &vat_main;
3048   vat_json_node_t *node = 0;
3049   u8 *eid = 0;
3050
3051   if (VAT_JSON_ARRAY != vam->json_tree.type)
3052     {
3053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3054       vat_json_init_array (&vam->json_tree);
3055     }
3056   node = vat_json_array_add (&vam->json_tree);
3057
3058   vat_json_init_object (node);
3059   if (~0 == mp->locator_set_index)
3060     vat_json_object_add_uint (node, "action", mp->action);
3061   else
3062     vat_json_object_add_uint (node, "locator_set_index",
3063                               clib_net_to_host_u32 (mp->locator_set_index));
3064
3065   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3066   if (mp->eid_type == 3)
3067     {
3068       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3069       vat_json_init_object (nsh_json);
3070       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3071       vat_json_object_add_uint (nsh_json, "spi",
3072                                 clib_net_to_host_u32 (nsh->spi));
3073       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3074     }
3075   else
3076     {
3077       eid = format (0, "%U", format_lisp_eid_vat,
3078                     mp->eid_type,
3079                     mp->eid,
3080                     mp->eid_prefix_len,
3081                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3082       vec_add1 (eid, 0);
3083       vat_json_object_add_string_copy (node, "eid", eid);
3084       vec_free (eid);
3085     }
3086   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3087   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3088   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3089
3090   if (mp->key_id)
3091     {
3092       vat_json_object_add_uint (node, "key_id",
3093                                 clib_net_to_host_u16 (mp->key_id));
3094       vat_json_object_add_string_copy (node, "key", mp->key);
3095     }
3096 }
3097
3098 static void
3099 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3100 {
3101   vat_main_t *vam = &vat_main;
3102   u8 *seid = 0, *deid = 0;
3103   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3104
3105   deid = format (0, "%U", format_lisp_eid_vat,
3106                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3107
3108   seid = format (0, "%U", format_lisp_eid_vat,
3109                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3110
3111   vec_add1 (deid, 0);
3112   vec_add1 (seid, 0);
3113
3114   if (mp->is_ip4)
3115     format_ip_address_fcn = format_ip4_address;
3116   else
3117     format_ip_address_fcn = format_ip6_address;
3118
3119
3120   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3121          clib_net_to_host_u32 (mp->vni),
3122          seid, deid,
3123          format_ip_address_fcn, mp->lloc,
3124          format_ip_address_fcn, mp->rloc,
3125          clib_net_to_host_u32 (mp->pkt_count),
3126          clib_net_to_host_u32 (mp->bytes));
3127
3128   vec_free (deid);
3129   vec_free (seid);
3130 }
3131
3132 static void
3133 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3134 {
3135   struct in6_addr ip6;
3136   struct in_addr ip4;
3137   vat_main_t *vam = &vat_main;
3138   vat_json_node_t *node = 0;
3139   u8 *deid = 0, *seid = 0;
3140
3141   if (VAT_JSON_ARRAY != vam->json_tree.type)
3142     {
3143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3144       vat_json_init_array (&vam->json_tree);
3145     }
3146   node = vat_json_array_add (&vam->json_tree);
3147
3148   vat_json_init_object (node);
3149   deid = format (0, "%U", format_lisp_eid_vat,
3150                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3151
3152   seid = format (0, "%U", format_lisp_eid_vat,
3153                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3154
3155   vec_add1 (deid, 0);
3156   vec_add1 (seid, 0);
3157
3158   vat_json_object_add_string_copy (node, "seid", seid);
3159   vat_json_object_add_string_copy (node, "deid", deid);
3160   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3161
3162   if (mp->is_ip4)
3163     {
3164       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3165       vat_json_object_add_ip4 (node, "lloc", ip4);
3166       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3167       vat_json_object_add_ip4 (node, "rloc", ip4);
3168     }
3169   else
3170     {
3171       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3172       vat_json_object_add_ip6 (node, "lloc", ip6);
3173       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3174       vat_json_object_add_ip6 (node, "rloc", ip6);
3175     }
3176   vat_json_object_add_uint (node, "pkt_count",
3177                             clib_net_to_host_u32 (mp->pkt_count));
3178   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3179
3180   vec_free (deid);
3181   vec_free (seid);
3182 }
3183
3184 static void
3185   vl_api_one_eid_table_map_details_t_handler
3186   (vl_api_one_eid_table_map_details_t * mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189
3190   u8 *line = format (0, "%=10d%=10d",
3191                      clib_net_to_host_u32 (mp->vni),
3192                      clib_net_to_host_u32 (mp->dp_table));
3193   print (vam->ofp, "%v", line);
3194   vec_free (line);
3195 }
3196
3197 static void
3198   vl_api_one_eid_table_map_details_t_handler_json
3199   (vl_api_one_eid_table_map_details_t * mp)
3200 {
3201   vat_main_t *vam = &vat_main;
3202   vat_json_node_t *node = NULL;
3203
3204   if (VAT_JSON_ARRAY != vam->json_tree.type)
3205     {
3206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3207       vat_json_init_array (&vam->json_tree);
3208     }
3209   node = vat_json_array_add (&vam->json_tree);
3210   vat_json_init_object (node);
3211   vat_json_object_add_uint (node, "dp_table",
3212                             clib_net_to_host_u32 (mp->dp_table));
3213   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3214 }
3215
3216 static void
3217   vl_api_one_eid_table_vni_details_t_handler
3218   (vl_api_one_eid_table_vni_details_t * mp)
3219 {
3220   vat_main_t *vam = &vat_main;
3221
3222   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3223   print (vam->ofp, "%v", line);
3224   vec_free (line);
3225 }
3226
3227 static void
3228   vl_api_one_eid_table_vni_details_t_handler_json
3229   (vl_api_one_eid_table_vni_details_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t *node = NULL;
3233
3234   if (VAT_JSON_ARRAY != vam->json_tree.type)
3235     {
3236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3237       vat_json_init_array (&vam->json_tree);
3238     }
3239   node = vat_json_array_add (&vam->json_tree);
3240   vat_json_init_object (node);
3241   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3242 }
3243
3244 static void
3245   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3246   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3247 {
3248   vat_main_t *vam = &vat_main;
3249   int retval = clib_net_to_host_u32 (mp->retval);
3250
3251   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3252   print (vam->ofp, "fallback threshold value: %d", mp->value);
3253
3254   vam->retval = retval;
3255   vam->result_ready = 1;
3256 }
3257
3258 static void
3259   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3260   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   vat_json_node_t _node, *node = &_node;
3264   int retval = clib_net_to_host_u32 (mp->retval);
3265
3266   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3267   vat_json_init_object (node);
3268   vat_json_object_add_uint (node, "value", mp->value);
3269
3270   vat_json_print (vam->ofp, node);
3271   vat_json_free (node);
3272
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278   vl_api_show_one_map_register_state_reply_t_handler
3279   (vl_api_show_one_map_register_state_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288 }
3289
3290 static void
3291   vl_api_show_one_map_register_state_reply_t_handler_json
3292   (vl_api_show_one_map_register_state_reply_t * mp)
3293 {
3294   vat_main_t *vam = &vat_main;
3295   vat_json_node_t _node, *node = &_node;
3296   int retval = clib_net_to_host_u32 (mp->retval);
3297
3298   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_string_copy (node, "state", s);
3302
3303   vat_json_print (vam->ofp, node);
3304   vat_json_free (node);
3305
3306   vam->retval = retval;
3307   vam->result_ready = 1;
3308   vec_free (s);
3309 }
3310
3311 static void
3312   vl_api_show_one_rloc_probe_state_reply_t_handler
3313   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   int retval = clib_net_to_host_u32 (mp->retval);
3317
3318   if (retval)
3319     goto end;
3320
3321   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3322 end:
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325 }
3326
3327 static void
3328   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3329   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t _node, *node = &_node;
3333   int retval = clib_net_to_host_u32 (mp->retval);
3334
3335   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3336   vat_json_init_object (node);
3337   vat_json_object_add_string_copy (node, "state", s);
3338
3339   vat_json_print (vam->ofp, node);
3340   vat_json_free (node);
3341
3342   vam->retval = retval;
3343   vam->result_ready = 1;
3344   vec_free (s);
3345 }
3346
3347 static void
3348   vl_api_show_one_stats_enable_disable_reply_t_handler
3349   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   int retval = clib_net_to_host_u32 (mp->retval);
3353
3354   if (retval)
3355     goto end;
3356
3357   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3358 end:
3359   vam->retval = retval;
3360   vam->result_ready = 1;
3361 }
3362
3363 static void
3364   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3365   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3366 {
3367   vat_main_t *vam = &vat_main;
3368   vat_json_node_t _node, *node = &_node;
3369   int retval = clib_net_to_host_u32 (mp->retval);
3370
3371   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3372   vat_json_init_object (node);
3373   vat_json_object_add_string_copy (node, "state", s);
3374
3375   vat_json_print (vam->ofp, node);
3376   vat_json_free (node);
3377
3378   vam->retval = retval;
3379   vam->result_ready = 1;
3380   vec_free (s);
3381 }
3382
3383 static void
3384 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3385 {
3386   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3387   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3388   e->vni = clib_net_to_host_u32 (e->vni);
3389 }
3390
3391 static void
3392   gpe_fwd_entries_get_reply_t_net_to_host
3393   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3394 {
3395   u32 i;
3396
3397   mp->count = clib_net_to_host_u32 (mp->count);
3398   for (i = 0; i < mp->count; i++)
3399     {
3400       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3401     }
3402 }
3403
3404 static u8 *
3405 format_gpe_encap_mode (u8 * s, va_list * args)
3406 {
3407   u32 mode = va_arg (*args, u32);
3408
3409   switch (mode)
3410     {
3411     case 0:
3412       return format (s, "lisp");
3413     case 1:
3414       return format (s, "vxlan");
3415     }
3416   return 0;
3417 }
3418
3419 static void
3420   vl_api_gpe_get_encap_mode_reply_t_handler
3421   (vl_api_gpe_get_encap_mode_reply_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424
3425   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3426   vam->retval = ntohl (mp->retval);
3427   vam->result_ready = 1;
3428 }
3429
3430 static void
3431   vl_api_gpe_get_encap_mode_reply_t_handler_json
3432   (vl_api_gpe_get_encap_mode_reply_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435   vat_json_node_t node;
3436
3437   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3438   vec_add1 (encap_mode, 0);
3439
3440   vat_json_init_object (&node);
3441   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3442
3443   vec_free (encap_mode);
3444   vat_json_print (vam->ofp, &node);
3445   vat_json_free (&node);
3446
3447   vam->retval = ntohl (mp->retval);
3448   vam->result_ready = 1;
3449 }
3450
3451 static void
3452   vl_api_gpe_fwd_entry_path_details_t_handler
3453   (vl_api_gpe_fwd_entry_path_details_t * mp)
3454 {
3455   vat_main_t *vam = &vat_main;
3456   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3457
3458   if (mp->lcl_loc.is_ip4)
3459     format_ip_address_fcn = format_ip4_address;
3460   else
3461     format_ip_address_fcn = format_ip6_address;
3462
3463   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3464          format_ip_address_fcn, &mp->lcl_loc,
3465          format_ip_address_fcn, &mp->rmt_loc);
3466 }
3467
3468 static void
3469 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3470 {
3471   struct in6_addr ip6;
3472   struct in_addr ip4;
3473
3474   if (loc->is_ip4)
3475     {
3476       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3477       vat_json_object_add_ip4 (n, "address", ip4);
3478     }
3479   else
3480     {
3481       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3482       vat_json_object_add_ip6 (n, "address", ip6);
3483     }
3484   vat_json_object_add_uint (n, "weight", loc->weight);
3485 }
3486
3487 static void
3488   vl_api_gpe_fwd_entry_path_details_t_handler_json
3489   (vl_api_gpe_fwd_entry_path_details_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   vat_json_node_t *node = NULL;
3493   vat_json_node_t *loc_node;
3494
3495   if (VAT_JSON_ARRAY != vam->json_tree.type)
3496     {
3497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3498       vat_json_init_array (&vam->json_tree);
3499     }
3500   node = vat_json_array_add (&vam->json_tree);
3501   vat_json_init_object (node);
3502
3503   loc_node = vat_json_object_add (node, "local_locator");
3504   vat_json_init_object (loc_node);
3505   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3506
3507   loc_node = vat_json_object_add (node, "remote_locator");
3508   vat_json_init_object (loc_node);
3509   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3510 }
3511
3512 static void
3513   vl_api_gpe_fwd_entries_get_reply_t_handler
3514   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   u32 i;
3518   int retval = clib_net_to_host_u32 (mp->retval);
3519   vl_api_gpe_fwd_entry_t *e;
3520
3521   if (retval)
3522     goto end;
3523
3524   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3525
3526   for (i = 0; i < mp->count; i++)
3527     {
3528       e = &mp->entries[i];
3529       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3530              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3531              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3532     }
3533
3534 end:
3535   vam->retval = retval;
3536   vam->result_ready = 1;
3537 }
3538
3539 static void
3540   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3541   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3542 {
3543   u8 *s = 0;
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t *e = 0, root;
3546   u32 i;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_gpe_fwd_entry_t *fwd;
3549
3550   if (retval)
3551     goto end;
3552
3553   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3554   vat_json_init_array (&root);
3555
3556   for (i = 0; i < mp->count; i++)
3557     {
3558       e = vat_json_array_add (&root);
3559       fwd = &mp->entries[i];
3560
3561       vat_json_init_object (e);
3562       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3563       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3564       vat_json_object_add_int (e, "vni", fwd->vni);
3565       vat_json_object_add_int (e, "action", fwd->action);
3566
3567       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3568                   fwd->leid_prefix_len);
3569       vec_add1 (s, 0);
3570       vat_json_object_add_string_copy (e, "leid", s);
3571       vec_free (s);
3572
3573       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3574                   fwd->reid_prefix_len);
3575       vec_add1 (s, 0);
3576       vat_json_object_add_string_copy (e, "reid", s);
3577       vec_free (s);
3578     }
3579
3580   vat_json_print (vam->ofp, &root);
3581   vat_json_free (&root);
3582
3583 end:
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3590   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   u32 i, n;
3594   int retval = clib_net_to_host_u32 (mp->retval);
3595   vl_api_gpe_native_fwd_rpath_t *r;
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601
3602   for (i = 0; i < n; i++)
3603     {
3604       r = &mp->entries[i];
3605       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3606              clib_net_to_host_u32 (r->fib_index),
3607              clib_net_to_host_u32 (r->nh_sw_if_index),
3608              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3609     }
3610
3611 end:
3612   vam->retval = retval;
3613   vam->result_ready = 1;
3614 }
3615
3616 static void
3617   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3618   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3619 {
3620   vat_main_t *vam = &vat_main;
3621   vat_json_node_t root, *e;
3622   u32 i, n;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624   vl_api_gpe_native_fwd_rpath_t *r;
3625   u8 *s;
3626
3627   if (retval)
3628     goto end;
3629
3630   n = clib_net_to_host_u32 (mp->count);
3631   vat_json_init_array (&root);
3632
3633   for (i = 0; i < n; i++)
3634     {
3635       e = vat_json_array_add (&root);
3636       vat_json_init_object (e);
3637       r = &mp->entries[i];
3638       s =
3639         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3640                 r->nh_addr);
3641       vec_add1 (s, 0);
3642       vat_json_object_add_string_copy (e, "ip4", s);
3643       vec_free (s);
3644
3645       vat_json_object_add_uint (e, "fib_index",
3646                                 clib_net_to_host_u32 (r->fib_index));
3647       vat_json_object_add_uint (e, "nh_sw_if_index",
3648                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3649     }
3650
3651   vat_json_print (vam->ofp, &root);
3652   vat_json_free (&root);
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3661   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3662 {
3663   vat_main_t *vam = &vat_main;
3664   u32 i, n;
3665   int retval = clib_net_to_host_u32 (mp->retval);
3666
3667   if (retval)
3668     goto end;
3669
3670   n = clib_net_to_host_u32 (mp->count);
3671
3672   for (i = 0; i < n; i++)
3673     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3674
3675 end:
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3682   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   vat_json_node_t root;
3686   u32 i, n;
3687   int retval = clib_net_to_host_u32 (mp->retval);
3688
3689   if (retval)
3690     goto end;
3691
3692   n = clib_net_to_host_u32 (mp->count);
3693   vat_json_init_array (&root);
3694
3695   for (i = 0; i < n; i++)
3696     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3697
3698   vat_json_print (vam->ofp, &root);
3699   vat_json_free (&root);
3700
3701 end:
3702   vam->retval = retval;
3703   vam->result_ready = 1;
3704 }
3705
3706 static void
3707   vl_api_one_ndp_entries_get_reply_t_handler
3708   (vl_api_one_ndp_entries_get_reply_t * mp)
3709 {
3710   vat_main_t *vam = &vat_main;
3711   u32 i, n;
3712   int retval = clib_net_to_host_u32 (mp->retval);
3713
3714   if (retval)
3715     goto end;
3716
3717   n = clib_net_to_host_u32 (mp->count);
3718
3719   for (i = 0; i < n; i++)
3720     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3721            format_ethernet_address, mp->entries[i].mac);
3722
3723 end:
3724   vam->retval = retval;
3725   vam->result_ready = 1;
3726 }
3727
3728 static void
3729   vl_api_one_ndp_entries_get_reply_t_handler_json
3730   (vl_api_one_ndp_entries_get_reply_t * mp)
3731 {
3732   u8 *s = 0;
3733   vat_main_t *vam = &vat_main;
3734   vat_json_node_t *e = 0, root;
3735   u32 i, n;
3736   int retval = clib_net_to_host_u32 (mp->retval);
3737   vl_api_one_ndp_entry_t *arp_entry;
3738
3739   if (retval)
3740     goto end;
3741
3742   n = clib_net_to_host_u32 (mp->count);
3743   vat_json_init_array (&root);
3744
3745   for (i = 0; i < n; i++)
3746     {
3747       e = vat_json_array_add (&root);
3748       arp_entry = &mp->entries[i];
3749
3750       vat_json_init_object (e);
3751       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3752       vec_add1 (s, 0);
3753
3754       vat_json_object_add_string_copy (e, "mac", s);
3755       vec_free (s);
3756
3757       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3758       vec_add1 (s, 0);
3759       vat_json_object_add_string_copy (e, "ip6", s);
3760       vec_free (s);
3761     }
3762
3763   vat_json_print (vam->ofp, &root);
3764   vat_json_free (&root);
3765
3766 end:
3767   vam->retval = retval;
3768   vam->result_ready = 1;
3769 }
3770
3771 static void
3772   vl_api_one_l2_arp_entries_get_reply_t_handler
3773   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   u32 i, n;
3777   int retval = clib_net_to_host_u32 (mp->retval);
3778
3779   if (retval)
3780     goto end;
3781
3782   n = clib_net_to_host_u32 (mp->count);
3783
3784   for (i = 0; i < n; i++)
3785     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3786            format_ethernet_address, mp->entries[i].mac);
3787
3788 end:
3789   vam->retval = retval;
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3795   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3796 {
3797   u8 *s = 0;
3798   vat_main_t *vam = &vat_main;
3799   vat_json_node_t *e = 0, root;
3800   u32 i, n;
3801   int retval = clib_net_to_host_u32 (mp->retval);
3802   vl_api_one_l2_arp_entry_t *arp_entry;
3803
3804   if (retval)
3805     goto end;
3806
3807   n = clib_net_to_host_u32 (mp->count);
3808   vat_json_init_array (&root);
3809
3810   for (i = 0; i < n; i++)
3811     {
3812       e = vat_json_array_add (&root);
3813       arp_entry = &mp->entries[i];
3814
3815       vat_json_init_object (e);
3816       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3817       vec_add1 (s, 0);
3818
3819       vat_json_object_add_string_copy (e, "mac", s);
3820       vec_free (s);
3821
3822       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3823       vec_add1 (s, 0);
3824       vat_json_object_add_string_copy (e, "ip4", s);
3825       vec_free (s);
3826     }
3827
3828   vat_json_print (vam->ofp, &root);
3829   vat_json_free (&root);
3830
3831 end:
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3838 {
3839   vat_main_t *vam = &vat_main;
3840   u32 i, n;
3841   int retval = clib_net_to_host_u32 (mp->retval);
3842
3843   if (retval)
3844     goto end;
3845
3846   n = clib_net_to_host_u32 (mp->count);
3847
3848   for (i = 0; i < n; i++)
3849     {
3850       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3851     }
3852
3853 end:
3854   vam->retval = retval;
3855   vam->result_ready = 1;
3856 }
3857
3858 static void
3859   vl_api_one_ndp_bd_get_reply_t_handler_json
3860   (vl_api_one_ndp_bd_get_reply_t * mp)
3861 {
3862   vat_main_t *vam = &vat_main;
3863   vat_json_node_t root;
3864   u32 i, n;
3865   int retval = clib_net_to_host_u32 (mp->retval);
3866
3867   if (retval)
3868     goto end;
3869
3870   n = clib_net_to_host_u32 (mp->count);
3871   vat_json_init_array (&root);
3872
3873   for (i = 0; i < n; i++)
3874     {
3875       vat_json_array_add_uint (&root,
3876                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3877     }
3878
3879   vat_json_print (vam->ofp, &root);
3880   vat_json_free (&root);
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_l2_arp_bd_get_reply_t_handler
3889   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3890 {
3891   vat_main_t *vam = &vat_main;
3892   u32 i, n;
3893   int retval = clib_net_to_host_u32 (mp->retval);
3894
3895   if (retval)
3896     goto end;
3897
3898   n = clib_net_to_host_u32 (mp->count);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3903     }
3904
3905 end:
3906   vam->retval = retval;
3907   vam->result_ready = 1;
3908 }
3909
3910 static void
3911   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3912   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3913 {
3914   vat_main_t *vam = &vat_main;
3915   vat_json_node_t root;
3916   u32 i, n;
3917   int retval = clib_net_to_host_u32 (mp->retval);
3918
3919   if (retval)
3920     goto end;
3921
3922   n = clib_net_to_host_u32 (mp->count);
3923   vat_json_init_array (&root);
3924
3925   for (i = 0; i < n; i++)
3926     {
3927       vat_json_array_add_uint (&root,
3928                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3929     }
3930
3931   vat_json_print (vam->ofp, &root);
3932   vat_json_free (&root);
3933
3934 end:
3935   vam->retval = retval;
3936   vam->result_ready = 1;
3937 }
3938
3939 static void
3940   vl_api_one_adjacencies_get_reply_t_handler
3941   (vl_api_one_adjacencies_get_reply_t * mp)
3942 {
3943   vat_main_t *vam = &vat_main;
3944   u32 i, n;
3945   int retval = clib_net_to_host_u32 (mp->retval);
3946   vl_api_one_adjacency_t *a;
3947
3948   if (retval)
3949     goto end;
3950
3951   n = clib_net_to_host_u32 (mp->count);
3952
3953   for (i = 0; i < n; i++)
3954     {
3955       a = &mp->adjacencies[i];
3956       print (vam->ofp, "%U %40U",
3957              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3958              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3959     }
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_adjacencies_get_reply_t_handler_json
3968   (vl_api_one_adjacencies_get_reply_t * mp)
3969 {
3970   u8 *s = 0;
3971   vat_main_t *vam = &vat_main;
3972   vat_json_node_t *e = 0, root;
3973   u32 i, n;
3974   int retval = clib_net_to_host_u32 (mp->retval);
3975   vl_api_one_adjacency_t *a;
3976
3977   if (retval)
3978     goto end;
3979
3980   n = clib_net_to_host_u32 (mp->count);
3981   vat_json_init_array (&root);
3982
3983   for (i = 0; i < n; i++)
3984     {
3985       e = vat_json_array_add (&root);
3986       a = &mp->adjacencies[i];
3987
3988       vat_json_init_object (e);
3989       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3990                   a->leid_prefix_len);
3991       vec_add1 (s, 0);
3992       vat_json_object_add_string_copy (e, "leid", s);
3993       vec_free (s);
3994
3995       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3996                   a->reid_prefix_len);
3997       vec_add1 (s, 0);
3998       vat_json_object_add_string_copy (e, "reid", s);
3999       vec_free (s);
4000     }
4001
4002   vat_json_print (vam->ofp, &root);
4003   vat_json_free (&root);
4004
4005 end:
4006   vam->retval = retval;
4007   vam->result_ready = 1;
4008 }
4009
4010 static void
4011 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4012 {
4013   vat_main_t *vam = &vat_main;
4014
4015   print (vam->ofp, "%=20U",
4016          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4017          mp->ip_address);
4018 }
4019
4020 static void
4021   vl_api_one_map_server_details_t_handler_json
4022   (vl_api_one_map_server_details_t * mp)
4023 {
4024   vat_main_t *vam = &vat_main;
4025   vat_json_node_t *node = NULL;
4026   struct in6_addr ip6;
4027   struct in_addr ip4;
4028
4029   if (VAT_JSON_ARRAY != vam->json_tree.type)
4030     {
4031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4032       vat_json_init_array (&vam->json_tree);
4033     }
4034   node = vat_json_array_add (&vam->json_tree);
4035
4036   vat_json_init_object (node);
4037   if (mp->is_ipv6)
4038     {
4039       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4040       vat_json_object_add_ip6 (node, "map-server", ip6);
4041     }
4042   else
4043     {
4044       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4045       vat_json_object_add_ip4 (node, "map-server", ip4);
4046     }
4047 }
4048
4049 static void
4050 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4051                                            * mp)
4052 {
4053   vat_main_t *vam = &vat_main;
4054
4055   print (vam->ofp, "%=20U",
4056          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4057          mp->ip_address);
4058 }
4059
4060 static void
4061   vl_api_one_map_resolver_details_t_handler_json
4062   (vl_api_one_map_resolver_details_t * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065   vat_json_node_t *node = NULL;
4066   struct in6_addr ip6;
4067   struct in_addr ip4;
4068
4069   if (VAT_JSON_ARRAY != vam->json_tree.type)
4070     {
4071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4072       vat_json_init_array (&vam->json_tree);
4073     }
4074   node = vat_json_array_add (&vam->json_tree);
4075
4076   vat_json_init_object (node);
4077   if (mp->is_ipv6)
4078     {
4079       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4080       vat_json_object_add_ip6 (node, "map resolver", ip6);
4081     }
4082   else
4083     {
4084       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4085       vat_json_object_add_ip4 (node, "map resolver", ip4);
4086     }
4087 }
4088
4089 static void
4090 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   i32 retval = ntohl (mp->retval);
4094
4095   if (0 <= retval)
4096     {
4097       print (vam->ofp, "feature: %s\ngpe: %s",
4098              mp->feature_status ? "enabled" : "disabled",
4099              mp->gpe_status ? "enabled" : "disabled");
4100     }
4101
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_show_one_status_reply_t_handler_json
4108   (vl_api_show_one_status_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t node;
4112   u8 *gpe_status = NULL;
4113   u8 *feature_status = NULL;
4114
4115   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4116   feature_status = format (0, "%s",
4117                            mp->feature_status ? "enabled" : "disabled");
4118   vec_add1 (gpe_status, 0);
4119   vec_add1 (feature_status, 0);
4120
4121   vat_json_init_object (&node);
4122   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4123   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4124
4125   vec_free (gpe_status);
4126   vec_free (feature_status);
4127
4128   vat_json_print (vam->ofp, &node);
4129   vat_json_free (&node);
4130
4131   vam->retval = ntohl (mp->retval);
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4137   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   i32 retval = ntohl (mp->retval);
4141
4142   if (retval >= 0)
4143     {
4144       print (vam->ofp, "%=20s", mp->locator_set_name);
4145     }
4146
4147   vam->retval = retval;
4148   vam->result_ready = 1;
4149 }
4150
4151 static void
4152   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4153   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4154 {
4155   vat_main_t *vam = &vat_main;
4156   vat_json_node_t *node = NULL;
4157
4158   if (VAT_JSON_ARRAY != vam->json_tree.type)
4159     {
4160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4161       vat_json_init_array (&vam->json_tree);
4162     }
4163   node = vat_json_array_add (&vam->json_tree);
4164
4165   vat_json_init_object (node);
4166   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4167
4168   vat_json_print (vam->ofp, node);
4169   vat_json_free (node);
4170
4171   vam->retval = ntohl (mp->retval);
4172   vam->result_ready = 1;
4173 }
4174
4175 static u8 *
4176 format_lisp_map_request_mode (u8 * s, va_list * args)
4177 {
4178   u32 mode = va_arg (*args, u32);
4179
4180   switch (mode)
4181     {
4182     case 0:
4183       return format (0, "dst-only");
4184     case 1:
4185       return format (0, "src-dst");
4186     }
4187   return 0;
4188 }
4189
4190 static void
4191   vl_api_show_one_map_request_mode_reply_t_handler
4192   (vl_api_show_one_map_request_mode_reply_t * mp)
4193 {
4194   vat_main_t *vam = &vat_main;
4195   i32 retval = ntohl (mp->retval);
4196
4197   if (0 <= retval)
4198     {
4199       u32 mode = mp->mode;
4200       print (vam->ofp, "map_request_mode: %U",
4201              format_lisp_map_request_mode, mode);
4202     }
4203
4204   vam->retval = retval;
4205   vam->result_ready = 1;
4206 }
4207
4208 static void
4209   vl_api_show_one_map_request_mode_reply_t_handler_json
4210   (vl_api_show_one_map_request_mode_reply_t * mp)
4211 {
4212   vat_main_t *vam = &vat_main;
4213   vat_json_node_t node;
4214   u8 *s = 0;
4215   u32 mode;
4216
4217   mode = mp->mode;
4218   s = format (0, "%U", format_lisp_map_request_mode, mode);
4219   vec_add1 (s, 0);
4220
4221   vat_json_init_object (&node);
4222   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4223   vat_json_print (vam->ofp, &node);
4224   vat_json_free (&node);
4225
4226   vec_free (s);
4227   vam->retval = ntohl (mp->retval);
4228   vam->result_ready = 1;
4229 }
4230
4231 static void
4232   vl_api_one_show_xtr_mode_reply_t_handler
4233   (vl_api_one_show_xtr_mode_reply_t * mp)
4234 {
4235   vat_main_t *vam = &vat_main;
4236   i32 retval = ntohl (mp->retval);
4237
4238   if (0 <= retval)
4239     {
4240       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4241     }
4242
4243   vam->retval = retval;
4244   vam->result_ready = 1;
4245 }
4246
4247 static void
4248   vl_api_one_show_xtr_mode_reply_t_handler_json
4249   (vl_api_one_show_xtr_mode_reply_t * mp)
4250 {
4251   vat_main_t *vam = &vat_main;
4252   vat_json_node_t node;
4253   u8 *status = 0;
4254
4255   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4256   vec_add1 (status, 0);
4257
4258   vat_json_init_object (&node);
4259   vat_json_object_add_string_copy (&node, "status", status);
4260
4261   vec_free (status);
4262
4263   vat_json_print (vam->ofp, &node);
4264   vat_json_free (&node);
4265
4266   vam->retval = ntohl (mp->retval);
4267   vam->result_ready = 1;
4268 }
4269
4270 static void
4271   vl_api_one_show_pitr_mode_reply_t_handler
4272   (vl_api_one_show_pitr_mode_reply_t * mp)
4273 {
4274   vat_main_t *vam = &vat_main;
4275   i32 retval = ntohl (mp->retval);
4276
4277   if (0 <= retval)
4278     {
4279       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4280     }
4281
4282   vam->retval = retval;
4283   vam->result_ready = 1;
4284 }
4285
4286 static void
4287   vl_api_one_show_pitr_mode_reply_t_handler_json
4288   (vl_api_one_show_pitr_mode_reply_t * mp)
4289 {
4290   vat_main_t *vam = &vat_main;
4291   vat_json_node_t node;
4292   u8 *status = 0;
4293
4294   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4295   vec_add1 (status, 0);
4296
4297   vat_json_init_object (&node);
4298   vat_json_object_add_string_copy (&node, "status", status);
4299
4300   vec_free (status);
4301
4302   vat_json_print (vam->ofp, &node);
4303   vat_json_free (&node);
4304
4305   vam->retval = ntohl (mp->retval);
4306   vam->result_ready = 1;
4307 }
4308
4309 static void
4310   vl_api_one_show_petr_mode_reply_t_handler
4311   (vl_api_one_show_petr_mode_reply_t * mp)
4312 {
4313   vat_main_t *vam = &vat_main;
4314   i32 retval = ntohl (mp->retval);
4315
4316   if (0 <= retval)
4317     {
4318       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4319     }
4320
4321   vam->retval = retval;
4322   vam->result_ready = 1;
4323 }
4324
4325 static void
4326   vl_api_one_show_petr_mode_reply_t_handler_json
4327   (vl_api_one_show_petr_mode_reply_t * mp)
4328 {
4329   vat_main_t *vam = &vat_main;
4330   vat_json_node_t node;
4331   u8 *status = 0;
4332
4333   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4334   vec_add1 (status, 0);
4335
4336   vat_json_init_object (&node);
4337   vat_json_object_add_string_copy (&node, "status", status);
4338
4339   vec_free (status);
4340
4341   vat_json_print (vam->ofp, &node);
4342   vat_json_free (&node);
4343
4344   vam->retval = ntohl (mp->retval);
4345   vam->result_ready = 1;
4346 }
4347
4348 static void
4349   vl_api_show_one_use_petr_reply_t_handler
4350   (vl_api_show_one_use_petr_reply_t * mp)
4351 {
4352   vat_main_t *vam = &vat_main;
4353   i32 retval = ntohl (mp->retval);
4354
4355   if (0 <= retval)
4356     {
4357       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4358       if (mp->status)
4359         {
4360           print (vam->ofp, "Proxy-ETR address; %U",
4361                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4362                  mp->address);
4363         }
4364     }
4365
4366   vam->retval = retval;
4367   vam->result_ready = 1;
4368 }
4369
4370 static void
4371   vl_api_show_one_use_petr_reply_t_handler_json
4372   (vl_api_show_one_use_petr_reply_t * mp)
4373 {
4374   vat_main_t *vam = &vat_main;
4375   vat_json_node_t node;
4376   u8 *status = 0;
4377   struct in_addr ip4;
4378   struct in6_addr ip6;
4379
4380   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4381   vec_add1 (status, 0);
4382
4383   vat_json_init_object (&node);
4384   vat_json_object_add_string_copy (&node, "status", status);
4385   if (mp->status)
4386     {
4387       if (mp->is_ip4)
4388         {
4389           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4390           vat_json_object_add_ip6 (&node, "address", ip6);
4391         }
4392       else
4393         {
4394           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4395           vat_json_object_add_ip4 (&node, "address", ip4);
4396         }
4397     }
4398
4399   vec_free (status);
4400
4401   vat_json_print (vam->ofp, &node);
4402   vat_json_free (&node);
4403
4404   vam->retval = ntohl (mp->retval);
4405   vam->result_ready = 1;
4406 }
4407
4408 static void
4409   vl_api_show_one_nsh_mapping_reply_t_handler
4410   (vl_api_show_one_nsh_mapping_reply_t * mp)
4411 {
4412   vat_main_t *vam = &vat_main;
4413   i32 retval = ntohl (mp->retval);
4414
4415   if (0 <= retval)
4416     {
4417       print (vam->ofp, "%-20s%-16s",
4418              mp->is_set ? "set" : "not-set",
4419              mp->is_set ? (char *) mp->locator_set_name : "");
4420     }
4421
4422   vam->retval = retval;
4423   vam->result_ready = 1;
4424 }
4425
4426 static void
4427   vl_api_show_one_nsh_mapping_reply_t_handler_json
4428   (vl_api_show_one_nsh_mapping_reply_t * mp)
4429 {
4430   vat_main_t *vam = &vat_main;
4431   vat_json_node_t node;
4432   u8 *status = 0;
4433
4434   status = format (0, "%s", mp->is_set ? "yes" : "no");
4435   vec_add1 (status, 0);
4436
4437   vat_json_init_object (&node);
4438   vat_json_object_add_string_copy (&node, "is_set", status);
4439   if (mp->is_set)
4440     {
4441       vat_json_object_add_string_copy (&node, "locator_set",
4442                                        mp->locator_set_name);
4443     }
4444
4445   vec_free (status);
4446
4447   vat_json_print (vam->ofp, &node);
4448   vat_json_free (&node);
4449
4450   vam->retval = ntohl (mp->retval);
4451   vam->result_ready = 1;
4452 }
4453
4454 static void
4455   vl_api_show_one_map_register_ttl_reply_t_handler
4456   (vl_api_show_one_map_register_ttl_reply_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459   i32 retval = ntohl (mp->retval);
4460
4461   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4462
4463   if (0 <= retval)
4464     {
4465       print (vam->ofp, "ttl: %u", mp->ttl);
4466     }
4467
4468   vam->retval = retval;
4469   vam->result_ready = 1;
4470 }
4471
4472 static void
4473   vl_api_show_one_map_register_ttl_reply_t_handler_json
4474   (vl_api_show_one_map_register_ttl_reply_t * mp)
4475 {
4476   vat_main_t *vam = &vat_main;
4477   vat_json_node_t node;
4478
4479   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4480   vat_json_init_object (&node);
4481   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4482
4483   vat_json_print (vam->ofp, &node);
4484   vat_json_free (&node);
4485
4486   vam->retval = ntohl (mp->retval);
4487   vam->result_ready = 1;
4488 }
4489
4490 static void
4491 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4492 {
4493   vat_main_t *vam = &vat_main;
4494   i32 retval = ntohl (mp->retval);
4495
4496   if (0 <= retval)
4497     {
4498       print (vam->ofp, "%-20s%-16s",
4499              mp->status ? "enabled" : "disabled",
4500              mp->status ? (char *) mp->locator_set_name : "");
4501     }
4502
4503   vam->retval = retval;
4504   vam->result_ready = 1;
4505 }
4506
4507 static void
4508 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4509 {
4510   vat_main_t *vam = &vat_main;
4511   vat_json_node_t node;
4512   u8 *status = 0;
4513
4514   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4515   vec_add1 (status, 0);
4516
4517   vat_json_init_object (&node);
4518   vat_json_object_add_string_copy (&node, "status", status);
4519   if (mp->status)
4520     {
4521       vat_json_object_add_string_copy (&node, "locator_set",
4522                                        mp->locator_set_name);
4523     }
4524
4525   vec_free (status);
4526
4527   vat_json_print (vam->ofp, &node);
4528   vat_json_free (&node);
4529
4530   vam->retval = ntohl (mp->retval);
4531   vam->result_ready = 1;
4532 }
4533
4534 static u8 *
4535 format_policer_type (u8 * s, va_list * va)
4536 {
4537   u32 i = va_arg (*va, u32);
4538
4539   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4540     s = format (s, "1r2c");
4541   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4542     s = format (s, "1r3c");
4543   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4544     s = format (s, "2r3c-2698");
4545   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4546     s = format (s, "2r3c-4115");
4547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4548     s = format (s, "2r3c-mef5cf1");
4549   else
4550     s = format (s, "ILLEGAL");
4551   return s;
4552 }
4553
4554 static u8 *
4555 format_policer_rate_type (u8 * s, va_list * va)
4556 {
4557   u32 i = va_arg (*va, u32);
4558
4559   if (i == SSE2_QOS_RATE_KBPS)
4560     s = format (s, "kbps");
4561   else if (i == SSE2_QOS_RATE_PPS)
4562     s = format (s, "pps");
4563   else
4564     s = format (s, "ILLEGAL");
4565   return s;
4566 }
4567
4568 static u8 *
4569 format_policer_round_type (u8 * s, va_list * va)
4570 {
4571   u32 i = va_arg (*va, u32);
4572
4573   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4574     s = format (s, "closest");
4575   else if (i == SSE2_QOS_ROUND_TO_UP)
4576     s = format (s, "up");
4577   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4578     s = format (s, "down");
4579   else
4580     s = format (s, "ILLEGAL");
4581   return s;
4582 }
4583
4584 static u8 *
4585 format_policer_action_type (u8 * s, va_list * va)
4586 {
4587   u32 i = va_arg (*va, u32);
4588
4589   if (i == SSE2_QOS_ACTION_DROP)
4590     s = format (s, "drop");
4591   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4592     s = format (s, "transmit");
4593   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4594     s = format (s, "mark-and-transmit");
4595   else
4596     s = format (s, "ILLEGAL");
4597   return s;
4598 }
4599
4600 static u8 *
4601 format_dscp (u8 * s, va_list * va)
4602 {
4603   u32 i = va_arg (*va, u32);
4604   char *t = 0;
4605
4606   switch (i)
4607     {
4608 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4609       foreach_vnet_dscp
4610 #undef _
4611     default:
4612       return format (s, "ILLEGAL");
4613     }
4614   s = format (s, "%s", t);
4615   return s;
4616 }
4617
4618 static void
4619 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4620 {
4621   vat_main_t *vam = &vat_main;
4622   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4623
4624   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4625     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4626   else
4627     conform_dscp_str = format (0, "");
4628
4629   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4630     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4631   else
4632     exceed_dscp_str = format (0, "");
4633
4634   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4635     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4636   else
4637     violate_dscp_str = format (0, "");
4638
4639   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4640          "rate type %U, round type %U, %s rate, %s color-aware, "
4641          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4642          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4643          "conform action %U%s, exceed action %U%s, violate action %U%s",
4644          mp->name,
4645          format_policer_type, mp->type,
4646          ntohl (mp->cir),
4647          ntohl (mp->eir),
4648          clib_net_to_host_u64 (mp->cb),
4649          clib_net_to_host_u64 (mp->eb),
4650          format_policer_rate_type, mp->rate_type,
4651          format_policer_round_type, mp->round_type,
4652          mp->single_rate ? "single" : "dual",
4653          mp->color_aware ? "is" : "not",
4654          ntohl (mp->cir_tokens_per_period),
4655          ntohl (mp->pir_tokens_per_period),
4656          ntohl (mp->scale),
4657          ntohl (mp->current_limit),
4658          ntohl (mp->current_bucket),
4659          ntohl (mp->extended_limit),
4660          ntohl (mp->extended_bucket),
4661          clib_net_to_host_u64 (mp->last_update_time),
4662          format_policer_action_type, mp->conform_action_type,
4663          conform_dscp_str,
4664          format_policer_action_type, mp->exceed_action_type,
4665          exceed_dscp_str,
4666          format_policer_action_type, mp->violate_action_type,
4667          violate_dscp_str);
4668
4669   vec_free (conform_dscp_str);
4670   vec_free (exceed_dscp_str);
4671   vec_free (violate_dscp_str);
4672 }
4673
4674 static void vl_api_policer_details_t_handler_json
4675   (vl_api_policer_details_t * mp)
4676 {
4677   vat_main_t *vam = &vat_main;
4678   vat_json_node_t *node;
4679   u8 *rate_type_str, *round_type_str, *type_str;
4680   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4681
4682   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4683   round_type_str =
4684     format (0, "%U", format_policer_round_type, mp->round_type);
4685   type_str = format (0, "%U", format_policer_type, mp->type);
4686   conform_action_str = format (0, "%U", format_policer_action_type,
4687                                mp->conform_action_type);
4688   exceed_action_str = format (0, "%U", format_policer_action_type,
4689                               mp->exceed_action_type);
4690   violate_action_str = format (0, "%U", format_policer_action_type,
4691                                mp->violate_action_type);
4692
4693   if (VAT_JSON_ARRAY != vam->json_tree.type)
4694     {
4695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4696       vat_json_init_array (&vam->json_tree);
4697     }
4698   node = vat_json_array_add (&vam->json_tree);
4699
4700   vat_json_init_object (node);
4701   vat_json_object_add_string_copy (node, "name", mp->name);
4702   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4703   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4704   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4705   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4706   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4707   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4708   vat_json_object_add_string_copy (node, "type", type_str);
4709   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4710   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4711   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4712   vat_json_object_add_uint (node, "cir_tokens_per_period",
4713                             ntohl (mp->cir_tokens_per_period));
4714   vat_json_object_add_uint (node, "eir_tokens_per_period",
4715                             ntohl (mp->pir_tokens_per_period));
4716   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4717   vat_json_object_add_uint (node, "current_bucket",
4718                             ntohl (mp->current_bucket));
4719   vat_json_object_add_uint (node, "extended_limit",
4720                             ntohl (mp->extended_limit));
4721   vat_json_object_add_uint (node, "extended_bucket",
4722                             ntohl (mp->extended_bucket));
4723   vat_json_object_add_uint (node, "last_update_time",
4724                             ntohl (mp->last_update_time));
4725   vat_json_object_add_string_copy (node, "conform_action",
4726                                    conform_action_str);
4727   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4728     {
4729       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4730       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4731       vec_free (dscp_str);
4732     }
4733   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4734   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4735     {
4736       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4737       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4738       vec_free (dscp_str);
4739     }
4740   vat_json_object_add_string_copy (node, "violate_action",
4741                                    violate_action_str);
4742   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4743     {
4744       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4745       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4746       vec_free (dscp_str);
4747     }
4748
4749   vec_free (rate_type_str);
4750   vec_free (round_type_str);
4751   vec_free (type_str);
4752   vec_free (conform_action_str);
4753   vec_free (exceed_action_str);
4754   vec_free (violate_action_str);
4755 }
4756
4757 static void
4758 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4759                                            mp)
4760 {
4761   vat_main_t *vam = &vat_main;
4762   int i, count = ntohl (mp->count);
4763
4764   if (count > 0)
4765     print (vam->ofp, "classify table ids (%d) : ", count);
4766   for (i = 0; i < count; i++)
4767     {
4768       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4769       print (vam->ofp, (i < count - 1) ? "," : "");
4770     }
4771   vam->retval = ntohl (mp->retval);
4772   vam->result_ready = 1;
4773 }
4774
4775 static void
4776   vl_api_classify_table_ids_reply_t_handler_json
4777   (vl_api_classify_table_ids_reply_t * mp)
4778 {
4779   vat_main_t *vam = &vat_main;
4780   int i, count = ntohl (mp->count);
4781
4782   if (count > 0)
4783     {
4784       vat_json_node_t node;
4785
4786       vat_json_init_object (&node);
4787       for (i = 0; i < count; i++)
4788         {
4789           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4790         }
4791       vat_json_print (vam->ofp, &node);
4792       vat_json_free (&node);
4793     }
4794   vam->retval = ntohl (mp->retval);
4795   vam->result_ready = 1;
4796 }
4797
4798 static void
4799   vl_api_classify_table_by_interface_reply_t_handler
4800   (vl_api_classify_table_by_interface_reply_t * mp)
4801 {
4802   vat_main_t *vam = &vat_main;
4803   u32 table_id;
4804
4805   table_id = ntohl (mp->l2_table_id);
4806   if (table_id != ~0)
4807     print (vam->ofp, "l2 table id : %d", table_id);
4808   else
4809     print (vam->ofp, "l2 table id : No input ACL tables configured");
4810   table_id = ntohl (mp->ip4_table_id);
4811   if (table_id != ~0)
4812     print (vam->ofp, "ip4 table id : %d", table_id);
4813   else
4814     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4815   table_id = ntohl (mp->ip6_table_id);
4816   if (table_id != ~0)
4817     print (vam->ofp, "ip6 table id : %d", table_id);
4818   else
4819     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4820   vam->retval = ntohl (mp->retval);
4821   vam->result_ready = 1;
4822 }
4823
4824 static void
4825   vl_api_classify_table_by_interface_reply_t_handler_json
4826   (vl_api_classify_table_by_interface_reply_t * mp)
4827 {
4828   vat_main_t *vam = &vat_main;
4829   vat_json_node_t node;
4830
4831   vat_json_init_object (&node);
4832
4833   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4834   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4835   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4836
4837   vat_json_print (vam->ofp, &node);
4838   vat_json_free (&node);
4839
4840   vam->retval = ntohl (mp->retval);
4841   vam->result_ready = 1;
4842 }
4843
4844 static void vl_api_policer_add_del_reply_t_handler
4845   (vl_api_policer_add_del_reply_t * mp)
4846 {
4847   vat_main_t *vam = &vat_main;
4848   i32 retval = ntohl (mp->retval);
4849   if (vam->async_mode)
4850     {
4851       vam->async_errors += (retval < 0);
4852     }
4853   else
4854     {
4855       vam->retval = retval;
4856       vam->result_ready = 1;
4857       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4858         /*
4859          * Note: this is just barely thread-safe, depends on
4860          * the main thread spinning waiting for an answer...
4861          */
4862         errmsg ("policer index %d", ntohl (mp->policer_index));
4863     }
4864 }
4865
4866 static void vl_api_policer_add_del_reply_t_handler_json
4867   (vl_api_policer_add_del_reply_t * mp)
4868 {
4869   vat_main_t *vam = &vat_main;
4870   vat_json_node_t node;
4871
4872   vat_json_init_object (&node);
4873   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4874   vat_json_object_add_uint (&node, "policer_index",
4875                             ntohl (mp->policer_index));
4876
4877   vat_json_print (vam->ofp, &node);
4878   vat_json_free (&node);
4879
4880   vam->retval = ntohl (mp->retval);
4881   vam->result_ready = 1;
4882 }
4883
4884 /* Format hex dump. */
4885 u8 *
4886 format_hex_bytes (u8 * s, va_list * va)
4887 {
4888   u8 *bytes = va_arg (*va, u8 *);
4889   int n_bytes = va_arg (*va, int);
4890   uword i;
4891
4892   /* Print short or long form depending on byte count. */
4893   uword short_form = n_bytes <= 32;
4894   u32 indent = format_get_indent (s);
4895
4896   if (n_bytes == 0)
4897     return s;
4898
4899   for (i = 0; i < n_bytes; i++)
4900     {
4901       if (!short_form && (i % 32) == 0)
4902         s = format (s, "%08x: ", i);
4903       s = format (s, "%02x", bytes[i]);
4904       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4905         s = format (s, "\n%U", format_white_space, indent);
4906     }
4907
4908   return s;
4909 }
4910
4911 static void
4912 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4913                                             * mp)
4914 {
4915   vat_main_t *vam = &vat_main;
4916   i32 retval = ntohl (mp->retval);
4917   if (retval == 0)
4918     {
4919       print (vam->ofp, "classify table info :");
4920       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4921              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4922              ntohl (mp->miss_next_index));
4923       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4924              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4925              ntohl (mp->match_n_vectors));
4926       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4927              ntohl (mp->mask_length));
4928     }
4929   vam->retval = retval;
4930   vam->result_ready = 1;
4931 }
4932
4933 static void
4934   vl_api_classify_table_info_reply_t_handler_json
4935   (vl_api_classify_table_info_reply_t * mp)
4936 {
4937   vat_main_t *vam = &vat_main;
4938   vat_json_node_t node;
4939
4940   i32 retval = ntohl (mp->retval);
4941   if (retval == 0)
4942     {
4943       vat_json_init_object (&node);
4944
4945       vat_json_object_add_int (&node, "sessions",
4946                                ntohl (mp->active_sessions));
4947       vat_json_object_add_int (&node, "nexttbl",
4948                                ntohl (mp->next_table_index));
4949       vat_json_object_add_int (&node, "nextnode",
4950                                ntohl (mp->miss_next_index));
4951       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4952       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4953       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4954       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4955                       ntohl (mp->mask_length), 0);
4956       vat_json_object_add_string_copy (&node, "mask", s);
4957
4958       vat_json_print (vam->ofp, &node);
4959       vat_json_free (&node);
4960     }
4961   vam->retval = ntohl (mp->retval);
4962   vam->result_ready = 1;
4963 }
4964
4965 static void
4966 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4967                                            mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970
4971   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4972          ntohl (mp->hit_next_index), ntohl (mp->advance),
4973          ntohl (mp->opaque_index));
4974   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4975          ntohl (mp->match_length));
4976 }
4977
4978 static void
4979   vl_api_classify_session_details_t_handler_json
4980   (vl_api_classify_session_details_t * mp)
4981 {
4982   vat_main_t *vam = &vat_main;
4983   vat_json_node_t *node = NULL;
4984
4985   if (VAT_JSON_ARRAY != vam->json_tree.type)
4986     {
4987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4988       vat_json_init_array (&vam->json_tree);
4989     }
4990   node = vat_json_array_add (&vam->json_tree);
4991
4992   vat_json_init_object (node);
4993   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4994   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4995   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4996   u8 *s =
4997     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4998             0);
4999   vat_json_object_add_string_copy (node, "match", s);
5000 }
5001
5002 static void vl_api_pg_create_interface_reply_t_handler
5003   (vl_api_pg_create_interface_reply_t * mp)
5004 {
5005   vat_main_t *vam = &vat_main;
5006
5007   vam->retval = ntohl (mp->retval);
5008   vam->result_ready = 1;
5009 }
5010
5011 static void vl_api_pg_create_interface_reply_t_handler_json
5012   (vl_api_pg_create_interface_reply_t * mp)
5013 {
5014   vat_main_t *vam = &vat_main;
5015   vat_json_node_t node;
5016
5017   i32 retval = ntohl (mp->retval);
5018   if (retval == 0)
5019     {
5020       vat_json_init_object (&node);
5021
5022       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5023
5024       vat_json_print (vam->ofp, &node);
5025       vat_json_free (&node);
5026     }
5027   vam->retval = ntohl (mp->retval);
5028   vam->result_ready = 1;
5029 }
5030
5031 static void vl_api_policer_classify_details_t_handler
5032   (vl_api_policer_classify_details_t * mp)
5033 {
5034   vat_main_t *vam = &vat_main;
5035
5036   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5037          ntohl (mp->table_index));
5038 }
5039
5040 static void vl_api_policer_classify_details_t_handler_json
5041   (vl_api_policer_classify_details_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   vat_json_node_t *node;
5045
5046   if (VAT_JSON_ARRAY != vam->json_tree.type)
5047     {
5048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5049       vat_json_init_array (&vam->json_tree);
5050     }
5051   node = vat_json_array_add (&vam->json_tree);
5052
5053   vat_json_init_object (node);
5054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5055   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5056 }
5057
5058 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5059   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062   i32 retval = ntohl (mp->retval);
5063   if (vam->async_mode)
5064     {
5065       vam->async_errors += (retval < 0);
5066     }
5067   else
5068     {
5069       vam->retval = retval;
5070       vam->sw_if_index = ntohl (mp->sw_if_index);
5071       vam->result_ready = 1;
5072     }
5073   vam->regenerate_interface_table = 1;
5074 }
5075
5076 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5077   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5078 {
5079   vat_main_t *vam = &vat_main;
5080   vat_json_node_t node;
5081
5082   vat_json_init_object (&node);
5083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5084   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5085
5086   vat_json_print (vam->ofp, &node);
5087   vat_json_free (&node);
5088
5089   vam->retval = ntohl (mp->retval);
5090   vam->result_ready = 1;
5091 }
5092
5093 static void vl_api_flow_classify_details_t_handler
5094   (vl_api_flow_classify_details_t * mp)
5095 {
5096   vat_main_t *vam = &vat_main;
5097
5098   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5099          ntohl (mp->table_index));
5100 }
5101
5102 static void vl_api_flow_classify_details_t_handler_json
5103   (vl_api_flow_classify_details_t * mp)
5104 {
5105   vat_main_t *vam = &vat_main;
5106   vat_json_node_t *node;
5107
5108   if (VAT_JSON_ARRAY != vam->json_tree.type)
5109     {
5110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5111       vat_json_init_array (&vam->json_tree);
5112     }
5113   node = vat_json_array_add (&vam->json_tree);
5114
5115   vat_json_init_object (node);
5116   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5117   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5118 }
5119
5120 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5121 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5122 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5123 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5124 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5125 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5126 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5127 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5128 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5129 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5130
5131 /*
5132  * Generate boilerplate reply handlers, which
5133  * dig the return value out of the xxx_reply_t API message,
5134  * stick it into vam->retval, and set vam->result_ready
5135  *
5136  * Could also do this by pointing N message decode slots at
5137  * a single function, but that could break in subtle ways.
5138  */
5139
5140 #define foreach_standard_reply_retval_handler           \
5141 _(sw_interface_set_flags_reply)                         \
5142 _(sw_interface_add_del_address_reply)                   \
5143 _(sw_interface_set_rx_mode_reply)                       \
5144 _(sw_interface_set_rx_placement_reply)                  \
5145 _(sw_interface_set_table_reply)                         \
5146 _(sw_interface_set_mpls_enable_reply)                   \
5147 _(sw_interface_set_vpath_reply)                         \
5148 _(sw_interface_set_vxlan_bypass_reply)                  \
5149 _(sw_interface_set_geneve_bypass_reply)                 \
5150 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5151 _(sw_interface_set_l2_bridge_reply)                     \
5152 _(bridge_domain_add_del_reply)                          \
5153 _(sw_interface_set_l2_xconnect_reply)                   \
5154 _(l2fib_add_del_reply)                                  \
5155 _(l2fib_flush_int_reply)                                \
5156 _(l2fib_flush_bd_reply)                                 \
5157 _(ip_add_del_route_reply)                               \
5158 _(ip_table_add_del_reply)                               \
5159 _(ip_mroute_add_del_reply)                              \
5160 _(mpls_route_add_del_reply)                             \
5161 _(mpls_table_add_del_reply)                             \
5162 _(mpls_ip_bind_unbind_reply)                            \
5163 _(bier_route_add_del_reply)                             \
5164 _(bier_table_add_del_reply)                             \
5165 _(proxy_arp_add_del_reply)                              \
5166 _(proxy_arp_intfc_enable_disable_reply)                 \
5167 _(sw_interface_set_unnumbered_reply)                    \
5168 _(ip_neighbor_add_del_reply)                            \
5169 _(oam_add_del_reply)                                    \
5170 _(reset_fib_reply)                                      \
5171 _(dhcp_proxy_config_reply)                              \
5172 _(dhcp_proxy_set_vss_reply)                             \
5173 _(dhcp_client_config_reply)                             \
5174 _(set_ip_flow_hash_reply)                               \
5175 _(sw_interface_ip6_enable_disable_reply)                \
5176 _(ip6nd_proxy_add_del_reply)                            \
5177 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5178 _(sw_interface_ip6nd_ra_config_reply)                   \
5179 _(set_arp_neighbor_limit_reply)                         \
5180 _(l2_patch_add_del_reply)                               \
5181 _(sr_mpls_policy_add_reply)                             \
5182 _(sr_mpls_policy_mod_reply)                             \
5183 _(sr_mpls_policy_del_reply)                             \
5184 _(sr_policy_add_reply)                                  \
5185 _(sr_policy_mod_reply)                                  \
5186 _(sr_policy_del_reply)                                  \
5187 _(sr_localsid_add_del_reply)                            \
5188 _(sr_steering_add_del_reply)                            \
5189 _(classify_add_del_session_reply)                       \
5190 _(classify_set_interface_ip_table_reply)                \
5191 _(classify_set_interface_l2_tables_reply)               \
5192 _(l2tpv3_set_tunnel_cookies_reply)                      \
5193 _(l2tpv3_interface_enable_disable_reply)                \
5194 _(l2tpv3_set_lookup_key_reply)                          \
5195 _(l2_fib_clear_table_reply)                             \
5196 _(l2_interface_efp_filter_reply)                        \
5197 _(l2_interface_vlan_tag_rewrite_reply)                  \
5198 _(modify_vhost_user_if_reply)                           \
5199 _(delete_vhost_user_if_reply)                           \
5200 _(ip_probe_neighbor_reply)                              \
5201 _(ip_scan_neighbor_enable_disable_reply)                \
5202 _(want_ip4_arp_events_reply)                            \
5203 _(want_ip6_nd_events_reply)                             \
5204 _(want_l2_macs_events_reply)                            \
5205 _(input_acl_set_interface_reply)                        \
5206 _(ipsec_spd_add_del_reply)                              \
5207 _(ipsec_interface_add_del_spd_reply)                    \
5208 _(ipsec_spd_add_del_entry_reply)                        \
5209 _(ipsec_sad_add_del_entry_reply)                        \
5210 _(ipsec_sa_set_key_reply)                               \
5211 _(ipsec_tunnel_if_add_del_reply)                        \
5212 _(ipsec_tunnel_if_set_key_reply)                        \
5213 _(ipsec_tunnel_if_set_sa_reply)                         \
5214 _(ikev2_profile_add_del_reply)                          \
5215 _(ikev2_profile_set_auth_reply)                         \
5216 _(ikev2_profile_set_id_reply)                           \
5217 _(ikev2_profile_set_ts_reply)                           \
5218 _(ikev2_set_local_key_reply)                            \
5219 _(ikev2_set_responder_reply)                            \
5220 _(ikev2_set_ike_transforms_reply)                       \
5221 _(ikev2_set_esp_transforms_reply)                       \
5222 _(ikev2_set_sa_lifetime_reply)                          \
5223 _(ikev2_initiate_sa_init_reply)                         \
5224 _(ikev2_initiate_del_ike_sa_reply)                      \
5225 _(ikev2_initiate_del_child_sa_reply)                    \
5226 _(ikev2_initiate_rekey_child_sa_reply)                  \
5227 _(delete_loopback_reply)                                \
5228 _(bd_ip_mac_add_del_reply)                              \
5229 _(bd_ip_mac_flush_reply)                                \
5230 _(want_interface_events_reply)                          \
5231 _(cop_interface_enable_disable_reply)                   \
5232 _(cop_whitelist_enable_disable_reply)                   \
5233 _(sw_interface_clear_stats_reply)                       \
5234 _(ioam_enable_reply)                                    \
5235 _(ioam_disable_reply)                                   \
5236 _(one_add_del_locator_reply)                            \
5237 _(one_add_del_local_eid_reply)                          \
5238 _(one_add_del_remote_mapping_reply)                     \
5239 _(one_add_del_adjacency_reply)                          \
5240 _(one_add_del_map_resolver_reply)                       \
5241 _(one_add_del_map_server_reply)                         \
5242 _(one_enable_disable_reply)                             \
5243 _(one_rloc_probe_enable_disable_reply)                  \
5244 _(one_map_register_enable_disable_reply)                \
5245 _(one_map_register_set_ttl_reply)                       \
5246 _(one_set_transport_protocol_reply)                     \
5247 _(one_map_register_fallback_threshold_reply)            \
5248 _(one_pitr_set_locator_set_reply)                       \
5249 _(one_map_request_mode_reply)                           \
5250 _(one_add_del_map_request_itr_rlocs_reply)              \
5251 _(one_eid_table_add_del_map_reply)                      \
5252 _(one_use_petr_reply)                                   \
5253 _(one_stats_enable_disable_reply)                       \
5254 _(one_add_del_l2_arp_entry_reply)                       \
5255 _(one_add_del_ndp_entry_reply)                          \
5256 _(one_stats_flush_reply)                                \
5257 _(one_enable_disable_xtr_mode_reply)                    \
5258 _(one_enable_disable_pitr_mode_reply)                   \
5259 _(one_enable_disable_petr_mode_reply)                   \
5260 _(gpe_enable_disable_reply)                             \
5261 _(gpe_set_encap_mode_reply)                             \
5262 _(gpe_add_del_iface_reply)                              \
5263 _(gpe_add_del_native_fwd_rpath_reply)                   \
5264 _(af_packet_delete_reply)                               \
5265 _(policer_classify_set_interface_reply)                 \
5266 _(netmap_create_reply)                                  \
5267 _(netmap_delete_reply)                                  \
5268 _(set_ipfix_exporter_reply)                             \
5269 _(set_ipfix_classify_stream_reply)                      \
5270 _(ipfix_classify_table_add_del_reply)                   \
5271 _(flow_classify_set_interface_reply)                    \
5272 _(sw_interface_span_enable_disable_reply)               \
5273 _(pg_capture_reply)                                     \
5274 _(pg_enable_disable_reply)                              \
5275 _(ip_source_and_port_range_check_add_del_reply)         \
5276 _(ip_source_and_port_range_check_interface_add_del_reply)\
5277 _(delete_subif_reply)                                   \
5278 _(l2_interface_pbb_tag_rewrite_reply)                   \
5279 _(set_punt_reply)                                       \
5280 _(feature_enable_disable_reply)                         \
5281 _(sw_interface_tag_add_del_reply)                       \
5282 _(hw_interface_set_mtu_reply)                           \
5283 _(p2p_ethernet_add_reply)                               \
5284 _(p2p_ethernet_del_reply)                               \
5285 _(lldp_config_reply)                                    \
5286 _(sw_interface_set_lldp_reply)                          \
5287 _(tcp_configure_src_addresses_reply)                    \
5288 _(dns_enable_disable_reply)                             \
5289 _(dns_name_server_add_del_reply)                        \
5290 _(session_rule_add_del_reply)                           \
5291 _(ip_container_proxy_add_del_reply)                     \
5292 _(output_acl_set_interface_reply)                       \
5293 _(qos_record_enable_disable_reply)
5294
5295 #define _(n)                                    \
5296     static void vl_api_##n##_t_handler          \
5297     (vl_api_##n##_t * mp)                       \
5298     {                                           \
5299         vat_main_t * vam = &vat_main;           \
5300         i32 retval = ntohl(mp->retval);         \
5301         if (vam->async_mode) {                  \
5302             vam->async_errors += (retval < 0);  \
5303         } else {                                \
5304             vam->retval = retval;               \
5305             vam->result_ready = 1;              \
5306         }                                       \
5307     }
5308 foreach_standard_reply_retval_handler;
5309 #undef _
5310
5311 #define _(n)                                    \
5312     static void vl_api_##n##_t_handler_json     \
5313     (vl_api_##n##_t * mp)                       \
5314     {                                           \
5315         vat_main_t * vam = &vat_main;           \
5316         vat_json_node_t node;                   \
5317         vat_json_init_object(&node);            \
5318         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5319         vat_json_print(vam->ofp, &node);        \
5320         vam->retval = ntohl(mp->retval);        \
5321         vam->result_ready = 1;                  \
5322     }
5323 foreach_standard_reply_retval_handler;
5324 #undef _
5325
5326 /*
5327  * Table of message reply handlers, must include boilerplate handlers
5328  * we just generated
5329  */
5330
5331 #define foreach_vpe_api_reply_msg                                       \
5332 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5333 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5334 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5335 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5336 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5337 _(CLI_REPLY, cli_reply)                                                 \
5338 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5339 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5340   sw_interface_add_del_address_reply)                                   \
5341 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5342 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5343 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5344 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5345 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5346 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5347 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5348 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5349 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5350 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5351   sw_interface_set_l2_xconnect_reply)                                   \
5352 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5353   sw_interface_set_l2_bridge_reply)                                     \
5354 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5355 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5356 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5357 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5358 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5359 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5360 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5361 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5362 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5363 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5364 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5365 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5366 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5367 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5368 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5369 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5370 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5371 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5372 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5373 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5374 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5375 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5376 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5377 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5378 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5379 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5380 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5381 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5382 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5383 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5384   proxy_arp_intfc_enable_disable_reply)                                 \
5385 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5386 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5387   sw_interface_set_unnumbered_reply)                                    \
5388 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5389 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5390 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5391 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5392 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5393 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5394 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5395 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5396 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5397 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5398 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5399   sw_interface_ip6_enable_disable_reply)                                \
5400 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5401 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5402 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5403   sw_interface_ip6nd_ra_prefix_reply)                                   \
5404 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5405   sw_interface_ip6nd_ra_config_reply)                                   \
5406 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5407 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5408 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5409 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5410 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5411 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5412 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5413 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5414 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5415 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5416 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5417 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5418 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5419 classify_set_interface_ip_table_reply)                                  \
5420 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5421   classify_set_interface_l2_tables_reply)                               \
5422 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5423 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5424 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5425 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5426 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5427   l2tpv3_interface_enable_disable_reply)                                \
5428 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5429 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5430 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5431 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5432 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5433 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5434 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5435 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5436 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5437 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5438 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5439 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5440 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5441 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5442 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5443 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5444 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5445 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5446 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5447 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5448 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5449 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5450 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5451 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5452 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5453 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5454 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5455 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5456 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5457 _(L2_MACS_EVENT, l2_macs_event)                                         \
5458 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5459 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5460 _(IP_DETAILS, ip_details)                                               \
5461 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5462 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5463 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5464 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5465 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5466 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5467 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5468 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5469 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5470 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5471 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5472 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5473 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5474 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5475 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5476 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5477 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5478 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5479 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5480 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5481 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5482 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5483 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5484 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5485 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5486 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5487 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5488 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5489 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5490 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5491 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5492 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5493 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5494 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5495 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5496 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5497 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5498 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5499 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5500 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5501 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5502 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5503 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5504 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5505   one_map_register_enable_disable_reply)                                \
5506 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5507 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5508 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5509 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5510   one_map_register_fallback_threshold_reply)                            \
5511 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5512   one_rloc_probe_enable_disable_reply)                                  \
5513 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5514 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5515 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5516 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5517 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5518 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5519 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5520 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5521 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5522 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5523 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5524 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5525 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5526 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5527 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5528 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5529   show_one_stats_enable_disable_reply)                                  \
5530 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5531 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5532 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5533 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5534 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5535 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5536 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5537 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5538   one_enable_disable_pitr_mode_reply)                                   \
5539 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5540   one_enable_disable_petr_mode_reply)                                   \
5541 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5542 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5543 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5544 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5545 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5546 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5547 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5548 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5549 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5550 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5551 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5552 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5553   gpe_add_del_native_fwd_rpath_reply)                                   \
5554 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5555   gpe_fwd_entry_path_details)                                           \
5556 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5557 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5558   one_add_del_map_request_itr_rlocs_reply)                              \
5559 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5560   one_get_map_request_itr_rlocs_reply)                                  \
5561 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5562 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5563 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5564 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5565 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5566 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5567   show_one_map_register_state_reply)                                    \
5568 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5569 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5570   show_one_map_register_fallback_threshold_reply)                       \
5571 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5572 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5573 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5574 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5575 _(POLICER_DETAILS, policer_details)                                     \
5576 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5577 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5578 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5579 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5580 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5581 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5582 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5583 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5584 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5585 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5586 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5587 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5588 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5589 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5590 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5591 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5592 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5593 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5594 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5595 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5596 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5597 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5598 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5599 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5600 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5601  ip_source_and_port_range_check_add_del_reply)                          \
5602 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5603  ip_source_and_port_range_check_interface_add_del_reply)                \
5604 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5605 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5606 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5607 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5608 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5609 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5610 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5611 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5612 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5613 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5614 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5615 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5616 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5617 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5618 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5619 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5620 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5621 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5622 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5623 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5624 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5625 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5626 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5627 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5628 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5629 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5630 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5631 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5632
5633 #define foreach_standalone_reply_msg                                    \
5634 _(SW_INTERFACE_EVENT, sw_interface_event)
5635
5636 typedef struct
5637 {
5638   u8 *name;
5639   u32 value;
5640 } name_sort_t;
5641
5642 #define STR_VTR_OP_CASE(op)     \
5643     case L2_VTR_ ## op:         \
5644         return "" # op;
5645
5646 static const char *
5647 str_vtr_op (u32 vtr_op)
5648 {
5649   switch (vtr_op)
5650     {
5651       STR_VTR_OP_CASE (DISABLED);
5652       STR_VTR_OP_CASE (PUSH_1);
5653       STR_VTR_OP_CASE (PUSH_2);
5654       STR_VTR_OP_CASE (POP_1);
5655       STR_VTR_OP_CASE (POP_2);
5656       STR_VTR_OP_CASE (TRANSLATE_1_1);
5657       STR_VTR_OP_CASE (TRANSLATE_1_2);
5658       STR_VTR_OP_CASE (TRANSLATE_2_1);
5659       STR_VTR_OP_CASE (TRANSLATE_2_2);
5660     }
5661
5662   return "UNKNOWN";
5663 }
5664
5665 static int
5666 dump_sub_interface_table (vat_main_t * vam)
5667 {
5668   const sw_interface_subif_t *sub = NULL;
5669
5670   if (vam->json_output)
5671     {
5672       clib_warning
5673         ("JSON output supported only for VPE API calls and dump_stats_table");
5674       return -99;
5675     }
5676
5677   print (vam->ofp,
5678          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5679          "Interface", "sw_if_index",
5680          "sub id", "dot1ad", "tags", "outer id",
5681          "inner id", "exact", "default", "outer any", "inner any");
5682
5683   vec_foreach (sub, vam->sw_if_subif_table)
5684   {
5685     print (vam->ofp,
5686            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5687            sub->interface_name,
5688            sub->sw_if_index,
5689            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5690            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5691            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5692            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5693     if (sub->vtr_op != L2_VTR_DISABLED)
5694       {
5695         print (vam->ofp,
5696                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5697                "tag1: %d tag2: %d ]",
5698                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5699                sub->vtr_tag1, sub->vtr_tag2);
5700       }
5701   }
5702
5703   return 0;
5704 }
5705
5706 static int
5707 name_sort_cmp (void *a1, void *a2)
5708 {
5709   name_sort_t *n1 = a1;
5710   name_sort_t *n2 = a2;
5711
5712   return strcmp ((char *) n1->name, (char *) n2->name);
5713 }
5714
5715 static int
5716 dump_interface_table (vat_main_t * vam)
5717 {
5718   hash_pair_t *p;
5719   name_sort_t *nses = 0, *ns;
5720
5721   if (vam->json_output)
5722     {
5723       clib_warning
5724         ("JSON output supported only for VPE API calls and dump_stats_table");
5725       return -99;
5726     }
5727
5728   /* *INDENT-OFF* */
5729   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5730   ({
5731     vec_add2 (nses, ns, 1);
5732     ns->name = (u8 *)(p->key);
5733     ns->value = (u32) p->value[0];
5734   }));
5735   /* *INDENT-ON* */
5736
5737   vec_sort_with_function (nses, name_sort_cmp);
5738
5739   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5740   vec_foreach (ns, nses)
5741   {
5742     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5743   }
5744   vec_free (nses);
5745   return 0;
5746 }
5747
5748 static int
5749 dump_ip_table (vat_main_t * vam, int is_ipv6)
5750 {
5751   const ip_details_t *det = NULL;
5752   const ip_address_details_t *address = NULL;
5753   u32 i = ~0;
5754
5755   print (vam->ofp, "%-12s", "sw_if_index");
5756
5757   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5758   {
5759     i++;
5760     if (!det->present)
5761       {
5762         continue;
5763       }
5764     print (vam->ofp, "%-12d", i);
5765     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5766     if (!det->addr)
5767       {
5768         continue;
5769       }
5770     vec_foreach (address, det->addr)
5771     {
5772       print (vam->ofp,
5773              "            %-30U%-13d",
5774              is_ipv6 ? format_ip6_address : format_ip4_address,
5775              address->ip, address->prefix_length);
5776     }
5777   }
5778
5779   return 0;
5780 }
5781
5782 static int
5783 dump_ipv4_table (vat_main_t * vam)
5784 {
5785   if (vam->json_output)
5786     {
5787       clib_warning
5788         ("JSON output supported only for VPE API calls and dump_stats_table");
5789       return -99;
5790     }
5791
5792   return dump_ip_table (vam, 0);
5793 }
5794
5795 static int
5796 dump_ipv6_table (vat_main_t * vam)
5797 {
5798   if (vam->json_output)
5799     {
5800       clib_warning
5801         ("JSON output supported only for VPE API calls and dump_stats_table");
5802       return -99;
5803     }
5804
5805   return dump_ip_table (vam, 1);
5806 }
5807
5808 /*
5809  * Pass CLI buffers directly in the CLI_INBAND API message,
5810  * instead of an additional shared memory area.
5811  */
5812 static int
5813 exec_inband (vat_main_t * vam)
5814 {
5815   vl_api_cli_inband_t *mp;
5816   unformat_input_t *i = vam->input;
5817   int ret;
5818
5819   if (vec_len (i->buffer) == 0)
5820     return -1;
5821
5822   if (vam->exec_mode == 0 && unformat (i, "mode"))
5823     {
5824       vam->exec_mode = 1;
5825       return 0;
5826     }
5827   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5828     {
5829       vam->exec_mode = 0;
5830       return 0;
5831     }
5832
5833   /*
5834    * In order for the CLI command to work, it
5835    * must be a vector ending in \n, not a C-string ending
5836    * in \n\0.
5837    */
5838   u32 len = vec_len (vam->input->buffer);
5839   M2 (CLI_INBAND, mp, len);
5840   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5841
5842   S (mp);
5843   W (ret);
5844   /* json responses may or may not include a useful reply... */
5845   if (vec_len (vam->cmd_reply))
5846     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5847   return ret;
5848 }
5849
5850 int
5851 exec (vat_main_t * vam)
5852 {
5853   return exec_inband (vam);
5854 }
5855
5856 static int
5857 api_create_loopback (vat_main_t * vam)
5858 {
5859   unformat_input_t *i = vam->input;
5860   vl_api_create_loopback_t *mp;
5861   vl_api_create_loopback_instance_t *mp_lbi;
5862   u8 mac_address[6];
5863   u8 mac_set = 0;
5864   u8 is_specified = 0;
5865   u32 user_instance = 0;
5866   int ret;
5867
5868   clib_memset (mac_address, 0, sizeof (mac_address));
5869
5870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5871     {
5872       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5873         mac_set = 1;
5874       if (unformat (i, "instance %d", &user_instance))
5875         is_specified = 1;
5876       else
5877         break;
5878     }
5879
5880   if (is_specified)
5881     {
5882       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5883       mp_lbi->is_specified = is_specified;
5884       if (is_specified)
5885         mp_lbi->user_instance = htonl (user_instance);
5886       if (mac_set)
5887         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5888       S (mp_lbi);
5889     }
5890   else
5891     {
5892       /* Construct the API message */
5893       M (CREATE_LOOPBACK, mp);
5894       if (mac_set)
5895         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5896       S (mp);
5897     }
5898
5899   W (ret);
5900   return ret;
5901 }
5902
5903 static int
5904 api_delete_loopback (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_delete_loopback_t *mp;
5908   u32 sw_if_index = ~0;
5909   int ret;
5910
5911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5912     {
5913       if (unformat (i, "sw_if_index %d", &sw_if_index))
5914         ;
5915       else
5916         break;
5917     }
5918
5919   if (sw_if_index == ~0)
5920     {
5921       errmsg ("missing sw_if_index");
5922       return -99;
5923     }
5924
5925   /* Construct the API message */
5926   M (DELETE_LOOPBACK, mp);
5927   mp->sw_if_index = ntohl (sw_if_index);
5928
5929   S (mp);
5930   W (ret);
5931   return ret;
5932 }
5933
5934 static int
5935 api_want_interface_events (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_want_interface_events_t *mp;
5939   int enable = -1;
5940   int ret;
5941
5942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943     {
5944       if (unformat (i, "enable"))
5945         enable = 1;
5946       else if (unformat (i, "disable"))
5947         enable = 0;
5948       else
5949         break;
5950     }
5951
5952   if (enable == -1)
5953     {
5954       errmsg ("missing enable|disable");
5955       return -99;
5956     }
5957
5958   M (WANT_INTERFACE_EVENTS, mp);
5959   mp->enable_disable = enable;
5960
5961   vam->interface_event_display = enable;
5962
5963   S (mp);
5964   W (ret);
5965   return ret;
5966 }
5967
5968
5969 /* Note: non-static, called once to set up the initial intfc table */
5970 int
5971 api_sw_interface_dump (vat_main_t * vam)
5972 {
5973   vl_api_sw_interface_dump_t *mp;
5974   vl_api_control_ping_t *mp_ping;
5975   hash_pair_t *p;
5976   name_sort_t *nses = 0, *ns;
5977   sw_interface_subif_t *sub = NULL;
5978   int ret;
5979
5980   /* Toss the old name table */
5981   /* *INDENT-OFF* */
5982   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5983   ({
5984     vec_add2 (nses, ns, 1);
5985     ns->name = (u8 *)(p->key);
5986     ns->value = (u32) p->value[0];
5987   }));
5988   /* *INDENT-ON* */
5989
5990   hash_free (vam->sw_if_index_by_interface_name);
5991
5992   vec_foreach (ns, nses) vec_free (ns->name);
5993
5994   vec_free (nses);
5995
5996   vec_foreach (sub, vam->sw_if_subif_table)
5997   {
5998     vec_free (sub->interface_name);
5999   }
6000   vec_free (vam->sw_if_subif_table);
6001
6002   /* recreate the interface name hash table */
6003   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6004
6005   /*
6006    * Ask for all interface names. Otherwise, the epic catalog of
6007    * name filters becomes ridiculously long, and vat ends up needing
6008    * to be taught about new interface types.
6009    */
6010   M (SW_INTERFACE_DUMP, mp);
6011   S (mp);
6012
6013   /* Use a control ping for synchronization */
6014   MPING (CONTROL_PING, mp_ping);
6015   S (mp_ping);
6016
6017   W (ret);
6018   return ret;
6019 }
6020
6021 static int
6022 api_sw_interface_set_flags (vat_main_t * vam)
6023 {
6024   unformat_input_t *i = vam->input;
6025   vl_api_sw_interface_set_flags_t *mp;
6026   u32 sw_if_index;
6027   u8 sw_if_index_set = 0;
6028   u8 admin_up = 0;
6029   int ret;
6030
6031   /* Parse args required to build the message */
6032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6033     {
6034       if (unformat (i, "admin-up"))
6035         admin_up = 1;
6036       else if (unformat (i, "admin-down"))
6037         admin_up = 0;
6038       else
6039         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6040         sw_if_index_set = 1;
6041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6042         sw_if_index_set = 1;
6043       else
6044         break;
6045     }
6046
6047   if (sw_if_index_set == 0)
6048     {
6049       errmsg ("missing interface name or sw_if_index");
6050       return -99;
6051     }
6052
6053   /* Construct the API message */
6054   M (SW_INTERFACE_SET_FLAGS, mp);
6055   mp->sw_if_index = ntohl (sw_if_index);
6056   mp->admin_up_down = admin_up;
6057
6058   /* send it... */
6059   S (mp);
6060
6061   /* Wait for a reply, return the good/bad news... */
6062   W (ret);
6063   return ret;
6064 }
6065
6066 static int
6067 api_sw_interface_set_rx_mode (vat_main_t * vam)
6068 {
6069   unformat_input_t *i = vam->input;
6070   vl_api_sw_interface_set_rx_mode_t *mp;
6071   u32 sw_if_index;
6072   u8 sw_if_index_set = 0;
6073   int ret;
6074   u8 queue_id_valid = 0;
6075   u32 queue_id;
6076   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6077
6078   /* Parse args required to build the message */
6079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6080     {
6081       if (unformat (i, "queue %d", &queue_id))
6082         queue_id_valid = 1;
6083       else if (unformat (i, "polling"))
6084         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6085       else if (unformat (i, "interrupt"))
6086         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6087       else if (unformat (i, "adaptive"))
6088         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6089       else
6090         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6091         sw_if_index_set = 1;
6092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6093         sw_if_index_set = 1;
6094       else
6095         break;
6096     }
6097
6098   if (sw_if_index_set == 0)
6099     {
6100       errmsg ("missing interface name or sw_if_index");
6101       return -99;
6102     }
6103   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6104     {
6105       errmsg ("missing rx-mode");
6106       return -99;
6107     }
6108
6109   /* Construct the API message */
6110   M (SW_INTERFACE_SET_RX_MODE, mp);
6111   mp->sw_if_index = ntohl (sw_if_index);
6112   mp->mode = mode;
6113   mp->queue_id_valid = queue_id_valid;
6114   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6115
6116   /* send it... */
6117   S (mp);
6118
6119   /* Wait for a reply, return the good/bad news... */
6120   W (ret);
6121   return ret;
6122 }
6123
6124 static int
6125 api_sw_interface_set_rx_placement (vat_main_t * vam)
6126 {
6127   unformat_input_t *i = vam->input;
6128   vl_api_sw_interface_set_rx_placement_t *mp;
6129   u32 sw_if_index;
6130   u8 sw_if_index_set = 0;
6131   int ret;
6132   u8 is_main = 0;
6133   u32 queue_id, thread_index;
6134
6135   /* Parse args required to build the message */
6136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6137     {
6138       if (unformat (i, "queue %d", &queue_id))
6139         ;
6140       else if (unformat (i, "main"))
6141         is_main = 1;
6142       else if (unformat (i, "worker %d", &thread_index))
6143         ;
6144       else
6145         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6146         sw_if_index_set = 1;
6147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6148         sw_if_index_set = 1;
6149       else
6150         break;
6151     }
6152
6153   if (sw_if_index_set == 0)
6154     {
6155       errmsg ("missing interface name or sw_if_index");
6156       return -99;
6157     }
6158
6159   if (is_main)
6160     thread_index = 0;
6161   /* Construct the API message */
6162   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6163   mp->sw_if_index = ntohl (sw_if_index);
6164   mp->worker_id = ntohl (thread_index);
6165   mp->queue_id = ntohl (queue_id);
6166   mp->is_main = is_main;
6167
6168   /* send it... */
6169   S (mp);
6170   /* Wait for a reply, return the good/bad news... */
6171   W (ret);
6172   return ret;
6173 }
6174
6175 static void vl_api_sw_interface_rx_placement_details_t_handler
6176   (vl_api_sw_interface_rx_placement_details_t * mp)
6177 {
6178   vat_main_t *vam = &vat_main;
6179   u32 worker_id = ntohl (mp->worker_id);
6180
6181   print (vam->ofp,
6182          "\n%-11d %-11s %-6d %-5d %-9s",
6183          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6184          worker_id, ntohl (mp->queue_id),
6185          (mp->mode ==
6186           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6187 }
6188
6189 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6190   (vl_api_sw_interface_rx_placement_details_t * mp)
6191 {
6192   vat_main_t *vam = &vat_main;
6193   vat_json_node_t *node = NULL;
6194
6195   if (VAT_JSON_ARRAY != vam->json_tree.type)
6196     {
6197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6198       vat_json_init_array (&vam->json_tree);
6199     }
6200   node = vat_json_array_add (&vam->json_tree);
6201
6202   vat_json_init_object (node);
6203   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6204   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6205   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6206   vat_json_object_add_uint (node, "mode", mp->mode);
6207 }
6208
6209 static int
6210 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6211 {
6212   unformat_input_t *i = vam->input;
6213   vl_api_sw_interface_rx_placement_dump_t *mp;
6214   vl_api_control_ping_t *mp_ping;
6215   int ret;
6216   u32 sw_if_index;
6217   u8 sw_if_index_set = 0;
6218
6219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220     {
6221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6222         sw_if_index_set++;
6223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6224         sw_if_index_set++;
6225       else
6226         break;
6227     }
6228
6229   print (vam->ofp,
6230          "\n%-11s %-11s %-6s %-5s %-4s",
6231          "sw_if_index", "main/worker", "thread", "queue", "mode");
6232
6233   /* Dump Interface rx placement */
6234   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6235
6236   if (sw_if_index_set)
6237     mp->sw_if_index = htonl (sw_if_index);
6238   else
6239     mp->sw_if_index = ~0;
6240
6241   S (mp);
6242
6243   /* Use a control ping for synchronization */
6244   MPING (CONTROL_PING, mp_ping);
6245   S (mp_ping);
6246
6247   W (ret);
6248   return ret;
6249 }
6250
6251 static int
6252 api_sw_interface_clear_stats (vat_main_t * vam)
6253 {
6254   unformat_input_t *i = vam->input;
6255   vl_api_sw_interface_clear_stats_t *mp;
6256   u32 sw_if_index;
6257   u8 sw_if_index_set = 0;
6258   int ret;
6259
6260   /* Parse args required to build the message */
6261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6262     {
6263       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6264         sw_if_index_set = 1;
6265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6266         sw_if_index_set = 1;
6267       else
6268         break;
6269     }
6270
6271   /* Construct the API message */
6272   M (SW_INTERFACE_CLEAR_STATS, mp);
6273
6274   if (sw_if_index_set == 1)
6275     mp->sw_if_index = ntohl (sw_if_index);
6276   else
6277     mp->sw_if_index = ~0;
6278
6279   /* send it... */
6280   S (mp);
6281
6282   /* Wait for a reply, return the good/bad news... */
6283   W (ret);
6284   return ret;
6285 }
6286
6287 static int
6288 api_sw_interface_add_del_address (vat_main_t * vam)
6289 {
6290   unformat_input_t *i = vam->input;
6291   vl_api_sw_interface_add_del_address_t *mp;
6292   u32 sw_if_index;
6293   u8 sw_if_index_set = 0;
6294   u8 is_add = 1, del_all = 0;
6295   u32 address_length = 0;
6296   u8 v4_address_set = 0;
6297   u8 v6_address_set = 0;
6298   ip4_address_t v4address;
6299   ip6_address_t v6address;
6300   int ret;
6301
6302   /* Parse args required to build the message */
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "del-all"))
6306         del_all = 1;
6307       else if (unformat (i, "del"))
6308         is_add = 0;
6309       else
6310         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6311         sw_if_index_set = 1;
6312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6313         sw_if_index_set = 1;
6314       else if (unformat (i, "%U/%d",
6315                          unformat_ip4_address, &v4address, &address_length))
6316         v4_address_set = 1;
6317       else if (unformat (i, "%U/%d",
6318                          unformat_ip6_address, &v6address, &address_length))
6319         v6_address_set = 1;
6320       else
6321         break;
6322     }
6323
6324   if (sw_if_index_set == 0)
6325     {
6326       errmsg ("missing interface name or sw_if_index");
6327       return -99;
6328     }
6329   if (v4_address_set && v6_address_set)
6330     {
6331       errmsg ("both v4 and v6 addresses set");
6332       return -99;
6333     }
6334   if (!v4_address_set && !v6_address_set && !del_all)
6335     {
6336       errmsg ("no addresses set");
6337       return -99;
6338     }
6339
6340   /* Construct the API message */
6341   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6342
6343   mp->sw_if_index = ntohl (sw_if_index);
6344   mp->is_add = is_add;
6345   mp->del_all = del_all;
6346   if (v6_address_set)
6347     {
6348       mp->is_ipv6 = 1;
6349       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6350     }
6351   else
6352     {
6353       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6354     }
6355   mp->address_length = address_length;
6356
6357   /* send it... */
6358   S (mp);
6359
6360   /* Wait for a reply, return good/bad news  */
6361   W (ret);
6362   return ret;
6363 }
6364
6365 static int
6366 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_sw_interface_set_mpls_enable_t *mp;
6370   u32 sw_if_index;
6371   u8 sw_if_index_set = 0;
6372   u8 enable = 1;
6373   int ret;
6374
6375   /* Parse args required to build the message */
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6379         sw_if_index_set = 1;
6380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6381         sw_if_index_set = 1;
6382       else if (unformat (i, "disable"))
6383         enable = 0;
6384       else if (unformat (i, "dis"))
6385         enable = 0;
6386       else
6387         break;
6388     }
6389
6390   if (sw_if_index_set == 0)
6391     {
6392       errmsg ("missing interface name or sw_if_index");
6393       return -99;
6394     }
6395
6396   /* Construct the API message */
6397   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6398
6399   mp->sw_if_index = ntohl (sw_if_index);
6400   mp->enable = enable;
6401
6402   /* send it... */
6403   S (mp);
6404
6405   /* Wait for a reply... */
6406   W (ret);
6407   return ret;
6408 }
6409
6410 static int
6411 api_sw_interface_set_table (vat_main_t * vam)
6412 {
6413   unformat_input_t *i = vam->input;
6414   vl_api_sw_interface_set_table_t *mp;
6415   u32 sw_if_index, vrf_id = 0;
6416   u8 sw_if_index_set = 0;
6417   u8 is_ipv6 = 0;
6418   int ret;
6419
6420   /* Parse args required to build the message */
6421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6422     {
6423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6424         sw_if_index_set = 1;
6425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6426         sw_if_index_set = 1;
6427       else if (unformat (i, "vrf %d", &vrf_id))
6428         ;
6429       else if (unformat (i, "ipv6"))
6430         is_ipv6 = 1;
6431       else
6432         break;
6433     }
6434
6435   if (sw_if_index_set == 0)
6436     {
6437       errmsg ("missing interface name or sw_if_index");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (SW_INTERFACE_SET_TABLE, mp);
6443
6444   mp->sw_if_index = ntohl (sw_if_index);
6445   mp->is_ipv6 = is_ipv6;
6446   mp->vrf_id = ntohl (vrf_id);
6447
6448   /* send it... */
6449   S (mp);
6450
6451   /* Wait for a reply... */
6452   W (ret);
6453   return ret;
6454 }
6455
6456 static void vl_api_sw_interface_get_table_reply_t_handler
6457   (vl_api_sw_interface_get_table_reply_t * mp)
6458 {
6459   vat_main_t *vam = &vat_main;
6460
6461   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6462
6463   vam->retval = ntohl (mp->retval);
6464   vam->result_ready = 1;
6465
6466 }
6467
6468 static void vl_api_sw_interface_get_table_reply_t_handler_json
6469   (vl_api_sw_interface_get_table_reply_t * mp)
6470 {
6471   vat_main_t *vam = &vat_main;
6472   vat_json_node_t node;
6473
6474   vat_json_init_object (&node);
6475   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6476   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6477
6478   vat_json_print (vam->ofp, &node);
6479   vat_json_free (&node);
6480
6481   vam->retval = ntohl (mp->retval);
6482   vam->result_ready = 1;
6483 }
6484
6485 static int
6486 api_sw_interface_get_table (vat_main_t * vam)
6487 {
6488   unformat_input_t *i = vam->input;
6489   vl_api_sw_interface_get_table_t *mp;
6490   u32 sw_if_index;
6491   u8 sw_if_index_set = 0;
6492   u8 is_ipv6 = 0;
6493   int ret;
6494
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6498         sw_if_index_set = 1;
6499       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6500         sw_if_index_set = 1;
6501       else if (unformat (i, "ipv6"))
6502         is_ipv6 = 1;
6503       else
6504         break;
6505     }
6506
6507   if (sw_if_index_set == 0)
6508     {
6509       errmsg ("missing interface name or sw_if_index");
6510       return -99;
6511     }
6512
6513   M (SW_INTERFACE_GET_TABLE, mp);
6514   mp->sw_if_index = htonl (sw_if_index);
6515   mp->is_ipv6 = is_ipv6;
6516
6517   S (mp);
6518   W (ret);
6519   return ret;
6520 }
6521
6522 static int
6523 api_sw_interface_set_vpath (vat_main_t * vam)
6524 {
6525   unformat_input_t *i = vam->input;
6526   vl_api_sw_interface_set_vpath_t *mp;
6527   u32 sw_if_index = 0;
6528   u8 sw_if_index_set = 0;
6529   u8 is_enable = 0;
6530   int ret;
6531
6532   /* Parse args required to build the message */
6533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6534     {
6535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6536         sw_if_index_set = 1;
6537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6538         sw_if_index_set = 1;
6539       else if (unformat (i, "enable"))
6540         is_enable = 1;
6541       else if (unformat (i, "disable"))
6542         is_enable = 0;
6543       else
6544         break;
6545     }
6546
6547   if (sw_if_index_set == 0)
6548     {
6549       errmsg ("missing interface name or sw_if_index");
6550       return -99;
6551     }
6552
6553   /* Construct the API message */
6554   M (SW_INTERFACE_SET_VPATH, mp);
6555
6556   mp->sw_if_index = ntohl (sw_if_index);
6557   mp->enable = is_enable;
6558
6559   /* send it... */
6560   S (mp);
6561
6562   /* Wait for a reply... */
6563   W (ret);
6564   return ret;
6565 }
6566
6567 static int
6568 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6569 {
6570   unformat_input_t *i = vam->input;
6571   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6572   u32 sw_if_index = 0;
6573   u8 sw_if_index_set = 0;
6574   u8 is_enable = 1;
6575   u8 is_ipv6 = 0;
6576   int ret;
6577
6578   /* Parse args required to build the message */
6579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580     {
6581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "enable"))
6586         is_enable = 1;
6587       else if (unformat (i, "disable"))
6588         is_enable = 0;
6589       else if (unformat (i, "ip4"))
6590         is_ipv6 = 0;
6591       else if (unformat (i, "ip6"))
6592         is_ipv6 = 1;
6593       else
6594         break;
6595     }
6596
6597   if (sw_if_index_set == 0)
6598     {
6599       errmsg ("missing interface name or sw_if_index");
6600       return -99;
6601     }
6602
6603   /* Construct the API message */
6604   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6605
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->enable = is_enable;
6608   mp->is_ipv6 = is_ipv6;
6609
6610   /* send it... */
6611   S (mp);
6612
6613   /* Wait for a reply... */
6614   W (ret);
6615   return ret;
6616 }
6617
6618 static int
6619 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_sw_interface_set_geneve_bypass_t *mp;
6623   u32 sw_if_index = 0;
6624   u8 sw_if_index_set = 0;
6625   u8 is_enable = 1;
6626   u8 is_ipv6 = 0;
6627   int ret;
6628
6629   /* Parse args required to build the message */
6630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631     {
6632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6633         sw_if_index_set = 1;
6634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6635         sw_if_index_set = 1;
6636       else if (unformat (i, "enable"))
6637         is_enable = 1;
6638       else if (unformat (i, "disable"))
6639         is_enable = 0;
6640       else if (unformat (i, "ip4"))
6641         is_ipv6 = 0;
6642       else if (unformat (i, "ip6"))
6643         is_ipv6 = 1;
6644       else
6645         break;
6646     }
6647
6648   if (sw_if_index_set == 0)
6649     {
6650       errmsg ("missing interface name or sw_if_index");
6651       return -99;
6652     }
6653
6654   /* Construct the API message */
6655   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6656
6657   mp->sw_if_index = ntohl (sw_if_index);
6658   mp->enable = is_enable;
6659   mp->is_ipv6 = is_ipv6;
6660
6661   /* send it... */
6662   S (mp);
6663
6664   /* Wait for a reply... */
6665   W (ret);
6666   return ret;
6667 }
6668
6669 static int
6670 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6671 {
6672   unformat_input_t *i = vam->input;
6673   vl_api_sw_interface_set_l2_xconnect_t *mp;
6674   u32 rx_sw_if_index;
6675   u8 rx_sw_if_index_set = 0;
6676   u32 tx_sw_if_index;
6677   u8 tx_sw_if_index_set = 0;
6678   u8 enable = 1;
6679   int ret;
6680
6681   /* Parse args required to build the message */
6682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683     {
6684       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6685         rx_sw_if_index_set = 1;
6686       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6687         tx_sw_if_index_set = 1;
6688       else if (unformat (i, "rx"))
6689         {
6690           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691             {
6692               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6693                             &rx_sw_if_index))
6694                 rx_sw_if_index_set = 1;
6695             }
6696           else
6697             break;
6698         }
6699       else if (unformat (i, "tx"))
6700         {
6701           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6702             {
6703               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6704                             &tx_sw_if_index))
6705                 tx_sw_if_index_set = 1;
6706             }
6707           else
6708             break;
6709         }
6710       else if (unformat (i, "enable"))
6711         enable = 1;
6712       else if (unformat (i, "disable"))
6713         enable = 0;
6714       else
6715         break;
6716     }
6717
6718   if (rx_sw_if_index_set == 0)
6719     {
6720       errmsg ("missing rx interface name or rx_sw_if_index");
6721       return -99;
6722     }
6723
6724   if (enable && (tx_sw_if_index_set == 0))
6725     {
6726       errmsg ("missing tx interface name or tx_sw_if_index");
6727       return -99;
6728     }
6729
6730   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6731
6732   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6733   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6734   mp->enable = enable;
6735
6736   S (mp);
6737   W (ret);
6738   return ret;
6739 }
6740
6741 static int
6742 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6743 {
6744   unformat_input_t *i = vam->input;
6745   vl_api_sw_interface_set_l2_bridge_t *mp;
6746   vl_api_l2_port_type_t port_type;
6747   u32 rx_sw_if_index;
6748   u8 rx_sw_if_index_set = 0;
6749   u32 bd_id;
6750   u8 bd_id_set = 0;
6751   u32 shg = 0;
6752   u8 enable = 1;
6753   int ret;
6754
6755   port_type = L2_API_PORT_TYPE_NORMAL;
6756
6757   /* Parse args required to build the message */
6758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6759     {
6760       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6761         rx_sw_if_index_set = 1;
6762       else if (unformat (i, "bd_id %d", &bd_id))
6763         bd_id_set = 1;
6764       else
6765         if (unformat
6766             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6767         rx_sw_if_index_set = 1;
6768       else if (unformat (i, "shg %d", &shg))
6769         ;
6770       else if (unformat (i, "bvi"))
6771         port_type = L2_API_PORT_TYPE_BVI;
6772       else if (unformat (i, "uu-fwd"))
6773         port_type = L2_API_PORT_TYPE_UU_FWD;
6774       else if (unformat (i, "enable"))
6775         enable = 1;
6776       else if (unformat (i, "disable"))
6777         enable = 0;
6778       else
6779         break;
6780     }
6781
6782   if (rx_sw_if_index_set == 0)
6783     {
6784       errmsg ("missing rx interface name or sw_if_index");
6785       return -99;
6786     }
6787
6788   if (enable && (bd_id_set == 0))
6789     {
6790       errmsg ("missing bridge domain");
6791       return -99;
6792     }
6793
6794   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6795
6796   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6797   mp->bd_id = ntohl (bd_id);
6798   mp->shg = (u8) shg;
6799   mp->port_type = ntohl (port_type);
6800   mp->enable = enable;
6801
6802   S (mp);
6803   W (ret);
6804   return ret;
6805 }
6806
6807 static int
6808 api_bridge_domain_dump (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_bridge_domain_dump_t *mp;
6812   vl_api_control_ping_t *mp_ping;
6813   u32 bd_id = ~0;
6814   int ret;
6815
6816   /* Parse args required to build the message */
6817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6818     {
6819       if (unformat (i, "bd_id %d", &bd_id))
6820         ;
6821       else
6822         break;
6823     }
6824
6825   M (BRIDGE_DOMAIN_DUMP, mp);
6826   mp->bd_id = ntohl (bd_id);
6827   S (mp);
6828
6829   /* Use a control ping for synchronization */
6830   MPING (CONTROL_PING, mp_ping);
6831   S (mp_ping);
6832
6833   W (ret);
6834   return ret;
6835 }
6836
6837 static int
6838 api_bridge_domain_add_del (vat_main_t * vam)
6839 {
6840   unformat_input_t *i = vam->input;
6841   vl_api_bridge_domain_add_del_t *mp;
6842   u32 bd_id = ~0;
6843   u8 is_add = 1;
6844   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6845   u8 *bd_tag = NULL;
6846   u32 mac_age = 0;
6847   int ret;
6848
6849   /* Parse args required to build the message */
6850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6851     {
6852       if (unformat (i, "bd_id %d", &bd_id))
6853         ;
6854       else if (unformat (i, "flood %d", &flood))
6855         ;
6856       else if (unformat (i, "uu-flood %d", &uu_flood))
6857         ;
6858       else if (unformat (i, "forward %d", &forward))
6859         ;
6860       else if (unformat (i, "learn %d", &learn))
6861         ;
6862       else if (unformat (i, "arp-term %d", &arp_term))
6863         ;
6864       else if (unformat (i, "mac-age %d", &mac_age))
6865         ;
6866       else if (unformat (i, "bd-tag %s", &bd_tag))
6867         ;
6868       else if (unformat (i, "del"))
6869         {
6870           is_add = 0;
6871           flood = uu_flood = forward = learn = 0;
6872         }
6873       else
6874         break;
6875     }
6876
6877   if (bd_id == ~0)
6878     {
6879       errmsg ("missing bridge domain");
6880       ret = -99;
6881       goto done;
6882     }
6883
6884   if (mac_age > 255)
6885     {
6886       errmsg ("mac age must be less than 256 ");
6887       ret = -99;
6888       goto done;
6889     }
6890
6891   if ((bd_tag) && (vec_len (bd_tag) > 63))
6892     {
6893       errmsg ("bd-tag cannot be longer than 63");
6894       ret = -99;
6895       goto done;
6896     }
6897
6898   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6899
6900   mp->bd_id = ntohl (bd_id);
6901   mp->flood = flood;
6902   mp->uu_flood = uu_flood;
6903   mp->forward = forward;
6904   mp->learn = learn;
6905   mp->arp_term = arp_term;
6906   mp->is_add = is_add;
6907   mp->mac_age = (u8) mac_age;
6908   if (bd_tag)
6909     {
6910       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6911       mp->bd_tag[vec_len (bd_tag)] = 0;
6912     }
6913   S (mp);
6914   W (ret);
6915
6916 done:
6917   vec_free (bd_tag);
6918   return ret;
6919 }
6920
6921 static int
6922 api_l2fib_flush_bd (vat_main_t * vam)
6923 {
6924   unformat_input_t *i = vam->input;
6925   vl_api_l2fib_flush_bd_t *mp;
6926   u32 bd_id = ~0;
6927   int ret;
6928
6929   /* Parse args required to build the message */
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "bd_id %d", &bd_id));
6933       else
6934         break;
6935     }
6936
6937   if (bd_id == ~0)
6938     {
6939       errmsg ("missing bridge domain");
6940       return -99;
6941     }
6942
6943   M (L2FIB_FLUSH_BD, mp);
6944
6945   mp->bd_id = htonl (bd_id);
6946
6947   S (mp);
6948   W (ret);
6949   return ret;
6950 }
6951
6952 static int
6953 api_l2fib_flush_int (vat_main_t * vam)
6954 {
6955   unformat_input_t *i = vam->input;
6956   vl_api_l2fib_flush_int_t *mp;
6957   u32 sw_if_index = ~0;
6958   int ret;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "sw_if_index %d", &sw_if_index));
6964       else
6965         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6966       else
6967         break;
6968     }
6969
6970   if (sw_if_index == ~0)
6971     {
6972       errmsg ("missing interface name or sw_if_index");
6973       return -99;
6974     }
6975
6976   M (L2FIB_FLUSH_INT, mp);
6977
6978   mp->sw_if_index = ntohl (sw_if_index);
6979
6980   S (mp);
6981   W (ret);
6982   return ret;
6983 }
6984
6985 static int
6986 api_l2fib_add_del (vat_main_t * vam)
6987 {
6988   unformat_input_t *i = vam->input;
6989   vl_api_l2fib_add_del_t *mp;
6990   f64 timeout;
6991   u8 mac[6] = { 0 };
6992   u8 mac_set = 0;
6993   u32 bd_id;
6994   u8 bd_id_set = 0;
6995   u32 sw_if_index = 0;
6996   u8 sw_if_index_set = 0;
6997   u8 is_add = 1;
6998   u8 static_mac = 0;
6999   u8 filter_mac = 0;
7000   u8 bvi_mac = 0;
7001   int count = 1;
7002   f64 before = 0;
7003   int j;
7004
7005   /* Parse args required to build the message */
7006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7007     {
7008       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7009         mac_set = 1;
7010       else if (unformat (i, "bd_id %d", &bd_id))
7011         bd_id_set = 1;
7012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if"))
7015         {
7016           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017             {
7018               if (unformat
7019                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7020                 sw_if_index_set = 1;
7021             }
7022           else
7023             break;
7024         }
7025       else if (unformat (i, "static"))
7026         static_mac = 1;
7027       else if (unformat (i, "filter"))
7028         {
7029           filter_mac = 1;
7030           static_mac = 1;
7031         }
7032       else if (unformat (i, "bvi"))
7033         {
7034           bvi_mac = 1;
7035           static_mac = 1;
7036         }
7037       else if (unformat (i, "del"))
7038         is_add = 0;
7039       else if (unformat (i, "count %d", &count))
7040         ;
7041       else
7042         break;
7043     }
7044
7045   if (mac_set == 0)
7046     {
7047       errmsg ("missing mac address");
7048       return -99;
7049     }
7050
7051   if (bd_id_set == 0)
7052     {
7053       errmsg ("missing bridge domain");
7054       return -99;
7055     }
7056
7057   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7058     {
7059       errmsg ("missing interface name or sw_if_index");
7060       return -99;
7061     }
7062
7063   if (count > 1)
7064     {
7065       /* Turn on async mode */
7066       vam->async_mode = 1;
7067       vam->async_errors = 0;
7068       before = vat_time_now (vam);
7069     }
7070
7071   for (j = 0; j < count; j++)
7072     {
7073       M (L2FIB_ADD_DEL, mp);
7074
7075       clib_memcpy (mp->mac, mac, 6);
7076       mp->bd_id = ntohl (bd_id);
7077       mp->is_add = is_add;
7078       mp->sw_if_index = ntohl (sw_if_index);
7079
7080       if (is_add)
7081         {
7082           mp->static_mac = static_mac;
7083           mp->filter_mac = filter_mac;
7084           mp->bvi_mac = bvi_mac;
7085         }
7086       increment_mac_address (mac);
7087       /* send it... */
7088       S (mp);
7089     }
7090
7091   if (count > 1)
7092     {
7093       vl_api_control_ping_t *mp_ping;
7094       f64 after;
7095
7096       /* Shut off async mode */
7097       vam->async_mode = 0;
7098
7099       MPING (CONTROL_PING, mp_ping);
7100       S (mp_ping);
7101
7102       timeout = vat_time_now (vam) + 1.0;
7103       while (vat_time_now (vam) < timeout)
7104         if (vam->result_ready == 1)
7105           goto out;
7106       vam->retval = -99;
7107
7108     out:
7109       if (vam->retval == -99)
7110         errmsg ("timeout");
7111
7112       if (vam->async_errors > 0)
7113         {
7114           errmsg ("%d asynchronous errors", vam->async_errors);
7115           vam->retval = -98;
7116         }
7117       vam->async_errors = 0;
7118       after = vat_time_now (vam);
7119
7120       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7121              count, after - before, count / (after - before));
7122     }
7123   else
7124     {
7125       int ret;
7126
7127       /* Wait for a reply... */
7128       W (ret);
7129       return ret;
7130     }
7131   /* Return the good/bad news */
7132   return (vam->retval);
7133 }
7134
7135 static int
7136 api_bridge_domain_set_mac_age (vat_main_t * vam)
7137 {
7138   unformat_input_t *i = vam->input;
7139   vl_api_bridge_domain_set_mac_age_t *mp;
7140   u32 bd_id = ~0;
7141   u32 mac_age = 0;
7142   int ret;
7143
7144   /* Parse args required to build the message */
7145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7146     {
7147       if (unformat (i, "bd_id %d", &bd_id));
7148       else if (unformat (i, "mac-age %d", &mac_age));
7149       else
7150         break;
7151     }
7152
7153   if (bd_id == ~0)
7154     {
7155       errmsg ("missing bridge domain");
7156       return -99;
7157     }
7158
7159   if (mac_age > 255)
7160     {
7161       errmsg ("mac age must be less than 256 ");
7162       return -99;
7163     }
7164
7165   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7166
7167   mp->bd_id = htonl (bd_id);
7168   mp->mac_age = (u8) mac_age;
7169
7170   S (mp);
7171   W (ret);
7172   return ret;
7173 }
7174
7175 static int
7176 api_l2_flags (vat_main_t * vam)
7177 {
7178   unformat_input_t *i = vam->input;
7179   vl_api_l2_flags_t *mp;
7180   u32 sw_if_index;
7181   u32 flags = 0;
7182   u8 sw_if_index_set = 0;
7183   u8 is_set = 0;
7184   int ret;
7185
7186   /* Parse args required to build the message */
7187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7188     {
7189       if (unformat (i, "sw_if_index %d", &sw_if_index))
7190         sw_if_index_set = 1;
7191       else if (unformat (i, "sw_if"))
7192         {
7193           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7194             {
7195               if (unformat
7196                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7197                 sw_if_index_set = 1;
7198             }
7199           else
7200             break;
7201         }
7202       else if (unformat (i, "learn"))
7203         flags |= L2_LEARN;
7204       else if (unformat (i, "forward"))
7205         flags |= L2_FWD;
7206       else if (unformat (i, "flood"))
7207         flags |= L2_FLOOD;
7208       else if (unformat (i, "uu-flood"))
7209         flags |= L2_UU_FLOOD;
7210       else if (unformat (i, "arp-term"))
7211         flags |= L2_ARP_TERM;
7212       else if (unformat (i, "off"))
7213         is_set = 0;
7214       else if (unformat (i, "disable"))
7215         is_set = 0;
7216       else
7217         break;
7218     }
7219
7220   if (sw_if_index_set == 0)
7221     {
7222       errmsg ("missing interface name or sw_if_index");
7223       return -99;
7224     }
7225
7226   M (L2_FLAGS, mp);
7227
7228   mp->sw_if_index = ntohl (sw_if_index);
7229   mp->feature_bitmap = ntohl (flags);
7230   mp->is_set = is_set;
7231
7232   S (mp);
7233   W (ret);
7234   return ret;
7235 }
7236
7237 static int
7238 api_bridge_flags (vat_main_t * vam)
7239 {
7240   unformat_input_t *i = vam->input;
7241   vl_api_bridge_flags_t *mp;
7242   u32 bd_id;
7243   u8 bd_id_set = 0;
7244   u8 is_set = 1;
7245   bd_flags_t flags = 0;
7246   int ret;
7247
7248   /* Parse args required to build the message */
7249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7250     {
7251       if (unformat (i, "bd_id %d", &bd_id))
7252         bd_id_set = 1;
7253       else if (unformat (i, "learn"))
7254         flags |= BRIDGE_API_FLAG_LEARN;
7255       else if (unformat (i, "forward"))
7256         flags |= BRIDGE_API_FLAG_FWD;
7257       else if (unformat (i, "flood"))
7258         flags |= BRIDGE_API_FLAG_FLOOD;
7259       else if (unformat (i, "uu-flood"))
7260         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7261       else if (unformat (i, "arp-term"))
7262         flags |= BRIDGE_API_FLAG_ARP_TERM;
7263       else if (unformat (i, "off"))
7264         is_set = 0;
7265       else if (unformat (i, "disable"))
7266         is_set = 0;
7267       else
7268         break;
7269     }
7270
7271   if (bd_id_set == 0)
7272     {
7273       errmsg ("missing bridge domain");
7274       return -99;
7275     }
7276
7277   M (BRIDGE_FLAGS, mp);
7278
7279   mp->bd_id = ntohl (bd_id);
7280   mp->flags = ntohl (flags);
7281   mp->is_set = is_set;
7282
7283   S (mp);
7284   W (ret);
7285   return ret;
7286 }
7287
7288 static int
7289 api_bd_ip_mac_add_del (vat_main_t * vam)
7290 {
7291   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7292   vl_api_mac_address_t mac = { 0 };
7293   unformat_input_t *i = vam->input;
7294   vl_api_bd_ip_mac_add_del_t *mp;
7295   ip46_type_t type;
7296   u32 bd_id;
7297   u8 is_ipv6 = 0;
7298   u8 is_add = 1;
7299   u8 bd_id_set = 0;
7300   u8 ip_set = 0;
7301   u8 mac_set = 0;
7302   u8 macaddr[6];
7303   int ret;
7304
7305
7306   /* Parse args required to build the message */
7307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7308     {
7309       if (unformat (i, "bd_id %d", &bd_id))
7310         {
7311           bd_id_set++;
7312         }
7313       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7314         {
7315           ip_set++;
7316         }
7317       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7318         {
7319           mac_set++;
7320         }
7321       else if (unformat (i, "del"))
7322         is_add = 0;
7323       else
7324         break;
7325     }
7326
7327   if (bd_id_set == 0)
7328     {
7329       errmsg ("missing bridge domain");
7330       return -99;
7331     }
7332   else if (ip_set == 0)
7333     {
7334       errmsg ("missing IP address");
7335       return -99;
7336     }
7337   else if (mac_set == 0)
7338     {
7339       errmsg ("missing MAC address");
7340       return -99;
7341     }
7342
7343   M (BD_IP_MAC_ADD_DEL, mp);
7344
7345   mp->bd_id = ntohl (bd_id);
7346   mp->is_add = is_add;
7347
7348   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7349   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7350
7351   S (mp);
7352   W (ret);
7353   return ret;
7354 }
7355
7356 static int
7357 api_bd_ip_mac_flush (vat_main_t * vam)
7358 {
7359   unformat_input_t *i = vam->input;
7360   vl_api_bd_ip_mac_flush_t *mp;
7361   u32 bd_id;
7362   u8 bd_id_set = 0;
7363   int ret;
7364
7365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (i, "bd_id %d", &bd_id))
7368         {
7369           bd_id_set++;
7370         }
7371       else
7372         break;
7373     }
7374
7375   if (bd_id_set == 0)
7376     {
7377       errmsg ("missing bridge domain");
7378       return -99;
7379     }
7380
7381   M (BD_IP_MAC_FLUSH, mp);
7382
7383   mp->bd_id = ntohl (bd_id);
7384
7385   S (mp);
7386   W (ret);
7387   return ret;
7388 }
7389
7390 static void vl_api_bd_ip_mac_details_t_handler
7391   (vl_api_bd_ip_mac_details_t * mp)
7392 {
7393   vat_main_t *vam = &vat_main;
7394   u8 *ip = 0;
7395
7396   if (!mp->is_ipv6)
7397     ip =
7398       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7399   else
7400     ip =
7401       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7402
7403   print (vam->ofp,
7404          "\n%-5d %-7s %-20U %-30s",
7405          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7406          format_ethernet_address, mp->mac_address, ip);
7407
7408   vec_free (ip);
7409 }
7410
7411 static void vl_api_bd_ip_mac_details_t_handler_json
7412   (vl_api_bd_ip_mac_details_t * mp)
7413 {
7414   vat_main_t *vam = &vat_main;
7415   vat_json_node_t *node = NULL;
7416
7417   if (VAT_JSON_ARRAY != vam->json_tree.type)
7418     {
7419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7420       vat_json_init_array (&vam->json_tree);
7421     }
7422   node = vat_json_array_add (&vam->json_tree);
7423
7424   vat_json_init_object (node);
7425   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7426   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7427   vat_json_object_add_string_copy (node, "mac_address",
7428                                    format (0, "%U", format_ethernet_address,
7429                                            &mp->mac_address));
7430   u8 *ip = 0;
7431
7432   if (!mp->is_ipv6)
7433     ip =
7434       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7435   else
7436     ip =
7437       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7438   vat_json_object_add_string_copy (node, "ip_address", ip);
7439   vec_free (ip);
7440 }
7441
7442 static int
7443 api_bd_ip_mac_dump (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_bd_ip_mac_dump_t *mp;
7447   vl_api_control_ping_t *mp_ping;
7448   int ret;
7449   u32 bd_id;
7450   u8 bd_id_set = 0;
7451
7452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7453     {
7454       if (unformat (i, "bd_id %d", &bd_id))
7455         {
7456           bd_id_set++;
7457         }
7458       else
7459         break;
7460     }
7461
7462   print (vam->ofp,
7463          "\n%-5s %-7s %-20s %-30s",
7464          "bd_id", "is_ipv6", "mac_address", "ip_address");
7465
7466   /* Dump Bridge Domain Ip to Mac entries */
7467   M (BD_IP_MAC_DUMP, mp);
7468
7469   if (bd_id_set)
7470     mp->bd_id = htonl (bd_id);
7471   else
7472     mp->bd_id = ~0;
7473
7474   S (mp);
7475
7476   /* Use a control ping for synchronization */
7477   MPING (CONTROL_PING, mp_ping);
7478   S (mp_ping);
7479
7480   W (ret);
7481   return ret;
7482 }
7483
7484 static int
7485 api_tap_create_v2 (vat_main_t * vam)
7486 {
7487   unformat_input_t *i = vam->input;
7488   vl_api_tap_create_v2_t *mp;
7489   u8 mac_address[6];
7490   u8 random_mac = 1;
7491   u32 id = ~0;
7492   u8 *host_if_name = 0;
7493   u8 *host_ns = 0;
7494   u8 host_mac_addr[6];
7495   u8 host_mac_addr_set = 0;
7496   u8 *host_bridge = 0;
7497   ip4_address_t host_ip4_addr;
7498   ip4_address_t host_ip4_gw;
7499   u8 host_ip4_gw_set = 0;
7500   u32 host_ip4_prefix_len = 0;
7501   ip6_address_t host_ip6_addr;
7502   ip6_address_t host_ip6_gw;
7503   u8 host_ip6_gw_set = 0;
7504   u32 host_ip6_prefix_len = 0;
7505   int ret;
7506   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7507
7508   clib_memset (mac_address, 0, sizeof (mac_address));
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7514         {
7515           random_mac = 0;
7516         }
7517       else if (unformat (i, "id %u", &id))
7518         ;
7519       else if (unformat (i, "host-if-name %s", &host_if_name))
7520         ;
7521       else if (unformat (i, "host-ns %s", &host_ns))
7522         ;
7523       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7524                          host_mac_addr))
7525         host_mac_addr_set = 1;
7526       else if (unformat (i, "host-bridge %s", &host_bridge))
7527         ;
7528       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7529                          &host_ip4_addr, &host_ip4_prefix_len))
7530         ;
7531       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7532                          &host_ip6_addr, &host_ip6_prefix_len))
7533         ;
7534       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7535                          &host_ip4_gw))
7536         host_ip4_gw_set = 1;
7537       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7538                          &host_ip6_gw))
7539         host_ip6_gw_set = 1;
7540       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7541         ;
7542       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7543         ;
7544       else
7545         break;
7546     }
7547
7548   if (vec_len (host_if_name) > 63)
7549     {
7550       errmsg ("tap name too long. ");
7551       return -99;
7552     }
7553   if (vec_len (host_ns) > 63)
7554     {
7555       errmsg ("host name space too long. ");
7556       return -99;
7557     }
7558   if (vec_len (host_bridge) > 63)
7559     {
7560       errmsg ("host bridge name too long. ");
7561       return -99;
7562     }
7563   if (host_ip4_prefix_len > 32)
7564     {
7565       errmsg ("host ip4 prefix length not valid. ");
7566       return -99;
7567     }
7568   if (host_ip6_prefix_len > 128)
7569     {
7570       errmsg ("host ip6 prefix length not valid. ");
7571       return -99;
7572     }
7573   if (!is_pow2 (rx_ring_sz))
7574     {
7575       errmsg ("rx ring size must be power of 2. ");
7576       return -99;
7577     }
7578   if (rx_ring_sz > 32768)
7579     {
7580       errmsg ("rx ring size must be 32768 or lower. ");
7581       return -99;
7582     }
7583   if (!is_pow2 (tx_ring_sz))
7584     {
7585       errmsg ("tx ring size must be power of 2. ");
7586       return -99;
7587     }
7588   if (tx_ring_sz > 32768)
7589     {
7590       errmsg ("tx ring size must be 32768 or lower. ");
7591       return -99;
7592     }
7593
7594   /* Construct the API message */
7595   M (TAP_CREATE_V2, mp);
7596
7597   mp->use_random_mac = random_mac;
7598
7599   mp->id = ntohl (id);
7600   mp->host_namespace_set = host_ns != 0;
7601   mp->host_bridge_set = host_bridge != 0;
7602   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7603   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7604   mp->rx_ring_sz = ntohs (rx_ring_sz);
7605   mp->tx_ring_sz = ntohs (tx_ring_sz);
7606
7607   if (random_mac == 0)
7608     clib_memcpy (mp->mac_address, mac_address, 6);
7609   if (host_mac_addr_set)
7610     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7611   if (host_if_name)
7612     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7613   if (host_ns)
7614     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7615   if (host_bridge)
7616     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7617   if (host_ip4_prefix_len)
7618     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7619   if (host_ip6_prefix_len)
7620     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7621   if (host_ip4_gw_set)
7622     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7623   if (host_ip6_gw_set)
7624     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7625
7626   vec_free (host_ns);
7627   vec_free (host_if_name);
7628   vec_free (host_bridge);
7629
7630   /* send it... */
7631   S (mp);
7632
7633   /* Wait for a reply... */
7634   W (ret);
7635   return ret;
7636 }
7637
7638 static int
7639 api_tap_delete_v2 (vat_main_t * vam)
7640 {
7641   unformat_input_t *i = vam->input;
7642   vl_api_tap_delete_v2_t *mp;
7643   u32 sw_if_index = ~0;
7644   u8 sw_if_index_set = 0;
7645   int ret;
7646
7647   /* Parse args required to build the message */
7648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7649     {
7650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7651         sw_if_index_set = 1;
7652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7653         sw_if_index_set = 1;
7654       else
7655         break;
7656     }
7657
7658   if (sw_if_index_set == 0)
7659     {
7660       errmsg ("missing vpp interface name. ");
7661       return -99;
7662     }
7663
7664   /* Construct the API message */
7665   M (TAP_DELETE_V2, mp);
7666
7667   mp->sw_if_index = ntohl (sw_if_index);
7668
7669   /* send it... */
7670   S (mp);
7671
7672   /* Wait for a reply... */
7673   W (ret);
7674   return ret;
7675 }
7676
7677 uword
7678 unformat_pci_addr (unformat_input_t * input, va_list * args)
7679 {
7680   struct pci_addr_t
7681   {
7682     u16 domain;
7683     u8 bus;
7684     u8 slot:5;
7685     u8 function:3;
7686   } *addr;
7687   addr = va_arg (*args, struct pci_addr_t *);
7688   u32 x[4];
7689
7690   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7691     return 0;
7692
7693   addr->domain = x[0];
7694   addr->bus = x[1];
7695   addr->slot = x[2];
7696   addr->function = x[3];
7697
7698   return 1;
7699 }
7700
7701 static int
7702 api_virtio_pci_create (vat_main_t * vam)
7703 {
7704   unformat_input_t *i = vam->input;
7705   vl_api_virtio_pci_create_t *mp;
7706   u8 mac_address[6];
7707   u8 random_mac = 1;
7708   u32 pci_addr = 0;
7709   u64 features = (u64) ~ (0ULL);
7710   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7711   int ret;
7712
7713   clib_memset (mac_address, 0, sizeof (mac_address));
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7719         {
7720           random_mac = 0;
7721         }
7722       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7723         ;
7724       else if (unformat (i, "features 0x%llx", &features))
7725         ;
7726       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7727         ;
7728       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7729         ;
7730       else
7731         break;
7732     }
7733
7734   if (pci_addr == 0)
7735     {
7736       errmsg ("pci address must be non zero. ");
7737       return -99;
7738     }
7739   if (!is_pow2 (rx_ring_sz))
7740     {
7741       errmsg ("rx ring size must be power of 2. ");
7742       return -99;
7743     }
7744   if (rx_ring_sz > 32768)
7745     {
7746       errmsg ("rx ring size must be 32768 or lower. ");
7747       return -99;
7748     }
7749   if (!is_pow2 (tx_ring_sz))
7750     {
7751       errmsg ("tx ring size must be power of 2. ");
7752       return -99;
7753     }
7754   if (tx_ring_sz > 32768)
7755     {
7756       errmsg ("tx ring size must be 32768 or lower. ");
7757       return -99;
7758     }
7759
7760   /* Construct the API message */
7761   M (VIRTIO_PCI_CREATE, mp);
7762
7763   mp->use_random_mac = random_mac;
7764
7765   mp->pci_addr = htonl (pci_addr);
7766   mp->features = clib_host_to_net_u64 (features);
7767   mp->rx_ring_sz = htons (rx_ring_sz);
7768   mp->tx_ring_sz = htons (tx_ring_sz);
7769
7770   if (random_mac == 0)
7771     clib_memcpy (mp->mac_address, mac_address, 6);
7772
7773   /* send it... */
7774   S (mp);
7775
7776   /* Wait for a reply... */
7777   W (ret);
7778   return ret;
7779 }
7780
7781 static int
7782 api_virtio_pci_delete (vat_main_t * vam)
7783 {
7784   unformat_input_t *i = vam->input;
7785   vl_api_virtio_pci_delete_t *mp;
7786   u32 sw_if_index = ~0;
7787   u8 sw_if_index_set = 0;
7788   int ret;
7789
7790   /* Parse args required to build the message */
7791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7792     {
7793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7794         sw_if_index_set = 1;
7795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7796         sw_if_index_set = 1;
7797       else
7798         break;
7799     }
7800
7801   if (sw_if_index_set == 0)
7802     {
7803       errmsg ("missing vpp interface name. ");
7804       return -99;
7805     }
7806
7807   /* Construct the API message */
7808   M (VIRTIO_PCI_DELETE, mp);
7809
7810   mp->sw_if_index = htonl (sw_if_index);
7811
7812   /* send it... */
7813   S (mp);
7814
7815   /* Wait for a reply... */
7816   W (ret);
7817   return ret;
7818 }
7819
7820 static int
7821 api_bond_create (vat_main_t * vam)
7822 {
7823   unformat_input_t *i = vam->input;
7824   vl_api_bond_create_t *mp;
7825   u8 mac_address[6];
7826   u8 custom_mac = 0;
7827   int ret;
7828   u8 mode;
7829   u8 lb;
7830   u8 mode_is_set = 0;
7831   u32 id = ~0;
7832
7833   clib_memset (mac_address, 0, sizeof (mac_address));
7834   lb = BOND_LB_L2;
7835
7836   /* Parse args required to build the message */
7837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7838     {
7839       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7840         mode_is_set = 1;
7841       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7842                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7843         ;
7844       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7845                          mac_address))
7846         custom_mac = 1;
7847       else if (unformat (i, "id %u", &id))
7848         ;
7849       else
7850         break;
7851     }
7852
7853   if (mode_is_set == 0)
7854     {
7855       errmsg ("Missing bond mode. ");
7856       return -99;
7857     }
7858
7859   /* Construct the API message */
7860   M (BOND_CREATE, mp);
7861
7862   mp->use_custom_mac = custom_mac;
7863
7864   mp->mode = mode;
7865   mp->lb = lb;
7866   mp->id = htonl (id);
7867
7868   if (custom_mac)
7869     clib_memcpy (mp->mac_address, mac_address, 6);
7870
7871   /* send it... */
7872   S (mp);
7873
7874   /* Wait for a reply... */
7875   W (ret);
7876   return ret;
7877 }
7878
7879 static int
7880 api_bond_delete (vat_main_t * vam)
7881 {
7882   unformat_input_t *i = vam->input;
7883   vl_api_bond_delete_t *mp;
7884   u32 sw_if_index = ~0;
7885   u8 sw_if_index_set = 0;
7886   int ret;
7887
7888   /* Parse args required to build the message */
7889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890     {
7891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7892         sw_if_index_set = 1;
7893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7894         sw_if_index_set = 1;
7895       else
7896         break;
7897     }
7898
7899   if (sw_if_index_set == 0)
7900     {
7901       errmsg ("missing vpp interface name. ");
7902       return -99;
7903     }
7904
7905   /* Construct the API message */
7906   M (BOND_DELETE, mp);
7907
7908   mp->sw_if_index = ntohl (sw_if_index);
7909
7910   /* send it... */
7911   S (mp);
7912
7913   /* Wait for a reply... */
7914   W (ret);
7915   return ret;
7916 }
7917
7918 static int
7919 api_bond_enslave (vat_main_t * vam)
7920 {
7921   unformat_input_t *i = vam->input;
7922   vl_api_bond_enslave_t *mp;
7923   u32 bond_sw_if_index;
7924   int ret;
7925   u8 is_passive;
7926   u8 is_long_timeout;
7927   u32 bond_sw_if_index_is_set = 0;
7928   u32 sw_if_index;
7929   u8 sw_if_index_is_set = 0;
7930
7931   /* Parse args required to build the message */
7932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7933     {
7934       if (unformat (i, "sw_if_index %d", &sw_if_index))
7935         sw_if_index_is_set = 1;
7936       else if (unformat (i, "bond %u", &bond_sw_if_index))
7937         bond_sw_if_index_is_set = 1;
7938       else if (unformat (i, "passive %d", &is_passive))
7939         ;
7940       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7941         ;
7942       else
7943         break;
7944     }
7945
7946   if (bond_sw_if_index_is_set == 0)
7947     {
7948       errmsg ("Missing bond sw_if_index. ");
7949       return -99;
7950     }
7951   if (sw_if_index_is_set == 0)
7952     {
7953       errmsg ("Missing slave sw_if_index. ");
7954       return -99;
7955     }
7956
7957   /* Construct the API message */
7958   M (BOND_ENSLAVE, mp);
7959
7960   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7961   mp->sw_if_index = ntohl (sw_if_index);
7962   mp->is_long_timeout = is_long_timeout;
7963   mp->is_passive = is_passive;
7964
7965   /* send it... */
7966   S (mp);
7967
7968   /* Wait for a reply... */
7969   W (ret);
7970   return ret;
7971 }
7972
7973 static int
7974 api_bond_detach_slave (vat_main_t * vam)
7975 {
7976   unformat_input_t *i = vam->input;
7977   vl_api_bond_detach_slave_t *mp;
7978   u32 sw_if_index = ~0;
7979   u8 sw_if_index_set = 0;
7980   int ret;
7981
7982   /* Parse args required to build the message */
7983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7984     {
7985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7986         sw_if_index_set = 1;
7987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7988         sw_if_index_set = 1;
7989       else
7990         break;
7991     }
7992
7993   if (sw_if_index_set == 0)
7994     {
7995       errmsg ("missing vpp interface name. ");
7996       return -99;
7997     }
7998
7999   /* Construct the API message */
8000   M (BOND_DETACH_SLAVE, mp);
8001
8002   mp->sw_if_index = ntohl (sw_if_index);
8003
8004   /* send it... */
8005   S (mp);
8006
8007   /* Wait for a reply... */
8008   W (ret);
8009   return ret;
8010 }
8011
8012 static int
8013 api_ip_table_add_del (vat_main_t * vam)
8014 {
8015   unformat_input_t *i = vam->input;
8016   vl_api_ip_table_add_del_t *mp;
8017   u32 table_id = ~0;
8018   u8 is_ipv6 = 0;
8019   u8 is_add = 1;
8020   int ret = 0;
8021
8022   /* Parse args required to build the message */
8023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8024     {
8025       if (unformat (i, "ipv6"))
8026         is_ipv6 = 1;
8027       else if (unformat (i, "del"))
8028         is_add = 0;
8029       else if (unformat (i, "add"))
8030         is_add = 1;
8031       else if (unformat (i, "table %d", &table_id))
8032         ;
8033       else
8034         {
8035           clib_warning ("parse error '%U'", format_unformat_error, i);
8036           return -99;
8037         }
8038     }
8039
8040   if (~0 == table_id)
8041     {
8042       errmsg ("missing table-ID");
8043       return -99;
8044     }
8045
8046   /* Construct the API message */
8047   M (IP_TABLE_ADD_DEL, mp);
8048
8049   mp->table_id = ntohl (table_id);
8050   mp->is_ipv6 = is_ipv6;
8051   mp->is_add = is_add;
8052
8053   /* send it... */
8054   S (mp);
8055
8056   /* Wait for a reply... */
8057   W (ret);
8058
8059   return ret;
8060 }
8061
8062 static int
8063 api_ip_add_del_route (vat_main_t * vam)
8064 {
8065   unformat_input_t *i = vam->input;
8066   vl_api_ip_add_del_route_t *mp;
8067   u32 sw_if_index = ~0, vrf_id = 0;
8068   u8 is_ipv6 = 0;
8069   u8 is_local = 0, is_drop = 0;
8070   u8 is_unreach = 0, is_prohibit = 0;
8071   u8 is_add = 1;
8072   u32 next_hop_weight = 1;
8073   u8 is_multipath = 0;
8074   u8 address_set = 0;
8075   u8 address_length_set = 0;
8076   u32 next_hop_table_id = 0;
8077   u32 resolve_attempts = 0;
8078   u32 dst_address_length = 0;
8079   u8 next_hop_set = 0;
8080   ip4_address_t v4_dst_address, v4_next_hop_address;
8081   ip6_address_t v6_dst_address, v6_next_hop_address;
8082   int count = 1;
8083   int j;
8084   f64 before = 0;
8085   u32 random_add_del = 0;
8086   u32 *random_vector = 0;
8087   uword *random_hash;
8088   u32 random_seed = 0xdeaddabe;
8089   u32 classify_table_index = ~0;
8090   u8 is_classify = 0;
8091   u8 resolve_host = 0, resolve_attached = 0;
8092   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8093   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8094   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8095
8096   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8097   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8098   /* Parse args required to build the message */
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8102         ;
8103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8104         ;
8105       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8106         {
8107           address_set = 1;
8108           is_ipv6 = 0;
8109         }
8110       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8111         {
8112           address_set = 1;
8113           is_ipv6 = 1;
8114         }
8115       else if (unformat (i, "/%d", &dst_address_length))
8116         {
8117           address_length_set = 1;
8118         }
8119
8120       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8121                                          &v4_next_hop_address))
8122         {
8123           next_hop_set = 1;
8124         }
8125       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8126                                          &v6_next_hop_address))
8127         {
8128           next_hop_set = 1;
8129         }
8130       else
8131         if (unformat
8132             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8133         {
8134           next_hop_set = 1;
8135         }
8136       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8137         {
8138           next_hop_set = 1;
8139         }
8140       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8141         ;
8142       else if (unformat (i, "weight %d", &next_hop_weight))
8143         ;
8144       else if (unformat (i, "drop"))
8145         {
8146           is_drop = 1;
8147         }
8148       else if (unformat (i, "null-send-unreach"))
8149         {
8150           is_unreach = 1;
8151         }
8152       else if (unformat (i, "null-send-prohibit"))
8153         {
8154           is_prohibit = 1;
8155         }
8156       else if (unformat (i, "local"))
8157         {
8158           is_local = 1;
8159         }
8160       else if (unformat (i, "classify %d", &classify_table_index))
8161         {
8162           is_classify = 1;
8163         }
8164       else if (unformat (i, "del"))
8165         is_add = 0;
8166       else if (unformat (i, "add"))
8167         is_add = 1;
8168       else if (unformat (i, "resolve-via-host"))
8169         resolve_host = 1;
8170       else if (unformat (i, "resolve-via-attached"))
8171         resolve_attached = 1;
8172       else if (unformat (i, "multipath"))
8173         is_multipath = 1;
8174       else if (unformat (i, "vrf %d", &vrf_id))
8175         ;
8176       else if (unformat (i, "count %d", &count))
8177         ;
8178       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8179         ;
8180       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8181         ;
8182       else if (unformat (i, "out-label %d", &next_hop_out_label))
8183         {
8184           vl_api_fib_mpls_label_t fib_label = {
8185             .label = ntohl (next_hop_out_label),
8186             .ttl = 64,
8187             .exp = 0,
8188           };
8189           vec_add1 (next_hop_out_label_stack, fib_label);
8190         }
8191       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8192         ;
8193       else if (unformat (i, "random"))
8194         random_add_del = 1;
8195       else if (unformat (i, "seed %d", &random_seed))
8196         ;
8197       else
8198         {
8199           clib_warning ("parse error '%U'", format_unformat_error, i);
8200           return -99;
8201         }
8202     }
8203
8204   if (!next_hop_set && !is_drop && !is_local &&
8205       !is_classify && !is_unreach && !is_prohibit &&
8206       MPLS_LABEL_INVALID == next_hop_via_label)
8207     {
8208       errmsg
8209         ("next hop / local / drop / unreach / prohibit / classify not set");
8210       return -99;
8211     }
8212
8213   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8214     {
8215       errmsg ("next hop and next-hop via label set");
8216       return -99;
8217     }
8218   if (address_set == 0)
8219     {
8220       errmsg ("missing addresses");
8221       return -99;
8222     }
8223
8224   if (address_length_set == 0)
8225     {
8226       errmsg ("missing address length");
8227       return -99;
8228     }
8229
8230   /* Generate a pile of unique, random routes */
8231   if (random_add_del)
8232     {
8233       u32 this_random_address;
8234       random_hash = hash_create (count, sizeof (uword));
8235
8236       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8237       for (j = 0; j <= count; j++)
8238         {
8239           do
8240             {
8241               this_random_address = random_u32 (&random_seed);
8242               this_random_address =
8243                 clib_host_to_net_u32 (this_random_address);
8244             }
8245           while (hash_get (random_hash, this_random_address));
8246           vec_add1 (random_vector, this_random_address);
8247           hash_set (random_hash, this_random_address, 1);
8248         }
8249       hash_free (random_hash);
8250       v4_dst_address.as_u32 = random_vector[0];
8251     }
8252
8253   if (count > 1)
8254     {
8255       /* Turn on async mode */
8256       vam->async_mode = 1;
8257       vam->async_errors = 0;
8258       before = vat_time_now (vam);
8259     }
8260
8261   for (j = 0; j < count; j++)
8262     {
8263       /* Construct the API message */
8264       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8265           vec_len (next_hop_out_label_stack));
8266
8267       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8268       mp->table_id = ntohl (vrf_id);
8269
8270       mp->is_add = is_add;
8271       mp->is_drop = is_drop;
8272       mp->is_unreach = is_unreach;
8273       mp->is_prohibit = is_prohibit;
8274       mp->is_ipv6 = is_ipv6;
8275       mp->is_local = is_local;
8276       mp->is_classify = is_classify;
8277       mp->is_multipath = is_multipath;
8278       mp->is_resolve_host = resolve_host;
8279       mp->is_resolve_attached = resolve_attached;
8280       mp->next_hop_weight = next_hop_weight;
8281       mp->next_hop_preference = 0;
8282       mp->dst_address_length = dst_address_length;
8283       mp->next_hop_table_id = ntohl (next_hop_table_id);
8284       mp->classify_table_index = ntohl (classify_table_index);
8285       mp->next_hop_via_label = ntohl (next_hop_via_label);
8286       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8287       if (0 != mp->next_hop_n_out_labels)
8288         {
8289           memcpy (mp->next_hop_out_label_stack,
8290                   next_hop_out_label_stack,
8291                   (vec_len (next_hop_out_label_stack) *
8292                    sizeof (vl_api_fib_mpls_label_t)));
8293           vec_free (next_hop_out_label_stack);
8294         }
8295
8296       if (is_ipv6)
8297         {
8298           clib_memcpy (mp->dst_address, &v6_dst_address,
8299                        sizeof (v6_dst_address));
8300           if (next_hop_set)
8301             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8302                          sizeof (v6_next_hop_address));
8303           increment_v6_address (&v6_dst_address);
8304         }
8305       else
8306         {
8307           clib_memcpy (mp->dst_address, &v4_dst_address,
8308                        sizeof (v4_dst_address));
8309           if (next_hop_set)
8310             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8311                          sizeof (v4_next_hop_address));
8312           if (random_add_del)
8313             v4_dst_address.as_u32 = random_vector[j + 1];
8314           else
8315             increment_v4_address (&v4_dst_address);
8316         }
8317       /* send it... */
8318       S (mp);
8319       /* If we receive SIGTERM, stop now... */
8320       if (vam->do_exit)
8321         break;
8322     }
8323
8324   /* When testing multiple add/del ops, use a control-ping to sync */
8325   if (count > 1)
8326     {
8327       vl_api_control_ping_t *mp_ping;
8328       f64 after;
8329       f64 timeout;
8330
8331       /* Shut off async mode */
8332       vam->async_mode = 0;
8333
8334       MPING (CONTROL_PING, mp_ping);
8335       S (mp_ping);
8336
8337       timeout = vat_time_now (vam) + 1.0;
8338       while (vat_time_now (vam) < timeout)
8339         if (vam->result_ready == 1)
8340           goto out;
8341       vam->retval = -99;
8342
8343     out:
8344       if (vam->retval == -99)
8345         errmsg ("timeout");
8346
8347       if (vam->async_errors > 0)
8348         {
8349           errmsg ("%d asynchronous errors", vam->async_errors);
8350           vam->retval = -98;
8351         }
8352       vam->async_errors = 0;
8353       after = vat_time_now (vam);
8354
8355       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8356       if (j > 0)
8357         count = j;
8358
8359       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8360              count, after - before, count / (after - before));
8361     }
8362   else
8363     {
8364       int ret;
8365
8366       /* Wait for a reply... */
8367       W (ret);
8368       return ret;
8369     }
8370
8371   /* Return the good/bad news */
8372   return (vam->retval);
8373 }
8374
8375 static int
8376 api_ip_mroute_add_del (vat_main_t * vam)
8377 {
8378   unformat_input_t *i = vam->input;
8379   vl_api_ip_mroute_add_del_t *mp;
8380   u32 sw_if_index = ~0, vrf_id = 0;
8381   u8 is_ipv6 = 0;
8382   u8 is_local = 0;
8383   u8 is_add = 1;
8384   u8 address_set = 0;
8385   u32 grp_address_length = 0;
8386   ip4_address_t v4_grp_address, v4_src_address;
8387   ip6_address_t v6_grp_address, v6_src_address;
8388   mfib_itf_flags_t iflags = 0;
8389   mfib_entry_flags_t eflags = 0;
8390   int ret;
8391
8392   /* Parse args required to build the message */
8393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8394     {
8395       if (unformat (i, "sw_if_index %d", &sw_if_index))
8396         ;
8397       else if (unformat (i, "%U %U",
8398                          unformat_ip4_address, &v4_src_address,
8399                          unformat_ip4_address, &v4_grp_address))
8400         {
8401           grp_address_length = 64;
8402           address_set = 1;
8403           is_ipv6 = 0;
8404         }
8405       else if (unformat (i, "%U %U",
8406                          unformat_ip6_address, &v6_src_address,
8407                          unformat_ip6_address, &v6_grp_address))
8408         {
8409           grp_address_length = 256;
8410           address_set = 1;
8411           is_ipv6 = 1;
8412         }
8413       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8414         {
8415           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8416           grp_address_length = 32;
8417           address_set = 1;
8418           is_ipv6 = 0;
8419         }
8420       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8421         {
8422           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8423           grp_address_length = 128;
8424           address_set = 1;
8425           is_ipv6 = 1;
8426         }
8427       else if (unformat (i, "/%d", &grp_address_length))
8428         ;
8429       else if (unformat (i, "local"))
8430         {
8431           is_local = 1;
8432         }
8433       else if (unformat (i, "del"))
8434         is_add = 0;
8435       else if (unformat (i, "add"))
8436         is_add = 1;
8437       else if (unformat (i, "vrf %d", &vrf_id))
8438         ;
8439       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8440         ;
8441       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8442         ;
8443       else
8444         {
8445           clib_warning ("parse error '%U'", format_unformat_error, i);
8446           return -99;
8447         }
8448     }
8449
8450   if (address_set == 0)
8451     {
8452       errmsg ("missing addresses\n");
8453       return -99;
8454     }
8455
8456   /* Construct the API message */
8457   M (IP_MROUTE_ADD_DEL, mp);
8458
8459   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8460   mp->table_id = ntohl (vrf_id);
8461
8462   mp->is_add = is_add;
8463   mp->is_ipv6 = is_ipv6;
8464   mp->is_local = is_local;
8465   mp->itf_flags = ntohl (iflags);
8466   mp->entry_flags = ntohl (eflags);
8467   mp->grp_address_length = grp_address_length;
8468   mp->grp_address_length = ntohs (mp->grp_address_length);
8469
8470   if (is_ipv6)
8471     {
8472       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8473       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8474     }
8475   else
8476     {
8477       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8478       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8479
8480     }
8481
8482   /* send it... */
8483   S (mp);
8484   /* Wait for a reply... */
8485   W (ret);
8486   return ret;
8487 }
8488
8489 static int
8490 api_mpls_table_add_del (vat_main_t * vam)
8491 {
8492   unformat_input_t *i = vam->input;
8493   vl_api_mpls_table_add_del_t *mp;
8494   u32 table_id = ~0;
8495   u8 is_add = 1;
8496   int ret = 0;
8497
8498   /* Parse args required to build the message */
8499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8500     {
8501       if (unformat (i, "table %d", &table_id))
8502         ;
8503       else if (unformat (i, "del"))
8504         is_add = 0;
8505       else if (unformat (i, "add"))
8506         is_add = 1;
8507       else
8508         {
8509           clib_warning ("parse error '%U'", format_unformat_error, i);
8510           return -99;
8511         }
8512     }
8513
8514   if (~0 == table_id)
8515     {
8516       errmsg ("missing table-ID");
8517       return -99;
8518     }
8519
8520   /* Construct the API message */
8521   M (MPLS_TABLE_ADD_DEL, mp);
8522
8523   mp->mt_table_id = ntohl (table_id);
8524   mp->mt_is_add = is_add;
8525
8526   /* send it... */
8527   S (mp);
8528
8529   /* Wait for a reply... */
8530   W (ret);
8531
8532   return ret;
8533 }
8534
8535 static int
8536 api_mpls_route_add_del (vat_main_t * vam)
8537 {
8538   unformat_input_t *i = vam->input;
8539   vl_api_mpls_route_add_del_t *mp;
8540   u32 sw_if_index = ~0, table_id = 0;
8541   u8 is_add = 1;
8542   u32 next_hop_weight = 1;
8543   u8 is_multipath = 0;
8544   u32 next_hop_table_id = 0;
8545   u8 next_hop_set = 0;
8546   ip4_address_t v4_next_hop_address = {
8547     .as_u32 = 0,
8548   };
8549   ip6_address_t v6_next_hop_address = { {0} };
8550   int count = 1;
8551   int j;
8552   f64 before = 0;
8553   u32 classify_table_index = ~0;
8554   u8 is_classify = 0;
8555   u8 resolve_host = 0, resolve_attached = 0;
8556   u8 is_interface_rx = 0;
8557   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8558   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8559   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8560   mpls_label_t local_label = MPLS_LABEL_INVALID;
8561   u8 is_eos = 0;
8562   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8568         ;
8569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8570         ;
8571       else if (unformat (i, "%d", &local_label))
8572         ;
8573       else if (unformat (i, "eos"))
8574         is_eos = 1;
8575       else if (unformat (i, "non-eos"))
8576         is_eos = 0;
8577       else if (unformat (i, "via %U", unformat_ip4_address,
8578                          &v4_next_hop_address))
8579         {
8580           next_hop_set = 1;
8581           next_hop_proto = DPO_PROTO_IP4;
8582         }
8583       else if (unformat (i, "via %U", unformat_ip6_address,
8584                          &v6_next_hop_address))
8585         {
8586           next_hop_set = 1;
8587           next_hop_proto = DPO_PROTO_IP6;
8588         }
8589       else if (unformat (i, "weight %d", &next_hop_weight))
8590         ;
8591       else if (unformat (i, "classify %d", &classify_table_index))
8592         {
8593           is_classify = 1;
8594         }
8595       else if (unformat (i, "del"))
8596         is_add = 0;
8597       else if (unformat (i, "add"))
8598         is_add = 1;
8599       else if (unformat (i, "resolve-via-host"))
8600         resolve_host = 1;
8601       else if (unformat (i, "resolve-via-attached"))
8602         resolve_attached = 1;
8603       else if (unformat (i, "multipath"))
8604         is_multipath = 1;
8605       else if (unformat (i, "count %d", &count))
8606         ;
8607       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8608         {
8609           next_hop_set = 1;
8610           next_hop_proto = DPO_PROTO_IP4;
8611         }
8612       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8613         {
8614           next_hop_set = 1;
8615           next_hop_proto = DPO_PROTO_IP6;
8616         }
8617       else
8618         if (unformat
8619             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8620              &sw_if_index))
8621         {
8622           next_hop_set = 1;
8623           next_hop_proto = DPO_PROTO_ETHERNET;
8624           is_interface_rx = 1;
8625         }
8626       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8627         {
8628           next_hop_set = 1;
8629           next_hop_proto = DPO_PROTO_ETHERNET;
8630           is_interface_rx = 1;
8631         }
8632       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8633         next_hop_set = 1;
8634       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8635         next_hop_set = 1;
8636       else if (unformat (i, "out-label %d", &next_hop_out_label))
8637         {
8638           vl_api_fib_mpls_label_t fib_label = {
8639             .label = ntohl (next_hop_out_label),
8640             .ttl = 64,
8641             .exp = 0,
8642           };
8643           vec_add1 (next_hop_out_label_stack, fib_label);
8644         }
8645       else
8646         {
8647           clib_warning ("parse error '%U'", format_unformat_error, i);
8648           return -99;
8649         }
8650     }
8651
8652   if (!next_hop_set && !is_classify)
8653     {
8654       errmsg ("next hop / classify not set");
8655       return -99;
8656     }
8657
8658   if (MPLS_LABEL_INVALID == local_label)
8659     {
8660       errmsg ("missing label");
8661       return -99;
8662     }
8663
8664   if (count > 1)
8665     {
8666       /* Turn on async mode */
8667       vam->async_mode = 1;
8668       vam->async_errors = 0;
8669       before = vat_time_now (vam);
8670     }
8671
8672   for (j = 0; j < count; j++)
8673     {
8674       /* Construct the API message */
8675       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8676           vec_len (next_hop_out_label_stack));
8677
8678       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8679       mp->mr_table_id = ntohl (table_id);
8680
8681       mp->mr_is_add = is_add;
8682       mp->mr_next_hop_proto = next_hop_proto;
8683       mp->mr_is_classify = is_classify;
8684       mp->mr_is_multipath = is_multipath;
8685       mp->mr_is_resolve_host = resolve_host;
8686       mp->mr_is_resolve_attached = resolve_attached;
8687       mp->mr_is_interface_rx = is_interface_rx;
8688       mp->mr_next_hop_weight = next_hop_weight;
8689       mp->mr_next_hop_preference = 0;
8690       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8691       mp->mr_classify_table_index = ntohl (classify_table_index);
8692       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8693       mp->mr_label = ntohl (local_label);
8694       mp->mr_eos = is_eos;
8695
8696       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8697       if (0 != mp->mr_next_hop_n_out_labels)
8698         {
8699           memcpy (mp->mr_next_hop_out_label_stack,
8700                   next_hop_out_label_stack,
8701                   vec_len (next_hop_out_label_stack) *
8702                   sizeof (vl_api_fib_mpls_label_t));
8703           vec_free (next_hop_out_label_stack);
8704         }
8705
8706       if (next_hop_set)
8707         {
8708           if (DPO_PROTO_IP4 == next_hop_proto)
8709             {
8710               clib_memcpy (mp->mr_next_hop,
8711                            &v4_next_hop_address,
8712                            sizeof (v4_next_hop_address));
8713             }
8714           else if (DPO_PROTO_IP6 == next_hop_proto)
8715
8716             {
8717               clib_memcpy (mp->mr_next_hop,
8718                            &v6_next_hop_address,
8719                            sizeof (v6_next_hop_address));
8720             }
8721         }
8722       local_label++;
8723
8724       /* send it... */
8725       S (mp);
8726       /* If we receive SIGTERM, stop now... */
8727       if (vam->do_exit)
8728         break;
8729     }
8730
8731   /* When testing multiple add/del ops, use a control-ping to sync */
8732   if (count > 1)
8733     {
8734       vl_api_control_ping_t *mp_ping;
8735       f64 after;
8736       f64 timeout;
8737
8738       /* Shut off async mode */
8739       vam->async_mode = 0;
8740
8741       MPING (CONTROL_PING, mp_ping);
8742       S (mp_ping);
8743
8744       timeout = vat_time_now (vam) + 1.0;
8745       while (vat_time_now (vam) < timeout)
8746         if (vam->result_ready == 1)
8747           goto out;
8748       vam->retval = -99;
8749
8750     out:
8751       if (vam->retval == -99)
8752         errmsg ("timeout");
8753
8754       if (vam->async_errors > 0)
8755         {
8756           errmsg ("%d asynchronous errors", vam->async_errors);
8757           vam->retval = -98;
8758         }
8759       vam->async_errors = 0;
8760       after = vat_time_now (vam);
8761
8762       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8763       if (j > 0)
8764         count = j;
8765
8766       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8767              count, after - before, count / (after - before));
8768     }
8769   else
8770     {
8771       int ret;
8772
8773       /* Wait for a reply... */
8774       W (ret);
8775       return ret;
8776     }
8777
8778   /* Return the good/bad news */
8779   return (vam->retval);
8780 }
8781
8782 static int
8783 api_mpls_ip_bind_unbind (vat_main_t * vam)
8784 {
8785   unformat_input_t *i = vam->input;
8786   vl_api_mpls_ip_bind_unbind_t *mp;
8787   u32 ip_table_id = 0;
8788   u8 is_bind = 1;
8789   u8 is_ip4 = 1;
8790   ip4_address_t v4_address;
8791   ip6_address_t v6_address;
8792   u32 address_length;
8793   u8 address_set = 0;
8794   mpls_label_t local_label = MPLS_LABEL_INVALID;
8795   int ret;
8796
8797   /* Parse args required to build the message */
8798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8799     {
8800       if (unformat (i, "%U/%d", unformat_ip4_address,
8801                     &v4_address, &address_length))
8802         {
8803           is_ip4 = 1;
8804           address_set = 1;
8805         }
8806       else if (unformat (i, "%U/%d", unformat_ip6_address,
8807                          &v6_address, &address_length))
8808         {
8809           is_ip4 = 0;
8810           address_set = 1;
8811         }
8812       else if (unformat (i, "%d", &local_label))
8813         ;
8814       else if (unformat (i, "table-id %d", &ip_table_id))
8815         ;
8816       else if (unformat (i, "unbind"))
8817         is_bind = 0;
8818       else if (unformat (i, "bind"))
8819         is_bind = 1;
8820       else
8821         {
8822           clib_warning ("parse error '%U'", format_unformat_error, i);
8823           return -99;
8824         }
8825     }
8826
8827   if (!address_set)
8828     {
8829       errmsg ("IP address not set");
8830       return -99;
8831     }
8832
8833   if (MPLS_LABEL_INVALID == local_label)
8834     {
8835       errmsg ("missing label");
8836       return -99;
8837     }
8838
8839   /* Construct the API message */
8840   M (MPLS_IP_BIND_UNBIND, mp);
8841
8842   mp->mb_is_bind = is_bind;
8843   mp->mb_is_ip4 = is_ip4;
8844   mp->mb_ip_table_id = ntohl (ip_table_id);
8845   mp->mb_mpls_table_id = 0;
8846   mp->mb_label = ntohl (local_label);
8847   mp->mb_address_length = address_length;
8848
8849   if (is_ip4)
8850     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8851   else
8852     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8853
8854   /* send it... */
8855   S (mp);
8856
8857   /* Wait for a reply... */
8858   W (ret);
8859   return ret;
8860 }
8861
8862 static int
8863 api_sr_mpls_policy_add (vat_main_t * vam)
8864 {
8865   unformat_input_t *i = vam->input;
8866   vl_api_sr_mpls_policy_add_t *mp;
8867   u32 bsid = 0;
8868   u32 weight = 1;
8869   u8 type = 0;
8870   u8 n_segments = 0;
8871   u32 sid;
8872   u32 *segments = NULL;
8873   int ret;
8874
8875   /* Parse args required to build the message */
8876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8877     {
8878       if (unformat (i, "bsid %d", &bsid))
8879         ;
8880       else if (unformat (i, "weight %d", &weight))
8881         ;
8882       else if (unformat (i, "spray"))
8883         type = 1;
8884       else if (unformat (i, "next %d", &sid))
8885         {
8886           n_segments += 1;
8887           vec_add1 (segments, htonl (sid));
8888         }
8889       else
8890         {
8891           clib_warning ("parse error '%U'", format_unformat_error, i);
8892           return -99;
8893         }
8894     }
8895
8896   if (bsid == 0)
8897     {
8898       errmsg ("bsid not set");
8899       return -99;
8900     }
8901
8902   if (n_segments == 0)
8903     {
8904       errmsg ("no sid in segment stack");
8905       return -99;
8906     }
8907
8908   /* Construct the API message */
8909   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8910
8911   mp->bsid = htonl (bsid);
8912   mp->weight = htonl (weight);
8913   mp->type = type;
8914   mp->n_segments = n_segments;
8915   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8916   vec_free (segments);
8917
8918   /* send it... */
8919   S (mp);
8920
8921   /* Wait for a reply... */
8922   W (ret);
8923   return ret;
8924 }
8925
8926 static int
8927 api_sr_mpls_policy_del (vat_main_t * vam)
8928 {
8929   unformat_input_t *i = vam->input;
8930   vl_api_sr_mpls_policy_del_t *mp;
8931   u32 bsid = 0;
8932   int ret;
8933
8934   /* Parse args required to build the message */
8935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8936     {
8937       if (unformat (i, "bsid %d", &bsid))
8938         ;
8939       else
8940         {
8941           clib_warning ("parse error '%U'", format_unformat_error, i);
8942           return -99;
8943         }
8944     }
8945
8946   if (bsid == 0)
8947     {
8948       errmsg ("bsid not set");
8949       return -99;
8950     }
8951
8952   /* Construct the API message */
8953   M (SR_MPLS_POLICY_DEL, mp);
8954
8955   mp->bsid = htonl (bsid);
8956
8957   /* send it... */
8958   S (mp);
8959
8960   /* Wait for a reply... */
8961   W (ret);
8962   return ret;
8963 }
8964
8965 static int
8966 api_bier_table_add_del (vat_main_t * vam)
8967 {
8968   unformat_input_t *i = vam->input;
8969   vl_api_bier_table_add_del_t *mp;
8970   u8 is_add = 1;
8971   u32 set = 0, sub_domain = 0, hdr_len = 3;
8972   mpls_label_t local_label = MPLS_LABEL_INVALID;
8973   int ret;
8974
8975   /* Parse args required to build the message */
8976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (i, "sub-domain %d", &sub_domain))
8979         ;
8980       else if (unformat (i, "set %d", &set))
8981         ;
8982       else if (unformat (i, "label %d", &local_label))
8983         ;
8984       else if (unformat (i, "hdr-len %d", &hdr_len))
8985         ;
8986       else if (unformat (i, "add"))
8987         is_add = 1;
8988       else if (unformat (i, "del"))
8989         is_add = 0;
8990       else
8991         {
8992           clib_warning ("parse error '%U'", format_unformat_error, i);
8993           return -99;
8994         }
8995     }
8996
8997   if (MPLS_LABEL_INVALID == local_label)
8998     {
8999       errmsg ("missing label\n");
9000       return -99;
9001     }
9002
9003   /* Construct the API message */
9004   M (BIER_TABLE_ADD_DEL, mp);
9005
9006   mp->bt_is_add = is_add;
9007   mp->bt_label = ntohl (local_label);
9008   mp->bt_tbl_id.bt_set = set;
9009   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9010   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9011
9012   /* send it... */
9013   S (mp);
9014
9015   /* Wait for a reply... */
9016   W (ret);
9017
9018   return (ret);
9019 }
9020
9021 static int
9022 api_bier_route_add_del (vat_main_t * vam)
9023 {
9024   unformat_input_t *i = vam->input;
9025   vl_api_bier_route_add_del_t *mp;
9026   u8 is_add = 1;
9027   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9028   ip4_address_t v4_next_hop_address;
9029   ip6_address_t v6_next_hop_address;
9030   u8 next_hop_set = 0;
9031   u8 next_hop_proto_is_ip4 = 1;
9032   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9033   int ret;
9034
9035   /* Parse args required to build the message */
9036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9037     {
9038       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9039         {
9040           next_hop_proto_is_ip4 = 1;
9041           next_hop_set = 1;
9042         }
9043       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9044         {
9045           next_hop_proto_is_ip4 = 0;
9046           next_hop_set = 1;
9047         }
9048       if (unformat (i, "sub-domain %d", &sub_domain))
9049         ;
9050       else if (unformat (i, "set %d", &set))
9051         ;
9052       else if (unformat (i, "hdr-len %d", &hdr_len))
9053         ;
9054       else if (unformat (i, "bp %d", &bp))
9055         ;
9056       else if (unformat (i, "add"))
9057         is_add = 1;
9058       else if (unformat (i, "del"))
9059         is_add = 0;
9060       else if (unformat (i, "out-label %d", &next_hop_out_label))
9061         ;
9062       else
9063         {
9064           clib_warning ("parse error '%U'", format_unformat_error, i);
9065           return -99;
9066         }
9067     }
9068
9069   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9070     {
9071       errmsg ("next hop / label set\n");
9072       return -99;
9073     }
9074   if (0 == bp)
9075     {
9076       errmsg ("bit=position not set\n");
9077       return -99;
9078     }
9079
9080   /* Construct the API message */
9081   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9082
9083   mp->br_is_add = is_add;
9084   mp->br_tbl_id.bt_set = set;
9085   mp->br_tbl_id.bt_sub_domain = sub_domain;
9086   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9087   mp->br_bp = ntohs (bp);
9088   mp->br_n_paths = 1;
9089   mp->br_paths[0].n_labels = 1;
9090   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9091   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9092
9093   if (next_hop_proto_is_ip4)
9094     {
9095       clib_memcpy (mp->br_paths[0].next_hop,
9096                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9097     }
9098   else
9099     {
9100       clib_memcpy (mp->br_paths[0].next_hop,
9101                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9102     }
9103
9104   /* send it... */
9105   S (mp);
9106
9107   /* Wait for a reply... */
9108   W (ret);
9109
9110   return (ret);
9111 }
9112
9113 static int
9114 api_proxy_arp_add_del (vat_main_t * vam)
9115 {
9116   unformat_input_t *i = vam->input;
9117   vl_api_proxy_arp_add_del_t *mp;
9118   u32 vrf_id = 0;
9119   u8 is_add = 1;
9120   ip4_address_t lo, hi;
9121   u8 range_set = 0;
9122   int ret;
9123
9124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9125     {
9126       if (unformat (i, "vrf %d", &vrf_id))
9127         ;
9128       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9129                          unformat_ip4_address, &hi))
9130         range_set = 1;
9131       else if (unformat (i, "del"))
9132         is_add = 0;
9133       else
9134         {
9135           clib_warning ("parse error '%U'", format_unformat_error, i);
9136           return -99;
9137         }
9138     }
9139
9140   if (range_set == 0)
9141     {
9142       errmsg ("address range not set");
9143       return -99;
9144     }
9145
9146   M (PROXY_ARP_ADD_DEL, mp);
9147
9148   mp->proxy.vrf_id = ntohl (vrf_id);
9149   mp->is_add = is_add;
9150   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9151   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9152
9153   S (mp);
9154   W (ret);
9155   return ret;
9156 }
9157
9158 static int
9159 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9160 {
9161   unformat_input_t *i = vam->input;
9162   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9163   u32 sw_if_index;
9164   u8 enable = 1;
9165   u8 sw_if_index_set = 0;
9166   int ret;
9167
9168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9169     {
9170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9171         sw_if_index_set = 1;
9172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9173         sw_if_index_set = 1;
9174       else if (unformat (i, "enable"))
9175         enable = 1;
9176       else if (unformat (i, "disable"))
9177         enable = 0;
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (sw_if_index_set == 0)
9186     {
9187       errmsg ("missing interface name or sw_if_index");
9188       return -99;
9189     }
9190
9191   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->enable_disable = enable;
9195
9196   S (mp);
9197   W (ret);
9198   return ret;
9199 }
9200
9201 static int
9202 api_mpls_tunnel_add_del (vat_main_t * vam)
9203 {
9204   unformat_input_t *i = vam->input;
9205   vl_api_mpls_tunnel_add_del_t *mp;
9206
9207   u8 is_add = 1;
9208   u8 l2_only = 0;
9209   u32 sw_if_index = ~0;
9210   u32 next_hop_sw_if_index = ~0;
9211   u32 next_hop_proto_is_ip4 = 1;
9212
9213   u32 next_hop_table_id = 0;
9214   ip4_address_t v4_next_hop_address = {
9215     .as_u32 = 0,
9216   };
9217   ip6_address_t v6_next_hop_address = { {0} };
9218   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9219   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9220   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9221   int ret;
9222
9223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9224     {
9225       if (unformat (i, "add"))
9226         is_add = 1;
9227       else
9228         if (unformat
9229             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9230         is_add = 0;
9231       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9232         is_add = 0;
9233       else if (unformat (i, "via %U",
9234                          unformat_ip4_address, &v4_next_hop_address))
9235         {
9236           next_hop_proto_is_ip4 = 1;
9237         }
9238       else if (unformat (i, "via %U",
9239                          unformat_ip6_address, &v6_next_hop_address))
9240         {
9241           next_hop_proto_is_ip4 = 0;
9242         }
9243       else if (unformat (i, "via-label %d", &next_hop_via_label))
9244         ;
9245       else
9246         if (unformat
9247             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9248         ;
9249       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9250         ;
9251       else if (unformat (i, "l2-only"))
9252         l2_only = 1;
9253       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9254         ;
9255       else if (unformat (i, "out-label %d", &next_hop_out_label))
9256         {
9257           vl_api_fib_mpls_label_t fib_label = {
9258             .label = ntohl (next_hop_out_label),
9259             .ttl = 64,
9260             .exp = 0,
9261           };
9262           vec_add1 (next_hop_out_label_stack, fib_label);
9263         }
9264       else
9265         {
9266           clib_warning ("parse error '%U'", format_unformat_error, i);
9267           return -99;
9268         }
9269     }
9270
9271   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9272       vec_len (next_hop_out_label_stack));
9273
9274   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9275   mp->mt_sw_if_index = ntohl (sw_if_index);
9276   mp->mt_is_add = is_add;
9277   mp->mt_l2_only = l2_only;
9278   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9279   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9280   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9281   mp->mt_next_hop_weight = 1;
9282   mp->mt_next_hop_preference = 0;
9283
9284   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9285
9286   if (0 != mp->mt_next_hop_n_out_labels)
9287     {
9288       clib_memcpy (mp->mt_next_hop_out_label_stack,
9289                    next_hop_out_label_stack,
9290                    (vec_len (next_hop_out_label_stack) *
9291                     sizeof (vl_api_fib_mpls_label_t)));
9292       vec_free (next_hop_out_label_stack);
9293     }
9294
9295   if (next_hop_proto_is_ip4)
9296     {
9297       clib_memcpy (mp->mt_next_hop,
9298                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9299     }
9300   else
9301     {
9302       clib_memcpy (mp->mt_next_hop,
9303                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9304     }
9305
9306   S (mp);
9307   W (ret);
9308   return ret;
9309 }
9310
9311 static int
9312 api_sw_interface_set_unnumbered (vat_main_t * vam)
9313 {
9314   unformat_input_t *i = vam->input;
9315   vl_api_sw_interface_set_unnumbered_t *mp;
9316   u32 sw_if_index;
9317   u32 unnum_sw_index = ~0;
9318   u8 is_add = 1;
9319   u8 sw_if_index_set = 0;
9320   int ret;
9321
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9329         ;
9330       else if (unformat (i, "del"))
9331         is_add = 0;
9332       else
9333         {
9334           clib_warning ("parse error '%U'", format_unformat_error, i);
9335           return -99;
9336         }
9337     }
9338
9339   if (sw_if_index_set == 0)
9340     {
9341       errmsg ("missing interface name or sw_if_index");
9342       return -99;
9343     }
9344
9345   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9346
9347   mp->sw_if_index = ntohl (sw_if_index);
9348   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9349   mp->is_add = is_add;
9350
9351   S (mp);
9352   W (ret);
9353   return ret;
9354 }
9355
9356 static int
9357 api_ip_neighbor_add_del (vat_main_t * vam)
9358 {
9359   unformat_input_t *i = vam->input;
9360   vl_api_ip_neighbor_add_del_t *mp;
9361   u32 sw_if_index;
9362   u8 sw_if_index_set = 0;
9363   u8 is_add = 1;
9364   u8 is_static = 0;
9365   u8 is_no_fib_entry = 0;
9366   u8 mac_address[6];
9367   u8 mac_set = 0;
9368   u8 v4_address_set = 0;
9369   u8 v6_address_set = 0;
9370   ip4_address_t v4address;
9371   ip6_address_t v6address;
9372   int ret;
9373
9374   clib_memset (mac_address, 0, sizeof (mac_address));
9375
9376   /* Parse args required to build the message */
9377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9378     {
9379       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9380         {
9381           mac_set = 1;
9382         }
9383       else if (unformat (i, "del"))
9384         is_add = 0;
9385       else
9386         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9387         sw_if_index_set = 1;
9388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "is_static"))
9391         is_static = 1;
9392       else if (unformat (i, "no-fib-entry"))
9393         is_no_fib_entry = 1;
9394       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9395         v4_address_set = 1;
9396       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9397         v6_address_set = 1;
9398       else
9399         {
9400           clib_warning ("parse error '%U'", format_unformat_error, i);
9401           return -99;
9402         }
9403     }
9404
9405   if (sw_if_index_set == 0)
9406     {
9407       errmsg ("missing interface name or sw_if_index");
9408       return -99;
9409     }
9410   if (v4_address_set && v6_address_set)
9411     {
9412       errmsg ("both v4 and v6 addresses set");
9413       return -99;
9414     }
9415   if (!v4_address_set && !v6_address_set)
9416     {
9417       errmsg ("no address set");
9418       return -99;
9419     }
9420
9421   /* Construct the API message */
9422   M (IP_NEIGHBOR_ADD_DEL, mp);
9423
9424   mp->sw_if_index = ntohl (sw_if_index);
9425   mp->is_add = is_add;
9426   mp->is_static = is_static;
9427   mp->is_no_adj_fib = is_no_fib_entry;
9428   if (mac_set)
9429     clib_memcpy (mp->mac_address, mac_address, 6);
9430   if (v6_address_set)
9431     {
9432       mp->is_ipv6 = 1;
9433       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9434     }
9435   else
9436     {
9437       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9438       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9439     }
9440
9441   /* send it... */
9442   S (mp);
9443
9444   /* Wait for a reply, return good/bad news  */
9445   W (ret);
9446   return ret;
9447 }
9448
9449 static int
9450 api_create_vlan_subif (vat_main_t * vam)
9451 {
9452   unformat_input_t *i = vam->input;
9453   vl_api_create_vlan_subif_t *mp;
9454   u32 sw_if_index;
9455   u8 sw_if_index_set = 0;
9456   u32 vlan_id;
9457   u8 vlan_id_set = 0;
9458   int ret;
9459
9460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (unformat (i, "sw_if_index %d", &sw_if_index))
9463         sw_if_index_set = 1;
9464       else
9465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9466         sw_if_index_set = 1;
9467       else if (unformat (i, "vlan %d", &vlan_id))
9468         vlan_id_set = 1;
9469       else
9470         {
9471           clib_warning ("parse error '%U'", format_unformat_error, i);
9472           return -99;
9473         }
9474     }
9475
9476   if (sw_if_index_set == 0)
9477     {
9478       errmsg ("missing interface name or sw_if_index");
9479       return -99;
9480     }
9481
9482   if (vlan_id_set == 0)
9483     {
9484       errmsg ("missing vlan_id");
9485       return -99;
9486     }
9487   M (CREATE_VLAN_SUBIF, mp);
9488
9489   mp->sw_if_index = ntohl (sw_if_index);
9490   mp->vlan_id = ntohl (vlan_id);
9491
9492   S (mp);
9493   W (ret);
9494   return ret;
9495 }
9496
9497 #define foreach_create_subif_bit                \
9498 _(no_tags)                                      \
9499 _(one_tag)                                      \
9500 _(two_tags)                                     \
9501 _(dot1ad)                                       \
9502 _(exact_match)                                  \
9503 _(default_sub)                                  \
9504 _(outer_vlan_id_any)                            \
9505 _(inner_vlan_id_any)
9506
9507 static int
9508 api_create_subif (vat_main_t * vam)
9509 {
9510   unformat_input_t *i = vam->input;
9511   vl_api_create_subif_t *mp;
9512   u32 sw_if_index;
9513   u8 sw_if_index_set = 0;
9514   u32 sub_id;
9515   u8 sub_id_set = 0;
9516   u32 no_tags = 0;
9517   u32 one_tag = 0;
9518   u32 two_tags = 0;
9519   u32 dot1ad = 0;
9520   u32 exact_match = 0;
9521   u32 default_sub = 0;
9522   u32 outer_vlan_id_any = 0;
9523   u32 inner_vlan_id_any = 0;
9524   u32 tmp;
9525   u16 outer_vlan_id = 0;
9526   u16 inner_vlan_id = 0;
9527   int ret;
9528
9529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9530     {
9531       if (unformat (i, "sw_if_index %d", &sw_if_index))
9532         sw_if_index_set = 1;
9533       else
9534         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9535         sw_if_index_set = 1;
9536       else if (unformat (i, "sub_id %d", &sub_id))
9537         sub_id_set = 1;
9538       else if (unformat (i, "outer_vlan_id %d", &tmp))
9539         outer_vlan_id = tmp;
9540       else if (unformat (i, "inner_vlan_id %d", &tmp))
9541         inner_vlan_id = tmp;
9542
9543 #define _(a) else if (unformat (i, #a)) a = 1 ;
9544       foreach_create_subif_bit
9545 #undef _
9546         else
9547         {
9548           clib_warning ("parse error '%U'", format_unformat_error, i);
9549           return -99;
9550         }
9551     }
9552
9553   if (sw_if_index_set == 0)
9554     {
9555       errmsg ("missing interface name or sw_if_index");
9556       return -99;
9557     }
9558
9559   if (sub_id_set == 0)
9560     {
9561       errmsg ("missing sub_id");
9562       return -99;
9563     }
9564   M (CREATE_SUBIF, mp);
9565
9566   mp->sw_if_index = ntohl (sw_if_index);
9567   mp->sub_id = ntohl (sub_id);
9568
9569 #define _(a) mp->a = a;
9570   foreach_create_subif_bit;
9571 #undef _
9572
9573   mp->outer_vlan_id = ntohs (outer_vlan_id);
9574   mp->inner_vlan_id = ntohs (inner_vlan_id);
9575
9576   S (mp);
9577   W (ret);
9578   return ret;
9579 }
9580
9581 static int
9582 api_oam_add_del (vat_main_t * vam)
9583 {
9584   unformat_input_t *i = vam->input;
9585   vl_api_oam_add_del_t *mp;
9586   u32 vrf_id = 0;
9587   u8 is_add = 1;
9588   ip4_address_t src, dst;
9589   u8 src_set = 0;
9590   u8 dst_set = 0;
9591   int ret;
9592
9593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9594     {
9595       if (unformat (i, "vrf %d", &vrf_id))
9596         ;
9597       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9598         src_set = 1;
9599       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9600         dst_set = 1;
9601       else if (unformat (i, "del"))
9602         is_add = 0;
9603       else
9604         {
9605           clib_warning ("parse error '%U'", format_unformat_error, i);
9606           return -99;
9607         }
9608     }
9609
9610   if (src_set == 0)
9611     {
9612       errmsg ("missing src addr");
9613       return -99;
9614     }
9615
9616   if (dst_set == 0)
9617     {
9618       errmsg ("missing dst addr");
9619       return -99;
9620     }
9621
9622   M (OAM_ADD_DEL, mp);
9623
9624   mp->vrf_id = ntohl (vrf_id);
9625   mp->is_add = is_add;
9626   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9627   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9628
9629   S (mp);
9630   W (ret);
9631   return ret;
9632 }
9633
9634 static int
9635 api_reset_fib (vat_main_t * vam)
9636 {
9637   unformat_input_t *i = vam->input;
9638   vl_api_reset_fib_t *mp;
9639   u32 vrf_id = 0;
9640   u8 is_ipv6 = 0;
9641   u8 vrf_id_set = 0;
9642
9643   int ret;
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "vrf %d", &vrf_id))
9647         vrf_id_set = 1;
9648       else if (unformat (i, "ipv6"))
9649         is_ipv6 = 1;
9650       else
9651         {
9652           clib_warning ("parse error '%U'", format_unformat_error, i);
9653           return -99;
9654         }
9655     }
9656
9657   if (vrf_id_set == 0)
9658     {
9659       errmsg ("missing vrf id");
9660       return -99;
9661     }
9662
9663   M (RESET_FIB, mp);
9664
9665   mp->vrf_id = ntohl (vrf_id);
9666   mp->is_ipv6 = is_ipv6;
9667
9668   S (mp);
9669   W (ret);
9670   return ret;
9671 }
9672
9673 static int
9674 api_dhcp_proxy_config (vat_main_t * vam)
9675 {
9676   unformat_input_t *i = vam->input;
9677   vl_api_dhcp_proxy_config_t *mp;
9678   u32 rx_vrf_id = 0;
9679   u32 server_vrf_id = 0;
9680   u8 is_add = 1;
9681   u8 v4_address_set = 0;
9682   u8 v6_address_set = 0;
9683   ip4_address_t v4address;
9684   ip6_address_t v6address;
9685   u8 v4_src_address_set = 0;
9686   u8 v6_src_address_set = 0;
9687   ip4_address_t v4srcaddress;
9688   ip6_address_t v6srcaddress;
9689   int ret;
9690
9691   /* Parse args required to build the message */
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "del"))
9695         is_add = 0;
9696       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9697         ;
9698       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9699         ;
9700       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9701         v4_address_set = 1;
9702       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9703         v6_address_set = 1;
9704       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9705         v4_src_address_set = 1;
9706       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9707         v6_src_address_set = 1;
9708       else
9709         break;
9710     }
9711
9712   if (v4_address_set && v6_address_set)
9713     {
9714       errmsg ("both v4 and v6 server addresses set");
9715       return -99;
9716     }
9717   if (!v4_address_set && !v6_address_set)
9718     {
9719       errmsg ("no server addresses set");
9720       return -99;
9721     }
9722
9723   if (v4_src_address_set && v6_src_address_set)
9724     {
9725       errmsg ("both v4 and v6  src addresses set");
9726       return -99;
9727     }
9728   if (!v4_src_address_set && !v6_src_address_set)
9729     {
9730       errmsg ("no src addresses set");
9731       return -99;
9732     }
9733
9734   if (!(v4_src_address_set && v4_address_set) &&
9735       !(v6_src_address_set && v6_address_set))
9736     {
9737       errmsg ("no matching server and src addresses set");
9738       return -99;
9739     }
9740
9741   /* Construct the API message */
9742   M (DHCP_PROXY_CONFIG, mp);
9743
9744   mp->is_add = is_add;
9745   mp->rx_vrf_id = ntohl (rx_vrf_id);
9746   mp->server_vrf_id = ntohl (server_vrf_id);
9747   if (v6_address_set)
9748     {
9749       mp->is_ipv6 = 1;
9750       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9751       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9752     }
9753   else
9754     {
9755       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9756       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9757     }
9758
9759   /* send it... */
9760   S (mp);
9761
9762   /* Wait for a reply, return good/bad news  */
9763   W (ret);
9764   return ret;
9765 }
9766
9767 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9768 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9769
9770 static void
9771 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9772 {
9773   vat_main_t *vam = &vat_main;
9774   u32 i, count = mp->count;
9775   vl_api_dhcp_server_t *s;
9776
9777   if (mp->is_ipv6)
9778     print (vam->ofp,
9779            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9780            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9781            ntohl (mp->rx_vrf_id),
9782            format_ip6_address, mp->dhcp_src_address,
9783            mp->vss_type, mp->vss_vpn_ascii_id,
9784            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9785   else
9786     print (vam->ofp,
9787            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9788            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9789            ntohl (mp->rx_vrf_id),
9790            format_ip4_address, mp->dhcp_src_address,
9791            mp->vss_type, mp->vss_vpn_ascii_id,
9792            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9793
9794   for (i = 0; i < count; i++)
9795     {
9796       s = &mp->servers[i];
9797
9798       if (mp->is_ipv6)
9799         print (vam->ofp,
9800                " Server Table-ID %d, Server Address %U",
9801                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9802       else
9803         print (vam->ofp,
9804                " Server Table-ID %d, Server Address %U",
9805                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9806     }
9807 }
9808
9809 static void vl_api_dhcp_proxy_details_t_handler_json
9810   (vl_api_dhcp_proxy_details_t * mp)
9811 {
9812   vat_main_t *vam = &vat_main;
9813   vat_json_node_t *node = NULL;
9814   u32 i, count = mp->count;
9815   struct in_addr ip4;
9816   struct in6_addr ip6;
9817   vl_api_dhcp_server_t *s;
9818
9819   if (VAT_JSON_ARRAY != vam->json_tree.type)
9820     {
9821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9822       vat_json_init_array (&vam->json_tree);
9823     }
9824   node = vat_json_array_add (&vam->json_tree);
9825
9826   vat_json_init_object (node);
9827   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9828   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9829                              sizeof (mp->vss_type));
9830   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9831                                    mp->vss_vpn_ascii_id);
9832   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9833   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9834
9835   if (mp->is_ipv6)
9836     {
9837       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9838       vat_json_object_add_ip6 (node, "src_address", ip6);
9839     }
9840   else
9841     {
9842       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9843       vat_json_object_add_ip4 (node, "src_address", ip4);
9844     }
9845
9846   for (i = 0; i < count; i++)
9847     {
9848       s = &mp->servers[i];
9849
9850       vat_json_object_add_uint (node, "server-table-id",
9851                                 ntohl (s->server_vrf_id));
9852
9853       if (mp->is_ipv6)
9854         {
9855           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9856           vat_json_object_add_ip4 (node, "src_address", ip4);
9857         }
9858       else
9859         {
9860           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9861           vat_json_object_add_ip6 (node, "server_address", ip6);
9862         }
9863     }
9864 }
9865
9866 static int
9867 api_dhcp_proxy_dump (vat_main_t * vam)
9868 {
9869   unformat_input_t *i = vam->input;
9870   vl_api_control_ping_t *mp_ping;
9871   vl_api_dhcp_proxy_dump_t *mp;
9872   u8 is_ipv6 = 0;
9873   int ret;
9874
9875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9876     {
9877       if (unformat (i, "ipv6"))
9878         is_ipv6 = 1;
9879       else
9880         {
9881           clib_warning ("parse error '%U'", format_unformat_error, i);
9882           return -99;
9883         }
9884     }
9885
9886   M (DHCP_PROXY_DUMP, mp);
9887
9888   mp->is_ip6 = is_ipv6;
9889   S (mp);
9890
9891   /* Use a control ping for synchronization */
9892   MPING (CONTROL_PING, mp_ping);
9893   S (mp_ping);
9894
9895   W (ret);
9896   return ret;
9897 }
9898
9899 static int
9900 api_dhcp_proxy_set_vss (vat_main_t * vam)
9901 {
9902   unformat_input_t *i = vam->input;
9903   vl_api_dhcp_proxy_set_vss_t *mp;
9904   u8 is_ipv6 = 0;
9905   u8 is_add = 1;
9906   u32 tbl_id = ~0;
9907   u8 vss_type = VSS_TYPE_DEFAULT;
9908   u8 *vpn_ascii_id = 0;
9909   u32 oui = 0;
9910   u32 fib_id = 0;
9911   int ret;
9912
9913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (i, "tbl_id %d", &tbl_id))
9916         ;
9917       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9918         vss_type = VSS_TYPE_ASCII;
9919       else if (unformat (i, "fib_id %d", &fib_id))
9920         vss_type = VSS_TYPE_VPN_ID;
9921       else if (unformat (i, "oui %d", &oui))
9922         vss_type = VSS_TYPE_VPN_ID;
9923       else if (unformat (i, "ipv6"))
9924         is_ipv6 = 1;
9925       else if (unformat (i, "del"))
9926         is_add = 0;
9927       else
9928         break;
9929     }
9930
9931   if (tbl_id == ~0)
9932     {
9933       errmsg ("missing tbl_id ");
9934       vec_free (vpn_ascii_id);
9935       return -99;
9936     }
9937
9938   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9939     {
9940       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9941       vec_free (vpn_ascii_id);
9942       return -99;
9943     }
9944
9945   M (DHCP_PROXY_SET_VSS, mp);
9946   mp->tbl_id = ntohl (tbl_id);
9947   mp->vss_type = vss_type;
9948   if (vpn_ascii_id)
9949     {
9950       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9951       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9952     }
9953   mp->vpn_index = ntohl (fib_id);
9954   mp->oui = ntohl (oui);
9955   mp->is_ipv6 = is_ipv6;
9956   mp->is_add = is_add;
9957
9958   S (mp);
9959   W (ret);
9960
9961   vec_free (vpn_ascii_id);
9962   return ret;
9963 }
9964
9965 static int
9966 api_dhcp_client_config (vat_main_t * vam)
9967 {
9968   unformat_input_t *i = vam->input;
9969   vl_api_dhcp_client_config_t *mp;
9970   u32 sw_if_index;
9971   u8 sw_if_index_set = 0;
9972   u8 is_add = 1;
9973   u8 *hostname = 0;
9974   u8 disable_event = 0;
9975   int ret;
9976
9977   /* Parse args required to build the message */
9978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9979     {
9980       if (unformat (i, "del"))
9981         is_add = 0;
9982       else
9983         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9984         sw_if_index_set = 1;
9985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9986         sw_if_index_set = 1;
9987       else if (unformat (i, "hostname %s", &hostname))
9988         ;
9989       else if (unformat (i, "disable_event"))
9990         disable_event = 1;
9991       else
9992         break;
9993     }
9994
9995   if (sw_if_index_set == 0)
9996     {
9997       errmsg ("missing interface name or sw_if_index");
9998       return -99;
9999     }
10000
10001   if (vec_len (hostname) > 63)
10002     {
10003       errmsg ("hostname too long");
10004     }
10005   vec_add1 (hostname, 0);
10006
10007   /* Construct the API message */
10008   M (DHCP_CLIENT_CONFIG, mp);
10009
10010   mp->is_add = is_add;
10011   mp->client.sw_if_index = htonl (sw_if_index);
10012   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10013   vec_free (hostname);
10014   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10015   mp->client.pid = htonl (getpid ());
10016
10017   /* send it... */
10018   S (mp);
10019
10020   /* Wait for a reply, return good/bad news  */
10021   W (ret);
10022   return ret;
10023 }
10024
10025 static int
10026 api_set_ip_flow_hash (vat_main_t * vam)
10027 {
10028   unformat_input_t *i = vam->input;
10029   vl_api_set_ip_flow_hash_t *mp;
10030   u32 vrf_id = 0;
10031   u8 is_ipv6 = 0;
10032   u8 vrf_id_set = 0;
10033   u8 src = 0;
10034   u8 dst = 0;
10035   u8 sport = 0;
10036   u8 dport = 0;
10037   u8 proto = 0;
10038   u8 reverse = 0;
10039   int ret;
10040
10041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10042     {
10043       if (unformat (i, "vrf %d", &vrf_id))
10044         vrf_id_set = 1;
10045       else if (unformat (i, "ipv6"))
10046         is_ipv6 = 1;
10047       else if (unformat (i, "src"))
10048         src = 1;
10049       else if (unformat (i, "dst"))
10050         dst = 1;
10051       else if (unformat (i, "sport"))
10052         sport = 1;
10053       else if (unformat (i, "dport"))
10054         dport = 1;
10055       else if (unformat (i, "proto"))
10056         proto = 1;
10057       else if (unformat (i, "reverse"))
10058         reverse = 1;
10059
10060       else
10061         {
10062           clib_warning ("parse error '%U'", format_unformat_error, i);
10063           return -99;
10064         }
10065     }
10066
10067   if (vrf_id_set == 0)
10068     {
10069       errmsg ("missing vrf id");
10070       return -99;
10071     }
10072
10073   M (SET_IP_FLOW_HASH, mp);
10074   mp->src = src;
10075   mp->dst = dst;
10076   mp->sport = sport;
10077   mp->dport = dport;
10078   mp->proto = proto;
10079   mp->reverse = reverse;
10080   mp->vrf_id = ntohl (vrf_id);
10081   mp->is_ipv6 = is_ipv6;
10082
10083   S (mp);
10084   W (ret);
10085   return ret;
10086 }
10087
10088 static int
10089 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10090 {
10091   unformat_input_t *i = vam->input;
10092   vl_api_sw_interface_ip6_enable_disable_t *mp;
10093   u32 sw_if_index;
10094   u8 sw_if_index_set = 0;
10095   u8 enable = 0;
10096   int ret;
10097
10098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10099     {
10100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10101         sw_if_index_set = 1;
10102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10103         sw_if_index_set = 1;
10104       else if (unformat (i, "enable"))
10105         enable = 1;
10106       else if (unformat (i, "disable"))
10107         enable = 0;
10108       else
10109         {
10110           clib_warning ("parse error '%U'", format_unformat_error, i);
10111           return -99;
10112         }
10113     }
10114
10115   if (sw_if_index_set == 0)
10116     {
10117       errmsg ("missing interface name or sw_if_index");
10118       return -99;
10119     }
10120
10121   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10122
10123   mp->sw_if_index = ntohl (sw_if_index);
10124   mp->enable = enable;
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_ip6nd_proxy_add_del (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_ip6nd_proxy_add_del_t *mp;
10136   u32 sw_if_index = ~0;
10137   u8 v6_address_set = 0;
10138   ip6_address_t v6address;
10139   u8 is_del = 0;
10140   int ret;
10141
10142   /* Parse args required to build the message */
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10146         ;
10147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10148         ;
10149       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10150         v6_address_set = 1;
10151       if (unformat (i, "del"))
10152         is_del = 1;
10153       else
10154         {
10155           clib_warning ("parse error '%U'", format_unformat_error, i);
10156           return -99;
10157         }
10158     }
10159
10160   if (sw_if_index == ~0)
10161     {
10162       errmsg ("missing interface name or sw_if_index");
10163       return -99;
10164     }
10165   if (!v6_address_set)
10166     {
10167       errmsg ("no address set");
10168       return -99;
10169     }
10170
10171   /* Construct the API message */
10172   M (IP6ND_PROXY_ADD_DEL, mp);
10173
10174   mp->is_del = is_del;
10175   mp->sw_if_index = ntohl (sw_if_index);
10176   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10177
10178   /* send it... */
10179   S (mp);
10180
10181   /* Wait for a reply, return good/bad news  */
10182   W (ret);
10183   return ret;
10184 }
10185
10186 static int
10187 api_ip6nd_proxy_dump (vat_main_t * vam)
10188 {
10189   vl_api_ip6nd_proxy_dump_t *mp;
10190   vl_api_control_ping_t *mp_ping;
10191   int ret;
10192
10193   M (IP6ND_PROXY_DUMP, mp);
10194
10195   S (mp);
10196
10197   /* Use a control ping for synchronization */
10198   MPING (CONTROL_PING, mp_ping);
10199   S (mp_ping);
10200
10201   W (ret);
10202   return ret;
10203 }
10204
10205 static void vl_api_ip6nd_proxy_details_t_handler
10206   (vl_api_ip6nd_proxy_details_t * mp)
10207 {
10208   vat_main_t *vam = &vat_main;
10209
10210   print (vam->ofp, "host %U sw_if_index %d",
10211          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10212 }
10213
10214 static void vl_api_ip6nd_proxy_details_t_handler_json
10215   (vl_api_ip6nd_proxy_details_t * mp)
10216 {
10217   vat_main_t *vam = &vat_main;
10218   struct in6_addr ip6;
10219   vat_json_node_t *node = NULL;
10220
10221   if (VAT_JSON_ARRAY != vam->json_tree.type)
10222     {
10223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10224       vat_json_init_array (&vam->json_tree);
10225     }
10226   node = vat_json_array_add (&vam->json_tree);
10227
10228   vat_json_init_object (node);
10229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10230
10231   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10232   vat_json_object_add_ip6 (node, "host", ip6);
10233 }
10234
10235 static int
10236 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10237 {
10238   unformat_input_t *i = vam->input;
10239   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10240   u32 sw_if_index;
10241   u8 sw_if_index_set = 0;
10242   u32 address_length = 0;
10243   u8 v6_address_set = 0;
10244   ip6_address_t v6address;
10245   u8 use_default = 0;
10246   u8 no_advertise = 0;
10247   u8 off_link = 0;
10248   u8 no_autoconfig = 0;
10249   u8 no_onlink = 0;
10250   u8 is_no = 0;
10251   u32 val_lifetime = 0;
10252   u32 pref_lifetime = 0;
10253   int ret;
10254
10255   /* Parse args required to build the message */
10256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10257     {
10258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10259         sw_if_index_set = 1;
10260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10261         sw_if_index_set = 1;
10262       else if (unformat (i, "%U/%d",
10263                          unformat_ip6_address, &v6address, &address_length))
10264         v6_address_set = 1;
10265       else if (unformat (i, "val_life %d", &val_lifetime))
10266         ;
10267       else if (unformat (i, "pref_life %d", &pref_lifetime))
10268         ;
10269       else if (unformat (i, "def"))
10270         use_default = 1;
10271       else if (unformat (i, "noadv"))
10272         no_advertise = 1;
10273       else if (unformat (i, "offl"))
10274         off_link = 1;
10275       else if (unformat (i, "noauto"))
10276         no_autoconfig = 1;
10277       else if (unformat (i, "nolink"))
10278         no_onlink = 1;
10279       else if (unformat (i, "isno"))
10280         is_no = 1;
10281       else
10282         {
10283           clib_warning ("parse error '%U'", format_unformat_error, i);
10284           return -99;
10285         }
10286     }
10287
10288   if (sw_if_index_set == 0)
10289     {
10290       errmsg ("missing interface name or sw_if_index");
10291       return -99;
10292     }
10293   if (!v6_address_set)
10294     {
10295       errmsg ("no address set");
10296       return -99;
10297     }
10298
10299   /* Construct the API message */
10300   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10301
10302   mp->sw_if_index = ntohl (sw_if_index);
10303   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10304   mp->address_length = address_length;
10305   mp->use_default = use_default;
10306   mp->no_advertise = no_advertise;
10307   mp->off_link = off_link;
10308   mp->no_autoconfig = no_autoconfig;
10309   mp->no_onlink = no_onlink;
10310   mp->is_no = is_no;
10311   mp->val_lifetime = ntohl (val_lifetime);
10312   mp->pref_lifetime = ntohl (pref_lifetime);
10313
10314   /* send it... */
10315   S (mp);
10316
10317   /* Wait for a reply, return good/bad news  */
10318   W (ret);
10319   return ret;
10320 }
10321
10322 static int
10323 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10327   u32 sw_if_index;
10328   u8 sw_if_index_set = 0;
10329   u8 suppress = 0;
10330   u8 managed = 0;
10331   u8 other = 0;
10332   u8 ll_option = 0;
10333   u8 send_unicast = 0;
10334   u8 cease = 0;
10335   u8 is_no = 0;
10336   u8 default_router = 0;
10337   u32 max_interval = 0;
10338   u32 min_interval = 0;
10339   u32 lifetime = 0;
10340   u32 initial_count = 0;
10341   u32 initial_interval = 0;
10342   int ret;
10343
10344
10345   /* Parse args required to build the message */
10346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10347     {
10348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10349         sw_if_index_set = 1;
10350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10351         sw_if_index_set = 1;
10352       else if (unformat (i, "maxint %d", &max_interval))
10353         ;
10354       else if (unformat (i, "minint %d", &min_interval))
10355         ;
10356       else if (unformat (i, "life %d", &lifetime))
10357         ;
10358       else if (unformat (i, "count %d", &initial_count))
10359         ;
10360       else if (unformat (i, "interval %d", &initial_interval))
10361         ;
10362       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10363         suppress = 1;
10364       else if (unformat (i, "managed"))
10365         managed = 1;
10366       else if (unformat (i, "other"))
10367         other = 1;
10368       else if (unformat (i, "ll"))
10369         ll_option = 1;
10370       else if (unformat (i, "send"))
10371         send_unicast = 1;
10372       else if (unformat (i, "cease"))
10373         cease = 1;
10374       else if (unformat (i, "isno"))
10375         is_no = 1;
10376       else if (unformat (i, "def"))
10377         default_router = 1;
10378       else
10379         {
10380           clib_warning ("parse error '%U'", format_unformat_error, i);
10381           return -99;
10382         }
10383     }
10384
10385   if (sw_if_index_set == 0)
10386     {
10387       errmsg ("missing interface name or sw_if_index");
10388       return -99;
10389     }
10390
10391   /* Construct the API message */
10392   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10393
10394   mp->sw_if_index = ntohl (sw_if_index);
10395   mp->max_interval = ntohl (max_interval);
10396   mp->min_interval = ntohl (min_interval);
10397   mp->lifetime = ntohl (lifetime);
10398   mp->initial_count = ntohl (initial_count);
10399   mp->initial_interval = ntohl (initial_interval);
10400   mp->suppress = suppress;
10401   mp->managed = managed;
10402   mp->other = other;
10403   mp->ll_option = ll_option;
10404   mp->send_unicast = send_unicast;
10405   mp->cease = cease;
10406   mp->is_no = is_no;
10407   mp->default_router = default_router;
10408
10409   /* send it... */
10410   S (mp);
10411
10412   /* Wait for a reply, return good/bad news  */
10413   W (ret);
10414   return ret;
10415 }
10416
10417 static int
10418 api_set_arp_neighbor_limit (vat_main_t * vam)
10419 {
10420   unformat_input_t *i = vam->input;
10421   vl_api_set_arp_neighbor_limit_t *mp;
10422   u32 arp_nbr_limit;
10423   u8 limit_set = 0;
10424   u8 is_ipv6 = 0;
10425   int ret;
10426
10427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10428     {
10429       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10430         limit_set = 1;
10431       else if (unformat (i, "ipv6"))
10432         is_ipv6 = 1;
10433       else
10434         {
10435           clib_warning ("parse error '%U'", format_unformat_error, i);
10436           return -99;
10437         }
10438     }
10439
10440   if (limit_set == 0)
10441     {
10442       errmsg ("missing limit value");
10443       return -99;
10444     }
10445
10446   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10447
10448   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10449   mp->is_ipv6 = is_ipv6;
10450
10451   S (mp);
10452   W (ret);
10453   return ret;
10454 }
10455
10456 static int
10457 api_l2_patch_add_del (vat_main_t * vam)
10458 {
10459   unformat_input_t *i = vam->input;
10460   vl_api_l2_patch_add_del_t *mp;
10461   u32 rx_sw_if_index;
10462   u8 rx_sw_if_index_set = 0;
10463   u32 tx_sw_if_index;
10464   u8 tx_sw_if_index_set = 0;
10465   u8 is_add = 1;
10466   int ret;
10467
10468   /* Parse args required to build the message */
10469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10470     {
10471       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10472         rx_sw_if_index_set = 1;
10473       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10474         tx_sw_if_index_set = 1;
10475       else if (unformat (i, "rx"))
10476         {
10477           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10478             {
10479               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10480                             &rx_sw_if_index))
10481                 rx_sw_if_index_set = 1;
10482             }
10483           else
10484             break;
10485         }
10486       else if (unformat (i, "tx"))
10487         {
10488           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10489             {
10490               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10491                             &tx_sw_if_index))
10492                 tx_sw_if_index_set = 1;
10493             }
10494           else
10495             break;
10496         }
10497       else if (unformat (i, "del"))
10498         is_add = 0;
10499       else
10500         break;
10501     }
10502
10503   if (rx_sw_if_index_set == 0)
10504     {
10505       errmsg ("missing rx interface name or rx_sw_if_index");
10506       return -99;
10507     }
10508
10509   if (tx_sw_if_index_set == 0)
10510     {
10511       errmsg ("missing tx interface name or tx_sw_if_index");
10512       return -99;
10513     }
10514
10515   M (L2_PATCH_ADD_DEL, mp);
10516
10517   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10518   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10519   mp->is_add = is_add;
10520
10521   S (mp);
10522   W (ret);
10523   return ret;
10524 }
10525
10526 u8 is_del;
10527 u8 localsid_addr[16];
10528 u8 end_psp;
10529 u8 behavior;
10530 u32 sw_if_index;
10531 u32 vlan_index;
10532 u32 fib_table;
10533 u8 nh_addr[16];
10534
10535 static int
10536 api_sr_localsid_add_del (vat_main_t * vam)
10537 {
10538   unformat_input_t *i = vam->input;
10539   vl_api_sr_localsid_add_del_t *mp;
10540
10541   u8 is_del;
10542   ip6_address_t localsid;
10543   u8 end_psp = 0;
10544   u8 behavior = ~0;
10545   u32 sw_if_index;
10546   u32 fib_table = ~(u32) 0;
10547   ip6_address_t nh_addr6;
10548   ip4_address_t nh_addr4;
10549   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10550   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10551
10552   bool nexthop_set = 0;
10553
10554   int ret;
10555
10556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10557     {
10558       if (unformat (i, "del"))
10559         is_del = 1;
10560       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10561       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10562         nexthop_set = 1;
10563       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10564         nexthop_set = 1;
10565       else if (unformat (i, "behavior %u", &behavior));
10566       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10567       else if (unformat (i, "fib-table %u", &fib_table));
10568       else if (unformat (i, "end.psp %u", &behavior));
10569       else
10570         break;
10571     }
10572
10573   M (SR_LOCALSID_ADD_DEL, mp);
10574
10575   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10576   if (nexthop_set)
10577     {
10578       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10579       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10580     }
10581   mp->behavior = behavior;
10582   mp->sw_if_index = ntohl (sw_if_index);
10583   mp->fib_table = ntohl (fib_table);
10584   mp->end_psp = end_psp;
10585   mp->is_del = is_del;
10586
10587   S (mp);
10588   W (ret);
10589   return ret;
10590 }
10591
10592 static int
10593 api_ioam_enable (vat_main_t * vam)
10594 {
10595   unformat_input_t *input = vam->input;
10596   vl_api_ioam_enable_t *mp;
10597   u32 id = 0;
10598   int has_trace_option = 0;
10599   int has_pot_option = 0;
10600   int has_seqno_option = 0;
10601   int has_analyse_option = 0;
10602   int ret;
10603
10604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10605     {
10606       if (unformat (input, "trace"))
10607         has_trace_option = 1;
10608       else if (unformat (input, "pot"))
10609         has_pot_option = 1;
10610       else if (unformat (input, "seqno"))
10611         has_seqno_option = 1;
10612       else if (unformat (input, "analyse"))
10613         has_analyse_option = 1;
10614       else
10615         break;
10616     }
10617   M (IOAM_ENABLE, mp);
10618   mp->id = htons (id);
10619   mp->seqno = has_seqno_option;
10620   mp->analyse = has_analyse_option;
10621   mp->pot_enable = has_pot_option;
10622   mp->trace_enable = has_trace_option;
10623
10624   S (mp);
10625   W (ret);
10626   return ret;
10627 }
10628
10629
10630 static int
10631 api_ioam_disable (vat_main_t * vam)
10632 {
10633   vl_api_ioam_disable_t *mp;
10634   int ret;
10635
10636   M (IOAM_DISABLE, mp);
10637   S (mp);
10638   W (ret);
10639   return ret;
10640 }
10641
10642 #define foreach_tcp_proto_field                 \
10643 _(src_port)                                     \
10644 _(dst_port)
10645
10646 #define foreach_udp_proto_field                 \
10647 _(src_port)                                     \
10648 _(dst_port)
10649
10650 #define foreach_ip4_proto_field                 \
10651 _(src_address)                                  \
10652 _(dst_address)                                  \
10653 _(tos)                                          \
10654 _(length)                                       \
10655 _(fragment_id)                                  \
10656 _(ttl)                                          \
10657 _(protocol)                                     \
10658 _(checksum)
10659
10660 typedef struct
10661 {
10662   u16 src_port, dst_port;
10663 } tcpudp_header_t;
10664
10665 #if VPP_API_TEST_BUILTIN == 0
10666 uword
10667 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10668 {
10669   u8 **maskp = va_arg (*args, u8 **);
10670   u8 *mask = 0;
10671   u8 found_something = 0;
10672   tcp_header_t *tcp;
10673
10674 #define _(a) u8 a=0;
10675   foreach_tcp_proto_field;
10676 #undef _
10677
10678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10679     {
10680       if (0);
10681 #define _(a) else if (unformat (input, #a)) a=1;
10682       foreach_tcp_proto_field
10683 #undef _
10684         else
10685         break;
10686     }
10687
10688 #define _(a) found_something += a;
10689   foreach_tcp_proto_field;
10690 #undef _
10691
10692   if (found_something == 0)
10693     return 0;
10694
10695   vec_validate (mask, sizeof (*tcp) - 1);
10696
10697   tcp = (tcp_header_t *) mask;
10698
10699 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10700   foreach_tcp_proto_field;
10701 #undef _
10702
10703   *maskp = mask;
10704   return 1;
10705 }
10706
10707 uword
10708 unformat_udp_mask (unformat_input_t * input, va_list * args)
10709 {
10710   u8 **maskp = va_arg (*args, u8 **);
10711   u8 *mask = 0;
10712   u8 found_something = 0;
10713   udp_header_t *udp;
10714
10715 #define _(a) u8 a=0;
10716   foreach_udp_proto_field;
10717 #undef _
10718
10719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10720     {
10721       if (0);
10722 #define _(a) else if (unformat (input, #a)) a=1;
10723       foreach_udp_proto_field
10724 #undef _
10725         else
10726         break;
10727     }
10728
10729 #define _(a) found_something += a;
10730   foreach_udp_proto_field;
10731 #undef _
10732
10733   if (found_something == 0)
10734     return 0;
10735
10736   vec_validate (mask, sizeof (*udp) - 1);
10737
10738   udp = (udp_header_t *) mask;
10739
10740 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10741   foreach_udp_proto_field;
10742 #undef _
10743
10744   *maskp = mask;
10745   return 1;
10746 }
10747
10748 uword
10749 unformat_l4_mask (unformat_input_t * input, va_list * args)
10750 {
10751   u8 **maskp = va_arg (*args, u8 **);
10752   u16 src_port = 0, dst_port = 0;
10753   tcpudp_header_t *tcpudp;
10754
10755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10758         return 1;
10759       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10760         return 1;
10761       else if (unformat (input, "src_port"))
10762         src_port = 0xFFFF;
10763       else if (unformat (input, "dst_port"))
10764         dst_port = 0xFFFF;
10765       else
10766         return 0;
10767     }
10768
10769   if (!src_port && !dst_port)
10770     return 0;
10771
10772   u8 *mask = 0;
10773   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10774
10775   tcpudp = (tcpudp_header_t *) mask;
10776   tcpudp->src_port = src_port;
10777   tcpudp->dst_port = dst_port;
10778
10779   *maskp = mask;
10780
10781   return 1;
10782 }
10783
10784 uword
10785 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10786 {
10787   u8 **maskp = va_arg (*args, u8 **);
10788   u8 *mask = 0;
10789   u8 found_something = 0;
10790   ip4_header_t *ip;
10791
10792 #define _(a) u8 a=0;
10793   foreach_ip4_proto_field;
10794 #undef _
10795   u8 version = 0;
10796   u8 hdr_length = 0;
10797
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "version"))
10802         version = 1;
10803       else if (unformat (input, "hdr_length"))
10804         hdr_length = 1;
10805       else if (unformat (input, "src"))
10806         src_address = 1;
10807       else if (unformat (input, "dst"))
10808         dst_address = 1;
10809       else if (unformat (input, "proto"))
10810         protocol = 1;
10811
10812 #define _(a) else if (unformat (input, #a)) a=1;
10813       foreach_ip4_proto_field
10814 #undef _
10815         else
10816         break;
10817     }
10818
10819 #define _(a) found_something += a;
10820   foreach_ip4_proto_field;
10821 #undef _
10822
10823   if (found_something == 0)
10824     return 0;
10825
10826   vec_validate (mask, sizeof (*ip) - 1);
10827
10828   ip = (ip4_header_t *) mask;
10829
10830 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10831   foreach_ip4_proto_field;
10832 #undef _
10833
10834   ip->ip_version_and_header_length = 0;
10835
10836   if (version)
10837     ip->ip_version_and_header_length |= 0xF0;
10838
10839   if (hdr_length)
10840     ip->ip_version_and_header_length |= 0x0F;
10841
10842   *maskp = mask;
10843   return 1;
10844 }
10845
10846 #define foreach_ip6_proto_field                 \
10847 _(src_address)                                  \
10848 _(dst_address)                                  \
10849 _(payload_length)                               \
10850 _(hop_limit)                                    \
10851 _(protocol)
10852
10853 uword
10854 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10855 {
10856   u8 **maskp = va_arg (*args, u8 **);
10857   u8 *mask = 0;
10858   u8 found_something = 0;
10859   ip6_header_t *ip;
10860   u32 ip_version_traffic_class_and_flow_label;
10861
10862 #define _(a) u8 a=0;
10863   foreach_ip6_proto_field;
10864 #undef _
10865   u8 version = 0;
10866   u8 traffic_class = 0;
10867   u8 flow_label = 0;
10868
10869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10870     {
10871       if (unformat (input, "version"))
10872         version = 1;
10873       else if (unformat (input, "traffic-class"))
10874         traffic_class = 1;
10875       else if (unformat (input, "flow-label"))
10876         flow_label = 1;
10877       else if (unformat (input, "src"))
10878         src_address = 1;
10879       else if (unformat (input, "dst"))
10880         dst_address = 1;
10881       else if (unformat (input, "proto"))
10882         protocol = 1;
10883
10884 #define _(a) else if (unformat (input, #a)) a=1;
10885       foreach_ip6_proto_field
10886 #undef _
10887         else
10888         break;
10889     }
10890
10891 #define _(a) found_something += a;
10892   foreach_ip6_proto_field;
10893 #undef _
10894
10895   if (found_something == 0)
10896     return 0;
10897
10898   vec_validate (mask, sizeof (*ip) - 1);
10899
10900   ip = (ip6_header_t *) mask;
10901
10902 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10903   foreach_ip6_proto_field;
10904 #undef _
10905
10906   ip_version_traffic_class_and_flow_label = 0;
10907
10908   if (version)
10909     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10910
10911   if (traffic_class)
10912     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10913
10914   if (flow_label)
10915     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10916
10917   ip->ip_version_traffic_class_and_flow_label =
10918     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10919
10920   *maskp = mask;
10921   return 1;
10922 }
10923
10924 uword
10925 unformat_l3_mask (unformat_input_t * input, va_list * args)
10926 {
10927   u8 **maskp = va_arg (*args, u8 **);
10928
10929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10930     {
10931       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10932         return 1;
10933       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10934         return 1;
10935       else
10936         break;
10937     }
10938   return 0;
10939 }
10940
10941 uword
10942 unformat_l2_mask (unformat_input_t * input, va_list * args)
10943 {
10944   u8 **maskp = va_arg (*args, u8 **);
10945   u8 *mask = 0;
10946   u8 src = 0;
10947   u8 dst = 0;
10948   u8 proto = 0;
10949   u8 tag1 = 0;
10950   u8 tag2 = 0;
10951   u8 ignore_tag1 = 0;
10952   u8 ignore_tag2 = 0;
10953   u8 cos1 = 0;
10954   u8 cos2 = 0;
10955   u8 dot1q = 0;
10956   u8 dot1ad = 0;
10957   int len = 14;
10958
10959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10960     {
10961       if (unformat (input, "src"))
10962         src = 1;
10963       else if (unformat (input, "dst"))
10964         dst = 1;
10965       else if (unformat (input, "proto"))
10966         proto = 1;
10967       else if (unformat (input, "tag1"))
10968         tag1 = 1;
10969       else if (unformat (input, "tag2"))
10970         tag2 = 1;
10971       else if (unformat (input, "ignore-tag1"))
10972         ignore_tag1 = 1;
10973       else if (unformat (input, "ignore-tag2"))
10974         ignore_tag2 = 1;
10975       else if (unformat (input, "cos1"))
10976         cos1 = 1;
10977       else if (unformat (input, "cos2"))
10978         cos2 = 1;
10979       else if (unformat (input, "dot1q"))
10980         dot1q = 1;
10981       else if (unformat (input, "dot1ad"))
10982         dot1ad = 1;
10983       else
10984         break;
10985     }
10986   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10987        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10988     return 0;
10989
10990   if (tag1 || ignore_tag1 || cos1 || dot1q)
10991     len = 18;
10992   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10993     len = 22;
10994
10995   vec_validate (mask, len - 1);
10996
10997   if (dst)
10998     clib_memset (mask, 0xff, 6);
10999
11000   if (src)
11001     clib_memset (mask + 6, 0xff, 6);
11002
11003   if (tag2 || dot1ad)
11004     {
11005       /* inner vlan tag */
11006       if (tag2)
11007         {
11008           mask[19] = 0xff;
11009           mask[18] = 0x0f;
11010         }
11011       if (cos2)
11012         mask[18] |= 0xe0;
11013       if (proto)
11014         mask[21] = mask[20] = 0xff;
11015       if (tag1)
11016         {
11017           mask[15] = 0xff;
11018           mask[14] = 0x0f;
11019         }
11020       if (cos1)
11021         mask[14] |= 0xe0;
11022       *maskp = mask;
11023       return 1;
11024     }
11025   if (tag1 | dot1q)
11026     {
11027       if (tag1)
11028         {
11029           mask[15] = 0xff;
11030           mask[14] = 0x0f;
11031         }
11032       if (cos1)
11033         mask[14] |= 0xe0;
11034       if (proto)
11035         mask[16] = mask[17] = 0xff;
11036
11037       *maskp = mask;
11038       return 1;
11039     }
11040   if (cos2)
11041     mask[18] |= 0xe0;
11042   if (cos1)
11043     mask[14] |= 0xe0;
11044   if (proto)
11045     mask[12] = mask[13] = 0xff;
11046
11047   *maskp = mask;
11048   return 1;
11049 }
11050
11051 uword
11052 unformat_classify_mask (unformat_input_t * input, va_list * args)
11053 {
11054   u8 **maskp = va_arg (*args, u8 **);
11055   u32 *skipp = va_arg (*args, u32 *);
11056   u32 *matchp = va_arg (*args, u32 *);
11057   u32 match;
11058   u8 *mask = 0;
11059   u8 *l2 = 0;
11060   u8 *l3 = 0;
11061   u8 *l4 = 0;
11062   int i;
11063
11064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11065     {
11066       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11067         ;
11068       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11069         ;
11070       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11071         ;
11072       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11073         ;
11074       else
11075         break;
11076     }
11077
11078   if (l4 && !l3)
11079     {
11080       vec_free (mask);
11081       vec_free (l2);
11082       vec_free (l4);
11083       return 0;
11084     }
11085
11086   if (mask || l2 || l3 || l4)
11087     {
11088       if (l2 || l3 || l4)
11089         {
11090           /* "With a free Ethernet header in every package" */
11091           if (l2 == 0)
11092             vec_validate (l2, 13);
11093           mask = l2;
11094           if (vec_len (l3))
11095             {
11096               vec_append (mask, l3);
11097               vec_free (l3);
11098             }
11099           if (vec_len (l4))
11100             {
11101               vec_append (mask, l4);
11102               vec_free (l4);
11103             }
11104         }
11105
11106       /* Scan forward looking for the first significant mask octet */
11107       for (i = 0; i < vec_len (mask); i++)
11108         if (mask[i])
11109           break;
11110
11111       /* compute (skip, match) params */
11112       *skipp = i / sizeof (u32x4);
11113       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11114
11115       /* Pad mask to an even multiple of the vector size */
11116       while (vec_len (mask) % sizeof (u32x4))
11117         vec_add1 (mask, 0);
11118
11119       match = vec_len (mask) / sizeof (u32x4);
11120
11121       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11122         {
11123           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11124           if (*tmp || *(tmp + 1))
11125             break;
11126           match--;
11127         }
11128       if (match == 0)
11129         clib_warning ("BUG: match 0");
11130
11131       _vec_len (mask) = match * sizeof (u32x4);
11132
11133       *matchp = match;
11134       *maskp = mask;
11135
11136       return 1;
11137     }
11138
11139   return 0;
11140 }
11141 #endif /* VPP_API_TEST_BUILTIN */
11142
11143 #define foreach_l2_next                         \
11144 _(drop, DROP)                                   \
11145 _(ethernet, ETHERNET_INPUT)                     \
11146 _(ip4, IP4_INPUT)                               \
11147 _(ip6, IP6_INPUT)
11148
11149 uword
11150 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11151 {
11152   u32 *miss_next_indexp = va_arg (*args, u32 *);
11153   u32 next_index = 0;
11154   u32 tmp;
11155
11156 #define _(n,N) \
11157   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11158   foreach_l2_next;
11159 #undef _
11160
11161   if (unformat (input, "%d", &tmp))
11162     {
11163       next_index = tmp;
11164       goto out;
11165     }
11166
11167   return 0;
11168
11169 out:
11170   *miss_next_indexp = next_index;
11171   return 1;
11172 }
11173
11174 #define foreach_ip_next                         \
11175 _(drop, DROP)                                   \
11176 _(local, LOCAL)                                 \
11177 _(rewrite, REWRITE)
11178
11179 uword
11180 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11181 {
11182   u32 *miss_next_indexp = va_arg (*args, u32 *);
11183   u32 next_index = 0;
11184   u32 tmp;
11185
11186 #define _(n,N) \
11187   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11188   foreach_ip_next;
11189 #undef _
11190
11191   if (unformat (input, "%d", &tmp))
11192     {
11193       next_index = tmp;
11194       goto out;
11195     }
11196
11197   return 0;
11198
11199 out:
11200   *miss_next_indexp = next_index;
11201   return 1;
11202 }
11203
11204 #define foreach_acl_next                        \
11205 _(deny, DENY)
11206
11207 uword
11208 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11209 {
11210   u32 *miss_next_indexp = va_arg (*args, u32 *);
11211   u32 next_index = 0;
11212   u32 tmp;
11213
11214 #define _(n,N) \
11215   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11216   foreach_acl_next;
11217 #undef _
11218
11219   if (unformat (input, "permit"))
11220     {
11221       next_index = ~0;
11222       goto out;
11223     }
11224   else if (unformat (input, "%d", &tmp))
11225     {
11226       next_index = tmp;
11227       goto out;
11228     }
11229
11230   return 0;
11231
11232 out:
11233   *miss_next_indexp = next_index;
11234   return 1;
11235 }
11236
11237 uword
11238 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11239 {
11240   u32 *r = va_arg (*args, u32 *);
11241
11242   if (unformat (input, "conform-color"))
11243     *r = POLICE_CONFORM;
11244   else if (unformat (input, "exceed-color"))
11245     *r = POLICE_EXCEED;
11246   else
11247     return 0;
11248
11249   return 1;
11250 }
11251
11252 static int
11253 api_classify_add_del_table (vat_main_t * vam)
11254 {
11255   unformat_input_t *i = vam->input;
11256   vl_api_classify_add_del_table_t *mp;
11257
11258   u32 nbuckets = 2;
11259   u32 skip = ~0;
11260   u32 match = ~0;
11261   int is_add = 1;
11262   int del_chain = 0;
11263   u32 table_index = ~0;
11264   u32 next_table_index = ~0;
11265   u32 miss_next_index = ~0;
11266   u32 memory_size = 32 << 20;
11267   u8 *mask = 0;
11268   u32 current_data_flag = 0;
11269   int current_data_offset = 0;
11270   int ret;
11271
11272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11273     {
11274       if (unformat (i, "del"))
11275         is_add = 0;
11276       else if (unformat (i, "del-chain"))
11277         {
11278           is_add = 0;
11279           del_chain = 1;
11280         }
11281       else if (unformat (i, "buckets %d", &nbuckets))
11282         ;
11283       else if (unformat (i, "memory_size %d", &memory_size))
11284         ;
11285       else if (unformat (i, "skip %d", &skip))
11286         ;
11287       else if (unformat (i, "match %d", &match))
11288         ;
11289       else if (unformat (i, "table %d", &table_index))
11290         ;
11291       else if (unformat (i, "mask %U", unformat_classify_mask,
11292                          &mask, &skip, &match))
11293         ;
11294       else if (unformat (i, "next-table %d", &next_table_index))
11295         ;
11296       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11297                          &miss_next_index))
11298         ;
11299       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11300                          &miss_next_index))
11301         ;
11302       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11303                          &miss_next_index))
11304         ;
11305       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11306         ;
11307       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11308         ;
11309       else
11310         break;
11311     }
11312
11313   if (is_add && mask == 0)
11314     {
11315       errmsg ("Mask required");
11316       return -99;
11317     }
11318
11319   if (is_add && skip == ~0)
11320     {
11321       errmsg ("skip count required");
11322       return -99;
11323     }
11324
11325   if (is_add && match == ~0)
11326     {
11327       errmsg ("match count required");
11328       return -99;
11329     }
11330
11331   if (!is_add && table_index == ~0)
11332     {
11333       errmsg ("table index required for delete");
11334       return -99;
11335     }
11336
11337   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11338
11339   mp->is_add = is_add;
11340   mp->del_chain = del_chain;
11341   mp->table_index = ntohl (table_index);
11342   mp->nbuckets = ntohl (nbuckets);
11343   mp->memory_size = ntohl (memory_size);
11344   mp->skip_n_vectors = ntohl (skip);
11345   mp->match_n_vectors = ntohl (match);
11346   mp->next_table_index = ntohl (next_table_index);
11347   mp->miss_next_index = ntohl (miss_next_index);
11348   mp->current_data_flag = ntohl (current_data_flag);
11349   mp->current_data_offset = ntohl (current_data_offset);
11350   mp->mask_len = ntohl (vec_len (mask));
11351   clib_memcpy (mp->mask, mask, vec_len (mask));
11352
11353   vec_free (mask);
11354
11355   S (mp);
11356   W (ret);
11357   return ret;
11358 }
11359
11360 #if VPP_API_TEST_BUILTIN == 0
11361 uword
11362 unformat_l4_match (unformat_input_t * input, va_list * args)
11363 {
11364   u8 **matchp = va_arg (*args, u8 **);
11365
11366   u8 *proto_header = 0;
11367   int src_port = 0;
11368   int dst_port = 0;
11369
11370   tcpudp_header_t h;
11371
11372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11373     {
11374       if (unformat (input, "src_port %d", &src_port))
11375         ;
11376       else if (unformat (input, "dst_port %d", &dst_port))
11377         ;
11378       else
11379         return 0;
11380     }
11381
11382   h.src_port = clib_host_to_net_u16 (src_port);
11383   h.dst_port = clib_host_to_net_u16 (dst_port);
11384   vec_validate (proto_header, sizeof (h) - 1);
11385   memcpy (proto_header, &h, sizeof (h));
11386
11387   *matchp = proto_header;
11388
11389   return 1;
11390 }
11391
11392 uword
11393 unformat_ip4_match (unformat_input_t * input, va_list * args)
11394 {
11395   u8 **matchp = va_arg (*args, u8 **);
11396   u8 *match = 0;
11397   ip4_header_t *ip;
11398   int version = 0;
11399   u32 version_val;
11400   int hdr_length = 0;
11401   u32 hdr_length_val;
11402   int src = 0, dst = 0;
11403   ip4_address_t src_val, dst_val;
11404   int proto = 0;
11405   u32 proto_val;
11406   int tos = 0;
11407   u32 tos_val;
11408   int length = 0;
11409   u32 length_val;
11410   int fragment_id = 0;
11411   u32 fragment_id_val;
11412   int ttl = 0;
11413   int ttl_val;
11414   int checksum = 0;
11415   u32 checksum_val;
11416
11417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11418     {
11419       if (unformat (input, "version %d", &version_val))
11420         version = 1;
11421       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11422         hdr_length = 1;
11423       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11424         src = 1;
11425       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11426         dst = 1;
11427       else if (unformat (input, "proto %d", &proto_val))
11428         proto = 1;
11429       else if (unformat (input, "tos %d", &tos_val))
11430         tos = 1;
11431       else if (unformat (input, "length %d", &length_val))
11432         length = 1;
11433       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11434         fragment_id = 1;
11435       else if (unformat (input, "ttl %d", &ttl_val))
11436         ttl = 1;
11437       else if (unformat (input, "checksum %d", &checksum_val))
11438         checksum = 1;
11439       else
11440         break;
11441     }
11442
11443   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11444       + ttl + checksum == 0)
11445     return 0;
11446
11447   /*
11448    * Aligned because we use the real comparison functions
11449    */
11450   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11451
11452   ip = (ip4_header_t *) match;
11453
11454   /* These are realistically matched in practice */
11455   if (src)
11456     ip->src_address.as_u32 = src_val.as_u32;
11457
11458   if (dst)
11459     ip->dst_address.as_u32 = dst_val.as_u32;
11460
11461   if (proto)
11462     ip->protocol = proto_val;
11463
11464
11465   /* These are not, but they're included for completeness */
11466   if (version)
11467     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11468
11469   if (hdr_length)
11470     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11471
11472   if (tos)
11473     ip->tos = tos_val;
11474
11475   if (length)
11476     ip->length = clib_host_to_net_u16 (length_val);
11477
11478   if (ttl)
11479     ip->ttl = ttl_val;
11480
11481   if (checksum)
11482     ip->checksum = clib_host_to_net_u16 (checksum_val);
11483
11484   *matchp = match;
11485   return 1;
11486 }
11487
11488 uword
11489 unformat_ip6_match (unformat_input_t * input, va_list * args)
11490 {
11491   u8 **matchp = va_arg (*args, u8 **);
11492   u8 *match = 0;
11493   ip6_header_t *ip;
11494   int version = 0;
11495   u32 version_val;
11496   u8 traffic_class = 0;
11497   u32 traffic_class_val = 0;
11498   u8 flow_label = 0;
11499   u8 flow_label_val;
11500   int src = 0, dst = 0;
11501   ip6_address_t src_val, dst_val;
11502   int proto = 0;
11503   u32 proto_val;
11504   int payload_length = 0;
11505   u32 payload_length_val;
11506   int hop_limit = 0;
11507   int hop_limit_val;
11508   u32 ip_version_traffic_class_and_flow_label;
11509
11510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11511     {
11512       if (unformat (input, "version %d", &version_val))
11513         version = 1;
11514       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11515         traffic_class = 1;
11516       else if (unformat (input, "flow_label %d", &flow_label_val))
11517         flow_label = 1;
11518       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11519         src = 1;
11520       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11521         dst = 1;
11522       else if (unformat (input, "proto %d", &proto_val))
11523         proto = 1;
11524       else if (unformat (input, "payload_length %d", &payload_length_val))
11525         payload_length = 1;
11526       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11527         hop_limit = 1;
11528       else
11529         break;
11530     }
11531
11532   if (version + traffic_class + flow_label + src + dst + proto +
11533       payload_length + hop_limit == 0)
11534     return 0;
11535
11536   /*
11537    * Aligned because we use the real comparison functions
11538    */
11539   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11540
11541   ip = (ip6_header_t *) match;
11542
11543   if (src)
11544     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11545
11546   if (dst)
11547     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11548
11549   if (proto)
11550     ip->protocol = proto_val;
11551
11552   ip_version_traffic_class_and_flow_label = 0;
11553
11554   if (version)
11555     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11556
11557   if (traffic_class)
11558     ip_version_traffic_class_and_flow_label |=
11559       (traffic_class_val & 0xFF) << 20;
11560
11561   if (flow_label)
11562     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11563
11564   ip->ip_version_traffic_class_and_flow_label =
11565     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11566
11567   if (payload_length)
11568     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11569
11570   if (hop_limit)
11571     ip->hop_limit = hop_limit_val;
11572
11573   *matchp = match;
11574   return 1;
11575 }
11576
11577 uword
11578 unformat_l3_match (unformat_input_t * input, va_list * args)
11579 {
11580   u8 **matchp = va_arg (*args, u8 **);
11581
11582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11583     {
11584       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11585         return 1;
11586       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11587         return 1;
11588       else
11589         break;
11590     }
11591   return 0;
11592 }
11593
11594 uword
11595 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11596 {
11597   u8 *tagp = va_arg (*args, u8 *);
11598   u32 tag;
11599
11600   if (unformat (input, "%d", &tag))
11601     {
11602       tagp[0] = (tag >> 8) & 0x0F;
11603       tagp[1] = tag & 0xFF;
11604       return 1;
11605     }
11606
11607   return 0;
11608 }
11609
11610 uword
11611 unformat_l2_match (unformat_input_t * input, va_list * args)
11612 {
11613   u8 **matchp = va_arg (*args, u8 **);
11614   u8 *match = 0;
11615   u8 src = 0;
11616   u8 src_val[6];
11617   u8 dst = 0;
11618   u8 dst_val[6];
11619   u8 proto = 0;
11620   u16 proto_val;
11621   u8 tag1 = 0;
11622   u8 tag1_val[2];
11623   u8 tag2 = 0;
11624   u8 tag2_val[2];
11625   int len = 14;
11626   u8 ignore_tag1 = 0;
11627   u8 ignore_tag2 = 0;
11628   u8 cos1 = 0;
11629   u8 cos2 = 0;
11630   u32 cos1_val = 0;
11631   u32 cos2_val = 0;
11632
11633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11634     {
11635       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11636         src = 1;
11637       else
11638         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11639         dst = 1;
11640       else if (unformat (input, "proto %U",
11641                          unformat_ethernet_type_host_byte_order, &proto_val))
11642         proto = 1;
11643       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11644         tag1 = 1;
11645       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11646         tag2 = 1;
11647       else if (unformat (input, "ignore-tag1"))
11648         ignore_tag1 = 1;
11649       else if (unformat (input, "ignore-tag2"))
11650         ignore_tag2 = 1;
11651       else if (unformat (input, "cos1 %d", &cos1_val))
11652         cos1 = 1;
11653       else if (unformat (input, "cos2 %d", &cos2_val))
11654         cos2 = 1;
11655       else
11656         break;
11657     }
11658   if ((src + dst + proto + tag1 + tag2 +
11659        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11660     return 0;
11661
11662   if (tag1 || ignore_tag1 || cos1)
11663     len = 18;
11664   if (tag2 || ignore_tag2 || cos2)
11665     len = 22;
11666
11667   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11668
11669   if (dst)
11670     clib_memcpy (match, dst_val, 6);
11671
11672   if (src)
11673     clib_memcpy (match + 6, src_val, 6);
11674
11675   if (tag2)
11676     {
11677       /* inner vlan tag */
11678       match[19] = tag2_val[1];
11679       match[18] = tag2_val[0];
11680       if (cos2)
11681         match[18] |= (cos2_val & 0x7) << 5;
11682       if (proto)
11683         {
11684           match[21] = proto_val & 0xff;
11685           match[20] = proto_val >> 8;
11686         }
11687       if (tag1)
11688         {
11689           match[15] = tag1_val[1];
11690           match[14] = tag1_val[0];
11691         }
11692       if (cos1)
11693         match[14] |= (cos1_val & 0x7) << 5;
11694       *matchp = match;
11695       return 1;
11696     }
11697   if (tag1)
11698     {
11699       match[15] = tag1_val[1];
11700       match[14] = tag1_val[0];
11701       if (proto)
11702         {
11703           match[17] = proto_val & 0xff;
11704           match[16] = proto_val >> 8;
11705         }
11706       if (cos1)
11707         match[14] |= (cos1_val & 0x7) << 5;
11708
11709       *matchp = match;
11710       return 1;
11711     }
11712   if (cos2)
11713     match[18] |= (cos2_val & 0x7) << 5;
11714   if (cos1)
11715     match[14] |= (cos1_val & 0x7) << 5;
11716   if (proto)
11717     {
11718       match[13] = proto_val & 0xff;
11719       match[12] = proto_val >> 8;
11720     }
11721
11722   *matchp = match;
11723   return 1;
11724 }
11725
11726 uword
11727 unformat_qos_source (unformat_input_t * input, va_list * args)
11728 {
11729   int *qs = va_arg (*args, int *);
11730
11731   if (unformat (input, "ip"))
11732     *qs = QOS_SOURCE_IP;
11733   else if (unformat (input, "mpls"))
11734     *qs = QOS_SOURCE_MPLS;
11735   else if (unformat (input, "ext"))
11736     *qs = QOS_SOURCE_EXT;
11737   else if (unformat (input, "vlan"))
11738     *qs = QOS_SOURCE_VLAN;
11739   else
11740     return 0;
11741
11742   return 1;
11743 }
11744 #endif
11745
11746 uword
11747 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11748 {
11749   u8 **matchp = va_arg (*args, u8 **);
11750   u32 skip_n_vectors = va_arg (*args, u32);
11751   u32 match_n_vectors = va_arg (*args, u32);
11752
11753   u8 *match = 0;
11754   u8 *l2 = 0;
11755   u8 *l3 = 0;
11756   u8 *l4 = 0;
11757
11758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11759     {
11760       if (unformat (input, "hex %U", unformat_hex_string, &match))
11761         ;
11762       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11763         ;
11764       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11765         ;
11766       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11767         ;
11768       else
11769         break;
11770     }
11771
11772   if (l4 && !l3)
11773     {
11774       vec_free (match);
11775       vec_free (l2);
11776       vec_free (l4);
11777       return 0;
11778     }
11779
11780   if (match || l2 || l3 || l4)
11781     {
11782       if (l2 || l3 || l4)
11783         {
11784           /* "Win a free Ethernet header in every packet" */
11785           if (l2 == 0)
11786             vec_validate_aligned (l2, 13, sizeof (u32x4));
11787           match = l2;
11788           if (vec_len (l3))
11789             {
11790               vec_append_aligned (match, l3, sizeof (u32x4));
11791               vec_free (l3);
11792             }
11793           if (vec_len (l4))
11794             {
11795               vec_append_aligned (match, l4, sizeof (u32x4));
11796               vec_free (l4);
11797             }
11798         }
11799
11800       /* Make sure the vector is big enough even if key is all 0's */
11801       vec_validate_aligned
11802         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11803          sizeof (u32x4));
11804
11805       /* Set size, include skipped vectors */
11806       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11807
11808       *matchp = match;
11809
11810       return 1;
11811     }
11812
11813   return 0;
11814 }
11815
11816 static int
11817 api_classify_add_del_session (vat_main_t * vam)
11818 {
11819   unformat_input_t *i = vam->input;
11820   vl_api_classify_add_del_session_t *mp;
11821   int is_add = 1;
11822   u32 table_index = ~0;
11823   u32 hit_next_index = ~0;
11824   u32 opaque_index = ~0;
11825   u8 *match = 0;
11826   i32 advance = 0;
11827   u32 skip_n_vectors = 0;
11828   u32 match_n_vectors = 0;
11829   u32 action = 0;
11830   u32 metadata = 0;
11831   int ret;
11832
11833   /*
11834    * Warning: you have to supply skip_n and match_n
11835    * because the API client cant simply look at the classify
11836    * table object.
11837    */
11838
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "del"))
11842         is_add = 0;
11843       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11844                          &hit_next_index))
11845         ;
11846       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11847                          &hit_next_index))
11848         ;
11849       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11850                          &hit_next_index))
11851         ;
11852       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11853         ;
11854       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11855         ;
11856       else if (unformat (i, "opaque-index %d", &opaque_index))
11857         ;
11858       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11859         ;
11860       else if (unformat (i, "match_n %d", &match_n_vectors))
11861         ;
11862       else if (unformat (i, "match %U", api_unformat_classify_match,
11863                          &match, skip_n_vectors, match_n_vectors))
11864         ;
11865       else if (unformat (i, "advance %d", &advance))
11866         ;
11867       else if (unformat (i, "table-index %d", &table_index))
11868         ;
11869       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11870         action = 1;
11871       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11872         action = 2;
11873       else if (unformat (i, "action %d", &action))
11874         ;
11875       else if (unformat (i, "metadata %d", &metadata))
11876         ;
11877       else
11878         break;
11879     }
11880
11881   if (table_index == ~0)
11882     {
11883       errmsg ("Table index required");
11884       return -99;
11885     }
11886
11887   if (is_add && match == 0)
11888     {
11889       errmsg ("Match value required");
11890       return -99;
11891     }
11892
11893   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11894
11895   mp->is_add = is_add;
11896   mp->table_index = ntohl (table_index);
11897   mp->hit_next_index = ntohl (hit_next_index);
11898   mp->opaque_index = ntohl (opaque_index);
11899   mp->advance = ntohl (advance);
11900   mp->action = action;
11901   mp->metadata = ntohl (metadata);
11902   mp->match_len = ntohl (vec_len (match));
11903   clib_memcpy (mp->match, match, vec_len (match));
11904   vec_free (match);
11905
11906   S (mp);
11907   W (ret);
11908   return ret;
11909 }
11910
11911 static int
11912 api_classify_set_interface_ip_table (vat_main_t * vam)
11913 {
11914   unformat_input_t *i = vam->input;
11915   vl_api_classify_set_interface_ip_table_t *mp;
11916   u32 sw_if_index;
11917   int sw_if_index_set;
11918   u32 table_index = ~0;
11919   u8 is_ipv6 = 0;
11920   int ret;
11921
11922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11923     {
11924       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11925         sw_if_index_set = 1;
11926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11927         sw_if_index_set = 1;
11928       else if (unformat (i, "table %d", &table_index))
11929         ;
11930       else
11931         {
11932           clib_warning ("parse error '%U'", format_unformat_error, i);
11933           return -99;
11934         }
11935     }
11936
11937   if (sw_if_index_set == 0)
11938     {
11939       errmsg ("missing interface name or sw_if_index");
11940       return -99;
11941     }
11942
11943
11944   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11945
11946   mp->sw_if_index = ntohl (sw_if_index);
11947   mp->table_index = ntohl (table_index);
11948   mp->is_ipv6 = is_ipv6;
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static int
11956 api_classify_set_interface_l2_tables (vat_main_t * vam)
11957 {
11958   unformat_input_t *i = vam->input;
11959   vl_api_classify_set_interface_l2_tables_t *mp;
11960   u32 sw_if_index;
11961   int sw_if_index_set;
11962   u32 ip4_table_index = ~0;
11963   u32 ip6_table_index = ~0;
11964   u32 other_table_index = ~0;
11965   u32 is_input = 1;
11966   int ret;
11967
11968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11969     {
11970       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11971         sw_if_index_set = 1;
11972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11973         sw_if_index_set = 1;
11974       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11975         ;
11976       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11977         ;
11978       else if (unformat (i, "other-table %d", &other_table_index))
11979         ;
11980       else if (unformat (i, "is-input %d", &is_input))
11981         ;
11982       else
11983         {
11984           clib_warning ("parse error '%U'", format_unformat_error, i);
11985           return -99;
11986         }
11987     }
11988
11989   if (sw_if_index_set == 0)
11990     {
11991       errmsg ("missing interface name or sw_if_index");
11992       return -99;
11993     }
11994
11995
11996   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11997
11998   mp->sw_if_index = ntohl (sw_if_index);
11999   mp->ip4_table_index = ntohl (ip4_table_index);
12000   mp->ip6_table_index = ntohl (ip6_table_index);
12001   mp->other_table_index = ntohl (other_table_index);
12002   mp->is_input = (u8) is_input;
12003
12004   S (mp);
12005   W (ret);
12006   return ret;
12007 }
12008
12009 static int
12010 api_set_ipfix_exporter (vat_main_t * vam)
12011 {
12012   unformat_input_t *i = vam->input;
12013   vl_api_set_ipfix_exporter_t *mp;
12014   ip4_address_t collector_address;
12015   u8 collector_address_set = 0;
12016   u32 collector_port = ~0;
12017   ip4_address_t src_address;
12018   u8 src_address_set = 0;
12019   u32 vrf_id = ~0;
12020   u32 path_mtu = ~0;
12021   u32 template_interval = ~0;
12022   u8 udp_checksum = 0;
12023   int ret;
12024
12025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12026     {
12027       if (unformat (i, "collector_address %U", unformat_ip4_address,
12028                     &collector_address))
12029         collector_address_set = 1;
12030       else if (unformat (i, "collector_port %d", &collector_port))
12031         ;
12032       else if (unformat (i, "src_address %U", unformat_ip4_address,
12033                          &src_address))
12034         src_address_set = 1;
12035       else if (unformat (i, "vrf_id %d", &vrf_id))
12036         ;
12037       else if (unformat (i, "path_mtu %d", &path_mtu))
12038         ;
12039       else if (unformat (i, "template_interval %d", &template_interval))
12040         ;
12041       else if (unformat (i, "udp_checksum"))
12042         udp_checksum = 1;
12043       else
12044         break;
12045     }
12046
12047   if (collector_address_set == 0)
12048     {
12049       errmsg ("collector_address required");
12050       return -99;
12051     }
12052
12053   if (src_address_set == 0)
12054     {
12055       errmsg ("src_address required");
12056       return -99;
12057     }
12058
12059   M (SET_IPFIX_EXPORTER, mp);
12060
12061   memcpy (mp->collector_address, collector_address.data,
12062           sizeof (collector_address.data));
12063   mp->collector_port = htons ((u16) collector_port);
12064   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12065   mp->vrf_id = htonl (vrf_id);
12066   mp->path_mtu = htonl (path_mtu);
12067   mp->template_interval = htonl (template_interval);
12068   mp->udp_checksum = udp_checksum;
12069
12070   S (mp);
12071   W (ret);
12072   return ret;
12073 }
12074
12075 static int
12076 api_set_ipfix_classify_stream (vat_main_t * vam)
12077 {
12078   unformat_input_t *i = vam->input;
12079   vl_api_set_ipfix_classify_stream_t *mp;
12080   u32 domain_id = 0;
12081   u32 src_port = UDP_DST_PORT_ipfix;
12082   int ret;
12083
12084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (i, "domain %d", &domain_id))
12087         ;
12088       else if (unformat (i, "src_port %d", &src_port))
12089         ;
12090       else
12091         {
12092           errmsg ("unknown input `%U'", format_unformat_error, i);
12093           return -99;
12094         }
12095     }
12096
12097   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12098
12099   mp->domain_id = htonl (domain_id);
12100   mp->src_port = htons ((u16) src_port);
12101
12102   S (mp);
12103   W (ret);
12104   return ret;
12105 }
12106
12107 static int
12108 api_ipfix_classify_table_add_del (vat_main_t * vam)
12109 {
12110   unformat_input_t *i = vam->input;
12111   vl_api_ipfix_classify_table_add_del_t *mp;
12112   int is_add = -1;
12113   u32 classify_table_index = ~0;
12114   u8 ip_version = 0;
12115   u8 transport_protocol = 255;
12116   int ret;
12117
12118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12119     {
12120       if (unformat (i, "add"))
12121         is_add = 1;
12122       else if (unformat (i, "del"))
12123         is_add = 0;
12124       else if (unformat (i, "table %d", &classify_table_index))
12125         ;
12126       else if (unformat (i, "ip4"))
12127         ip_version = 4;
12128       else if (unformat (i, "ip6"))
12129         ip_version = 6;
12130       else if (unformat (i, "tcp"))
12131         transport_protocol = 6;
12132       else if (unformat (i, "udp"))
12133         transport_protocol = 17;
12134       else
12135         {
12136           errmsg ("unknown input `%U'", format_unformat_error, i);
12137           return -99;
12138         }
12139     }
12140
12141   if (is_add == -1)
12142     {
12143       errmsg ("expecting: add|del");
12144       return -99;
12145     }
12146   if (classify_table_index == ~0)
12147     {
12148       errmsg ("classifier table not specified");
12149       return -99;
12150     }
12151   if (ip_version == 0)
12152     {
12153       errmsg ("IP version not specified");
12154       return -99;
12155     }
12156
12157   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12158
12159   mp->is_add = is_add;
12160   mp->table_id = htonl (classify_table_index);
12161   mp->ip_version = ip_version;
12162   mp->transport_protocol = transport_protocol;
12163
12164   S (mp);
12165   W (ret);
12166   return ret;
12167 }
12168
12169 static int
12170 api_get_node_index (vat_main_t * vam)
12171 {
12172   unformat_input_t *i = vam->input;
12173   vl_api_get_node_index_t *mp;
12174   u8 *name = 0;
12175   int ret;
12176
12177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12178     {
12179       if (unformat (i, "node %s", &name))
12180         ;
12181       else
12182         break;
12183     }
12184   if (name == 0)
12185     {
12186       errmsg ("node name required");
12187       return -99;
12188     }
12189   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12190     {
12191       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12192       return -99;
12193     }
12194
12195   M (GET_NODE_INDEX, mp);
12196   clib_memcpy (mp->node_name, name, vec_len (name));
12197   vec_free (name);
12198
12199   S (mp);
12200   W (ret);
12201   return ret;
12202 }
12203
12204 static int
12205 api_get_next_index (vat_main_t * vam)
12206 {
12207   unformat_input_t *i = vam->input;
12208   vl_api_get_next_index_t *mp;
12209   u8 *node_name = 0, *next_node_name = 0;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "node-name %s", &node_name))
12215         ;
12216       else if (unformat (i, "next-node-name %s", &next_node_name))
12217         break;
12218     }
12219
12220   if (node_name == 0)
12221     {
12222       errmsg ("node name required");
12223       return -99;
12224     }
12225   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12226     {
12227       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12228       return -99;
12229     }
12230
12231   if (next_node_name == 0)
12232     {
12233       errmsg ("next node name required");
12234       return -99;
12235     }
12236   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12237     {
12238       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12239       return -99;
12240     }
12241
12242   M (GET_NEXT_INDEX, mp);
12243   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12244   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12245   vec_free (node_name);
12246   vec_free (next_node_name);
12247
12248   S (mp);
12249   W (ret);
12250   return ret;
12251 }
12252
12253 static int
12254 api_add_node_next (vat_main_t * vam)
12255 {
12256   unformat_input_t *i = vam->input;
12257   vl_api_add_node_next_t *mp;
12258   u8 *name = 0;
12259   u8 *next = 0;
12260   int ret;
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "node %s", &name))
12265         ;
12266       else if (unformat (i, "next %s", &next))
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   if (next == 0)
12282     {
12283       errmsg ("next node required");
12284       return -99;
12285     }
12286   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12287     {
12288       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12289       return -99;
12290     }
12291
12292   M (ADD_NODE_NEXT, mp);
12293   clib_memcpy (mp->node_name, name, vec_len (name));
12294   clib_memcpy (mp->next_name, next, vec_len (next));
12295   vec_free (name);
12296   vec_free (next);
12297
12298   S (mp);
12299   W (ret);
12300   return ret;
12301 }
12302
12303 static int
12304 api_l2tpv3_create_tunnel (vat_main_t * vam)
12305 {
12306   unformat_input_t *i = vam->input;
12307   ip6_address_t client_address, our_address;
12308   int client_address_set = 0;
12309   int our_address_set = 0;
12310   u32 local_session_id = 0;
12311   u32 remote_session_id = 0;
12312   u64 local_cookie = 0;
12313   u64 remote_cookie = 0;
12314   u8 l2_sublayer_present = 0;
12315   vl_api_l2tpv3_create_tunnel_t *mp;
12316   int ret;
12317
12318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12319     {
12320       if (unformat (i, "client_address %U", unformat_ip6_address,
12321                     &client_address))
12322         client_address_set = 1;
12323       else if (unformat (i, "our_address %U", unformat_ip6_address,
12324                          &our_address))
12325         our_address_set = 1;
12326       else if (unformat (i, "local_session_id %d", &local_session_id))
12327         ;
12328       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12329         ;
12330       else if (unformat (i, "local_cookie %lld", &local_cookie))
12331         ;
12332       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12333         ;
12334       else if (unformat (i, "l2-sublayer-present"))
12335         l2_sublayer_present = 1;
12336       else
12337         break;
12338     }
12339
12340   if (client_address_set == 0)
12341     {
12342       errmsg ("client_address required");
12343       return -99;
12344     }
12345
12346   if (our_address_set == 0)
12347     {
12348       errmsg ("our_address required");
12349       return -99;
12350     }
12351
12352   M (L2TPV3_CREATE_TUNNEL, mp);
12353
12354   clib_memcpy (mp->client_address, client_address.as_u8,
12355                sizeof (mp->client_address));
12356
12357   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12358
12359   mp->local_session_id = ntohl (local_session_id);
12360   mp->remote_session_id = ntohl (remote_session_id);
12361   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12362   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12363   mp->l2_sublayer_present = l2_sublayer_present;
12364   mp->is_ipv6 = 1;
12365
12366   S (mp);
12367   W (ret);
12368   return ret;
12369 }
12370
12371 static int
12372 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12373 {
12374   unformat_input_t *i = vam->input;
12375   u32 sw_if_index;
12376   u8 sw_if_index_set = 0;
12377   u64 new_local_cookie = 0;
12378   u64 new_remote_cookie = 0;
12379   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12380   int ret;
12381
12382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12383     {
12384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12385         sw_if_index_set = 1;
12386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12387         sw_if_index_set = 1;
12388       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12389         ;
12390       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12391         ;
12392       else
12393         break;
12394     }
12395
12396   if (sw_if_index_set == 0)
12397     {
12398       errmsg ("missing interface name or sw_if_index");
12399       return -99;
12400     }
12401
12402   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12403
12404   mp->sw_if_index = ntohl (sw_if_index);
12405   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12406   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12407
12408   S (mp);
12409   W (ret);
12410   return ret;
12411 }
12412
12413 static int
12414 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12415 {
12416   unformat_input_t *i = vam->input;
12417   vl_api_l2tpv3_interface_enable_disable_t *mp;
12418   u32 sw_if_index;
12419   u8 sw_if_index_set = 0;
12420   u8 enable_disable = 1;
12421   int ret;
12422
12423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12424     {
12425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12426         sw_if_index_set = 1;
12427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12428         sw_if_index_set = 1;
12429       else if (unformat (i, "enable"))
12430         enable_disable = 1;
12431       else if (unformat (i, "disable"))
12432         enable_disable = 0;
12433       else
12434         break;
12435     }
12436
12437   if (sw_if_index_set == 0)
12438     {
12439       errmsg ("missing interface name or sw_if_index");
12440       return -99;
12441     }
12442
12443   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12444
12445   mp->sw_if_index = ntohl (sw_if_index);
12446   mp->enable_disable = enable_disable;
12447
12448   S (mp);
12449   W (ret);
12450   return ret;
12451 }
12452
12453 static int
12454 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12455 {
12456   unformat_input_t *i = vam->input;
12457   vl_api_l2tpv3_set_lookup_key_t *mp;
12458   u8 key = ~0;
12459   int ret;
12460
12461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12462     {
12463       if (unformat (i, "lookup_v6_src"))
12464         key = L2T_LOOKUP_SRC_ADDRESS;
12465       else if (unformat (i, "lookup_v6_dst"))
12466         key = L2T_LOOKUP_DST_ADDRESS;
12467       else if (unformat (i, "lookup_session_id"))
12468         key = L2T_LOOKUP_SESSION_ID;
12469       else
12470         break;
12471     }
12472
12473   if (key == (u8) ~ 0)
12474     {
12475       errmsg ("l2tp session lookup key unset");
12476       return -99;
12477     }
12478
12479   M (L2TPV3_SET_LOOKUP_KEY, mp);
12480
12481   mp->key = key;
12482
12483   S (mp);
12484   W (ret);
12485   return ret;
12486 }
12487
12488 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12489   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12490 {
12491   vat_main_t *vam = &vat_main;
12492
12493   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12494          format_ip6_address, mp->our_address,
12495          format_ip6_address, mp->client_address,
12496          clib_net_to_host_u32 (mp->sw_if_index));
12497
12498   print (vam->ofp,
12499          "   local cookies %016llx %016llx remote cookie %016llx",
12500          clib_net_to_host_u64 (mp->local_cookie[0]),
12501          clib_net_to_host_u64 (mp->local_cookie[1]),
12502          clib_net_to_host_u64 (mp->remote_cookie));
12503
12504   print (vam->ofp, "   local session-id %d remote session-id %d",
12505          clib_net_to_host_u32 (mp->local_session_id),
12506          clib_net_to_host_u32 (mp->remote_session_id));
12507
12508   print (vam->ofp, "   l2 specific sublayer %s\n",
12509          mp->l2_sublayer_present ? "preset" : "absent");
12510
12511 }
12512
12513 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12514   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12515 {
12516   vat_main_t *vam = &vat_main;
12517   vat_json_node_t *node = NULL;
12518   struct in6_addr addr;
12519
12520   if (VAT_JSON_ARRAY != vam->json_tree.type)
12521     {
12522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12523       vat_json_init_array (&vam->json_tree);
12524     }
12525   node = vat_json_array_add (&vam->json_tree);
12526
12527   vat_json_init_object (node);
12528
12529   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12530   vat_json_object_add_ip6 (node, "our_address", addr);
12531   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12532   vat_json_object_add_ip6 (node, "client_address", addr);
12533
12534   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12535   vat_json_init_array (lc);
12536   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12537   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12538   vat_json_object_add_uint (node, "remote_cookie",
12539                             clib_net_to_host_u64 (mp->remote_cookie));
12540
12541   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12542   vat_json_object_add_uint (node, "local_session_id",
12543                             clib_net_to_host_u32 (mp->local_session_id));
12544   vat_json_object_add_uint (node, "remote_session_id",
12545                             clib_net_to_host_u32 (mp->remote_session_id));
12546   vat_json_object_add_string_copy (node, "l2_sublayer",
12547                                    mp->l2_sublayer_present ? (u8 *) "present"
12548                                    : (u8 *) "absent");
12549 }
12550
12551 static int
12552 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12553 {
12554   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12555   vl_api_control_ping_t *mp_ping;
12556   int ret;
12557
12558   /* Get list of l2tpv3-tunnel interfaces */
12559   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12560   S (mp);
12561
12562   /* Use a control ping for synchronization */
12563   MPING (CONTROL_PING, mp_ping);
12564   S (mp_ping);
12565
12566   W (ret);
12567   return ret;
12568 }
12569
12570
12571 static void vl_api_sw_interface_tap_v2_details_t_handler
12572   (vl_api_sw_interface_tap_v2_details_t * mp)
12573 {
12574   vat_main_t *vam = &vat_main;
12575
12576   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12577                     mp->host_ip4_prefix_len);
12578   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12579                     mp->host_ip6_prefix_len);
12580
12581   print (vam->ofp,
12582          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12583          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12584          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12585          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12586          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12587
12588   vec_free (ip4);
12589   vec_free (ip6);
12590 }
12591
12592 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12593   (vl_api_sw_interface_tap_v2_details_t * mp)
12594 {
12595   vat_main_t *vam = &vat_main;
12596   vat_json_node_t *node = NULL;
12597
12598   if (VAT_JSON_ARRAY != vam->json_tree.type)
12599     {
12600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12601       vat_json_init_array (&vam->json_tree);
12602     }
12603   node = vat_json_array_add (&vam->json_tree);
12604
12605   vat_json_init_object (node);
12606   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12607   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12608   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12609   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12610   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12611   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12612   vat_json_object_add_string_copy (node, "host_mac_addr",
12613                                    format (0, "%U", format_ethernet_address,
12614                                            &mp->host_mac_addr));
12615   vat_json_object_add_string_copy (node, "host_namespace",
12616                                    mp->host_namespace);
12617   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12618   vat_json_object_add_string_copy (node, "host_ip4_addr",
12619                                    format (0, "%U/%d", format_ip4_address,
12620                                            mp->host_ip4_addr,
12621                                            mp->host_ip4_prefix_len));
12622   vat_json_object_add_string_copy (node, "host_ip6_addr",
12623                                    format (0, "%U/%d", format_ip6_address,
12624                                            mp->host_ip6_addr,
12625                                            mp->host_ip6_prefix_len));
12626
12627 }
12628
12629 static int
12630 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12631 {
12632   vl_api_sw_interface_tap_v2_dump_t *mp;
12633   vl_api_control_ping_t *mp_ping;
12634   int ret;
12635
12636   print (vam->ofp,
12637          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12638          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12639          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12640          "host_ip6_addr");
12641
12642   /* Get list of tap interfaces */
12643   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12644   S (mp);
12645
12646   /* Use a control ping for synchronization */
12647   MPING (CONTROL_PING, mp_ping);
12648   S (mp_ping);
12649
12650   W (ret);
12651   return ret;
12652 }
12653
12654 static void vl_api_sw_interface_virtio_pci_details_t_handler
12655   (vl_api_sw_interface_virtio_pci_details_t * mp)
12656 {
12657   vat_main_t *vam = &vat_main;
12658
12659   typedef union
12660   {
12661     struct
12662     {
12663       u16 domain;
12664       u8 bus;
12665       u8 slot:5;
12666       u8 function:3;
12667     };
12668     u32 as_u32;
12669   } pci_addr_t;
12670   pci_addr_t addr;
12671   addr.as_u32 = ntohl (mp->pci_addr);
12672   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12673                          addr.slot, addr.function);
12674
12675   print (vam->ofp,
12676          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12677          pci_addr, ntohl (mp->sw_if_index),
12678          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12679          format_ethernet_address, mp->mac_addr,
12680          clib_net_to_host_u64 (mp->features));
12681   vec_free (pci_addr);
12682 }
12683
12684 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12685   (vl_api_sw_interface_virtio_pci_details_t * mp)
12686 {
12687   vat_main_t *vam = &vat_main;
12688   vat_json_node_t *node = NULL;
12689
12690   if (VAT_JSON_ARRAY != vam->json_tree.type)
12691     {
12692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12693       vat_json_init_array (&vam->json_tree);
12694     }
12695   node = vat_json_array_add (&vam->json_tree);
12696
12697   vat_json_init_object (node);
12698   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12700   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12701   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12702   vat_json_object_add_uint (node, "features",
12703                             clib_net_to_host_u64 (mp->features));
12704   vat_json_object_add_string_copy (node, "mac_addr",
12705                                    format (0, "%U", format_ethernet_address,
12706                                            &mp->mac_addr));
12707 }
12708
12709 static int
12710 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12711 {
12712   vl_api_sw_interface_virtio_pci_dump_t *mp;
12713   vl_api_control_ping_t *mp_ping;
12714   int ret;
12715
12716   print (vam->ofp,
12717          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12718          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12719          "mac_addr", "features");
12720
12721   /* Get list of tap interfaces */
12722   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12723   S (mp);
12724
12725   /* Use a control ping for synchronization */
12726   MPING (CONTROL_PING, mp_ping);
12727   S (mp_ping);
12728
12729   W (ret);
12730   return ret;
12731 }
12732
12733 static int
12734 api_vxlan_offload_rx (vat_main_t * vam)
12735 {
12736   unformat_input_t *line_input = vam->input;
12737   vl_api_vxlan_offload_rx_t *mp;
12738   u32 hw_if_index = ~0, rx_if_index = ~0;
12739   u8 is_add = 1;
12740   int ret;
12741
12742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12743     {
12744       if (unformat (line_input, "del"))
12745         is_add = 0;
12746       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12747                          &hw_if_index))
12748         ;
12749       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12750         ;
12751       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12752                          &rx_if_index))
12753         ;
12754       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12755         ;
12756       else
12757         {
12758           errmsg ("parse error '%U'", format_unformat_error, line_input);
12759           return -99;
12760         }
12761     }
12762
12763   if (hw_if_index == ~0)
12764     {
12765       errmsg ("no hw interface");
12766       return -99;
12767     }
12768
12769   if (rx_if_index == ~0)
12770     {
12771       errmsg ("no rx tunnel");
12772       return -99;
12773     }
12774
12775   M (VXLAN_OFFLOAD_RX, mp);
12776
12777   mp->hw_if_index = ntohl (hw_if_index);
12778   mp->sw_if_index = ntohl (rx_if_index);
12779   mp->enable = is_add;
12780
12781   S (mp);
12782   W (ret);
12783   return ret;
12784 }
12785
12786 static uword unformat_vxlan_decap_next
12787   (unformat_input_t * input, va_list * args)
12788 {
12789   u32 *result = va_arg (*args, u32 *);
12790   u32 tmp;
12791
12792   if (unformat (input, "l2"))
12793     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12794   else if (unformat (input, "%d", &tmp))
12795     *result = tmp;
12796   else
12797     return 0;
12798   return 1;
12799 }
12800
12801 static int
12802 api_vxlan_add_del_tunnel (vat_main_t * vam)
12803 {
12804   unformat_input_t *line_input = vam->input;
12805   vl_api_vxlan_add_del_tunnel_t *mp;
12806   ip46_address_t src, dst;
12807   u8 is_add = 1;
12808   u8 ipv4_set = 0, ipv6_set = 0;
12809   u8 src_set = 0;
12810   u8 dst_set = 0;
12811   u8 grp_set = 0;
12812   u32 instance = ~0;
12813   u32 mcast_sw_if_index = ~0;
12814   u32 encap_vrf_id = 0;
12815   u32 decap_next_index = ~0;
12816   u32 vni = 0;
12817   int ret;
12818
12819   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12820   clib_memset (&src, 0, sizeof src);
12821   clib_memset (&dst, 0, sizeof dst);
12822
12823   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12824     {
12825       if (unformat (line_input, "del"))
12826         is_add = 0;
12827       else if (unformat (line_input, "instance %d", &instance))
12828         ;
12829       else
12830         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12831         {
12832           ipv4_set = 1;
12833           src_set = 1;
12834         }
12835       else
12836         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12837         {
12838           ipv4_set = 1;
12839           dst_set = 1;
12840         }
12841       else
12842         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12843         {
12844           ipv6_set = 1;
12845           src_set = 1;
12846         }
12847       else
12848         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12849         {
12850           ipv6_set = 1;
12851           dst_set = 1;
12852         }
12853       else if (unformat (line_input, "group %U %U",
12854                          unformat_ip4_address, &dst.ip4,
12855                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12856         {
12857           grp_set = dst_set = 1;
12858           ipv4_set = 1;
12859         }
12860       else if (unformat (line_input, "group %U",
12861                          unformat_ip4_address, &dst.ip4))
12862         {
12863           grp_set = dst_set = 1;
12864           ipv4_set = 1;
12865         }
12866       else if (unformat (line_input, "group %U %U",
12867                          unformat_ip6_address, &dst.ip6,
12868                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12869         {
12870           grp_set = dst_set = 1;
12871           ipv6_set = 1;
12872         }
12873       else if (unformat (line_input, "group %U",
12874                          unformat_ip6_address, &dst.ip6))
12875         {
12876           grp_set = dst_set = 1;
12877           ipv6_set = 1;
12878         }
12879       else
12880         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12881         ;
12882       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12883         ;
12884       else if (unformat (line_input, "decap-next %U",
12885                          unformat_vxlan_decap_next, &decap_next_index))
12886         ;
12887       else if (unformat (line_input, "vni %d", &vni))
12888         ;
12889       else
12890         {
12891           errmsg ("parse error '%U'", format_unformat_error, line_input);
12892           return -99;
12893         }
12894     }
12895
12896   if (src_set == 0)
12897     {
12898       errmsg ("tunnel src address not specified");
12899       return -99;
12900     }
12901   if (dst_set == 0)
12902     {
12903       errmsg ("tunnel dst address not specified");
12904       return -99;
12905     }
12906
12907   if (grp_set && !ip46_address_is_multicast (&dst))
12908     {
12909       errmsg ("tunnel group address not multicast");
12910       return -99;
12911     }
12912   if (grp_set && mcast_sw_if_index == ~0)
12913     {
12914       errmsg ("tunnel nonexistent multicast device");
12915       return -99;
12916     }
12917   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12918     {
12919       errmsg ("tunnel dst address must be unicast");
12920       return -99;
12921     }
12922
12923
12924   if (ipv4_set && ipv6_set)
12925     {
12926       errmsg ("both IPv4 and IPv6 addresses specified");
12927       return -99;
12928     }
12929
12930   if ((vni == 0) || (vni >> 24))
12931     {
12932       errmsg ("vni not specified or out of range");
12933       return -99;
12934     }
12935
12936   M (VXLAN_ADD_DEL_TUNNEL, mp);
12937
12938   if (ipv6_set)
12939     {
12940       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12941       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12942     }
12943   else
12944     {
12945       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12946       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12947     }
12948
12949   mp->instance = htonl (instance);
12950   mp->encap_vrf_id = ntohl (encap_vrf_id);
12951   mp->decap_next_index = ntohl (decap_next_index);
12952   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12953   mp->vni = ntohl (vni);
12954   mp->is_add = is_add;
12955   mp->is_ipv6 = ipv6_set;
12956
12957   S (mp);
12958   W (ret);
12959   return ret;
12960 }
12961
12962 static void vl_api_vxlan_tunnel_details_t_handler
12963   (vl_api_vxlan_tunnel_details_t * mp)
12964 {
12965   vat_main_t *vam = &vat_main;
12966   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12967   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12968
12969   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12970          ntohl (mp->sw_if_index),
12971          ntohl (mp->instance),
12972          format_ip46_address, &src, IP46_TYPE_ANY,
12973          format_ip46_address, &dst, IP46_TYPE_ANY,
12974          ntohl (mp->encap_vrf_id),
12975          ntohl (mp->decap_next_index), ntohl (mp->vni),
12976          ntohl (mp->mcast_sw_if_index));
12977 }
12978
12979 static void vl_api_vxlan_tunnel_details_t_handler_json
12980   (vl_api_vxlan_tunnel_details_t * mp)
12981 {
12982   vat_main_t *vam = &vat_main;
12983   vat_json_node_t *node = NULL;
12984
12985   if (VAT_JSON_ARRAY != vam->json_tree.type)
12986     {
12987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12988       vat_json_init_array (&vam->json_tree);
12989     }
12990   node = vat_json_array_add (&vam->json_tree);
12991
12992   vat_json_init_object (node);
12993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12994
12995   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12996
12997   if (mp->is_ipv6)
12998     {
12999       struct in6_addr ip6;
13000
13001       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13002       vat_json_object_add_ip6 (node, "src_address", ip6);
13003       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13004       vat_json_object_add_ip6 (node, "dst_address", ip6);
13005     }
13006   else
13007     {
13008       struct in_addr ip4;
13009
13010       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13011       vat_json_object_add_ip4 (node, "src_address", ip4);
13012       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13013       vat_json_object_add_ip4 (node, "dst_address", ip4);
13014     }
13015   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13016   vat_json_object_add_uint (node, "decap_next_index",
13017                             ntohl (mp->decap_next_index));
13018   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13019   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13020   vat_json_object_add_uint (node, "mcast_sw_if_index",
13021                             ntohl (mp->mcast_sw_if_index));
13022 }
13023
13024 static int
13025 api_vxlan_tunnel_dump (vat_main_t * vam)
13026 {
13027   unformat_input_t *i = vam->input;
13028   vl_api_vxlan_tunnel_dump_t *mp;
13029   vl_api_control_ping_t *mp_ping;
13030   u32 sw_if_index;
13031   u8 sw_if_index_set = 0;
13032   int ret;
13033
13034   /* Parse args required to build the message */
13035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13036     {
13037       if (unformat (i, "sw_if_index %d", &sw_if_index))
13038         sw_if_index_set = 1;
13039       else
13040         break;
13041     }
13042
13043   if (sw_if_index_set == 0)
13044     {
13045       sw_if_index = ~0;
13046     }
13047
13048   if (!vam->json_output)
13049     {
13050       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13051              "sw_if_index", "instance", "src_address", "dst_address",
13052              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13053     }
13054
13055   /* Get list of vxlan-tunnel interfaces */
13056   M (VXLAN_TUNNEL_DUMP, mp);
13057
13058   mp->sw_if_index = htonl (sw_if_index);
13059
13060   S (mp);
13061
13062   /* Use a control ping for synchronization */
13063   MPING (CONTROL_PING, mp_ping);
13064   S (mp_ping);
13065
13066   W (ret);
13067   return ret;
13068 }
13069
13070 static uword unformat_geneve_decap_next
13071   (unformat_input_t * input, va_list * args)
13072 {
13073   u32 *result = va_arg (*args, u32 *);
13074   u32 tmp;
13075
13076   if (unformat (input, "l2"))
13077     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13078   else if (unformat (input, "%d", &tmp))
13079     *result = tmp;
13080   else
13081     return 0;
13082   return 1;
13083 }
13084
13085 static int
13086 api_geneve_add_del_tunnel (vat_main_t * vam)
13087 {
13088   unformat_input_t *line_input = vam->input;
13089   vl_api_geneve_add_del_tunnel_t *mp;
13090   ip46_address_t src, dst;
13091   u8 is_add = 1;
13092   u8 ipv4_set = 0, ipv6_set = 0;
13093   u8 src_set = 0;
13094   u8 dst_set = 0;
13095   u8 grp_set = 0;
13096   u32 mcast_sw_if_index = ~0;
13097   u32 encap_vrf_id = 0;
13098   u32 decap_next_index = ~0;
13099   u32 vni = 0;
13100   int ret;
13101
13102   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13103   clib_memset (&src, 0, sizeof src);
13104   clib_memset (&dst, 0, sizeof dst);
13105
13106   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13107     {
13108       if (unformat (line_input, "del"))
13109         is_add = 0;
13110       else
13111         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13112         {
13113           ipv4_set = 1;
13114           src_set = 1;
13115         }
13116       else
13117         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13118         {
13119           ipv4_set = 1;
13120           dst_set = 1;
13121         }
13122       else
13123         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13124         {
13125           ipv6_set = 1;
13126           src_set = 1;
13127         }
13128       else
13129         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13130         {
13131           ipv6_set = 1;
13132           dst_set = 1;
13133         }
13134       else if (unformat (line_input, "group %U %U",
13135                          unformat_ip4_address, &dst.ip4,
13136                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13137         {
13138           grp_set = dst_set = 1;
13139           ipv4_set = 1;
13140         }
13141       else if (unformat (line_input, "group %U",
13142                          unformat_ip4_address, &dst.ip4))
13143         {
13144           grp_set = dst_set = 1;
13145           ipv4_set = 1;
13146         }
13147       else if (unformat (line_input, "group %U %U",
13148                          unformat_ip6_address, &dst.ip6,
13149                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13150         {
13151           grp_set = dst_set = 1;
13152           ipv6_set = 1;
13153         }
13154       else if (unformat (line_input, "group %U",
13155                          unformat_ip6_address, &dst.ip6))
13156         {
13157           grp_set = dst_set = 1;
13158           ipv6_set = 1;
13159         }
13160       else
13161         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13162         ;
13163       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13164         ;
13165       else if (unformat (line_input, "decap-next %U",
13166                          unformat_geneve_decap_next, &decap_next_index))
13167         ;
13168       else if (unformat (line_input, "vni %d", &vni))
13169         ;
13170       else
13171         {
13172           errmsg ("parse error '%U'", format_unformat_error, line_input);
13173           return -99;
13174         }
13175     }
13176
13177   if (src_set == 0)
13178     {
13179       errmsg ("tunnel src address not specified");
13180       return -99;
13181     }
13182   if (dst_set == 0)
13183     {
13184       errmsg ("tunnel dst address not specified");
13185       return -99;
13186     }
13187
13188   if (grp_set && !ip46_address_is_multicast (&dst))
13189     {
13190       errmsg ("tunnel group address not multicast");
13191       return -99;
13192     }
13193   if (grp_set && mcast_sw_if_index == ~0)
13194     {
13195       errmsg ("tunnel nonexistent multicast device");
13196       return -99;
13197     }
13198   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13199     {
13200       errmsg ("tunnel dst address must be unicast");
13201       return -99;
13202     }
13203
13204
13205   if (ipv4_set && ipv6_set)
13206     {
13207       errmsg ("both IPv4 and IPv6 addresses specified");
13208       return -99;
13209     }
13210
13211   if ((vni == 0) || (vni >> 24))
13212     {
13213       errmsg ("vni not specified or out of range");
13214       return -99;
13215     }
13216
13217   M (GENEVE_ADD_DEL_TUNNEL, mp);
13218
13219   if (ipv6_set)
13220     {
13221       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13222       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13223     }
13224   else
13225     {
13226       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13227       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13228     }
13229   mp->encap_vrf_id = ntohl (encap_vrf_id);
13230   mp->decap_next_index = ntohl (decap_next_index);
13231   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13232   mp->vni = ntohl (vni);
13233   mp->is_add = is_add;
13234   mp->is_ipv6 = ipv6_set;
13235
13236   S (mp);
13237   W (ret);
13238   return ret;
13239 }
13240
13241 static void vl_api_geneve_tunnel_details_t_handler
13242   (vl_api_geneve_tunnel_details_t * mp)
13243 {
13244   vat_main_t *vam = &vat_main;
13245   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13246   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13247
13248   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13249          ntohl (mp->sw_if_index),
13250          format_ip46_address, &src, IP46_TYPE_ANY,
13251          format_ip46_address, &dst, IP46_TYPE_ANY,
13252          ntohl (mp->encap_vrf_id),
13253          ntohl (mp->decap_next_index), ntohl (mp->vni),
13254          ntohl (mp->mcast_sw_if_index));
13255 }
13256
13257 static void vl_api_geneve_tunnel_details_t_handler_json
13258   (vl_api_geneve_tunnel_details_t * mp)
13259 {
13260   vat_main_t *vam = &vat_main;
13261   vat_json_node_t *node = NULL;
13262
13263   if (VAT_JSON_ARRAY != vam->json_tree.type)
13264     {
13265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13266       vat_json_init_array (&vam->json_tree);
13267     }
13268   node = vat_json_array_add (&vam->json_tree);
13269
13270   vat_json_init_object (node);
13271   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13272   if (mp->is_ipv6)
13273     {
13274       struct in6_addr ip6;
13275
13276       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13277       vat_json_object_add_ip6 (node, "src_address", ip6);
13278       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13279       vat_json_object_add_ip6 (node, "dst_address", ip6);
13280     }
13281   else
13282     {
13283       struct in_addr ip4;
13284
13285       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13286       vat_json_object_add_ip4 (node, "src_address", ip4);
13287       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13288       vat_json_object_add_ip4 (node, "dst_address", ip4);
13289     }
13290   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13291   vat_json_object_add_uint (node, "decap_next_index",
13292                             ntohl (mp->decap_next_index));
13293   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13294   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13295   vat_json_object_add_uint (node, "mcast_sw_if_index",
13296                             ntohl (mp->mcast_sw_if_index));
13297 }
13298
13299 static int
13300 api_geneve_tunnel_dump (vat_main_t * vam)
13301 {
13302   unformat_input_t *i = vam->input;
13303   vl_api_geneve_tunnel_dump_t *mp;
13304   vl_api_control_ping_t *mp_ping;
13305   u32 sw_if_index;
13306   u8 sw_if_index_set = 0;
13307   int ret;
13308
13309   /* Parse args required to build the message */
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "sw_if_index %d", &sw_if_index))
13313         sw_if_index_set = 1;
13314       else
13315         break;
13316     }
13317
13318   if (sw_if_index_set == 0)
13319     {
13320       sw_if_index = ~0;
13321     }
13322
13323   if (!vam->json_output)
13324     {
13325       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13326              "sw_if_index", "local_address", "remote_address",
13327              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13328     }
13329
13330   /* Get list of geneve-tunnel interfaces */
13331   M (GENEVE_TUNNEL_DUMP, mp);
13332
13333   mp->sw_if_index = htonl (sw_if_index);
13334
13335   S (mp);
13336
13337   /* Use a control ping for synchronization */
13338   M (CONTROL_PING, mp_ping);
13339   S (mp_ping);
13340
13341   W (ret);
13342   return ret;
13343 }
13344
13345 static int
13346 api_gre_add_del_tunnel (vat_main_t * vam)
13347 {
13348   unformat_input_t *line_input = vam->input;
13349   vl_api_gre_add_del_tunnel_t *mp;
13350   ip4_address_t src4, dst4;
13351   ip6_address_t src6, dst6;
13352   u8 is_add = 1;
13353   u8 ipv4_set = 0;
13354   u8 ipv6_set = 0;
13355   u8 t_type = GRE_TUNNEL_TYPE_L3;
13356   u8 src_set = 0;
13357   u8 dst_set = 0;
13358   u32 outer_fib_id = 0;
13359   u32 session_id = 0;
13360   u32 instance = ~0;
13361   int ret;
13362
13363   clib_memset (&src4, 0, sizeof src4);
13364   clib_memset (&dst4, 0, sizeof dst4);
13365   clib_memset (&src6, 0, sizeof src6);
13366   clib_memset (&dst6, 0, sizeof dst6);
13367
13368   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13369     {
13370       if (unformat (line_input, "del"))
13371         is_add = 0;
13372       else if (unformat (line_input, "instance %d", &instance))
13373         ;
13374       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13375         {
13376           src_set = 1;
13377           ipv4_set = 1;
13378         }
13379       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13380         {
13381           dst_set = 1;
13382           ipv4_set = 1;
13383         }
13384       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13385         {
13386           src_set = 1;
13387           ipv6_set = 1;
13388         }
13389       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13390         {
13391           dst_set = 1;
13392           ipv6_set = 1;
13393         }
13394       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13395         ;
13396       else if (unformat (line_input, "teb"))
13397         t_type = GRE_TUNNEL_TYPE_TEB;
13398       else if (unformat (line_input, "erspan %d", &session_id))
13399         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13400       else
13401         {
13402           errmsg ("parse error '%U'", format_unformat_error, line_input);
13403           return -99;
13404         }
13405     }
13406
13407   if (src_set == 0)
13408     {
13409       errmsg ("tunnel src address not specified");
13410       return -99;
13411     }
13412   if (dst_set == 0)
13413     {
13414       errmsg ("tunnel dst address not specified");
13415       return -99;
13416     }
13417   if (ipv4_set && ipv6_set)
13418     {
13419       errmsg ("both IPv4 and IPv6 addresses specified");
13420       return -99;
13421     }
13422
13423
13424   M (GRE_ADD_DEL_TUNNEL, mp);
13425
13426   if (ipv4_set)
13427     {
13428       clib_memcpy (&mp->src_address, &src4, 4);
13429       clib_memcpy (&mp->dst_address, &dst4, 4);
13430     }
13431   else
13432     {
13433       clib_memcpy (&mp->src_address, &src6, 16);
13434       clib_memcpy (&mp->dst_address, &dst6, 16);
13435     }
13436   mp->instance = htonl (instance);
13437   mp->outer_fib_id = htonl (outer_fib_id);
13438   mp->is_add = is_add;
13439   mp->session_id = htons ((u16) session_id);
13440   mp->tunnel_type = t_type;
13441   mp->is_ipv6 = ipv6_set;
13442
13443   S (mp);
13444   W (ret);
13445   return ret;
13446 }
13447
13448 static void vl_api_gre_tunnel_details_t_handler
13449   (vl_api_gre_tunnel_details_t * mp)
13450 {
13451   vat_main_t *vam = &vat_main;
13452   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13453   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13454
13455   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13456          ntohl (mp->sw_if_index),
13457          ntohl (mp->instance),
13458          format_ip46_address, &src, IP46_TYPE_ANY,
13459          format_ip46_address, &dst, IP46_TYPE_ANY,
13460          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13461 }
13462
13463 static void vl_api_gre_tunnel_details_t_handler_json
13464   (vl_api_gre_tunnel_details_t * mp)
13465 {
13466   vat_main_t *vam = &vat_main;
13467   vat_json_node_t *node = NULL;
13468   struct in_addr ip4;
13469   struct in6_addr ip6;
13470
13471   if (VAT_JSON_ARRAY != vam->json_tree.type)
13472     {
13473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13474       vat_json_init_array (&vam->json_tree);
13475     }
13476   node = vat_json_array_add (&vam->json_tree);
13477
13478   vat_json_init_object (node);
13479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13480   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13481   if (!mp->is_ipv6)
13482     {
13483       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13484       vat_json_object_add_ip4 (node, "src_address", ip4);
13485       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13486       vat_json_object_add_ip4 (node, "dst_address", ip4);
13487     }
13488   else
13489     {
13490       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13491       vat_json_object_add_ip6 (node, "src_address", ip6);
13492       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13493       vat_json_object_add_ip6 (node, "dst_address", ip6);
13494     }
13495   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13496   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13497   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13498   vat_json_object_add_uint (node, "session_id", mp->session_id);
13499 }
13500
13501 static int
13502 api_gre_tunnel_dump (vat_main_t * vam)
13503 {
13504   unformat_input_t *i = vam->input;
13505   vl_api_gre_tunnel_dump_t *mp;
13506   vl_api_control_ping_t *mp_ping;
13507   u32 sw_if_index;
13508   u8 sw_if_index_set = 0;
13509   int ret;
13510
13511   /* Parse args required to build the message */
13512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13513     {
13514       if (unformat (i, "sw_if_index %d", &sw_if_index))
13515         sw_if_index_set = 1;
13516       else
13517         break;
13518     }
13519
13520   if (sw_if_index_set == 0)
13521     {
13522       sw_if_index = ~0;
13523     }
13524
13525   if (!vam->json_output)
13526     {
13527       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13528              "sw_if_index", "instance", "src_address", "dst_address",
13529              "tunnel_type", "outer_fib_id", "session_id");
13530     }
13531
13532   /* Get list of gre-tunnel interfaces */
13533   M (GRE_TUNNEL_DUMP, mp);
13534
13535   mp->sw_if_index = htonl (sw_if_index);
13536
13537   S (mp);
13538
13539   /* Use a control ping for synchronization */
13540   MPING (CONTROL_PING, mp_ping);
13541   S (mp_ping);
13542
13543   W (ret);
13544   return ret;
13545 }
13546
13547 static int
13548 api_l2_fib_clear_table (vat_main_t * vam)
13549 {
13550 //  unformat_input_t * i = vam->input;
13551   vl_api_l2_fib_clear_table_t *mp;
13552   int ret;
13553
13554   M (L2_FIB_CLEAR_TABLE, mp);
13555
13556   S (mp);
13557   W (ret);
13558   return ret;
13559 }
13560
13561 static int
13562 api_l2_interface_efp_filter (vat_main_t * vam)
13563 {
13564   unformat_input_t *i = vam->input;
13565   vl_api_l2_interface_efp_filter_t *mp;
13566   u32 sw_if_index;
13567   u8 enable = 1;
13568   u8 sw_if_index_set = 0;
13569   int ret;
13570
13571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13572     {
13573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13574         sw_if_index_set = 1;
13575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13576         sw_if_index_set = 1;
13577       else if (unformat (i, "enable"))
13578         enable = 1;
13579       else if (unformat (i, "disable"))
13580         enable = 0;
13581       else
13582         {
13583           clib_warning ("parse error '%U'", format_unformat_error, i);
13584           return -99;
13585         }
13586     }
13587
13588   if (sw_if_index_set == 0)
13589     {
13590       errmsg ("missing sw_if_index");
13591       return -99;
13592     }
13593
13594   M (L2_INTERFACE_EFP_FILTER, mp);
13595
13596   mp->sw_if_index = ntohl (sw_if_index);
13597   mp->enable_disable = enable;
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 #define foreach_vtr_op                          \
13605 _("disable",  L2_VTR_DISABLED)                  \
13606 _("push-1",  L2_VTR_PUSH_1)                     \
13607 _("push-2",  L2_VTR_PUSH_2)                     \
13608 _("pop-1",  L2_VTR_POP_1)                       \
13609 _("pop-2",  L2_VTR_POP_2)                       \
13610 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13611 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13612 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13613 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13614
13615 static int
13616 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13617 {
13618   unformat_input_t *i = vam->input;
13619   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13620   u32 sw_if_index;
13621   u8 sw_if_index_set = 0;
13622   u8 vtr_op_set = 0;
13623   u32 vtr_op = 0;
13624   u32 push_dot1q = 1;
13625   u32 tag1 = ~0;
13626   u32 tag2 = ~0;
13627   int ret;
13628
13629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13630     {
13631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13632         sw_if_index_set = 1;
13633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13634         sw_if_index_set = 1;
13635       else if (unformat (i, "vtr_op %d", &vtr_op))
13636         vtr_op_set = 1;
13637 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13638       foreach_vtr_op
13639 #undef _
13640         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13641         ;
13642       else if (unformat (i, "tag1 %d", &tag1))
13643         ;
13644       else if (unformat (i, "tag2 %d", &tag2))
13645         ;
13646       else
13647         {
13648           clib_warning ("parse error '%U'", format_unformat_error, i);
13649           return -99;
13650         }
13651     }
13652
13653   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13654     {
13655       errmsg ("missing vtr operation or sw_if_index");
13656       return -99;
13657     }
13658
13659   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13660   mp->sw_if_index = ntohl (sw_if_index);
13661   mp->vtr_op = ntohl (vtr_op);
13662   mp->push_dot1q = ntohl (push_dot1q);
13663   mp->tag1 = ntohl (tag1);
13664   mp->tag2 = ntohl (tag2);
13665
13666   S (mp);
13667   W (ret);
13668   return ret;
13669 }
13670
13671 static int
13672 api_create_vhost_user_if (vat_main_t * vam)
13673 {
13674   unformat_input_t *i = vam->input;
13675   vl_api_create_vhost_user_if_t *mp;
13676   u8 *file_name;
13677   u8 is_server = 0;
13678   u8 file_name_set = 0;
13679   u32 custom_dev_instance = ~0;
13680   u8 hwaddr[6];
13681   u8 use_custom_mac = 0;
13682   u8 disable_mrg_rxbuf = 0;
13683   u8 disable_indirect_desc = 0;
13684   u8 *tag = 0;
13685   int ret;
13686
13687   /* Shut up coverity */
13688   clib_memset (hwaddr, 0, sizeof (hwaddr));
13689
13690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13691     {
13692       if (unformat (i, "socket %s", &file_name))
13693         {
13694           file_name_set = 1;
13695         }
13696       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13697         ;
13698       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13699         use_custom_mac = 1;
13700       else if (unformat (i, "server"))
13701         is_server = 1;
13702       else if (unformat (i, "disable_mrg_rxbuf"))
13703         disable_mrg_rxbuf = 1;
13704       else if (unformat (i, "disable_indirect_desc"))
13705         disable_indirect_desc = 1;
13706       else if (unformat (i, "tag %s", &tag))
13707         ;
13708       else
13709         break;
13710     }
13711
13712   if (file_name_set == 0)
13713     {
13714       errmsg ("missing socket file name");
13715       return -99;
13716     }
13717
13718   if (vec_len (file_name) > 255)
13719     {
13720       errmsg ("socket file name too long");
13721       return -99;
13722     }
13723   vec_add1 (file_name, 0);
13724
13725   M (CREATE_VHOST_USER_IF, mp);
13726
13727   mp->is_server = is_server;
13728   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13729   mp->disable_indirect_desc = disable_indirect_desc;
13730   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13731   vec_free (file_name);
13732   if (custom_dev_instance != ~0)
13733     {
13734       mp->renumber = 1;
13735       mp->custom_dev_instance = ntohl (custom_dev_instance);
13736     }
13737
13738   mp->use_custom_mac = use_custom_mac;
13739   clib_memcpy (mp->mac_address, hwaddr, 6);
13740   if (tag)
13741     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13742   vec_free (tag);
13743
13744   S (mp);
13745   W (ret);
13746   return ret;
13747 }
13748
13749 static int
13750 api_modify_vhost_user_if (vat_main_t * vam)
13751 {
13752   unformat_input_t *i = vam->input;
13753   vl_api_modify_vhost_user_if_t *mp;
13754   u8 *file_name;
13755   u8 is_server = 0;
13756   u8 file_name_set = 0;
13757   u32 custom_dev_instance = ~0;
13758   u8 sw_if_index_set = 0;
13759   u32 sw_if_index = (u32) ~ 0;
13760   int ret;
13761
13762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13763     {
13764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13765         sw_if_index_set = 1;
13766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13767         sw_if_index_set = 1;
13768       else if (unformat (i, "socket %s", &file_name))
13769         {
13770           file_name_set = 1;
13771         }
13772       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13773         ;
13774       else if (unformat (i, "server"))
13775         is_server = 1;
13776       else
13777         break;
13778     }
13779
13780   if (sw_if_index_set == 0)
13781     {
13782       errmsg ("missing sw_if_index or interface name");
13783       return -99;
13784     }
13785
13786   if (file_name_set == 0)
13787     {
13788       errmsg ("missing socket file name");
13789       return -99;
13790     }
13791
13792   if (vec_len (file_name) > 255)
13793     {
13794       errmsg ("socket file name too long");
13795       return -99;
13796     }
13797   vec_add1 (file_name, 0);
13798
13799   M (MODIFY_VHOST_USER_IF, mp);
13800
13801   mp->sw_if_index = ntohl (sw_if_index);
13802   mp->is_server = is_server;
13803   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13804   vec_free (file_name);
13805   if (custom_dev_instance != ~0)
13806     {
13807       mp->renumber = 1;
13808       mp->custom_dev_instance = ntohl (custom_dev_instance);
13809     }
13810
13811   S (mp);
13812   W (ret);
13813   return ret;
13814 }
13815
13816 static int
13817 api_delete_vhost_user_if (vat_main_t * vam)
13818 {
13819   unformat_input_t *i = vam->input;
13820   vl_api_delete_vhost_user_if_t *mp;
13821   u32 sw_if_index = ~0;
13822   u8 sw_if_index_set = 0;
13823   int ret;
13824
13825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13826     {
13827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13828         sw_if_index_set = 1;
13829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13830         sw_if_index_set = 1;
13831       else
13832         break;
13833     }
13834
13835   if (sw_if_index_set == 0)
13836     {
13837       errmsg ("missing sw_if_index or interface name");
13838       return -99;
13839     }
13840
13841
13842   M (DELETE_VHOST_USER_IF, mp);
13843
13844   mp->sw_if_index = ntohl (sw_if_index);
13845
13846   S (mp);
13847   W (ret);
13848   return ret;
13849 }
13850
13851 static void vl_api_sw_interface_vhost_user_details_t_handler
13852   (vl_api_sw_interface_vhost_user_details_t * mp)
13853 {
13854   vat_main_t *vam = &vat_main;
13855
13856   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13857          (char *) mp->interface_name,
13858          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13859          clib_net_to_host_u64 (mp->features), mp->is_server,
13860          ntohl (mp->num_regions), (char *) mp->sock_filename);
13861   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13862 }
13863
13864 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13865   (vl_api_sw_interface_vhost_user_details_t * mp)
13866 {
13867   vat_main_t *vam = &vat_main;
13868   vat_json_node_t *node = NULL;
13869
13870   if (VAT_JSON_ARRAY != vam->json_tree.type)
13871     {
13872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13873       vat_json_init_array (&vam->json_tree);
13874     }
13875   node = vat_json_array_add (&vam->json_tree);
13876
13877   vat_json_init_object (node);
13878   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13879   vat_json_object_add_string_copy (node, "interface_name",
13880                                    mp->interface_name);
13881   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13882                             ntohl (mp->virtio_net_hdr_sz));
13883   vat_json_object_add_uint (node, "features",
13884                             clib_net_to_host_u64 (mp->features));
13885   vat_json_object_add_uint (node, "is_server", mp->is_server);
13886   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13887   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13888   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13889 }
13890
13891 static int
13892 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13893 {
13894   vl_api_sw_interface_vhost_user_dump_t *mp;
13895   vl_api_control_ping_t *mp_ping;
13896   int ret;
13897   print (vam->ofp,
13898          "Interface name            idx hdr_sz features server regions filename");
13899
13900   /* Get list of vhost-user interfaces */
13901   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13902   S (mp);
13903
13904   /* Use a control ping for synchronization */
13905   MPING (CONTROL_PING, mp_ping);
13906   S (mp_ping);
13907
13908   W (ret);
13909   return ret;
13910 }
13911
13912 static int
13913 api_show_version (vat_main_t * vam)
13914 {
13915   vl_api_show_version_t *mp;
13916   int ret;
13917
13918   M (SHOW_VERSION, mp);
13919
13920   S (mp);
13921   W (ret);
13922   return ret;
13923 }
13924
13925
13926 static int
13927 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13928 {
13929   unformat_input_t *line_input = vam->input;
13930   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13931   ip4_address_t local4, remote4;
13932   ip6_address_t local6, remote6;
13933   u8 is_add = 1;
13934   u8 ipv4_set = 0, ipv6_set = 0;
13935   u8 local_set = 0;
13936   u8 remote_set = 0;
13937   u8 grp_set = 0;
13938   u32 mcast_sw_if_index = ~0;
13939   u32 encap_vrf_id = 0;
13940   u32 decap_vrf_id = 0;
13941   u8 protocol = ~0;
13942   u32 vni;
13943   u8 vni_set = 0;
13944   int ret;
13945
13946   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13947   clib_memset (&local4, 0, sizeof local4);
13948   clib_memset (&remote4, 0, sizeof remote4);
13949   clib_memset (&local6, 0, sizeof local6);
13950   clib_memset (&remote6, 0, sizeof remote6);
13951
13952   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13953     {
13954       if (unformat (line_input, "del"))
13955         is_add = 0;
13956       else if (unformat (line_input, "local %U",
13957                          unformat_ip4_address, &local4))
13958         {
13959           local_set = 1;
13960           ipv4_set = 1;
13961         }
13962       else if (unformat (line_input, "remote %U",
13963                          unformat_ip4_address, &remote4))
13964         {
13965           remote_set = 1;
13966           ipv4_set = 1;
13967         }
13968       else if (unformat (line_input, "local %U",
13969                          unformat_ip6_address, &local6))
13970         {
13971           local_set = 1;
13972           ipv6_set = 1;
13973         }
13974       else if (unformat (line_input, "remote %U",
13975                          unformat_ip6_address, &remote6))
13976         {
13977           remote_set = 1;
13978           ipv6_set = 1;
13979         }
13980       else if (unformat (line_input, "group %U %U",
13981                          unformat_ip4_address, &remote4,
13982                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13983         {
13984           grp_set = remote_set = 1;
13985           ipv4_set = 1;
13986         }
13987       else if (unformat (line_input, "group %U",
13988                          unformat_ip4_address, &remote4))
13989         {
13990           grp_set = remote_set = 1;
13991           ipv4_set = 1;
13992         }
13993       else if (unformat (line_input, "group %U %U",
13994                          unformat_ip6_address, &remote6,
13995                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13996         {
13997           grp_set = remote_set = 1;
13998           ipv6_set = 1;
13999         }
14000       else if (unformat (line_input, "group %U",
14001                          unformat_ip6_address, &remote6))
14002         {
14003           grp_set = remote_set = 1;
14004           ipv6_set = 1;
14005         }
14006       else
14007         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14008         ;
14009       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14010         ;
14011       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14012         ;
14013       else if (unformat (line_input, "vni %d", &vni))
14014         vni_set = 1;
14015       else if (unformat (line_input, "next-ip4"))
14016         protocol = 1;
14017       else if (unformat (line_input, "next-ip6"))
14018         protocol = 2;
14019       else if (unformat (line_input, "next-ethernet"))
14020         protocol = 3;
14021       else if (unformat (line_input, "next-nsh"))
14022         protocol = 4;
14023       else
14024         {
14025           errmsg ("parse error '%U'", format_unformat_error, line_input);
14026           return -99;
14027         }
14028     }
14029
14030   if (local_set == 0)
14031     {
14032       errmsg ("tunnel local address not specified");
14033       return -99;
14034     }
14035   if (remote_set == 0)
14036     {
14037       errmsg ("tunnel remote address not specified");
14038       return -99;
14039     }
14040   if (grp_set && mcast_sw_if_index == ~0)
14041     {
14042       errmsg ("tunnel nonexistent multicast device");
14043       return -99;
14044     }
14045   if (ipv4_set && ipv6_set)
14046     {
14047       errmsg ("both IPv4 and IPv6 addresses specified");
14048       return -99;
14049     }
14050
14051   if (vni_set == 0)
14052     {
14053       errmsg ("vni not specified");
14054       return -99;
14055     }
14056
14057   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14058
14059
14060   if (ipv6_set)
14061     {
14062       clib_memcpy (&mp->local, &local6, sizeof (local6));
14063       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14064     }
14065   else
14066     {
14067       clib_memcpy (&mp->local, &local4, sizeof (local4));
14068       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14069     }
14070
14071   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14072   mp->encap_vrf_id = ntohl (encap_vrf_id);
14073   mp->decap_vrf_id = ntohl (decap_vrf_id);
14074   mp->protocol = protocol;
14075   mp->vni = ntohl (vni);
14076   mp->is_add = is_add;
14077   mp->is_ipv6 = ipv6_set;
14078
14079   S (mp);
14080   W (ret);
14081   return ret;
14082 }
14083
14084 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14085   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14086 {
14087   vat_main_t *vam = &vat_main;
14088   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14089   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14090
14091   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14092          ntohl (mp->sw_if_index),
14093          format_ip46_address, &local, IP46_TYPE_ANY,
14094          format_ip46_address, &remote, IP46_TYPE_ANY,
14095          ntohl (mp->vni), mp->protocol,
14096          ntohl (mp->mcast_sw_if_index),
14097          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14098 }
14099
14100
14101 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14102   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14103 {
14104   vat_main_t *vam = &vat_main;
14105   vat_json_node_t *node = NULL;
14106   struct in_addr ip4;
14107   struct in6_addr ip6;
14108
14109   if (VAT_JSON_ARRAY != vam->json_tree.type)
14110     {
14111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14112       vat_json_init_array (&vam->json_tree);
14113     }
14114   node = vat_json_array_add (&vam->json_tree);
14115
14116   vat_json_init_object (node);
14117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14118   if (mp->is_ipv6)
14119     {
14120       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14121       vat_json_object_add_ip6 (node, "local", ip6);
14122       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14123       vat_json_object_add_ip6 (node, "remote", ip6);
14124     }
14125   else
14126     {
14127       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14128       vat_json_object_add_ip4 (node, "local", ip4);
14129       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14130       vat_json_object_add_ip4 (node, "remote", ip4);
14131     }
14132   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14133   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14134   vat_json_object_add_uint (node, "mcast_sw_if_index",
14135                             ntohl (mp->mcast_sw_if_index));
14136   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14137   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14138   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14139 }
14140
14141 static int
14142 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14143 {
14144   unformat_input_t *i = vam->input;
14145   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14146   vl_api_control_ping_t *mp_ping;
14147   u32 sw_if_index;
14148   u8 sw_if_index_set = 0;
14149   int ret;
14150
14151   /* Parse args required to build the message */
14152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14153     {
14154       if (unformat (i, "sw_if_index %d", &sw_if_index))
14155         sw_if_index_set = 1;
14156       else
14157         break;
14158     }
14159
14160   if (sw_if_index_set == 0)
14161     {
14162       sw_if_index = ~0;
14163     }
14164
14165   if (!vam->json_output)
14166     {
14167       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14168              "sw_if_index", "local", "remote", "vni",
14169              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14170     }
14171
14172   /* Get list of vxlan-tunnel interfaces */
14173   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14174
14175   mp->sw_if_index = htonl (sw_if_index);
14176
14177   S (mp);
14178
14179   /* Use a control ping for synchronization */
14180   MPING (CONTROL_PING, mp_ping);
14181   S (mp_ping);
14182
14183   W (ret);
14184   return ret;
14185 }
14186
14187 static void vl_api_l2_fib_table_details_t_handler
14188   (vl_api_l2_fib_table_details_t * mp)
14189 {
14190   vat_main_t *vam = &vat_main;
14191
14192   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14193          "       %d       %d     %d",
14194          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14195          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14196          mp->bvi_mac);
14197 }
14198
14199 static void vl_api_l2_fib_table_details_t_handler_json
14200   (vl_api_l2_fib_table_details_t * mp)
14201 {
14202   vat_main_t *vam = &vat_main;
14203   vat_json_node_t *node = NULL;
14204
14205   if (VAT_JSON_ARRAY != vam->json_tree.type)
14206     {
14207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14208       vat_json_init_array (&vam->json_tree);
14209     }
14210   node = vat_json_array_add (&vam->json_tree);
14211
14212   vat_json_init_object (node);
14213   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14214   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14215   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14216   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14217   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14218   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14219 }
14220
14221 static int
14222 api_l2_fib_table_dump (vat_main_t * vam)
14223 {
14224   unformat_input_t *i = vam->input;
14225   vl_api_l2_fib_table_dump_t *mp;
14226   vl_api_control_ping_t *mp_ping;
14227   u32 bd_id;
14228   u8 bd_id_set = 0;
14229   int ret;
14230
14231   /* Parse args required to build the message */
14232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14233     {
14234       if (unformat (i, "bd_id %d", &bd_id))
14235         bd_id_set = 1;
14236       else
14237         break;
14238     }
14239
14240   if (bd_id_set == 0)
14241     {
14242       errmsg ("missing bridge domain");
14243       return -99;
14244     }
14245
14246   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14247
14248   /* Get list of l2 fib entries */
14249   M (L2_FIB_TABLE_DUMP, mp);
14250
14251   mp->bd_id = ntohl (bd_id);
14252   S (mp);
14253
14254   /* Use a control ping for synchronization */
14255   MPING (CONTROL_PING, mp_ping);
14256   S (mp_ping);
14257
14258   W (ret);
14259   return ret;
14260 }
14261
14262
14263 static int
14264 api_interface_name_renumber (vat_main_t * vam)
14265 {
14266   unformat_input_t *line_input = vam->input;
14267   vl_api_interface_name_renumber_t *mp;
14268   u32 sw_if_index = ~0;
14269   u32 new_show_dev_instance = ~0;
14270   int ret;
14271
14272   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14273     {
14274       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14275                     &sw_if_index))
14276         ;
14277       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14278         ;
14279       else if (unformat (line_input, "new_show_dev_instance %d",
14280                          &new_show_dev_instance))
14281         ;
14282       else
14283         break;
14284     }
14285
14286   if (sw_if_index == ~0)
14287     {
14288       errmsg ("missing interface name or sw_if_index");
14289       return -99;
14290     }
14291
14292   if (new_show_dev_instance == ~0)
14293     {
14294       errmsg ("missing new_show_dev_instance");
14295       return -99;
14296     }
14297
14298   M (INTERFACE_NAME_RENUMBER, mp);
14299
14300   mp->sw_if_index = ntohl (sw_if_index);
14301   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14302
14303   S (mp);
14304   W (ret);
14305   return ret;
14306 }
14307
14308 static int
14309 api_ip_probe_neighbor (vat_main_t * vam)
14310 {
14311   unformat_input_t *i = vam->input;
14312   vl_api_ip_probe_neighbor_t *mp;
14313   u8 int_set = 0;
14314   u8 adr_set = 0;
14315   u8 is_ipv6 = 0;
14316   u8 dst_adr[16];
14317   u32 sw_if_index;
14318   int ret;
14319
14320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14321     {
14322       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14323         int_set = 1;
14324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14325         int_set = 1;
14326       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14327         adr_set = 1;
14328       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14329         {
14330           adr_set = 1;
14331           is_ipv6 = 1;
14332         }
14333       else
14334         break;
14335     }
14336
14337   if (int_set == 0)
14338     {
14339       errmsg ("missing interface");
14340       return -99;
14341     }
14342
14343   if (adr_set == 0)
14344     {
14345       errmsg ("missing addresses");
14346       return -99;
14347     }
14348
14349   M (IP_PROBE_NEIGHBOR, mp);
14350
14351   mp->sw_if_index = ntohl (sw_if_index);
14352   mp->is_ipv6 = is_ipv6;
14353   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14354
14355   S (mp);
14356   W (ret);
14357   return ret;
14358 }
14359
14360 static int
14361 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14362 {
14363   unformat_input_t *i = vam->input;
14364   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14365   u8 mode = IP_SCAN_V46_NEIGHBORS;
14366   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14367   int ret;
14368
14369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14370     {
14371       if (unformat (i, "ip4"))
14372         mode = IP_SCAN_V4_NEIGHBORS;
14373       else if (unformat (i, "ip6"))
14374         mode = IP_SCAN_V6_NEIGHBORS;
14375       if (unformat (i, "both"))
14376         mode = IP_SCAN_V46_NEIGHBORS;
14377       else if (unformat (i, "disable"))
14378         mode = IP_SCAN_DISABLED;
14379       else if (unformat (i, "interval %d", &interval))
14380         ;
14381       else if (unformat (i, "max-time %d", &time))
14382         ;
14383       else if (unformat (i, "max-update %d", &update))
14384         ;
14385       else if (unformat (i, "delay %d", &delay))
14386         ;
14387       else if (unformat (i, "stale %d", &stale))
14388         ;
14389       else
14390         break;
14391     }
14392
14393   if (interval > 255)
14394     {
14395       errmsg ("interval cannot exceed 255 minutes.");
14396       return -99;
14397     }
14398   if (time > 255)
14399     {
14400       errmsg ("max-time cannot exceed 255 usec.");
14401       return -99;
14402     }
14403   if (update > 255)
14404     {
14405       errmsg ("max-update cannot exceed 255.");
14406       return -99;
14407     }
14408   if (delay > 255)
14409     {
14410       errmsg ("delay cannot exceed 255 msec.");
14411       return -99;
14412     }
14413   if (stale > 255)
14414     {
14415       errmsg ("stale cannot exceed 255 minutes.");
14416       return -99;
14417     }
14418
14419   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14420   mp->mode = mode;
14421   mp->scan_interval = interval;
14422   mp->max_proc_time = time;
14423   mp->max_update = update;
14424   mp->scan_int_delay = delay;
14425   mp->stale_threshold = stale;
14426
14427   S (mp);
14428   W (ret);
14429   return ret;
14430 }
14431
14432 static int
14433 api_want_ip4_arp_events (vat_main_t * vam)
14434 {
14435   unformat_input_t *line_input = vam->input;
14436   vl_api_want_ip4_arp_events_t *mp;
14437   ip4_address_t address;
14438   int address_set = 0;
14439   u32 enable_disable = 1;
14440   int ret;
14441
14442   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14443     {
14444       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14445         address_set = 1;
14446       else if (unformat (line_input, "del"))
14447         enable_disable = 0;
14448       else
14449         break;
14450     }
14451
14452   if (address_set == 0)
14453     {
14454       errmsg ("missing addresses");
14455       return -99;
14456     }
14457
14458   M (WANT_IP4_ARP_EVENTS, mp);
14459   mp->enable_disable = enable_disable;
14460   mp->pid = htonl (getpid ());
14461   mp->address = address.as_u32;
14462
14463   S (mp);
14464   W (ret);
14465   return ret;
14466 }
14467
14468 static int
14469 api_want_ip6_nd_events (vat_main_t * vam)
14470 {
14471   unformat_input_t *line_input = vam->input;
14472   vl_api_want_ip6_nd_events_t *mp;
14473   ip6_address_t address;
14474   int address_set = 0;
14475   u32 enable_disable = 1;
14476   int ret;
14477
14478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14479     {
14480       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14481         address_set = 1;
14482       else if (unformat (line_input, "del"))
14483         enable_disable = 0;
14484       else
14485         break;
14486     }
14487
14488   if (address_set == 0)
14489     {
14490       errmsg ("missing addresses");
14491       return -99;
14492     }
14493
14494   M (WANT_IP6_ND_EVENTS, mp);
14495   mp->enable_disable = enable_disable;
14496   mp->pid = htonl (getpid ());
14497   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14498
14499   S (mp);
14500   W (ret);
14501   return ret;
14502 }
14503
14504 static int
14505 api_want_l2_macs_events (vat_main_t * vam)
14506 {
14507   unformat_input_t *line_input = vam->input;
14508   vl_api_want_l2_macs_events_t *mp;
14509   u8 enable_disable = 1;
14510   u32 scan_delay = 0;
14511   u32 max_macs_in_event = 0;
14512   u32 learn_limit = 0;
14513   int ret;
14514
14515   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14516     {
14517       if (unformat (line_input, "learn-limit %d", &learn_limit))
14518         ;
14519       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14520         ;
14521       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14522         ;
14523       else if (unformat (line_input, "disable"))
14524         enable_disable = 0;
14525       else
14526         break;
14527     }
14528
14529   M (WANT_L2_MACS_EVENTS, mp);
14530   mp->enable_disable = enable_disable;
14531   mp->pid = htonl (getpid ());
14532   mp->learn_limit = htonl (learn_limit);
14533   mp->scan_delay = (u8) scan_delay;
14534   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14535   S (mp);
14536   W (ret);
14537   return ret;
14538 }
14539
14540 static int
14541 api_input_acl_set_interface (vat_main_t * vam)
14542 {
14543   unformat_input_t *i = vam->input;
14544   vl_api_input_acl_set_interface_t *mp;
14545   u32 sw_if_index;
14546   int sw_if_index_set;
14547   u32 ip4_table_index = ~0;
14548   u32 ip6_table_index = ~0;
14549   u32 l2_table_index = ~0;
14550   u8 is_add = 1;
14551   int ret;
14552
14553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14554     {
14555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14556         sw_if_index_set = 1;
14557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14558         sw_if_index_set = 1;
14559       else if (unformat (i, "del"))
14560         is_add = 0;
14561       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14562         ;
14563       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14564         ;
14565       else if (unformat (i, "l2-table %d", &l2_table_index))
14566         ;
14567       else
14568         {
14569           clib_warning ("parse error '%U'", format_unformat_error, i);
14570           return -99;
14571         }
14572     }
14573
14574   if (sw_if_index_set == 0)
14575     {
14576       errmsg ("missing interface name or sw_if_index");
14577       return -99;
14578     }
14579
14580   M (INPUT_ACL_SET_INTERFACE, mp);
14581
14582   mp->sw_if_index = ntohl (sw_if_index);
14583   mp->ip4_table_index = ntohl (ip4_table_index);
14584   mp->ip6_table_index = ntohl (ip6_table_index);
14585   mp->l2_table_index = ntohl (l2_table_index);
14586   mp->is_add = is_add;
14587
14588   S (mp);
14589   W (ret);
14590   return ret;
14591 }
14592
14593 static int
14594 api_output_acl_set_interface (vat_main_t * vam)
14595 {
14596   unformat_input_t *i = vam->input;
14597   vl_api_output_acl_set_interface_t *mp;
14598   u32 sw_if_index;
14599   int sw_if_index_set;
14600   u32 ip4_table_index = ~0;
14601   u32 ip6_table_index = ~0;
14602   u32 l2_table_index = ~0;
14603   u8 is_add = 1;
14604   int ret;
14605
14606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14607     {
14608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14609         sw_if_index_set = 1;
14610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14611         sw_if_index_set = 1;
14612       else if (unformat (i, "del"))
14613         is_add = 0;
14614       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14615         ;
14616       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14617         ;
14618       else if (unformat (i, "l2-table %d", &l2_table_index))
14619         ;
14620       else
14621         {
14622           clib_warning ("parse error '%U'", format_unformat_error, i);
14623           return -99;
14624         }
14625     }
14626
14627   if (sw_if_index_set == 0)
14628     {
14629       errmsg ("missing interface name or sw_if_index");
14630       return -99;
14631     }
14632
14633   M (OUTPUT_ACL_SET_INTERFACE, mp);
14634
14635   mp->sw_if_index = ntohl (sw_if_index);
14636   mp->ip4_table_index = ntohl (ip4_table_index);
14637   mp->ip6_table_index = ntohl (ip6_table_index);
14638   mp->l2_table_index = ntohl (l2_table_index);
14639   mp->is_add = is_add;
14640
14641   S (mp);
14642   W (ret);
14643   return ret;
14644 }
14645
14646 static int
14647 api_ip_address_dump (vat_main_t * vam)
14648 {
14649   unformat_input_t *i = vam->input;
14650   vl_api_ip_address_dump_t *mp;
14651   vl_api_control_ping_t *mp_ping;
14652   u32 sw_if_index = ~0;
14653   u8 sw_if_index_set = 0;
14654   u8 ipv4_set = 0;
14655   u8 ipv6_set = 0;
14656   int ret;
14657
14658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14659     {
14660       if (unformat (i, "sw_if_index %d", &sw_if_index))
14661         sw_if_index_set = 1;
14662       else
14663         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14664         sw_if_index_set = 1;
14665       else if (unformat (i, "ipv4"))
14666         ipv4_set = 1;
14667       else if (unformat (i, "ipv6"))
14668         ipv6_set = 1;
14669       else
14670         break;
14671     }
14672
14673   if (ipv4_set && ipv6_set)
14674     {
14675       errmsg ("ipv4 and ipv6 flags cannot be both set");
14676       return -99;
14677     }
14678
14679   if ((!ipv4_set) && (!ipv6_set))
14680     {
14681       errmsg ("no ipv4 nor ipv6 flag set");
14682       return -99;
14683     }
14684
14685   if (sw_if_index_set == 0)
14686     {
14687       errmsg ("missing interface name or sw_if_index");
14688       return -99;
14689     }
14690
14691   vam->current_sw_if_index = sw_if_index;
14692   vam->is_ipv6 = ipv6_set;
14693
14694   M (IP_ADDRESS_DUMP, mp);
14695   mp->sw_if_index = ntohl (sw_if_index);
14696   mp->is_ipv6 = ipv6_set;
14697   S (mp);
14698
14699   /* Use a control ping for synchronization */
14700   MPING (CONTROL_PING, mp_ping);
14701   S (mp_ping);
14702
14703   W (ret);
14704   return ret;
14705 }
14706
14707 static int
14708 api_ip_dump (vat_main_t * vam)
14709 {
14710   vl_api_ip_dump_t *mp;
14711   vl_api_control_ping_t *mp_ping;
14712   unformat_input_t *in = vam->input;
14713   int ipv4_set = 0;
14714   int ipv6_set = 0;
14715   int is_ipv6;
14716   int i;
14717   int ret;
14718
14719   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (unformat (in, "ipv4"))
14722         ipv4_set = 1;
14723       else if (unformat (in, "ipv6"))
14724         ipv6_set = 1;
14725       else
14726         break;
14727     }
14728
14729   if (ipv4_set && ipv6_set)
14730     {
14731       errmsg ("ipv4 and ipv6 flags cannot be both set");
14732       return -99;
14733     }
14734
14735   if ((!ipv4_set) && (!ipv6_set))
14736     {
14737       errmsg ("no ipv4 nor ipv6 flag set");
14738       return -99;
14739     }
14740
14741   is_ipv6 = ipv6_set;
14742   vam->is_ipv6 = is_ipv6;
14743
14744   /* free old data */
14745   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14746     {
14747       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14748     }
14749   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14750
14751   M (IP_DUMP, mp);
14752   mp->is_ipv6 = ipv6_set;
14753   S (mp);
14754
14755   /* Use a control ping for synchronization */
14756   MPING (CONTROL_PING, mp_ping);
14757   S (mp_ping);
14758
14759   W (ret);
14760   return ret;
14761 }
14762
14763 static int
14764 api_ipsec_spd_add_del (vat_main_t * vam)
14765 {
14766   unformat_input_t *i = vam->input;
14767   vl_api_ipsec_spd_add_del_t *mp;
14768   u32 spd_id = ~0;
14769   u8 is_add = 1;
14770   int ret;
14771
14772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14773     {
14774       if (unformat (i, "spd_id %d", &spd_id))
14775         ;
14776       else if (unformat (i, "del"))
14777         is_add = 0;
14778       else
14779         {
14780           clib_warning ("parse error '%U'", format_unformat_error, i);
14781           return -99;
14782         }
14783     }
14784   if (spd_id == ~0)
14785     {
14786       errmsg ("spd_id must be set");
14787       return -99;
14788     }
14789
14790   M (IPSEC_SPD_ADD_DEL, mp);
14791
14792   mp->spd_id = ntohl (spd_id);
14793   mp->is_add = is_add;
14794
14795   S (mp);
14796   W (ret);
14797   return ret;
14798 }
14799
14800 static int
14801 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14802 {
14803   unformat_input_t *i = vam->input;
14804   vl_api_ipsec_interface_add_del_spd_t *mp;
14805   u32 sw_if_index;
14806   u8 sw_if_index_set = 0;
14807   u32 spd_id = (u32) ~ 0;
14808   u8 is_add = 1;
14809   int ret;
14810
14811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14812     {
14813       if (unformat (i, "del"))
14814         is_add = 0;
14815       else if (unformat (i, "spd_id %d", &spd_id))
14816         ;
14817       else
14818         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14819         sw_if_index_set = 1;
14820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14821         sw_if_index_set = 1;
14822       else
14823         {
14824           clib_warning ("parse error '%U'", format_unformat_error, i);
14825           return -99;
14826         }
14827
14828     }
14829
14830   if (spd_id == (u32) ~ 0)
14831     {
14832       errmsg ("spd_id must be set");
14833       return -99;
14834     }
14835
14836   if (sw_if_index_set == 0)
14837     {
14838       errmsg ("missing interface name or sw_if_index");
14839       return -99;
14840     }
14841
14842   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14843
14844   mp->spd_id = ntohl (spd_id);
14845   mp->sw_if_index = ntohl (sw_if_index);
14846   mp->is_add = is_add;
14847
14848   S (mp);
14849   W (ret);
14850   return ret;
14851 }
14852
14853 static int
14854 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14855 {
14856   unformat_input_t *i = vam->input;
14857   vl_api_ipsec_spd_add_del_entry_t *mp;
14858   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14859   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14860   i32 priority = 0;
14861   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14862   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14863   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14864   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14865   int ret;
14866
14867   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14868   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14869   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14870   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14871   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14872   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14873
14874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14875     {
14876       if (unformat (i, "del"))
14877         is_add = 0;
14878       if (unformat (i, "outbound"))
14879         is_outbound = 1;
14880       if (unformat (i, "inbound"))
14881         is_outbound = 0;
14882       else if (unformat (i, "spd_id %d", &spd_id))
14883         ;
14884       else if (unformat (i, "sa_id %d", &sa_id))
14885         ;
14886       else if (unformat (i, "priority %d", &priority))
14887         ;
14888       else if (unformat (i, "protocol %d", &protocol))
14889         ;
14890       else if (unformat (i, "lport_start %d", &lport_start))
14891         ;
14892       else if (unformat (i, "lport_stop %d", &lport_stop))
14893         ;
14894       else if (unformat (i, "rport_start %d", &rport_start))
14895         ;
14896       else if (unformat (i, "rport_stop %d", &rport_stop))
14897         ;
14898       else
14899         if (unformat
14900             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14901         {
14902           is_ipv6 = 0;
14903           is_ip_any = 0;
14904         }
14905       else
14906         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14907         {
14908           is_ipv6 = 0;
14909           is_ip_any = 0;
14910         }
14911       else
14912         if (unformat
14913             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14914         {
14915           is_ipv6 = 0;
14916           is_ip_any = 0;
14917         }
14918       else
14919         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14920         {
14921           is_ipv6 = 0;
14922           is_ip_any = 0;
14923         }
14924       else
14925         if (unformat
14926             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14927         {
14928           is_ipv6 = 1;
14929           is_ip_any = 0;
14930         }
14931       else
14932         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14933         {
14934           is_ipv6 = 1;
14935           is_ip_any = 0;
14936         }
14937       else
14938         if (unformat
14939             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14940         {
14941           is_ipv6 = 1;
14942           is_ip_any = 0;
14943         }
14944       else
14945         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14946         {
14947           is_ipv6 = 1;
14948           is_ip_any = 0;
14949         }
14950       else
14951         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14952         {
14953           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14954             {
14955               clib_warning ("unsupported action: 'resolve'");
14956               return -99;
14957             }
14958         }
14959       else
14960         {
14961           clib_warning ("parse error '%U'", format_unformat_error, i);
14962           return -99;
14963         }
14964
14965     }
14966
14967   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14968
14969   mp->spd_id = ntohl (spd_id);
14970   mp->priority = ntohl (priority);
14971   mp->is_outbound = is_outbound;
14972
14973   mp->is_ipv6 = is_ipv6;
14974   if (is_ipv6 || is_ip_any)
14975     {
14976       clib_memcpy (mp->remote_address_start, &raddr6_start,
14977                    sizeof (ip6_address_t));
14978       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14979                    sizeof (ip6_address_t));
14980       clib_memcpy (mp->local_address_start, &laddr6_start,
14981                    sizeof (ip6_address_t));
14982       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14983                    sizeof (ip6_address_t));
14984     }
14985   else
14986     {
14987       clib_memcpy (mp->remote_address_start, &raddr4_start,
14988                    sizeof (ip4_address_t));
14989       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14990                    sizeof (ip4_address_t));
14991       clib_memcpy (mp->local_address_start, &laddr4_start,
14992                    sizeof (ip4_address_t));
14993       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14994                    sizeof (ip4_address_t));
14995     }
14996   mp->protocol = (u8) protocol;
14997   mp->local_port_start = ntohs ((u16) lport_start);
14998   mp->local_port_stop = ntohs ((u16) lport_stop);
14999   mp->remote_port_start = ntohs ((u16) rport_start);
15000   mp->remote_port_stop = ntohs ((u16) rport_stop);
15001   mp->policy = (u8) policy;
15002   mp->sa_id = ntohl (sa_id);
15003   mp->is_add = is_add;
15004   mp->is_ip_any = is_ip_any;
15005   S (mp);
15006   W (ret);
15007   return ret;
15008 }
15009
15010 static int
15011 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15012 {
15013   unformat_input_t *i = vam->input;
15014   vl_api_ipsec_sad_add_del_entry_t *mp;
15015   u32 sad_id = 0, spi = 0;
15016   u8 *ck = 0, *ik = 0;
15017   u8 is_add = 1;
15018
15019   u8 protocol = IPSEC_PROTOCOL_AH;
15020   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15021   u32 crypto_alg = 0, integ_alg = 0;
15022   ip4_address_t tun_src4;
15023   ip4_address_t tun_dst4;
15024   ip6_address_t tun_src6;
15025   ip6_address_t tun_dst6;
15026   int ret;
15027
15028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15029     {
15030       if (unformat (i, "del"))
15031         is_add = 0;
15032       else if (unformat (i, "sad_id %d", &sad_id))
15033         ;
15034       else if (unformat (i, "spi %d", &spi))
15035         ;
15036       else if (unformat (i, "esp"))
15037         protocol = IPSEC_PROTOCOL_ESP;
15038       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15039         {
15040           is_tunnel = 1;
15041           is_tunnel_ipv6 = 0;
15042         }
15043       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15044         {
15045           is_tunnel = 1;
15046           is_tunnel_ipv6 = 0;
15047         }
15048       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15049         {
15050           is_tunnel = 1;
15051           is_tunnel_ipv6 = 1;
15052         }
15053       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15054         {
15055           is_tunnel = 1;
15056           is_tunnel_ipv6 = 1;
15057         }
15058       else
15059         if (unformat
15060             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15061         {
15062           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15063             {
15064               clib_warning ("unsupported crypto-alg: '%U'",
15065                             format_ipsec_crypto_alg, crypto_alg);
15066               return -99;
15067             }
15068         }
15069       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15070         ;
15071       else
15072         if (unformat
15073             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15074         {
15075           if (integ_alg >= IPSEC_INTEG_N_ALG)
15076             {
15077               clib_warning ("unsupported integ-alg: '%U'",
15078                             format_ipsec_integ_alg, integ_alg);
15079               return -99;
15080             }
15081         }
15082       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15083         ;
15084       else
15085         {
15086           clib_warning ("parse error '%U'", format_unformat_error, i);
15087           return -99;
15088         }
15089
15090     }
15091
15092   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15093
15094   mp->sad_id = ntohl (sad_id);
15095   mp->is_add = is_add;
15096   mp->protocol = protocol;
15097   mp->spi = ntohl (spi);
15098   mp->is_tunnel = is_tunnel;
15099   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15100   mp->crypto_algorithm = crypto_alg;
15101   mp->integrity_algorithm = integ_alg;
15102   mp->crypto_key_length = vec_len (ck);
15103   mp->integrity_key_length = vec_len (ik);
15104
15105   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15106     mp->crypto_key_length = sizeof (mp->crypto_key);
15107
15108   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15109     mp->integrity_key_length = sizeof (mp->integrity_key);
15110
15111   if (ck)
15112     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15113   if (ik)
15114     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15115
15116   if (is_tunnel)
15117     {
15118       if (is_tunnel_ipv6)
15119         {
15120           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15121                        sizeof (ip6_address_t));
15122           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15123                        sizeof (ip6_address_t));
15124         }
15125       else
15126         {
15127           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15128                        sizeof (ip4_address_t));
15129           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15130                        sizeof (ip4_address_t));
15131         }
15132     }
15133
15134   S (mp);
15135   W (ret);
15136   return ret;
15137 }
15138
15139 static int
15140 api_ipsec_sa_set_key (vat_main_t * vam)
15141 {
15142   unformat_input_t *i = vam->input;
15143   vl_api_ipsec_sa_set_key_t *mp;
15144   u32 sa_id;
15145   u8 *ck = 0, *ik = 0;
15146   int ret;
15147
15148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15149     {
15150       if (unformat (i, "sa_id %d", &sa_id))
15151         ;
15152       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15153         ;
15154       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15155         ;
15156       else
15157         {
15158           clib_warning ("parse error '%U'", format_unformat_error, i);
15159           return -99;
15160         }
15161     }
15162
15163   M (IPSEC_SA_SET_KEY, mp);
15164
15165   mp->sa_id = ntohl (sa_id);
15166   mp->crypto_key_length = vec_len (ck);
15167   mp->integrity_key_length = vec_len (ik);
15168
15169   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15170     mp->crypto_key_length = sizeof (mp->crypto_key);
15171
15172   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15173     mp->integrity_key_length = sizeof (mp->integrity_key);
15174
15175   if (ck)
15176     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15177   if (ik)
15178     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15179
15180   S (mp);
15181   W (ret);
15182   return ret;
15183 }
15184
15185 static int
15186 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15187 {
15188   unformat_input_t *i = vam->input;
15189   vl_api_ipsec_tunnel_if_add_del_t *mp;
15190   u32 local_spi = 0, remote_spi = 0;
15191   u32 crypto_alg = 0, integ_alg = 0;
15192   u8 *lck = NULL, *rck = NULL;
15193   u8 *lik = NULL, *rik = NULL;
15194   ip4_address_t local_ip = { {0} };
15195   ip4_address_t remote_ip = { {0} };
15196   u8 is_add = 1;
15197   u8 esn = 0;
15198   u8 anti_replay = 0;
15199   u8 renumber = 0;
15200   u32 instance = ~0;
15201   int ret;
15202
15203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15204     {
15205       if (unformat (i, "del"))
15206         is_add = 0;
15207       else if (unformat (i, "esn"))
15208         esn = 1;
15209       else if (unformat (i, "anti_replay"))
15210         anti_replay = 1;
15211       else if (unformat (i, "local_spi %d", &local_spi))
15212         ;
15213       else if (unformat (i, "remote_spi %d", &remote_spi))
15214         ;
15215       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15216         ;
15217       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15218         ;
15219       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15220         ;
15221       else
15222         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15223         ;
15224       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15225         ;
15226       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15227         ;
15228       else
15229         if (unformat
15230             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15231         {
15232           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15233             {
15234               errmsg ("unsupported crypto-alg: '%U'\n",
15235                       format_ipsec_crypto_alg, crypto_alg);
15236               return -99;
15237             }
15238         }
15239       else
15240         if (unformat
15241             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15242         {
15243           if (integ_alg >= IPSEC_INTEG_N_ALG)
15244             {
15245               errmsg ("unsupported integ-alg: '%U'\n",
15246                       format_ipsec_integ_alg, integ_alg);
15247               return -99;
15248             }
15249         }
15250       else if (unformat (i, "instance %u", &instance))
15251         renumber = 1;
15252       else
15253         {
15254           errmsg ("parse error '%U'\n", format_unformat_error, i);
15255           return -99;
15256         }
15257     }
15258
15259   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15260
15261   mp->is_add = is_add;
15262   mp->esn = esn;
15263   mp->anti_replay = anti_replay;
15264
15265   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15266   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15267
15268   mp->local_spi = htonl (local_spi);
15269   mp->remote_spi = htonl (remote_spi);
15270   mp->crypto_alg = (u8) crypto_alg;
15271
15272   mp->local_crypto_key_len = 0;
15273   if (lck)
15274     {
15275       mp->local_crypto_key_len = vec_len (lck);
15276       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15277         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15278       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15279     }
15280
15281   mp->remote_crypto_key_len = 0;
15282   if (rck)
15283     {
15284       mp->remote_crypto_key_len = vec_len (rck);
15285       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15286         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15287       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15288     }
15289
15290   mp->integ_alg = (u8) integ_alg;
15291
15292   mp->local_integ_key_len = 0;
15293   if (lik)
15294     {
15295       mp->local_integ_key_len = vec_len (lik);
15296       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15297         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15298       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15299     }
15300
15301   mp->remote_integ_key_len = 0;
15302   if (rik)
15303     {
15304       mp->remote_integ_key_len = vec_len (rik);
15305       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15306         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15307       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15308     }
15309
15310   if (renumber)
15311     {
15312       mp->renumber = renumber;
15313       mp->show_instance = ntohl (instance);
15314     }
15315
15316   S (mp);
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static void
15322 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15323 {
15324   vat_main_t *vam = &vat_main;
15325
15326   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15327          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15328          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15329          "tunnel_src_addr %U tunnel_dst_addr %U "
15330          "salt %u seq_outbound %lu last_seq_inbound %lu "
15331          "replay_window %lu total_data_size %lu\n",
15332          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15333          mp->protocol,
15334          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15335          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15336          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15337          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15338          mp->tunnel_src_addr,
15339          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15340          mp->tunnel_dst_addr,
15341          ntohl (mp->salt),
15342          clib_net_to_host_u64 (mp->seq_outbound),
15343          clib_net_to_host_u64 (mp->last_seq_inbound),
15344          clib_net_to_host_u64 (mp->replay_window),
15345          clib_net_to_host_u64 (mp->total_data_size));
15346 }
15347
15348 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15349 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15350
15351 static void vl_api_ipsec_sa_details_t_handler_json
15352   (vl_api_ipsec_sa_details_t * mp)
15353 {
15354   vat_main_t *vam = &vat_main;
15355   vat_json_node_t *node = NULL;
15356   struct in_addr src_ip4, dst_ip4;
15357   struct in6_addr src_ip6, dst_ip6;
15358
15359   if (VAT_JSON_ARRAY != vam->json_tree.type)
15360     {
15361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15362       vat_json_init_array (&vam->json_tree);
15363     }
15364   node = vat_json_array_add (&vam->json_tree);
15365
15366   vat_json_init_object (node);
15367   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15368   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15369   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15370   vat_json_object_add_uint (node, "proto", mp->protocol);
15371   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15372   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15373   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15374   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15375   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15376   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15377   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15378                              mp->crypto_key_len);
15379   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15380                              mp->integ_key_len);
15381   if (mp->is_tunnel_ip6)
15382     {
15383       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15384       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15385       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15386       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15387     }
15388   else
15389     {
15390       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15391       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15392       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15393       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15394     }
15395   vat_json_object_add_uint (node, "replay_window",
15396                             clib_net_to_host_u64 (mp->replay_window));
15397   vat_json_object_add_uint (node, "total_data_size",
15398                             clib_net_to_host_u64 (mp->total_data_size));
15399
15400 }
15401
15402 static int
15403 api_ipsec_sa_dump (vat_main_t * vam)
15404 {
15405   unformat_input_t *i = vam->input;
15406   vl_api_ipsec_sa_dump_t *mp;
15407   vl_api_control_ping_t *mp_ping;
15408   u32 sa_id = ~0;
15409   int ret;
15410
15411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15412     {
15413       if (unformat (i, "sa_id %d", &sa_id))
15414         ;
15415       else
15416         {
15417           clib_warning ("parse error '%U'", format_unformat_error, i);
15418           return -99;
15419         }
15420     }
15421
15422   M (IPSEC_SA_DUMP, mp);
15423
15424   mp->sa_id = ntohl (sa_id);
15425
15426   S (mp);
15427
15428   /* Use a control ping for synchronization */
15429   M (CONTROL_PING, mp_ping);
15430   S (mp_ping);
15431
15432   W (ret);
15433   return ret;
15434 }
15435
15436 static int
15437 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15438 {
15439   unformat_input_t *i = vam->input;
15440   vl_api_ipsec_tunnel_if_set_key_t *mp;
15441   u32 sw_if_index = ~0;
15442   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15443   u8 *key = 0;
15444   u32 alg = ~0;
15445   int ret;
15446
15447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15448     {
15449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15450         ;
15451       else
15452         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15453         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15454       else
15455         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15456         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15457       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15458         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15459       else
15460         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15461         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15462       else if (unformat (i, "%U", unformat_hex_string, &key))
15463         ;
15464       else
15465         {
15466           clib_warning ("parse error '%U'", format_unformat_error, i);
15467           return -99;
15468         }
15469     }
15470
15471   if (sw_if_index == ~0)
15472     {
15473       errmsg ("interface must be specified");
15474       return -99;
15475     }
15476
15477   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15478     {
15479       errmsg ("key type must be specified");
15480       return -99;
15481     }
15482
15483   if (alg == ~0)
15484     {
15485       errmsg ("algorithm must be specified");
15486       return -99;
15487     }
15488
15489   if (vec_len (key) == 0)
15490     {
15491       errmsg ("key must be specified");
15492       return -99;
15493     }
15494
15495   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15496
15497   mp->sw_if_index = htonl (sw_if_index);
15498   mp->alg = alg;
15499   mp->key_type = key_type;
15500   mp->key_len = vec_len (key);
15501   clib_memcpy (mp->key, key, vec_len (key));
15502
15503   S (mp);
15504   W (ret);
15505
15506   return ret;
15507 }
15508
15509 static int
15510 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15511 {
15512   unformat_input_t *i = vam->input;
15513   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15514   u32 sw_if_index = ~0;
15515   u32 sa_id = ~0;
15516   u8 is_outbound = (u8) ~ 0;
15517   int ret;
15518
15519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15520     {
15521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15522         ;
15523       else if (unformat (i, "sa_id %d", &sa_id))
15524         ;
15525       else if (unformat (i, "outbound"))
15526         is_outbound = 1;
15527       else if (unformat (i, "inbound"))
15528         is_outbound = 0;
15529       else
15530         {
15531           clib_warning ("parse error '%U'", format_unformat_error, i);
15532           return -99;
15533         }
15534     }
15535
15536   if (sw_if_index == ~0)
15537     {
15538       errmsg ("interface must be specified");
15539       return -99;
15540     }
15541
15542   if (sa_id == ~0)
15543     {
15544       errmsg ("SA ID must be specified");
15545       return -99;
15546     }
15547
15548   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15549
15550   mp->sw_if_index = htonl (sw_if_index);
15551   mp->sa_id = htonl (sa_id);
15552   mp->is_outbound = is_outbound;
15553
15554   S (mp);
15555   W (ret);
15556
15557   return ret;
15558 }
15559
15560 static int
15561 api_ikev2_profile_add_del (vat_main_t * vam)
15562 {
15563   unformat_input_t *i = vam->input;
15564   vl_api_ikev2_profile_add_del_t *mp;
15565   u8 is_add = 1;
15566   u8 *name = 0;
15567   int ret;
15568
15569   const char *valid_chars = "a-zA-Z0-9_";
15570
15571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15572     {
15573       if (unformat (i, "del"))
15574         is_add = 0;
15575       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15576         vec_add1 (name, 0);
15577       else
15578         {
15579           errmsg ("parse error '%U'", format_unformat_error, i);
15580           return -99;
15581         }
15582     }
15583
15584   if (!vec_len (name))
15585     {
15586       errmsg ("profile name must be specified");
15587       return -99;
15588     }
15589
15590   if (vec_len (name) > 64)
15591     {
15592       errmsg ("profile name too long");
15593       return -99;
15594     }
15595
15596   M (IKEV2_PROFILE_ADD_DEL, mp);
15597
15598   clib_memcpy (mp->name, name, vec_len (name));
15599   mp->is_add = is_add;
15600   vec_free (name);
15601
15602   S (mp);
15603   W (ret);
15604   return ret;
15605 }
15606
15607 static int
15608 api_ikev2_profile_set_auth (vat_main_t * vam)
15609 {
15610   unformat_input_t *i = vam->input;
15611   vl_api_ikev2_profile_set_auth_t *mp;
15612   u8 *name = 0;
15613   u8 *data = 0;
15614   u32 auth_method = 0;
15615   u8 is_hex = 0;
15616   int ret;
15617
15618   const char *valid_chars = "a-zA-Z0-9_";
15619
15620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15621     {
15622       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15623         vec_add1 (name, 0);
15624       else if (unformat (i, "auth_method %U",
15625                          unformat_ikev2_auth_method, &auth_method))
15626         ;
15627       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15628         is_hex = 1;
15629       else if (unformat (i, "auth_data %v", &data))
15630         ;
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   if (!vec_len (data))
15651     {
15652       errmsg ("auth_data must be specified");
15653       return -99;
15654     }
15655
15656   if (!auth_method)
15657     {
15658       errmsg ("auth_method must be specified");
15659       return -99;
15660     }
15661
15662   M (IKEV2_PROFILE_SET_AUTH, mp);
15663
15664   mp->is_hex = is_hex;
15665   mp->auth_method = (u8) auth_method;
15666   mp->data_len = vec_len (data);
15667   clib_memcpy (mp->name, name, vec_len (name));
15668   clib_memcpy (mp->data, data, vec_len (data));
15669   vec_free (name);
15670   vec_free (data);
15671
15672   S (mp);
15673   W (ret);
15674   return ret;
15675 }
15676
15677 static int
15678 api_ikev2_profile_set_id (vat_main_t * vam)
15679 {
15680   unformat_input_t *i = vam->input;
15681   vl_api_ikev2_profile_set_id_t *mp;
15682   u8 *name = 0;
15683   u8 *data = 0;
15684   u8 is_local = 0;
15685   u32 id_type = 0;
15686   ip4_address_t ip4;
15687   int ret;
15688
15689   const char *valid_chars = "a-zA-Z0-9_";
15690
15691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15692     {
15693       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15694         vec_add1 (name, 0);
15695       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15696         ;
15697       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15698         {
15699           data = vec_new (u8, 4);
15700           clib_memcpy (data, ip4.as_u8, 4);
15701         }
15702       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15703         ;
15704       else if (unformat (i, "id_data %v", &data))
15705         ;
15706       else if (unformat (i, "local"))
15707         is_local = 1;
15708       else if (unformat (i, "remote"))
15709         is_local = 0;
15710       else
15711         {
15712           errmsg ("parse error '%U'", format_unformat_error, i);
15713           return -99;
15714         }
15715     }
15716
15717   if (!vec_len (name))
15718     {
15719       errmsg ("profile name must be specified");
15720       return -99;
15721     }
15722
15723   if (vec_len (name) > 64)
15724     {
15725       errmsg ("profile name too long");
15726       return -99;
15727     }
15728
15729   if (!vec_len (data))
15730     {
15731       errmsg ("id_data must be specified");
15732       return -99;
15733     }
15734
15735   if (!id_type)
15736     {
15737       errmsg ("id_type must be specified");
15738       return -99;
15739     }
15740
15741   M (IKEV2_PROFILE_SET_ID, mp);
15742
15743   mp->is_local = is_local;
15744   mp->id_type = (u8) id_type;
15745   mp->data_len = vec_len (data);
15746   clib_memcpy (mp->name, name, vec_len (name));
15747   clib_memcpy (mp->data, data, vec_len (data));
15748   vec_free (name);
15749   vec_free (data);
15750
15751   S (mp);
15752   W (ret);
15753   return ret;
15754 }
15755
15756 static int
15757 api_ikev2_profile_set_ts (vat_main_t * vam)
15758 {
15759   unformat_input_t *i = vam->input;
15760   vl_api_ikev2_profile_set_ts_t *mp;
15761   u8 *name = 0;
15762   u8 is_local = 0;
15763   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15764   ip4_address_t start_addr, end_addr;
15765
15766   const char *valid_chars = "a-zA-Z0-9_";
15767   int ret;
15768
15769   start_addr.as_u32 = 0;
15770   end_addr.as_u32 = (u32) ~ 0;
15771
15772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15773     {
15774       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15775         vec_add1 (name, 0);
15776       else if (unformat (i, "protocol %d", &proto))
15777         ;
15778       else if (unformat (i, "start_port %d", &start_port))
15779         ;
15780       else if (unformat (i, "end_port %d", &end_port))
15781         ;
15782       else
15783         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15784         ;
15785       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15786         ;
15787       else if (unformat (i, "local"))
15788         is_local = 1;
15789       else if (unformat (i, "remote"))
15790         is_local = 0;
15791       else
15792         {
15793           errmsg ("parse error '%U'", format_unformat_error, i);
15794           return -99;
15795         }
15796     }
15797
15798   if (!vec_len (name))
15799     {
15800       errmsg ("profile name must be specified");
15801       return -99;
15802     }
15803
15804   if (vec_len (name) > 64)
15805     {
15806       errmsg ("profile name too long");
15807       return -99;
15808     }
15809
15810   M (IKEV2_PROFILE_SET_TS, mp);
15811
15812   mp->is_local = is_local;
15813   mp->proto = (u8) proto;
15814   mp->start_port = (u16) start_port;
15815   mp->end_port = (u16) end_port;
15816   mp->start_addr = start_addr.as_u32;
15817   mp->end_addr = end_addr.as_u32;
15818   clib_memcpy (mp->name, name, vec_len (name));
15819   vec_free (name);
15820
15821   S (mp);
15822   W (ret);
15823   return ret;
15824 }
15825
15826 static int
15827 api_ikev2_set_local_key (vat_main_t * vam)
15828 {
15829   unformat_input_t *i = vam->input;
15830   vl_api_ikev2_set_local_key_t *mp;
15831   u8 *file = 0;
15832   int ret;
15833
15834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15835     {
15836       if (unformat (i, "file %v", &file))
15837         vec_add1 (file, 0);
15838       else
15839         {
15840           errmsg ("parse error '%U'", format_unformat_error, i);
15841           return -99;
15842         }
15843     }
15844
15845   if (!vec_len (file))
15846     {
15847       errmsg ("RSA key file must be specified");
15848       return -99;
15849     }
15850
15851   if (vec_len (file) > 256)
15852     {
15853       errmsg ("file name too long");
15854       return -99;
15855     }
15856
15857   M (IKEV2_SET_LOCAL_KEY, mp);
15858
15859   clib_memcpy (mp->key_file, file, vec_len (file));
15860   vec_free (file);
15861
15862   S (mp);
15863   W (ret);
15864   return ret;
15865 }
15866
15867 static int
15868 api_ikev2_set_responder (vat_main_t * vam)
15869 {
15870   unformat_input_t *i = vam->input;
15871   vl_api_ikev2_set_responder_t *mp;
15872   int ret;
15873   u8 *name = 0;
15874   u32 sw_if_index = ~0;
15875   ip4_address_t address;
15876
15877   const char *valid_chars = "a-zA-Z0-9_";
15878
15879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15880     {
15881       if (unformat
15882           (i, "%U interface %d address %U", unformat_token, valid_chars,
15883            &name, &sw_if_index, unformat_ip4_address, &address))
15884         vec_add1 (name, 0);
15885       else
15886         {
15887           errmsg ("parse error '%U'", format_unformat_error, i);
15888           return -99;
15889         }
15890     }
15891
15892   if (!vec_len (name))
15893     {
15894       errmsg ("profile name must be specified");
15895       return -99;
15896     }
15897
15898   if (vec_len (name) > 64)
15899     {
15900       errmsg ("profile name too long");
15901       return -99;
15902     }
15903
15904   M (IKEV2_SET_RESPONDER, mp);
15905
15906   clib_memcpy (mp->name, name, vec_len (name));
15907   vec_free (name);
15908
15909   mp->sw_if_index = sw_if_index;
15910   clib_memcpy (mp->address, &address, sizeof (address));
15911
15912   S (mp);
15913   W (ret);
15914   return ret;
15915 }
15916
15917 static int
15918 api_ikev2_set_ike_transforms (vat_main_t * vam)
15919 {
15920   unformat_input_t *i = vam->input;
15921   vl_api_ikev2_set_ike_transforms_t *mp;
15922   int ret;
15923   u8 *name = 0;
15924   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15925
15926   const char *valid_chars = "a-zA-Z0-9_";
15927
15928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15929     {
15930       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15931                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15932         vec_add1 (name, 0);
15933       else
15934         {
15935           errmsg ("parse error '%U'", format_unformat_error, i);
15936           return -99;
15937         }
15938     }
15939
15940   if (!vec_len (name))
15941     {
15942       errmsg ("profile name must be specified");
15943       return -99;
15944     }
15945
15946   if (vec_len (name) > 64)
15947     {
15948       errmsg ("profile name too long");
15949       return -99;
15950     }
15951
15952   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15953
15954   clib_memcpy (mp->name, name, vec_len (name));
15955   vec_free (name);
15956   mp->crypto_alg = crypto_alg;
15957   mp->crypto_key_size = crypto_key_size;
15958   mp->integ_alg = integ_alg;
15959   mp->dh_group = dh_group;
15960
15961   S (mp);
15962   W (ret);
15963   return ret;
15964 }
15965
15966
15967 static int
15968 api_ikev2_set_esp_transforms (vat_main_t * vam)
15969 {
15970   unformat_input_t *i = vam->input;
15971   vl_api_ikev2_set_esp_transforms_t *mp;
15972   int ret;
15973   u8 *name = 0;
15974   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15975
15976   const char *valid_chars = "a-zA-Z0-9_";
15977
15978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15981                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15982         vec_add1 (name, 0);
15983       else
15984         {
15985           errmsg ("parse error '%U'", format_unformat_error, i);
15986           return -99;
15987         }
15988     }
15989
15990   if (!vec_len (name))
15991     {
15992       errmsg ("profile name must be specified");
15993       return -99;
15994     }
15995
15996   if (vec_len (name) > 64)
15997     {
15998       errmsg ("profile name too long");
15999       return -99;
16000     }
16001
16002   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16003
16004   clib_memcpy (mp->name, name, vec_len (name));
16005   vec_free (name);
16006   mp->crypto_alg = crypto_alg;
16007   mp->crypto_key_size = crypto_key_size;
16008   mp->integ_alg = integ_alg;
16009   mp->dh_group = dh_group;
16010
16011   S (mp);
16012   W (ret);
16013   return ret;
16014 }
16015
16016 static int
16017 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16018 {
16019   unformat_input_t *i = vam->input;
16020   vl_api_ikev2_set_sa_lifetime_t *mp;
16021   int ret;
16022   u8 *name = 0;
16023   u64 lifetime, lifetime_maxdata;
16024   u32 lifetime_jitter, handover;
16025
16026   const char *valid_chars = "a-zA-Z0-9_";
16027
16028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16029     {
16030       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16031                     &lifetime, &lifetime_jitter, &handover,
16032                     &lifetime_maxdata))
16033         vec_add1 (name, 0);
16034       else
16035         {
16036           errmsg ("parse error '%U'", format_unformat_error, i);
16037           return -99;
16038         }
16039     }
16040
16041   if (!vec_len (name))
16042     {
16043       errmsg ("profile name must be specified");
16044       return -99;
16045     }
16046
16047   if (vec_len (name) > 64)
16048     {
16049       errmsg ("profile name too long");
16050       return -99;
16051     }
16052
16053   M (IKEV2_SET_SA_LIFETIME, mp);
16054
16055   clib_memcpy (mp->name, name, vec_len (name));
16056   vec_free (name);
16057   mp->lifetime = lifetime;
16058   mp->lifetime_jitter = lifetime_jitter;
16059   mp->handover = handover;
16060   mp->lifetime_maxdata = lifetime_maxdata;
16061
16062   S (mp);
16063   W (ret);
16064   return ret;
16065 }
16066
16067 static int
16068 api_ikev2_initiate_sa_init (vat_main_t * vam)
16069 {
16070   unformat_input_t *i = vam->input;
16071   vl_api_ikev2_initiate_sa_init_t *mp;
16072   int ret;
16073   u8 *name = 0;
16074
16075   const char *valid_chars = "a-zA-Z0-9_";
16076
16077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16078     {
16079       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16080         vec_add1 (name, 0);
16081       else
16082         {
16083           errmsg ("parse error '%U'", format_unformat_error, i);
16084           return -99;
16085         }
16086     }
16087
16088   if (!vec_len (name))
16089     {
16090       errmsg ("profile name must be specified");
16091       return -99;
16092     }
16093
16094   if (vec_len (name) > 64)
16095     {
16096       errmsg ("profile name too long");
16097       return -99;
16098     }
16099
16100   M (IKEV2_INITIATE_SA_INIT, mp);
16101
16102   clib_memcpy (mp->name, name, vec_len (name));
16103   vec_free (name);
16104
16105   S (mp);
16106   W (ret);
16107   return ret;
16108 }
16109
16110 static int
16111 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16112 {
16113   unformat_input_t *i = vam->input;
16114   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16115   int ret;
16116   u64 ispi;
16117
16118
16119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16120     {
16121       if (unformat (i, "%lx", &ispi))
16122         ;
16123       else
16124         {
16125           errmsg ("parse error '%U'", format_unformat_error, i);
16126           return -99;
16127         }
16128     }
16129
16130   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16131
16132   mp->ispi = ispi;
16133
16134   S (mp);
16135   W (ret);
16136   return ret;
16137 }
16138
16139 static int
16140 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16141 {
16142   unformat_input_t *i = vam->input;
16143   vl_api_ikev2_initiate_del_child_sa_t *mp;
16144   int ret;
16145   u32 ispi;
16146
16147
16148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (i, "%x", &ispi))
16151         ;
16152       else
16153         {
16154           errmsg ("parse error '%U'", format_unformat_error, i);
16155           return -99;
16156         }
16157     }
16158
16159   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16160
16161   mp->ispi = ispi;
16162
16163   S (mp);
16164   W (ret);
16165   return ret;
16166 }
16167
16168 static int
16169 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16170 {
16171   unformat_input_t *i = vam->input;
16172   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16173   int ret;
16174   u32 ispi;
16175
16176
16177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16178     {
16179       if (unformat (i, "%x", &ispi))
16180         ;
16181       else
16182         {
16183           errmsg ("parse error '%U'", format_unformat_error, i);
16184           return -99;
16185         }
16186     }
16187
16188   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16189
16190   mp->ispi = ispi;
16191
16192   S (mp);
16193   W (ret);
16194   return ret;
16195 }
16196
16197 static int
16198 api_get_first_msg_id (vat_main_t * vam)
16199 {
16200   vl_api_get_first_msg_id_t *mp;
16201   unformat_input_t *i = vam->input;
16202   u8 *name;
16203   u8 name_set = 0;
16204   int ret;
16205
16206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16207     {
16208       if (unformat (i, "client %s", &name))
16209         name_set = 1;
16210       else
16211         break;
16212     }
16213
16214   if (name_set == 0)
16215     {
16216       errmsg ("missing client name");
16217       return -99;
16218     }
16219   vec_add1 (name, 0);
16220
16221   if (vec_len (name) > 63)
16222     {
16223       errmsg ("client name too long");
16224       return -99;
16225     }
16226
16227   M (GET_FIRST_MSG_ID, mp);
16228   clib_memcpy (mp->name, name, vec_len (name));
16229   S (mp);
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_cop_interface_enable_disable (vat_main_t * vam)
16236 {
16237   unformat_input_t *line_input = vam->input;
16238   vl_api_cop_interface_enable_disable_t *mp;
16239   u32 sw_if_index = ~0;
16240   u8 enable_disable = 1;
16241   int ret;
16242
16243   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16244     {
16245       if (unformat (line_input, "disable"))
16246         enable_disable = 0;
16247       if (unformat (line_input, "enable"))
16248         enable_disable = 1;
16249       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16250                          vam, &sw_if_index))
16251         ;
16252       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16253         ;
16254       else
16255         break;
16256     }
16257
16258   if (sw_if_index == ~0)
16259     {
16260       errmsg ("missing interface name or sw_if_index");
16261       return -99;
16262     }
16263
16264   /* Construct the API message */
16265   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16266   mp->sw_if_index = ntohl (sw_if_index);
16267   mp->enable_disable = enable_disable;
16268
16269   /* send it... */
16270   S (mp);
16271   /* Wait for the reply */
16272   W (ret);
16273   return ret;
16274 }
16275
16276 static int
16277 api_cop_whitelist_enable_disable (vat_main_t * vam)
16278 {
16279   unformat_input_t *line_input = vam->input;
16280   vl_api_cop_whitelist_enable_disable_t *mp;
16281   u32 sw_if_index = ~0;
16282   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16283   u32 fib_id = 0;
16284   int ret;
16285
16286   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16287     {
16288       if (unformat (line_input, "ip4"))
16289         ip4 = 1;
16290       else if (unformat (line_input, "ip6"))
16291         ip6 = 1;
16292       else if (unformat (line_input, "default"))
16293         default_cop = 1;
16294       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16295                          vam, &sw_if_index))
16296         ;
16297       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16298         ;
16299       else if (unformat (line_input, "fib-id %d", &fib_id))
16300         ;
16301       else
16302         break;
16303     }
16304
16305   if (sw_if_index == ~0)
16306     {
16307       errmsg ("missing interface name or sw_if_index");
16308       return -99;
16309     }
16310
16311   /* Construct the API message */
16312   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16313   mp->sw_if_index = ntohl (sw_if_index);
16314   mp->fib_id = ntohl (fib_id);
16315   mp->ip4 = ip4;
16316   mp->ip6 = ip6;
16317   mp->default_cop = default_cop;
16318
16319   /* send it... */
16320   S (mp);
16321   /* Wait for the reply */
16322   W (ret);
16323   return ret;
16324 }
16325
16326 static int
16327 api_get_node_graph (vat_main_t * vam)
16328 {
16329   vl_api_get_node_graph_t *mp;
16330   int ret;
16331
16332   M (GET_NODE_GRAPH, mp);
16333
16334   /* send it... */
16335   S (mp);
16336   /* Wait for the reply */
16337   W (ret);
16338   return ret;
16339 }
16340
16341 /* *INDENT-OFF* */
16342 /** Used for parsing LISP eids */
16343 typedef CLIB_PACKED(struct{
16344   u8 addr[16];   /**< eid address */
16345   u32 len;       /**< prefix length if IP */
16346   u8 type;      /**< type of eid */
16347 }) lisp_eid_vat_t;
16348 /* *INDENT-ON* */
16349
16350 static uword
16351 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16352 {
16353   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16354
16355   clib_memset (a, 0, sizeof (a[0]));
16356
16357   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16358     {
16359       a->type = 0;              /* ipv4 type */
16360     }
16361   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16362     {
16363       a->type = 1;              /* ipv6 type */
16364     }
16365   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16366     {
16367       a->type = 2;              /* mac type */
16368     }
16369   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16370     {
16371       a->type = 3;              /* NSH type */
16372       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16373       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16374     }
16375   else
16376     {
16377       return 0;
16378     }
16379
16380   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16381     {
16382       return 0;
16383     }
16384
16385   return 1;
16386 }
16387
16388 static int
16389 lisp_eid_size_vat (u8 type)
16390 {
16391   switch (type)
16392     {
16393     case 0:
16394       return 4;
16395     case 1:
16396       return 16;
16397     case 2:
16398       return 6;
16399     case 3:
16400       return 5;
16401     }
16402   return 0;
16403 }
16404
16405 static void
16406 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16407 {
16408   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16409 }
16410
16411 static int
16412 api_one_add_del_locator_set (vat_main_t * vam)
16413 {
16414   unformat_input_t *input = vam->input;
16415   vl_api_one_add_del_locator_set_t *mp;
16416   u8 is_add = 1;
16417   u8 *locator_set_name = NULL;
16418   u8 locator_set_name_set = 0;
16419   vl_api_local_locator_t locator, *locators = 0;
16420   u32 sw_if_index, priority, weight;
16421   u32 data_len = 0;
16422
16423   int ret;
16424   /* Parse args required to build the message */
16425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16426     {
16427       if (unformat (input, "del"))
16428         {
16429           is_add = 0;
16430         }
16431       else if (unformat (input, "locator-set %s", &locator_set_name))
16432         {
16433           locator_set_name_set = 1;
16434         }
16435       else if (unformat (input, "sw_if_index %u p %u w %u",
16436                          &sw_if_index, &priority, &weight))
16437         {
16438           locator.sw_if_index = htonl (sw_if_index);
16439           locator.priority = priority;
16440           locator.weight = weight;
16441           vec_add1 (locators, locator);
16442         }
16443       else
16444         if (unformat
16445             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16446              &sw_if_index, &priority, &weight))
16447         {
16448           locator.sw_if_index = htonl (sw_if_index);
16449           locator.priority = priority;
16450           locator.weight = weight;
16451           vec_add1 (locators, locator);
16452         }
16453       else
16454         break;
16455     }
16456
16457   if (locator_set_name_set == 0)
16458     {
16459       errmsg ("missing locator-set name");
16460       vec_free (locators);
16461       return -99;
16462     }
16463
16464   if (vec_len (locator_set_name) > 64)
16465     {
16466       errmsg ("locator-set name too long");
16467       vec_free (locator_set_name);
16468       vec_free (locators);
16469       return -99;
16470     }
16471   vec_add1 (locator_set_name, 0);
16472
16473   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16474
16475   /* Construct the API message */
16476   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16477
16478   mp->is_add = is_add;
16479   clib_memcpy (mp->locator_set_name, locator_set_name,
16480                vec_len (locator_set_name));
16481   vec_free (locator_set_name);
16482
16483   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16484   if (locators)
16485     clib_memcpy (mp->locators, locators, data_len);
16486   vec_free (locators);
16487
16488   /* send it... */
16489   S (mp);
16490
16491   /* Wait for a reply... */
16492   W (ret);
16493   return ret;
16494 }
16495
16496 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16497
16498 static int
16499 api_one_add_del_locator (vat_main_t * vam)
16500 {
16501   unformat_input_t *input = vam->input;
16502   vl_api_one_add_del_locator_t *mp;
16503   u32 tmp_if_index = ~0;
16504   u32 sw_if_index = ~0;
16505   u8 sw_if_index_set = 0;
16506   u8 sw_if_index_if_name_set = 0;
16507   u32 priority = ~0;
16508   u8 priority_set = 0;
16509   u32 weight = ~0;
16510   u8 weight_set = 0;
16511   u8 is_add = 1;
16512   u8 *locator_set_name = NULL;
16513   u8 locator_set_name_set = 0;
16514   int ret;
16515
16516   /* Parse args required to build the message */
16517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (input, "del"))
16520         {
16521           is_add = 0;
16522         }
16523       else if (unformat (input, "locator-set %s", &locator_set_name))
16524         {
16525           locator_set_name_set = 1;
16526         }
16527       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16528                          &tmp_if_index))
16529         {
16530           sw_if_index_if_name_set = 1;
16531           sw_if_index = tmp_if_index;
16532         }
16533       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16534         {
16535           sw_if_index_set = 1;
16536           sw_if_index = tmp_if_index;
16537         }
16538       else if (unformat (input, "p %d", &priority))
16539         {
16540           priority_set = 1;
16541         }
16542       else if (unformat (input, "w %d", &weight))
16543         {
16544           weight_set = 1;
16545         }
16546       else
16547         break;
16548     }
16549
16550   if (locator_set_name_set == 0)
16551     {
16552       errmsg ("missing locator-set name");
16553       return -99;
16554     }
16555
16556   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16557     {
16558       errmsg ("missing sw_if_index");
16559       vec_free (locator_set_name);
16560       return -99;
16561     }
16562
16563   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16564     {
16565       errmsg ("cannot use both params interface name and sw_if_index");
16566       vec_free (locator_set_name);
16567       return -99;
16568     }
16569
16570   if (priority_set == 0)
16571     {
16572       errmsg ("missing locator-set priority");
16573       vec_free (locator_set_name);
16574       return -99;
16575     }
16576
16577   if (weight_set == 0)
16578     {
16579       errmsg ("missing locator-set weight");
16580       vec_free (locator_set_name);
16581       return -99;
16582     }
16583
16584   if (vec_len (locator_set_name) > 64)
16585     {
16586       errmsg ("locator-set name too long");
16587       vec_free (locator_set_name);
16588       return -99;
16589     }
16590   vec_add1 (locator_set_name, 0);
16591
16592   /* Construct the API message */
16593   M (ONE_ADD_DEL_LOCATOR, mp);
16594
16595   mp->is_add = is_add;
16596   mp->sw_if_index = ntohl (sw_if_index);
16597   mp->priority = priority;
16598   mp->weight = weight;
16599   clib_memcpy (mp->locator_set_name, locator_set_name,
16600                vec_len (locator_set_name));
16601   vec_free (locator_set_name);
16602
16603   /* send it... */
16604   S (mp);
16605
16606   /* Wait for a reply... */
16607   W (ret);
16608   return ret;
16609 }
16610
16611 #define api_lisp_add_del_locator api_one_add_del_locator
16612
16613 uword
16614 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16615 {
16616   u32 *key_id = va_arg (*args, u32 *);
16617   u8 *s = 0;
16618
16619   if (unformat (input, "%s", &s))
16620     {
16621       if (!strcmp ((char *) s, "sha1"))
16622         key_id[0] = HMAC_SHA_1_96;
16623       else if (!strcmp ((char *) s, "sha256"))
16624         key_id[0] = HMAC_SHA_256_128;
16625       else
16626         {
16627           clib_warning ("invalid key_id: '%s'", s);
16628           key_id[0] = HMAC_NO_KEY;
16629         }
16630     }
16631   else
16632     return 0;
16633
16634   vec_free (s);
16635   return 1;
16636 }
16637
16638 static int
16639 api_one_add_del_local_eid (vat_main_t * vam)
16640 {
16641   unformat_input_t *input = vam->input;
16642   vl_api_one_add_del_local_eid_t *mp;
16643   u8 is_add = 1;
16644   u8 eid_set = 0;
16645   lisp_eid_vat_t _eid, *eid = &_eid;
16646   u8 *locator_set_name = 0;
16647   u8 locator_set_name_set = 0;
16648   u32 vni = 0;
16649   u16 key_id = 0;
16650   u8 *key = 0;
16651   int ret;
16652
16653   /* Parse args required to build the message */
16654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16655     {
16656       if (unformat (input, "del"))
16657         {
16658           is_add = 0;
16659         }
16660       else if (unformat (input, "vni %d", &vni))
16661         {
16662           ;
16663         }
16664       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16665         {
16666           eid_set = 1;
16667         }
16668       else if (unformat (input, "locator-set %s", &locator_set_name))
16669         {
16670           locator_set_name_set = 1;
16671         }
16672       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16673         ;
16674       else if (unformat (input, "secret-key %_%v%_", &key))
16675         ;
16676       else
16677         break;
16678     }
16679
16680   if (locator_set_name_set == 0)
16681     {
16682       errmsg ("missing locator-set name");
16683       return -99;
16684     }
16685
16686   if (0 == eid_set)
16687     {
16688       errmsg ("EID address not set!");
16689       vec_free (locator_set_name);
16690       return -99;
16691     }
16692
16693   if (key && (0 == key_id))
16694     {
16695       errmsg ("invalid key_id!");
16696       return -99;
16697     }
16698
16699   if (vec_len (key) > 64)
16700     {
16701       errmsg ("key too long");
16702       vec_free (key);
16703       return -99;
16704     }
16705
16706   if (vec_len (locator_set_name) > 64)
16707     {
16708       errmsg ("locator-set name too long");
16709       vec_free (locator_set_name);
16710       return -99;
16711     }
16712   vec_add1 (locator_set_name, 0);
16713
16714   /* Construct the API message */
16715   M (ONE_ADD_DEL_LOCAL_EID, mp);
16716
16717   mp->is_add = is_add;
16718   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16719   mp->eid_type = eid->type;
16720   mp->prefix_len = eid->len;
16721   mp->vni = clib_host_to_net_u32 (vni);
16722   mp->key_id = clib_host_to_net_u16 (key_id);
16723   clib_memcpy (mp->locator_set_name, locator_set_name,
16724                vec_len (locator_set_name));
16725   clib_memcpy (mp->key, key, vec_len (key));
16726
16727   vec_free (locator_set_name);
16728   vec_free (key);
16729
16730   /* send it... */
16731   S (mp);
16732
16733   /* Wait for a reply... */
16734   W (ret);
16735   return ret;
16736 }
16737
16738 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16739
16740 static int
16741 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16742 {
16743   u32 dp_table = 0, vni = 0;;
16744   unformat_input_t *input = vam->input;
16745   vl_api_gpe_add_del_fwd_entry_t *mp;
16746   u8 is_add = 1;
16747   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16748   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16749   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16750   u32 action = ~0, w;
16751   ip4_address_t rmt_rloc4, lcl_rloc4;
16752   ip6_address_t rmt_rloc6, lcl_rloc6;
16753   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16754   int ret;
16755
16756   clib_memset (&rloc, 0, sizeof (rloc));
16757
16758   /* Parse args required to build the message */
16759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16760     {
16761       if (unformat (input, "del"))
16762         is_add = 0;
16763       else if (unformat (input, "add"))
16764         is_add = 1;
16765       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16766         {
16767           rmt_eid_set = 1;
16768         }
16769       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16770         {
16771           lcl_eid_set = 1;
16772         }
16773       else if (unformat (input, "vrf %d", &dp_table))
16774         ;
16775       else if (unformat (input, "bd %d", &dp_table))
16776         ;
16777       else if (unformat (input, "vni %d", &vni))
16778         ;
16779       else if (unformat (input, "w %d", &w))
16780         {
16781           if (!curr_rloc)
16782             {
16783               errmsg ("No RLOC configured for setting priority/weight!");
16784               return -99;
16785             }
16786           curr_rloc->weight = w;
16787         }
16788       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16789                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16790         {
16791           rloc.is_ip4 = 1;
16792
16793           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16794           rloc.weight = 0;
16795           vec_add1 (lcl_locs, rloc);
16796
16797           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16798           vec_add1 (rmt_locs, rloc);
16799           /* weight saved in rmt loc */
16800           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16801         }
16802       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16803                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16804         {
16805           rloc.is_ip4 = 0;
16806           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16807           rloc.weight = 0;
16808           vec_add1 (lcl_locs, rloc);
16809
16810           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16811           vec_add1 (rmt_locs, rloc);
16812           /* weight saved in rmt loc */
16813           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16814         }
16815       else if (unformat (input, "action %d", &action))
16816         {
16817           ;
16818         }
16819       else
16820         {
16821           clib_warning ("parse error '%U'", format_unformat_error, input);
16822           return -99;
16823         }
16824     }
16825
16826   if (!rmt_eid_set)
16827     {
16828       errmsg ("remote eid addresses not set");
16829       return -99;
16830     }
16831
16832   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16833     {
16834       errmsg ("eid types don't match");
16835       return -99;
16836     }
16837
16838   if (0 == rmt_locs && (u32) ~ 0 == action)
16839     {
16840       errmsg ("action not set for negative mapping");
16841       return -99;
16842     }
16843
16844   /* Construct the API message */
16845   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16846       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16847
16848   mp->is_add = is_add;
16849   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16850   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16851   mp->eid_type = rmt_eid->type;
16852   mp->dp_table = clib_host_to_net_u32 (dp_table);
16853   mp->vni = clib_host_to_net_u32 (vni);
16854   mp->rmt_len = rmt_eid->len;
16855   mp->lcl_len = lcl_eid->len;
16856   mp->action = action;
16857
16858   if (0 != rmt_locs && 0 != lcl_locs)
16859     {
16860       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16861       clib_memcpy (mp->locs, lcl_locs,
16862                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16863
16864       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16865       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16866                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16867     }
16868   vec_free (lcl_locs);
16869   vec_free (rmt_locs);
16870
16871   /* send it... */
16872   S (mp);
16873
16874   /* Wait for a reply... */
16875   W (ret);
16876   return ret;
16877 }
16878
16879 static int
16880 api_one_add_del_map_server (vat_main_t * vam)
16881 {
16882   unformat_input_t *input = vam->input;
16883   vl_api_one_add_del_map_server_t *mp;
16884   u8 is_add = 1;
16885   u8 ipv4_set = 0;
16886   u8 ipv6_set = 0;
16887   ip4_address_t ipv4;
16888   ip6_address_t ipv6;
16889   int ret;
16890
16891   /* Parse args required to build the message */
16892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16893     {
16894       if (unformat (input, "del"))
16895         {
16896           is_add = 0;
16897         }
16898       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16899         {
16900           ipv4_set = 1;
16901         }
16902       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16903         {
16904           ipv6_set = 1;
16905         }
16906       else
16907         break;
16908     }
16909
16910   if (ipv4_set && ipv6_set)
16911     {
16912       errmsg ("both eid v4 and v6 addresses set");
16913       return -99;
16914     }
16915
16916   if (!ipv4_set && !ipv6_set)
16917     {
16918       errmsg ("eid addresses not set");
16919       return -99;
16920     }
16921
16922   /* Construct the API message */
16923   M (ONE_ADD_DEL_MAP_SERVER, mp);
16924
16925   mp->is_add = is_add;
16926   if (ipv6_set)
16927     {
16928       mp->is_ipv6 = 1;
16929       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16930     }
16931   else
16932     {
16933       mp->is_ipv6 = 0;
16934       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16935     }
16936
16937   /* send it... */
16938   S (mp);
16939
16940   /* Wait for a reply... */
16941   W (ret);
16942   return ret;
16943 }
16944
16945 #define api_lisp_add_del_map_server api_one_add_del_map_server
16946
16947 static int
16948 api_one_add_del_map_resolver (vat_main_t * vam)
16949 {
16950   unformat_input_t *input = vam->input;
16951   vl_api_one_add_del_map_resolver_t *mp;
16952   u8 is_add = 1;
16953   u8 ipv4_set = 0;
16954   u8 ipv6_set = 0;
16955   ip4_address_t ipv4;
16956   ip6_address_t ipv6;
16957   int ret;
16958
16959   /* Parse args required to build the message */
16960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (input, "del"))
16963         {
16964           is_add = 0;
16965         }
16966       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16967         {
16968           ipv4_set = 1;
16969         }
16970       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16971         {
16972           ipv6_set = 1;
16973         }
16974       else
16975         break;
16976     }
16977
16978   if (ipv4_set && ipv6_set)
16979     {
16980       errmsg ("both eid v4 and v6 addresses set");
16981       return -99;
16982     }
16983
16984   if (!ipv4_set && !ipv6_set)
16985     {
16986       errmsg ("eid addresses not set");
16987       return -99;
16988     }
16989
16990   /* Construct the API message */
16991   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16992
16993   mp->is_add = is_add;
16994   if (ipv6_set)
16995     {
16996       mp->is_ipv6 = 1;
16997       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16998     }
16999   else
17000     {
17001       mp->is_ipv6 = 0;
17002       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17003     }
17004
17005   /* send it... */
17006   S (mp);
17007
17008   /* Wait for a reply... */
17009   W (ret);
17010   return ret;
17011 }
17012
17013 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17014
17015 static int
17016 api_lisp_gpe_enable_disable (vat_main_t * vam)
17017 {
17018   unformat_input_t *input = vam->input;
17019   vl_api_gpe_enable_disable_t *mp;
17020   u8 is_set = 0;
17021   u8 is_en = 1;
17022   int ret;
17023
17024   /* Parse args required to build the message */
17025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17026     {
17027       if (unformat (input, "enable"))
17028         {
17029           is_set = 1;
17030           is_en = 1;
17031         }
17032       else if (unformat (input, "disable"))
17033         {
17034           is_set = 1;
17035           is_en = 0;
17036         }
17037       else
17038         break;
17039     }
17040
17041   if (is_set == 0)
17042     {
17043       errmsg ("Value not set");
17044       return -99;
17045     }
17046
17047   /* Construct the API message */
17048   M (GPE_ENABLE_DISABLE, mp);
17049
17050   mp->is_en = is_en;
17051
17052   /* send it... */
17053   S (mp);
17054
17055   /* Wait for a reply... */
17056   W (ret);
17057   return ret;
17058 }
17059
17060 static int
17061 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17062 {
17063   unformat_input_t *input = vam->input;
17064   vl_api_one_rloc_probe_enable_disable_t *mp;
17065   u8 is_set = 0;
17066   u8 is_en = 0;
17067   int ret;
17068
17069   /* Parse args required to build the message */
17070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17071     {
17072       if (unformat (input, "enable"))
17073         {
17074           is_set = 1;
17075           is_en = 1;
17076         }
17077       else if (unformat (input, "disable"))
17078         is_set = 1;
17079       else
17080         break;
17081     }
17082
17083   if (!is_set)
17084     {
17085       errmsg ("Value not set");
17086       return -99;
17087     }
17088
17089   /* Construct the API message */
17090   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17091
17092   mp->is_enabled = is_en;
17093
17094   /* send it... */
17095   S (mp);
17096
17097   /* Wait for a reply... */
17098   W (ret);
17099   return ret;
17100 }
17101
17102 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17103
17104 static int
17105 api_one_map_register_enable_disable (vat_main_t * vam)
17106 {
17107   unformat_input_t *input = vam->input;
17108   vl_api_one_map_register_enable_disable_t *mp;
17109   u8 is_set = 0;
17110   u8 is_en = 0;
17111   int ret;
17112
17113   /* Parse args required to build the message */
17114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17115     {
17116       if (unformat (input, "enable"))
17117         {
17118           is_set = 1;
17119           is_en = 1;
17120         }
17121       else if (unformat (input, "disable"))
17122         is_set = 1;
17123       else
17124         break;
17125     }
17126
17127   if (!is_set)
17128     {
17129       errmsg ("Value not set");
17130       return -99;
17131     }
17132
17133   /* Construct the API message */
17134   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17135
17136   mp->is_enabled = is_en;
17137
17138   /* send it... */
17139   S (mp);
17140
17141   /* Wait for a reply... */
17142   W (ret);
17143   return ret;
17144 }
17145
17146 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17147
17148 static int
17149 api_one_enable_disable (vat_main_t * vam)
17150 {
17151   unformat_input_t *input = vam->input;
17152   vl_api_one_enable_disable_t *mp;
17153   u8 is_set = 0;
17154   u8 is_en = 0;
17155   int ret;
17156
17157   /* Parse args required to build the message */
17158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17159     {
17160       if (unformat (input, "enable"))
17161         {
17162           is_set = 1;
17163           is_en = 1;
17164         }
17165       else if (unformat (input, "disable"))
17166         {
17167           is_set = 1;
17168         }
17169       else
17170         break;
17171     }
17172
17173   if (!is_set)
17174     {
17175       errmsg ("Value not set");
17176       return -99;
17177     }
17178
17179   /* Construct the API message */
17180   M (ONE_ENABLE_DISABLE, mp);
17181
17182   mp->is_en = is_en;
17183
17184   /* send it... */
17185   S (mp);
17186
17187   /* Wait for a reply... */
17188   W (ret);
17189   return ret;
17190 }
17191
17192 #define api_lisp_enable_disable api_one_enable_disable
17193
17194 static int
17195 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17196 {
17197   unformat_input_t *input = vam->input;
17198   vl_api_one_enable_disable_xtr_mode_t *mp;
17199   u8 is_set = 0;
17200   u8 is_en = 0;
17201   int ret;
17202
17203   /* Parse args required to build the message */
17204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17205     {
17206       if (unformat (input, "enable"))
17207         {
17208           is_set = 1;
17209           is_en = 1;
17210         }
17211       else if (unformat (input, "disable"))
17212         {
17213           is_set = 1;
17214         }
17215       else
17216         break;
17217     }
17218
17219   if (!is_set)
17220     {
17221       errmsg ("Value not set");
17222       return -99;
17223     }
17224
17225   /* Construct the API message */
17226   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17227
17228   mp->is_en = is_en;
17229
17230   /* send it... */
17231   S (mp);
17232
17233   /* Wait for a reply... */
17234   W (ret);
17235   return ret;
17236 }
17237
17238 static int
17239 api_one_show_xtr_mode (vat_main_t * vam)
17240 {
17241   vl_api_one_show_xtr_mode_t *mp;
17242   int ret;
17243
17244   /* Construct the API message */
17245   M (ONE_SHOW_XTR_MODE, mp);
17246
17247   /* send it... */
17248   S (mp);
17249
17250   /* Wait for a reply... */
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static int
17256 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17257 {
17258   unformat_input_t *input = vam->input;
17259   vl_api_one_enable_disable_pitr_mode_t *mp;
17260   u8 is_set = 0;
17261   u8 is_en = 0;
17262   int ret;
17263
17264   /* Parse args required to build the message */
17265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17266     {
17267       if (unformat (input, "enable"))
17268         {
17269           is_set = 1;
17270           is_en = 1;
17271         }
17272       else if (unformat (input, "disable"))
17273         {
17274           is_set = 1;
17275         }
17276       else
17277         break;
17278     }
17279
17280   if (!is_set)
17281     {
17282       errmsg ("Value not set");
17283       return -99;
17284     }
17285
17286   /* Construct the API message */
17287   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17288
17289   mp->is_en = is_en;
17290
17291   /* send it... */
17292   S (mp);
17293
17294   /* Wait for a reply... */
17295   W (ret);
17296   return ret;
17297 }
17298
17299 static int
17300 api_one_show_pitr_mode (vat_main_t * vam)
17301 {
17302   vl_api_one_show_pitr_mode_t *mp;
17303   int ret;
17304
17305   /* Construct the API message */
17306   M (ONE_SHOW_PITR_MODE, mp);
17307
17308   /* send it... */
17309   S (mp);
17310
17311   /* Wait for a reply... */
17312   W (ret);
17313   return ret;
17314 }
17315
17316 static int
17317 api_one_enable_disable_petr_mode (vat_main_t * vam)
17318 {
17319   unformat_input_t *input = vam->input;
17320   vl_api_one_enable_disable_petr_mode_t *mp;
17321   u8 is_set = 0;
17322   u8 is_en = 0;
17323   int ret;
17324
17325   /* Parse args required to build the message */
17326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17327     {
17328       if (unformat (input, "enable"))
17329         {
17330           is_set = 1;
17331           is_en = 1;
17332         }
17333       else if (unformat (input, "disable"))
17334         {
17335           is_set = 1;
17336         }
17337       else
17338         break;
17339     }
17340
17341   if (!is_set)
17342     {
17343       errmsg ("Value not set");
17344       return -99;
17345     }
17346
17347   /* Construct the API message */
17348   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17349
17350   mp->is_en = is_en;
17351
17352   /* send it... */
17353   S (mp);
17354
17355   /* Wait for a reply... */
17356   W (ret);
17357   return ret;
17358 }
17359
17360 static int
17361 api_one_show_petr_mode (vat_main_t * vam)
17362 {
17363   vl_api_one_show_petr_mode_t *mp;
17364   int ret;
17365
17366   /* Construct the API message */
17367   M (ONE_SHOW_PETR_MODE, mp);
17368
17369   /* send it... */
17370   S (mp);
17371
17372   /* Wait for a reply... */
17373   W (ret);
17374   return ret;
17375 }
17376
17377 static int
17378 api_show_one_map_register_state (vat_main_t * vam)
17379 {
17380   vl_api_show_one_map_register_state_t *mp;
17381   int ret;
17382
17383   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17384
17385   /* send */
17386   S (mp);
17387
17388   /* wait for reply */
17389   W (ret);
17390   return ret;
17391 }
17392
17393 #define api_show_lisp_map_register_state api_show_one_map_register_state
17394
17395 static int
17396 api_show_one_rloc_probe_state (vat_main_t * vam)
17397 {
17398   vl_api_show_one_rloc_probe_state_t *mp;
17399   int ret;
17400
17401   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17402
17403   /* send */
17404   S (mp);
17405
17406   /* wait for reply */
17407   W (ret);
17408   return ret;
17409 }
17410
17411 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17412
17413 static int
17414 api_one_add_del_ndp_entry (vat_main_t * vam)
17415 {
17416   vl_api_one_add_del_ndp_entry_t *mp;
17417   unformat_input_t *input = vam->input;
17418   u8 is_add = 1;
17419   u8 mac_set = 0;
17420   u8 bd_set = 0;
17421   u8 ip_set = 0;
17422   u8 mac[6] = { 0, };
17423   u8 ip6[16] = { 0, };
17424   u32 bd = ~0;
17425   int ret;
17426
17427   /* Parse args required to build the message */
17428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (input, "del"))
17431         is_add = 0;
17432       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17433         mac_set = 1;
17434       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17435         ip_set = 1;
17436       else if (unformat (input, "bd %d", &bd))
17437         bd_set = 1;
17438       else
17439         {
17440           errmsg ("parse error '%U'", format_unformat_error, input);
17441           return -99;
17442         }
17443     }
17444
17445   if (!bd_set || !ip_set || (!mac_set && is_add))
17446     {
17447       errmsg ("Missing BD, IP or MAC!");
17448       return -99;
17449     }
17450
17451   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17452   mp->is_add = is_add;
17453   clib_memcpy (mp->mac, mac, 6);
17454   mp->bd = clib_host_to_net_u32 (bd);
17455   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17456
17457   /* send */
17458   S (mp);
17459
17460   /* wait for reply */
17461   W (ret);
17462   return ret;
17463 }
17464
17465 static int
17466 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17467 {
17468   vl_api_one_add_del_l2_arp_entry_t *mp;
17469   unformat_input_t *input = vam->input;
17470   u8 is_add = 1;
17471   u8 mac_set = 0;
17472   u8 bd_set = 0;
17473   u8 ip_set = 0;
17474   u8 mac[6] = { 0, };
17475   u32 ip4 = 0, bd = ~0;
17476   int ret;
17477
17478   /* Parse args required to build the message */
17479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17480     {
17481       if (unformat (input, "del"))
17482         is_add = 0;
17483       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17484         mac_set = 1;
17485       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17486         ip_set = 1;
17487       else if (unformat (input, "bd %d", &bd))
17488         bd_set = 1;
17489       else
17490         {
17491           errmsg ("parse error '%U'", format_unformat_error, input);
17492           return -99;
17493         }
17494     }
17495
17496   if (!bd_set || !ip_set || (!mac_set && is_add))
17497     {
17498       errmsg ("Missing BD, IP or MAC!");
17499       return -99;
17500     }
17501
17502   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17503   mp->is_add = is_add;
17504   clib_memcpy (mp->mac, mac, 6);
17505   mp->bd = clib_host_to_net_u32 (bd);
17506   mp->ip4 = ip4;
17507
17508   /* send */
17509   S (mp);
17510
17511   /* wait for reply */
17512   W (ret);
17513   return ret;
17514 }
17515
17516 static int
17517 api_one_ndp_bd_get (vat_main_t * vam)
17518 {
17519   vl_api_one_ndp_bd_get_t *mp;
17520   int ret;
17521
17522   M (ONE_NDP_BD_GET, mp);
17523
17524   /* send */
17525   S (mp);
17526
17527   /* wait for reply */
17528   W (ret);
17529   return ret;
17530 }
17531
17532 static int
17533 api_one_ndp_entries_get (vat_main_t * vam)
17534 {
17535   vl_api_one_ndp_entries_get_t *mp;
17536   unformat_input_t *input = vam->input;
17537   u8 bd_set = 0;
17538   u32 bd = ~0;
17539   int ret;
17540
17541   /* Parse args required to build the message */
17542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17543     {
17544       if (unformat (input, "bd %d", &bd))
17545         bd_set = 1;
17546       else
17547         {
17548           errmsg ("parse error '%U'", format_unformat_error, input);
17549           return -99;
17550         }
17551     }
17552
17553   if (!bd_set)
17554     {
17555       errmsg ("Expected bridge domain!");
17556       return -99;
17557     }
17558
17559   M (ONE_NDP_ENTRIES_GET, mp);
17560   mp->bd = clib_host_to_net_u32 (bd);
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_l2_arp_bd_get (vat_main_t * vam)
17572 {
17573   vl_api_one_l2_arp_bd_get_t *mp;
17574   int ret;
17575
17576   M (ONE_L2_ARP_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_l2_arp_entries_get (vat_main_t * vam)
17588 {
17589   vl_api_one_l2_arp_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_L2_ARP_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_stats_enable_disable (vat_main_t * vam)
17626 {
17627   vl_api_one_stats_enable_disable_t *mp;
17628   unformat_input_t *input = vam->input;
17629   u8 is_set = 0;
17630   u8 is_en = 0;
17631   int ret;
17632
17633   /* Parse args required to build the message */
17634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17635     {
17636       if (unformat (input, "enable"))
17637         {
17638           is_set = 1;
17639           is_en = 1;
17640         }
17641       else if (unformat (input, "disable"))
17642         {
17643           is_set = 1;
17644         }
17645       else
17646         break;
17647     }
17648
17649   if (!is_set)
17650     {
17651       errmsg ("Value not set");
17652       return -99;
17653     }
17654
17655   M (ONE_STATS_ENABLE_DISABLE, mp);
17656   mp->is_en = is_en;
17657
17658   /* send */
17659   S (mp);
17660
17661   /* wait for reply */
17662   W (ret);
17663   return ret;
17664 }
17665
17666 static int
17667 api_show_one_stats_enable_disable (vat_main_t * vam)
17668 {
17669   vl_api_show_one_stats_enable_disable_t *mp;
17670   int ret;
17671
17672   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17673
17674   /* send */
17675   S (mp);
17676
17677   /* wait for reply */
17678   W (ret);
17679   return ret;
17680 }
17681
17682 static int
17683 api_show_one_map_request_mode (vat_main_t * vam)
17684 {
17685   vl_api_show_one_map_request_mode_t *mp;
17686   int ret;
17687
17688   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17689
17690   /* send */
17691   S (mp);
17692
17693   /* wait for reply */
17694   W (ret);
17695   return ret;
17696 }
17697
17698 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17699
17700 static int
17701 api_one_map_request_mode (vat_main_t * vam)
17702 {
17703   unformat_input_t *input = vam->input;
17704   vl_api_one_map_request_mode_t *mp;
17705   u8 mode = 0;
17706   int ret;
17707
17708   /* Parse args required to build the message */
17709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17710     {
17711       if (unformat (input, "dst-only"))
17712         mode = 0;
17713       else if (unformat (input, "src-dst"))
17714         mode = 1;
17715       else
17716         {
17717           errmsg ("parse error '%U'", format_unformat_error, input);
17718           return -99;
17719         }
17720     }
17721
17722   M (ONE_MAP_REQUEST_MODE, mp);
17723
17724   mp->mode = mode;
17725
17726   /* send */
17727   S (mp);
17728
17729   /* wait for reply */
17730   W (ret);
17731   return ret;
17732 }
17733
17734 #define api_lisp_map_request_mode api_one_map_request_mode
17735
17736 /**
17737  * Enable/disable ONE proxy ITR.
17738  *
17739  * @param vam vpp API test context
17740  * @return return code
17741  */
17742 static int
17743 api_one_pitr_set_locator_set (vat_main_t * vam)
17744 {
17745   u8 ls_name_set = 0;
17746   unformat_input_t *input = vam->input;
17747   vl_api_one_pitr_set_locator_set_t *mp;
17748   u8 is_add = 1;
17749   u8 *ls_name = 0;
17750   int ret;
17751
17752   /* Parse args required to build the message */
17753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17754     {
17755       if (unformat (input, "del"))
17756         is_add = 0;
17757       else if (unformat (input, "locator-set %s", &ls_name))
17758         ls_name_set = 1;
17759       else
17760         {
17761           errmsg ("parse error '%U'", format_unformat_error, input);
17762           return -99;
17763         }
17764     }
17765
17766   if (!ls_name_set)
17767     {
17768       errmsg ("locator-set name not set!");
17769       return -99;
17770     }
17771
17772   M (ONE_PITR_SET_LOCATOR_SET, mp);
17773
17774   mp->is_add = is_add;
17775   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17776   vec_free (ls_name);
17777
17778   /* send */
17779   S (mp);
17780
17781   /* wait for reply */
17782   W (ret);
17783   return ret;
17784 }
17785
17786 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17787
17788 static int
17789 api_one_nsh_set_locator_set (vat_main_t * vam)
17790 {
17791   u8 ls_name_set = 0;
17792   unformat_input_t *input = vam->input;
17793   vl_api_one_nsh_set_locator_set_t *mp;
17794   u8 is_add = 1;
17795   u8 *ls_name = 0;
17796   int ret;
17797
17798   /* Parse args required to build the message */
17799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17800     {
17801       if (unformat (input, "del"))
17802         is_add = 0;
17803       else if (unformat (input, "ls %s", &ls_name))
17804         ls_name_set = 1;
17805       else
17806         {
17807           errmsg ("parse error '%U'", format_unformat_error, input);
17808           return -99;
17809         }
17810     }
17811
17812   if (!ls_name_set && is_add)
17813     {
17814       errmsg ("locator-set name not set!");
17815       return -99;
17816     }
17817
17818   M (ONE_NSH_SET_LOCATOR_SET, mp);
17819
17820   mp->is_add = is_add;
17821   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17822   vec_free (ls_name);
17823
17824   /* send */
17825   S (mp);
17826
17827   /* wait for reply */
17828   W (ret);
17829   return ret;
17830 }
17831
17832 static int
17833 api_show_one_pitr (vat_main_t * vam)
17834 {
17835   vl_api_show_one_pitr_t *mp;
17836   int ret;
17837
17838   if (!vam->json_output)
17839     {
17840       print (vam->ofp, "%=20s", "lisp status:");
17841     }
17842
17843   M (SHOW_ONE_PITR, mp);
17844   /* send it... */
17845   S (mp);
17846
17847   /* Wait for a reply... */
17848   W (ret);
17849   return ret;
17850 }
17851
17852 #define api_show_lisp_pitr api_show_one_pitr
17853
17854 static int
17855 api_one_use_petr (vat_main_t * vam)
17856 {
17857   unformat_input_t *input = vam->input;
17858   vl_api_one_use_petr_t *mp;
17859   u8 is_add = 0;
17860   ip_address_t ip;
17861   int ret;
17862
17863   clib_memset (&ip, 0, sizeof (ip));
17864
17865   /* Parse args required to build the message */
17866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17867     {
17868       if (unformat (input, "disable"))
17869         is_add = 0;
17870       else
17871         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17872         {
17873           is_add = 1;
17874           ip_addr_version (&ip) = IP4;
17875         }
17876       else
17877         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17878         {
17879           is_add = 1;
17880           ip_addr_version (&ip) = IP6;
17881         }
17882       else
17883         {
17884           errmsg ("parse error '%U'", format_unformat_error, input);
17885           return -99;
17886         }
17887     }
17888
17889   M (ONE_USE_PETR, mp);
17890
17891   mp->is_add = is_add;
17892   if (is_add)
17893     {
17894       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17895       if (mp->is_ip4)
17896         clib_memcpy (mp->address, &ip, 4);
17897       else
17898         clib_memcpy (mp->address, &ip, 16);
17899     }
17900
17901   /* send */
17902   S (mp);
17903
17904   /* wait for reply */
17905   W (ret);
17906   return ret;
17907 }
17908
17909 #define api_lisp_use_petr api_one_use_petr
17910
17911 static int
17912 api_show_one_nsh_mapping (vat_main_t * vam)
17913 {
17914   vl_api_show_one_use_petr_t *mp;
17915   int ret;
17916
17917   if (!vam->json_output)
17918     {
17919       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17920     }
17921
17922   M (SHOW_ONE_NSH_MAPPING, mp);
17923   /* send it... */
17924   S (mp);
17925
17926   /* Wait for a reply... */
17927   W (ret);
17928   return ret;
17929 }
17930
17931 static int
17932 api_show_one_use_petr (vat_main_t * vam)
17933 {
17934   vl_api_show_one_use_petr_t *mp;
17935   int ret;
17936
17937   if (!vam->json_output)
17938     {
17939       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17940     }
17941
17942   M (SHOW_ONE_USE_PETR, mp);
17943   /* send it... */
17944   S (mp);
17945
17946   /* Wait for a reply... */
17947   W (ret);
17948   return ret;
17949 }
17950
17951 #define api_show_lisp_use_petr api_show_one_use_petr
17952
17953 /**
17954  * Add/delete mapping between vni and vrf
17955  */
17956 static int
17957 api_one_eid_table_add_del_map (vat_main_t * vam)
17958 {
17959   unformat_input_t *input = vam->input;
17960   vl_api_one_eid_table_add_del_map_t *mp;
17961   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17962   u32 vni, vrf, bd_index;
17963   int ret;
17964
17965   /* Parse args required to build the message */
17966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17967     {
17968       if (unformat (input, "del"))
17969         is_add = 0;
17970       else if (unformat (input, "vrf %d", &vrf))
17971         vrf_set = 1;
17972       else if (unformat (input, "bd_index %d", &bd_index))
17973         bd_index_set = 1;
17974       else if (unformat (input, "vni %d", &vni))
17975         vni_set = 1;
17976       else
17977         break;
17978     }
17979
17980   if (!vni_set || (!vrf_set && !bd_index_set))
17981     {
17982       errmsg ("missing arguments!");
17983       return -99;
17984     }
17985
17986   if (vrf_set && bd_index_set)
17987     {
17988       errmsg ("error: both vrf and bd entered!");
17989       return -99;
17990     }
17991
17992   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17993
17994   mp->is_add = is_add;
17995   mp->vni = htonl (vni);
17996   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17997   mp->is_l2 = bd_index_set;
17998
17999   /* send */
18000   S (mp);
18001
18002   /* wait for reply */
18003   W (ret);
18004   return ret;
18005 }
18006
18007 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18008
18009 uword
18010 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18011 {
18012   u32 *action = va_arg (*args, u32 *);
18013   u8 *s = 0;
18014
18015   if (unformat (input, "%s", &s))
18016     {
18017       if (!strcmp ((char *) s, "no-action"))
18018         action[0] = 0;
18019       else if (!strcmp ((char *) s, "natively-forward"))
18020         action[0] = 1;
18021       else if (!strcmp ((char *) s, "send-map-request"))
18022         action[0] = 2;
18023       else if (!strcmp ((char *) s, "drop"))
18024         action[0] = 3;
18025       else
18026         {
18027           clib_warning ("invalid action: '%s'", s);
18028           action[0] = 3;
18029         }
18030     }
18031   else
18032     return 0;
18033
18034   vec_free (s);
18035   return 1;
18036 }
18037
18038 /**
18039  * Add/del remote mapping to/from ONE control plane
18040  *
18041  * @param vam vpp API test context
18042  * @return return code
18043  */
18044 static int
18045 api_one_add_del_remote_mapping (vat_main_t * vam)
18046 {
18047   unformat_input_t *input = vam->input;
18048   vl_api_one_add_del_remote_mapping_t *mp;
18049   u32 vni = 0;
18050   lisp_eid_vat_t _eid, *eid = &_eid;
18051   lisp_eid_vat_t _seid, *seid = &_seid;
18052   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18053   u32 action = ~0, p, w, data_len;
18054   ip4_address_t rloc4;
18055   ip6_address_t rloc6;
18056   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18057   int ret;
18058
18059   clib_memset (&rloc, 0, sizeof (rloc));
18060
18061   /* Parse args required to build the message */
18062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18063     {
18064       if (unformat (input, "del-all"))
18065         {
18066           del_all = 1;
18067         }
18068       else if (unformat (input, "del"))
18069         {
18070           is_add = 0;
18071         }
18072       else if (unformat (input, "add"))
18073         {
18074           is_add = 1;
18075         }
18076       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18077         {
18078           eid_set = 1;
18079         }
18080       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18081         {
18082           seid_set = 1;
18083         }
18084       else if (unformat (input, "vni %d", &vni))
18085         {
18086           ;
18087         }
18088       else if (unformat (input, "p %d w %d", &p, &w))
18089         {
18090           if (!curr_rloc)
18091             {
18092               errmsg ("No RLOC configured for setting priority/weight!");
18093               return -99;
18094             }
18095           curr_rloc->priority = p;
18096           curr_rloc->weight = w;
18097         }
18098       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18099         {
18100           rloc.is_ip4 = 1;
18101           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18102           vec_add1 (rlocs, rloc);
18103           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18104         }
18105       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18106         {
18107           rloc.is_ip4 = 0;
18108           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18109           vec_add1 (rlocs, rloc);
18110           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18111         }
18112       else if (unformat (input, "action %U",
18113                          unformat_negative_mapping_action, &action))
18114         {
18115           ;
18116         }
18117       else
18118         {
18119           clib_warning ("parse error '%U'", format_unformat_error, input);
18120           return -99;
18121         }
18122     }
18123
18124   if (0 == eid_set)
18125     {
18126       errmsg ("missing params!");
18127       return -99;
18128     }
18129
18130   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18131     {
18132       errmsg ("no action set for negative map-reply!");
18133       return -99;
18134     }
18135
18136   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18137
18138   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18139   mp->is_add = is_add;
18140   mp->vni = htonl (vni);
18141   mp->action = (u8) action;
18142   mp->is_src_dst = seid_set;
18143   mp->eid_len = eid->len;
18144   mp->seid_len = seid->len;
18145   mp->del_all = del_all;
18146   mp->eid_type = eid->type;
18147   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18148   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18149
18150   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18151   clib_memcpy (mp->rlocs, rlocs, data_len);
18152   vec_free (rlocs);
18153
18154   /* send it... */
18155   S (mp);
18156
18157   /* Wait for a reply... */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18163
18164 /**
18165  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18166  * forwarding entries in data-plane accordingly.
18167  *
18168  * @param vam vpp API test context
18169  * @return return code
18170  */
18171 static int
18172 api_one_add_del_adjacency (vat_main_t * vam)
18173 {
18174   unformat_input_t *input = vam->input;
18175   vl_api_one_add_del_adjacency_t *mp;
18176   u32 vni = 0;
18177   ip4_address_t leid4, reid4;
18178   ip6_address_t leid6, reid6;
18179   u8 reid_mac[6] = { 0 };
18180   u8 leid_mac[6] = { 0 };
18181   u8 reid_type, leid_type;
18182   u32 leid_len = 0, reid_len = 0, len;
18183   u8 is_add = 1;
18184   int ret;
18185
18186   leid_type = reid_type = (u8) ~ 0;
18187
18188   /* Parse args required to build the message */
18189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18190     {
18191       if (unformat (input, "del"))
18192         {
18193           is_add = 0;
18194         }
18195       else if (unformat (input, "add"))
18196         {
18197           is_add = 1;
18198         }
18199       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18200                          &reid4, &len))
18201         {
18202           reid_type = 0;        /* ipv4 */
18203           reid_len = len;
18204         }
18205       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18206                          &reid6, &len))
18207         {
18208           reid_type = 1;        /* ipv6 */
18209           reid_len = len;
18210         }
18211       else if (unformat (input, "reid %U", unformat_ethernet_address,
18212                          reid_mac))
18213         {
18214           reid_type = 2;        /* mac */
18215         }
18216       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18217                          &leid4, &len))
18218         {
18219           leid_type = 0;        /* ipv4 */
18220           leid_len = len;
18221         }
18222       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18223                          &leid6, &len))
18224         {
18225           leid_type = 1;        /* ipv6 */
18226           leid_len = len;
18227         }
18228       else if (unformat (input, "leid %U", unformat_ethernet_address,
18229                          leid_mac))
18230         {
18231           leid_type = 2;        /* mac */
18232         }
18233       else if (unformat (input, "vni %d", &vni))
18234         {
18235           ;
18236         }
18237       else
18238         {
18239           errmsg ("parse error '%U'", format_unformat_error, input);
18240           return -99;
18241         }
18242     }
18243
18244   if ((u8) ~ 0 == reid_type)
18245     {
18246       errmsg ("missing params!");
18247       return -99;
18248     }
18249
18250   if (leid_type != reid_type)
18251     {
18252       errmsg ("remote and local EIDs are of different types!");
18253       return -99;
18254     }
18255
18256   M (ONE_ADD_DEL_ADJACENCY, mp);
18257   mp->is_add = is_add;
18258   mp->vni = htonl (vni);
18259   mp->leid_len = leid_len;
18260   mp->reid_len = reid_len;
18261   mp->eid_type = reid_type;
18262
18263   switch (mp->eid_type)
18264     {
18265     case 0:
18266       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18267       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18268       break;
18269     case 1:
18270       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18271       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18272       break;
18273     case 2:
18274       clib_memcpy (mp->leid, leid_mac, 6);
18275       clib_memcpy (mp->reid, reid_mac, 6);
18276       break;
18277     default:
18278       errmsg ("unknown EID type %d!", mp->eid_type);
18279       return 0;
18280     }
18281
18282   /* send it... */
18283   S (mp);
18284
18285   /* Wait for a reply... */
18286   W (ret);
18287   return ret;
18288 }
18289
18290 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18291
18292 uword
18293 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18294 {
18295   u32 *mode = va_arg (*args, u32 *);
18296
18297   if (unformat (input, "lisp"))
18298     *mode = 0;
18299   else if (unformat (input, "vxlan"))
18300     *mode = 1;
18301   else
18302     return 0;
18303
18304   return 1;
18305 }
18306
18307 static int
18308 api_gpe_get_encap_mode (vat_main_t * vam)
18309 {
18310   vl_api_gpe_get_encap_mode_t *mp;
18311   int ret;
18312
18313   /* Construct the API message */
18314   M (GPE_GET_ENCAP_MODE, mp);
18315
18316   /* send it... */
18317   S (mp);
18318
18319   /* Wait for a reply... */
18320   W (ret);
18321   return ret;
18322 }
18323
18324 static int
18325 api_gpe_set_encap_mode (vat_main_t * vam)
18326 {
18327   unformat_input_t *input = vam->input;
18328   vl_api_gpe_set_encap_mode_t *mp;
18329   int ret;
18330   u32 mode = 0;
18331
18332   /* Parse args required to build the message */
18333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18334     {
18335       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18336         ;
18337       else
18338         break;
18339     }
18340
18341   /* Construct the API message */
18342   M (GPE_SET_ENCAP_MODE, mp);
18343
18344   mp->mode = mode;
18345
18346   /* send it... */
18347   S (mp);
18348
18349   /* Wait for a reply... */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18356 {
18357   unformat_input_t *input = vam->input;
18358   vl_api_gpe_add_del_iface_t *mp;
18359   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18360   u32 dp_table = 0, vni = 0;
18361   int ret;
18362
18363   /* Parse args required to build the message */
18364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18365     {
18366       if (unformat (input, "up"))
18367         {
18368           action_set = 1;
18369           is_add = 1;
18370         }
18371       else if (unformat (input, "down"))
18372         {
18373           action_set = 1;
18374           is_add = 0;
18375         }
18376       else if (unformat (input, "table_id %d", &dp_table))
18377         {
18378           dp_table_set = 1;
18379         }
18380       else if (unformat (input, "bd_id %d", &dp_table))
18381         {
18382           dp_table_set = 1;
18383           is_l2 = 1;
18384         }
18385       else if (unformat (input, "vni %d", &vni))
18386         {
18387           vni_set = 1;
18388         }
18389       else
18390         break;
18391     }
18392
18393   if (action_set == 0)
18394     {
18395       errmsg ("Action not set");
18396       return -99;
18397     }
18398   if (dp_table_set == 0 || vni_set == 0)
18399     {
18400       errmsg ("vni and dp_table must be set");
18401       return -99;
18402     }
18403
18404   /* Construct the API message */
18405   M (GPE_ADD_DEL_IFACE, mp);
18406
18407   mp->is_add = is_add;
18408   mp->dp_table = clib_host_to_net_u32 (dp_table);
18409   mp->is_l2 = is_l2;
18410   mp->vni = clib_host_to_net_u32 (vni);
18411
18412   /* send it... */
18413   S (mp);
18414
18415   /* Wait for a reply... */
18416   W (ret);
18417   return ret;
18418 }
18419
18420 static int
18421 api_one_map_register_fallback_threshold (vat_main_t * vam)
18422 {
18423   unformat_input_t *input = vam->input;
18424   vl_api_one_map_register_fallback_threshold_t *mp;
18425   u32 value = 0;
18426   u8 is_set = 0;
18427   int ret;
18428
18429   /* Parse args required to build the message */
18430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18431     {
18432       if (unformat (input, "%u", &value))
18433         is_set = 1;
18434       else
18435         {
18436           clib_warning ("parse error '%U'", format_unformat_error, input);
18437           return -99;
18438         }
18439     }
18440
18441   if (!is_set)
18442     {
18443       errmsg ("fallback threshold value is missing!");
18444       return -99;
18445     }
18446
18447   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18448   mp->value = clib_host_to_net_u32 (value);
18449
18450   /* send it... */
18451   S (mp);
18452
18453   /* Wait for a reply... */
18454   W (ret);
18455   return ret;
18456 }
18457
18458 static int
18459 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18460 {
18461   vl_api_show_one_map_register_fallback_threshold_t *mp;
18462   int ret;
18463
18464   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18465
18466   /* send it... */
18467   S (mp);
18468
18469   /* Wait for a reply... */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 uword
18475 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18476 {
18477   u32 *proto = va_arg (*args, u32 *);
18478
18479   if (unformat (input, "udp"))
18480     *proto = 1;
18481   else if (unformat (input, "api"))
18482     *proto = 2;
18483   else
18484     return 0;
18485
18486   return 1;
18487 }
18488
18489 static int
18490 api_one_set_transport_protocol (vat_main_t * vam)
18491 {
18492   unformat_input_t *input = vam->input;
18493   vl_api_one_set_transport_protocol_t *mp;
18494   u8 is_set = 0;
18495   u32 protocol = 0;
18496   int ret;
18497
18498   /* Parse args required to build the message */
18499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18502         is_set = 1;
18503       else
18504         {
18505           clib_warning ("parse error '%U'", format_unformat_error, input);
18506           return -99;
18507         }
18508     }
18509
18510   if (!is_set)
18511     {
18512       errmsg ("Transport protocol missing!");
18513       return -99;
18514     }
18515
18516   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18517   mp->protocol = (u8) protocol;
18518
18519   /* send it... */
18520   S (mp);
18521
18522   /* Wait for a reply... */
18523   W (ret);
18524   return ret;
18525 }
18526
18527 static int
18528 api_one_get_transport_protocol (vat_main_t * vam)
18529 {
18530   vl_api_one_get_transport_protocol_t *mp;
18531   int ret;
18532
18533   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18534
18535   /* send it... */
18536   S (mp);
18537
18538   /* Wait for a reply... */
18539   W (ret);
18540   return ret;
18541 }
18542
18543 static int
18544 api_one_map_register_set_ttl (vat_main_t * vam)
18545 {
18546   unformat_input_t *input = vam->input;
18547   vl_api_one_map_register_set_ttl_t *mp;
18548   u32 ttl = 0;
18549   u8 is_set = 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", &ttl))
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 ("TTL value missing!");
18567       return -99;
18568     }
18569
18570   M (ONE_MAP_REGISTER_SET_TTL, mp);
18571   mp->ttl = clib_host_to_net_u32 (ttl);
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_show_one_map_register_ttl (vat_main_t * vam)
18583 {
18584   vl_api_show_one_map_register_ttl_t *mp;
18585   int ret;
18586
18587   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18588
18589   /* send it... */
18590   S (mp);
18591
18592   /* Wait for a reply... */
18593   W (ret);
18594   return ret;
18595 }
18596
18597 /**
18598  * Add/del map request itr rlocs from ONE control plane and updates
18599  *
18600  * @param vam vpp API test context
18601  * @return return code
18602  */
18603 static int
18604 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18605 {
18606   unformat_input_t *input = vam->input;
18607   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18608   u8 *locator_set_name = 0;
18609   u8 locator_set_name_set = 0;
18610   u8 is_add = 1;
18611   int ret;
18612
18613   /* Parse args required to build the message */
18614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18615     {
18616       if (unformat (input, "del"))
18617         {
18618           is_add = 0;
18619         }
18620       else if (unformat (input, "%_%v%_", &locator_set_name))
18621         {
18622           locator_set_name_set = 1;
18623         }
18624       else
18625         {
18626           clib_warning ("parse error '%U'", format_unformat_error, input);
18627           return -99;
18628         }
18629     }
18630
18631   if (is_add && !locator_set_name_set)
18632     {
18633       errmsg ("itr-rloc is not set!");
18634       return -99;
18635     }
18636
18637   if (is_add && vec_len (locator_set_name) > 64)
18638     {
18639       errmsg ("itr-rloc locator-set name too long");
18640       vec_free (locator_set_name);
18641       return -99;
18642     }
18643
18644   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18645   mp->is_add = is_add;
18646   if (is_add)
18647     {
18648       clib_memcpy (mp->locator_set_name, locator_set_name,
18649                    vec_len (locator_set_name));
18650     }
18651   else
18652     {
18653       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18654     }
18655   vec_free (locator_set_name);
18656
18657   /* send it... */
18658   S (mp);
18659
18660   /* Wait for a reply... */
18661   W (ret);
18662   return ret;
18663 }
18664
18665 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18666
18667 static int
18668 api_one_locator_dump (vat_main_t * vam)
18669 {
18670   unformat_input_t *input = vam->input;
18671   vl_api_one_locator_dump_t *mp;
18672   vl_api_control_ping_t *mp_ping;
18673   u8 is_index_set = 0, is_name_set = 0;
18674   u8 *ls_name = 0;
18675   u32 ls_index = ~0;
18676   int ret;
18677
18678   /* Parse args required to build the message */
18679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18680     {
18681       if (unformat (input, "ls_name %_%v%_", &ls_name))
18682         {
18683           is_name_set = 1;
18684         }
18685       else if (unformat (input, "ls_index %d", &ls_index))
18686         {
18687           is_index_set = 1;
18688         }
18689       else
18690         {
18691           errmsg ("parse error '%U'", format_unformat_error, input);
18692           return -99;
18693         }
18694     }
18695
18696   if (!is_index_set && !is_name_set)
18697     {
18698       errmsg ("error: expected one of index or name!");
18699       return -99;
18700     }
18701
18702   if (is_index_set && is_name_set)
18703     {
18704       errmsg ("error: only one param expected!");
18705       return -99;
18706     }
18707
18708   if (vec_len (ls_name) > 62)
18709     {
18710       errmsg ("error: locator set name too long!");
18711       return -99;
18712     }
18713
18714   if (!vam->json_output)
18715     {
18716       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18717     }
18718
18719   M (ONE_LOCATOR_DUMP, mp);
18720   mp->is_index_set = is_index_set;
18721
18722   if (is_index_set)
18723     mp->ls_index = clib_host_to_net_u32 (ls_index);
18724   else
18725     {
18726       vec_add1 (ls_name, 0);
18727       strncpy ((char *) mp->ls_name, (char *) ls_name,
18728                sizeof (mp->ls_name) - 1);
18729     }
18730
18731   /* send it... */
18732   S (mp);
18733
18734   /* Use a control ping for synchronization */
18735   MPING (CONTROL_PING, mp_ping);
18736   S (mp_ping);
18737
18738   /* Wait for a reply... */
18739   W (ret);
18740   return ret;
18741 }
18742
18743 #define api_lisp_locator_dump api_one_locator_dump
18744
18745 static int
18746 api_one_locator_set_dump (vat_main_t * vam)
18747 {
18748   vl_api_one_locator_set_dump_t *mp;
18749   vl_api_control_ping_t *mp_ping;
18750   unformat_input_t *input = vam->input;
18751   u8 filter = 0;
18752   int ret;
18753
18754   /* Parse args required to build the message */
18755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18756     {
18757       if (unformat (input, "local"))
18758         {
18759           filter = 1;
18760         }
18761       else if (unformat (input, "remote"))
18762         {
18763           filter = 2;
18764         }
18765       else
18766         {
18767           errmsg ("parse error '%U'", format_unformat_error, input);
18768           return -99;
18769         }
18770     }
18771
18772   if (!vam->json_output)
18773     {
18774       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18775     }
18776
18777   M (ONE_LOCATOR_SET_DUMP, mp);
18778
18779   mp->filter = filter;
18780
18781   /* send it... */
18782   S (mp);
18783
18784   /* Use a control ping for synchronization */
18785   MPING (CONTROL_PING, mp_ping);
18786   S (mp_ping);
18787
18788   /* Wait for a reply... */
18789   W (ret);
18790   return ret;
18791 }
18792
18793 #define api_lisp_locator_set_dump api_one_locator_set_dump
18794
18795 static int
18796 api_one_eid_table_map_dump (vat_main_t * vam)
18797 {
18798   u8 is_l2 = 0;
18799   u8 mode_set = 0;
18800   unformat_input_t *input = vam->input;
18801   vl_api_one_eid_table_map_dump_t *mp;
18802   vl_api_control_ping_t *mp_ping;
18803   int ret;
18804
18805   /* Parse args required to build the message */
18806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18807     {
18808       if (unformat (input, "l2"))
18809         {
18810           is_l2 = 1;
18811           mode_set = 1;
18812         }
18813       else if (unformat (input, "l3"))
18814         {
18815           is_l2 = 0;
18816           mode_set = 1;
18817         }
18818       else
18819         {
18820           errmsg ("parse error '%U'", format_unformat_error, input);
18821           return -99;
18822         }
18823     }
18824
18825   if (!mode_set)
18826     {
18827       errmsg ("expected one of 'l2' or 'l3' parameter!");
18828       return -99;
18829     }
18830
18831   if (!vam->json_output)
18832     {
18833       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18834     }
18835
18836   M (ONE_EID_TABLE_MAP_DUMP, mp);
18837   mp->is_l2 = is_l2;
18838
18839   /* send it... */
18840   S (mp);
18841
18842   /* Use a control ping for synchronization */
18843   MPING (CONTROL_PING, mp_ping);
18844   S (mp_ping);
18845
18846   /* Wait for a reply... */
18847   W (ret);
18848   return ret;
18849 }
18850
18851 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18852
18853 static int
18854 api_one_eid_table_vni_dump (vat_main_t * vam)
18855 {
18856   vl_api_one_eid_table_vni_dump_t *mp;
18857   vl_api_control_ping_t *mp_ping;
18858   int ret;
18859
18860   if (!vam->json_output)
18861     {
18862       print (vam->ofp, "VNI");
18863     }
18864
18865   M (ONE_EID_TABLE_VNI_DUMP, mp);
18866
18867   /* send it... */
18868   S (mp);
18869
18870   /* Use a control ping for synchronization */
18871   MPING (CONTROL_PING, mp_ping);
18872   S (mp_ping);
18873
18874   /* Wait for a reply... */
18875   W (ret);
18876   return ret;
18877 }
18878
18879 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18880
18881 static int
18882 api_one_eid_table_dump (vat_main_t * vam)
18883 {
18884   unformat_input_t *i = vam->input;
18885   vl_api_one_eid_table_dump_t *mp;
18886   vl_api_control_ping_t *mp_ping;
18887   struct in_addr ip4;
18888   struct in6_addr ip6;
18889   u8 mac[6];
18890   u8 eid_type = ~0, eid_set = 0;
18891   u32 prefix_length = ~0, t, vni = 0;
18892   u8 filter = 0;
18893   int ret;
18894   lisp_nsh_api_t nsh;
18895
18896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18897     {
18898       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18899         {
18900           eid_set = 1;
18901           eid_type = 0;
18902           prefix_length = t;
18903         }
18904       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18905         {
18906           eid_set = 1;
18907           eid_type = 1;
18908           prefix_length = t;
18909         }
18910       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18911         {
18912           eid_set = 1;
18913           eid_type = 2;
18914         }
18915       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18916         {
18917           eid_set = 1;
18918           eid_type = 3;
18919         }
18920       else if (unformat (i, "vni %d", &t))
18921         {
18922           vni = t;
18923         }
18924       else if (unformat (i, "local"))
18925         {
18926           filter = 1;
18927         }
18928       else if (unformat (i, "remote"))
18929         {
18930           filter = 2;
18931         }
18932       else
18933         {
18934           errmsg ("parse error '%U'", format_unformat_error, i);
18935           return -99;
18936         }
18937     }
18938
18939   if (!vam->json_output)
18940     {
18941       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18942              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18943     }
18944
18945   M (ONE_EID_TABLE_DUMP, mp);
18946
18947   mp->filter = filter;
18948   if (eid_set)
18949     {
18950       mp->eid_set = 1;
18951       mp->vni = htonl (vni);
18952       mp->eid_type = eid_type;
18953       switch (eid_type)
18954         {
18955         case 0:
18956           mp->prefix_length = prefix_length;
18957           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18958           break;
18959         case 1:
18960           mp->prefix_length = prefix_length;
18961           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18962           break;
18963         case 2:
18964           clib_memcpy (mp->eid, mac, sizeof (mac));
18965           break;
18966         case 3:
18967           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18968           break;
18969         default:
18970           errmsg ("unknown EID type %d!", eid_type);
18971           return -99;
18972         }
18973     }
18974
18975   /* send it... */
18976   S (mp);
18977
18978   /* Use a control ping for synchronization */
18979   MPING (CONTROL_PING, mp_ping);
18980   S (mp_ping);
18981
18982   /* Wait for a reply... */
18983   W (ret);
18984   return ret;
18985 }
18986
18987 #define api_lisp_eid_table_dump api_one_eid_table_dump
18988
18989 static int
18990 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18991 {
18992   unformat_input_t *i = vam->input;
18993   vl_api_gpe_fwd_entries_get_t *mp;
18994   u8 vni_set = 0;
18995   u32 vni = ~0;
18996   int ret;
18997
18998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18999     {
19000       if (unformat (i, "vni %d", &vni))
19001         {
19002           vni_set = 1;
19003         }
19004       else
19005         {
19006           errmsg ("parse error '%U'", format_unformat_error, i);
19007           return -99;
19008         }
19009     }
19010
19011   if (!vni_set)
19012     {
19013       errmsg ("vni not set!");
19014       return -99;
19015     }
19016
19017   if (!vam->json_output)
19018     {
19019       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19020              "leid", "reid");
19021     }
19022
19023   M (GPE_FWD_ENTRIES_GET, mp);
19024   mp->vni = clib_host_to_net_u32 (vni);
19025
19026   /* send it... */
19027   S (mp);
19028
19029   /* Wait for a reply... */
19030   W (ret);
19031   return ret;
19032 }
19033
19034 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19035 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19036 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19037 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19038 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19039 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19040 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19041 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19042
19043 static int
19044 api_one_adjacencies_get (vat_main_t * vam)
19045 {
19046   unformat_input_t *i = vam->input;
19047   vl_api_one_adjacencies_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, "%s %40s", "leid", "reid");
19074     }
19075
19076   M (ONE_ADJACENCIES_GET, mp);
19077   mp->vni = clib_host_to_net_u32 (vni);
19078
19079   /* send it... */
19080   S (mp);
19081
19082   /* Wait for a reply... */
19083   W (ret);
19084   return ret;
19085 }
19086
19087 #define api_lisp_adjacencies_get api_one_adjacencies_get
19088
19089 static int
19090 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19091 {
19092   unformat_input_t *i = vam->input;
19093   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19094   int ret;
19095   u8 ip_family_set = 0, is_ip4 = 1;
19096
19097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19098     {
19099       if (unformat (i, "ip4"))
19100         {
19101           ip_family_set = 1;
19102           is_ip4 = 1;
19103         }
19104       else if (unformat (i, "ip6"))
19105         {
19106           ip_family_set = 1;
19107           is_ip4 = 0;
19108         }
19109       else
19110         {
19111           errmsg ("parse error '%U'", format_unformat_error, i);
19112           return -99;
19113         }
19114     }
19115
19116   if (!ip_family_set)
19117     {
19118       errmsg ("ip family not set!");
19119       return -99;
19120     }
19121
19122   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19123   mp->is_ip4 = is_ip4;
19124
19125   /* send it... */
19126   S (mp);
19127
19128   /* Wait for a reply... */
19129   W (ret);
19130   return ret;
19131 }
19132
19133 static int
19134 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19135 {
19136   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19137   int ret;
19138
19139   if (!vam->json_output)
19140     {
19141       print (vam->ofp, "VNIs");
19142     }
19143
19144   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19145
19146   /* send it... */
19147   S (mp);
19148
19149   /* Wait for a reply... */
19150   W (ret);
19151   return ret;
19152 }
19153
19154 static int
19155 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19156 {
19157   unformat_input_t *i = vam->input;
19158   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19159   int ret = 0;
19160   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19161   struct in_addr ip4;
19162   struct in6_addr ip6;
19163   u32 table_id = 0, nh_sw_if_index = ~0;
19164
19165   clib_memset (&ip4, 0, sizeof (ip4));
19166   clib_memset (&ip6, 0, sizeof (ip6));
19167
19168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19169     {
19170       if (unformat (i, "del"))
19171         is_add = 0;
19172       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19173                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19174         {
19175           ip_set = 1;
19176           is_ip4 = 1;
19177         }
19178       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19179                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19180         {
19181           ip_set = 1;
19182           is_ip4 = 0;
19183         }
19184       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19185         {
19186           ip_set = 1;
19187           is_ip4 = 1;
19188           nh_sw_if_index = ~0;
19189         }
19190       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19191         {
19192           ip_set = 1;
19193           is_ip4 = 0;
19194           nh_sw_if_index = ~0;
19195         }
19196       else if (unformat (i, "table %d", &table_id))
19197         ;
19198       else
19199         {
19200           errmsg ("parse error '%U'", format_unformat_error, i);
19201           return -99;
19202         }
19203     }
19204
19205   if (!ip_set)
19206     {
19207       errmsg ("nh addr not set!");
19208       return -99;
19209     }
19210
19211   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19212   mp->is_add = is_add;
19213   mp->table_id = clib_host_to_net_u32 (table_id);
19214   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19215   mp->is_ip4 = is_ip4;
19216   if (is_ip4)
19217     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19218   else
19219     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19220
19221   /* send it... */
19222   S (mp);
19223
19224   /* Wait for a reply... */
19225   W (ret);
19226   return ret;
19227 }
19228
19229 static int
19230 api_one_map_server_dump (vat_main_t * vam)
19231 {
19232   vl_api_one_map_server_dump_t *mp;
19233   vl_api_control_ping_t *mp_ping;
19234   int ret;
19235
19236   if (!vam->json_output)
19237     {
19238       print (vam->ofp, "%=20s", "Map server");
19239     }
19240
19241   M (ONE_MAP_SERVER_DUMP, mp);
19242   /* send it... */
19243   S (mp);
19244
19245   /* Use a control ping for synchronization */
19246   MPING (CONTROL_PING, mp_ping);
19247   S (mp_ping);
19248
19249   /* Wait for a reply... */
19250   W (ret);
19251   return ret;
19252 }
19253
19254 #define api_lisp_map_server_dump api_one_map_server_dump
19255
19256 static int
19257 api_one_map_resolver_dump (vat_main_t * vam)
19258 {
19259   vl_api_one_map_resolver_dump_t *mp;
19260   vl_api_control_ping_t *mp_ping;
19261   int ret;
19262
19263   if (!vam->json_output)
19264     {
19265       print (vam->ofp, "%=20s", "Map resolver");
19266     }
19267
19268   M (ONE_MAP_RESOLVER_DUMP, mp);
19269   /* send it... */
19270   S (mp);
19271
19272   /* Use a control ping for synchronization */
19273   MPING (CONTROL_PING, mp_ping);
19274   S (mp_ping);
19275
19276   /* Wait for a reply... */
19277   W (ret);
19278   return ret;
19279 }
19280
19281 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19282
19283 static int
19284 api_one_stats_flush (vat_main_t * vam)
19285 {
19286   vl_api_one_stats_flush_t *mp;
19287   int ret = 0;
19288
19289   M (ONE_STATS_FLUSH, mp);
19290   S (mp);
19291   W (ret);
19292   return ret;
19293 }
19294
19295 static int
19296 api_one_stats_dump (vat_main_t * vam)
19297 {
19298   vl_api_one_stats_dump_t *mp;
19299   vl_api_control_ping_t *mp_ping;
19300   int ret;
19301
19302   M (ONE_STATS_DUMP, mp);
19303   /* send it... */
19304   S (mp);
19305
19306   /* Use a control ping for synchronization */
19307   MPING (CONTROL_PING, mp_ping);
19308   S (mp_ping);
19309
19310   /* Wait for a reply... */
19311   W (ret);
19312   return ret;
19313 }
19314
19315 static int
19316 api_show_one_status (vat_main_t * vam)
19317 {
19318   vl_api_show_one_status_t *mp;
19319   int ret;
19320
19321   if (!vam->json_output)
19322     {
19323       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19324     }
19325
19326   M (SHOW_ONE_STATUS, mp);
19327   /* send it... */
19328   S (mp);
19329   /* Wait for a reply... */
19330   W (ret);
19331   return ret;
19332 }
19333
19334 #define api_show_lisp_status api_show_one_status
19335
19336 static int
19337 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19338 {
19339   vl_api_gpe_fwd_entry_path_dump_t *mp;
19340   vl_api_control_ping_t *mp_ping;
19341   unformat_input_t *i = vam->input;
19342   u32 fwd_entry_index = ~0;
19343   int ret;
19344
19345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19346     {
19347       if (unformat (i, "index %d", &fwd_entry_index))
19348         ;
19349       else
19350         break;
19351     }
19352
19353   if (~0 == fwd_entry_index)
19354     {
19355       errmsg ("no index specified!");
19356       return -99;
19357     }
19358
19359   if (!vam->json_output)
19360     {
19361       print (vam->ofp, "first line");
19362     }
19363
19364   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19365
19366   /* send it... */
19367   S (mp);
19368   /* Use a control ping for synchronization */
19369   MPING (CONTROL_PING, mp_ping);
19370   S (mp_ping);
19371
19372   /* Wait for a reply... */
19373   W (ret);
19374   return ret;
19375 }
19376
19377 static int
19378 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19379 {
19380   vl_api_one_get_map_request_itr_rlocs_t *mp;
19381   int ret;
19382
19383   if (!vam->json_output)
19384     {
19385       print (vam->ofp, "%=20s", "itr-rlocs:");
19386     }
19387
19388   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19389   /* send it... */
19390   S (mp);
19391   /* Wait for a reply... */
19392   W (ret);
19393   return ret;
19394 }
19395
19396 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19397
19398 static int
19399 api_af_packet_create (vat_main_t * vam)
19400 {
19401   unformat_input_t *i = vam->input;
19402   vl_api_af_packet_create_t *mp;
19403   u8 *host_if_name = 0;
19404   u8 hw_addr[6];
19405   u8 random_hw_addr = 1;
19406   int ret;
19407
19408   clib_memset (hw_addr, 0, sizeof (hw_addr));
19409
19410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19411     {
19412       if (unformat (i, "name %s", &host_if_name))
19413         vec_add1 (host_if_name, 0);
19414       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19415         random_hw_addr = 0;
19416       else
19417         break;
19418     }
19419
19420   if (!vec_len (host_if_name))
19421     {
19422       errmsg ("host-interface name must be specified");
19423       return -99;
19424     }
19425
19426   if (vec_len (host_if_name) > 64)
19427     {
19428       errmsg ("host-interface name too long");
19429       return -99;
19430     }
19431
19432   M (AF_PACKET_CREATE, mp);
19433
19434   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19435   clib_memcpy (mp->hw_addr, hw_addr, 6);
19436   mp->use_random_hw_addr = random_hw_addr;
19437   vec_free (host_if_name);
19438
19439   S (mp);
19440
19441   /* *INDENT-OFF* */
19442   W2 (ret,
19443       ({
19444         if (ret == 0)
19445           fprintf (vam->ofp ? vam->ofp : stderr,
19446                    " new sw_if_index = %d\n", vam->sw_if_index);
19447       }));
19448   /* *INDENT-ON* */
19449   return ret;
19450 }
19451
19452 static int
19453 api_af_packet_delete (vat_main_t * vam)
19454 {
19455   unformat_input_t *i = vam->input;
19456   vl_api_af_packet_delete_t *mp;
19457   u8 *host_if_name = 0;
19458   int ret;
19459
19460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19461     {
19462       if (unformat (i, "name %s", &host_if_name))
19463         vec_add1 (host_if_name, 0);
19464       else
19465         break;
19466     }
19467
19468   if (!vec_len (host_if_name))
19469     {
19470       errmsg ("host-interface name must be specified");
19471       return -99;
19472     }
19473
19474   if (vec_len (host_if_name) > 64)
19475     {
19476       errmsg ("host-interface name too long");
19477       return -99;
19478     }
19479
19480   M (AF_PACKET_DELETE, mp);
19481
19482   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19483   vec_free (host_if_name);
19484
19485   S (mp);
19486   W (ret);
19487   return ret;
19488 }
19489
19490 static void vl_api_af_packet_details_t_handler
19491   (vl_api_af_packet_details_t * mp)
19492 {
19493   vat_main_t *vam = &vat_main;
19494
19495   print (vam->ofp, "%-16s %d",
19496          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19497 }
19498
19499 static void vl_api_af_packet_details_t_handler_json
19500   (vl_api_af_packet_details_t * mp)
19501 {
19502   vat_main_t *vam = &vat_main;
19503   vat_json_node_t *node = NULL;
19504
19505   if (VAT_JSON_ARRAY != vam->json_tree.type)
19506     {
19507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19508       vat_json_init_array (&vam->json_tree);
19509     }
19510   node = vat_json_array_add (&vam->json_tree);
19511
19512   vat_json_init_object (node);
19513   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19514   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19515 }
19516
19517 static int
19518 api_af_packet_dump (vat_main_t * vam)
19519 {
19520   vl_api_af_packet_dump_t *mp;
19521   vl_api_control_ping_t *mp_ping;
19522   int ret;
19523
19524   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19525   /* Get list of tap interfaces */
19526   M (AF_PACKET_DUMP, mp);
19527   S (mp);
19528
19529   /* Use a control ping for synchronization */
19530   MPING (CONTROL_PING, mp_ping);
19531   S (mp_ping);
19532
19533   W (ret);
19534   return ret;
19535 }
19536
19537 static int
19538 api_policer_add_del (vat_main_t * vam)
19539 {
19540   unformat_input_t *i = vam->input;
19541   vl_api_policer_add_del_t *mp;
19542   u8 is_add = 1;
19543   u8 *name = 0;
19544   u32 cir = 0;
19545   u32 eir = 0;
19546   u64 cb = 0;
19547   u64 eb = 0;
19548   u8 rate_type = 0;
19549   u8 round_type = 0;
19550   u8 type = 0;
19551   u8 color_aware = 0;
19552   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19553   int ret;
19554
19555   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19556   conform_action.dscp = 0;
19557   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19558   exceed_action.dscp = 0;
19559   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19560   violate_action.dscp = 0;
19561
19562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19563     {
19564       if (unformat (i, "del"))
19565         is_add = 0;
19566       else if (unformat (i, "name %s", &name))
19567         vec_add1 (name, 0);
19568       else if (unformat (i, "cir %u", &cir))
19569         ;
19570       else if (unformat (i, "eir %u", &eir))
19571         ;
19572       else if (unformat (i, "cb %u", &cb))
19573         ;
19574       else if (unformat (i, "eb %u", &eb))
19575         ;
19576       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19577                          &rate_type))
19578         ;
19579       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19580                          &round_type))
19581         ;
19582       else if (unformat (i, "type %U", unformat_policer_type, &type))
19583         ;
19584       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19585                          &conform_action))
19586         ;
19587       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19588                          &exceed_action))
19589         ;
19590       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19591                          &violate_action))
19592         ;
19593       else if (unformat (i, "color-aware"))
19594         color_aware = 1;
19595       else
19596         break;
19597     }
19598
19599   if (!vec_len (name))
19600     {
19601       errmsg ("policer name must be specified");
19602       return -99;
19603     }
19604
19605   if (vec_len (name) > 64)
19606     {
19607       errmsg ("policer name too long");
19608       return -99;
19609     }
19610
19611   M (POLICER_ADD_DEL, mp);
19612
19613   clib_memcpy (mp->name, name, vec_len (name));
19614   vec_free (name);
19615   mp->is_add = is_add;
19616   mp->cir = ntohl (cir);
19617   mp->eir = ntohl (eir);
19618   mp->cb = clib_net_to_host_u64 (cb);
19619   mp->eb = clib_net_to_host_u64 (eb);
19620   mp->rate_type = rate_type;
19621   mp->round_type = round_type;
19622   mp->type = type;
19623   mp->conform_action_type = conform_action.action_type;
19624   mp->conform_dscp = conform_action.dscp;
19625   mp->exceed_action_type = exceed_action.action_type;
19626   mp->exceed_dscp = exceed_action.dscp;
19627   mp->violate_action_type = violate_action.action_type;
19628   mp->violate_dscp = violate_action.dscp;
19629   mp->color_aware = color_aware;
19630
19631   S (mp);
19632   W (ret);
19633   return ret;
19634 }
19635
19636 static int
19637 api_policer_dump (vat_main_t * vam)
19638 {
19639   unformat_input_t *i = vam->input;
19640   vl_api_policer_dump_t *mp;
19641   vl_api_control_ping_t *mp_ping;
19642   u8 *match_name = 0;
19643   u8 match_name_valid = 0;
19644   int ret;
19645
19646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19647     {
19648       if (unformat (i, "name %s", &match_name))
19649         {
19650           vec_add1 (match_name, 0);
19651           match_name_valid = 1;
19652         }
19653       else
19654         break;
19655     }
19656
19657   M (POLICER_DUMP, mp);
19658   mp->match_name_valid = match_name_valid;
19659   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19660   vec_free (match_name);
19661   /* send it... */
19662   S (mp);
19663
19664   /* Use a control ping for synchronization */
19665   MPING (CONTROL_PING, mp_ping);
19666   S (mp_ping);
19667
19668   /* Wait for a reply... */
19669   W (ret);
19670   return ret;
19671 }
19672
19673 static int
19674 api_policer_classify_set_interface (vat_main_t * vam)
19675 {
19676   unformat_input_t *i = vam->input;
19677   vl_api_policer_classify_set_interface_t *mp;
19678   u32 sw_if_index;
19679   int sw_if_index_set;
19680   u32 ip4_table_index = ~0;
19681   u32 ip6_table_index = ~0;
19682   u32 l2_table_index = ~0;
19683   u8 is_add = 1;
19684   int ret;
19685
19686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19687     {
19688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19689         sw_if_index_set = 1;
19690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19691         sw_if_index_set = 1;
19692       else if (unformat (i, "del"))
19693         is_add = 0;
19694       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19695         ;
19696       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19697         ;
19698       else if (unformat (i, "l2-table %d", &l2_table_index))
19699         ;
19700       else
19701         {
19702           clib_warning ("parse error '%U'", format_unformat_error, i);
19703           return -99;
19704         }
19705     }
19706
19707   if (sw_if_index_set == 0)
19708     {
19709       errmsg ("missing interface name or sw_if_index");
19710       return -99;
19711     }
19712
19713   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19714
19715   mp->sw_if_index = ntohl (sw_if_index);
19716   mp->ip4_table_index = ntohl (ip4_table_index);
19717   mp->ip6_table_index = ntohl (ip6_table_index);
19718   mp->l2_table_index = ntohl (l2_table_index);
19719   mp->is_add = is_add;
19720
19721   S (mp);
19722   W (ret);
19723   return ret;
19724 }
19725
19726 static int
19727 api_policer_classify_dump (vat_main_t * vam)
19728 {
19729   unformat_input_t *i = vam->input;
19730   vl_api_policer_classify_dump_t *mp;
19731   vl_api_control_ping_t *mp_ping;
19732   u8 type = POLICER_CLASSIFY_N_TABLES;
19733   int ret;
19734
19735   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19736     ;
19737   else
19738     {
19739       errmsg ("classify table type must be specified");
19740       return -99;
19741     }
19742
19743   if (!vam->json_output)
19744     {
19745       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19746     }
19747
19748   M (POLICER_CLASSIFY_DUMP, mp);
19749   mp->type = type;
19750   /* send it... */
19751   S (mp);
19752
19753   /* Use a control ping for synchronization */
19754   MPING (CONTROL_PING, mp_ping);
19755   S (mp_ping);
19756
19757   /* Wait for a reply... */
19758   W (ret);
19759   return ret;
19760 }
19761
19762 static int
19763 api_netmap_create (vat_main_t * vam)
19764 {
19765   unformat_input_t *i = vam->input;
19766   vl_api_netmap_create_t *mp;
19767   u8 *if_name = 0;
19768   u8 hw_addr[6];
19769   u8 random_hw_addr = 1;
19770   u8 is_pipe = 0;
19771   u8 is_master = 0;
19772   int ret;
19773
19774   clib_memset (hw_addr, 0, sizeof (hw_addr));
19775
19776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19777     {
19778       if (unformat (i, "name %s", &if_name))
19779         vec_add1 (if_name, 0);
19780       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19781         random_hw_addr = 0;
19782       else if (unformat (i, "pipe"))
19783         is_pipe = 1;
19784       else if (unformat (i, "master"))
19785         is_master = 1;
19786       else if (unformat (i, "slave"))
19787         is_master = 0;
19788       else
19789         break;
19790     }
19791
19792   if (!vec_len (if_name))
19793     {
19794       errmsg ("interface name must be specified");
19795       return -99;
19796     }
19797
19798   if (vec_len (if_name) > 64)
19799     {
19800       errmsg ("interface name too long");
19801       return -99;
19802     }
19803
19804   M (NETMAP_CREATE, mp);
19805
19806   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19807   clib_memcpy (mp->hw_addr, hw_addr, 6);
19808   mp->use_random_hw_addr = random_hw_addr;
19809   mp->is_pipe = is_pipe;
19810   mp->is_master = is_master;
19811   vec_free (if_name);
19812
19813   S (mp);
19814   W (ret);
19815   return ret;
19816 }
19817
19818 static int
19819 api_netmap_delete (vat_main_t * vam)
19820 {
19821   unformat_input_t *i = vam->input;
19822   vl_api_netmap_delete_t *mp;
19823   u8 *if_name = 0;
19824   int ret;
19825
19826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19827     {
19828       if (unformat (i, "name %s", &if_name))
19829         vec_add1 (if_name, 0);
19830       else
19831         break;
19832     }
19833
19834   if (!vec_len (if_name))
19835     {
19836       errmsg ("interface name must be specified");
19837       return -99;
19838     }
19839
19840   if (vec_len (if_name) > 64)
19841     {
19842       errmsg ("interface name too long");
19843       return -99;
19844     }
19845
19846   M (NETMAP_DELETE, mp);
19847
19848   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19849   vec_free (if_name);
19850
19851   S (mp);
19852   W (ret);
19853   return ret;
19854 }
19855
19856 static void
19857 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19858 {
19859   if (fp->afi == IP46_TYPE_IP6)
19860     print (vam->ofp,
19861            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19862            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19863            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19864            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19865            format_ip6_address, fp->next_hop);
19866   else if (fp->afi == IP46_TYPE_IP4)
19867     print (vam->ofp,
19868            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19869            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19870            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19871            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19872            format_ip4_address, fp->next_hop);
19873 }
19874
19875 static void
19876 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19877                                  vl_api_fib_path_t * fp)
19878 {
19879   struct in_addr ip4;
19880   struct in6_addr ip6;
19881
19882   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19883   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19884   vat_json_object_add_uint (node, "is_local", fp->is_local);
19885   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19886   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19887   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19888   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19889   if (fp->afi == IP46_TYPE_IP4)
19890     {
19891       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19892       vat_json_object_add_ip4 (node, "next_hop", ip4);
19893     }
19894   else if (fp->afi == IP46_TYPE_IP6)
19895     {
19896       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19897       vat_json_object_add_ip6 (node, "next_hop", ip6);
19898     }
19899 }
19900
19901 static void
19902 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19903 {
19904   vat_main_t *vam = &vat_main;
19905   int count = ntohl (mp->mt_count);
19906   vl_api_fib_path_t *fp;
19907   i32 i;
19908
19909   print (vam->ofp, "[%d]: sw_if_index %d via:",
19910          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19911   fp = mp->mt_paths;
19912   for (i = 0; i < count; i++)
19913     {
19914       vl_api_mpls_fib_path_print (vam, fp);
19915       fp++;
19916     }
19917
19918   print (vam->ofp, "");
19919 }
19920
19921 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19922 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19923
19924 static void
19925 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19926 {
19927   vat_main_t *vam = &vat_main;
19928   vat_json_node_t *node = NULL;
19929   int count = ntohl (mp->mt_count);
19930   vl_api_fib_path_t *fp;
19931   i32 i;
19932
19933   if (VAT_JSON_ARRAY != vam->json_tree.type)
19934     {
19935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19936       vat_json_init_array (&vam->json_tree);
19937     }
19938   node = vat_json_array_add (&vam->json_tree);
19939
19940   vat_json_init_object (node);
19941   vat_json_object_add_uint (node, "tunnel_index",
19942                             ntohl (mp->mt_tunnel_index));
19943   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19944
19945   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19946
19947   fp = mp->mt_paths;
19948   for (i = 0; i < count; i++)
19949     {
19950       vl_api_mpls_fib_path_json_print (node, fp);
19951       fp++;
19952     }
19953 }
19954
19955 static int
19956 api_mpls_tunnel_dump (vat_main_t * vam)
19957 {
19958   vl_api_mpls_tunnel_dump_t *mp;
19959   vl_api_control_ping_t *mp_ping;
19960   u32 sw_if_index = ~0;
19961   int ret;
19962
19963   /* Parse args required to build the message */
19964   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19965     {
19966       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19967         ;
19968     }
19969
19970   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19971
19972   M (MPLS_TUNNEL_DUMP, mp);
19973   mp->sw_if_index = htonl (sw_if_index);
19974   S (mp);
19975
19976   /* Use a control ping for synchronization */
19977   MPING (CONTROL_PING, mp_ping);
19978   S (mp_ping);
19979
19980   W (ret);
19981   return ret;
19982 }
19983
19984 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19985 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19986
19987
19988 static void
19989 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19990 {
19991   vat_main_t *vam = &vat_main;
19992   int count = ntohl (mp->count);
19993   vl_api_fib_path_t *fp;
19994   int i;
19995
19996   print (vam->ofp,
19997          "table-id %d, label %u, ess_bit %u",
19998          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19999   fp = mp->path;
20000   for (i = 0; i < count; i++)
20001     {
20002       vl_api_mpls_fib_path_print (vam, fp);
20003       fp++;
20004     }
20005 }
20006
20007 static void vl_api_mpls_fib_details_t_handler_json
20008   (vl_api_mpls_fib_details_t * mp)
20009 {
20010   vat_main_t *vam = &vat_main;
20011   int count = ntohl (mp->count);
20012   vat_json_node_t *node = NULL;
20013   vl_api_fib_path_t *fp;
20014   int i;
20015
20016   if (VAT_JSON_ARRAY != vam->json_tree.type)
20017     {
20018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20019       vat_json_init_array (&vam->json_tree);
20020     }
20021   node = vat_json_array_add (&vam->json_tree);
20022
20023   vat_json_init_object (node);
20024   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20025   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20026   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20027   vat_json_object_add_uint (node, "path_count", count);
20028   fp = mp->path;
20029   for (i = 0; i < count; i++)
20030     {
20031       vl_api_mpls_fib_path_json_print (node, fp);
20032       fp++;
20033     }
20034 }
20035
20036 static int
20037 api_mpls_fib_dump (vat_main_t * vam)
20038 {
20039   vl_api_mpls_fib_dump_t *mp;
20040   vl_api_control_ping_t *mp_ping;
20041   int ret;
20042
20043   M (MPLS_FIB_DUMP, mp);
20044   S (mp);
20045
20046   /* Use a control ping for synchronization */
20047   MPING (CONTROL_PING, mp_ping);
20048   S (mp_ping);
20049
20050   W (ret);
20051   return ret;
20052 }
20053
20054 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20055 #define vl_api_ip_fib_details_t_print vl_noop_handler
20056
20057 static void
20058 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20059 {
20060   vat_main_t *vam = &vat_main;
20061   int count = ntohl (mp->count);
20062   vl_api_fib_path_t *fp;
20063   int i;
20064
20065   print (vam->ofp,
20066          "table-id %d, prefix %U/%d stats-index %d",
20067          ntohl (mp->table_id), format_ip4_address, mp->address,
20068          mp->address_length, ntohl (mp->stats_index));
20069   fp = mp->path;
20070   for (i = 0; i < count; i++)
20071     {
20072       if (fp->afi == IP46_TYPE_IP6)
20073         print (vam->ofp,
20074                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20075                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20076                "next_hop_table %d",
20077                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20078                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20079                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20080       else if (fp->afi == IP46_TYPE_IP4)
20081         print (vam->ofp,
20082                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20083                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20084                "next_hop_table %d",
20085                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20086                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20087                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20088       fp++;
20089     }
20090 }
20091
20092 static void vl_api_ip_fib_details_t_handler_json
20093   (vl_api_ip_fib_details_t * mp)
20094 {
20095   vat_main_t *vam = &vat_main;
20096   int count = ntohl (mp->count);
20097   vat_json_node_t *node = NULL;
20098   struct in_addr ip4;
20099   struct in6_addr ip6;
20100   vl_api_fib_path_t *fp;
20101   int i;
20102
20103   if (VAT_JSON_ARRAY != vam->json_tree.type)
20104     {
20105       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20106       vat_json_init_array (&vam->json_tree);
20107     }
20108   node = vat_json_array_add (&vam->json_tree);
20109
20110   vat_json_init_object (node);
20111   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20112   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20113   vat_json_object_add_ip4 (node, "prefix", ip4);
20114   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20115   vat_json_object_add_uint (node, "path_count", count);
20116   fp = mp->path;
20117   for (i = 0; i < count; i++)
20118     {
20119       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20120       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20121       vat_json_object_add_uint (node, "is_local", fp->is_local);
20122       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20123       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20124       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20125       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20126       if (fp->afi == IP46_TYPE_IP4)
20127         {
20128           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20129           vat_json_object_add_ip4 (node, "next_hop", ip4);
20130         }
20131       else if (fp->afi == IP46_TYPE_IP6)
20132         {
20133           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20134           vat_json_object_add_ip6 (node, "next_hop", ip6);
20135         }
20136     }
20137 }
20138
20139 static int
20140 api_ip_fib_dump (vat_main_t * vam)
20141 {
20142   vl_api_ip_fib_dump_t *mp;
20143   vl_api_control_ping_t *mp_ping;
20144   int ret;
20145
20146   M (IP_FIB_DUMP, mp);
20147   S (mp);
20148
20149   /* Use a control ping for synchronization */
20150   MPING (CONTROL_PING, mp_ping);
20151   S (mp_ping);
20152
20153   W (ret);
20154   return ret;
20155 }
20156
20157 static int
20158 api_ip_mfib_dump (vat_main_t * vam)
20159 {
20160   vl_api_ip_mfib_dump_t *mp;
20161   vl_api_control_ping_t *mp_ping;
20162   int ret;
20163
20164   M (IP_MFIB_DUMP, mp);
20165   S (mp);
20166
20167   /* Use a control ping for synchronization */
20168   MPING (CONTROL_PING, mp_ping);
20169   S (mp_ping);
20170
20171   W (ret);
20172   return ret;
20173 }
20174
20175 static void vl_api_ip_neighbor_details_t_handler
20176   (vl_api_ip_neighbor_details_t * mp)
20177 {
20178   vat_main_t *vam = &vat_main;
20179
20180   print (vam->ofp, "%c %U %U",
20181          (mp->is_static) ? 'S' : 'D',
20182          format_ethernet_address, &mp->mac_address,
20183          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20184          &mp->ip_address);
20185 }
20186
20187 static void vl_api_ip_neighbor_details_t_handler_json
20188   (vl_api_ip_neighbor_details_t * mp)
20189 {
20190
20191   vat_main_t *vam = &vat_main;
20192   vat_json_node_t *node;
20193   struct in_addr ip4;
20194   struct in6_addr ip6;
20195
20196   if (VAT_JSON_ARRAY != vam->json_tree.type)
20197     {
20198       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20199       vat_json_init_array (&vam->json_tree);
20200     }
20201   node = vat_json_array_add (&vam->json_tree);
20202
20203   vat_json_init_object (node);
20204   vat_json_object_add_string_copy (node, "flag",
20205                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20206                                    "dynamic");
20207
20208   vat_json_object_add_string_copy (node, "link_layer",
20209                                    format (0, "%U", format_ethernet_address,
20210                                            &mp->mac_address));
20211
20212   if (mp->is_ipv6)
20213     {
20214       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20215       vat_json_object_add_ip6 (node, "ip_address", ip6);
20216     }
20217   else
20218     {
20219       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20220       vat_json_object_add_ip4 (node, "ip_address", ip4);
20221     }
20222 }
20223
20224 static int
20225 api_ip_neighbor_dump (vat_main_t * vam)
20226 {
20227   unformat_input_t *i = vam->input;
20228   vl_api_ip_neighbor_dump_t *mp;
20229   vl_api_control_ping_t *mp_ping;
20230   u8 is_ipv6 = 0;
20231   u32 sw_if_index = ~0;
20232   int ret;
20233
20234   /* Parse args required to build the message */
20235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20236     {
20237       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20238         ;
20239       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20240         ;
20241       else if (unformat (i, "ip6"))
20242         is_ipv6 = 1;
20243       else
20244         break;
20245     }
20246
20247   if (sw_if_index == ~0)
20248     {
20249       errmsg ("missing interface name or sw_if_index");
20250       return -99;
20251     }
20252
20253   M (IP_NEIGHBOR_DUMP, mp);
20254   mp->is_ipv6 = (u8) is_ipv6;
20255   mp->sw_if_index = ntohl (sw_if_index);
20256   S (mp);
20257
20258   /* Use a control ping for synchronization */
20259   MPING (CONTROL_PING, mp_ping);
20260   S (mp_ping);
20261
20262   W (ret);
20263   return ret;
20264 }
20265
20266 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20267 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20268
20269 static void
20270 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20271 {
20272   vat_main_t *vam = &vat_main;
20273   int count = ntohl (mp->count);
20274   vl_api_fib_path_t *fp;
20275   int i;
20276
20277   print (vam->ofp,
20278          "table-id %d, prefix %U/%d stats-index %d",
20279          ntohl (mp->table_id), format_ip6_address, mp->address,
20280          mp->address_length, ntohl (mp->stats_index));
20281   fp = mp->path;
20282   for (i = 0; i < count; i++)
20283     {
20284       if (fp->afi == IP46_TYPE_IP6)
20285         print (vam->ofp,
20286                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20287                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20288                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20289                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20290                format_ip6_address, fp->next_hop);
20291       else if (fp->afi == IP46_TYPE_IP4)
20292         print (vam->ofp,
20293                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20294                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20295                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20296                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20297                format_ip4_address, fp->next_hop);
20298       fp++;
20299     }
20300 }
20301
20302 static void vl_api_ip6_fib_details_t_handler_json
20303   (vl_api_ip6_fib_details_t * mp)
20304 {
20305   vat_main_t *vam = &vat_main;
20306   int count = ntohl (mp->count);
20307   vat_json_node_t *node = NULL;
20308   struct in_addr ip4;
20309   struct in6_addr ip6;
20310   vl_api_fib_path_t *fp;
20311   int i;
20312
20313   if (VAT_JSON_ARRAY != vam->json_tree.type)
20314     {
20315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20316       vat_json_init_array (&vam->json_tree);
20317     }
20318   node = vat_json_array_add (&vam->json_tree);
20319
20320   vat_json_init_object (node);
20321   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20322   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20323   vat_json_object_add_ip6 (node, "prefix", ip6);
20324   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20325   vat_json_object_add_uint (node, "path_count", count);
20326   fp = mp->path;
20327   for (i = 0; i < count; i++)
20328     {
20329       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20330       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20331       vat_json_object_add_uint (node, "is_local", fp->is_local);
20332       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20333       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20334       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20335       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20336       if (fp->afi == IP46_TYPE_IP4)
20337         {
20338           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20339           vat_json_object_add_ip4 (node, "next_hop", ip4);
20340         }
20341       else if (fp->afi == IP46_TYPE_IP6)
20342         {
20343           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20344           vat_json_object_add_ip6 (node, "next_hop", ip6);
20345         }
20346     }
20347 }
20348
20349 static int
20350 api_ip6_fib_dump (vat_main_t * vam)
20351 {
20352   vl_api_ip6_fib_dump_t *mp;
20353   vl_api_control_ping_t *mp_ping;
20354   int ret;
20355
20356   M (IP6_FIB_DUMP, mp);
20357   S (mp);
20358
20359   /* Use a control ping for synchronization */
20360   MPING (CONTROL_PING, mp_ping);
20361   S (mp_ping);
20362
20363   W (ret);
20364   return ret;
20365 }
20366
20367 static int
20368 api_ip6_mfib_dump (vat_main_t * vam)
20369 {
20370   vl_api_ip6_mfib_dump_t *mp;
20371   vl_api_control_ping_t *mp_ping;
20372   int ret;
20373
20374   M (IP6_MFIB_DUMP, mp);
20375   S (mp);
20376
20377   /* Use a control ping for synchronization */
20378   MPING (CONTROL_PING, mp_ping);
20379   S (mp_ping);
20380
20381   W (ret);
20382   return ret;
20383 }
20384
20385 int
20386 api_classify_table_ids (vat_main_t * vam)
20387 {
20388   vl_api_classify_table_ids_t *mp;
20389   int ret;
20390
20391   /* Construct the API message */
20392   M (CLASSIFY_TABLE_IDS, mp);
20393   mp->context = 0;
20394
20395   S (mp);
20396   W (ret);
20397   return ret;
20398 }
20399
20400 int
20401 api_classify_table_by_interface (vat_main_t * vam)
20402 {
20403   unformat_input_t *input = vam->input;
20404   vl_api_classify_table_by_interface_t *mp;
20405
20406   u32 sw_if_index = ~0;
20407   int ret;
20408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20409     {
20410       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20411         ;
20412       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20413         ;
20414       else
20415         break;
20416     }
20417   if (sw_if_index == ~0)
20418     {
20419       errmsg ("missing interface name or sw_if_index");
20420       return -99;
20421     }
20422
20423   /* Construct the API message */
20424   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20425   mp->context = 0;
20426   mp->sw_if_index = ntohl (sw_if_index);
20427
20428   S (mp);
20429   W (ret);
20430   return ret;
20431 }
20432
20433 int
20434 api_classify_table_info (vat_main_t * vam)
20435 {
20436   unformat_input_t *input = vam->input;
20437   vl_api_classify_table_info_t *mp;
20438
20439   u32 table_id = ~0;
20440   int ret;
20441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20442     {
20443       if (unformat (input, "table_id %d", &table_id))
20444         ;
20445       else
20446         break;
20447     }
20448   if (table_id == ~0)
20449     {
20450       errmsg ("missing table id");
20451       return -99;
20452     }
20453
20454   /* Construct the API message */
20455   M (CLASSIFY_TABLE_INFO, mp);
20456   mp->context = 0;
20457   mp->table_id = ntohl (table_id);
20458
20459   S (mp);
20460   W (ret);
20461   return ret;
20462 }
20463
20464 int
20465 api_classify_session_dump (vat_main_t * vam)
20466 {
20467   unformat_input_t *input = vam->input;
20468   vl_api_classify_session_dump_t *mp;
20469   vl_api_control_ping_t *mp_ping;
20470
20471   u32 table_id = ~0;
20472   int ret;
20473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20474     {
20475       if (unformat (input, "table_id %d", &table_id))
20476         ;
20477       else
20478         break;
20479     }
20480   if (table_id == ~0)
20481     {
20482       errmsg ("missing table id");
20483       return -99;
20484     }
20485
20486   /* Construct the API message */
20487   M (CLASSIFY_SESSION_DUMP, mp);
20488   mp->context = 0;
20489   mp->table_id = ntohl (table_id);
20490   S (mp);
20491
20492   /* Use a control ping for synchronization */
20493   MPING (CONTROL_PING, mp_ping);
20494   S (mp_ping);
20495
20496   W (ret);
20497   return ret;
20498 }
20499
20500 static void
20501 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20502 {
20503   vat_main_t *vam = &vat_main;
20504
20505   print (vam->ofp, "collector_address %U, collector_port %d, "
20506          "src_address %U, vrf_id %d, path_mtu %u, "
20507          "template_interval %u, udp_checksum %d",
20508          format_ip4_address, mp->collector_address,
20509          ntohs (mp->collector_port),
20510          format_ip4_address, mp->src_address,
20511          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20512          ntohl (mp->template_interval), mp->udp_checksum);
20513
20514   vam->retval = 0;
20515   vam->result_ready = 1;
20516 }
20517
20518 static void
20519   vl_api_ipfix_exporter_details_t_handler_json
20520   (vl_api_ipfix_exporter_details_t * mp)
20521 {
20522   vat_main_t *vam = &vat_main;
20523   vat_json_node_t node;
20524   struct in_addr collector_address;
20525   struct in_addr src_address;
20526
20527   vat_json_init_object (&node);
20528   clib_memcpy (&collector_address, &mp->collector_address,
20529                sizeof (collector_address));
20530   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20531   vat_json_object_add_uint (&node, "collector_port",
20532                             ntohs (mp->collector_port));
20533   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20534   vat_json_object_add_ip4 (&node, "src_address", src_address);
20535   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20536   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20537   vat_json_object_add_uint (&node, "template_interval",
20538                             ntohl (mp->template_interval));
20539   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20540
20541   vat_json_print (vam->ofp, &node);
20542   vat_json_free (&node);
20543   vam->retval = 0;
20544   vam->result_ready = 1;
20545 }
20546
20547 int
20548 api_ipfix_exporter_dump (vat_main_t * vam)
20549 {
20550   vl_api_ipfix_exporter_dump_t *mp;
20551   int ret;
20552
20553   /* Construct the API message */
20554   M (IPFIX_EXPORTER_DUMP, mp);
20555   mp->context = 0;
20556
20557   S (mp);
20558   W (ret);
20559   return ret;
20560 }
20561
20562 static int
20563 api_ipfix_classify_stream_dump (vat_main_t * vam)
20564 {
20565   vl_api_ipfix_classify_stream_dump_t *mp;
20566   int ret;
20567
20568   /* Construct the API message */
20569   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20570   mp->context = 0;
20571
20572   S (mp);
20573   W (ret);
20574   return ret;
20575   /* NOTREACHED */
20576   return 0;
20577 }
20578
20579 static void
20580   vl_api_ipfix_classify_stream_details_t_handler
20581   (vl_api_ipfix_classify_stream_details_t * mp)
20582 {
20583   vat_main_t *vam = &vat_main;
20584   print (vam->ofp, "domain_id %d, src_port %d",
20585          ntohl (mp->domain_id), ntohs (mp->src_port));
20586   vam->retval = 0;
20587   vam->result_ready = 1;
20588 }
20589
20590 static void
20591   vl_api_ipfix_classify_stream_details_t_handler_json
20592   (vl_api_ipfix_classify_stream_details_t * mp)
20593 {
20594   vat_main_t *vam = &vat_main;
20595   vat_json_node_t node;
20596
20597   vat_json_init_object (&node);
20598   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20599   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20600
20601   vat_json_print (vam->ofp, &node);
20602   vat_json_free (&node);
20603   vam->retval = 0;
20604   vam->result_ready = 1;
20605 }
20606
20607 static int
20608 api_ipfix_classify_table_dump (vat_main_t * vam)
20609 {
20610   vl_api_ipfix_classify_table_dump_t *mp;
20611   vl_api_control_ping_t *mp_ping;
20612   int ret;
20613
20614   if (!vam->json_output)
20615     {
20616       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20617              "transport_protocol");
20618     }
20619
20620   /* Construct the API message */
20621   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20622
20623   /* send it... */
20624   S (mp);
20625
20626   /* Use a control ping for synchronization */
20627   MPING (CONTROL_PING, mp_ping);
20628   S (mp_ping);
20629
20630   W (ret);
20631   return ret;
20632 }
20633
20634 static void
20635   vl_api_ipfix_classify_table_details_t_handler
20636   (vl_api_ipfix_classify_table_details_t * mp)
20637 {
20638   vat_main_t *vam = &vat_main;
20639   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20640          mp->transport_protocol);
20641 }
20642
20643 static void
20644   vl_api_ipfix_classify_table_details_t_handler_json
20645   (vl_api_ipfix_classify_table_details_t * mp)
20646 {
20647   vat_json_node_t *node = NULL;
20648   vat_main_t *vam = &vat_main;
20649
20650   if (VAT_JSON_ARRAY != vam->json_tree.type)
20651     {
20652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20653       vat_json_init_array (&vam->json_tree);
20654     }
20655
20656   node = vat_json_array_add (&vam->json_tree);
20657   vat_json_init_object (node);
20658
20659   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20660   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20661   vat_json_object_add_uint (node, "transport_protocol",
20662                             mp->transport_protocol);
20663 }
20664
20665 static int
20666 api_sw_interface_span_enable_disable (vat_main_t * vam)
20667 {
20668   unformat_input_t *i = vam->input;
20669   vl_api_sw_interface_span_enable_disable_t *mp;
20670   u32 src_sw_if_index = ~0;
20671   u32 dst_sw_if_index = ~0;
20672   u8 state = 3;
20673   int ret;
20674   u8 is_l2 = 0;
20675
20676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20677     {
20678       if (unformat
20679           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20680         ;
20681       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20682         ;
20683       else
20684         if (unformat
20685             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20686         ;
20687       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20688         ;
20689       else if (unformat (i, "disable"))
20690         state = 0;
20691       else if (unformat (i, "rx"))
20692         state = 1;
20693       else if (unformat (i, "tx"))
20694         state = 2;
20695       else if (unformat (i, "both"))
20696         state = 3;
20697       else if (unformat (i, "l2"))
20698         is_l2 = 1;
20699       else
20700         break;
20701     }
20702
20703   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20704
20705   mp->sw_if_index_from = htonl (src_sw_if_index);
20706   mp->sw_if_index_to = htonl (dst_sw_if_index);
20707   mp->state = state;
20708   mp->is_l2 = is_l2;
20709
20710   S (mp);
20711   W (ret);
20712   return ret;
20713 }
20714
20715 static void
20716 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20717                                             * mp)
20718 {
20719   vat_main_t *vam = &vat_main;
20720   u8 *sw_if_from_name = 0;
20721   u8 *sw_if_to_name = 0;
20722   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20723   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20724   char *states[] = { "none", "rx", "tx", "both" };
20725   hash_pair_t *p;
20726
20727   /* *INDENT-OFF* */
20728   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20729   ({
20730     if ((u32) p->value[0] == sw_if_index_from)
20731       {
20732         sw_if_from_name = (u8 *)(p->key);
20733         if (sw_if_to_name)
20734           break;
20735       }
20736     if ((u32) p->value[0] == sw_if_index_to)
20737       {
20738         sw_if_to_name = (u8 *)(p->key);
20739         if (sw_if_from_name)
20740           break;
20741       }
20742   }));
20743   /* *INDENT-ON* */
20744   print (vam->ofp, "%20s => %20s (%s) %s",
20745          sw_if_from_name, sw_if_to_name, states[mp->state],
20746          mp->is_l2 ? "l2" : "device");
20747 }
20748
20749 static void
20750   vl_api_sw_interface_span_details_t_handler_json
20751   (vl_api_sw_interface_span_details_t * mp)
20752 {
20753   vat_main_t *vam = &vat_main;
20754   vat_json_node_t *node = NULL;
20755   u8 *sw_if_from_name = 0;
20756   u8 *sw_if_to_name = 0;
20757   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20758   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20759   hash_pair_t *p;
20760
20761   /* *INDENT-OFF* */
20762   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20763   ({
20764     if ((u32) p->value[0] == sw_if_index_from)
20765       {
20766         sw_if_from_name = (u8 *)(p->key);
20767         if (sw_if_to_name)
20768           break;
20769       }
20770     if ((u32) p->value[0] == sw_if_index_to)
20771       {
20772         sw_if_to_name = (u8 *)(p->key);
20773         if (sw_if_from_name)
20774           break;
20775       }
20776   }));
20777   /* *INDENT-ON* */
20778
20779   if (VAT_JSON_ARRAY != vam->json_tree.type)
20780     {
20781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20782       vat_json_init_array (&vam->json_tree);
20783     }
20784   node = vat_json_array_add (&vam->json_tree);
20785
20786   vat_json_init_object (node);
20787   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20788   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20789   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20790   if (0 != sw_if_to_name)
20791     {
20792       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20793     }
20794   vat_json_object_add_uint (node, "state", mp->state);
20795   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20796 }
20797
20798 static int
20799 api_sw_interface_span_dump (vat_main_t * vam)
20800 {
20801   unformat_input_t *input = vam->input;
20802   vl_api_sw_interface_span_dump_t *mp;
20803   vl_api_control_ping_t *mp_ping;
20804   u8 is_l2 = 0;
20805   int ret;
20806
20807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20808     {
20809       if (unformat (input, "l2"))
20810         is_l2 = 1;
20811       else
20812         break;
20813     }
20814
20815   M (SW_INTERFACE_SPAN_DUMP, mp);
20816   mp->is_l2 = is_l2;
20817   S (mp);
20818
20819   /* Use a control ping for synchronization */
20820   MPING (CONTROL_PING, mp_ping);
20821   S (mp_ping);
20822
20823   W (ret);
20824   return ret;
20825 }
20826
20827 int
20828 api_pg_create_interface (vat_main_t * vam)
20829 {
20830   unformat_input_t *input = vam->input;
20831   vl_api_pg_create_interface_t *mp;
20832
20833   u32 if_id = ~0;
20834   int ret;
20835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20836     {
20837       if (unformat (input, "if_id %d", &if_id))
20838         ;
20839       else
20840         break;
20841     }
20842   if (if_id == ~0)
20843     {
20844       errmsg ("missing pg interface index");
20845       return -99;
20846     }
20847
20848   /* Construct the API message */
20849   M (PG_CREATE_INTERFACE, mp);
20850   mp->context = 0;
20851   mp->interface_id = ntohl (if_id);
20852
20853   S (mp);
20854   W (ret);
20855   return ret;
20856 }
20857
20858 int
20859 api_pg_capture (vat_main_t * vam)
20860 {
20861   unformat_input_t *input = vam->input;
20862   vl_api_pg_capture_t *mp;
20863
20864   u32 if_id = ~0;
20865   u8 enable = 1;
20866   u32 count = 1;
20867   u8 pcap_file_set = 0;
20868   u8 *pcap_file = 0;
20869   int ret;
20870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20871     {
20872       if (unformat (input, "if_id %d", &if_id))
20873         ;
20874       else if (unformat (input, "pcap %s", &pcap_file))
20875         pcap_file_set = 1;
20876       else if (unformat (input, "count %d", &count))
20877         ;
20878       else if (unformat (input, "disable"))
20879         enable = 0;
20880       else
20881         break;
20882     }
20883   if (if_id == ~0)
20884     {
20885       errmsg ("missing pg interface index");
20886       return -99;
20887     }
20888   if (pcap_file_set > 0)
20889     {
20890       if (vec_len (pcap_file) > 255)
20891         {
20892           errmsg ("pcap file name is too long");
20893           return -99;
20894         }
20895     }
20896
20897   u32 name_len = vec_len (pcap_file);
20898   /* Construct the API message */
20899   M (PG_CAPTURE, mp);
20900   mp->context = 0;
20901   mp->interface_id = ntohl (if_id);
20902   mp->is_enabled = enable;
20903   mp->count = ntohl (count);
20904   mp->pcap_name_length = ntohl (name_len);
20905   if (pcap_file_set != 0)
20906     {
20907       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20908     }
20909   vec_free (pcap_file);
20910
20911   S (mp);
20912   W (ret);
20913   return ret;
20914 }
20915
20916 int
20917 api_pg_enable_disable (vat_main_t * vam)
20918 {
20919   unformat_input_t *input = vam->input;
20920   vl_api_pg_enable_disable_t *mp;
20921
20922   u8 enable = 1;
20923   u8 stream_name_set = 0;
20924   u8 *stream_name = 0;
20925   int ret;
20926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20927     {
20928       if (unformat (input, "stream %s", &stream_name))
20929         stream_name_set = 1;
20930       else if (unformat (input, "disable"))
20931         enable = 0;
20932       else
20933         break;
20934     }
20935
20936   if (stream_name_set > 0)
20937     {
20938       if (vec_len (stream_name) > 255)
20939         {
20940           errmsg ("stream name too long");
20941           return -99;
20942         }
20943     }
20944
20945   u32 name_len = vec_len (stream_name);
20946   /* Construct the API message */
20947   M (PG_ENABLE_DISABLE, mp);
20948   mp->context = 0;
20949   mp->is_enabled = enable;
20950   if (stream_name_set != 0)
20951     {
20952       mp->stream_name_length = ntohl (name_len);
20953       clib_memcpy (mp->stream_name, stream_name, name_len);
20954     }
20955   vec_free (stream_name);
20956
20957   S (mp);
20958   W (ret);
20959   return ret;
20960 }
20961
20962 int
20963 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20964 {
20965   unformat_input_t *input = vam->input;
20966   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20967
20968   u16 *low_ports = 0;
20969   u16 *high_ports = 0;
20970   u16 this_low;
20971   u16 this_hi;
20972   ip4_address_t ip4_addr;
20973   ip6_address_t ip6_addr;
20974   u32 length;
20975   u32 tmp, tmp2;
20976   u8 prefix_set = 0;
20977   u32 vrf_id = ~0;
20978   u8 is_add = 1;
20979   u8 is_ipv6 = 0;
20980   int ret;
20981
20982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20983     {
20984       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20985         {
20986           prefix_set = 1;
20987         }
20988       else
20989         if (unformat
20990             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20991         {
20992           prefix_set = 1;
20993           is_ipv6 = 1;
20994         }
20995       else if (unformat (input, "vrf %d", &vrf_id))
20996         ;
20997       else if (unformat (input, "del"))
20998         is_add = 0;
20999       else if (unformat (input, "port %d", &tmp))
21000         {
21001           if (tmp == 0 || tmp > 65535)
21002             {
21003               errmsg ("port %d out of range", tmp);
21004               return -99;
21005             }
21006           this_low = tmp;
21007           this_hi = this_low + 1;
21008           vec_add1 (low_ports, this_low);
21009           vec_add1 (high_ports, this_hi);
21010         }
21011       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21012         {
21013           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21014             {
21015               errmsg ("incorrect range parameters");
21016               return -99;
21017             }
21018           this_low = tmp;
21019           /* Note: in debug CLI +1 is added to high before
21020              passing to real fn that does "the work"
21021              (ip_source_and_port_range_check_add_del).
21022              This fn is a wrapper around the binary API fn a
21023              control plane will call, which expects this increment
21024              to have occurred. Hence letting the binary API control
21025              plane fn do the increment for consistency between VAT
21026              and other control planes.
21027            */
21028           this_hi = tmp2;
21029           vec_add1 (low_ports, this_low);
21030           vec_add1 (high_ports, this_hi);
21031         }
21032       else
21033         break;
21034     }
21035
21036   if (prefix_set == 0)
21037     {
21038       errmsg ("<address>/<mask> not specified");
21039       return -99;
21040     }
21041
21042   if (vrf_id == ~0)
21043     {
21044       errmsg ("VRF ID required, not specified");
21045       return -99;
21046     }
21047
21048   if (vrf_id == 0)
21049     {
21050       errmsg
21051         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21052       return -99;
21053     }
21054
21055   if (vec_len (low_ports) == 0)
21056     {
21057       errmsg ("At least one port or port range required");
21058       return -99;
21059     }
21060
21061   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21062
21063   mp->is_add = is_add;
21064
21065   if (is_ipv6)
21066     {
21067       mp->is_ipv6 = 1;
21068       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21069     }
21070   else
21071     {
21072       mp->is_ipv6 = 0;
21073       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21074     }
21075
21076   mp->mask_length = length;
21077   mp->number_of_ranges = vec_len (low_ports);
21078
21079   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21080   vec_free (low_ports);
21081
21082   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21083   vec_free (high_ports);
21084
21085   mp->vrf_id = ntohl (vrf_id);
21086
21087   S (mp);
21088   W (ret);
21089   return ret;
21090 }
21091
21092 int
21093 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21094 {
21095   unformat_input_t *input = vam->input;
21096   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21097   u32 sw_if_index = ~0;
21098   int vrf_set = 0;
21099   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21100   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21101   u8 is_add = 1;
21102   int ret;
21103
21104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21105     {
21106       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21107         ;
21108       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21109         ;
21110       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21111         vrf_set = 1;
21112       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21113         vrf_set = 1;
21114       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21115         vrf_set = 1;
21116       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21117         vrf_set = 1;
21118       else if (unformat (input, "del"))
21119         is_add = 0;
21120       else
21121         break;
21122     }
21123
21124   if (sw_if_index == ~0)
21125     {
21126       errmsg ("Interface required but not specified");
21127       return -99;
21128     }
21129
21130   if (vrf_set == 0)
21131     {
21132       errmsg ("VRF ID required but not specified");
21133       return -99;
21134     }
21135
21136   if (tcp_out_vrf_id == 0
21137       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21138     {
21139       errmsg
21140         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21141       return -99;
21142     }
21143
21144   /* Construct the API message */
21145   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21146
21147   mp->sw_if_index = ntohl (sw_if_index);
21148   mp->is_add = is_add;
21149   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21150   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21151   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21152   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21153
21154   /* send it... */
21155   S (mp);
21156
21157   /* Wait for a reply... */
21158   W (ret);
21159   return ret;
21160 }
21161
21162 static int
21163 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21164 {
21165   unformat_input_t *i = vam->input;
21166   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21167   u32 local_sa_id = 0;
21168   u32 remote_sa_id = 0;
21169   ip4_address_t src_address;
21170   ip4_address_t dst_address;
21171   u8 is_add = 1;
21172   int ret;
21173
21174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21175     {
21176       if (unformat (i, "local_sa %d", &local_sa_id))
21177         ;
21178       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21179         ;
21180       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21181         ;
21182       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21183         ;
21184       else if (unformat (i, "del"))
21185         is_add = 0;
21186       else
21187         {
21188           clib_warning ("parse error '%U'", format_unformat_error, i);
21189           return -99;
21190         }
21191     }
21192
21193   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21194
21195   mp->local_sa_id = ntohl (local_sa_id);
21196   mp->remote_sa_id = ntohl (remote_sa_id);
21197   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21198   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21199   mp->is_add = is_add;
21200
21201   S (mp);
21202   W (ret);
21203   return ret;
21204 }
21205
21206 static int
21207 api_set_punt (vat_main_t * vam)
21208 {
21209   unformat_input_t *i = vam->input;
21210   vl_api_set_punt_t *mp;
21211   u32 ipv = ~0;
21212   u32 protocol = ~0;
21213   u32 port = ~0;
21214   int is_add = 1;
21215   int ret;
21216
21217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21218     {
21219       if (unformat (i, "ip %d", &ipv))
21220         ;
21221       else if (unformat (i, "protocol %d", &protocol))
21222         ;
21223       else if (unformat (i, "port %d", &port))
21224         ;
21225       else if (unformat (i, "del"))
21226         is_add = 0;
21227       else
21228         {
21229           clib_warning ("parse error '%U'", format_unformat_error, i);
21230           return -99;
21231         }
21232     }
21233
21234   M (SET_PUNT, mp);
21235
21236   mp->is_add = (u8) is_add;
21237   mp->punt.ipv = (u8) ipv;
21238   mp->punt.l4_protocol = (u8) protocol;
21239   mp->punt.l4_port = htons ((u16) port);
21240
21241   S (mp);
21242   W (ret);
21243   return ret;
21244 }
21245
21246 static void vl_api_ipsec_gre_tunnel_details_t_handler
21247   (vl_api_ipsec_gre_tunnel_details_t * mp)
21248 {
21249   vat_main_t *vam = &vat_main;
21250
21251   print (vam->ofp, "%11d%15U%15U%14d%14d",
21252          ntohl (mp->sw_if_index),
21253          format_ip4_address, &mp->src_address,
21254          format_ip4_address, &mp->dst_address,
21255          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21256 }
21257
21258 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21259   (vl_api_ipsec_gre_tunnel_details_t * mp)
21260 {
21261   vat_main_t *vam = &vat_main;
21262   vat_json_node_t *node = NULL;
21263   struct in_addr ip4;
21264
21265   if (VAT_JSON_ARRAY != vam->json_tree.type)
21266     {
21267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21268       vat_json_init_array (&vam->json_tree);
21269     }
21270   node = vat_json_array_add (&vam->json_tree);
21271
21272   vat_json_init_object (node);
21273   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21274   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21275   vat_json_object_add_ip4 (node, "src_address", ip4);
21276   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21277   vat_json_object_add_ip4 (node, "dst_address", ip4);
21278   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21279   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21280 }
21281
21282 static int
21283 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21284 {
21285   unformat_input_t *i = vam->input;
21286   vl_api_ipsec_gre_tunnel_dump_t *mp;
21287   vl_api_control_ping_t *mp_ping;
21288   u32 sw_if_index;
21289   u8 sw_if_index_set = 0;
21290   int ret;
21291
21292   /* Parse args required to build the message */
21293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21294     {
21295       if (unformat (i, "sw_if_index %d", &sw_if_index))
21296         sw_if_index_set = 1;
21297       else
21298         break;
21299     }
21300
21301   if (sw_if_index_set == 0)
21302     {
21303       sw_if_index = ~0;
21304     }
21305
21306   if (!vam->json_output)
21307     {
21308       print (vam->ofp, "%11s%15s%15s%14s%14s",
21309              "sw_if_index", "src_address", "dst_address",
21310              "local_sa_id", "remote_sa_id");
21311     }
21312
21313   /* Get list of gre-tunnel interfaces */
21314   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21315
21316   mp->sw_if_index = htonl (sw_if_index);
21317
21318   S (mp);
21319
21320   /* Use a control ping for synchronization */
21321   MPING (CONTROL_PING, mp_ping);
21322   S (mp_ping);
21323
21324   W (ret);
21325   return ret;
21326 }
21327
21328 static int
21329 api_delete_subif (vat_main_t * vam)
21330 {
21331   unformat_input_t *i = vam->input;
21332   vl_api_delete_subif_t *mp;
21333   u32 sw_if_index = ~0;
21334   int ret;
21335
21336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21337     {
21338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21339         ;
21340       if (unformat (i, "sw_if_index %d", &sw_if_index))
21341         ;
21342       else
21343         break;
21344     }
21345
21346   if (sw_if_index == ~0)
21347     {
21348       errmsg ("missing sw_if_index");
21349       return -99;
21350     }
21351
21352   /* Construct the API message */
21353   M (DELETE_SUBIF, mp);
21354   mp->sw_if_index = ntohl (sw_if_index);
21355
21356   S (mp);
21357   W (ret);
21358   return ret;
21359 }
21360
21361 #define foreach_pbb_vtr_op      \
21362 _("disable",  L2_VTR_DISABLED)  \
21363 _("pop",  L2_VTR_POP_2)         \
21364 _("push",  L2_VTR_PUSH_2)
21365
21366 static int
21367 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21368 {
21369   unformat_input_t *i = vam->input;
21370   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21371   u32 sw_if_index = ~0, vtr_op = ~0;
21372   u16 outer_tag = ~0;
21373   u8 dmac[6], smac[6];
21374   u8 dmac_set = 0, smac_set = 0;
21375   u16 vlanid = 0;
21376   u32 sid = ~0;
21377   u32 tmp;
21378   int ret;
21379
21380   /* Shut up coverity */
21381   clib_memset (dmac, 0, sizeof (dmac));
21382   clib_memset (smac, 0, sizeof (smac));
21383
21384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21385     {
21386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21387         ;
21388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21389         ;
21390       else if (unformat (i, "vtr_op %d", &vtr_op))
21391         ;
21392 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21393       foreach_pbb_vtr_op
21394 #undef _
21395         else if (unformat (i, "translate_pbb_stag"))
21396         {
21397           if (unformat (i, "%d", &tmp))
21398             {
21399               vtr_op = L2_VTR_TRANSLATE_2_1;
21400               outer_tag = tmp;
21401             }
21402           else
21403             {
21404               errmsg
21405                 ("translate_pbb_stag operation requires outer tag definition");
21406               return -99;
21407             }
21408         }
21409       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21410         dmac_set++;
21411       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21412         smac_set++;
21413       else if (unformat (i, "sid %d", &sid))
21414         ;
21415       else if (unformat (i, "vlanid %d", &tmp))
21416         vlanid = tmp;
21417       else
21418         {
21419           clib_warning ("parse error '%U'", format_unformat_error, i);
21420           return -99;
21421         }
21422     }
21423
21424   if ((sw_if_index == ~0) || (vtr_op == ~0))
21425     {
21426       errmsg ("missing sw_if_index or vtr operation");
21427       return -99;
21428     }
21429   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21430       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21431     {
21432       errmsg
21433         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21434       return -99;
21435     }
21436
21437   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21438   mp->sw_if_index = ntohl (sw_if_index);
21439   mp->vtr_op = ntohl (vtr_op);
21440   mp->outer_tag = ntohs (outer_tag);
21441   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21442   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21443   mp->b_vlanid = ntohs (vlanid);
21444   mp->i_sid = ntohl (sid);
21445
21446   S (mp);
21447   W (ret);
21448   return ret;
21449 }
21450
21451 static int
21452 api_flow_classify_set_interface (vat_main_t * vam)
21453 {
21454   unformat_input_t *i = vam->input;
21455   vl_api_flow_classify_set_interface_t *mp;
21456   u32 sw_if_index;
21457   int sw_if_index_set;
21458   u32 ip4_table_index = ~0;
21459   u32 ip6_table_index = ~0;
21460   u8 is_add = 1;
21461   int ret;
21462
21463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21464     {
21465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21466         sw_if_index_set = 1;
21467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21468         sw_if_index_set = 1;
21469       else if (unformat (i, "del"))
21470         is_add = 0;
21471       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21472         ;
21473       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21474         ;
21475       else
21476         {
21477           clib_warning ("parse error '%U'", format_unformat_error, i);
21478           return -99;
21479         }
21480     }
21481
21482   if (sw_if_index_set == 0)
21483     {
21484       errmsg ("missing interface name or sw_if_index");
21485       return -99;
21486     }
21487
21488   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21489
21490   mp->sw_if_index = ntohl (sw_if_index);
21491   mp->ip4_table_index = ntohl (ip4_table_index);
21492   mp->ip6_table_index = ntohl (ip6_table_index);
21493   mp->is_add = is_add;
21494
21495   S (mp);
21496   W (ret);
21497   return ret;
21498 }
21499
21500 static int
21501 api_flow_classify_dump (vat_main_t * vam)
21502 {
21503   unformat_input_t *i = vam->input;
21504   vl_api_flow_classify_dump_t *mp;
21505   vl_api_control_ping_t *mp_ping;
21506   u8 type = FLOW_CLASSIFY_N_TABLES;
21507   int ret;
21508
21509   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21510     ;
21511   else
21512     {
21513       errmsg ("classify table type must be specified");
21514       return -99;
21515     }
21516
21517   if (!vam->json_output)
21518     {
21519       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21520     }
21521
21522   M (FLOW_CLASSIFY_DUMP, mp);
21523   mp->type = type;
21524   /* send it... */
21525   S (mp);
21526
21527   /* Use a control ping for synchronization */
21528   MPING (CONTROL_PING, mp_ping);
21529   S (mp_ping);
21530
21531   /* Wait for a reply... */
21532   W (ret);
21533   return ret;
21534 }
21535
21536 static int
21537 api_feature_enable_disable (vat_main_t * vam)
21538 {
21539   unformat_input_t *i = vam->input;
21540   vl_api_feature_enable_disable_t *mp;
21541   u8 *arc_name = 0;
21542   u8 *feature_name = 0;
21543   u32 sw_if_index = ~0;
21544   u8 enable = 1;
21545   int ret;
21546
21547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21548     {
21549       if (unformat (i, "arc_name %s", &arc_name))
21550         ;
21551       else if (unformat (i, "feature_name %s", &feature_name))
21552         ;
21553       else
21554         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21555         ;
21556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21557         ;
21558       else if (unformat (i, "disable"))
21559         enable = 0;
21560       else
21561         break;
21562     }
21563
21564   if (arc_name == 0)
21565     {
21566       errmsg ("missing arc name");
21567       return -99;
21568     }
21569   if (vec_len (arc_name) > 63)
21570     {
21571       errmsg ("arc name too long");
21572     }
21573
21574   if (feature_name == 0)
21575     {
21576       errmsg ("missing feature name");
21577       return -99;
21578     }
21579   if (vec_len (feature_name) > 63)
21580     {
21581       errmsg ("feature name too long");
21582     }
21583
21584   if (sw_if_index == ~0)
21585     {
21586       errmsg ("missing interface name or sw_if_index");
21587       return -99;
21588     }
21589
21590   /* Construct the API message */
21591   M (FEATURE_ENABLE_DISABLE, mp);
21592   mp->sw_if_index = ntohl (sw_if_index);
21593   mp->enable = enable;
21594   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21595   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21596   vec_free (arc_name);
21597   vec_free (feature_name);
21598
21599   S (mp);
21600   W (ret);
21601   return ret;
21602 }
21603
21604 static int
21605 api_sw_interface_tag_add_del (vat_main_t * vam)
21606 {
21607   unformat_input_t *i = vam->input;
21608   vl_api_sw_interface_tag_add_del_t *mp;
21609   u32 sw_if_index = ~0;
21610   u8 *tag = 0;
21611   u8 enable = 1;
21612   int ret;
21613
21614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21615     {
21616       if (unformat (i, "tag %s", &tag))
21617         ;
21618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21619         ;
21620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21621         ;
21622       else if (unformat (i, "del"))
21623         enable = 0;
21624       else
21625         break;
21626     }
21627
21628   if (sw_if_index == ~0)
21629     {
21630       errmsg ("missing interface name or sw_if_index");
21631       return -99;
21632     }
21633
21634   if (enable && (tag == 0))
21635     {
21636       errmsg ("no tag specified");
21637       return -99;
21638     }
21639
21640   /* Construct the API message */
21641   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21642   mp->sw_if_index = ntohl (sw_if_index);
21643   mp->is_add = enable;
21644   if (enable)
21645     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21646   vec_free (tag);
21647
21648   S (mp);
21649   W (ret);
21650   return ret;
21651 }
21652
21653 static void vl_api_l2_xconnect_details_t_handler
21654   (vl_api_l2_xconnect_details_t * mp)
21655 {
21656   vat_main_t *vam = &vat_main;
21657
21658   print (vam->ofp, "%15d%15d",
21659          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21660 }
21661
21662 static void vl_api_l2_xconnect_details_t_handler_json
21663   (vl_api_l2_xconnect_details_t * mp)
21664 {
21665   vat_main_t *vam = &vat_main;
21666   vat_json_node_t *node = NULL;
21667
21668   if (VAT_JSON_ARRAY != vam->json_tree.type)
21669     {
21670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21671       vat_json_init_array (&vam->json_tree);
21672     }
21673   node = vat_json_array_add (&vam->json_tree);
21674
21675   vat_json_init_object (node);
21676   vat_json_object_add_uint (node, "rx_sw_if_index",
21677                             ntohl (mp->rx_sw_if_index));
21678   vat_json_object_add_uint (node, "tx_sw_if_index",
21679                             ntohl (mp->tx_sw_if_index));
21680 }
21681
21682 static int
21683 api_l2_xconnect_dump (vat_main_t * vam)
21684 {
21685   vl_api_l2_xconnect_dump_t *mp;
21686   vl_api_control_ping_t *mp_ping;
21687   int ret;
21688
21689   if (!vam->json_output)
21690     {
21691       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21692     }
21693
21694   M (L2_XCONNECT_DUMP, mp);
21695
21696   S (mp);
21697
21698   /* Use a control ping for synchronization */
21699   MPING (CONTROL_PING, mp_ping);
21700   S (mp_ping);
21701
21702   W (ret);
21703   return ret;
21704 }
21705
21706 static int
21707 api_hw_interface_set_mtu (vat_main_t * vam)
21708 {
21709   unformat_input_t *i = vam->input;
21710   vl_api_hw_interface_set_mtu_t *mp;
21711   u32 sw_if_index = ~0;
21712   u32 mtu = 0;
21713   int ret;
21714
21715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21716     {
21717       if (unformat (i, "mtu %d", &mtu))
21718         ;
21719       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21720         ;
21721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21722         ;
21723       else
21724         break;
21725     }
21726
21727   if (sw_if_index == ~0)
21728     {
21729       errmsg ("missing interface name or sw_if_index");
21730       return -99;
21731     }
21732
21733   if (mtu == 0)
21734     {
21735       errmsg ("no mtu specified");
21736       return -99;
21737     }
21738
21739   /* Construct the API message */
21740   M (HW_INTERFACE_SET_MTU, mp);
21741   mp->sw_if_index = ntohl (sw_if_index);
21742   mp->mtu = ntohs ((u16) mtu);
21743
21744   S (mp);
21745   W (ret);
21746   return ret;
21747 }
21748
21749 static int
21750 api_p2p_ethernet_add (vat_main_t * vam)
21751 {
21752   unformat_input_t *i = vam->input;
21753   vl_api_p2p_ethernet_add_t *mp;
21754   u32 parent_if_index = ~0;
21755   u32 sub_id = ~0;
21756   u8 remote_mac[6];
21757   u8 mac_set = 0;
21758   int ret;
21759
21760   clib_memset (remote_mac, 0, sizeof (remote_mac));
21761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21762     {
21763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21764         ;
21765       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21766         ;
21767       else
21768         if (unformat
21769             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21770         mac_set++;
21771       else if (unformat (i, "sub_id %d", &sub_id))
21772         ;
21773       else
21774         {
21775           clib_warning ("parse error '%U'", format_unformat_error, i);
21776           return -99;
21777         }
21778     }
21779
21780   if (parent_if_index == ~0)
21781     {
21782       errmsg ("missing interface name or sw_if_index");
21783       return -99;
21784     }
21785   if (mac_set == 0)
21786     {
21787       errmsg ("missing remote mac address");
21788       return -99;
21789     }
21790   if (sub_id == ~0)
21791     {
21792       errmsg ("missing sub-interface id");
21793       return -99;
21794     }
21795
21796   M (P2P_ETHERNET_ADD, mp);
21797   mp->parent_if_index = ntohl (parent_if_index);
21798   mp->subif_id = ntohl (sub_id);
21799   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21800
21801   S (mp);
21802   W (ret);
21803   return ret;
21804 }
21805
21806 static int
21807 api_p2p_ethernet_del (vat_main_t * vam)
21808 {
21809   unformat_input_t *i = vam->input;
21810   vl_api_p2p_ethernet_del_t *mp;
21811   u32 parent_if_index = ~0;
21812   u8 remote_mac[6];
21813   u8 mac_set = 0;
21814   int ret;
21815
21816   clib_memset (remote_mac, 0, sizeof (remote_mac));
21817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21818     {
21819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21820         ;
21821       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21822         ;
21823       else
21824         if (unformat
21825             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21826         mac_set++;
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
21845   M (P2P_ETHERNET_DEL, mp);
21846   mp->parent_if_index = ntohl (parent_if_index);
21847   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21848
21849   S (mp);
21850   W (ret);
21851   return ret;
21852 }
21853
21854 static int
21855 api_lldp_config (vat_main_t * vam)
21856 {
21857   unformat_input_t *i = vam->input;
21858   vl_api_lldp_config_t *mp;
21859   int tx_hold = 0;
21860   int tx_interval = 0;
21861   u8 *sys_name = NULL;
21862   int ret;
21863
21864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21865     {
21866       if (unformat (i, "system-name %s", &sys_name))
21867         ;
21868       else if (unformat (i, "tx-hold %d", &tx_hold))
21869         ;
21870       else if (unformat (i, "tx-interval %d", &tx_interval))
21871         ;
21872       else
21873         {
21874           clib_warning ("parse error '%U'", format_unformat_error, i);
21875           return -99;
21876         }
21877     }
21878
21879   vec_add1 (sys_name, 0);
21880
21881   M (LLDP_CONFIG, mp);
21882   mp->tx_hold = htonl (tx_hold);
21883   mp->tx_interval = htonl (tx_interval);
21884   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21885   vec_free (sys_name);
21886
21887   S (mp);
21888   W (ret);
21889   return ret;
21890 }
21891
21892 static int
21893 api_sw_interface_set_lldp (vat_main_t * vam)
21894 {
21895   unformat_input_t *i = vam->input;
21896   vl_api_sw_interface_set_lldp_t *mp;
21897   u32 sw_if_index = ~0;
21898   u32 enable = 1;
21899   u8 *port_desc = NULL, *mgmt_oid = NULL;
21900   ip4_address_t ip4_addr;
21901   ip6_address_t ip6_addr;
21902   int ret;
21903
21904   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21905   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21906
21907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21908     {
21909       if (unformat (i, "disable"))
21910         enable = 0;
21911       else
21912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21913         ;
21914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21915         ;
21916       else if (unformat (i, "port-desc %s", &port_desc))
21917         ;
21918       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21919         ;
21920       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21921         ;
21922       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21923         ;
21924       else
21925         break;
21926     }
21927
21928   if (sw_if_index == ~0)
21929     {
21930       errmsg ("missing interface name or sw_if_index");
21931       return -99;
21932     }
21933
21934   /* Construct the API message */
21935   vec_add1 (port_desc, 0);
21936   vec_add1 (mgmt_oid, 0);
21937   M (SW_INTERFACE_SET_LLDP, mp);
21938   mp->sw_if_index = ntohl (sw_if_index);
21939   mp->enable = enable;
21940   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21941   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21942   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21943   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21944   vec_free (port_desc);
21945   vec_free (mgmt_oid);
21946
21947   S (mp);
21948   W (ret);
21949   return ret;
21950 }
21951
21952 static int
21953 api_tcp_configure_src_addresses (vat_main_t * vam)
21954 {
21955   vl_api_tcp_configure_src_addresses_t *mp;
21956   unformat_input_t *i = vam->input;
21957   ip4_address_t v4first, v4last;
21958   ip6_address_t v6first, v6last;
21959   u8 range_set = 0;
21960   u32 vrf_id = 0;
21961   int ret;
21962
21963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21964     {
21965       if (unformat (i, "%U - %U",
21966                     unformat_ip4_address, &v4first,
21967                     unformat_ip4_address, &v4last))
21968         {
21969           if (range_set)
21970             {
21971               errmsg ("one range per message (range already set)");
21972               return -99;
21973             }
21974           range_set = 1;
21975         }
21976       else if (unformat (i, "%U - %U",
21977                          unformat_ip6_address, &v6first,
21978                          unformat_ip6_address, &v6last))
21979         {
21980           if (range_set)
21981             {
21982               errmsg ("one range per message (range already set)");
21983               return -99;
21984             }
21985           range_set = 2;
21986         }
21987       else if (unformat (i, "vrf %d", &vrf_id))
21988         ;
21989       else
21990         break;
21991     }
21992
21993   if (range_set == 0)
21994     {
21995       errmsg ("address range not set");
21996       return -99;
21997     }
21998
21999   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22000   mp->vrf_id = ntohl (vrf_id);
22001   /* ipv6? */
22002   if (range_set == 2)
22003     {
22004       mp->is_ipv6 = 1;
22005       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22006       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22007     }
22008   else
22009     {
22010       mp->is_ipv6 = 0;
22011       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22012       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22013     }
22014   S (mp);
22015   W (ret);
22016   return ret;
22017 }
22018
22019 static void vl_api_app_namespace_add_del_reply_t_handler
22020   (vl_api_app_namespace_add_del_reply_t * mp)
22021 {
22022   vat_main_t *vam = &vat_main;
22023   i32 retval = ntohl (mp->retval);
22024   if (vam->async_mode)
22025     {
22026       vam->async_errors += (retval < 0);
22027     }
22028   else
22029     {
22030       vam->retval = retval;
22031       if (retval == 0)
22032         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22033       vam->result_ready = 1;
22034     }
22035 }
22036
22037 static void vl_api_app_namespace_add_del_reply_t_handler_json
22038   (vl_api_app_namespace_add_del_reply_t * mp)
22039 {
22040   vat_main_t *vam = &vat_main;
22041   vat_json_node_t node;
22042
22043   vat_json_init_object (&node);
22044   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22045   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22046
22047   vat_json_print (vam->ofp, &node);
22048   vat_json_free (&node);
22049
22050   vam->retval = ntohl (mp->retval);
22051   vam->result_ready = 1;
22052 }
22053
22054 static int
22055 api_app_namespace_add_del (vat_main_t * vam)
22056 {
22057   vl_api_app_namespace_add_del_t *mp;
22058   unformat_input_t *i = vam->input;
22059   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22060   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22061   u64 secret;
22062   int ret;
22063
22064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22065     {
22066       if (unformat (i, "id %_%v%_", &ns_id))
22067         ;
22068       else if (unformat (i, "secret %lu", &secret))
22069         secret_set = 1;
22070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22071         sw_if_index_set = 1;
22072       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22073         ;
22074       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22075         ;
22076       else
22077         break;
22078     }
22079   if (!ns_id || !secret_set || !sw_if_index_set)
22080     {
22081       errmsg ("namespace id, secret and sw_if_index must be set");
22082       return -99;
22083     }
22084   if (vec_len (ns_id) > 64)
22085     {
22086       errmsg ("namespace id too long");
22087       return -99;
22088     }
22089   M (APP_NAMESPACE_ADD_DEL, mp);
22090
22091   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22092   mp->namespace_id_len = vec_len (ns_id);
22093   mp->secret = clib_host_to_net_u64 (secret);
22094   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22095   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22096   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22097   vec_free (ns_id);
22098   S (mp);
22099   W (ret);
22100   return ret;
22101 }
22102
22103 static int
22104 api_sock_init_shm (vat_main_t * vam)
22105 {
22106 #if VPP_API_TEST_BUILTIN == 0
22107   unformat_input_t *i = vam->input;
22108   vl_api_shm_elem_config_t *config = 0;
22109   u64 size = 64 << 20;
22110   int rv;
22111
22112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22113     {
22114       if (unformat (i, "size %U", unformat_memory_size, &size))
22115         ;
22116       else
22117         break;
22118     }
22119
22120   /*
22121    * Canned custom ring allocator config.
22122    * Should probably parse all of this
22123    */
22124   vec_validate (config, 6);
22125   config[0].type = VL_API_VLIB_RING;
22126   config[0].size = 256;
22127   config[0].count = 32;
22128
22129   config[1].type = VL_API_VLIB_RING;
22130   config[1].size = 1024;
22131   config[1].count = 16;
22132
22133   config[2].type = VL_API_VLIB_RING;
22134   config[2].size = 4096;
22135   config[2].count = 2;
22136
22137   config[3].type = VL_API_CLIENT_RING;
22138   config[3].size = 256;
22139   config[3].count = 32;
22140
22141   config[4].type = VL_API_CLIENT_RING;
22142   config[4].size = 1024;
22143   config[4].count = 16;
22144
22145   config[5].type = VL_API_CLIENT_RING;
22146   config[5].size = 4096;
22147   config[5].count = 2;
22148
22149   config[6].type = VL_API_QUEUE;
22150   config[6].count = 128;
22151   config[6].size = sizeof (uword);
22152
22153   rv = vl_socket_client_init_shm (config);
22154   if (!rv)
22155     vam->client_index_invalid = 1;
22156   return rv;
22157 #else
22158   return -99;
22159 #endif
22160 }
22161
22162 static int
22163 api_dns_enable_disable (vat_main_t * vam)
22164 {
22165   unformat_input_t *line_input = vam->input;
22166   vl_api_dns_enable_disable_t *mp;
22167   u8 enable_disable = 1;
22168   int ret;
22169
22170   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22171     {
22172       if (unformat (line_input, "disable"))
22173         enable_disable = 0;
22174       if (unformat (line_input, "enable"))
22175         enable_disable = 1;
22176       else
22177         break;
22178     }
22179
22180   /* Construct the API message */
22181   M (DNS_ENABLE_DISABLE, mp);
22182   mp->enable = enable_disable;
22183
22184   /* send it... */
22185   S (mp);
22186   /* Wait for the reply */
22187   W (ret);
22188   return ret;
22189 }
22190
22191 static int
22192 api_dns_resolve_name (vat_main_t * vam)
22193 {
22194   unformat_input_t *line_input = vam->input;
22195   vl_api_dns_resolve_name_t *mp;
22196   u8 *name = 0;
22197   int ret;
22198
22199   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22200     {
22201       if (unformat (line_input, "%s", &name))
22202         ;
22203       else
22204         break;
22205     }
22206
22207   if (vec_len (name) > 127)
22208     {
22209       errmsg ("name too long");
22210       return -99;
22211     }
22212
22213   /* Construct the API message */
22214   M (DNS_RESOLVE_NAME, mp);
22215   memcpy (mp->name, name, vec_len (name));
22216   vec_free (name);
22217
22218   /* send it... */
22219   S (mp);
22220   /* Wait for the reply */
22221   W (ret);
22222   return ret;
22223 }
22224
22225 static int
22226 api_dns_resolve_ip (vat_main_t * vam)
22227 {
22228   unformat_input_t *line_input = vam->input;
22229   vl_api_dns_resolve_ip_t *mp;
22230   int is_ip6 = -1;
22231   ip4_address_t addr4;
22232   ip6_address_t addr6;
22233   int ret;
22234
22235   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22236     {
22237       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22238         is_ip6 = 1;
22239       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22240         is_ip6 = 0;
22241       else
22242         break;
22243     }
22244
22245   if (is_ip6 == -1)
22246     {
22247       errmsg ("missing address");
22248       return -99;
22249     }
22250
22251   /* Construct the API message */
22252   M (DNS_RESOLVE_IP, mp);
22253   mp->is_ip6 = is_ip6;
22254   if (is_ip6)
22255     memcpy (mp->address, &addr6, sizeof (addr6));
22256   else
22257     memcpy (mp->address, &addr4, sizeof (addr4));
22258
22259   /* send it... */
22260   S (mp);
22261   /* Wait for the reply */
22262   W (ret);
22263   return ret;
22264 }
22265
22266 static int
22267 api_dns_name_server_add_del (vat_main_t * vam)
22268 {
22269   unformat_input_t *i = vam->input;
22270   vl_api_dns_name_server_add_del_t *mp;
22271   u8 is_add = 1;
22272   ip6_address_t ip6_server;
22273   ip4_address_t ip4_server;
22274   int ip6_set = 0;
22275   int ip4_set = 0;
22276   int ret = 0;
22277
22278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22279     {
22280       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22281         ip6_set = 1;
22282       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22283         ip4_set = 1;
22284       else if (unformat (i, "del"))
22285         is_add = 0;
22286       else
22287         {
22288           clib_warning ("parse error '%U'", format_unformat_error, i);
22289           return -99;
22290         }
22291     }
22292
22293   if (ip4_set && ip6_set)
22294     {
22295       errmsg ("Only one server address allowed per message");
22296       return -99;
22297     }
22298   if ((ip4_set + ip6_set) == 0)
22299     {
22300       errmsg ("Server address required");
22301       return -99;
22302     }
22303
22304   /* Construct the API message */
22305   M (DNS_NAME_SERVER_ADD_DEL, mp);
22306
22307   if (ip6_set)
22308     {
22309       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22310       mp->is_ip6 = 1;
22311     }
22312   else
22313     {
22314       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22315       mp->is_ip6 = 0;
22316     }
22317
22318   mp->is_add = is_add;
22319
22320   /* send it... */
22321   S (mp);
22322
22323   /* Wait for a reply, return good/bad news  */
22324   W (ret);
22325   return ret;
22326 }
22327
22328 static void
22329 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22330 {
22331   vat_main_t *vam = &vat_main;
22332
22333   if (mp->is_ip4)
22334     {
22335       print (vam->ofp,
22336              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22337              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22338              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22339              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22340              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22341              clib_net_to_host_u32 (mp->action_index), mp->tag);
22342     }
22343   else
22344     {
22345       print (vam->ofp,
22346              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22347              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22348              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22349              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22350              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22351              clib_net_to_host_u32 (mp->action_index), mp->tag);
22352     }
22353 }
22354
22355 static void
22356 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22357                                              mp)
22358 {
22359   vat_main_t *vam = &vat_main;
22360   vat_json_node_t *node = NULL;
22361   struct in6_addr ip6;
22362   struct in_addr ip4;
22363
22364   if (VAT_JSON_ARRAY != vam->json_tree.type)
22365     {
22366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22367       vat_json_init_array (&vam->json_tree);
22368     }
22369   node = vat_json_array_add (&vam->json_tree);
22370   vat_json_init_object (node);
22371
22372   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22373   vat_json_object_add_uint (node, "appns_index",
22374                             clib_net_to_host_u32 (mp->appns_index));
22375   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22376   vat_json_object_add_uint (node, "scope", mp->scope);
22377   vat_json_object_add_uint (node, "action_index",
22378                             clib_net_to_host_u32 (mp->action_index));
22379   vat_json_object_add_uint (node, "lcl_port",
22380                             clib_net_to_host_u16 (mp->lcl_port));
22381   vat_json_object_add_uint (node, "rmt_port",
22382                             clib_net_to_host_u16 (mp->rmt_port));
22383   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22384   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22385   vat_json_object_add_string_copy (node, "tag", mp->tag);
22386   if (mp->is_ip4)
22387     {
22388       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22389       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22390       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22391       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22392     }
22393   else
22394     {
22395       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22396       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22397       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22398       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22399     }
22400 }
22401
22402 static int
22403 api_session_rule_add_del (vat_main_t * vam)
22404 {
22405   vl_api_session_rule_add_del_t *mp;
22406   unformat_input_t *i = vam->input;
22407   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22408   u32 appns_index = 0, scope = 0;
22409   ip4_address_t lcl_ip4, rmt_ip4;
22410   ip6_address_t lcl_ip6, rmt_ip6;
22411   u8 is_ip4 = 1, conn_set = 0;
22412   u8 is_add = 1, *tag = 0;
22413   int ret;
22414
22415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22416     {
22417       if (unformat (i, "del"))
22418         is_add = 0;
22419       else if (unformat (i, "add"))
22420         ;
22421       else if (unformat (i, "proto tcp"))
22422         proto = 0;
22423       else if (unformat (i, "proto udp"))
22424         proto = 1;
22425       else if (unformat (i, "appns %d", &appns_index))
22426         ;
22427       else if (unformat (i, "scope %d", &scope))
22428         ;
22429       else if (unformat (i, "tag %_%v%_", &tag))
22430         ;
22431       else
22432         if (unformat
22433             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22434              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22435              &rmt_port))
22436         {
22437           is_ip4 = 1;
22438           conn_set = 1;
22439         }
22440       else
22441         if (unformat
22442             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22443              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22444              &rmt_port))
22445         {
22446           is_ip4 = 0;
22447           conn_set = 1;
22448         }
22449       else if (unformat (i, "action %d", &action))
22450         ;
22451       else
22452         break;
22453     }
22454   if (proto == ~0 || !conn_set || action == ~0)
22455     {
22456       errmsg ("transport proto, connection and action must be set");
22457       return -99;
22458     }
22459
22460   if (scope > 3)
22461     {
22462       errmsg ("scope should be 0-3");
22463       return -99;
22464     }
22465
22466   M (SESSION_RULE_ADD_DEL, mp);
22467
22468   mp->is_ip4 = is_ip4;
22469   mp->transport_proto = proto;
22470   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22471   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22472   mp->lcl_plen = lcl_plen;
22473   mp->rmt_plen = rmt_plen;
22474   mp->action_index = clib_host_to_net_u32 (action);
22475   mp->appns_index = clib_host_to_net_u32 (appns_index);
22476   mp->scope = scope;
22477   mp->is_add = is_add;
22478   if (is_ip4)
22479     {
22480       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22481       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22482     }
22483   else
22484     {
22485       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22486       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22487     }
22488   if (tag)
22489     {
22490       clib_memcpy (mp->tag, tag, vec_len (tag));
22491       vec_free (tag);
22492     }
22493
22494   S (mp);
22495   W (ret);
22496   return ret;
22497 }
22498
22499 static int
22500 api_session_rules_dump (vat_main_t * vam)
22501 {
22502   vl_api_session_rules_dump_t *mp;
22503   vl_api_control_ping_t *mp_ping;
22504   int ret;
22505
22506   if (!vam->json_output)
22507     {
22508       print (vam->ofp, "%=20s", "Session Rules");
22509     }
22510
22511   M (SESSION_RULES_DUMP, mp);
22512   /* send it... */
22513   S (mp);
22514
22515   /* Use a control ping for synchronization */
22516   MPING (CONTROL_PING, mp_ping);
22517   S (mp_ping);
22518
22519   /* Wait for a reply... */
22520   W (ret);
22521   return ret;
22522 }
22523
22524 static int
22525 api_ip_container_proxy_add_del (vat_main_t * vam)
22526 {
22527   vl_api_ip_container_proxy_add_del_t *mp;
22528   unformat_input_t *i = vam->input;
22529   u32 plen = ~0, sw_if_index = ~0;
22530   ip4_address_t ip4;
22531   ip6_address_t ip6;
22532   u8 is_ip4 = 1;
22533   u8 is_add = 1;
22534   int ret;
22535
22536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22537     {
22538       if (unformat (i, "del"))
22539         is_add = 0;
22540       else if (unformat (i, "add"))
22541         ;
22542       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22543         {
22544           is_ip4 = 1;
22545           plen = 32;
22546         }
22547       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22548         {
22549           is_ip4 = 0;
22550           plen = 128;
22551         }
22552       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22553         ;
22554       else
22555         break;
22556     }
22557   if (sw_if_index == ~0 || plen == ~0)
22558     {
22559       errmsg ("address and sw_if_index must be set");
22560       return -99;
22561     }
22562
22563   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22564
22565   mp->is_ip4 = is_ip4;
22566   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22567   mp->plen = plen;
22568   mp->is_add = is_add;
22569   if (is_ip4)
22570     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22571   else
22572     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22573
22574   S (mp);
22575   W (ret);
22576   return ret;
22577 }
22578
22579 static int
22580 api_qos_record_enable_disable (vat_main_t * vam)
22581 {
22582   unformat_input_t *i = vam->input;
22583   vl_api_qos_record_enable_disable_t *mp;
22584   u32 sw_if_index, qs = 0xff;
22585   u8 sw_if_index_set = 0;
22586   u8 enable = 1;
22587   int ret;
22588
22589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22590     {
22591       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22592         sw_if_index_set = 1;
22593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22594         sw_if_index_set = 1;
22595       else if (unformat (i, "%U", unformat_qos_source, &qs))
22596         ;
22597       else if (unformat (i, "disable"))
22598         enable = 0;
22599       else
22600         {
22601           clib_warning ("parse error '%U'", format_unformat_error, i);
22602           return -99;
22603         }
22604     }
22605
22606   if (sw_if_index_set == 0)
22607     {
22608       errmsg ("missing interface name or sw_if_index");
22609       return -99;
22610     }
22611   if (qs == 0xff)
22612     {
22613       errmsg ("input location must be specified");
22614       return -99;
22615     }
22616
22617   M (QOS_RECORD_ENABLE_DISABLE, mp);
22618
22619   mp->sw_if_index = ntohl (sw_if_index);
22620   mp->input_source = qs;
22621   mp->enable = enable;
22622
22623   S (mp);
22624   W (ret);
22625   return ret;
22626 }
22627
22628
22629 static int
22630 q_or_quit (vat_main_t * vam)
22631 {
22632 #if VPP_API_TEST_BUILTIN == 0
22633   longjmp (vam->jump_buf, 1);
22634 #endif
22635   return 0;                     /* not so much */
22636 }
22637
22638 static int
22639 q (vat_main_t * vam)
22640 {
22641   return q_or_quit (vam);
22642 }
22643
22644 static int
22645 quit (vat_main_t * vam)
22646 {
22647   return q_or_quit (vam);
22648 }
22649
22650 static int
22651 comment (vat_main_t * vam)
22652 {
22653   return 0;
22654 }
22655
22656 static int
22657 statseg (vat_main_t * vam)
22658 {
22659   ssvm_private_t *ssvmp = &vam->stat_segment;
22660   ssvm_shared_header_t *shared_header = ssvmp->sh;
22661   vlib_counter_t **counters;
22662   u64 thread0_index1_packets;
22663   u64 thread0_index1_bytes;
22664   f64 vector_rate, input_rate;
22665   uword *p;
22666
22667   uword *counter_vector_by_name;
22668   if (vam->stat_segment_lockp == 0)
22669     {
22670       errmsg ("Stat segment not mapped...");
22671       return -99;
22672     }
22673
22674   /* look up "/if/rx for sw_if_index 1 as a test */
22675
22676   clib_spinlock_lock (vam->stat_segment_lockp);
22677
22678   counter_vector_by_name = (uword *) shared_header->opaque[1];
22679
22680   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22681   if (p == 0)
22682     {
22683       clib_spinlock_unlock (vam->stat_segment_lockp);
22684       errmsg ("/if/tx not found?");
22685       return -99;
22686     }
22687
22688   /* Fish per-thread vector of combined counters from shared memory */
22689   counters = (vlib_counter_t **) p[0];
22690
22691   if (vec_len (counters[0]) < 2)
22692     {
22693       clib_spinlock_unlock (vam->stat_segment_lockp);
22694       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22695       return -99;
22696     }
22697
22698   /* Read thread 0 sw_if_index 1 counter */
22699   thread0_index1_packets = counters[0][1].packets;
22700   thread0_index1_bytes = counters[0][1].bytes;
22701
22702   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22703   if (p == 0)
22704     {
22705       clib_spinlock_unlock (vam->stat_segment_lockp);
22706       errmsg ("vector_rate not found?");
22707       return -99;
22708     }
22709
22710   vector_rate = *(f64 *) (p[0]);
22711   p = hash_get_mem (counter_vector_by_name, "input_rate");
22712   if (p == 0)
22713     {
22714       clib_spinlock_unlock (vam->stat_segment_lockp);
22715       errmsg ("input_rate not found?");
22716       return -99;
22717     }
22718   input_rate = *(f64 *) (p[0]);
22719
22720   clib_spinlock_unlock (vam->stat_segment_lockp);
22721
22722   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22723          vector_rate, input_rate);
22724   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22725          thread0_index1_packets, thread0_index1_bytes);
22726
22727   return 0;
22728 }
22729
22730 static int
22731 cmd_cmp (void *a1, void *a2)
22732 {
22733   u8 **c1 = a1;
22734   u8 **c2 = a2;
22735
22736   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22737 }
22738
22739 static int
22740 help (vat_main_t * vam)
22741 {
22742   u8 **cmds = 0;
22743   u8 *name = 0;
22744   hash_pair_t *p;
22745   unformat_input_t *i = vam->input;
22746   int j;
22747
22748   if (unformat (i, "%s", &name))
22749     {
22750       uword *hs;
22751
22752       vec_add1 (name, 0);
22753
22754       hs = hash_get_mem (vam->help_by_name, name);
22755       if (hs)
22756         print (vam->ofp, "usage: %s %s", name, hs[0]);
22757       else
22758         print (vam->ofp, "No such msg / command '%s'", name);
22759       vec_free (name);
22760       return 0;
22761     }
22762
22763   print (vam->ofp, "Help is available for the following:");
22764
22765     /* *INDENT-OFF* */
22766     hash_foreach_pair (p, vam->function_by_name,
22767     ({
22768       vec_add1 (cmds, (u8 *)(p->key));
22769     }));
22770     /* *INDENT-ON* */
22771
22772   vec_sort_with_function (cmds, cmd_cmp);
22773
22774   for (j = 0; j < vec_len (cmds); j++)
22775     print (vam->ofp, "%s", cmds[j]);
22776
22777   vec_free (cmds);
22778   return 0;
22779 }
22780
22781 static int
22782 set (vat_main_t * vam)
22783 {
22784   u8 *name = 0, *value = 0;
22785   unformat_input_t *i = vam->input;
22786
22787   if (unformat (i, "%s", &name))
22788     {
22789       /* The input buffer is a vector, not a string. */
22790       value = vec_dup (i->buffer);
22791       vec_delete (value, i->index, 0);
22792       /* Almost certainly has a trailing newline */
22793       if (value[vec_len (value) - 1] == '\n')
22794         value[vec_len (value) - 1] = 0;
22795       /* Make sure it's a proper string, one way or the other */
22796       vec_add1 (value, 0);
22797       (void) clib_macro_set_value (&vam->macro_main,
22798                                    (char *) name, (char *) value);
22799     }
22800   else
22801     errmsg ("usage: set <name> <value>");
22802
22803   vec_free (name);
22804   vec_free (value);
22805   return 0;
22806 }
22807
22808 static int
22809 unset (vat_main_t * vam)
22810 {
22811   u8 *name = 0;
22812
22813   if (unformat (vam->input, "%s", &name))
22814     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22815       errmsg ("unset: %s wasn't set", name);
22816   vec_free (name);
22817   return 0;
22818 }
22819
22820 typedef struct
22821 {
22822   u8 *name;
22823   u8 *value;
22824 } macro_sort_t;
22825
22826
22827 static int
22828 macro_sort_cmp (void *a1, void *a2)
22829 {
22830   macro_sort_t *s1 = a1;
22831   macro_sort_t *s2 = a2;
22832
22833   return strcmp ((char *) (s1->name), (char *) (s2->name));
22834 }
22835
22836 static int
22837 dump_macro_table (vat_main_t * vam)
22838 {
22839   macro_sort_t *sort_me = 0, *sm;
22840   int i;
22841   hash_pair_t *p;
22842
22843     /* *INDENT-OFF* */
22844     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22845     ({
22846       vec_add2 (sort_me, sm, 1);
22847       sm->name = (u8 *)(p->key);
22848       sm->value = (u8 *) (p->value[0]);
22849     }));
22850     /* *INDENT-ON* */
22851
22852   vec_sort_with_function (sort_me, macro_sort_cmp);
22853
22854   if (vec_len (sort_me))
22855     print (vam->ofp, "%-15s%s", "Name", "Value");
22856   else
22857     print (vam->ofp, "The macro table is empty...");
22858
22859   for (i = 0; i < vec_len (sort_me); i++)
22860     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22861   return 0;
22862 }
22863
22864 static int
22865 dump_node_table (vat_main_t * vam)
22866 {
22867   int i, j;
22868   vlib_node_t *node, *next_node;
22869
22870   if (vec_len (vam->graph_nodes) == 0)
22871     {
22872       print (vam->ofp, "Node table empty, issue get_node_graph...");
22873       return 0;
22874     }
22875
22876   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22877     {
22878       node = vam->graph_nodes[0][i];
22879       print (vam->ofp, "[%d] %s", i, node->name);
22880       for (j = 0; j < vec_len (node->next_nodes); j++)
22881         {
22882           if (node->next_nodes[j] != ~0)
22883             {
22884               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22885               print (vam->ofp, "  [%d] %s", j, next_node->name);
22886             }
22887         }
22888     }
22889   return 0;
22890 }
22891
22892 static int
22893 value_sort_cmp (void *a1, void *a2)
22894 {
22895   name_sort_t *n1 = a1;
22896   name_sort_t *n2 = a2;
22897
22898   if (n1->value < n2->value)
22899     return -1;
22900   if (n1->value > n2->value)
22901     return 1;
22902   return 0;
22903 }
22904
22905
22906 static int
22907 dump_msg_api_table (vat_main_t * vam)
22908 {
22909   api_main_t *am = &api_main;
22910   name_sort_t *nses = 0, *ns;
22911   hash_pair_t *hp;
22912   int i;
22913
22914   /* *INDENT-OFF* */
22915   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22916   ({
22917     vec_add2 (nses, ns, 1);
22918     ns->name = (u8 *)(hp->key);
22919     ns->value = (u32) hp->value[0];
22920   }));
22921   /* *INDENT-ON* */
22922
22923   vec_sort_with_function (nses, value_sort_cmp);
22924
22925   for (i = 0; i < vec_len (nses); i++)
22926     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22927   vec_free (nses);
22928   return 0;
22929 }
22930
22931 static int
22932 get_msg_id (vat_main_t * vam)
22933 {
22934   u8 *name_and_crc;
22935   u32 message_index;
22936
22937   if (unformat (vam->input, "%s", &name_and_crc))
22938     {
22939       message_index = vl_msg_api_get_msg_index (name_and_crc);
22940       if (message_index == ~0)
22941         {
22942           print (vam->ofp, " '%s' not found", name_and_crc);
22943           return 0;
22944         }
22945       print (vam->ofp, " '%s' has message index %d",
22946              name_and_crc, message_index);
22947       return 0;
22948     }
22949   errmsg ("name_and_crc required...");
22950   return 0;
22951 }
22952
22953 static int
22954 search_node_table (vat_main_t * vam)
22955 {
22956   unformat_input_t *line_input = vam->input;
22957   u8 *node_to_find;
22958   int j;
22959   vlib_node_t *node, *next_node;
22960   uword *p;
22961
22962   if (vam->graph_node_index_by_name == 0)
22963     {
22964       print (vam->ofp, "Node table empty, issue get_node_graph...");
22965       return 0;
22966     }
22967
22968   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22969     {
22970       if (unformat (line_input, "%s", &node_to_find))
22971         {
22972           vec_add1 (node_to_find, 0);
22973           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22974           if (p == 0)
22975             {
22976               print (vam->ofp, "%s not found...", node_to_find);
22977               goto out;
22978             }
22979           node = vam->graph_nodes[0][p[0]];
22980           print (vam->ofp, "[%d] %s", p[0], node->name);
22981           for (j = 0; j < vec_len (node->next_nodes); j++)
22982             {
22983               if (node->next_nodes[j] != ~0)
22984                 {
22985                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22986                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22987                 }
22988             }
22989         }
22990
22991       else
22992         {
22993           clib_warning ("parse error '%U'", format_unformat_error,
22994                         line_input);
22995           return -99;
22996         }
22997
22998     out:
22999       vec_free (node_to_find);
23000
23001     }
23002
23003   return 0;
23004 }
23005
23006
23007 static int
23008 script (vat_main_t * vam)
23009 {
23010 #if (VPP_API_TEST_BUILTIN==0)
23011   u8 *s = 0;
23012   char *save_current_file;
23013   unformat_input_t save_input;
23014   jmp_buf save_jump_buf;
23015   u32 save_line_number;
23016
23017   FILE *new_fp, *save_ifp;
23018
23019   if (unformat (vam->input, "%s", &s))
23020     {
23021       new_fp = fopen ((char *) s, "r");
23022       if (new_fp == 0)
23023         {
23024           errmsg ("Couldn't open script file %s", s);
23025           vec_free (s);
23026           return -99;
23027         }
23028     }
23029   else
23030     {
23031       errmsg ("Missing script name");
23032       return -99;
23033     }
23034
23035   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23036   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23037   save_ifp = vam->ifp;
23038   save_line_number = vam->input_line_number;
23039   save_current_file = (char *) vam->current_file;
23040
23041   vam->input_line_number = 0;
23042   vam->ifp = new_fp;
23043   vam->current_file = s;
23044   do_one_file (vam);
23045
23046   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23047   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23048   vam->ifp = save_ifp;
23049   vam->input_line_number = save_line_number;
23050   vam->current_file = (u8 *) save_current_file;
23051   vec_free (s);
23052
23053   return 0;
23054 #else
23055   clib_warning ("use the exec command...");
23056   return -99;
23057 #endif
23058 }
23059
23060 static int
23061 echo (vat_main_t * vam)
23062 {
23063   print (vam->ofp, "%v", vam->input->buffer);
23064   return 0;
23065 }
23066
23067 /* List of API message constructors, CLI names map to api_xxx */
23068 #define foreach_vpe_api_msg                                             \
23069 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23070 _(sw_interface_dump,"")                                                 \
23071 _(sw_interface_set_flags,                                               \
23072   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23073 _(sw_interface_add_del_address,                                         \
23074   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23075 _(sw_interface_set_rx_mode,                                             \
23076   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23077 _(sw_interface_set_rx_placement,                                        \
23078   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23079 _(sw_interface_rx_placement_dump,                                       \
23080   "[<intfc> | sw_if_index <id>]")                                         \
23081 _(sw_interface_set_table,                                               \
23082   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23083 _(sw_interface_set_mpls_enable,                                         \
23084   "<intfc> | sw_if_index [disable | dis]")                              \
23085 _(sw_interface_set_vpath,                                               \
23086   "<intfc> | sw_if_index <id> enable | disable")                        \
23087 _(sw_interface_set_vxlan_bypass,                                        \
23088   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23089 _(sw_interface_set_geneve_bypass,                                       \
23090   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23091 _(sw_interface_set_l2_xconnect,                                         \
23092   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23093   "enable | disable")                                                   \
23094 _(sw_interface_set_l2_bridge,                                           \
23095   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23096   "[shg <split-horizon-group>] [bvi]\n"                                 \
23097   "enable | disable")                                                   \
23098 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23099 _(bridge_domain_add_del,                                                \
23100   "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") \
23101 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23102 _(l2fib_add_del,                                                        \
23103   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23104 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23105 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23106 _(l2_flags,                                                             \
23107   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23108 _(bridge_flags,                                                         \
23109   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23110 _(tap_create_v2,                                                        \
23111   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23112 _(tap_delete_v2,                                                        \
23113   "<vpp-if-name> | sw_if_index <id>")                                   \
23114 _(sw_interface_tap_v2_dump, "")                                         \
23115 _(virtio_pci_create,                                                    \
23116   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
23117 _(virtio_pci_delete,                                                    \
23118   "<vpp-if-name> | sw_if_index <id>")                                   \
23119 _(sw_interface_virtio_pci_dump, "")                                     \
23120 _(bond_create,                                                          \
23121   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23122   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
23123   "[id <if-id>]")                                                       \
23124 _(bond_delete,                                                          \
23125   "<vpp-if-name> | sw_if_index <id>")                                   \
23126 _(bond_enslave,                                                         \
23127   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23128 _(bond_detach_slave,                                                    \
23129   "sw_if_index <n>")                                                    \
23130 _(sw_interface_bond_dump, "")                                           \
23131 _(sw_interface_slave_dump,                                              \
23132   "<vpp-if-name> | sw_if_index <id>")                                   \
23133 _(ip_table_add_del,                                                     \
23134   "table <n> [ipv6] [add | del]\n")                                     \
23135 _(ip_add_del_route,                                                     \
23136   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23137   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23138   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23139   "[multipath] [count <n>] [del]")                                      \
23140 _(ip_mroute_add_del,                                                    \
23141   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23142   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23143 _(mpls_table_add_del,                                                   \
23144   "table <n> [add | del]\n")                                            \
23145 _(mpls_route_add_del,                                                   \
23146   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23147   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23148   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23149   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23150   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23151   "[count <n>] [del]")                                                  \
23152 _(mpls_ip_bind_unbind,                                                  \
23153   "<label> <addr/len>")                                                 \
23154 _(mpls_tunnel_add_del,                                                  \
23155   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23156   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23157   "[l2-only]  [out-label <n>]")                                         \
23158 _(sr_mpls_policy_add,                                                   \
23159   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23160 _(sr_mpls_policy_del,                                                   \
23161   "bsid <id>")                                                          \
23162 _(bier_table_add_del,                                                   \
23163   "<label> <sub-domain> <set> <bsl> [del]")                             \
23164 _(bier_route_add_del,                                                   \
23165   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23166   "[<intfc> | sw_if_index <id>]"                                        \
23167   "[weight <n>] [del] [multipath]")                                     \
23168 _(proxy_arp_add_del,                                                    \
23169   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23170 _(proxy_arp_intfc_enable_disable,                                       \
23171   "<intfc> | sw_if_index <id> enable | disable")                        \
23172 _(sw_interface_set_unnumbered,                                          \
23173   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23174 _(ip_neighbor_add_del,                                                  \
23175   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23176   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23177 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23178 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23179   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23180   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23181   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23182 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23183 _(reset_fib, "vrf <n> [ipv6]")                                          \
23184 _(dhcp_proxy_config,                                                    \
23185   "svr <v46-address> src <v46-address>\n"                               \
23186    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23187 _(dhcp_proxy_set_vss,                                                   \
23188   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23189 _(dhcp_proxy_dump, "ip6")                                               \
23190 _(dhcp_client_config,                                                   \
23191   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23192 _(set_ip_flow_hash,                                                     \
23193   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23194 _(sw_interface_ip6_enable_disable,                                      \
23195   "<intfc> | sw_if_index <id> enable | disable")                        \
23196 _(ip6nd_proxy_add_del,                                                  \
23197   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23198 _(ip6nd_proxy_dump, "")                                                 \
23199 _(sw_interface_ip6nd_ra_prefix,                                         \
23200   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23201   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23202   "[nolink] [isno]")                                                    \
23203 _(sw_interface_ip6nd_ra_config,                                         \
23204   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23205   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23206   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23207 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23208 _(l2_patch_add_del,                                                     \
23209   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23210   "enable | disable")                                                   \
23211 _(sr_localsid_add_del,                                                  \
23212   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23213   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23214 _(classify_add_del_table,                                               \
23215   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23216   " [del] [del-chain] mask <mask-value>\n"                              \
23217   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23218   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23219 _(classify_add_del_session,                                             \
23220   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23221   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23222   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23223   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23224 _(classify_set_interface_ip_table,                                      \
23225   "<intfc> | sw_if_index <nn> table <nn>")                              \
23226 _(classify_set_interface_l2_tables,                                     \
23227   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23228   "  [other-table <nn>]")                                               \
23229 _(get_node_index, "node <node-name")                                    \
23230 _(add_node_next, "node <node-name> next <next-node-name>")              \
23231 _(l2tpv3_create_tunnel,                                                 \
23232   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23233   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23234   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23235 _(l2tpv3_set_tunnel_cookies,                                            \
23236   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23237   "[new_remote_cookie <nn>]\n")                                         \
23238 _(l2tpv3_interface_enable_disable,                                      \
23239   "<intfc> | sw_if_index <nn> enable | disable")                        \
23240 _(l2tpv3_set_lookup_key,                                                \
23241   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23242 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23243 _(vxlan_offload_rx,                                                     \
23244   "hw { <interface name> | hw_if_index <nn>} "                          \
23245   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23246 _(vxlan_add_del_tunnel,                                                 \
23247   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23248   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23249   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23250 _(geneve_add_del_tunnel,                                                \
23251   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23252   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23253   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23254 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23255 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23256 _(gre_add_del_tunnel,                                                   \
23257   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23258   "[teb | erspan <session-id>] [del]")                                  \
23259 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23260 _(l2_fib_clear_table, "")                                               \
23261 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23262 _(l2_interface_vlan_tag_rewrite,                                        \
23263   "<intfc> | sw_if_index <nn> \n"                                       \
23264   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23265   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23266 _(create_vhost_user_if,                                                 \
23267         "socket <filename> [server] [renumber <dev_instance>] "         \
23268         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23269         "[mac <mac_address>]")                                          \
23270 _(modify_vhost_user_if,                                                 \
23271         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23272         "[server] [renumber <dev_instance>]")                           \
23273 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23274 _(sw_interface_vhost_user_dump, "")                                     \
23275 _(show_version, "")                                                     \
23276 _(show_threads, "")                                                     \
23277 _(vxlan_gpe_add_del_tunnel,                                             \
23278   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23279   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23280   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23281   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23282 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23283 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23284 _(interface_name_renumber,                                              \
23285   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23286 _(input_acl_set_interface,                                              \
23287   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23288   "  [l2-table <nn>] [del]")                                            \
23289 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23290 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23291   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23292 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23293 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23294 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23295 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23296 _(ip_dump, "ipv4 | ipv6")                                               \
23297 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23298 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23299   "  spid_id <n> ")                                                     \
23300 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23301   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23302   "  integ_alg <alg> integ_key <hex>")                                  \
23303 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23304   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23305   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23306   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23307 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23308 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23309   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23310   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23311   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23312   "  [instance <n>]")     \
23313 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23314 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23315   "  <alg> <hex>\n")                                                    \
23316 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23317 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23318 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23319   "(auth_data 0x<data> | auth_data <data>)")                            \
23320 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23321   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23322 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23323   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23324   "(local|remote)")                                                     \
23325 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23326 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23327 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23328 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23329 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23330 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23331 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23332 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23333 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23334 _(delete_loopback,"sw_if_index <nn>")                                   \
23335 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23336 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23337 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23338 _(want_interface_events,  "enable|disable")                             \
23339 _(get_first_msg_id, "client <name>")                                    \
23340 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23341 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23342   "fib-id <nn> [ip4][ip6][default]")                                    \
23343 _(get_node_graph, " ")                                                  \
23344 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23345 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23346 _(ioam_disable, "")                                                     \
23347 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23348                             " sw_if_index <sw_if_index> p <priority> "  \
23349                             "w <weight>] [del]")                        \
23350 _(one_add_del_locator, "locator-set <locator_name> "                    \
23351                         "iface <intf> | sw_if_index <sw_if_index> "     \
23352                         "p <priority> w <weight> [del]")                \
23353 _(one_add_del_local_eid,"vni <vni> eid "                                \
23354                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23355                          "locator-set <locator_name> [del]"             \
23356                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23357 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23358 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23359 _(one_enable_disable, "enable|disable")                                 \
23360 _(one_map_register_enable_disable, "enable|disable")                    \
23361 _(one_map_register_fallback_threshold, "<value>")                       \
23362 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23363 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23364                                "[seid <seid>] "                         \
23365                                "rloc <locator> p <prio> "               \
23366                                "w <weight> [rloc <loc> ... ] "          \
23367                                "action <action> [del-all]")             \
23368 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23369                           "<local-eid>")                                \
23370 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23371 _(one_use_petr, "ip-address> | disable")                                \
23372 _(one_map_request_mode, "src-dst|dst-only")                             \
23373 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23374 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23375 _(one_locator_set_dump, "[local | remote]")                             \
23376 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23377 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23378                        "[local] | [remote]")                            \
23379 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23380 _(one_ndp_bd_get, "")                                                   \
23381 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23382 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23383 _(one_l2_arp_bd_get, "")                                                \
23384 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23385 _(one_stats_enable_disable, "enable|disable")                           \
23386 _(show_one_stats_enable_disable, "")                                    \
23387 _(one_eid_table_vni_dump, "")                                           \
23388 _(one_eid_table_map_dump, "l2|l3")                                      \
23389 _(one_map_resolver_dump, "")                                            \
23390 _(one_map_server_dump, "")                                              \
23391 _(one_adjacencies_get, "vni <vni>")                                     \
23392 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23393 _(show_one_rloc_probe_state, "")                                        \
23394 _(show_one_map_register_state, "")                                      \
23395 _(show_one_status, "")                                                  \
23396 _(one_stats_dump, "")                                                   \
23397 _(one_stats_flush, "")                                                  \
23398 _(one_get_map_request_itr_rlocs, "")                                    \
23399 _(one_map_register_set_ttl, "<ttl>")                                    \
23400 _(one_set_transport_protocol, "udp|api")                                \
23401 _(one_get_transport_protocol, "")                                       \
23402 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23403 _(one_show_xtr_mode, "")                                                \
23404 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23405 _(one_show_pitr_mode, "")                                               \
23406 _(one_enable_disable_petr_mode, "enable|disable")                       \
23407 _(one_show_petr_mode, "")                                               \
23408 _(show_one_nsh_mapping, "")                                             \
23409 _(show_one_pitr, "")                                                    \
23410 _(show_one_use_petr, "")                                                \
23411 _(show_one_map_request_mode, "")                                        \
23412 _(show_one_map_register_ttl, "")                                        \
23413 _(show_one_map_register_fallback_threshold, "")                         \
23414 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23415                             " sw_if_index <sw_if_index> p <priority> "  \
23416                             "w <weight>] [del]")                        \
23417 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23418                         "iface <intf> | sw_if_index <sw_if_index> "     \
23419                         "p <priority> w <weight> [del]")                \
23420 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23421                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23422                          "locator-set <locator_name> [del]"             \
23423                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23424 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23425 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23426 _(lisp_enable_disable, "enable|disable")                                \
23427 _(lisp_map_register_enable_disable, "enable|disable")                   \
23428 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23429 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23430                                "[seid <seid>] "                         \
23431                                "rloc <locator> p <prio> "               \
23432                                "w <weight> [rloc <loc> ... ] "          \
23433                                "action <action> [del-all]")             \
23434 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23435                           "<local-eid>")                                \
23436 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23437 _(lisp_use_petr, "<ip-address> | disable")                              \
23438 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23439 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23440 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23441 _(lisp_locator_set_dump, "[local | remote]")                            \
23442 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23443 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23444                        "[local] | [remote]")                            \
23445 _(lisp_eid_table_vni_dump, "")                                          \
23446 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23447 _(lisp_map_resolver_dump, "")                                           \
23448 _(lisp_map_server_dump, "")                                             \
23449 _(lisp_adjacencies_get, "vni <vni>")                                    \
23450 _(gpe_fwd_entry_vnis_get, "")                                           \
23451 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23452 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23453                                 "[table <table-id>]")                   \
23454 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23455 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23456 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23457 _(gpe_get_encap_mode, "")                                               \
23458 _(lisp_gpe_add_del_iface, "up|down")                                    \
23459 _(lisp_gpe_enable_disable, "enable|disable")                            \
23460 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23461   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23462 _(show_lisp_rloc_probe_state, "")                                       \
23463 _(show_lisp_map_register_state, "")                                     \
23464 _(show_lisp_status, "")                                                 \
23465 _(lisp_get_map_request_itr_rlocs, "")                                   \
23466 _(show_lisp_pitr, "")                                                   \
23467 _(show_lisp_use_petr, "")                                               \
23468 _(show_lisp_map_request_mode, "")                                       \
23469 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23470 _(af_packet_delete, "name <host interface name>")                       \
23471 _(af_packet_dump, "")                                                   \
23472 _(policer_add_del, "name <policer name> <params> [del]")                \
23473 _(policer_dump, "[name <policer name>]")                                \
23474 _(policer_classify_set_interface,                                       \
23475   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23476   "  [l2-table <nn>] [del]")                                            \
23477 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23478 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23479     "[master|slave]")                                                   \
23480 _(netmap_delete, "name <interface name>")                               \
23481 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23482 _(mpls_fib_dump, "")                                                    \
23483 _(classify_table_ids, "")                                               \
23484 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23485 _(classify_table_info, "table_id <nn>")                                 \
23486 _(classify_session_dump, "table_id <nn>")                               \
23487 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23488     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23489     "[template_interval <nn>] [udp_checksum]")                          \
23490 _(ipfix_exporter_dump, "")                                              \
23491 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23492 _(ipfix_classify_stream_dump, "")                                       \
23493 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23494 _(ipfix_classify_table_dump, "")                                        \
23495 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23496 _(sw_interface_span_dump, "[l2]")                                           \
23497 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23498 _(pg_create_interface, "if_id <nn>")                                    \
23499 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23500 _(pg_enable_disable, "[stream <id>] disable")                           \
23501 _(ip_source_and_port_range_check_add_del,                               \
23502   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23503 _(ip_source_and_port_range_check_interface_add_del,                     \
23504   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23505   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23506 _(ipsec_gre_add_del_tunnel,                                             \
23507   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23508 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23509 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23510 _(l2_interface_pbb_tag_rewrite,                                         \
23511   "<intfc> | sw_if_index <nn> \n"                                       \
23512   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23513   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23514 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23515 _(flow_classify_set_interface,                                          \
23516   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23517 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23518 _(ip_fib_dump, "")                                                      \
23519 _(ip_mfib_dump, "")                                                     \
23520 _(ip6_fib_dump, "")                                                     \
23521 _(ip6_mfib_dump, "")                                                    \
23522 _(feature_enable_disable, "arc_name <arc_name> "                        \
23523   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23524 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23525 "[disable]")                                                            \
23526 _(l2_xconnect_dump, "")                                                 \
23527 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23528 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23529 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23530 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23531 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23532 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23533 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23534   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23535 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23536 _(sock_init_shm, "size <nnn>")                                          \
23537 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23538 _(dns_enable_disable, "[enable][disable]")                              \
23539 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23540 _(dns_resolve_name, "<hostname>")                                       \
23541 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23542 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23543 _(dns_resolve_name, "<hostname>")                                       \
23544 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23545   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23546 _(session_rules_dump, "")                                               \
23547 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23548 _(output_acl_set_interface,                                             \
23549   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23550   "  [l2-table <nn>] [del]")                                            \
23551 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23552
23553 /* List of command functions, CLI names map directly to functions */
23554 #define foreach_cli_function                                    \
23555 _(comment, "usage: comment <ignore-rest-of-line>")              \
23556 _(dump_interface_table, "usage: dump_interface_table")          \
23557 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23558 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23559 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23560 _(dump_macro_table, "usage: dump_macro_table ")                 \
23561 _(dump_node_table, "usage: dump_node_table")                    \
23562 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23563 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23564 _(echo, "usage: echo <message>")                                \
23565 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23566 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23567 _(help, "usage: help")                                          \
23568 _(q, "usage: quit")                                             \
23569 _(quit, "usage: quit")                                          \
23570 _(search_node_table, "usage: search_node_table <name>...")      \
23571 _(set, "usage: set <variable-name> <value>")                    \
23572 _(script, "usage: script <file-name>")                          \
23573 _(statseg, "usage: statseg");                                   \
23574 _(unset, "usage: unset <variable-name>")
23575
23576 #define _(N,n)                                  \
23577     static void vl_api_##n##_t_handler_uni      \
23578     (vl_api_##n##_t * mp)                       \
23579     {                                           \
23580         vat_main_t * vam = &vat_main;           \
23581         if (vam->json_output) {                 \
23582             vl_api_##n##_t_handler_json(mp);    \
23583         } else {                                \
23584             vl_api_##n##_t_handler(mp);         \
23585         }                                       \
23586     }
23587 foreach_vpe_api_reply_msg;
23588 #if VPP_API_TEST_BUILTIN == 0
23589 foreach_standalone_reply_msg;
23590 #endif
23591 #undef _
23592
23593 void
23594 vat_api_hookup (vat_main_t * vam)
23595 {
23596 #define _(N,n)                                                  \
23597     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23598                            vl_api_##n##_t_handler_uni,          \
23599                            vl_noop_handler,                     \
23600                            vl_api_##n##_t_endian,               \
23601                            vl_api_##n##_t_print,                \
23602                            sizeof(vl_api_##n##_t), 1);
23603   foreach_vpe_api_reply_msg;
23604 #if VPP_API_TEST_BUILTIN == 0
23605   foreach_standalone_reply_msg;
23606 #endif
23607 #undef _
23608
23609 #if (VPP_API_TEST_BUILTIN==0)
23610   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23611
23612   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23613
23614   vam->function_by_name = hash_create_string (0, sizeof (uword));
23615
23616   vam->help_by_name = hash_create_string (0, sizeof (uword));
23617 #endif
23618
23619   /* API messages we can send */
23620 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23621   foreach_vpe_api_msg;
23622 #undef _
23623
23624   /* Help strings */
23625 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23626   foreach_vpe_api_msg;
23627 #undef _
23628
23629   /* CLI functions */
23630 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23631   foreach_cli_function;
23632 #undef _
23633
23634   /* Help strings */
23635 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23636   foreach_cli_function;
23637 #undef _
23638 }
23639
23640 #if VPP_API_TEST_BUILTIN
23641 static clib_error_t *
23642 vat_api_hookup_shim (vlib_main_t * vm)
23643 {
23644   vat_api_hookup (&vat_main);
23645   return 0;
23646 }
23647
23648 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23649 #endif
23650
23651 /*
23652  * fd.io coding-style-patch-verification: ON
23653  *
23654  * Local Variables:
23655  * eval: (c-set-style "gnu")
23656  * End:
23657  */