bond: Add bonding driver and LACP protocol
[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 <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/in_out_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   vam->socket_client_main = &socket_client_main;
91   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
92                                    0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 int
102 vl_socket_client_read (int wait)
103 {
104   return -1;
105 };
106
107 int
108 vl_socket_client_write ()
109 {
110   return -1;
111 };
112
113 void *
114 vl_socket_client_msg_alloc (int nbytes)
115 {
116   return 0;
117 }
118 #endif
119
120
121 f64
122 vat_time_now (vat_main_t * vam)
123 {
124 #if VPP_API_TEST_BUILTIN
125   return vlib_time_now (vam->vlib_main);
126 #else
127   return clib_time_now (&vam->clib_time);
128 #endif
129 }
130
131 void
132 errmsg (char *fmt, ...)
133 {
134   vat_main_t *vam = &vat_main;
135   va_list va;
136   u8 *s;
137
138   va_start (va, fmt);
139   s = va_format (0, fmt, &va);
140   va_end (va);
141
142   vec_add1 (s, 0);
143
144 #if VPP_API_TEST_BUILTIN
145   vlib_cli_output (vam->vlib_main, (char *) s);
146 #else
147   {
148     if (vam->ifp != stdin)
149       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
150                vam->input_line_number);
151     fformat (vam->ofp, (char *) s);
152     fflush (vam->ofp);
153   }
154 #endif
155
156   vec_free (s);
157 }
158
159 #if VPP_API_TEST_BUILTIN == 0
160 static uword
161 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
162 {
163   vat_main_t *vam = va_arg (*args, vat_main_t *);
164   u32 *result = va_arg (*args, u32 *);
165   u8 *if_name;
166   uword *p;
167
168   if (!unformat (input, "%s", &if_name))
169     return 0;
170
171   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
172   if (p == 0)
173     return 0;
174   *result = p[0];
175   return 1;
176 }
177
178 /* Parse an IP4 address %d.%d.%d.%d. */
179 uword
180 unformat_ip4_address (unformat_input_t * input, va_list * args)
181 {
182   u8 *result = va_arg (*args, u8 *);
183   unsigned a[4];
184
185   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
186     return 0;
187
188   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
189     return 0;
190
191   result[0] = a[0];
192   result[1] = a[1];
193   result[2] = a[2];
194   result[3] = a[3];
195
196   return 1;
197 }
198
199 uword
200 unformat_ethernet_address (unformat_input_t * input, va_list * args)
201 {
202   u8 *result = va_arg (*args, u8 *);
203   u32 i, a[6];
204
205   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
206                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
207     return 0;
208
209   /* Check range. */
210   for (i = 0; i < 6; i++)
211     if (a[i] >= (1 << 8))
212       return 0;
213
214   for (i = 0; i < 6; i++)
215     result[i] = a[i];
216
217   return 1;
218 }
219
220 /* Returns ethernet type as an int in host byte order. */
221 uword
222 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
223                                         va_list * args)
224 {
225   u16 *result = va_arg (*args, u16 *);
226   int type;
227
228   /* Numeric type. */
229   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
230     {
231       if (type >= (1 << 16))
232         return 0;
233       *result = type;
234       return 1;
235     }
236   return 0;
237 }
238
239 /* Parse an IP6 address. */
240 uword
241 unformat_ip6_address (unformat_input_t * input, va_list * args)
242 {
243   ip6_address_t *result = va_arg (*args, ip6_address_t *);
244   u16 hex_quads[8];
245   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
246   uword c, n_colon, double_colon_index;
247
248   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
249   double_colon_index = ARRAY_LEN (hex_quads);
250   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
251     {
252       hex_digit = 16;
253       if (c >= '0' && c <= '9')
254         hex_digit = c - '0';
255       else if (c >= 'a' && c <= 'f')
256         hex_digit = c + 10 - 'a';
257       else if (c >= 'A' && c <= 'F')
258         hex_digit = c + 10 - 'A';
259       else if (c == ':' && n_colon < 2)
260         n_colon++;
261       else
262         {
263           unformat_put_input (input);
264           break;
265         }
266
267       /* Too many hex quads. */
268       if (n_hex_quads >= ARRAY_LEN (hex_quads))
269         return 0;
270
271       if (hex_digit < 16)
272         {
273           hex_quad = (hex_quad << 4) | hex_digit;
274
275           /* Hex quad must fit in 16 bits. */
276           if (n_hex_digits >= 4)
277             return 0;
278
279           n_colon = 0;
280           n_hex_digits++;
281         }
282
283       /* Save position of :: */
284       if (n_colon == 2)
285         {
286           /* More than one :: ? */
287           if (double_colon_index < ARRAY_LEN (hex_quads))
288             return 0;
289           double_colon_index = n_hex_quads;
290         }
291
292       if (n_colon > 0 && n_hex_digits > 0)
293         {
294           hex_quads[n_hex_quads++] = hex_quad;
295           hex_quad = 0;
296           n_hex_digits = 0;
297         }
298     }
299
300   if (n_hex_digits > 0)
301     hex_quads[n_hex_quads++] = hex_quad;
302
303   {
304     word i;
305
306     /* Expand :: to appropriate number of zero hex quads. */
307     if (double_colon_index < ARRAY_LEN (hex_quads))
308       {
309         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
310
311         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
312           hex_quads[n_zero + i] = hex_quads[i];
313
314         for (i = 0; i < n_zero; i++)
315           hex_quads[double_colon_index + i] = 0;
316
317         n_hex_quads = ARRAY_LEN (hex_quads);
318       }
319
320     /* Too few hex quads given. */
321     if (n_hex_quads < ARRAY_LEN (hex_quads))
322       return 0;
323
324     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
325       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
326
327     return 1;
328   }
329 }
330
331 uword
332 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
338   foreach_ipsec_policy_action
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 uword
346 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
347 {
348   u32 *r = va_arg (*args, u32 *);
349
350   if (0);
351 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
352   foreach_ipsec_crypto_alg
353 #undef _
354     else
355     return 0;
356   return 1;
357 }
358
359 u8 *
360 format_ipsec_crypto_alg (u8 * s, va_list * args)
361 {
362   u32 i = va_arg (*args, u32);
363   u8 *t = 0;
364
365   switch (i)
366     {
367 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
368       foreach_ipsec_crypto_alg
369 #undef _
370     default:
371       return format (s, "unknown");
372     }
373   return format (s, "%s", t);
374 }
375
376 uword
377 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
383   foreach_ipsec_integ_alg
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 uword
408 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
409 {
410   u32 *r = va_arg (*args, u32 *);
411
412   if (0);
413 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
414   foreach_ikev2_auth_method
415 #undef _
416     else
417     return 0;
418   return 1;
419 }
420
421 uword
422 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
423 {
424   u32 *r = va_arg (*args, u32 *);
425
426   if (0);
427 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
428   foreach_ikev2_id_type
429 #undef _
430     else
431     return 0;
432   return 1;
433 }
434 #else /* VPP_API_TEST_BUILTIN == 1 */
435 static uword
436 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
437 {
438   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
439   vnet_main_t *vnm = vnet_get_main ();
440   u32 *result = va_arg (*args, u32 *);
441   u32 sw_if_index;
442
443   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
444     return 0;
445
446   *result = sw_if_index;
447   return 1;
448 }
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 static uword
452 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
453 {
454   u8 *r = va_arg (*args, u8 *);
455
456   if (unformat (input, "kbps"))
457     *r = SSE2_QOS_RATE_KBPS;
458   else if (unformat (input, "pps"))
459     *r = SSE2_QOS_RATE_PPS;
460   else
461     return 0;
462   return 1;
463 }
464
465 static uword
466 unformat_policer_round_type (unformat_input_t * input, va_list * args)
467 {
468   u8 *r = va_arg (*args, u8 *);
469
470   if (unformat (input, "closest"))
471     *r = SSE2_QOS_ROUND_TO_CLOSEST;
472   else if (unformat (input, "up"))
473     *r = SSE2_QOS_ROUND_TO_UP;
474   else if (unformat (input, "down"))
475     *r = SSE2_QOS_ROUND_TO_DOWN;
476   else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "1r2c"))
487     *r = SSE2_QOS_POLICER_TYPE_1R2C;
488   else if (unformat (input, "1r3c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
490   else if (unformat (input, "2r3c-2698"))
491     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
492   else if (unformat (input, "2r3c-4115"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
494   else if (unformat (input, "2r3c-mef5cf1"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
496   else
497     return 0;
498   return 1;
499 }
500
501 static uword
502 unformat_dscp (unformat_input_t * input, va_list * va)
503 {
504   u8 *r = va_arg (*va, u8 *);
505
506   if (0);
507 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
508   foreach_vnet_dscp
509 #undef _
510     else
511     return 0;
512   return 1;
513 }
514
515 static uword
516 unformat_policer_action_type (unformat_input_t * input, va_list * va)
517 {
518   sse2_qos_pol_action_params_st *a
519     = va_arg (*va, sse2_qos_pol_action_params_st *);
520
521   if (unformat (input, "drop"))
522     a->action_type = SSE2_QOS_ACTION_DROP;
523   else if (unformat (input, "transmit"))
524     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
525   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
526     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
527   else
528     return 0;
529   return 1;
530 }
531
532 static uword
533 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
534 {
535   u32 *r = va_arg (*va, u32 *);
536   u32 tid;
537
538   if (unformat (input, "ip4"))
539     tid = POLICER_CLASSIFY_TABLE_IP4;
540   else if (unformat (input, "ip6"))
541     tid = POLICER_CLASSIFY_TABLE_IP6;
542   else if (unformat (input, "l2"))
543     tid = POLICER_CLASSIFY_TABLE_L2;
544   else
545     return 0;
546
547   *r = tid;
548   return 1;
549 }
550
551 static uword
552 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
553 {
554   u32 *r = va_arg (*va, u32 *);
555   u32 tid;
556
557   if (unformat (input, "ip4"))
558     tid = FLOW_CLASSIFY_TABLE_IP4;
559   else if (unformat (input, "ip6"))
560     tid = FLOW_CLASSIFY_TABLE_IP6;
561   else
562     return 0;
563
564   *r = tid;
565   return 1;
566 }
567
568 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
569 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
570 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
571 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
572
573 #if (VPP_API_TEST_BUILTIN==0)
574 uword
575 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
576 {
577   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
578   mfib_itf_attribute_t attr;
579
580   old = *iflags;
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_long_names[attr]))
584       *iflags |= (1 << attr);
585   }
586   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
587   {
588     if (unformat (input, mfib_itf_flag_names[attr]))
589       *iflags |= (1 << attr);
590   }
591
592   return (old == *iflags ? 0 : 1);
593 }
594
595 uword
596 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
597 {
598   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
599   mfib_entry_attribute_t attr;
600
601   old = *eflags;
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_long_names[attr]))
605       *eflags |= (1 << attr);
606   }
607   FOR_EACH_MFIB_ATTRIBUTE (attr)
608   {
609     if (unformat (input, mfib_flag_names[attr]))
610       *eflags |= (1 << attr);
611   }
612
613   return (old == *eflags ? 0 : 1);
614 }
615
616 u8 *
617 format_ip4_address (u8 * s, va_list * args)
618 {
619   u8 *a = va_arg (*args, u8 *);
620   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
621 }
622
623 u8 *
624 format_ip6_address (u8 * s, va_list * args)
625 {
626   ip6_address_t *a = va_arg (*args, ip6_address_t *);
627   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
628
629   i_max_n_zero = ARRAY_LEN (a->as_u16);
630   max_n_zeros = 0;
631   i_first_zero = i_max_n_zero;
632   n_zeros = 0;
633   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
634     {
635       u32 is_zero = a->as_u16[i] == 0;
636       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
637         {
638           i_first_zero = i;
639           n_zeros = 0;
640         }
641       n_zeros += is_zero;
642       if ((!is_zero && n_zeros > max_n_zeros)
643           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
644         {
645           i_max_n_zero = i_first_zero;
646           max_n_zeros = n_zeros;
647           i_first_zero = ARRAY_LEN (a->as_u16);
648           n_zeros = 0;
649         }
650     }
651
652   last_double_colon = 0;
653   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
654     {
655       if (i == i_max_n_zero && max_n_zeros > 1)
656         {
657           s = format (s, "::");
658           i += max_n_zeros - 1;
659           last_double_colon = 1;
660         }
661       else
662         {
663           s = format (s, "%s%x",
664                       (last_double_colon || i == 0) ? "" : ":",
665                       clib_net_to_host_u16 (a->as_u16[i]));
666           last_double_colon = 0;
667         }
668     }
669
670   return s;
671 }
672
673 /* Format an IP46 address. */
674 u8 *
675 format_ip46_address (u8 * s, va_list * args)
676 {
677   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
678   ip46_type_t type = va_arg (*args, ip46_type_t);
679   int is_ip4 = 1;
680
681   switch (type)
682     {
683     case IP46_TYPE_ANY:
684       is_ip4 = ip46_address_is_ip4 (ip46);
685       break;
686     case IP46_TYPE_IP4:
687       is_ip4 = 1;
688       break;
689     case IP46_TYPE_IP6:
690       is_ip4 = 0;
691       break;
692     }
693
694   return is_ip4 ?
695     format (s, "%U", format_ip4_address, &ip46->ip4) :
696     format (s, "%U", format_ip6_address, &ip46->ip6);
697 }
698
699 u8 *
700 format_ethernet_address (u8 * s, va_list * args)
701 {
702   u8 *a = va_arg (*args, u8 *);
703
704   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
705                  a[0], a[1], a[2], a[3], a[4], a[5]);
706 }
707 #endif
708
709 static void
710 increment_v4_address (ip4_address_t * a)
711 {
712   u32 v;
713
714   v = ntohl (a->as_u32) + 1;
715   a->as_u32 = ntohl (v);
716 }
717
718 static void
719 increment_v6_address (ip6_address_t * a)
720 {
721   u64 v0, v1;
722
723   v0 = clib_net_to_host_u64 (a->as_u64[0]);
724   v1 = clib_net_to_host_u64 (a->as_u64[1]);
725
726   v1 += 1;
727   if (v1 == 0)
728     v0 += 1;
729   a->as_u64[0] = clib_net_to_host_u64 (v0);
730   a->as_u64[1] = clib_net_to_host_u64 (v1);
731 }
732
733 static void
734 increment_mac_address (u8 * mac)
735 {
736   u64 tmp = *((u64 *) mac);
737   tmp = clib_net_to_host_u64 (tmp);
738   tmp += 1 << 16;               /* skip unused (least significant) octets */
739   tmp = clib_host_to_net_u64 (tmp);
740
741   clib_memcpy (mac, &tmp, 6);
742 }
743
744 static void vl_api_create_loopback_reply_t_handler
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   i32 retval = ntohl (mp->retval);
749
750   vam->retval = retval;
751   vam->regenerate_interface_table = 1;
752   vam->sw_if_index = ntohl (mp->sw_if_index);
753   vam->result_ready = 1;
754 }
755
756 static void vl_api_create_loopback_reply_t_handler_json
757   (vl_api_create_loopback_reply_t * mp)
758 {
759   vat_main_t *vam = &vat_main;
760   vat_json_node_t node;
761
762   vat_json_init_object (&node);
763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
765
766   vat_json_print (vam->ofp, &node);
767   vat_json_free (&node);
768   vam->retval = ntohl (mp->retval);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   i32 retval = ntohl (mp->retval);
777
778   vam->retval = retval;
779   vam->regenerate_interface_table = 1;
780   vam->sw_if_index = ntohl (mp->sw_if_index);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_loopback_instance_reply_t_handler_json
785   (vl_api_create_loopback_instance_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   vat_json_node_t node;
789
790   vat_json_init_object (&node);
791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
792   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
793
794   vat_json_print (vam->ofp, &node);
795   vat_json_free (&node);
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->sw_if_index = ntohl (mp->sw_if_index);
809   vam->result_ready = 1;
810 }
811
812 static void vl_api_af_packet_create_reply_t_handler_json
813   (vl_api_af_packet_create_reply_t * mp)
814 {
815   vat_main_t *vam = &vat_main;
816   vat_json_node_t node;
817
818   vat_json_init_object (&node);
819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
821
822   vat_json_print (vam->ofp, &node);
823   vat_json_free (&node);
824
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_vlan_subif_reply_t_handler_json
842   (vl_api_create_vlan_subif_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_subif_reply_t_handler_json
871   (vl_api_create_subif_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_interface_name_renumber_reply_t_handler
888   (vl_api_interface_name_renumber_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_interface_name_renumber_reply_t_handler_json
899   (vl_api_interface_name_renumber_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 /*
915  * Special-case: build the interface table, maintain
916  * the next loopback sw_if_index vbl.
917  */
918 static void vl_api_sw_interface_details_t_handler
919   (vl_api_sw_interface_details_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   u8 *s = format (0, "%s%c", mp->interface_name, 0);
923
924   hash_set_mem (vam->sw_if_index_by_interface_name, s,
925                 ntohl (mp->sw_if_index));
926
927   /* In sub interface case, fill the sub interface table entry */
928   if (mp->sw_if_index != mp->sup_sw_if_index)
929     {
930       sw_interface_subif_t *sub = NULL;
931
932       vec_add2 (vam->sw_if_subif_table, sub, 1);
933
934       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
935       strncpy ((char *) sub->interface_name, (char *) s,
936                vec_len (sub->interface_name));
937       sub->sw_if_index = ntohl (mp->sw_if_index);
938       sub->sub_id = ntohl (mp->sub_id);
939
940       sub->sub_dot1ad = mp->sub_dot1ad;
941       sub->sub_number_of_tags = mp->sub_number_of_tags;
942       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
943       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
944       sub->sub_exact_match = mp->sub_exact_match;
945       sub->sub_default = mp->sub_default;
946       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
947       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
948
949       /* vlan tag rewrite */
950       sub->vtr_op = ntohl (mp->vtr_op);
951       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
952       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
953       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
954     }
955 }
956
957 static void vl_api_sw_interface_details_t_handler_json
958   (vl_api_sw_interface_details_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   vat_json_node_t *node = NULL;
962
963   if (VAT_JSON_ARRAY != vam->json_tree.type)
964     {
965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
966       vat_json_init_array (&vam->json_tree);
967     }
968   node = vat_json_array_add (&vam->json_tree);
969
970   vat_json_init_object (node);
971   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
972   vat_json_object_add_uint (node, "sup_sw_if_index",
973                             ntohl (mp->sup_sw_if_index));
974   vat_json_object_add_uint (node, "l2_address_length",
975                             ntohl (mp->l2_address_length));
976   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
977                              sizeof (mp->l2_address));
978   vat_json_object_add_string_copy (node, "interface_name",
979                                    mp->interface_name);
980   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
981   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
982   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
983   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
984   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
985   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
986   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
987   vat_json_object_add_uint (node, "sub_number_of_tags",
988                             mp->sub_number_of_tags);
989   vat_json_object_add_uint (node, "sub_outer_vlan_id",
990                             ntohs (mp->sub_outer_vlan_id));
991   vat_json_object_add_uint (node, "sub_inner_vlan_id",
992                             ntohs (mp->sub_inner_vlan_id));
993   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
994   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
995   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
996                             mp->sub_outer_vlan_id_any);
997   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
998                             mp->sub_inner_vlan_id_any);
999   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1000   vat_json_object_add_uint (node, "vtr_push_dot1q",
1001                             ntohl (mp->vtr_push_dot1q));
1002   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1003   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1004   if (mp->sub_dot1ah)
1005     {
1006       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1007                                        format (0, "%U",
1008                                                format_ethernet_address,
1009                                                &mp->b_dmac));
1010       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1011                                        format (0, "%U",
1012                                                format_ethernet_address,
1013                                                &mp->b_smac));
1014       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1015       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1016     }
1017 }
1018
1019 #if VPP_API_TEST_BUILTIN == 0
1020 static void vl_api_sw_interface_event_t_handler
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   if (vam->interface_event_display)
1025     errmsg ("interface flags: sw_if_index %d %s %s",
1026             ntohl (mp->sw_if_index),
1027             mp->admin_up_down ? "admin-up" : "admin-down",
1028             mp->link_up_down ? "link-up" : "link-down");
1029 }
1030 #endif
1031
1032 static void vl_api_sw_interface_event_t_handler_json
1033   (vl_api_sw_interface_event_t * mp)
1034 {
1035   /* JSON output not supported */
1036 }
1037
1038 static void
1039 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1040 {
1041   vat_main_t *vam = &vat_main;
1042   i32 retval = ntohl (mp->retval);
1043
1044   vam->retval = retval;
1045   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1046   vam->result_ready = 1;
1047 }
1048
1049 static void
1050 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1051 {
1052   vat_main_t *vam = &vat_main;
1053   vat_json_node_t node;
1054   api_main_t *am = &api_main;
1055   void *oldheap;
1056   u8 *reply;
1057
1058   vat_json_init_object (&node);
1059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1060   vat_json_object_add_uint (&node, "reply_in_shmem",
1061                             ntohl (mp->reply_in_shmem));
1062   /* Toss the shared-memory original... */
1063   pthread_mutex_lock (&am->vlib_rp->mutex);
1064   oldheap = svm_push_data_heap (am->vlib_rp);
1065
1066   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1067   vec_free (reply);
1068
1069   svm_pop_heap (oldheap);
1070   pthread_mutex_unlock (&am->vlib_rp->mutex);
1071
1072   vat_json_print (vam->ofp, &node);
1073   vat_json_free (&node);
1074
1075   vam->retval = ntohl (mp->retval);
1076   vam->result_ready = 1;
1077 }
1078
1079 static void
1080 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   i32 retval = ntohl (mp->retval);
1084   u32 length = ntohl (mp->length);
1085
1086   vec_reset_length (vam->cmd_reply);
1087
1088   vam->retval = retval;
1089   if (retval == 0)
1090     {
1091       vec_validate (vam->cmd_reply, length);
1092       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1093       vam->cmd_reply[length] = 0;
1094     }
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103
1104   vec_reset_length (vam->cmd_reply);
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_classify_add_del_table_reply_t_handler
1118   (vl_api_classify_add_del_table_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0 &&
1130           ((mp->new_table_index != 0xFFFFFFFF) ||
1131            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1132            (mp->match_n_vectors != 0xFFFFFFFF)))
1133         /*
1134          * Note: this is just barely thread-safe, depends on
1135          * the main thread spinning waiting for an answer...
1136          */
1137         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1138                 ntohl (mp->new_table_index),
1139                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1140       vam->result_ready = 1;
1141     }
1142 }
1143
1144 static void vl_api_classify_add_del_table_reply_t_handler_json
1145   (vl_api_classify_add_del_table_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vat_json_init_object (&node);
1151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1152   vat_json_object_add_uint (&node, "new_table_index",
1153                             ntohl (mp->new_table_index));
1154   vat_json_object_add_uint (&node, "skip_n_vectors",
1155                             ntohl (mp->skip_n_vectors));
1156   vat_json_object_add_uint (&node, "match_n_vectors",
1157                             ntohl (mp->match_n_vectors));
1158
1159   vat_json_print (vam->ofp, &node);
1160   vat_json_free (&node);
1161
1162   vam->retval = ntohl (mp->retval);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void vl_api_get_node_index_reply_t_handler
1167   (vl_api_get_node_index_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   i32 retval = ntohl (mp->retval);
1171   if (vam->async_mode)
1172     {
1173       vam->async_errors += (retval < 0);
1174     }
1175   else
1176     {
1177       vam->retval = retval;
1178       if (retval == 0)
1179         errmsg ("node index %d", ntohl (mp->node_index));
1180       vam->result_ready = 1;
1181     }
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler_json
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   vat_json_node_t node;
1189
1190   vat_json_init_object (&node);
1191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1192   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1193
1194   vat_json_print (vam->ofp, &node);
1195   vat_json_free (&node);
1196
1197   vam->retval = ntohl (mp->retval);
1198   vam->result_ready = 1;
1199 }
1200
1201 static void vl_api_get_next_index_reply_t_handler
1202   (vl_api_get_next_index_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   i32 retval = ntohl (mp->retval);
1206   if (vam->async_mode)
1207     {
1208       vam->async_errors += (retval < 0);
1209     }
1210   else
1211     {
1212       vam->retval = retval;
1213       if (retval == 0)
1214         errmsg ("next node index %d", ntohl (mp->next_index));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler_json
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1228
1229   vat_json_print (vam->ofp, &node);
1230   vat_json_free (&node);
1231
1232   vam->retval = ntohl (mp->retval);
1233   vam->result_ready = 1;
1234 }
1235
1236 static void vl_api_add_node_next_reply_t_handler
1237   (vl_api_add_node_next_reply_t * mp)
1238 {
1239   vat_main_t *vam = &vat_main;
1240   i32 retval = ntohl (mp->retval);
1241   if (vam->async_mode)
1242     {
1243       vam->async_errors += (retval < 0);
1244     }
1245   else
1246     {
1247       vam->retval = retval;
1248       if (retval == 0)
1249         errmsg ("next index %d", ntohl (mp->next_index));
1250       vam->result_ready = 1;
1251     }
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler_json
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   vat_json_node_t node;
1259
1260   vat_json_init_object (&node);
1261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1262   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1263
1264   vat_json_print (vam->ofp, &node);
1265   vat_json_free (&node);
1266
1267   vam->retval = ntohl (mp->retval);
1268   vam->result_ready = 1;
1269 }
1270
1271 static void vl_api_show_version_reply_t_handler
1272   (vl_api_show_version_reply_t * mp)
1273 {
1274   vat_main_t *vam = &vat_main;
1275   i32 retval = ntohl (mp->retval);
1276
1277   if (retval >= 0)
1278     {
1279       errmsg ("        program: %s", mp->program);
1280       errmsg ("        version: %s", mp->version);
1281       errmsg ("     build date: %s", mp->build_date);
1282       errmsg ("build directory: %s", mp->build_directory);
1283     }
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_show_version_reply_t_handler_json
1289   (vl_api_show_version_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   vat_json_node_t node;
1293
1294   vat_json_init_object (&node);
1295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1296   vat_json_object_add_string_copy (&node, "program", mp->program);
1297   vat_json_object_add_string_copy (&node, "version", mp->version);
1298   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1299   vat_json_object_add_string_copy (&node, "build_directory",
1300                                    mp->build_directory);
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void
1310 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1311 {
1312   u32 sw_if_index = ntohl (mp->sw_if_index);
1313   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1314           mp->mac_ip ? "mac/ip binding" : "address resolution",
1315           ntohl (mp->pid), format_ip4_address, &mp->address,
1316           format_ethernet_address, mp->new_mac, sw_if_index);
1317 }
1318
1319 static void
1320 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1321 {
1322   /* JSON output not supported */
1323 }
1324
1325 static void
1326 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1327 {
1328   u32 sw_if_index = ntohl (mp->sw_if_index);
1329   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1330           mp->mac_ip ? "mac/ip binding" : "address resolution",
1331           ntohl (mp->pid), format_ip6_address, mp->address,
1332           format_ethernet_address, mp->new_mac, sw_if_index);
1333 }
1334
1335 static void
1336 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1337 {
1338   /* JSON output not supported */
1339 }
1340
1341 static void
1342 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1343 {
1344   u32 n_macs = ntohl (mp->n_macs);
1345   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1346           ntohl (mp->pid), mp->client_index, n_macs);
1347   int i;
1348   for (i = 0; i < n_macs; i++)
1349     {
1350       vl_api_mac_entry_t *mac = &mp->mac[i];
1351       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->action);
1354       if (i == 1000)
1355         break;
1356     }
1357 }
1358
1359 static void
1360 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1361 {
1362   /* JSON output not supported */
1363 }
1364
1365 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1366 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1367
1368 /*
1369  * Special-case: build the bridge domain table, maintain
1370  * the next bd id vbl.
1371  */
1372 static void vl_api_bridge_domain_details_t_handler
1373   (vl_api_bridge_domain_details_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1377   int i;
1378
1379   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1380          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1381
1382   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1383          ntohl (mp->bd_id), mp->learn, mp->forward,
1384          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1385
1386   if (n_sw_ifs)
1387     {
1388       vl_api_bridge_domain_sw_if_t *sw_ifs;
1389       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1390              "Interface Name");
1391
1392       sw_ifs = mp->sw_if_details;
1393       for (i = 0; i < n_sw_ifs; i++)
1394         {
1395           u8 *sw_if_name = 0;
1396           u32 sw_if_index;
1397           hash_pair_t *p;
1398
1399           sw_if_index = ntohl (sw_ifs->sw_if_index);
1400
1401           /* *INDENT-OFF* */
1402           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1403                              ({
1404                                if ((u32) p->value[0] == sw_if_index)
1405                                  {
1406                                    sw_if_name = (u8 *)(p->key);
1407                                    break;
1408                                  }
1409                              }));
1410           /* *INDENT-ON* */
1411           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1412                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1413                  "sw_if_index not found!");
1414
1415           sw_ifs++;
1416         }
1417     }
1418 }
1419
1420 static void vl_api_bridge_domain_details_t_handler_json
1421   (vl_api_bridge_domain_details_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   vat_json_node_t *node, *array = NULL;
1425   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1426
1427   if (VAT_JSON_ARRAY != vam->json_tree.type)
1428     {
1429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1430       vat_json_init_array (&vam->json_tree);
1431     }
1432   node = vat_json_array_add (&vam->json_tree);
1433
1434   vat_json_init_object (node);
1435   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1436   vat_json_object_add_uint (node, "flood", mp->flood);
1437   vat_json_object_add_uint (node, "forward", mp->forward);
1438   vat_json_object_add_uint (node, "learn", mp->learn);
1439   vat_json_object_add_uint (node, "bvi_sw_if_index",
1440                             ntohl (mp->bvi_sw_if_index));
1441   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1442   array = vat_json_object_add (node, "sw_if");
1443   vat_json_init_array (array);
1444
1445
1446
1447   if (n_sw_ifs)
1448     {
1449       vl_api_bridge_domain_sw_if_t *sw_ifs;
1450       int i;
1451
1452       sw_ifs = mp->sw_if_details;
1453       for (i = 0; i < n_sw_ifs; i++)
1454         {
1455           node = vat_json_array_add (array);
1456           vat_json_init_object (node);
1457           vat_json_object_add_uint (node, "sw_if_index",
1458                                     ntohl (sw_ifs->sw_if_index));
1459           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1460           sw_ifs++;
1461         }
1462     }
1463 }
1464
1465 static void vl_api_control_ping_reply_t_handler
1466   (vl_api_control_ping_reply_t * mp)
1467 {
1468   vat_main_t *vam = &vat_main;
1469   i32 retval = ntohl (mp->retval);
1470   if (vam->async_mode)
1471     {
1472       vam->async_errors += (retval < 0);
1473     }
1474   else
1475     {
1476       vam->retval = retval;
1477       vam->result_ready = 1;
1478     }
1479   if (vam->socket_client_main)
1480     vam->socket_client_main->control_pings_outstanding--;
1481 }
1482
1483 static void vl_api_control_ping_reply_t_handler_json
1484   (vl_api_control_ping_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488
1489   if (VAT_JSON_NONE != vam->json_tree.type)
1490     {
1491       vat_json_print (vam->ofp, &vam->json_tree);
1492       vat_json_free (&vam->json_tree);
1493       vam->json_tree.type = VAT_JSON_NONE;
1494     }
1495   else
1496     {
1497       /* just print [] */
1498       vat_json_init_array (&vam->json_tree);
1499       vat_json_print (vam->ofp, &vam->json_tree);
1500       vam->json_tree.type = VAT_JSON_NONE;
1501     }
1502
1503   vam->retval = retval;
1504   vam->result_ready = 1;
1505 }
1506
1507 static void
1508   vl_api_bridge_domain_set_mac_age_reply_t_handler
1509   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1525   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void
1541 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2_flags_reply_t_handler_json
1557   (vl_api_l2_flags_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1565                             ntohl (mp->resulting_feature_bitmap));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_bridge_flags_reply_t_handler
1575   (vl_api_bridge_flags_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_bridge_flags_reply_t_handler_json
1591   (vl_api_bridge_flags_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1599                             ntohl (mp->resulting_feature_bitmap));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_tap_connect_reply_t_handler
1609   (vl_api_tap_connect_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623
1624 }
1625
1626 static void vl_api_tap_connect_reply_t_handler_json
1627   (vl_api_tap_connect_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641
1642 }
1643
1644 static void
1645 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_tap_modify_reply_t_handler_json
1662   (vl_api_tap_modify_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void
1679 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   i32 retval = ntohl (mp->retval);
1683   if (vam->async_mode)
1684     {
1685       vam->async_errors += (retval < 0);
1686     }
1687   else
1688     {
1689       vam->retval = retval;
1690       vam->result_ready = 1;
1691     }
1692 }
1693
1694 static void vl_api_tap_delete_reply_t_handler_json
1695   (vl_api_tap_delete_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   vat_json_node_t node;
1699
1700   vat_json_init_object (&node);
1701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void
1711 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   i32 retval = ntohl (mp->retval);
1715   if (vam->async_mode)
1716     {
1717       vam->async_errors += (retval < 0);
1718     }
1719   else
1720     {
1721       vam->retval = retval;
1722       vam->sw_if_index = ntohl (mp->sw_if_index);
1723       vam->result_ready = 1;
1724     }
1725
1726 }
1727
1728 static void vl_api_tap_create_v2_reply_t_handler_json
1729   (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   vat_json_node_t node;
1733
1734   vat_json_init_object (&node);
1735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1736   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1737
1738   vat_json_print (vam->ofp, &node);
1739   vat_json_free (&node);
1740
1741   vam->retval = ntohl (mp->retval);
1742   vam->result_ready = 1;
1743
1744 }
1745
1746 static void
1747 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   i32 retval = ntohl (mp->retval);
1751   if (vam->async_mode)
1752     {
1753       vam->async_errors += (retval < 0);
1754     }
1755   else
1756     {
1757       vam->retval = retval;
1758       vam->result_ready = 1;
1759     }
1760 }
1761
1762 static void vl_api_tap_delete_v2_reply_t_handler_json
1763   (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   vat_json_node_t node;
1767
1768   vat_json_init_object (&node);
1769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1770
1771   vat_json_print (vam->ofp, &node);
1772   vat_json_free (&node);
1773
1774   vam->retval = ntohl (mp->retval);
1775   vam->result_ready = 1;
1776 }
1777
1778 static void
1779 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   i32 retval = ntohl (mp->retval);
1783
1784   if (vam->async_mode)
1785     {
1786       vam->async_errors += (retval < 0);
1787     }
1788   else
1789     {
1790       vam->retval = retval;
1791       vam->sw_if_index = ntohl (mp->sw_if_index);
1792       vam->result_ready = 1;
1793     }
1794 }
1795
1796 static void vl_api_bond_create_reply_t_handler_json
1797   (vl_api_bond_create_reply_t * mp)
1798 {
1799   vat_main_t *vam = &vat_main;
1800   vat_json_node_t node;
1801
1802   vat_json_init_object (&node);
1803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1805
1806   vat_json_print (vam->ofp, &node);
1807   vat_json_free (&node);
1808
1809   vam->retval = ntohl (mp->retval);
1810   vam->result_ready = 1;
1811 }
1812
1813 static void
1814 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   i32 retval = ntohl (mp->retval);
1818
1819   if (vam->async_mode)
1820     {
1821       vam->async_errors += (retval < 0);
1822     }
1823   else
1824     {
1825       vam->retval = retval;
1826       vam->result_ready = 1;
1827     }
1828 }
1829
1830 static void vl_api_bond_delete_reply_t_handler_json
1831   (vl_api_bond_delete_reply_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   vat_json_node_t node;
1835
1836   vat_json_init_object (&node);
1837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1838
1839   vat_json_print (vam->ofp, &node);
1840   vat_json_free (&node);
1841
1842   vam->retval = ntohl (mp->retval);
1843   vam->result_ready = 1;
1844 }
1845
1846 static void
1847 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851
1852   if (vam->async_mode)
1853     {
1854       vam->async_errors += (retval < 0);
1855     }
1856   else
1857     {
1858       vam->retval = retval;
1859       vam->result_ready = 1;
1860     }
1861 }
1862
1863 static void vl_api_bond_enslave_reply_t_handler_json
1864   (vl_api_bond_enslave_reply_t * mp)
1865 {
1866   vat_main_t *vam = &vat_main;
1867   vat_json_node_t node;
1868
1869   vat_json_init_object (&node);
1870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1871
1872   vat_json_print (vam->ofp, &node);
1873   vat_json_free (&node);
1874
1875   vam->retval = ntohl (mp->retval);
1876   vam->result_ready = 1;
1877 }
1878
1879 static void
1880 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1881                                           mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   i32 retval = ntohl (mp->retval);
1885
1886   if (vam->async_mode)
1887     {
1888       vam->async_errors += (retval < 0);
1889     }
1890   else
1891     {
1892       vam->retval = retval;
1893       vam->result_ready = 1;
1894     }
1895 }
1896
1897 static void vl_api_bond_detach_slave_reply_t_handler_json
1898   (vl_api_bond_detach_slave_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   vat_json_node_t node;
1902
1903   vat_json_init_object (&node);
1904   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1905
1906   vat_json_print (vam->ofp, &node);
1907   vat_json_free (&node);
1908
1909   vam->retval = ntohl (mp->retval);
1910   vam->result_ready = 1;
1911 }
1912
1913 static void vl_api_sw_interface_bond_details_t_handler
1914   (vl_api_sw_interface_bond_details_t * mp)
1915 {
1916   vat_main_t *vam = &vat_main;
1917
1918   print (vam->ofp,
1919          "%-16s %-12d %-12U %-13U %-14u %-14u",
1920          mp->interface_name, ntohl (mp->sw_if_index),
1921          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1922          ntohl (mp->active_slaves), ntohl (mp->slaves));
1923 }
1924
1925 static void vl_api_sw_interface_bond_details_t_handler_json
1926   (vl_api_sw_interface_bond_details_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   vat_json_node_t *node = NULL;
1930
1931   if (VAT_JSON_ARRAY != vam->json_tree.type)
1932     {
1933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1934       vat_json_init_array (&vam->json_tree);
1935     }
1936   node = vat_json_array_add (&vam->json_tree);
1937
1938   vat_json_init_object (node);
1939   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1940   vat_json_object_add_string_copy (node, "interface_name",
1941                                    mp->interface_name);
1942   vat_json_object_add_uint (node, "mode", mp->mode);
1943   vat_json_object_add_uint (node, "load_balance", mp->lb);
1944   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1945   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1946 }
1947
1948 static int
1949 api_sw_interface_bond_dump (vat_main_t * vam)
1950 {
1951   vl_api_sw_interface_bond_dump_t *mp;
1952   vl_api_control_ping_t *mp_ping;
1953   int ret;
1954
1955   print (vam->ofp,
1956          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1957          "interface name", "sw_if_index", "mode", "load balance",
1958          "active slaves", "slaves");
1959
1960   /* Get list of bond interfaces */
1961   M (SW_INTERFACE_BOND_DUMP, mp);
1962   S (mp);
1963
1964   /* Use a control ping for synchronization */
1965   MPING (CONTROL_PING, mp_ping);
1966   S (mp_ping);
1967
1968   W (ret);
1969   return ret;
1970 }
1971
1972 static void vl_api_sw_interface_slave_details_t_handler
1973   (vl_api_sw_interface_slave_details_t * mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976
1977   print (vam->ofp,
1978          "%-25s %-12d %-12d %d", mp->interface_name,
1979          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1980 }
1981
1982 static void vl_api_sw_interface_slave_details_t_handler_json
1983   (vl_api_sw_interface_slave_details_t * mp)
1984 {
1985   vat_main_t *vam = &vat_main;
1986   vat_json_node_t *node = NULL;
1987
1988   if (VAT_JSON_ARRAY != vam->json_tree.type)
1989     {
1990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1991       vat_json_init_array (&vam->json_tree);
1992     }
1993   node = vat_json_array_add (&vam->json_tree);
1994
1995   vat_json_init_object (node);
1996   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1997   vat_json_object_add_string_copy (node, "interface_name",
1998                                    mp->interface_name);
1999   vat_json_object_add_uint (node, "passive", mp->is_passive);
2000   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2001 }
2002
2003 static int
2004 api_sw_interface_slave_dump (vat_main_t * vam)
2005 {
2006   unformat_input_t *i = vam->input;
2007   vl_api_sw_interface_slave_dump_t *mp;
2008   vl_api_control_ping_t *mp_ping;
2009   u32 sw_if_index = ~0;
2010   u8 sw_if_index_set = 0;
2011   int ret;
2012
2013   /* Parse args required to build the message */
2014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2015     {
2016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2017         sw_if_index_set = 1;
2018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2019         sw_if_index_set = 1;
2020       else
2021         break;
2022     }
2023
2024   if (sw_if_index_set == 0)
2025     {
2026       errmsg ("missing vpp interface name. ");
2027       return -99;
2028     }
2029
2030   print (vam->ofp,
2031          "\n%-25s %-12s %-12s %s",
2032          "slave interface name", "sw_if_index", "passive", "long_timeout");
2033
2034   /* Get list of bond interfaces */
2035   M (SW_INTERFACE_SLAVE_DUMP, mp);
2036   mp->sw_if_index = ntohl (sw_if_index);
2037   S (mp);
2038
2039   /* Use a control ping for synchronization */
2040   MPING (CONTROL_PING, mp_ping);
2041   S (mp_ping);
2042
2043   W (ret);
2044   return ret;
2045 }
2046
2047 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2048   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2049 {
2050   vat_main_t *vam = &vat_main;
2051   i32 retval = ntohl (mp->retval);
2052   if (vam->async_mode)
2053     {
2054       vam->async_errors += (retval < 0);
2055     }
2056   else
2057     {
2058       vam->retval = retval;
2059       vam->result_ready = 1;
2060     }
2061 }
2062
2063 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2064   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2065 {
2066   vat_main_t *vam = &vat_main;
2067   vat_json_node_t node;
2068
2069   vat_json_init_object (&node);
2070   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2071   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2072                             ntohl (mp->sw_if_index));
2073
2074   vat_json_print (vam->ofp, &node);
2075   vat_json_free (&node);
2076
2077   vam->retval = ntohl (mp->retval);
2078   vam->result_ready = 1;
2079 }
2080
2081 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2082   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2083 {
2084   vat_main_t *vam = &vat_main;
2085   i32 retval = ntohl (mp->retval);
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->sw_if_index = ntohl (mp->sw_if_index);
2094       vam->result_ready = 1;
2095     }
2096 }
2097
2098 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2099   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102   vat_json_node_t node;
2103
2104   vat_json_init_object (&node);
2105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2106   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2107
2108   vat_json_print (vam->ofp, &node);
2109   vat_json_free (&node);
2110
2111   vam->retval = ntohl (mp->retval);
2112   vam->result_ready = 1;
2113 }
2114
2115 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2116   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2117 {
2118   vat_main_t *vam = &vat_main;
2119   i32 retval = ntohl (mp->retval);
2120   if (vam->async_mode)
2121     {
2122       vam->async_errors += (retval < 0);
2123     }
2124   else
2125     {
2126       vam->retval = retval;
2127       vam->result_ready = 1;
2128     }
2129 }
2130
2131 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2132   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2133 {
2134   vat_main_t *vam = &vat_main;
2135   vat_json_node_t node;
2136
2137   vat_json_init_object (&node);
2138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2139   vat_json_object_add_uint (&node, "fwd_entry_index",
2140                             clib_net_to_host_u32 (mp->fwd_entry_index));
2141
2142   vat_json_print (vam->ofp, &node);
2143   vat_json_free (&node);
2144
2145   vam->retval = ntohl (mp->retval);
2146   vam->result_ready = 1;
2147 }
2148
2149 u8 *
2150 format_lisp_transport_protocol (u8 * s, va_list * args)
2151 {
2152   u32 proto = va_arg (*args, u32);
2153
2154   switch (proto)
2155     {
2156     case 1:
2157       return format (s, "udp");
2158     case 2:
2159       return format (s, "api");
2160     default:
2161       return 0;
2162     }
2163   return 0;
2164 }
2165
2166 static void vl_api_one_get_transport_protocol_reply_t_handler
2167   (vl_api_one_get_transport_protocol_reply_t * mp)
2168 {
2169   vat_main_t *vam = &vat_main;
2170   i32 retval = ntohl (mp->retval);
2171   if (vam->async_mode)
2172     {
2173       vam->async_errors += (retval < 0);
2174     }
2175   else
2176     {
2177       u32 proto = mp->protocol;
2178       print (vam->ofp, "Transport protocol: %U",
2179              format_lisp_transport_protocol, proto);
2180       vam->retval = retval;
2181       vam->result_ready = 1;
2182     }
2183 }
2184
2185 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2186   (vl_api_one_get_transport_protocol_reply_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   vat_json_node_t node;
2190   u8 *s;
2191
2192   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2193   vec_add1 (s, 0);
2194
2195   vat_json_init_object (&node);
2196   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2197   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2198
2199   vec_free (s);
2200   vat_json_print (vam->ofp, &node);
2201   vat_json_free (&node);
2202
2203   vam->retval = ntohl (mp->retval);
2204   vam->result_ready = 1;
2205 }
2206
2207 static void vl_api_one_add_del_locator_set_reply_t_handler
2208   (vl_api_one_add_del_locator_set_reply_t * mp)
2209 {
2210   vat_main_t *vam = &vat_main;
2211   i32 retval = ntohl (mp->retval);
2212   if (vam->async_mode)
2213     {
2214       vam->async_errors += (retval < 0);
2215     }
2216   else
2217     {
2218       vam->retval = retval;
2219       vam->result_ready = 1;
2220     }
2221 }
2222
2223 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2224   (vl_api_one_add_del_locator_set_reply_t * mp)
2225 {
2226   vat_main_t *vam = &vat_main;
2227   vat_json_node_t node;
2228
2229   vat_json_init_object (&node);
2230   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2231   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2232
2233   vat_json_print (vam->ofp, &node);
2234   vat_json_free (&node);
2235
2236   vam->retval = ntohl (mp->retval);
2237   vam->result_ready = 1;
2238 }
2239
2240 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2241   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   i32 retval = ntohl (mp->retval);
2245   if (vam->async_mode)
2246     {
2247       vam->async_errors += (retval < 0);
2248     }
2249   else
2250     {
2251       vam->retval = retval;
2252       vam->sw_if_index = ntohl (mp->sw_if_index);
2253       vam->result_ready = 1;
2254     }
2255   vam->regenerate_interface_table = 1;
2256 }
2257
2258 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2259   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2260 {
2261   vat_main_t *vam = &vat_main;
2262   vat_json_node_t node;
2263
2264   vat_json_init_object (&node);
2265   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2266   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2267
2268   vat_json_print (vam->ofp, &node);
2269   vat_json_free (&node);
2270
2271   vam->retval = ntohl (mp->retval);
2272   vam->result_ready = 1;
2273 }
2274
2275 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2276   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   i32 retval = ntohl (mp->retval);
2280   if (vam->async_mode)
2281     {
2282       vam->async_errors += (retval < 0);
2283     }
2284   else
2285     {
2286       vam->retval = retval;
2287       vam->sw_if_index = ntohl (mp->sw_if_index);
2288       vam->result_ready = 1;
2289     }
2290 }
2291
2292 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2293   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2301
2302   vat_json_print (vam->ofp, &node);
2303   vat_json_free (&node);
2304
2305   vam->retval = ntohl (mp->retval);
2306   vam->result_ready = 1;
2307 }
2308
2309 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2310   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2311 {
2312   vat_main_t *vam = &vat_main;
2313   i32 retval = ntohl (mp->retval);
2314   if (vam->async_mode)
2315     {
2316       vam->async_errors += (retval < 0);
2317     }
2318   else
2319     {
2320       vam->retval = retval;
2321       vam->sw_if_index = ntohl (mp->sw_if_index);
2322       vam->result_ready = 1;
2323     }
2324   vam->regenerate_interface_table = 1;
2325 }
2326
2327 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2328   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331   vat_json_node_t node;
2332
2333   vat_json_init_object (&node);
2334   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2335   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2336
2337   vat_json_print (vam->ofp, &node);
2338   vat_json_free (&node);
2339
2340   vam->retval = ntohl (mp->retval);
2341   vam->result_ready = 1;
2342 }
2343
2344 static void vl_api_gre_add_del_tunnel_reply_t_handler
2345   (vl_api_gre_add_del_tunnel_reply_t * mp)
2346 {
2347   vat_main_t *vam = &vat_main;
2348   i32 retval = ntohl (mp->retval);
2349   if (vam->async_mode)
2350     {
2351       vam->async_errors += (retval < 0);
2352     }
2353   else
2354     {
2355       vam->retval = retval;
2356       vam->sw_if_index = ntohl (mp->sw_if_index);
2357       vam->result_ready = 1;
2358     }
2359 }
2360
2361 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2362   (vl_api_gre_add_del_tunnel_reply_t * mp)
2363 {
2364   vat_main_t *vam = &vat_main;
2365   vat_json_node_t node;
2366
2367   vat_json_init_object (&node);
2368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2369   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2370
2371   vat_json_print (vam->ofp, &node);
2372   vat_json_free (&node);
2373
2374   vam->retval = ntohl (mp->retval);
2375   vam->result_ready = 1;
2376 }
2377
2378 static void vl_api_create_vhost_user_if_reply_t_handler
2379   (vl_api_create_vhost_user_if_reply_t * mp)
2380 {
2381   vat_main_t *vam = &vat_main;
2382   i32 retval = ntohl (mp->retval);
2383   if (vam->async_mode)
2384     {
2385       vam->async_errors += (retval < 0);
2386     }
2387   else
2388     {
2389       vam->retval = retval;
2390       vam->sw_if_index = ntohl (mp->sw_if_index);
2391       vam->result_ready = 1;
2392     }
2393   vam->regenerate_interface_table = 1;
2394 }
2395
2396 static void vl_api_create_vhost_user_if_reply_t_handler_json
2397   (vl_api_create_vhost_user_if_reply_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   vat_json_node_t node;
2401
2402   vat_json_init_object (&node);
2403   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2404   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2405
2406   vat_json_print (vam->ofp, &node);
2407   vat_json_free (&node);
2408
2409   vam->retval = ntohl (mp->retval);
2410   vam->result_ready = 1;
2411 }
2412
2413 static clib_error_t *
2414 receive_fd_msg (int socket_fd, int *my_fd)
2415 {
2416   char msgbuf[16];
2417   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2418   struct msghdr mh = { 0 };
2419   struct iovec iov[1];
2420   ssize_t size;
2421   struct ucred *cr = 0;
2422   struct cmsghdr *cmsg;
2423   pid_t pid __attribute__ ((unused));
2424   uid_t uid __attribute__ ((unused));
2425   gid_t gid __attribute__ ((unused));
2426
2427   iov[0].iov_base = msgbuf;
2428   iov[0].iov_len = 5;
2429   mh.msg_iov = iov;
2430   mh.msg_iovlen = 1;
2431   mh.msg_control = ctl;
2432   mh.msg_controllen = sizeof (ctl);
2433
2434   memset (ctl, 0, sizeof (ctl));
2435
2436   /* receive the incoming message */
2437   size = recvmsg (socket_fd, &mh, 0);
2438   if (size != 5)
2439     {
2440       return (size == 0) ? clib_error_return (0, "disconnected") :
2441         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2442                                 socket_fd);
2443     }
2444
2445   cmsg = CMSG_FIRSTHDR (&mh);
2446   while (cmsg)
2447     {
2448       if (cmsg->cmsg_level == SOL_SOCKET)
2449         {
2450           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2451             {
2452               cr = (struct ucred *) CMSG_DATA (cmsg);
2453               uid = cr->uid;
2454               gid = cr->gid;
2455               pid = cr->pid;
2456             }
2457           else if (cmsg->cmsg_type == SCM_RIGHTS)
2458             {
2459               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2460             }
2461         }
2462       cmsg = CMSG_NXTHDR (&mh, cmsg);
2463     }
2464   return 0;
2465 }
2466
2467 static void vl_api_memfd_segment_create_reply_t_handler
2468   (vl_api_memfd_segment_create_reply_t * mp)
2469 {
2470   /* Dont bother in the builtin version */
2471 #if VPP_API_TEST_BUILTIN == 0
2472   vat_main_t *vam = &vat_main;
2473   api_main_t *am = &api_main;
2474   socket_client_main_t *scm = vam->socket_client_main;
2475   int my_fd = -1;
2476   clib_error_t *error;
2477   ssvm_private_t memfd;
2478   i32 retval = ntohl (mp->retval);
2479
2480   if (retval == 0)
2481     {
2482       error = receive_fd_msg (scm->socket_fd, &my_fd);
2483       if (error)
2484         {
2485           retval = -99;
2486           goto out;
2487         }
2488
2489       memset (&memfd, 0, sizeof (memfd));
2490       memfd.fd = my_fd;
2491
2492       vam->client_index_invalid = 1;
2493
2494       /* Note: this closes memfd.fd */
2495       retval = ssvm_slave_init_memfd (&memfd);
2496       if (retval)
2497         clib_warning ("WARNING: segment map returned %d", retval);
2498
2499       /* Pivot to the memory client segment that vpp just created */
2500
2501       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2502
2503       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2504
2505       vl_client_install_client_message_handlers ();
2506
2507       vl_client_connect_to_vlib_no_map ("pvt",
2508                                         "vpp_api_test(p)",
2509                                         32 /* input_queue_length */ );
2510       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2511
2512       vl_socket_client_enable_disable (0 /* disable socket */ );
2513     }
2514
2515 out:
2516   if (vam->async_mode)
2517     {
2518       vam->async_errors += (retval < 0);
2519     }
2520   else
2521     {
2522       vam->retval = retval;
2523       vam->result_ready = 1;
2524     }
2525 #endif
2526 }
2527
2528 static void vl_api_memfd_segment_create_reply_t_handler_json
2529   (vl_api_memfd_segment_create_reply_t * mp)
2530 {
2531   clib_warning ("no");
2532 }
2533
2534 static void vl_api_dns_resolve_name_reply_t_handler
2535   (vl_api_dns_resolve_name_reply_t * mp)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   i32 retval = ntohl (mp->retval);
2539   if (vam->async_mode)
2540     {
2541       vam->async_errors += (retval < 0);
2542     }
2543   else
2544     {
2545       vam->retval = retval;
2546       vam->result_ready = 1;
2547
2548       if (retval == 0)
2549         {
2550           if (mp->ip4_set)
2551             clib_warning ("ip4 address %U", format_ip4_address,
2552                           (ip4_address_t *) mp->ip4_address);
2553           if (mp->ip6_set)
2554             clib_warning ("ip6 address %U", format_ip6_address,
2555                           (ip6_address_t *) mp->ip6_address);
2556         }
2557       else
2558         clib_warning ("retval %d", retval);
2559     }
2560 }
2561
2562 static void vl_api_dns_resolve_name_reply_t_handler_json
2563   (vl_api_dns_resolve_name_reply_t * mp)
2564 {
2565   clib_warning ("not implemented");
2566 }
2567
2568 static void vl_api_dns_resolve_ip_reply_t_handler
2569   (vl_api_dns_resolve_ip_reply_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   i32 retval = ntohl (mp->retval);
2573   if (vam->async_mode)
2574     {
2575       vam->async_errors += (retval < 0);
2576     }
2577   else
2578     {
2579       vam->retval = retval;
2580       vam->result_ready = 1;
2581
2582       if (retval == 0)
2583         {
2584           clib_warning ("canonical name %s", mp->name);
2585         }
2586       else
2587         clib_warning ("retval %d", retval);
2588     }
2589 }
2590
2591 static void vl_api_dns_resolve_ip_reply_t_handler_json
2592   (vl_api_dns_resolve_ip_reply_t * mp)
2593 {
2594   clib_warning ("not implemented");
2595 }
2596
2597
2598 static void vl_api_ip_address_details_t_handler
2599   (vl_api_ip_address_details_t * mp)
2600 {
2601   vat_main_t *vam = &vat_main;
2602   static ip_address_details_t empty_ip_address_details = { {0} };
2603   ip_address_details_t *address = NULL;
2604   ip_details_t *current_ip_details = NULL;
2605   ip_details_t *details = NULL;
2606
2607   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2608
2609   if (!details || vam->current_sw_if_index >= vec_len (details)
2610       || !details[vam->current_sw_if_index].present)
2611     {
2612       errmsg ("ip address details arrived but not stored");
2613       errmsg ("ip_dump should be called first");
2614       return;
2615     }
2616
2617   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2618
2619 #define addresses (current_ip_details->addr)
2620
2621   vec_validate_init_empty (addresses, vec_len (addresses),
2622                            empty_ip_address_details);
2623
2624   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2625
2626   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2627   address->prefix_length = mp->prefix_length;
2628 #undef addresses
2629 }
2630
2631 static void vl_api_ip_address_details_t_handler_json
2632   (vl_api_ip_address_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   vat_json_node_t *node = NULL;
2636   struct in6_addr ip6;
2637   struct in_addr ip4;
2638
2639   if (VAT_JSON_ARRAY != vam->json_tree.type)
2640     {
2641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2642       vat_json_init_array (&vam->json_tree);
2643     }
2644   node = vat_json_array_add (&vam->json_tree);
2645
2646   vat_json_init_object (node);
2647   if (vam->is_ipv6)
2648     {
2649       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2650       vat_json_object_add_ip6 (node, "ip", ip6);
2651     }
2652   else
2653     {
2654       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2655       vat_json_object_add_ip4 (node, "ip", ip4);
2656     }
2657   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2658 }
2659
2660 static void
2661 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2662 {
2663   vat_main_t *vam = &vat_main;
2664   static ip_details_t empty_ip_details = { 0 };
2665   ip_details_t *ip = NULL;
2666   u32 sw_if_index = ~0;
2667
2668   sw_if_index = ntohl (mp->sw_if_index);
2669
2670   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2671                            sw_if_index, empty_ip_details);
2672
2673   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2674                          sw_if_index);
2675
2676   ip->present = 1;
2677 }
2678
2679 static void
2680 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683
2684   if (VAT_JSON_ARRAY != vam->json_tree.type)
2685     {
2686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2687       vat_json_init_array (&vam->json_tree);
2688     }
2689   vat_json_array_add_uint (&vam->json_tree,
2690                            clib_net_to_host_u32 (mp->sw_if_index));
2691 }
2692
2693 static void vl_api_map_domain_details_t_handler_json
2694   (vl_api_map_domain_details_t * mp)
2695 {
2696   vat_json_node_t *node = NULL;
2697   vat_main_t *vam = &vat_main;
2698   struct in6_addr ip6;
2699   struct in_addr ip4;
2700
2701   if (VAT_JSON_ARRAY != vam->json_tree.type)
2702     {
2703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2704       vat_json_init_array (&vam->json_tree);
2705     }
2706
2707   node = vat_json_array_add (&vam->json_tree);
2708   vat_json_init_object (node);
2709
2710   vat_json_object_add_uint (node, "domain_index",
2711                             clib_net_to_host_u32 (mp->domain_index));
2712   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2713   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2714   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2715   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2716   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2717   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2718   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2719   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2720   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2721   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2722   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2723   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2724   vat_json_object_add_uint (node, "flags", mp->flags);
2725   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2726   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2727 }
2728
2729 static void vl_api_map_domain_details_t_handler
2730   (vl_api_map_domain_details_t * mp)
2731 {
2732   vat_main_t *vam = &vat_main;
2733
2734   if (mp->is_translation)
2735     {
2736       print (vam->ofp,
2737              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2738              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2739              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2740              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2741              clib_net_to_host_u32 (mp->domain_index));
2742     }
2743   else
2744     {
2745       print (vam->ofp,
2746              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2747              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2748              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2749              format_ip6_address, mp->ip6_src,
2750              clib_net_to_host_u32 (mp->domain_index));
2751     }
2752   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2753          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2754          mp->is_translation ? "map-t" : "");
2755 }
2756
2757 static void vl_api_map_rule_details_t_handler_json
2758   (vl_api_map_rule_details_t * mp)
2759 {
2760   struct in6_addr ip6;
2761   vat_json_node_t *node = NULL;
2762   vat_main_t *vam = &vat_main;
2763
2764   if (VAT_JSON_ARRAY != vam->json_tree.type)
2765     {
2766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2767       vat_json_init_array (&vam->json_tree);
2768     }
2769
2770   node = vat_json_array_add (&vam->json_tree);
2771   vat_json_init_object (node);
2772
2773   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2774   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2775   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2776 }
2777
2778 static void
2779 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2780 {
2781   vat_main_t *vam = &vat_main;
2782   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2783          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2784 }
2785
2786 static void
2787 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2788 {
2789   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2790           "router_addr %U host_mac %U",
2791           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2792           format_ip4_address, &mp->host_address,
2793           format_ip4_address, &mp->router_address,
2794           format_ethernet_address, mp->host_mac);
2795 }
2796
2797 static void vl_api_dhcp_compl_event_t_handler_json
2798   (vl_api_dhcp_compl_event_t * mp)
2799 {
2800   /* JSON output not supported */
2801 }
2802
2803 static void
2804 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2805                               u32 counter)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   static u64 default_counter = 0;
2809
2810   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2811                            NULL);
2812   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2813                            sw_if_index, default_counter);
2814   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2815 }
2816
2817 static void
2818 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2819                                 interface_counter_t counter)
2820 {
2821   vat_main_t *vam = &vat_main;
2822   static interface_counter_t default_counter = { 0, };
2823
2824   vec_validate_init_empty (vam->combined_interface_counters,
2825                            vnet_counter_type, NULL);
2826   vec_validate_init_empty (vam->combined_interface_counters
2827                            [vnet_counter_type], sw_if_index, default_counter);
2828   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2829 }
2830
2831 static void vl_api_vnet_interface_simple_counters_t_handler
2832   (vl_api_vnet_interface_simple_counters_t * mp)
2833 {
2834   /* not supported */
2835 }
2836
2837 static void vl_api_vnet_interface_combined_counters_t_handler
2838   (vl_api_vnet_interface_combined_counters_t * mp)
2839 {
2840   /* not supported */
2841 }
2842
2843 static void vl_api_vnet_interface_simple_counters_t_handler_json
2844   (vl_api_vnet_interface_simple_counters_t * mp)
2845 {
2846   u64 *v_packets;
2847   u64 packets;
2848   u32 count;
2849   u32 first_sw_if_index;
2850   int i;
2851
2852   count = ntohl (mp->count);
2853   first_sw_if_index = ntohl (mp->first_sw_if_index);
2854
2855   v_packets = (u64 *) & mp->data;
2856   for (i = 0; i < count; i++)
2857     {
2858       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2859       set_simple_interface_counter (mp->vnet_counter_type,
2860                                     first_sw_if_index + i, packets);
2861       v_packets++;
2862     }
2863 }
2864
2865 static void vl_api_vnet_interface_combined_counters_t_handler_json
2866   (vl_api_vnet_interface_combined_counters_t * mp)
2867 {
2868   interface_counter_t counter;
2869   vlib_counter_t *v;
2870   u32 first_sw_if_index;
2871   int i;
2872   u32 count;
2873
2874   count = ntohl (mp->count);
2875   first_sw_if_index = ntohl (mp->first_sw_if_index);
2876
2877   v = (vlib_counter_t *) & mp->data;
2878   for (i = 0; i < count; i++)
2879     {
2880       counter.packets =
2881         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2882       counter.bytes =
2883         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2884       set_combined_interface_counter (mp->vnet_counter_type,
2885                                       first_sw_if_index + i, counter);
2886       v++;
2887     }
2888 }
2889
2890 static u32
2891 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   u32 i;
2895
2896   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2897     {
2898       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2899         {
2900           return i;
2901         }
2902     }
2903   return ~0;
2904 }
2905
2906 static u32
2907 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2908 {
2909   vat_main_t *vam = &vat_main;
2910   u32 i;
2911
2912   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2913     {
2914       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2915         {
2916           return i;
2917         }
2918     }
2919   return ~0;
2920 }
2921
2922 static void vl_api_vnet_ip4_fib_counters_t_handler
2923   (vl_api_vnet_ip4_fib_counters_t * mp)
2924 {
2925   /* not supported */
2926 }
2927
2928 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2929   (vl_api_vnet_ip4_fib_counters_t * mp)
2930 {
2931   vat_main_t *vam = &vat_main;
2932   vl_api_ip4_fib_counter_t *v;
2933   ip4_fib_counter_t *counter;
2934   struct in_addr ip4;
2935   u32 vrf_id;
2936   u32 vrf_index;
2937   u32 count;
2938   int i;
2939
2940   vrf_id = ntohl (mp->vrf_id);
2941   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2942   if (~0 == vrf_index)
2943     {
2944       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2945       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2946       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2947       vec_validate (vam->ip4_fib_counters, vrf_index);
2948       vam->ip4_fib_counters[vrf_index] = NULL;
2949     }
2950
2951   vec_free (vam->ip4_fib_counters[vrf_index]);
2952   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2953   count = ntohl (mp->count);
2954   for (i = 0; i < count; i++)
2955     {
2956       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2957       counter = &vam->ip4_fib_counters[vrf_index][i];
2958       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2959       counter->address = ip4;
2960       counter->address_length = v->address_length;
2961       counter->packets = clib_net_to_host_u64 (v->packets);
2962       counter->bytes = clib_net_to_host_u64 (v->bytes);
2963       v++;
2964     }
2965 }
2966
2967 static void vl_api_vnet_ip4_nbr_counters_t_handler
2968   (vl_api_vnet_ip4_nbr_counters_t * mp)
2969 {
2970   /* not supported */
2971 }
2972
2973 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2974   (vl_api_vnet_ip4_nbr_counters_t * mp)
2975 {
2976   vat_main_t *vam = &vat_main;
2977   vl_api_ip4_nbr_counter_t *v;
2978   ip4_nbr_counter_t *counter;
2979   u32 sw_if_index;
2980   u32 count;
2981   int i;
2982
2983   sw_if_index = ntohl (mp->sw_if_index);
2984   count = ntohl (mp->count);
2985   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2986
2987   if (mp->begin)
2988     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2989
2990   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2991   for (i = 0; i < count; i++)
2992     {
2993       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2994       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2995       counter->address.s_addr = v->address;
2996       counter->packets = clib_net_to_host_u64 (v->packets);
2997       counter->bytes = clib_net_to_host_u64 (v->bytes);
2998       counter->linkt = v->link_type;
2999       v++;
3000     }
3001 }
3002
3003 static void vl_api_vnet_ip6_fib_counters_t_handler
3004   (vl_api_vnet_ip6_fib_counters_t * mp)
3005 {
3006   /* not supported */
3007 }
3008
3009 static void vl_api_vnet_ip6_fib_counters_t_handler_json
3010   (vl_api_vnet_ip6_fib_counters_t * mp)
3011 {
3012   vat_main_t *vam = &vat_main;
3013   vl_api_ip6_fib_counter_t *v;
3014   ip6_fib_counter_t *counter;
3015   struct in6_addr ip6;
3016   u32 vrf_id;
3017   u32 vrf_index;
3018   u32 count;
3019   int i;
3020
3021   vrf_id = ntohl (mp->vrf_id);
3022   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
3023   if (~0 == vrf_index)
3024     {
3025       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
3026       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
3027       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
3028       vec_validate (vam->ip6_fib_counters, vrf_index);
3029       vam->ip6_fib_counters[vrf_index] = NULL;
3030     }
3031
3032   vec_free (vam->ip6_fib_counters[vrf_index]);
3033   v = (vl_api_ip6_fib_counter_t *) & mp->c;
3034   count = ntohl (mp->count);
3035   for (i = 0; i < count; i++)
3036     {
3037       vec_validate (vam->ip6_fib_counters[vrf_index], i);
3038       counter = &vam->ip6_fib_counters[vrf_index][i];
3039       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3040       counter->address = ip6;
3041       counter->address_length = v->address_length;
3042       counter->packets = clib_net_to_host_u64 (v->packets);
3043       counter->bytes = clib_net_to_host_u64 (v->bytes);
3044       v++;
3045     }
3046 }
3047
3048 static void vl_api_vnet_ip6_nbr_counters_t_handler
3049   (vl_api_vnet_ip6_nbr_counters_t * mp)
3050 {
3051   /* not supported */
3052 }
3053
3054 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
3055   (vl_api_vnet_ip6_nbr_counters_t * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058   vl_api_ip6_nbr_counter_t *v;
3059   ip6_nbr_counter_t *counter;
3060   struct in6_addr ip6;
3061   u32 sw_if_index;
3062   u32 count;
3063   int i;
3064
3065   sw_if_index = ntohl (mp->sw_if_index);
3066   count = ntohl (mp->count);
3067   vec_validate (vam->ip6_nbr_counters, sw_if_index);
3068
3069   if (mp->begin)
3070     vec_free (vam->ip6_nbr_counters[sw_if_index]);
3071
3072   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
3073   for (i = 0; i < count; i++)
3074     {
3075       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
3076       counter = &vam->ip6_nbr_counters[sw_if_index][i];
3077       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3078       counter->address = ip6;
3079       counter->packets = clib_net_to_host_u64 (v->packets);
3080       counter->bytes = clib_net_to_host_u64 (v->bytes);
3081       v++;
3082     }
3083 }
3084
3085 static void vl_api_get_first_msg_id_reply_t_handler
3086   (vl_api_get_first_msg_id_reply_t * mp)
3087 {
3088   vat_main_t *vam = &vat_main;
3089   i32 retval = ntohl (mp->retval);
3090
3091   if (vam->async_mode)
3092     {
3093       vam->async_errors += (retval < 0);
3094     }
3095   else
3096     {
3097       vam->retval = retval;
3098       vam->result_ready = 1;
3099     }
3100   if (retval >= 0)
3101     {
3102       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3103     }
3104 }
3105
3106 static void vl_api_get_first_msg_id_reply_t_handler_json
3107   (vl_api_get_first_msg_id_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t node;
3111
3112   vat_json_init_object (&node);
3113   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3114   vat_json_object_add_uint (&node, "first_msg_id",
3115                             (uint) ntohs (mp->first_msg_id));
3116
3117   vat_json_print (vam->ofp, &node);
3118   vat_json_free (&node);
3119
3120   vam->retval = ntohl (mp->retval);
3121   vam->result_ready = 1;
3122 }
3123
3124 static void vl_api_get_node_graph_reply_t_handler
3125   (vl_api_get_node_graph_reply_t * mp)
3126 {
3127   vat_main_t *vam = &vat_main;
3128   api_main_t *am = &api_main;
3129   i32 retval = ntohl (mp->retval);
3130   u8 *pvt_copy, *reply;
3131   void *oldheap;
3132   vlib_node_t *node;
3133   int i;
3134
3135   if (vam->async_mode)
3136     {
3137       vam->async_errors += (retval < 0);
3138     }
3139   else
3140     {
3141       vam->retval = retval;
3142       vam->result_ready = 1;
3143     }
3144
3145   /* "Should never happen..." */
3146   if (retval != 0)
3147     return;
3148
3149   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3150   pvt_copy = vec_dup (reply);
3151
3152   /* Toss the shared-memory original... */
3153   pthread_mutex_lock (&am->vlib_rp->mutex);
3154   oldheap = svm_push_data_heap (am->vlib_rp);
3155
3156   vec_free (reply);
3157
3158   svm_pop_heap (oldheap);
3159   pthread_mutex_unlock (&am->vlib_rp->mutex);
3160
3161   if (vam->graph_nodes)
3162     {
3163       hash_free (vam->graph_node_index_by_name);
3164
3165       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3166         {
3167           node = vam->graph_nodes[i];
3168           vec_free (node->name);
3169           vec_free (node->next_nodes);
3170           vec_free (node);
3171         }
3172       vec_free (vam->graph_nodes);
3173     }
3174
3175   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3176   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3177   vec_free (pvt_copy);
3178
3179   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3180     {
3181       node = vam->graph_nodes[i];
3182       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3183     }
3184 }
3185
3186 static void vl_api_get_node_graph_reply_t_handler_json
3187   (vl_api_get_node_graph_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   api_main_t *am = &api_main;
3191   void *oldheap;
3192   vat_json_node_t node;
3193   u8 *reply;
3194
3195   /* $$$$ make this real? */
3196   vat_json_init_object (&node);
3197   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3198   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3199
3200   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3201
3202   /* Toss the shared-memory original... */
3203   pthread_mutex_lock (&am->vlib_rp->mutex);
3204   oldheap = svm_push_data_heap (am->vlib_rp);
3205
3206   vec_free (reply);
3207
3208   svm_pop_heap (oldheap);
3209   pthread_mutex_unlock (&am->vlib_rp->mutex);
3210
3211   vat_json_print (vam->ofp, &node);
3212   vat_json_free (&node);
3213
3214   vam->retval = ntohl (mp->retval);
3215   vam->result_ready = 1;
3216 }
3217
3218 static void
3219 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   u8 *s = 0;
3223
3224   if (mp->local)
3225     {
3226       s = format (s, "%=16d%=16d%=16d",
3227                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3228     }
3229   else
3230     {
3231       s = format (s, "%=16U%=16d%=16d",
3232                   mp->is_ipv6 ? format_ip6_address :
3233                   format_ip4_address,
3234                   mp->ip_address, mp->priority, mp->weight);
3235     }
3236
3237   print (vam->ofp, "%v", s);
3238   vec_free (s);
3239 }
3240
3241 static void
3242 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3243 {
3244   vat_main_t *vam = &vat_main;
3245   vat_json_node_t *node = NULL;
3246   struct in6_addr ip6;
3247   struct in_addr ip4;
3248
3249   if (VAT_JSON_ARRAY != vam->json_tree.type)
3250     {
3251       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3252       vat_json_init_array (&vam->json_tree);
3253     }
3254   node = vat_json_array_add (&vam->json_tree);
3255   vat_json_init_object (node);
3256
3257   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3258   vat_json_object_add_uint (node, "priority", mp->priority);
3259   vat_json_object_add_uint (node, "weight", mp->weight);
3260
3261   if (mp->local)
3262     vat_json_object_add_uint (node, "sw_if_index",
3263                               clib_net_to_host_u32 (mp->sw_if_index));
3264   else
3265     {
3266       if (mp->is_ipv6)
3267         {
3268           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3269           vat_json_object_add_ip6 (node, "address", ip6);
3270         }
3271       else
3272         {
3273           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3274           vat_json_object_add_ip4 (node, "address", ip4);
3275         }
3276     }
3277 }
3278
3279 static void
3280 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3281                                           mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   u8 *ls_name = 0;
3285
3286   ls_name = format (0, "%s", mp->ls_name);
3287
3288   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3289          ls_name);
3290   vec_free (ls_name);
3291 }
3292
3293 static void
3294   vl_api_one_locator_set_details_t_handler_json
3295   (vl_api_one_locator_set_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   vat_json_node_t *node = 0;
3299   u8 *ls_name = 0;
3300
3301   ls_name = format (0, "%s", mp->ls_name);
3302   vec_add1 (ls_name, 0);
3303
3304   if (VAT_JSON_ARRAY != vam->json_tree.type)
3305     {
3306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3307       vat_json_init_array (&vam->json_tree);
3308     }
3309   node = vat_json_array_add (&vam->json_tree);
3310
3311   vat_json_init_object (node);
3312   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3313   vat_json_object_add_uint (node, "ls_index",
3314                             clib_net_to_host_u32 (mp->ls_index));
3315   vec_free (ls_name);
3316 }
3317
3318 typedef struct
3319 {
3320   u32 spi;
3321   u8 si;
3322 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3323
3324 uword
3325 unformat_nsh_address (unformat_input_t * input, va_list * args)
3326 {
3327   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3328   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3329 }
3330
3331 u8 *
3332 format_nsh_address_vat (u8 * s, va_list * args)
3333 {
3334   nsh_t *a = va_arg (*args, nsh_t *);
3335   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3336 }
3337
3338 static u8 *
3339 format_lisp_flat_eid (u8 * s, va_list * args)
3340 {
3341   u32 type = va_arg (*args, u32);
3342   u8 *eid = va_arg (*args, u8 *);
3343   u32 eid_len = va_arg (*args, u32);
3344
3345   switch (type)
3346     {
3347     case 0:
3348       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3349     case 1:
3350       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3351     case 2:
3352       return format (s, "%U", format_ethernet_address, eid);
3353     case 3:
3354       return format (s, "%U", format_nsh_address_vat, eid);
3355     }
3356   return 0;
3357 }
3358
3359 static u8 *
3360 format_lisp_eid_vat (u8 * s, va_list * args)
3361 {
3362   u32 type = va_arg (*args, u32);
3363   u8 *eid = va_arg (*args, u8 *);
3364   u32 eid_len = va_arg (*args, u32);
3365   u8 *seid = va_arg (*args, u8 *);
3366   u32 seid_len = va_arg (*args, u32);
3367   u32 is_src_dst = va_arg (*args, u32);
3368
3369   if (is_src_dst)
3370     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3371
3372   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3373
3374   return s;
3375 }
3376
3377 static void
3378 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   u8 *s = 0, *eid = 0;
3382
3383   if (~0 == mp->locator_set_index)
3384     s = format (0, "action: %d", mp->action);
3385   else
3386     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3387
3388   eid = format (0, "%U", format_lisp_eid_vat,
3389                 mp->eid_type,
3390                 mp->eid,
3391                 mp->eid_prefix_len,
3392                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3393   vec_add1 (eid, 0);
3394
3395   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3396          clib_net_to_host_u32 (mp->vni),
3397          eid,
3398          mp->is_local ? "local" : "remote",
3399          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3400          clib_net_to_host_u16 (mp->key_id), mp->key);
3401
3402   vec_free (s);
3403   vec_free (eid);
3404 }
3405
3406 static void
3407 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3408                                              * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t *node = 0;
3412   u8 *eid = 0;
3413
3414   if (VAT_JSON_ARRAY != vam->json_tree.type)
3415     {
3416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3417       vat_json_init_array (&vam->json_tree);
3418     }
3419   node = vat_json_array_add (&vam->json_tree);
3420
3421   vat_json_init_object (node);
3422   if (~0 == mp->locator_set_index)
3423     vat_json_object_add_uint (node, "action", mp->action);
3424   else
3425     vat_json_object_add_uint (node, "locator_set_index",
3426                               clib_net_to_host_u32 (mp->locator_set_index));
3427
3428   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3429   if (mp->eid_type == 3)
3430     {
3431       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3432       vat_json_init_object (nsh_json);
3433       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3434       vat_json_object_add_uint (nsh_json, "spi",
3435                                 clib_net_to_host_u32 (nsh->spi));
3436       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3437     }
3438   else
3439     {
3440       eid = format (0, "%U", format_lisp_eid_vat,
3441                     mp->eid_type,
3442                     mp->eid,
3443                     mp->eid_prefix_len,
3444                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3445       vec_add1 (eid, 0);
3446       vat_json_object_add_string_copy (node, "eid", eid);
3447       vec_free (eid);
3448     }
3449   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3450   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3451   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3452
3453   if (mp->key_id)
3454     {
3455       vat_json_object_add_uint (node, "key_id",
3456                                 clib_net_to_host_u16 (mp->key_id));
3457       vat_json_object_add_string_copy (node, "key", mp->key);
3458     }
3459 }
3460
3461 static void
3462 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u8 *seid = 0, *deid = 0;
3466   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3467
3468   deid = format (0, "%U", format_lisp_eid_vat,
3469                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3470
3471   seid = format (0, "%U", format_lisp_eid_vat,
3472                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3473
3474   vec_add1 (deid, 0);
3475   vec_add1 (seid, 0);
3476
3477   if (mp->is_ip4)
3478     format_ip_address_fcn = format_ip4_address;
3479   else
3480     format_ip_address_fcn = format_ip6_address;
3481
3482
3483   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3484          clib_net_to_host_u32 (mp->vni),
3485          seid, deid,
3486          format_ip_address_fcn, mp->lloc,
3487          format_ip_address_fcn, mp->rloc,
3488          clib_net_to_host_u32 (mp->pkt_count),
3489          clib_net_to_host_u32 (mp->bytes));
3490
3491   vec_free (deid);
3492   vec_free (seid);
3493 }
3494
3495 static void
3496 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3497 {
3498   struct in6_addr ip6;
3499   struct in_addr ip4;
3500   vat_main_t *vam = &vat_main;
3501   vat_json_node_t *node = 0;
3502   u8 *deid = 0, *seid = 0;
3503
3504   if (VAT_JSON_ARRAY != vam->json_tree.type)
3505     {
3506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3507       vat_json_init_array (&vam->json_tree);
3508     }
3509   node = vat_json_array_add (&vam->json_tree);
3510
3511   vat_json_init_object (node);
3512   deid = format (0, "%U", format_lisp_eid_vat,
3513                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3514
3515   seid = format (0, "%U", format_lisp_eid_vat,
3516                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3517
3518   vec_add1 (deid, 0);
3519   vec_add1 (seid, 0);
3520
3521   vat_json_object_add_string_copy (node, "seid", seid);
3522   vat_json_object_add_string_copy (node, "deid", deid);
3523   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3524
3525   if (mp->is_ip4)
3526     {
3527       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3528       vat_json_object_add_ip4 (node, "lloc", ip4);
3529       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3530       vat_json_object_add_ip4 (node, "rloc", ip4);
3531     }
3532   else
3533     {
3534       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3535       vat_json_object_add_ip6 (node, "lloc", ip6);
3536       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3537       vat_json_object_add_ip6 (node, "rloc", ip6);
3538     }
3539   vat_json_object_add_uint (node, "pkt_count",
3540                             clib_net_to_host_u32 (mp->pkt_count));
3541   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3542
3543   vec_free (deid);
3544   vec_free (seid);
3545 }
3546
3547 static void
3548   vl_api_one_eid_table_map_details_t_handler
3549   (vl_api_one_eid_table_map_details_t * mp)
3550 {
3551   vat_main_t *vam = &vat_main;
3552
3553   u8 *line = format (0, "%=10d%=10d",
3554                      clib_net_to_host_u32 (mp->vni),
3555                      clib_net_to_host_u32 (mp->dp_table));
3556   print (vam->ofp, "%v", line);
3557   vec_free (line);
3558 }
3559
3560 static void
3561   vl_api_one_eid_table_map_details_t_handler_json
3562   (vl_api_one_eid_table_map_details_t * mp)
3563 {
3564   vat_main_t *vam = &vat_main;
3565   vat_json_node_t *node = NULL;
3566
3567   if (VAT_JSON_ARRAY != vam->json_tree.type)
3568     {
3569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3570       vat_json_init_array (&vam->json_tree);
3571     }
3572   node = vat_json_array_add (&vam->json_tree);
3573   vat_json_init_object (node);
3574   vat_json_object_add_uint (node, "dp_table",
3575                             clib_net_to_host_u32 (mp->dp_table));
3576   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3577 }
3578
3579 static void
3580   vl_api_one_eid_table_vni_details_t_handler
3581   (vl_api_one_eid_table_vni_details_t * mp)
3582 {
3583   vat_main_t *vam = &vat_main;
3584
3585   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3586   print (vam->ofp, "%v", line);
3587   vec_free (line);
3588 }
3589
3590 static void
3591   vl_api_one_eid_table_vni_details_t_handler_json
3592   (vl_api_one_eid_table_vni_details_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   vat_json_node_t *node = NULL;
3596
3597   if (VAT_JSON_ARRAY != vam->json_tree.type)
3598     {
3599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3600       vat_json_init_array (&vam->json_tree);
3601     }
3602   node = vat_json_array_add (&vam->json_tree);
3603   vat_json_init_object (node);
3604   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3605 }
3606
3607 static void
3608   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3609   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613
3614   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3615   print (vam->ofp, "fallback threshold value: %d", mp->value);
3616
3617   vam->retval = retval;
3618   vam->result_ready = 1;
3619 }
3620
3621 static void
3622   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3623   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3624 {
3625   vat_main_t *vam = &vat_main;
3626   vat_json_node_t _node, *node = &_node;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628
3629   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3630   vat_json_init_object (node);
3631   vat_json_object_add_uint (node, "value", mp->value);
3632
3633   vat_json_print (vam->ofp, node);
3634   vat_json_free (node);
3635
3636   vam->retval = retval;
3637   vam->result_ready = 1;
3638 }
3639
3640 static void
3641   vl_api_show_one_map_register_state_reply_t_handler
3642   (vl_api_show_one_map_register_state_reply_t * mp)
3643 {
3644   vat_main_t *vam = &vat_main;
3645   int retval = clib_net_to_host_u32 (mp->retval);
3646
3647   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3648
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651 }
3652
3653 static void
3654   vl_api_show_one_map_register_state_reply_t_handler_json
3655   (vl_api_show_one_map_register_state_reply_t * mp)
3656 {
3657   vat_main_t *vam = &vat_main;
3658   vat_json_node_t _node, *node = &_node;
3659   int retval = clib_net_to_host_u32 (mp->retval);
3660
3661   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3662
3663   vat_json_init_object (node);
3664   vat_json_object_add_string_copy (node, "state", s);
3665
3666   vat_json_print (vam->ofp, node);
3667   vat_json_free (node);
3668
3669   vam->retval = retval;
3670   vam->result_ready = 1;
3671   vec_free (s);
3672 }
3673
3674 static void
3675   vl_api_show_one_rloc_probe_state_reply_t_handler
3676   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3677 {
3678   vat_main_t *vam = &vat_main;
3679   int retval = clib_net_to_host_u32 (mp->retval);
3680
3681   if (retval)
3682     goto end;
3683
3684   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3692   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   vat_json_node_t _node, *node = &_node;
3696   int retval = clib_net_to_host_u32 (mp->retval);
3697
3698   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3699   vat_json_init_object (node);
3700   vat_json_object_add_string_copy (node, "state", s);
3701
3702   vat_json_print (vam->ofp, node);
3703   vat_json_free (node);
3704
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707   vec_free (s);
3708 }
3709
3710 static void
3711   vl_api_show_one_stats_enable_disable_reply_t_handler
3712   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716
3717   if (retval)
3718     goto end;
3719
3720   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3721 end:
3722   vam->retval = retval;
3723   vam->result_ready = 1;
3724 }
3725
3726 static void
3727   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3728   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3729 {
3730   vat_main_t *vam = &vat_main;
3731   vat_json_node_t _node, *node = &_node;
3732   int retval = clib_net_to_host_u32 (mp->retval);
3733
3734   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3735   vat_json_init_object (node);
3736   vat_json_object_add_string_copy (node, "state", s);
3737
3738   vat_json_print (vam->ofp, node);
3739   vat_json_free (node);
3740
3741   vam->retval = retval;
3742   vam->result_ready = 1;
3743   vec_free (s);
3744 }
3745
3746 static void
3747 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3748 {
3749   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3750   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3751   e->vni = clib_net_to_host_u32 (e->vni);
3752 }
3753
3754 static void
3755   gpe_fwd_entries_get_reply_t_net_to_host
3756   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3757 {
3758   u32 i;
3759
3760   mp->count = clib_net_to_host_u32 (mp->count);
3761   for (i = 0; i < mp->count; i++)
3762     {
3763       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3764     }
3765 }
3766
3767 static u8 *
3768 format_gpe_encap_mode (u8 * s, va_list * args)
3769 {
3770   u32 mode = va_arg (*args, u32);
3771
3772   switch (mode)
3773     {
3774     case 0:
3775       return format (s, "lisp");
3776     case 1:
3777       return format (s, "vxlan");
3778     }
3779   return 0;
3780 }
3781
3782 static void
3783   vl_api_gpe_get_encap_mode_reply_t_handler
3784   (vl_api_gpe_get_encap_mode_reply_t * mp)
3785 {
3786   vat_main_t *vam = &vat_main;
3787
3788   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3789   vam->retval = ntohl (mp->retval);
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_gpe_get_encap_mode_reply_t_handler_json
3795   (vl_api_gpe_get_encap_mode_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   vat_json_node_t node;
3799
3800   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3801   vec_add1 (encap_mode, 0);
3802
3803   vat_json_init_object (&node);
3804   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3805
3806   vec_free (encap_mode);
3807   vat_json_print (vam->ofp, &node);
3808   vat_json_free (&node);
3809
3810   vam->retval = ntohl (mp->retval);
3811   vam->result_ready = 1;
3812 }
3813
3814 static void
3815   vl_api_gpe_fwd_entry_path_details_t_handler
3816   (vl_api_gpe_fwd_entry_path_details_t * mp)
3817 {
3818   vat_main_t *vam = &vat_main;
3819   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3820
3821   if (mp->lcl_loc.is_ip4)
3822     format_ip_address_fcn = format_ip4_address;
3823   else
3824     format_ip_address_fcn = format_ip6_address;
3825
3826   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3827          format_ip_address_fcn, &mp->lcl_loc,
3828          format_ip_address_fcn, &mp->rmt_loc);
3829 }
3830
3831 static void
3832 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3833 {
3834   struct in6_addr ip6;
3835   struct in_addr ip4;
3836
3837   if (loc->is_ip4)
3838     {
3839       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3840       vat_json_object_add_ip4 (n, "address", ip4);
3841     }
3842   else
3843     {
3844       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3845       vat_json_object_add_ip6 (n, "address", ip6);
3846     }
3847   vat_json_object_add_uint (n, "weight", loc->weight);
3848 }
3849
3850 static void
3851   vl_api_gpe_fwd_entry_path_details_t_handler_json
3852   (vl_api_gpe_fwd_entry_path_details_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   vat_json_node_t *node = NULL;
3856   vat_json_node_t *loc_node;
3857
3858   if (VAT_JSON_ARRAY != vam->json_tree.type)
3859     {
3860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3861       vat_json_init_array (&vam->json_tree);
3862     }
3863   node = vat_json_array_add (&vam->json_tree);
3864   vat_json_init_object (node);
3865
3866   loc_node = vat_json_object_add (node, "local_locator");
3867   vat_json_init_object (loc_node);
3868   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3869
3870   loc_node = vat_json_object_add (node, "remote_locator");
3871   vat_json_init_object (loc_node);
3872   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3873 }
3874
3875 static void
3876   vl_api_gpe_fwd_entries_get_reply_t_handler
3877   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3878 {
3879   vat_main_t *vam = &vat_main;
3880   u32 i;
3881   int retval = clib_net_to_host_u32 (mp->retval);
3882   vl_api_gpe_fwd_entry_t *e;
3883
3884   if (retval)
3885     goto end;
3886
3887   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3888
3889   for (i = 0; i < mp->count; i++)
3890     {
3891       e = &mp->entries[i];
3892       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3893              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3894              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3895     }
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3904   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3905 {
3906   u8 *s = 0;
3907   vat_main_t *vam = &vat_main;
3908   vat_json_node_t *e = 0, root;
3909   u32 i;
3910   int retval = clib_net_to_host_u32 (mp->retval);
3911   vl_api_gpe_fwd_entry_t *fwd;
3912
3913   if (retval)
3914     goto end;
3915
3916   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3917   vat_json_init_array (&root);
3918
3919   for (i = 0; i < mp->count; i++)
3920     {
3921       e = vat_json_array_add (&root);
3922       fwd = &mp->entries[i];
3923
3924       vat_json_init_object (e);
3925       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3926       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3927       vat_json_object_add_int (e, "vni", fwd->vni);
3928       vat_json_object_add_int (e, "action", fwd->action);
3929
3930       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3931                   fwd->leid_prefix_len);
3932       vec_add1 (s, 0);
3933       vat_json_object_add_string_copy (e, "leid", s);
3934       vec_free (s);
3935
3936       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3937                   fwd->reid_prefix_len);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "reid", s);
3940       vec_free (s);
3941     }
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3953   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3954 {
3955   vat_main_t *vam = &vat_main;
3956   u32 i, n;
3957   int retval = clib_net_to_host_u32 (mp->retval);
3958   vl_api_gpe_native_fwd_rpath_t *r;
3959
3960   if (retval)
3961     goto end;
3962
3963   n = clib_net_to_host_u32 (mp->count);
3964
3965   for (i = 0; i < n; i++)
3966     {
3967       r = &mp->entries[i];
3968       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3969              clib_net_to_host_u32 (r->fib_index),
3970              clib_net_to_host_u32 (r->nh_sw_if_index),
3971              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3972     }
3973
3974 end:
3975   vam->retval = retval;
3976   vam->result_ready = 1;
3977 }
3978
3979 static void
3980   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3981   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3982 {
3983   vat_main_t *vam = &vat_main;
3984   vat_json_node_t root, *e;
3985   u32 i, n;
3986   int retval = clib_net_to_host_u32 (mp->retval);
3987   vl_api_gpe_native_fwd_rpath_t *r;
3988   u8 *s;
3989
3990   if (retval)
3991     goto end;
3992
3993   n = clib_net_to_host_u32 (mp->count);
3994   vat_json_init_array (&root);
3995
3996   for (i = 0; i < n; i++)
3997     {
3998       e = vat_json_array_add (&root);
3999       vat_json_init_object (e);
4000       r = &mp->entries[i];
4001       s =
4002         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
4003                 r->nh_addr);
4004       vec_add1 (s, 0);
4005       vat_json_object_add_string_copy (e, "ip4", s);
4006       vec_free (s);
4007
4008       vat_json_object_add_uint (e, "fib_index",
4009                                 clib_net_to_host_u32 (r->fib_index));
4010       vat_json_object_add_uint (e, "nh_sw_if_index",
4011                                 clib_net_to_host_u32 (r->nh_sw_if_index));
4012     }
4013
4014   vat_json_print (vam->ofp, &root);
4015   vat_json_free (&root);
4016
4017 end:
4018   vam->retval = retval;
4019   vam->result_ready = 1;
4020 }
4021
4022 static void
4023   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
4024   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
4025 {
4026   vat_main_t *vam = &vat_main;
4027   u32 i, n;
4028   int retval = clib_net_to_host_u32 (mp->retval);
4029
4030   if (retval)
4031     goto end;
4032
4033   n = clib_net_to_host_u32 (mp->count);
4034
4035   for (i = 0; i < n; i++)
4036     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
4037
4038 end:
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
4045   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t root;
4049   u32 i, n;
4050   int retval = clib_net_to_host_u32 (mp->retval);
4051
4052   if (retval)
4053     goto end;
4054
4055   n = clib_net_to_host_u32 (mp->count);
4056   vat_json_init_array (&root);
4057
4058   for (i = 0; i < n; i++)
4059     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
4060
4061   vat_json_print (vam->ofp, &root);
4062   vat_json_free (&root);
4063
4064 end:
4065   vam->retval = retval;
4066   vam->result_ready = 1;
4067 }
4068
4069 static void
4070   vl_api_one_ndp_entries_get_reply_t_handler
4071   (vl_api_one_ndp_entries_get_reply_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   u32 i, n;
4075   int retval = clib_net_to_host_u32 (mp->retval);
4076
4077   if (retval)
4078     goto end;
4079
4080   n = clib_net_to_host_u32 (mp->count);
4081
4082   for (i = 0; i < n; i++)
4083     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4084            format_ethernet_address, mp->entries[i].mac);
4085
4086 end:
4087   vam->retval = retval;
4088   vam->result_ready = 1;
4089 }
4090
4091 static void
4092   vl_api_one_ndp_entries_get_reply_t_handler_json
4093   (vl_api_one_ndp_entries_get_reply_t * mp)
4094 {
4095   u8 *s = 0;
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t *e = 0, root;
4098   u32 i, n;
4099   int retval = clib_net_to_host_u32 (mp->retval);
4100   vl_api_one_ndp_entry_t *arp_entry;
4101
4102   if (retval)
4103     goto end;
4104
4105   n = clib_net_to_host_u32 (mp->count);
4106   vat_json_init_array (&root);
4107
4108   for (i = 0; i < n; i++)
4109     {
4110       e = vat_json_array_add (&root);
4111       arp_entry = &mp->entries[i];
4112
4113       vat_json_init_object (e);
4114       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4115       vec_add1 (s, 0);
4116
4117       vat_json_object_add_string_copy (e, "mac", s);
4118       vec_free (s);
4119
4120       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4121       vec_add1 (s, 0);
4122       vat_json_object_add_string_copy (e, "ip6", s);
4123       vec_free (s);
4124     }
4125
4126   vat_json_print (vam->ofp, &root);
4127   vat_json_free (&root);
4128
4129 end:
4130   vam->retval = retval;
4131   vam->result_ready = 1;
4132 }
4133
4134 static void
4135   vl_api_one_l2_arp_entries_get_reply_t_handler
4136   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4137 {
4138   vat_main_t *vam = &vat_main;
4139   u32 i, n;
4140   int retval = clib_net_to_host_u32 (mp->retval);
4141
4142   if (retval)
4143     goto end;
4144
4145   n = clib_net_to_host_u32 (mp->count);
4146
4147   for (i = 0; i < n; i++)
4148     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4149            format_ethernet_address, mp->entries[i].mac);
4150
4151 end:
4152   vam->retval = retval;
4153   vam->result_ready = 1;
4154 }
4155
4156 static void
4157   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4158   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4159 {
4160   u8 *s = 0;
4161   vat_main_t *vam = &vat_main;
4162   vat_json_node_t *e = 0, root;
4163   u32 i, n;
4164   int retval = clib_net_to_host_u32 (mp->retval);
4165   vl_api_one_l2_arp_entry_t *arp_entry;
4166
4167   if (retval)
4168     goto end;
4169
4170   n = clib_net_to_host_u32 (mp->count);
4171   vat_json_init_array (&root);
4172
4173   for (i = 0; i < n; i++)
4174     {
4175       e = vat_json_array_add (&root);
4176       arp_entry = &mp->entries[i];
4177
4178       vat_json_init_object (e);
4179       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4180       vec_add1 (s, 0);
4181
4182       vat_json_object_add_string_copy (e, "mac", s);
4183       vec_free (s);
4184
4185       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4186       vec_add1 (s, 0);
4187       vat_json_object_add_string_copy (e, "ip4", s);
4188       vec_free (s);
4189     }
4190
4191   vat_json_print (vam->ofp, &root);
4192   vat_json_free (&root);
4193
4194 end:
4195   vam->retval = retval;
4196   vam->result_ready = 1;
4197 }
4198
4199 static void
4200 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   u32 i, n;
4204   int retval = clib_net_to_host_u32 (mp->retval);
4205
4206   if (retval)
4207     goto end;
4208
4209   n = clib_net_to_host_u32 (mp->count);
4210
4211   for (i = 0; i < n; i++)
4212     {
4213       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4214     }
4215
4216 end:
4217   vam->retval = retval;
4218   vam->result_ready = 1;
4219 }
4220
4221 static void
4222   vl_api_one_ndp_bd_get_reply_t_handler_json
4223   (vl_api_one_ndp_bd_get_reply_t * mp)
4224 {
4225   vat_main_t *vam = &vat_main;
4226   vat_json_node_t root;
4227   u32 i, n;
4228   int retval = clib_net_to_host_u32 (mp->retval);
4229
4230   if (retval)
4231     goto end;
4232
4233   n = clib_net_to_host_u32 (mp->count);
4234   vat_json_init_array (&root);
4235
4236   for (i = 0; i < n; i++)
4237     {
4238       vat_json_array_add_uint (&root,
4239                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4240     }
4241
4242   vat_json_print (vam->ofp, &root);
4243   vat_json_free (&root);
4244
4245 end:
4246   vam->retval = retval;
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_l2_arp_bd_get_reply_t_handler
4252   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   u32 i, n;
4256   int retval = clib_net_to_host_u32 (mp->retval);
4257
4258   if (retval)
4259     goto end;
4260
4261   n = clib_net_to_host_u32 (mp->count);
4262
4263   for (i = 0; i < n; i++)
4264     {
4265       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4266     }
4267
4268 end:
4269   vam->retval = retval;
4270   vam->result_ready = 1;
4271 }
4272
4273 static void
4274   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4275   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4276 {
4277   vat_main_t *vam = &vat_main;
4278   vat_json_node_t root;
4279   u32 i, n;
4280   int retval = clib_net_to_host_u32 (mp->retval);
4281
4282   if (retval)
4283     goto end;
4284
4285   n = clib_net_to_host_u32 (mp->count);
4286   vat_json_init_array (&root);
4287
4288   for (i = 0; i < n; i++)
4289     {
4290       vat_json_array_add_uint (&root,
4291                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4292     }
4293
4294   vat_json_print (vam->ofp, &root);
4295   vat_json_free (&root);
4296
4297 end:
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_one_adjacencies_get_reply_t_handler
4304   (vl_api_one_adjacencies_get_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   u32 i, n;
4308   int retval = clib_net_to_host_u32 (mp->retval);
4309   vl_api_one_adjacency_t *a;
4310
4311   if (retval)
4312     goto end;
4313
4314   n = clib_net_to_host_u32 (mp->count);
4315
4316   for (i = 0; i < n; i++)
4317     {
4318       a = &mp->adjacencies[i];
4319       print (vam->ofp, "%U %40U",
4320              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4321              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4322     }
4323
4324 end:
4325   vam->retval = retval;
4326   vam->result_ready = 1;
4327 }
4328
4329 static void
4330   vl_api_one_adjacencies_get_reply_t_handler_json
4331   (vl_api_one_adjacencies_get_reply_t * mp)
4332 {
4333   u8 *s = 0;
4334   vat_main_t *vam = &vat_main;
4335   vat_json_node_t *e = 0, root;
4336   u32 i, n;
4337   int retval = clib_net_to_host_u32 (mp->retval);
4338   vl_api_one_adjacency_t *a;
4339
4340   if (retval)
4341     goto end;
4342
4343   n = clib_net_to_host_u32 (mp->count);
4344   vat_json_init_array (&root);
4345
4346   for (i = 0; i < n; i++)
4347     {
4348       e = vat_json_array_add (&root);
4349       a = &mp->adjacencies[i];
4350
4351       vat_json_init_object (e);
4352       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4353                   a->leid_prefix_len);
4354       vec_add1 (s, 0);
4355       vat_json_object_add_string_copy (e, "leid", s);
4356       vec_free (s);
4357
4358       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4359                   a->reid_prefix_len);
4360       vec_add1 (s, 0);
4361       vat_json_object_add_string_copy (e, "reid", s);
4362       vec_free (s);
4363     }
4364
4365   vat_json_print (vam->ofp, &root);
4366   vat_json_free (&root);
4367
4368 end:
4369   vam->retval = retval;
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4375 {
4376   vat_main_t *vam = &vat_main;
4377
4378   print (vam->ofp, "%=20U",
4379          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4380          mp->ip_address);
4381 }
4382
4383 static void
4384   vl_api_one_map_server_details_t_handler_json
4385   (vl_api_one_map_server_details_t * mp)
4386 {
4387   vat_main_t *vam = &vat_main;
4388   vat_json_node_t *node = NULL;
4389   struct in6_addr ip6;
4390   struct in_addr ip4;
4391
4392   if (VAT_JSON_ARRAY != vam->json_tree.type)
4393     {
4394       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4395       vat_json_init_array (&vam->json_tree);
4396     }
4397   node = vat_json_array_add (&vam->json_tree);
4398
4399   vat_json_init_object (node);
4400   if (mp->is_ipv6)
4401     {
4402       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4403       vat_json_object_add_ip6 (node, "map-server", ip6);
4404     }
4405   else
4406     {
4407       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4408       vat_json_object_add_ip4 (node, "map-server", ip4);
4409     }
4410 }
4411
4412 static void
4413 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4414                                            * mp)
4415 {
4416   vat_main_t *vam = &vat_main;
4417
4418   print (vam->ofp, "%=20U",
4419          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4420          mp->ip_address);
4421 }
4422
4423 static void
4424   vl_api_one_map_resolver_details_t_handler_json
4425   (vl_api_one_map_resolver_details_t * mp)
4426 {
4427   vat_main_t *vam = &vat_main;
4428   vat_json_node_t *node = NULL;
4429   struct in6_addr ip6;
4430   struct in_addr ip4;
4431
4432   if (VAT_JSON_ARRAY != vam->json_tree.type)
4433     {
4434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4435       vat_json_init_array (&vam->json_tree);
4436     }
4437   node = vat_json_array_add (&vam->json_tree);
4438
4439   vat_json_init_object (node);
4440   if (mp->is_ipv6)
4441     {
4442       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4443       vat_json_object_add_ip6 (node, "map resolver", ip6);
4444     }
4445   else
4446     {
4447       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4448       vat_json_object_add_ip4 (node, "map resolver", ip4);
4449     }
4450 }
4451
4452 static void
4453 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4454 {
4455   vat_main_t *vam = &vat_main;
4456   i32 retval = ntohl (mp->retval);
4457
4458   if (0 <= retval)
4459     {
4460       print (vam->ofp, "feature: %s\ngpe: %s",
4461              mp->feature_status ? "enabled" : "disabled",
4462              mp->gpe_status ? "enabled" : "disabled");
4463     }
4464
4465   vam->retval = retval;
4466   vam->result_ready = 1;
4467 }
4468
4469 static void
4470   vl_api_show_one_status_reply_t_handler_json
4471   (vl_api_show_one_status_reply_t * mp)
4472 {
4473   vat_main_t *vam = &vat_main;
4474   vat_json_node_t node;
4475   u8 *gpe_status = NULL;
4476   u8 *feature_status = NULL;
4477
4478   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4479   feature_status = format (0, "%s",
4480                            mp->feature_status ? "enabled" : "disabled");
4481   vec_add1 (gpe_status, 0);
4482   vec_add1 (feature_status, 0);
4483
4484   vat_json_init_object (&node);
4485   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4486   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4487
4488   vec_free (gpe_status);
4489   vec_free (feature_status);
4490
4491   vat_json_print (vam->ofp, &node);
4492   vat_json_free (&node);
4493
4494   vam->retval = ntohl (mp->retval);
4495   vam->result_ready = 1;
4496 }
4497
4498 static void
4499   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4500   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4501 {
4502   vat_main_t *vam = &vat_main;
4503   i32 retval = ntohl (mp->retval);
4504
4505   if (retval >= 0)
4506     {
4507       print (vam->ofp, "%=20s", mp->locator_set_name);
4508     }
4509
4510   vam->retval = retval;
4511   vam->result_ready = 1;
4512 }
4513
4514 static void
4515   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4516   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4517 {
4518   vat_main_t *vam = &vat_main;
4519   vat_json_node_t *node = NULL;
4520
4521   if (VAT_JSON_ARRAY != vam->json_tree.type)
4522     {
4523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4524       vat_json_init_array (&vam->json_tree);
4525     }
4526   node = vat_json_array_add (&vam->json_tree);
4527
4528   vat_json_init_object (node);
4529   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4530
4531   vat_json_print (vam->ofp, node);
4532   vat_json_free (node);
4533
4534   vam->retval = ntohl (mp->retval);
4535   vam->result_ready = 1;
4536 }
4537
4538 static u8 *
4539 format_lisp_map_request_mode (u8 * s, va_list * args)
4540 {
4541   u32 mode = va_arg (*args, u32);
4542
4543   switch (mode)
4544     {
4545     case 0:
4546       return format (0, "dst-only");
4547     case 1:
4548       return format (0, "src-dst");
4549     }
4550   return 0;
4551 }
4552
4553 static void
4554   vl_api_show_one_map_request_mode_reply_t_handler
4555   (vl_api_show_one_map_request_mode_reply_t * mp)
4556 {
4557   vat_main_t *vam = &vat_main;
4558   i32 retval = ntohl (mp->retval);
4559
4560   if (0 <= retval)
4561     {
4562       u32 mode = mp->mode;
4563       print (vam->ofp, "map_request_mode: %U",
4564              format_lisp_map_request_mode, mode);
4565     }
4566
4567   vam->retval = retval;
4568   vam->result_ready = 1;
4569 }
4570
4571 static void
4572   vl_api_show_one_map_request_mode_reply_t_handler_json
4573   (vl_api_show_one_map_request_mode_reply_t * mp)
4574 {
4575   vat_main_t *vam = &vat_main;
4576   vat_json_node_t node;
4577   u8 *s = 0;
4578   u32 mode;
4579
4580   mode = mp->mode;
4581   s = format (0, "%U", format_lisp_map_request_mode, mode);
4582   vec_add1 (s, 0);
4583
4584   vat_json_init_object (&node);
4585   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   vec_free (s);
4590   vam->retval = ntohl (mp->retval);
4591   vam->result_ready = 1;
4592 }
4593
4594 static void
4595   vl_api_one_show_xtr_mode_reply_t_handler
4596   (vl_api_one_show_xtr_mode_reply_t * mp)
4597 {
4598   vat_main_t *vam = &vat_main;
4599   i32 retval = ntohl (mp->retval);
4600
4601   if (0 <= retval)
4602     {
4603       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4604     }
4605
4606   vam->retval = retval;
4607   vam->result_ready = 1;
4608 }
4609
4610 static void
4611   vl_api_one_show_xtr_mode_reply_t_handler_json
4612   (vl_api_one_show_xtr_mode_reply_t * mp)
4613 {
4614   vat_main_t *vam = &vat_main;
4615   vat_json_node_t node;
4616   u8 *status = 0;
4617
4618   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4619   vec_add1 (status, 0);
4620
4621   vat_json_init_object (&node);
4622   vat_json_object_add_string_copy (&node, "status", status);
4623
4624   vec_free (status);
4625
4626   vat_json_print (vam->ofp, &node);
4627   vat_json_free (&node);
4628
4629   vam->retval = ntohl (mp->retval);
4630   vam->result_ready = 1;
4631 }
4632
4633 static void
4634   vl_api_one_show_pitr_mode_reply_t_handler
4635   (vl_api_one_show_pitr_mode_reply_t * mp)
4636 {
4637   vat_main_t *vam = &vat_main;
4638   i32 retval = ntohl (mp->retval);
4639
4640   if (0 <= retval)
4641     {
4642       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4643     }
4644
4645   vam->retval = retval;
4646   vam->result_ready = 1;
4647 }
4648
4649 static void
4650   vl_api_one_show_pitr_mode_reply_t_handler_json
4651   (vl_api_one_show_pitr_mode_reply_t * mp)
4652 {
4653   vat_main_t *vam = &vat_main;
4654   vat_json_node_t node;
4655   u8 *status = 0;
4656
4657   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4658   vec_add1 (status, 0);
4659
4660   vat_json_init_object (&node);
4661   vat_json_object_add_string_copy (&node, "status", status);
4662
4663   vec_free (status);
4664
4665   vat_json_print (vam->ofp, &node);
4666   vat_json_free (&node);
4667
4668   vam->retval = ntohl (mp->retval);
4669   vam->result_ready = 1;
4670 }
4671
4672 static void
4673   vl_api_one_show_petr_mode_reply_t_handler
4674   (vl_api_one_show_petr_mode_reply_t * mp)
4675 {
4676   vat_main_t *vam = &vat_main;
4677   i32 retval = ntohl (mp->retval);
4678
4679   if (0 <= retval)
4680     {
4681       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4682     }
4683
4684   vam->retval = retval;
4685   vam->result_ready = 1;
4686 }
4687
4688 static void
4689   vl_api_one_show_petr_mode_reply_t_handler_json
4690   (vl_api_one_show_petr_mode_reply_t * mp)
4691 {
4692   vat_main_t *vam = &vat_main;
4693   vat_json_node_t node;
4694   u8 *status = 0;
4695
4696   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4697   vec_add1 (status, 0);
4698
4699   vat_json_init_object (&node);
4700   vat_json_object_add_string_copy (&node, "status", status);
4701
4702   vec_free (status);
4703
4704   vat_json_print (vam->ofp, &node);
4705   vat_json_free (&node);
4706
4707   vam->retval = ntohl (mp->retval);
4708   vam->result_ready = 1;
4709 }
4710
4711 static void
4712   vl_api_show_one_use_petr_reply_t_handler
4713   (vl_api_show_one_use_petr_reply_t * mp)
4714 {
4715   vat_main_t *vam = &vat_main;
4716   i32 retval = ntohl (mp->retval);
4717
4718   if (0 <= retval)
4719     {
4720       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4721       if (mp->status)
4722         {
4723           print (vam->ofp, "Proxy-ETR address; %U",
4724                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4725                  mp->address);
4726         }
4727     }
4728
4729   vam->retval = retval;
4730   vam->result_ready = 1;
4731 }
4732
4733 static void
4734   vl_api_show_one_use_petr_reply_t_handler_json
4735   (vl_api_show_one_use_petr_reply_t * mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   vat_json_node_t node;
4739   u8 *status = 0;
4740   struct in_addr ip4;
4741   struct in6_addr ip6;
4742
4743   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4744   vec_add1 (status, 0);
4745
4746   vat_json_init_object (&node);
4747   vat_json_object_add_string_copy (&node, "status", status);
4748   if (mp->status)
4749     {
4750       if (mp->is_ip4)
4751         {
4752           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4753           vat_json_object_add_ip6 (&node, "address", ip6);
4754         }
4755       else
4756         {
4757           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4758           vat_json_object_add_ip4 (&node, "address", ip4);
4759         }
4760     }
4761
4762   vec_free (status);
4763
4764   vat_json_print (vam->ofp, &node);
4765   vat_json_free (&node);
4766
4767   vam->retval = ntohl (mp->retval);
4768   vam->result_ready = 1;
4769 }
4770
4771 static void
4772   vl_api_show_one_nsh_mapping_reply_t_handler
4773   (vl_api_show_one_nsh_mapping_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   i32 retval = ntohl (mp->retval);
4777
4778   if (0 <= retval)
4779     {
4780       print (vam->ofp, "%-20s%-16s",
4781              mp->is_set ? "set" : "not-set",
4782              mp->is_set ? (char *) mp->locator_set_name : "");
4783     }
4784
4785   vam->retval = retval;
4786   vam->result_ready = 1;
4787 }
4788
4789 static void
4790   vl_api_show_one_nsh_mapping_reply_t_handler_json
4791   (vl_api_show_one_nsh_mapping_reply_t * mp)
4792 {
4793   vat_main_t *vam = &vat_main;
4794   vat_json_node_t node;
4795   u8 *status = 0;
4796
4797   status = format (0, "%s", mp->is_set ? "yes" : "no");
4798   vec_add1 (status, 0);
4799
4800   vat_json_init_object (&node);
4801   vat_json_object_add_string_copy (&node, "is_set", status);
4802   if (mp->is_set)
4803     {
4804       vat_json_object_add_string_copy (&node, "locator_set",
4805                                        mp->locator_set_name);
4806     }
4807
4808   vec_free (status);
4809
4810   vat_json_print (vam->ofp, &node);
4811   vat_json_free (&node);
4812
4813   vam->retval = ntohl (mp->retval);
4814   vam->result_ready = 1;
4815 }
4816
4817 static void
4818   vl_api_show_one_map_register_ttl_reply_t_handler
4819   (vl_api_show_one_map_register_ttl_reply_t * mp)
4820 {
4821   vat_main_t *vam = &vat_main;
4822   i32 retval = ntohl (mp->retval);
4823
4824   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4825
4826   if (0 <= retval)
4827     {
4828       print (vam->ofp, "ttl: %u", mp->ttl);
4829     }
4830
4831   vam->retval = retval;
4832   vam->result_ready = 1;
4833 }
4834
4835 static void
4836   vl_api_show_one_map_register_ttl_reply_t_handler_json
4837   (vl_api_show_one_map_register_ttl_reply_t * mp)
4838 {
4839   vat_main_t *vam = &vat_main;
4840   vat_json_node_t node;
4841
4842   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4843   vat_json_init_object (&node);
4844   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4845
4846   vat_json_print (vam->ofp, &node);
4847   vat_json_free (&node);
4848
4849   vam->retval = ntohl (mp->retval);
4850   vam->result_ready = 1;
4851 }
4852
4853 static void
4854 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858
4859   if (0 <= retval)
4860     {
4861       print (vam->ofp, "%-20s%-16s",
4862              mp->status ? "enabled" : "disabled",
4863              mp->status ? (char *) mp->locator_set_name : "");
4864     }
4865
4866   vam->retval = retval;
4867   vam->result_ready = 1;
4868 }
4869
4870 static void
4871 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t node;
4875   u8 *status = 0;
4876
4877   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4878   vec_add1 (status, 0);
4879
4880   vat_json_init_object (&node);
4881   vat_json_object_add_string_copy (&node, "status", status);
4882   if (mp->status)
4883     {
4884       vat_json_object_add_string_copy (&node, "locator_set",
4885                                        mp->locator_set_name);
4886     }
4887
4888   vec_free (status);
4889
4890   vat_json_print (vam->ofp, &node);
4891   vat_json_free (&node);
4892
4893   vam->retval = ntohl (mp->retval);
4894   vam->result_ready = 1;
4895 }
4896
4897 static u8 *
4898 format_policer_type (u8 * s, va_list * va)
4899 {
4900   u32 i = va_arg (*va, u32);
4901
4902   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4903     s = format (s, "1r2c");
4904   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4905     s = format (s, "1r3c");
4906   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4907     s = format (s, "2r3c-2698");
4908   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4909     s = format (s, "2r3c-4115");
4910   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4911     s = format (s, "2r3c-mef5cf1");
4912   else
4913     s = format (s, "ILLEGAL");
4914   return s;
4915 }
4916
4917 static u8 *
4918 format_policer_rate_type (u8 * s, va_list * va)
4919 {
4920   u32 i = va_arg (*va, u32);
4921
4922   if (i == SSE2_QOS_RATE_KBPS)
4923     s = format (s, "kbps");
4924   else if (i == SSE2_QOS_RATE_PPS)
4925     s = format (s, "pps");
4926   else
4927     s = format (s, "ILLEGAL");
4928   return s;
4929 }
4930
4931 static u8 *
4932 format_policer_round_type (u8 * s, va_list * va)
4933 {
4934   u32 i = va_arg (*va, u32);
4935
4936   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4937     s = format (s, "closest");
4938   else if (i == SSE2_QOS_ROUND_TO_UP)
4939     s = format (s, "up");
4940   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4941     s = format (s, "down");
4942   else
4943     s = format (s, "ILLEGAL");
4944   return s;
4945 }
4946
4947 static u8 *
4948 format_policer_action_type (u8 * s, va_list * va)
4949 {
4950   u32 i = va_arg (*va, u32);
4951
4952   if (i == SSE2_QOS_ACTION_DROP)
4953     s = format (s, "drop");
4954   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4955     s = format (s, "transmit");
4956   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4957     s = format (s, "mark-and-transmit");
4958   else
4959     s = format (s, "ILLEGAL");
4960   return s;
4961 }
4962
4963 static u8 *
4964 format_dscp (u8 * s, va_list * va)
4965 {
4966   u32 i = va_arg (*va, u32);
4967   char *t = 0;
4968
4969   switch (i)
4970     {
4971 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4972       foreach_vnet_dscp
4973 #undef _
4974     default:
4975       return format (s, "ILLEGAL");
4976     }
4977   s = format (s, "%s", t);
4978   return s;
4979 }
4980
4981 static void
4982 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4983 {
4984   vat_main_t *vam = &vat_main;
4985   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4986
4987   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4988     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4989   else
4990     conform_dscp_str = format (0, "");
4991
4992   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4993     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4994   else
4995     exceed_dscp_str = format (0, "");
4996
4997   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4998     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4999   else
5000     violate_dscp_str = format (0, "");
5001
5002   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
5003          "rate type %U, round type %U, %s rate, %s color-aware, "
5004          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
5005          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
5006          "conform action %U%s, exceed action %U%s, violate action %U%s",
5007          mp->name,
5008          format_policer_type, mp->type,
5009          ntohl (mp->cir),
5010          ntohl (mp->eir),
5011          clib_net_to_host_u64 (mp->cb),
5012          clib_net_to_host_u64 (mp->eb),
5013          format_policer_rate_type, mp->rate_type,
5014          format_policer_round_type, mp->round_type,
5015          mp->single_rate ? "single" : "dual",
5016          mp->color_aware ? "is" : "not",
5017          ntohl (mp->cir_tokens_per_period),
5018          ntohl (mp->pir_tokens_per_period),
5019          ntohl (mp->scale),
5020          ntohl (mp->current_limit),
5021          ntohl (mp->current_bucket),
5022          ntohl (mp->extended_limit),
5023          ntohl (mp->extended_bucket),
5024          clib_net_to_host_u64 (mp->last_update_time),
5025          format_policer_action_type, mp->conform_action_type,
5026          conform_dscp_str,
5027          format_policer_action_type, mp->exceed_action_type,
5028          exceed_dscp_str,
5029          format_policer_action_type, mp->violate_action_type,
5030          violate_dscp_str);
5031
5032   vec_free (conform_dscp_str);
5033   vec_free (exceed_dscp_str);
5034   vec_free (violate_dscp_str);
5035 }
5036
5037 static void vl_api_policer_details_t_handler_json
5038   (vl_api_policer_details_t * mp)
5039 {
5040   vat_main_t *vam = &vat_main;
5041   vat_json_node_t *node;
5042   u8 *rate_type_str, *round_type_str, *type_str;
5043   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
5044
5045   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
5046   round_type_str =
5047     format (0, "%U", format_policer_round_type, mp->round_type);
5048   type_str = format (0, "%U", format_policer_type, mp->type);
5049   conform_action_str = format (0, "%U", format_policer_action_type,
5050                                mp->conform_action_type);
5051   exceed_action_str = format (0, "%U", format_policer_action_type,
5052                               mp->exceed_action_type);
5053   violate_action_str = format (0, "%U", format_policer_action_type,
5054                                mp->violate_action_type);
5055
5056   if (VAT_JSON_ARRAY != vam->json_tree.type)
5057     {
5058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5059       vat_json_init_array (&vam->json_tree);
5060     }
5061   node = vat_json_array_add (&vam->json_tree);
5062
5063   vat_json_init_object (node);
5064   vat_json_object_add_string_copy (node, "name", mp->name);
5065   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
5066   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
5067   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
5068   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
5069   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
5070   vat_json_object_add_string_copy (node, "round_type", round_type_str);
5071   vat_json_object_add_string_copy (node, "type", type_str);
5072   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
5073   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5074   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5075   vat_json_object_add_uint (node, "cir_tokens_per_period",
5076                             ntohl (mp->cir_tokens_per_period));
5077   vat_json_object_add_uint (node, "eir_tokens_per_period",
5078                             ntohl (mp->pir_tokens_per_period));
5079   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5080   vat_json_object_add_uint (node, "current_bucket",
5081                             ntohl (mp->current_bucket));
5082   vat_json_object_add_uint (node, "extended_limit",
5083                             ntohl (mp->extended_limit));
5084   vat_json_object_add_uint (node, "extended_bucket",
5085                             ntohl (mp->extended_bucket));
5086   vat_json_object_add_uint (node, "last_update_time",
5087                             ntohl (mp->last_update_time));
5088   vat_json_object_add_string_copy (node, "conform_action",
5089                                    conform_action_str);
5090   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5091     {
5092       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5093       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5094       vec_free (dscp_str);
5095     }
5096   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5097   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5098     {
5099       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5100       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5101       vec_free (dscp_str);
5102     }
5103   vat_json_object_add_string_copy (node, "violate_action",
5104                                    violate_action_str);
5105   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5106     {
5107       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5108       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5109       vec_free (dscp_str);
5110     }
5111
5112   vec_free (rate_type_str);
5113   vec_free (round_type_str);
5114   vec_free (type_str);
5115   vec_free (conform_action_str);
5116   vec_free (exceed_action_str);
5117   vec_free (violate_action_str);
5118 }
5119
5120 static void
5121 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5122                                            mp)
5123 {
5124   vat_main_t *vam = &vat_main;
5125   int i, count = ntohl (mp->count);
5126
5127   if (count > 0)
5128     print (vam->ofp, "classify table ids (%d) : ", count);
5129   for (i = 0; i < count; i++)
5130     {
5131       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5132       print (vam->ofp, (i < count - 1) ? "," : "");
5133     }
5134   vam->retval = ntohl (mp->retval);
5135   vam->result_ready = 1;
5136 }
5137
5138 static void
5139   vl_api_classify_table_ids_reply_t_handler_json
5140   (vl_api_classify_table_ids_reply_t * mp)
5141 {
5142   vat_main_t *vam = &vat_main;
5143   int i, count = ntohl (mp->count);
5144
5145   if (count > 0)
5146     {
5147       vat_json_node_t node;
5148
5149       vat_json_init_object (&node);
5150       for (i = 0; i < count; i++)
5151         {
5152           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5153         }
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162   vl_api_classify_table_by_interface_reply_t_handler
5163   (vl_api_classify_table_by_interface_reply_t * mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166   u32 table_id;
5167
5168   table_id = ntohl (mp->l2_table_id);
5169   if (table_id != ~0)
5170     print (vam->ofp, "l2 table id : %d", table_id);
5171   else
5172     print (vam->ofp, "l2 table id : No input ACL tables configured");
5173   table_id = ntohl (mp->ip4_table_id);
5174   if (table_id != ~0)
5175     print (vam->ofp, "ip4 table id : %d", table_id);
5176   else
5177     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5178   table_id = ntohl (mp->ip6_table_id);
5179   if (table_id != ~0)
5180     print (vam->ofp, "ip6 table id : %d", table_id);
5181   else
5182     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5183   vam->retval = ntohl (mp->retval);
5184   vam->result_ready = 1;
5185 }
5186
5187 static void
5188   vl_api_classify_table_by_interface_reply_t_handler_json
5189   (vl_api_classify_table_by_interface_reply_t * mp)
5190 {
5191   vat_main_t *vam = &vat_main;
5192   vat_json_node_t node;
5193
5194   vat_json_init_object (&node);
5195
5196   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5197   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5198   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5199
5200   vat_json_print (vam->ofp, &node);
5201   vat_json_free (&node);
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_policer_add_del_reply_t_handler
5208   (vl_api_policer_add_del_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   i32 retval = ntohl (mp->retval);
5212   if (vam->async_mode)
5213     {
5214       vam->async_errors += (retval < 0);
5215     }
5216   else
5217     {
5218       vam->retval = retval;
5219       vam->result_ready = 1;
5220       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5221         /*
5222          * Note: this is just barely thread-safe, depends on
5223          * the main thread spinning waiting for an answer...
5224          */
5225         errmsg ("policer index %d", ntohl (mp->policer_index));
5226     }
5227 }
5228
5229 static void vl_api_policer_add_del_reply_t_handler_json
5230   (vl_api_policer_add_del_reply_t * mp)
5231 {
5232   vat_main_t *vam = &vat_main;
5233   vat_json_node_t node;
5234
5235   vat_json_init_object (&node);
5236   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5237   vat_json_object_add_uint (&node, "policer_index",
5238                             ntohl (mp->policer_index));
5239
5240   vat_json_print (vam->ofp, &node);
5241   vat_json_free (&node);
5242
5243   vam->retval = ntohl (mp->retval);
5244   vam->result_ready = 1;
5245 }
5246
5247 /* Format hex dump. */
5248 u8 *
5249 format_hex_bytes (u8 * s, va_list * va)
5250 {
5251   u8 *bytes = va_arg (*va, u8 *);
5252   int n_bytes = va_arg (*va, int);
5253   uword i;
5254
5255   /* Print short or long form depending on byte count. */
5256   uword short_form = n_bytes <= 32;
5257   u32 indent = format_get_indent (s);
5258
5259   if (n_bytes == 0)
5260     return s;
5261
5262   for (i = 0; i < n_bytes; i++)
5263     {
5264       if (!short_form && (i % 32) == 0)
5265         s = format (s, "%08x: ", i);
5266       s = format (s, "%02x", bytes[i]);
5267       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5268         s = format (s, "\n%U", format_white_space, indent);
5269     }
5270
5271   return s;
5272 }
5273
5274 static void
5275 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5276                                             * mp)
5277 {
5278   vat_main_t *vam = &vat_main;
5279   i32 retval = ntohl (mp->retval);
5280   if (retval == 0)
5281     {
5282       print (vam->ofp, "classify table info :");
5283       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5284              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5285              ntohl (mp->miss_next_index));
5286       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5287              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5288              ntohl (mp->match_n_vectors));
5289       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5290              ntohl (mp->mask_length));
5291     }
5292   vam->retval = retval;
5293   vam->result_ready = 1;
5294 }
5295
5296 static void
5297   vl_api_classify_table_info_reply_t_handler_json
5298   (vl_api_classify_table_info_reply_t * mp)
5299 {
5300   vat_main_t *vam = &vat_main;
5301   vat_json_node_t node;
5302
5303   i32 retval = ntohl (mp->retval);
5304   if (retval == 0)
5305     {
5306       vat_json_init_object (&node);
5307
5308       vat_json_object_add_int (&node, "sessions",
5309                                ntohl (mp->active_sessions));
5310       vat_json_object_add_int (&node, "nexttbl",
5311                                ntohl (mp->next_table_index));
5312       vat_json_object_add_int (&node, "nextnode",
5313                                ntohl (mp->miss_next_index));
5314       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5315       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5316       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5317       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5318                       ntohl (mp->mask_length), 0);
5319       vat_json_object_add_string_copy (&node, "mask", s);
5320
5321       vat_json_print (vam->ofp, &node);
5322       vat_json_free (&node);
5323     }
5324   vam->retval = ntohl (mp->retval);
5325   vam->result_ready = 1;
5326 }
5327
5328 static void
5329 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5330                                            mp)
5331 {
5332   vat_main_t *vam = &vat_main;
5333
5334   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5335          ntohl (mp->hit_next_index), ntohl (mp->advance),
5336          ntohl (mp->opaque_index));
5337   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5338          ntohl (mp->match_length));
5339 }
5340
5341 static void
5342   vl_api_classify_session_details_t_handler_json
5343   (vl_api_classify_session_details_t * mp)
5344 {
5345   vat_main_t *vam = &vat_main;
5346   vat_json_node_t *node = NULL;
5347
5348   if (VAT_JSON_ARRAY != vam->json_tree.type)
5349     {
5350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5351       vat_json_init_array (&vam->json_tree);
5352     }
5353   node = vat_json_array_add (&vam->json_tree);
5354
5355   vat_json_init_object (node);
5356   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5357   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5358   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5359   u8 *s =
5360     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5361             0);
5362   vat_json_object_add_string_copy (node, "match", s);
5363 }
5364
5365 static void vl_api_pg_create_interface_reply_t_handler
5366   (vl_api_pg_create_interface_reply_t * mp)
5367 {
5368   vat_main_t *vam = &vat_main;
5369
5370   vam->retval = ntohl (mp->retval);
5371   vam->result_ready = 1;
5372 }
5373
5374 static void vl_api_pg_create_interface_reply_t_handler_json
5375   (vl_api_pg_create_interface_reply_t * mp)
5376 {
5377   vat_main_t *vam = &vat_main;
5378   vat_json_node_t node;
5379
5380   i32 retval = ntohl (mp->retval);
5381   if (retval == 0)
5382     {
5383       vat_json_init_object (&node);
5384
5385       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5386
5387       vat_json_print (vam->ofp, &node);
5388       vat_json_free (&node);
5389     }
5390   vam->retval = ntohl (mp->retval);
5391   vam->result_ready = 1;
5392 }
5393
5394 static void vl_api_policer_classify_details_t_handler
5395   (vl_api_policer_classify_details_t * mp)
5396 {
5397   vat_main_t *vam = &vat_main;
5398
5399   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5400          ntohl (mp->table_index));
5401 }
5402
5403 static void vl_api_policer_classify_details_t_handler_json
5404   (vl_api_policer_classify_details_t * mp)
5405 {
5406   vat_main_t *vam = &vat_main;
5407   vat_json_node_t *node;
5408
5409   if (VAT_JSON_ARRAY != vam->json_tree.type)
5410     {
5411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5412       vat_json_init_array (&vam->json_tree);
5413     }
5414   node = vat_json_array_add (&vam->json_tree);
5415
5416   vat_json_init_object (node);
5417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5418   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5419 }
5420
5421 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5422   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5423 {
5424   vat_main_t *vam = &vat_main;
5425   i32 retval = ntohl (mp->retval);
5426   if (vam->async_mode)
5427     {
5428       vam->async_errors += (retval < 0);
5429     }
5430   else
5431     {
5432       vam->retval = retval;
5433       vam->sw_if_index = ntohl (mp->sw_if_index);
5434       vam->result_ready = 1;
5435     }
5436   vam->regenerate_interface_table = 1;
5437 }
5438
5439 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5440   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5441 {
5442   vat_main_t *vam = &vat_main;
5443   vat_json_node_t node;
5444
5445   vat_json_init_object (&node);
5446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5448
5449   vat_json_print (vam->ofp, &node);
5450   vat_json_free (&node);
5451
5452   vam->retval = ntohl (mp->retval);
5453   vam->result_ready = 1;
5454 }
5455
5456 static void vl_api_flow_classify_details_t_handler
5457   (vl_api_flow_classify_details_t * mp)
5458 {
5459   vat_main_t *vam = &vat_main;
5460
5461   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5462          ntohl (mp->table_index));
5463 }
5464
5465 static void vl_api_flow_classify_details_t_handler_json
5466   (vl_api_flow_classify_details_t * mp)
5467 {
5468   vat_main_t *vam = &vat_main;
5469   vat_json_node_t *node;
5470
5471   if (VAT_JSON_ARRAY != vam->json_tree.type)
5472     {
5473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5474       vat_json_init_array (&vam->json_tree);
5475     }
5476   node = vat_json_array_add (&vam->json_tree);
5477
5478   vat_json_init_object (node);
5479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5480   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5481 }
5482
5483 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5484 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5485 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5486 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5487 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5488 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5489 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5490 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5491 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5492 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5493 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5494 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5495 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5496 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5497 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5498 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5499 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5500 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5501 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5502 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5503 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5504 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5505
5506 /*
5507  * Generate boilerplate reply handlers, which
5508  * dig the return value out of the xxx_reply_t API message,
5509  * stick it into vam->retval, and set vam->result_ready
5510  *
5511  * Could also do this by pointing N message decode slots at
5512  * a single function, but that could break in subtle ways.
5513  */
5514
5515 #define foreach_standard_reply_retval_handler           \
5516 _(sw_interface_set_flags_reply)                         \
5517 _(sw_interface_add_del_address_reply)                   \
5518 _(sw_interface_set_rx_mode_reply)                       \
5519 _(sw_interface_set_table_reply)                         \
5520 _(sw_interface_set_mpls_enable_reply)                   \
5521 _(sw_interface_set_vpath_reply)                         \
5522 _(sw_interface_set_vxlan_bypass_reply)                  \
5523 _(sw_interface_set_geneve_bypass_reply)                 \
5524 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5525 _(sw_interface_set_l2_bridge_reply)                     \
5526 _(bridge_domain_add_del_reply)                          \
5527 _(sw_interface_set_l2_xconnect_reply)                   \
5528 _(l2fib_add_del_reply)                                  \
5529 _(l2fib_flush_int_reply)                                \
5530 _(l2fib_flush_bd_reply)                                 \
5531 _(ip_add_del_route_reply)                               \
5532 _(ip_table_add_del_reply)                               \
5533 _(ip_mroute_add_del_reply)                              \
5534 _(mpls_route_add_del_reply)                             \
5535 _(mpls_table_add_del_reply)                             \
5536 _(mpls_ip_bind_unbind_reply)                            \
5537 _(bier_route_add_del_reply)                             \
5538 _(bier_table_add_del_reply)                             \
5539 _(proxy_arp_add_del_reply)                              \
5540 _(proxy_arp_intfc_enable_disable_reply)                 \
5541 _(sw_interface_set_unnumbered_reply)                    \
5542 _(ip_neighbor_add_del_reply)                            \
5543 _(oam_add_del_reply)                                    \
5544 _(reset_fib_reply)                                      \
5545 _(dhcp_proxy_config_reply)                              \
5546 _(dhcp_proxy_set_vss_reply)                             \
5547 _(dhcp_client_config_reply)                             \
5548 _(set_ip_flow_hash_reply)                               \
5549 _(sw_interface_ip6_enable_disable_reply)                \
5550 _(sw_interface_ip6_set_link_local_address_reply)        \
5551 _(ip6nd_proxy_add_del_reply)                            \
5552 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5553 _(sw_interface_ip6nd_ra_config_reply)                   \
5554 _(set_arp_neighbor_limit_reply)                         \
5555 _(l2_patch_add_del_reply)                               \
5556 _(sr_policy_add_reply)                                  \
5557 _(sr_policy_mod_reply)                                  \
5558 _(sr_policy_del_reply)                                  \
5559 _(sr_localsid_add_del_reply)                            \
5560 _(sr_steering_add_del_reply)                            \
5561 _(classify_add_del_session_reply)                       \
5562 _(classify_set_interface_ip_table_reply)                \
5563 _(classify_set_interface_l2_tables_reply)               \
5564 _(l2tpv3_set_tunnel_cookies_reply)                      \
5565 _(l2tpv3_interface_enable_disable_reply)                \
5566 _(l2tpv3_set_lookup_key_reply)                          \
5567 _(l2_fib_clear_table_reply)                             \
5568 _(l2_interface_efp_filter_reply)                        \
5569 _(l2_interface_vlan_tag_rewrite_reply)                  \
5570 _(modify_vhost_user_if_reply)                           \
5571 _(delete_vhost_user_if_reply)                           \
5572 _(want_ip4_arp_events_reply)                            \
5573 _(want_ip6_nd_events_reply)                             \
5574 _(want_l2_macs_events_reply)                            \
5575 _(input_acl_set_interface_reply)                        \
5576 _(ipsec_spd_add_del_reply)                              \
5577 _(ipsec_interface_add_del_spd_reply)                    \
5578 _(ipsec_spd_add_del_entry_reply)                        \
5579 _(ipsec_sad_add_del_entry_reply)                        \
5580 _(ipsec_sa_set_key_reply)                               \
5581 _(ipsec_tunnel_if_add_del_reply)                        \
5582 _(ipsec_tunnel_if_set_key_reply)                        \
5583 _(ipsec_tunnel_if_set_sa_reply)                         \
5584 _(ikev2_profile_add_del_reply)                          \
5585 _(ikev2_profile_set_auth_reply)                         \
5586 _(ikev2_profile_set_id_reply)                           \
5587 _(ikev2_profile_set_ts_reply)                           \
5588 _(ikev2_set_local_key_reply)                            \
5589 _(ikev2_set_responder_reply)                            \
5590 _(ikev2_set_ike_transforms_reply)                       \
5591 _(ikev2_set_esp_transforms_reply)                       \
5592 _(ikev2_set_sa_lifetime_reply)                          \
5593 _(ikev2_initiate_sa_init_reply)                         \
5594 _(ikev2_initiate_del_ike_sa_reply)                      \
5595 _(ikev2_initiate_del_child_sa_reply)                    \
5596 _(ikev2_initiate_rekey_child_sa_reply)                  \
5597 _(delete_loopback_reply)                                \
5598 _(bd_ip_mac_add_del_reply)                              \
5599 _(map_del_domain_reply)                                 \
5600 _(map_add_del_rule_reply)                               \
5601 _(want_interface_events_reply)                          \
5602 _(want_stats_reply)                                     \
5603 _(cop_interface_enable_disable_reply)                   \
5604 _(cop_whitelist_enable_disable_reply)                   \
5605 _(sw_interface_clear_stats_reply)                       \
5606 _(ioam_enable_reply)                                    \
5607 _(ioam_disable_reply)                                   \
5608 _(one_add_del_locator_reply)                            \
5609 _(one_add_del_local_eid_reply)                          \
5610 _(one_add_del_remote_mapping_reply)                     \
5611 _(one_add_del_adjacency_reply)                          \
5612 _(one_add_del_map_resolver_reply)                       \
5613 _(one_add_del_map_server_reply)                         \
5614 _(one_enable_disable_reply)                             \
5615 _(one_rloc_probe_enable_disable_reply)                  \
5616 _(one_map_register_enable_disable_reply)                \
5617 _(one_map_register_set_ttl_reply)                       \
5618 _(one_set_transport_protocol_reply)                     \
5619 _(one_map_register_fallback_threshold_reply)            \
5620 _(one_pitr_set_locator_set_reply)                       \
5621 _(one_map_request_mode_reply)                           \
5622 _(one_add_del_map_request_itr_rlocs_reply)              \
5623 _(one_eid_table_add_del_map_reply)                      \
5624 _(one_use_petr_reply)                                   \
5625 _(one_stats_enable_disable_reply)                       \
5626 _(one_add_del_l2_arp_entry_reply)                       \
5627 _(one_add_del_ndp_entry_reply)                          \
5628 _(one_stats_flush_reply)                                \
5629 _(one_enable_disable_xtr_mode_reply)                    \
5630 _(one_enable_disable_pitr_mode_reply)                   \
5631 _(one_enable_disable_petr_mode_reply)                   \
5632 _(gpe_enable_disable_reply)                             \
5633 _(gpe_set_encap_mode_reply)                             \
5634 _(gpe_add_del_iface_reply)                              \
5635 _(gpe_add_del_native_fwd_rpath_reply)                   \
5636 _(af_packet_delete_reply)                               \
5637 _(policer_classify_set_interface_reply)                 \
5638 _(netmap_create_reply)                                  \
5639 _(netmap_delete_reply)                                  \
5640 _(set_ipfix_exporter_reply)                             \
5641 _(set_ipfix_classify_stream_reply)                      \
5642 _(ipfix_classify_table_add_del_reply)                   \
5643 _(flow_classify_set_interface_reply)                    \
5644 _(sw_interface_span_enable_disable_reply)               \
5645 _(pg_capture_reply)                                     \
5646 _(pg_enable_disable_reply)                              \
5647 _(ip_source_and_port_range_check_add_del_reply)         \
5648 _(ip_source_and_port_range_check_interface_add_del_reply)\
5649 _(delete_subif_reply)                                   \
5650 _(l2_interface_pbb_tag_rewrite_reply)                   \
5651 _(punt_reply)                                           \
5652 _(feature_enable_disable_reply)                         \
5653 _(sw_interface_tag_add_del_reply)                       \
5654 _(sw_interface_set_mtu_reply)                           \
5655 _(p2p_ethernet_add_reply)                               \
5656 _(p2p_ethernet_del_reply)                               \
5657 _(lldp_config_reply)                                    \
5658 _(sw_interface_set_lldp_reply)                          \
5659 _(tcp_configure_src_addresses_reply)                    \
5660 _(dns_enable_disable_reply)                             \
5661 _(dns_name_server_add_del_reply)                        \
5662 _(session_rule_add_del_reply)                           \
5663 _(ip_container_proxy_add_del_reply)                     \
5664 _(output_acl_set_interface_reply)
5665
5666 #define _(n)                                    \
5667     static void vl_api_##n##_t_handler          \
5668     (vl_api_##n##_t * mp)                       \
5669     {                                           \
5670         vat_main_t * vam = &vat_main;           \
5671         i32 retval = ntohl(mp->retval);         \
5672         if (vam->async_mode) {                  \
5673             vam->async_errors += (retval < 0);  \
5674         } else {                                \
5675             vam->retval = retval;               \
5676             vam->result_ready = 1;              \
5677         }                                       \
5678     }
5679 foreach_standard_reply_retval_handler;
5680 #undef _
5681
5682 #define _(n)                                    \
5683     static void vl_api_##n##_t_handler_json     \
5684     (vl_api_##n##_t * mp)                       \
5685     {                                           \
5686         vat_main_t * vam = &vat_main;           \
5687         vat_json_node_t node;                   \
5688         vat_json_init_object(&node);            \
5689         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5690         vat_json_print(vam->ofp, &node);        \
5691         vam->retval = ntohl(mp->retval);        \
5692         vam->result_ready = 1;                  \
5693     }
5694 foreach_standard_reply_retval_handler;
5695 #undef _
5696
5697 /*
5698  * Table of message reply handlers, must include boilerplate handlers
5699  * we just generated
5700  */
5701
5702 #define foreach_vpe_api_reply_msg                                       \
5703 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5704 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5705 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5706 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5707 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5708 _(CLI_REPLY, cli_reply)                                                 \
5709 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5710 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5711   sw_interface_add_del_address_reply)                                   \
5712 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5713 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5714 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5715 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5716 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5717 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5718 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5719 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5720   sw_interface_set_l2_xconnect_reply)                                   \
5721 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5722   sw_interface_set_l2_bridge_reply)                                     \
5723 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5724 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5725 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5726 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5727 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5728 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5729 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5730 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5731 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5732 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5733 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5734 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5735 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5736 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5737 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5738 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5739 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5740 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5741 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5742 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5743 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5744 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5745 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5746 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5747 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5748 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5749 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5750 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5751 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5752 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5753 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5754   proxy_arp_intfc_enable_disable_reply)                                 \
5755 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5756 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5757   sw_interface_set_unnumbered_reply)                                    \
5758 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5759 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5760 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5761 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5762 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5763 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5764 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5765 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5766 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5767 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5768 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5769   sw_interface_ip6_enable_disable_reply)                                \
5770 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5771   sw_interface_ip6_set_link_local_address_reply)                        \
5772 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5773 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5774 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5775   sw_interface_ip6nd_ra_prefix_reply)                                   \
5776 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5777   sw_interface_ip6nd_ra_config_reply)                                   \
5778 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5779 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5780 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5781 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5782 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5783 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5784 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5785 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5786 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5787 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5788 classify_set_interface_ip_table_reply)                                  \
5789 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5790   classify_set_interface_l2_tables_reply)                               \
5791 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5792 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5793 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5794 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5795 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5796   l2tpv3_interface_enable_disable_reply)                                \
5797 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5798 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5799 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5800 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5801 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5802 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5803 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5804 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5805 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5806 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5807 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5808 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5809 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5810 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5811 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5812 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5813 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5814 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5815 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5816 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5817 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5818 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5819 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5820 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5821 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5822 _(L2_MACS_EVENT, l2_macs_event)                                         \
5823 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5824 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5825 _(IP_DETAILS, ip_details)                                               \
5826 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5827 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5828 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5829 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5830 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5831 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5832 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5833 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5834 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5835 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5836 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5837 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5838 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5839 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5840 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5841 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5842 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5843 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5844 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5845 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5846 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5847 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5848 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5849 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5850 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5851 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5852 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5853 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5854 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5855 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5856 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5857 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5858 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5859 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5860 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5861 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5862 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5863 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5864 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5865 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5866 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5867 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5868 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5869 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5870 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5871 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5872 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5873 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5874   one_map_register_enable_disable_reply)                                \
5875 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5876 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5877 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5878 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5879   one_map_register_fallback_threshold_reply)                            \
5880 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5881   one_rloc_probe_enable_disable_reply)                                  \
5882 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5883 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5884 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5885 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5886 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5887 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5888 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5889 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5890 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5891 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5892 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5893 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5894 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5895 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5896 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5897 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5898   show_one_stats_enable_disable_reply)                                  \
5899 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5900 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5901 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5902 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5903 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5904 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5905 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5906 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5907   one_enable_disable_pitr_mode_reply)                                   \
5908 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5909   one_enable_disable_petr_mode_reply)                                   \
5910 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5911 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5912 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5913 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5914 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5915 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5916 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5917 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5918 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5919 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5920 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5921 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5922   gpe_add_del_native_fwd_rpath_reply)                                   \
5923 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5924   gpe_fwd_entry_path_details)                                           \
5925 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5926 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5927   one_add_del_map_request_itr_rlocs_reply)                              \
5928 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5929   one_get_map_request_itr_rlocs_reply)                                  \
5930 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5931 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5932 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5933 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5934 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5935 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5936   show_one_map_register_state_reply)                                    \
5937 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5938 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5939   show_one_map_register_fallback_threshold_reply)                       \
5940 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5941 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5942 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5943 _(POLICER_DETAILS, policer_details)                                     \
5944 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5945 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5946 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5947 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5948 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5949 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5950 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5951 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5952 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5953 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5954 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5955 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5956 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5957 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5958 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5959 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5960 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5961 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5962 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5963 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5964 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5965 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5966 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5967 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5968 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5969  ip_source_and_port_range_check_add_del_reply)                          \
5970 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5971  ip_source_and_port_range_check_interface_add_del_reply)                \
5972 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5973 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5974 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5975 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5976 _(PUNT_REPLY, punt_reply)                                               \
5977 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5978 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5979 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5980 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5981 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5982 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5983 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5984 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5985 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5986 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5987 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5988 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5989 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5990 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5991 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5992 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5993 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5994 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5995 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5996 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5997 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5998 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5999
6000 #define foreach_standalone_reply_msg                                    \
6001 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
6002 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
6003 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
6004 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
6005 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
6006 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
6007 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
6008 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
6009
6010 typedef struct
6011 {
6012   u8 *name;
6013   u32 value;
6014 } name_sort_t;
6015
6016
6017 #define STR_VTR_OP_CASE(op)     \
6018     case L2_VTR_ ## op:         \
6019         return "" # op;
6020
6021 static const char *
6022 str_vtr_op (u32 vtr_op)
6023 {
6024   switch (vtr_op)
6025     {
6026       STR_VTR_OP_CASE (DISABLED);
6027       STR_VTR_OP_CASE (PUSH_1);
6028       STR_VTR_OP_CASE (PUSH_2);
6029       STR_VTR_OP_CASE (POP_1);
6030       STR_VTR_OP_CASE (POP_2);
6031       STR_VTR_OP_CASE (TRANSLATE_1_1);
6032       STR_VTR_OP_CASE (TRANSLATE_1_2);
6033       STR_VTR_OP_CASE (TRANSLATE_2_1);
6034       STR_VTR_OP_CASE (TRANSLATE_2_2);
6035     }
6036
6037   return "UNKNOWN";
6038 }
6039
6040 static int
6041 dump_sub_interface_table (vat_main_t * vam)
6042 {
6043   const sw_interface_subif_t *sub = NULL;
6044
6045   if (vam->json_output)
6046     {
6047       clib_warning
6048         ("JSON output supported only for VPE API calls and dump_stats_table");
6049       return -99;
6050     }
6051
6052   print (vam->ofp,
6053          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
6054          "Interface", "sw_if_index",
6055          "sub id", "dot1ad", "tags", "outer id",
6056          "inner id", "exact", "default", "outer any", "inner any");
6057
6058   vec_foreach (sub, vam->sw_if_subif_table)
6059   {
6060     print (vam->ofp,
6061            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
6062            sub->interface_name,
6063            sub->sw_if_index,
6064            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
6065            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6066            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6067            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6068     if (sub->vtr_op != L2_VTR_DISABLED)
6069       {
6070         print (vam->ofp,
6071                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6072                "tag1: %d tag2: %d ]",
6073                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6074                sub->vtr_tag1, sub->vtr_tag2);
6075       }
6076   }
6077
6078   return 0;
6079 }
6080
6081 static int
6082 name_sort_cmp (void *a1, void *a2)
6083 {
6084   name_sort_t *n1 = a1;
6085   name_sort_t *n2 = a2;
6086
6087   return strcmp ((char *) n1->name, (char *) n2->name);
6088 }
6089
6090 static int
6091 dump_interface_table (vat_main_t * vam)
6092 {
6093   hash_pair_t *p;
6094   name_sort_t *nses = 0, *ns;
6095
6096   if (vam->json_output)
6097     {
6098       clib_warning
6099         ("JSON output supported only for VPE API calls and dump_stats_table");
6100       return -99;
6101     }
6102
6103   /* *INDENT-OFF* */
6104   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6105   ({
6106     vec_add2 (nses, ns, 1);
6107     ns->name = (u8 *)(p->key);
6108     ns->value = (u32) p->value[0];
6109   }));
6110   /* *INDENT-ON* */
6111
6112   vec_sort_with_function (nses, name_sort_cmp);
6113
6114   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6115   vec_foreach (ns, nses)
6116   {
6117     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6118   }
6119   vec_free (nses);
6120   return 0;
6121 }
6122
6123 static int
6124 dump_ip_table (vat_main_t * vam, int is_ipv6)
6125 {
6126   const ip_details_t *det = NULL;
6127   const ip_address_details_t *address = NULL;
6128   u32 i = ~0;
6129
6130   print (vam->ofp, "%-12s", "sw_if_index");
6131
6132   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6133   {
6134     i++;
6135     if (!det->present)
6136       {
6137         continue;
6138       }
6139     print (vam->ofp, "%-12d", i);
6140     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6141     if (!det->addr)
6142       {
6143         continue;
6144       }
6145     vec_foreach (address, det->addr)
6146     {
6147       print (vam->ofp,
6148              "            %-30U%-13d",
6149              is_ipv6 ? format_ip6_address : format_ip4_address,
6150              address->ip, address->prefix_length);
6151     }
6152   }
6153
6154   return 0;
6155 }
6156
6157 static int
6158 dump_ipv4_table (vat_main_t * vam)
6159 {
6160   if (vam->json_output)
6161     {
6162       clib_warning
6163         ("JSON output supported only for VPE API calls and dump_stats_table");
6164       return -99;
6165     }
6166
6167   return dump_ip_table (vam, 0);
6168 }
6169
6170 static int
6171 dump_ipv6_table (vat_main_t * vam)
6172 {
6173   if (vam->json_output)
6174     {
6175       clib_warning
6176         ("JSON output supported only for VPE API calls and dump_stats_table");
6177       return -99;
6178     }
6179
6180   return dump_ip_table (vam, 1);
6181 }
6182
6183 static char *
6184 counter_type_to_str (u8 counter_type, u8 is_combined)
6185 {
6186   if (!is_combined)
6187     {
6188       switch (counter_type)
6189         {
6190         case VNET_INTERFACE_COUNTER_DROP:
6191           return "drop";
6192         case VNET_INTERFACE_COUNTER_PUNT:
6193           return "punt";
6194         case VNET_INTERFACE_COUNTER_IP4:
6195           return "ip4";
6196         case VNET_INTERFACE_COUNTER_IP6:
6197           return "ip6";
6198         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6199           return "rx-no-buf";
6200         case VNET_INTERFACE_COUNTER_RX_MISS:
6201           return "rx-miss";
6202         case VNET_INTERFACE_COUNTER_RX_ERROR:
6203           return "rx-error";
6204         case VNET_INTERFACE_COUNTER_TX_ERROR:
6205           return "tx-error";
6206         default:
6207           return "INVALID-COUNTER-TYPE";
6208         }
6209     }
6210   else
6211     {
6212       switch (counter_type)
6213         {
6214         case VNET_INTERFACE_COUNTER_RX:
6215           return "rx";
6216         case VNET_INTERFACE_COUNTER_TX:
6217           return "tx";
6218         default:
6219           return "INVALID-COUNTER-TYPE";
6220         }
6221     }
6222 }
6223
6224 static int
6225 dump_stats_table (vat_main_t * vam)
6226 {
6227   vat_json_node_t node;
6228   vat_json_node_t *msg_array;
6229   vat_json_node_t *msg;
6230   vat_json_node_t *counter_array;
6231   vat_json_node_t *counter;
6232   interface_counter_t c;
6233   u64 packets;
6234   ip4_fib_counter_t *c4;
6235   ip6_fib_counter_t *c6;
6236   ip4_nbr_counter_t *n4;
6237   ip6_nbr_counter_t *n6;
6238   int i, j;
6239
6240   if (!vam->json_output)
6241     {
6242       clib_warning ("dump_stats_table supported only in JSON format");
6243       return -99;
6244     }
6245
6246   vat_json_init_object (&node);
6247
6248   /* interface counters */
6249   msg_array = vat_json_object_add (&node, "interface_counters");
6250   vat_json_init_array (msg_array);
6251   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6252     {
6253       msg = vat_json_array_add (msg_array);
6254       vat_json_init_object (msg);
6255       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6256                                        (u8 *) counter_type_to_str (i, 0));
6257       vat_json_object_add_int (msg, "is_combined", 0);
6258       counter_array = vat_json_object_add (msg, "data");
6259       vat_json_init_array (counter_array);
6260       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6261         {
6262           packets = vam->simple_interface_counters[i][j];
6263           vat_json_array_add_uint (counter_array, packets);
6264         }
6265     }
6266   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6267     {
6268       msg = vat_json_array_add (msg_array);
6269       vat_json_init_object (msg);
6270       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6271                                        (u8 *) counter_type_to_str (i, 1));
6272       vat_json_object_add_int (msg, "is_combined", 1);
6273       counter_array = vat_json_object_add (msg, "data");
6274       vat_json_init_array (counter_array);
6275       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6276         {
6277           c = vam->combined_interface_counters[i][j];
6278           counter = vat_json_array_add (counter_array);
6279           vat_json_init_object (counter);
6280           vat_json_object_add_uint (counter, "packets", c.packets);
6281           vat_json_object_add_uint (counter, "bytes", c.bytes);
6282         }
6283     }
6284
6285   /* ip4 fib counters */
6286   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6287   vat_json_init_array (msg_array);
6288   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6289     {
6290       msg = vat_json_array_add (msg_array);
6291       vat_json_init_object (msg);
6292       vat_json_object_add_uint (msg, "vrf_id",
6293                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6294       counter_array = vat_json_object_add (msg, "c");
6295       vat_json_init_array (counter_array);
6296       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6297         {
6298           counter = vat_json_array_add (counter_array);
6299           vat_json_init_object (counter);
6300           c4 = &vam->ip4_fib_counters[i][j];
6301           vat_json_object_add_ip4 (counter, "address", c4->address);
6302           vat_json_object_add_uint (counter, "address_length",
6303                                     c4->address_length);
6304           vat_json_object_add_uint (counter, "packets", c4->packets);
6305           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6306         }
6307     }
6308
6309   /* ip6 fib counters */
6310   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6311   vat_json_init_array (msg_array);
6312   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6313     {
6314       msg = vat_json_array_add (msg_array);
6315       vat_json_init_object (msg);
6316       vat_json_object_add_uint (msg, "vrf_id",
6317                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6318       counter_array = vat_json_object_add (msg, "c");
6319       vat_json_init_array (counter_array);
6320       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6321         {
6322           counter = vat_json_array_add (counter_array);
6323           vat_json_init_object (counter);
6324           c6 = &vam->ip6_fib_counters[i][j];
6325           vat_json_object_add_ip6 (counter, "address", c6->address);
6326           vat_json_object_add_uint (counter, "address_length",
6327                                     c6->address_length);
6328           vat_json_object_add_uint (counter, "packets", c6->packets);
6329           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6330         }
6331     }
6332
6333   /* ip4 nbr counters */
6334   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6335   vat_json_init_array (msg_array);
6336   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6337     {
6338       msg = vat_json_array_add (msg_array);
6339       vat_json_init_object (msg);
6340       vat_json_object_add_uint (msg, "sw_if_index", i);
6341       counter_array = vat_json_object_add (msg, "c");
6342       vat_json_init_array (counter_array);
6343       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6344         {
6345           counter = vat_json_array_add (counter_array);
6346           vat_json_init_object (counter);
6347           n4 = &vam->ip4_nbr_counters[i][j];
6348           vat_json_object_add_ip4 (counter, "address", n4->address);
6349           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6350           vat_json_object_add_uint (counter, "packets", n4->packets);
6351           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6352         }
6353     }
6354
6355   /* ip6 nbr counters */
6356   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6357   vat_json_init_array (msg_array);
6358   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6359     {
6360       msg = vat_json_array_add (msg_array);
6361       vat_json_init_object (msg);
6362       vat_json_object_add_uint (msg, "sw_if_index", i);
6363       counter_array = vat_json_object_add (msg, "c");
6364       vat_json_init_array (counter_array);
6365       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6366         {
6367           counter = vat_json_array_add (counter_array);
6368           vat_json_init_object (counter);
6369           n6 = &vam->ip6_nbr_counters[i][j];
6370           vat_json_object_add_ip6 (counter, "address", n6->address);
6371           vat_json_object_add_uint (counter, "packets", n6->packets);
6372           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6373         }
6374     }
6375
6376   vat_json_print (vam->ofp, &node);
6377   vat_json_free (&node);
6378
6379   return 0;
6380 }
6381
6382 /*
6383  * Pass CLI buffers directly in the CLI_INBAND API message,
6384  * instead of an additional shared memory area.
6385  */
6386 static int
6387 exec_inband (vat_main_t * vam)
6388 {
6389   vl_api_cli_inband_t *mp;
6390   unformat_input_t *i = vam->input;
6391   int ret;
6392
6393   if (vec_len (i->buffer) == 0)
6394     return -1;
6395
6396   if (vam->exec_mode == 0 && unformat (i, "mode"))
6397     {
6398       vam->exec_mode = 1;
6399       return 0;
6400     }
6401   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6402     {
6403       vam->exec_mode = 0;
6404       return 0;
6405     }
6406
6407   /*
6408    * In order for the CLI command to work, it
6409    * must be a vector ending in \n, not a C-string ending
6410    * in \n\0.
6411    */
6412   u32 len = vec_len (vam->input->buffer);
6413   M2 (CLI_INBAND, mp, len);
6414   clib_memcpy (mp->cmd, vam->input->buffer, len);
6415   mp->length = htonl (len);
6416
6417   S (mp);
6418   W (ret);
6419   /* json responses may or may not include a useful reply... */
6420   if (vec_len (vam->cmd_reply))
6421     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6422   return ret;
6423 }
6424
6425 int
6426 exec (vat_main_t * vam)
6427 {
6428   return exec_inband (vam);
6429 }
6430
6431 static int
6432 api_create_loopback (vat_main_t * vam)
6433 {
6434   unformat_input_t *i = vam->input;
6435   vl_api_create_loopback_t *mp;
6436   vl_api_create_loopback_instance_t *mp_lbi;
6437   u8 mac_address[6];
6438   u8 mac_set = 0;
6439   u8 is_specified = 0;
6440   u32 user_instance = 0;
6441   int ret;
6442
6443   memset (mac_address, 0, sizeof (mac_address));
6444
6445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6446     {
6447       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6448         mac_set = 1;
6449       if (unformat (i, "instance %d", &user_instance))
6450         is_specified = 1;
6451       else
6452         break;
6453     }
6454
6455   if (is_specified)
6456     {
6457       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6458       mp_lbi->is_specified = is_specified;
6459       if (is_specified)
6460         mp_lbi->user_instance = htonl (user_instance);
6461       if (mac_set)
6462         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6463       S (mp_lbi);
6464     }
6465   else
6466     {
6467       /* Construct the API message */
6468       M (CREATE_LOOPBACK, mp);
6469       if (mac_set)
6470         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6471       S (mp);
6472     }
6473
6474   W (ret);
6475   return ret;
6476 }
6477
6478 static int
6479 api_delete_loopback (vat_main_t * vam)
6480 {
6481   unformat_input_t *i = vam->input;
6482   vl_api_delete_loopback_t *mp;
6483   u32 sw_if_index = ~0;
6484   int ret;
6485
6486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6487     {
6488       if (unformat (i, "sw_if_index %d", &sw_if_index))
6489         ;
6490       else
6491         break;
6492     }
6493
6494   if (sw_if_index == ~0)
6495     {
6496       errmsg ("missing sw_if_index");
6497       return -99;
6498     }
6499
6500   /* Construct the API message */
6501   M (DELETE_LOOPBACK, mp);
6502   mp->sw_if_index = ntohl (sw_if_index);
6503
6504   S (mp);
6505   W (ret);
6506   return ret;
6507 }
6508
6509 static int
6510 api_want_stats (vat_main_t * vam)
6511 {
6512   unformat_input_t *i = vam->input;
6513   vl_api_want_stats_t *mp;
6514   int enable = -1;
6515   int ret;
6516
6517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6518     {
6519       if (unformat (i, "enable"))
6520         enable = 1;
6521       else if (unformat (i, "disable"))
6522         enable = 0;
6523       else
6524         break;
6525     }
6526
6527   if (enable == -1)
6528     {
6529       errmsg ("missing enable|disable");
6530       return -99;
6531     }
6532
6533   M (WANT_STATS, mp);
6534   mp->enable_disable = enable;
6535
6536   S (mp);
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_want_interface_events (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_want_interface_events_t *mp;
6546   int enable = -1;
6547   int ret;
6548
6549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6550     {
6551       if (unformat (i, "enable"))
6552         enable = 1;
6553       else if (unformat (i, "disable"))
6554         enable = 0;
6555       else
6556         break;
6557     }
6558
6559   if (enable == -1)
6560     {
6561       errmsg ("missing enable|disable");
6562       return -99;
6563     }
6564
6565   M (WANT_INTERFACE_EVENTS, mp);
6566   mp->enable_disable = enable;
6567
6568   vam->interface_event_display = enable;
6569
6570   S (mp);
6571   W (ret);
6572   return ret;
6573 }
6574
6575
6576 /* Note: non-static, called once to set up the initial intfc table */
6577 int
6578 api_sw_interface_dump (vat_main_t * vam)
6579 {
6580   vl_api_sw_interface_dump_t *mp;
6581   vl_api_control_ping_t *mp_ping;
6582   hash_pair_t *p;
6583   name_sort_t *nses = 0, *ns;
6584   sw_interface_subif_t *sub = NULL;
6585   int ret;
6586
6587   /* Toss the old name table */
6588   /* *INDENT-OFF* */
6589   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6590   ({
6591     vec_add2 (nses, ns, 1);
6592     ns->name = (u8 *)(p->key);
6593     ns->value = (u32) p->value[0];
6594   }));
6595   /* *INDENT-ON* */
6596
6597   hash_free (vam->sw_if_index_by_interface_name);
6598
6599   vec_foreach (ns, nses) vec_free (ns->name);
6600
6601   vec_free (nses);
6602
6603   vec_foreach (sub, vam->sw_if_subif_table)
6604   {
6605     vec_free (sub->interface_name);
6606   }
6607   vec_free (vam->sw_if_subif_table);
6608
6609   /* recreate the interface name hash table */
6610   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6611
6612   /*
6613    * Ask for all interface names. Otherwise, the epic catalog of
6614    * name filters becomes ridiculously long, and vat ends up needing
6615    * to be taught about new interface types.
6616    */
6617   M (SW_INTERFACE_DUMP, mp);
6618   S (mp);
6619
6620   /* Use a control ping for synchronization */
6621   MPING (CONTROL_PING, mp_ping);
6622   S (mp_ping);
6623
6624   W (ret);
6625   return ret;
6626 }
6627
6628 static int
6629 api_sw_interface_set_flags (vat_main_t * vam)
6630 {
6631   unformat_input_t *i = vam->input;
6632   vl_api_sw_interface_set_flags_t *mp;
6633   u32 sw_if_index;
6634   u8 sw_if_index_set = 0;
6635   u8 admin_up = 0;
6636   int ret;
6637
6638   /* Parse args required to build the message */
6639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640     {
6641       if (unformat (i, "admin-up"))
6642         admin_up = 1;
6643       else if (unformat (i, "admin-down"))
6644         admin_up = 0;
6645       else
6646         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6647         sw_if_index_set = 1;
6648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6649         sw_if_index_set = 1;
6650       else
6651         break;
6652     }
6653
6654   if (sw_if_index_set == 0)
6655     {
6656       errmsg ("missing interface name or sw_if_index");
6657       return -99;
6658     }
6659
6660   /* Construct the API message */
6661   M (SW_INTERFACE_SET_FLAGS, mp);
6662   mp->sw_if_index = ntohl (sw_if_index);
6663   mp->admin_up_down = admin_up;
6664
6665   /* send it... */
6666   S (mp);
6667
6668   /* Wait for a reply, return the good/bad news... */
6669   W (ret);
6670   return ret;
6671 }
6672
6673 static int
6674 api_sw_interface_set_rx_mode (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_sw_interface_set_rx_mode_t *mp;
6678   u32 sw_if_index;
6679   u8 sw_if_index_set = 0;
6680   int ret;
6681   u8 queue_id_valid = 0;
6682   u32 queue_id;
6683   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6684
6685   /* Parse args required to build the message */
6686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6687     {
6688       if (unformat (i, "queue %d", &queue_id))
6689         queue_id_valid = 1;
6690       else if (unformat (i, "polling"))
6691         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6692       else if (unformat (i, "interrupt"))
6693         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6694       else if (unformat (i, "adaptive"))
6695         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6696       else
6697         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6698         sw_if_index_set = 1;
6699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6700         sw_if_index_set = 1;
6701       else
6702         break;
6703     }
6704
6705   if (sw_if_index_set == 0)
6706     {
6707       errmsg ("missing interface name or sw_if_index");
6708       return -99;
6709     }
6710   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6711     {
6712       errmsg ("missing rx-mode");
6713       return -99;
6714     }
6715
6716   /* Construct the API message */
6717   M (SW_INTERFACE_SET_RX_MODE, mp);
6718   mp->sw_if_index = ntohl (sw_if_index);
6719   mp->mode = mode;
6720   mp->queue_id_valid = queue_id_valid;
6721   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6722
6723   /* send it... */
6724   S (mp);
6725
6726   /* Wait for a reply, return the good/bad news... */
6727   W (ret);
6728   return ret;
6729 }
6730
6731 static int
6732 api_sw_interface_clear_stats (vat_main_t * vam)
6733 {
6734   unformat_input_t *i = vam->input;
6735   vl_api_sw_interface_clear_stats_t *mp;
6736   u32 sw_if_index;
6737   u8 sw_if_index_set = 0;
6738   int ret;
6739
6740   /* Parse args required to build the message */
6741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6742     {
6743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6744         sw_if_index_set = 1;
6745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6746         sw_if_index_set = 1;
6747       else
6748         break;
6749     }
6750
6751   /* Construct the API message */
6752   M (SW_INTERFACE_CLEAR_STATS, mp);
6753
6754   if (sw_if_index_set == 1)
6755     mp->sw_if_index = ntohl (sw_if_index);
6756   else
6757     mp->sw_if_index = ~0;
6758
6759   /* send it... */
6760   S (mp);
6761
6762   /* Wait for a reply, return the good/bad news... */
6763   W (ret);
6764   return ret;
6765 }
6766
6767 static int
6768 api_sw_interface_add_del_address (vat_main_t * vam)
6769 {
6770   unformat_input_t *i = vam->input;
6771   vl_api_sw_interface_add_del_address_t *mp;
6772   u32 sw_if_index;
6773   u8 sw_if_index_set = 0;
6774   u8 is_add = 1, del_all = 0;
6775   u32 address_length = 0;
6776   u8 v4_address_set = 0;
6777   u8 v6_address_set = 0;
6778   ip4_address_t v4address;
6779   ip6_address_t v6address;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "del-all"))
6786         del_all = 1;
6787       else if (unformat (i, "del"))
6788         is_add = 0;
6789       else
6790         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6791         sw_if_index_set = 1;
6792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6793         sw_if_index_set = 1;
6794       else if (unformat (i, "%U/%d",
6795                          unformat_ip4_address, &v4address, &address_length))
6796         v4_address_set = 1;
6797       else if (unformat (i, "%U/%d",
6798                          unformat_ip6_address, &v6address, &address_length))
6799         v6_address_set = 1;
6800       else
6801         break;
6802     }
6803
6804   if (sw_if_index_set == 0)
6805     {
6806       errmsg ("missing interface name or sw_if_index");
6807       return -99;
6808     }
6809   if (v4_address_set && v6_address_set)
6810     {
6811       errmsg ("both v4 and v6 addresses set");
6812       return -99;
6813     }
6814   if (!v4_address_set && !v6_address_set && !del_all)
6815     {
6816       errmsg ("no addresses set");
6817       return -99;
6818     }
6819
6820   /* Construct the API message */
6821   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6822
6823   mp->sw_if_index = ntohl (sw_if_index);
6824   mp->is_add = is_add;
6825   mp->del_all = del_all;
6826   if (v6_address_set)
6827     {
6828       mp->is_ipv6 = 1;
6829       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6830     }
6831   else
6832     {
6833       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6834     }
6835   mp->address_length = address_length;
6836
6837   /* send it... */
6838   S (mp);
6839
6840   /* Wait for a reply, return good/bad news  */
6841   W (ret);
6842   return ret;
6843 }
6844
6845 static int
6846 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6847 {
6848   unformat_input_t *i = vam->input;
6849   vl_api_sw_interface_set_mpls_enable_t *mp;
6850   u32 sw_if_index;
6851   u8 sw_if_index_set = 0;
6852   u8 enable = 1;
6853   int ret;
6854
6855   /* Parse args required to build the message */
6856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6857     {
6858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6859         sw_if_index_set = 1;
6860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6861         sw_if_index_set = 1;
6862       else if (unformat (i, "disable"))
6863         enable = 0;
6864       else if (unformat (i, "dis"))
6865         enable = 0;
6866       else
6867         break;
6868     }
6869
6870   if (sw_if_index_set == 0)
6871     {
6872       errmsg ("missing interface name or sw_if_index");
6873       return -99;
6874     }
6875
6876   /* Construct the API message */
6877   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6878
6879   mp->sw_if_index = ntohl (sw_if_index);
6880   mp->enable = enable;
6881
6882   /* send it... */
6883   S (mp);
6884
6885   /* Wait for a reply... */
6886   W (ret);
6887   return ret;
6888 }
6889
6890 static int
6891 api_sw_interface_set_table (vat_main_t * vam)
6892 {
6893   unformat_input_t *i = vam->input;
6894   vl_api_sw_interface_set_table_t *mp;
6895   u32 sw_if_index, vrf_id = 0;
6896   u8 sw_if_index_set = 0;
6897   u8 is_ipv6 = 0;
6898   int ret;
6899
6900   /* Parse args required to build the message */
6901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6902     {
6903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6904         sw_if_index_set = 1;
6905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6906         sw_if_index_set = 1;
6907       else if (unformat (i, "vrf %d", &vrf_id))
6908         ;
6909       else if (unformat (i, "ipv6"))
6910         is_ipv6 = 1;
6911       else
6912         break;
6913     }
6914
6915   if (sw_if_index_set == 0)
6916     {
6917       errmsg ("missing interface name or sw_if_index");
6918       return -99;
6919     }
6920
6921   /* Construct the API message */
6922   M (SW_INTERFACE_SET_TABLE, mp);
6923
6924   mp->sw_if_index = ntohl (sw_if_index);
6925   mp->is_ipv6 = is_ipv6;
6926   mp->vrf_id = ntohl (vrf_id);
6927
6928   /* send it... */
6929   S (mp);
6930
6931   /* Wait for a reply... */
6932   W (ret);
6933   return ret;
6934 }
6935
6936 static void vl_api_sw_interface_get_table_reply_t_handler
6937   (vl_api_sw_interface_get_table_reply_t * mp)
6938 {
6939   vat_main_t *vam = &vat_main;
6940
6941   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6942
6943   vam->retval = ntohl (mp->retval);
6944   vam->result_ready = 1;
6945
6946 }
6947
6948 static void vl_api_sw_interface_get_table_reply_t_handler_json
6949   (vl_api_sw_interface_get_table_reply_t * mp)
6950 {
6951   vat_main_t *vam = &vat_main;
6952   vat_json_node_t node;
6953
6954   vat_json_init_object (&node);
6955   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6956   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6957
6958   vat_json_print (vam->ofp, &node);
6959   vat_json_free (&node);
6960
6961   vam->retval = ntohl (mp->retval);
6962   vam->result_ready = 1;
6963 }
6964
6965 static int
6966 api_sw_interface_get_table (vat_main_t * vam)
6967 {
6968   unformat_input_t *i = vam->input;
6969   vl_api_sw_interface_get_table_t *mp;
6970   u32 sw_if_index;
6971   u8 sw_if_index_set = 0;
6972   u8 is_ipv6 = 0;
6973   int ret;
6974
6975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6976     {
6977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6978         sw_if_index_set = 1;
6979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6980         sw_if_index_set = 1;
6981       else if (unformat (i, "ipv6"))
6982         is_ipv6 = 1;
6983       else
6984         break;
6985     }
6986
6987   if (sw_if_index_set == 0)
6988     {
6989       errmsg ("missing interface name or sw_if_index");
6990       return -99;
6991     }
6992
6993   M (SW_INTERFACE_GET_TABLE, mp);
6994   mp->sw_if_index = htonl (sw_if_index);
6995   mp->is_ipv6 = is_ipv6;
6996
6997   S (mp);
6998   W (ret);
6999   return ret;
7000 }
7001
7002 static int
7003 api_sw_interface_set_vpath (vat_main_t * vam)
7004 {
7005   unformat_input_t *i = vam->input;
7006   vl_api_sw_interface_set_vpath_t *mp;
7007   u32 sw_if_index = 0;
7008   u8 sw_if_index_set = 0;
7009   u8 is_enable = 0;
7010   int ret;
7011
7012   /* Parse args required to build the message */
7013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014     {
7015       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7016         sw_if_index_set = 1;
7017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7018         sw_if_index_set = 1;
7019       else if (unformat (i, "enable"))
7020         is_enable = 1;
7021       else if (unformat (i, "disable"))
7022         is_enable = 0;
7023       else
7024         break;
7025     }
7026
7027   if (sw_if_index_set == 0)
7028     {
7029       errmsg ("missing interface name or sw_if_index");
7030       return -99;
7031     }
7032
7033   /* Construct the API message */
7034   M (SW_INTERFACE_SET_VPATH, mp);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->enable = is_enable;
7038
7039   /* send it... */
7040   S (mp);
7041
7042   /* Wait for a reply... */
7043   W (ret);
7044   return ret;
7045 }
7046
7047 static int
7048 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7052   u32 sw_if_index = 0;
7053   u8 sw_if_index_set = 0;
7054   u8 is_enable = 1;
7055   u8 is_ipv6 = 0;
7056   int ret;
7057
7058   /* Parse args required to build the message */
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7062         sw_if_index_set = 1;
7063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "enable"))
7066         is_enable = 1;
7067       else if (unformat (i, "disable"))
7068         is_enable = 0;
7069       else if (unformat (i, "ip4"))
7070         is_ipv6 = 0;
7071       else if (unformat (i, "ip6"))
7072         is_ipv6 = 1;
7073       else
7074         break;
7075     }
7076
7077   if (sw_if_index_set == 0)
7078     {
7079       errmsg ("missing interface name or sw_if_index");
7080       return -99;
7081     }
7082
7083   /* Construct the API message */
7084   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7085
7086   mp->sw_if_index = ntohl (sw_if_index);
7087   mp->enable = is_enable;
7088   mp->is_ipv6 = is_ipv6;
7089
7090   /* send it... */
7091   S (mp);
7092
7093   /* Wait for a reply... */
7094   W (ret);
7095   return ret;
7096 }
7097
7098 static int
7099 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7100 {
7101   unformat_input_t *i = vam->input;
7102   vl_api_sw_interface_set_geneve_bypass_t *mp;
7103   u32 sw_if_index = 0;
7104   u8 sw_if_index_set = 0;
7105   u8 is_enable = 1;
7106   u8 is_ipv6 = 0;
7107   int ret;
7108
7109   /* Parse args required to build the message */
7110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7111     {
7112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7113         sw_if_index_set = 1;
7114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7115         sw_if_index_set = 1;
7116       else if (unformat (i, "enable"))
7117         is_enable = 1;
7118       else if (unformat (i, "disable"))
7119         is_enable = 0;
7120       else if (unformat (i, "ip4"))
7121         is_ipv6 = 0;
7122       else if (unformat (i, "ip6"))
7123         is_ipv6 = 1;
7124       else
7125         break;
7126     }
7127
7128   if (sw_if_index_set == 0)
7129     {
7130       errmsg ("missing interface name or sw_if_index");
7131       return -99;
7132     }
7133
7134   /* Construct the API message */
7135   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7136
7137   mp->sw_if_index = ntohl (sw_if_index);
7138   mp->enable = is_enable;
7139   mp->is_ipv6 = is_ipv6;
7140
7141   /* send it... */
7142   S (mp);
7143
7144   /* Wait for a reply... */
7145   W (ret);
7146   return ret;
7147 }
7148
7149 static int
7150 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7151 {
7152   unformat_input_t *i = vam->input;
7153   vl_api_sw_interface_set_l2_xconnect_t *mp;
7154   u32 rx_sw_if_index;
7155   u8 rx_sw_if_index_set = 0;
7156   u32 tx_sw_if_index;
7157   u8 tx_sw_if_index_set = 0;
7158   u8 enable = 1;
7159   int ret;
7160
7161   /* Parse args required to build the message */
7162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7163     {
7164       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7165         rx_sw_if_index_set = 1;
7166       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7167         tx_sw_if_index_set = 1;
7168       else if (unformat (i, "rx"))
7169         {
7170           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171             {
7172               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7173                             &rx_sw_if_index))
7174                 rx_sw_if_index_set = 1;
7175             }
7176           else
7177             break;
7178         }
7179       else if (unformat (i, "tx"))
7180         {
7181           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7182             {
7183               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7184                             &tx_sw_if_index))
7185                 tx_sw_if_index_set = 1;
7186             }
7187           else
7188             break;
7189         }
7190       else if (unformat (i, "enable"))
7191         enable = 1;
7192       else if (unformat (i, "disable"))
7193         enable = 0;
7194       else
7195         break;
7196     }
7197
7198   if (rx_sw_if_index_set == 0)
7199     {
7200       errmsg ("missing rx interface name or rx_sw_if_index");
7201       return -99;
7202     }
7203
7204   if (enable && (tx_sw_if_index_set == 0))
7205     {
7206       errmsg ("missing tx interface name or tx_sw_if_index");
7207       return -99;
7208     }
7209
7210   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7211
7212   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7213   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7214   mp->enable = enable;
7215
7216   S (mp);
7217   W (ret);
7218   return ret;
7219 }
7220
7221 static int
7222 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_sw_interface_set_l2_bridge_t *mp;
7226   u32 rx_sw_if_index;
7227   u8 rx_sw_if_index_set = 0;
7228   u32 bd_id;
7229   u8 bd_id_set = 0;
7230   u8 bvi = 0;
7231   u32 shg = 0;
7232   u8 enable = 1;
7233   int ret;
7234
7235   /* Parse args required to build the message */
7236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237     {
7238       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7239         rx_sw_if_index_set = 1;
7240       else if (unformat (i, "bd_id %d", &bd_id))
7241         bd_id_set = 1;
7242       else
7243         if (unformat
7244             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7245         rx_sw_if_index_set = 1;
7246       else if (unformat (i, "shg %d", &shg))
7247         ;
7248       else if (unformat (i, "bvi"))
7249         bvi = 1;
7250       else if (unformat (i, "enable"))
7251         enable = 1;
7252       else if (unformat (i, "disable"))
7253         enable = 0;
7254       else
7255         break;
7256     }
7257
7258   if (rx_sw_if_index_set == 0)
7259     {
7260       errmsg ("missing rx interface name or sw_if_index");
7261       return -99;
7262     }
7263
7264   if (enable && (bd_id_set == 0))
7265     {
7266       errmsg ("missing bridge domain");
7267       return -99;
7268     }
7269
7270   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7271
7272   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7273   mp->bd_id = ntohl (bd_id);
7274   mp->shg = (u8) shg;
7275   mp->bvi = bvi;
7276   mp->enable = enable;
7277
7278   S (mp);
7279   W (ret);
7280   return ret;
7281 }
7282
7283 static int
7284 api_bridge_domain_dump (vat_main_t * vam)
7285 {
7286   unformat_input_t *i = vam->input;
7287   vl_api_bridge_domain_dump_t *mp;
7288   vl_api_control_ping_t *mp_ping;
7289   u32 bd_id = ~0;
7290   int ret;
7291
7292   /* Parse args required to build the message */
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "bd_id %d", &bd_id))
7296         ;
7297       else
7298         break;
7299     }
7300
7301   M (BRIDGE_DOMAIN_DUMP, mp);
7302   mp->bd_id = ntohl (bd_id);
7303   S (mp);
7304
7305   /* Use a control ping for synchronization */
7306   MPING (CONTROL_PING, mp_ping);
7307   S (mp_ping);
7308
7309   W (ret);
7310   return ret;
7311 }
7312
7313 static int
7314 api_bridge_domain_add_del (vat_main_t * vam)
7315 {
7316   unformat_input_t *i = vam->input;
7317   vl_api_bridge_domain_add_del_t *mp;
7318   u32 bd_id = ~0;
7319   u8 is_add = 1;
7320   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7321   u8 *bd_tag = NULL;
7322   u32 mac_age = 0;
7323   int ret;
7324
7325   /* Parse args required to build the message */
7326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7327     {
7328       if (unformat (i, "bd_id %d", &bd_id))
7329         ;
7330       else if (unformat (i, "flood %d", &flood))
7331         ;
7332       else if (unformat (i, "uu-flood %d", &uu_flood))
7333         ;
7334       else if (unformat (i, "forward %d", &forward))
7335         ;
7336       else if (unformat (i, "learn %d", &learn))
7337         ;
7338       else if (unformat (i, "arp-term %d", &arp_term))
7339         ;
7340       else if (unformat (i, "mac-age %d", &mac_age))
7341         ;
7342       else if (unformat (i, "bd-tag %s", &bd_tag))
7343         ;
7344       else if (unformat (i, "del"))
7345         {
7346           is_add = 0;
7347           flood = uu_flood = forward = learn = 0;
7348         }
7349       else
7350         break;
7351     }
7352
7353   if (bd_id == ~0)
7354     {
7355       errmsg ("missing bridge domain");
7356       ret = -99;
7357       goto done;
7358     }
7359
7360   if (mac_age > 255)
7361     {
7362       errmsg ("mac age must be less than 256 ");
7363       ret = -99;
7364       goto done;
7365     }
7366
7367   if ((bd_tag) && (vec_len (bd_tag) > 63))
7368     {
7369       errmsg ("bd-tag cannot be longer than 63");
7370       ret = -99;
7371       goto done;
7372     }
7373
7374   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7375
7376   mp->bd_id = ntohl (bd_id);
7377   mp->flood = flood;
7378   mp->uu_flood = uu_flood;
7379   mp->forward = forward;
7380   mp->learn = learn;
7381   mp->arp_term = arp_term;
7382   mp->is_add = is_add;
7383   mp->mac_age = (u8) mac_age;
7384   if (bd_tag)
7385     {
7386       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7387       mp->bd_tag[vec_len (bd_tag)] = 0;
7388     }
7389   S (mp);
7390   W (ret);
7391
7392 done:
7393   vec_free (bd_tag);
7394   return ret;
7395 }
7396
7397 static int
7398 api_l2fib_flush_bd (vat_main_t * vam)
7399 {
7400   unformat_input_t *i = vam->input;
7401   vl_api_l2fib_flush_bd_t *mp;
7402   u32 bd_id = ~0;
7403   int ret;
7404
7405   /* Parse args required to build the message */
7406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7407     {
7408       if (unformat (i, "bd_id %d", &bd_id));
7409       else
7410         break;
7411     }
7412
7413   if (bd_id == ~0)
7414     {
7415       errmsg ("missing bridge domain");
7416       return -99;
7417     }
7418
7419   M (L2FIB_FLUSH_BD, mp);
7420
7421   mp->bd_id = htonl (bd_id);
7422
7423   S (mp);
7424   W (ret);
7425   return ret;
7426 }
7427
7428 static int
7429 api_l2fib_flush_int (vat_main_t * vam)
7430 {
7431   unformat_input_t *i = vam->input;
7432   vl_api_l2fib_flush_int_t *mp;
7433   u32 sw_if_index = ~0;
7434   int ret;
7435
7436   /* Parse args required to build the message */
7437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438     {
7439       if (unformat (i, "sw_if_index %d", &sw_if_index));
7440       else
7441         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7442       else
7443         break;
7444     }
7445
7446   if (sw_if_index == ~0)
7447     {
7448       errmsg ("missing interface name or sw_if_index");
7449       return -99;
7450     }
7451
7452   M (L2FIB_FLUSH_INT, mp);
7453
7454   mp->sw_if_index = ntohl (sw_if_index);
7455
7456   S (mp);
7457   W (ret);
7458   return ret;
7459 }
7460
7461 static int
7462 api_l2fib_add_del (vat_main_t * vam)
7463 {
7464   unformat_input_t *i = vam->input;
7465   vl_api_l2fib_add_del_t *mp;
7466   f64 timeout;
7467   u8 mac[6] = { 0 };
7468   u8 mac_set = 0;
7469   u32 bd_id;
7470   u8 bd_id_set = 0;
7471   u32 sw_if_index = ~0;
7472   u8 sw_if_index_set = 0;
7473   u8 is_add = 1;
7474   u8 static_mac = 0;
7475   u8 filter_mac = 0;
7476   u8 bvi_mac = 0;
7477   int count = 1;
7478   f64 before = 0;
7479   int j;
7480
7481   /* Parse args required to build the message */
7482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7483     {
7484       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7485         mac_set = 1;
7486       else if (unformat (i, "bd_id %d", &bd_id))
7487         bd_id_set = 1;
7488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7489         sw_if_index_set = 1;
7490       else if (unformat (i, "sw_if"))
7491         {
7492           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7493             {
7494               if (unformat
7495                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7496                 sw_if_index_set = 1;
7497             }
7498           else
7499             break;
7500         }
7501       else if (unformat (i, "static"))
7502         static_mac = 1;
7503       else if (unformat (i, "filter"))
7504         {
7505           filter_mac = 1;
7506           static_mac = 1;
7507         }
7508       else if (unformat (i, "bvi"))
7509         {
7510           bvi_mac = 1;
7511           static_mac = 1;
7512         }
7513       else if (unformat (i, "del"))
7514         is_add = 0;
7515       else if (unformat (i, "count %d", &count))
7516         ;
7517       else
7518         break;
7519     }
7520
7521   if (mac_set == 0)
7522     {
7523       errmsg ("missing mac address");
7524       return -99;
7525     }
7526
7527   if (bd_id_set == 0)
7528     {
7529       errmsg ("missing bridge domain");
7530       return -99;
7531     }
7532
7533   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7534     {
7535       errmsg ("missing interface name or sw_if_index");
7536       return -99;
7537     }
7538
7539   if (count > 1)
7540     {
7541       /* Turn on async mode */
7542       vam->async_mode = 1;
7543       vam->async_errors = 0;
7544       before = vat_time_now (vam);
7545     }
7546
7547   for (j = 0; j < count; j++)
7548     {
7549       M (L2FIB_ADD_DEL, mp);
7550
7551       clib_memcpy (mp->mac, mac, 6);
7552       mp->bd_id = ntohl (bd_id);
7553       mp->is_add = is_add;
7554
7555       if (is_add)
7556         {
7557           mp->sw_if_index = ntohl (sw_if_index);
7558           mp->static_mac = static_mac;
7559           mp->filter_mac = filter_mac;
7560           mp->bvi_mac = bvi_mac;
7561         }
7562       increment_mac_address (mac);
7563       /* send it... */
7564       S (mp);
7565     }
7566
7567   if (count > 1)
7568     {
7569       vl_api_control_ping_t *mp_ping;
7570       f64 after;
7571
7572       /* Shut off async mode */
7573       vam->async_mode = 0;
7574
7575       MPING (CONTROL_PING, mp_ping);
7576       S (mp_ping);
7577
7578       timeout = vat_time_now (vam) + 1.0;
7579       while (vat_time_now (vam) < timeout)
7580         if (vam->result_ready == 1)
7581           goto out;
7582       vam->retval = -99;
7583
7584     out:
7585       if (vam->retval == -99)
7586         errmsg ("timeout");
7587
7588       if (vam->async_errors > 0)
7589         {
7590           errmsg ("%d asynchronous errors", vam->async_errors);
7591           vam->retval = -98;
7592         }
7593       vam->async_errors = 0;
7594       after = vat_time_now (vam);
7595
7596       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7597              count, after - before, count / (after - before));
7598     }
7599   else
7600     {
7601       int ret;
7602
7603       /* Wait for a reply... */
7604       W (ret);
7605       return ret;
7606     }
7607   /* Return the good/bad news */
7608   return (vam->retval);
7609 }
7610
7611 static int
7612 api_bridge_domain_set_mac_age (vat_main_t * vam)
7613 {
7614   unformat_input_t *i = vam->input;
7615   vl_api_bridge_domain_set_mac_age_t *mp;
7616   u32 bd_id = ~0;
7617   u32 mac_age = 0;
7618   int ret;
7619
7620   /* Parse args required to build the message */
7621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7622     {
7623       if (unformat (i, "bd_id %d", &bd_id));
7624       else if (unformat (i, "mac-age %d", &mac_age));
7625       else
7626         break;
7627     }
7628
7629   if (bd_id == ~0)
7630     {
7631       errmsg ("missing bridge domain");
7632       return -99;
7633     }
7634
7635   if (mac_age > 255)
7636     {
7637       errmsg ("mac age must be less than 256 ");
7638       return -99;
7639     }
7640
7641   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7642
7643   mp->bd_id = htonl (bd_id);
7644   mp->mac_age = (u8) mac_age;
7645
7646   S (mp);
7647   W (ret);
7648   return ret;
7649 }
7650
7651 static int
7652 api_l2_flags (vat_main_t * vam)
7653 {
7654   unformat_input_t *i = vam->input;
7655   vl_api_l2_flags_t *mp;
7656   u32 sw_if_index;
7657   u32 flags = 0;
7658   u8 sw_if_index_set = 0;
7659   u8 is_set = 0;
7660   int ret;
7661
7662   /* Parse args required to build the message */
7663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7664     {
7665       if (unformat (i, "sw_if_index %d", &sw_if_index))
7666         sw_if_index_set = 1;
7667       else if (unformat (i, "sw_if"))
7668         {
7669           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7670             {
7671               if (unformat
7672                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7673                 sw_if_index_set = 1;
7674             }
7675           else
7676             break;
7677         }
7678       else if (unformat (i, "learn"))
7679         flags |= L2_LEARN;
7680       else if (unformat (i, "forward"))
7681         flags |= L2_FWD;
7682       else if (unformat (i, "flood"))
7683         flags |= L2_FLOOD;
7684       else if (unformat (i, "uu-flood"))
7685         flags |= L2_UU_FLOOD;
7686       else if (unformat (i, "arp-term"))
7687         flags |= L2_ARP_TERM;
7688       else if (unformat (i, "off"))
7689         is_set = 0;
7690       else if (unformat (i, "disable"))
7691         is_set = 0;
7692       else
7693         break;
7694     }
7695
7696   if (sw_if_index_set == 0)
7697     {
7698       errmsg ("missing interface name or sw_if_index");
7699       return -99;
7700     }
7701
7702   M (L2_FLAGS, mp);
7703
7704   mp->sw_if_index = ntohl (sw_if_index);
7705   mp->feature_bitmap = ntohl (flags);
7706   mp->is_set = is_set;
7707
7708   S (mp);
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_bridge_flags (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_bridge_flags_t *mp;
7718   u32 bd_id;
7719   u8 bd_id_set = 0;
7720   u8 is_set = 1;
7721   u32 flags = 0;
7722   int ret;
7723
7724   /* Parse args required to build the message */
7725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7726     {
7727       if (unformat (i, "bd_id %d", &bd_id))
7728         bd_id_set = 1;
7729       else if (unformat (i, "learn"))
7730         flags |= L2_LEARN;
7731       else if (unformat (i, "forward"))
7732         flags |= L2_FWD;
7733       else if (unformat (i, "flood"))
7734         flags |= L2_FLOOD;
7735       else if (unformat (i, "uu-flood"))
7736         flags |= L2_UU_FLOOD;
7737       else if (unformat (i, "arp-term"))
7738         flags |= L2_ARP_TERM;
7739       else if (unformat (i, "off"))
7740         is_set = 0;
7741       else if (unformat (i, "disable"))
7742         is_set = 0;
7743       else
7744         break;
7745     }
7746
7747   if (bd_id_set == 0)
7748     {
7749       errmsg ("missing bridge domain");
7750       return -99;
7751     }
7752
7753   M (BRIDGE_FLAGS, mp);
7754
7755   mp->bd_id = ntohl (bd_id);
7756   mp->feature_bitmap = ntohl (flags);
7757   mp->is_set = is_set;
7758
7759   S (mp);
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_bd_ip_mac_add_del (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_bd_ip_mac_add_del_t *mp;
7769   u32 bd_id;
7770   u8 is_ipv6 = 0;
7771   u8 is_add = 1;
7772   u8 bd_id_set = 0;
7773   u8 ip_set = 0;
7774   u8 mac_set = 0;
7775   ip4_address_t v4addr;
7776   ip6_address_t v6addr;
7777   u8 macaddr[6];
7778   int ret;
7779
7780
7781   /* Parse args required to build the message */
7782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7783     {
7784       if (unformat (i, "bd_id %d", &bd_id))
7785         {
7786           bd_id_set++;
7787         }
7788       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7789         {
7790           ip_set++;
7791         }
7792       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7793         {
7794           ip_set++;
7795           is_ipv6++;
7796         }
7797       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7798         {
7799           mac_set++;
7800         }
7801       else if (unformat (i, "del"))
7802         is_add = 0;
7803       else
7804         break;
7805     }
7806
7807   if (bd_id_set == 0)
7808     {
7809       errmsg ("missing bridge domain");
7810       return -99;
7811     }
7812   else if (ip_set == 0)
7813     {
7814       errmsg ("missing IP address");
7815       return -99;
7816     }
7817   else if (mac_set == 0)
7818     {
7819       errmsg ("missing MAC address");
7820       return -99;
7821     }
7822
7823   M (BD_IP_MAC_ADD_DEL, mp);
7824
7825   mp->bd_id = ntohl (bd_id);
7826   mp->is_ipv6 = is_ipv6;
7827   mp->is_add = is_add;
7828   if (is_ipv6)
7829     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7830   else
7831     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7832   clib_memcpy (mp->mac_address, macaddr, 6);
7833   S (mp);
7834   W (ret);
7835   return ret;
7836 }
7837
7838 static int
7839 api_tap_connect (vat_main_t * vam)
7840 {
7841   unformat_input_t *i = vam->input;
7842   vl_api_tap_connect_t *mp;
7843   u8 mac_address[6];
7844   u8 random_mac = 1;
7845   u8 name_set = 0;
7846   u8 *tap_name;
7847   u8 *tag = 0;
7848   ip4_address_t ip4_address;
7849   u32 ip4_mask_width;
7850   int ip4_address_set = 0;
7851   ip6_address_t ip6_address;
7852   u32 ip6_mask_width;
7853   int ip6_address_set = 0;
7854   int ret;
7855
7856   memset (mac_address, 0, sizeof (mac_address));
7857
7858   /* Parse args required to build the message */
7859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7860     {
7861       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7862         {
7863           random_mac = 0;
7864         }
7865       else if (unformat (i, "random-mac"))
7866         random_mac = 1;
7867       else if (unformat (i, "tapname %s", &tap_name))
7868         name_set = 1;
7869       else if (unformat (i, "tag %s", &tag))
7870         ;
7871       else if (unformat (i, "address %U/%d",
7872                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7873         ip4_address_set = 1;
7874       else if (unformat (i, "address %U/%d",
7875                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7876         ip6_address_set = 1;
7877       else
7878         break;
7879     }
7880
7881   if (name_set == 0)
7882     {
7883       errmsg ("missing tap name");
7884       return -99;
7885     }
7886   if (vec_len (tap_name) > 63)
7887     {
7888       errmsg ("tap name too long");
7889       return -99;
7890     }
7891   vec_add1 (tap_name, 0);
7892
7893   if (vec_len (tag) > 63)
7894     {
7895       errmsg ("tag too long");
7896       return -99;
7897     }
7898
7899   /* Construct the API message */
7900   M (TAP_CONNECT, mp);
7901
7902   mp->use_random_mac = random_mac;
7903   clib_memcpy (mp->mac_address, mac_address, 6);
7904   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7905   if (tag)
7906     clib_memcpy (mp->tag, tag, vec_len (tag));
7907
7908   if (ip4_address_set)
7909     {
7910       mp->ip4_address_set = 1;
7911       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7912       mp->ip4_mask_width = ip4_mask_width;
7913     }
7914   if (ip6_address_set)
7915     {
7916       mp->ip6_address_set = 1;
7917       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7918       mp->ip6_mask_width = ip6_mask_width;
7919     }
7920
7921   vec_free (tap_name);
7922   vec_free (tag);
7923
7924   /* send it... */
7925   S (mp);
7926
7927   /* Wait for a reply... */
7928   W (ret);
7929   return ret;
7930 }
7931
7932 static int
7933 api_tap_modify (vat_main_t * vam)
7934 {
7935   unformat_input_t *i = vam->input;
7936   vl_api_tap_modify_t *mp;
7937   u8 mac_address[6];
7938   u8 random_mac = 1;
7939   u8 name_set = 0;
7940   u8 *tap_name;
7941   u32 sw_if_index = ~0;
7942   u8 sw_if_index_set = 0;
7943   int ret;
7944
7945   memset (mac_address, 0, sizeof (mac_address));
7946
7947   /* Parse args required to build the message */
7948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7949     {
7950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7951         sw_if_index_set = 1;
7952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7953         sw_if_index_set = 1;
7954       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7955         {
7956           random_mac = 0;
7957         }
7958       else if (unformat (i, "random-mac"))
7959         random_mac = 1;
7960       else if (unformat (i, "tapname %s", &tap_name))
7961         name_set = 1;
7962       else
7963         break;
7964     }
7965
7966   if (sw_if_index_set == 0)
7967     {
7968       errmsg ("missing vpp interface name");
7969       return -99;
7970     }
7971   if (name_set == 0)
7972     {
7973       errmsg ("missing tap name");
7974       return -99;
7975     }
7976   if (vec_len (tap_name) > 63)
7977     {
7978       errmsg ("tap name too long");
7979     }
7980   vec_add1 (tap_name, 0);
7981
7982   /* Construct the API message */
7983   M (TAP_MODIFY, mp);
7984
7985   mp->use_random_mac = random_mac;
7986   mp->sw_if_index = ntohl (sw_if_index);
7987   clib_memcpy (mp->mac_address, mac_address, 6);
7988   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7989   vec_free (tap_name);
7990
7991   /* send it... */
7992   S (mp);
7993
7994   /* Wait for a reply... */
7995   W (ret);
7996   return ret;
7997 }
7998
7999 static int
8000 api_tap_delete (vat_main_t * vam)
8001 {
8002   unformat_input_t *i = vam->input;
8003   vl_api_tap_delete_t *mp;
8004   u32 sw_if_index = ~0;
8005   u8 sw_if_index_set = 0;
8006   int ret;
8007
8008   /* Parse args required to build the message */
8009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8010     {
8011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8012         sw_if_index_set = 1;
8013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8014         sw_if_index_set = 1;
8015       else
8016         break;
8017     }
8018
8019   if (sw_if_index_set == 0)
8020     {
8021       errmsg ("missing vpp interface name");
8022       return -99;
8023     }
8024
8025   /* Construct the API message */
8026   M (TAP_DELETE, mp);
8027
8028   mp->sw_if_index = ntohl (sw_if_index);
8029
8030   /* send it... */
8031   S (mp);
8032
8033   /* Wait for a reply... */
8034   W (ret);
8035   return ret;
8036 }
8037
8038 static int
8039 api_tap_create_v2 (vat_main_t * vam)
8040 {
8041   unformat_input_t *i = vam->input;
8042   vl_api_tap_create_v2_t *mp;
8043   u8 mac_address[6];
8044   u8 random_mac = 1;
8045   u32 id = ~0;
8046   u8 *host_if_name = 0;
8047   u8 *host_ns = 0;
8048   u8 host_mac_addr[6];
8049   u8 host_mac_addr_set = 0;
8050   u8 *host_bridge = 0;
8051   ip4_address_t host_ip4_addr;
8052   ip4_address_t host_ip4_gw;
8053   u8 host_ip4_gw_set = 0;
8054   u32 host_ip4_prefix_len = 0;
8055   ip6_address_t host_ip6_addr;
8056   ip6_address_t host_ip6_gw;
8057   u8 host_ip6_gw_set = 0;
8058   u32 host_ip6_prefix_len = 0;
8059   int ret;
8060   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8061
8062   memset (mac_address, 0, sizeof (mac_address));
8063
8064   /* Parse args required to build the message */
8065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8068         {
8069           random_mac = 0;
8070         }
8071       else if (unformat (i, "id %u", &id))
8072         ;
8073       else if (unformat (i, "host-if-name %s", &host_if_name))
8074         ;
8075       else if (unformat (i, "host-ns %s", &host_ns))
8076         ;
8077       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8078                          host_mac_addr))
8079         host_mac_addr_set = 1;
8080       else if (unformat (i, "host-bridge %s", &host_bridge))
8081         ;
8082       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8083                          &host_ip4_addr, &host_ip4_prefix_len))
8084         ;
8085       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8086                          &host_ip6_addr, &host_ip6_prefix_len))
8087         ;
8088       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8089                          &host_ip4_gw))
8090         host_ip4_gw_set = 1;
8091       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8092                          &host_ip6_gw))
8093         host_ip6_gw_set = 1;
8094       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8095         ;
8096       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8097         ;
8098       else
8099         break;
8100     }
8101
8102   if (vec_len (host_if_name) > 63)
8103     {
8104       errmsg ("tap name too long. ");
8105       return -99;
8106     }
8107   if (vec_len (host_ns) > 63)
8108     {
8109       errmsg ("host name space too long. ");
8110       return -99;
8111     }
8112   if (vec_len (host_bridge) > 63)
8113     {
8114       errmsg ("host bridge name too long. ");
8115       return -99;
8116     }
8117   if (host_ip4_prefix_len > 32)
8118     {
8119       errmsg ("host ip4 prefix length not valid. ");
8120       return -99;
8121     }
8122   if (host_ip6_prefix_len > 128)
8123     {
8124       errmsg ("host ip6 prefix length not valid. ");
8125       return -99;
8126     }
8127   if (!is_pow2 (rx_ring_sz))
8128     {
8129       errmsg ("rx ring size must be power of 2. ");
8130       return -99;
8131     }
8132   if (rx_ring_sz > 32768)
8133     {
8134       errmsg ("rx ring size must be 32768 or lower. ");
8135       return -99;
8136     }
8137   if (!is_pow2 (tx_ring_sz))
8138     {
8139       errmsg ("tx ring size must be power of 2. ");
8140       return -99;
8141     }
8142   if (tx_ring_sz > 32768)
8143     {
8144       errmsg ("tx ring size must be 32768 or lower. ");
8145       return -99;
8146     }
8147
8148   /* Construct the API message */
8149   M (TAP_CREATE_V2, mp);
8150
8151   mp->use_random_mac = random_mac;
8152
8153   mp->id = ntohl (id);
8154   mp->host_namespace_set = host_ns != 0;
8155   mp->host_bridge_set = host_bridge != 0;
8156   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8157   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8158   mp->rx_ring_sz = ntohs (rx_ring_sz);
8159   mp->tx_ring_sz = ntohs (tx_ring_sz);
8160
8161   if (random_mac == 0)
8162     clib_memcpy (mp->mac_address, mac_address, 6);
8163   if (host_mac_addr_set)
8164     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8165   if (host_if_name)
8166     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8167   if (host_ns)
8168     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8169   if (host_bridge)
8170     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8171   if (host_ip4_prefix_len)
8172     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8173   if (host_ip4_prefix_len)
8174     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8175   if (host_ip4_gw_set)
8176     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8177   if (host_ip6_gw_set)
8178     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8179
8180   vec_free (host_ns);
8181   vec_free (host_if_name);
8182   vec_free (host_bridge);
8183
8184   /* send it... */
8185   S (mp);
8186
8187   /* Wait for a reply... */
8188   W (ret);
8189   return ret;
8190 }
8191
8192 static int
8193 api_tap_delete_v2 (vat_main_t * vam)
8194 {
8195   unformat_input_t *i = vam->input;
8196   vl_api_tap_delete_v2_t *mp;
8197   u32 sw_if_index = ~0;
8198   u8 sw_if_index_set = 0;
8199   int ret;
8200
8201   /* Parse args required to build the message */
8202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8203     {
8204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8205         sw_if_index_set = 1;
8206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8207         sw_if_index_set = 1;
8208       else
8209         break;
8210     }
8211
8212   if (sw_if_index_set == 0)
8213     {
8214       errmsg ("missing vpp interface name. ");
8215       return -99;
8216     }
8217
8218   /* Construct the API message */
8219   M (TAP_DELETE_V2, mp);
8220
8221   mp->sw_if_index = ntohl (sw_if_index);
8222
8223   /* send it... */
8224   S (mp);
8225
8226   /* Wait for a reply... */
8227   W (ret);
8228   return ret;
8229 }
8230
8231 static int
8232 api_bond_create (vat_main_t * vam)
8233 {
8234   unformat_input_t *i = vam->input;
8235   vl_api_bond_create_t *mp;
8236   u8 mac_address[6];
8237   u8 custom_mac = 0;
8238   int ret;
8239   u8 mode;
8240   u8 lb;
8241   u8 mode_is_set = 0;
8242
8243   memset (mac_address, 0, sizeof (mac_address));
8244   lb = BOND_LB_L2;
8245
8246   /* Parse args required to build the message */
8247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8250         mode_is_set = 1;
8251       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8252                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8253         ;
8254       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8255                          mac_address))
8256         custom_mac = 1;
8257       else
8258         break;
8259     }
8260
8261   if (mode_is_set == 0)
8262     {
8263       errmsg ("Missing bond mode. ");
8264       return -99;
8265     }
8266
8267   /* Construct the API message */
8268   M (BOND_CREATE, mp);
8269
8270   mp->use_custom_mac = custom_mac;
8271
8272   mp->mode = mode;
8273   mp->lb = lb;
8274
8275   if (custom_mac)
8276     clib_memcpy (mp->mac_address, mac_address, 6);
8277
8278   /* send it... */
8279   S (mp);
8280
8281   /* Wait for a reply... */
8282   W (ret);
8283   return ret;
8284 }
8285
8286 static int
8287 api_bond_delete (vat_main_t * vam)
8288 {
8289   unformat_input_t *i = vam->input;
8290   vl_api_bond_delete_t *mp;
8291   u32 sw_if_index = ~0;
8292   u8 sw_if_index_set = 0;
8293   int ret;
8294
8295   /* Parse args required to build the message */
8296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8299         sw_if_index_set = 1;
8300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8301         sw_if_index_set = 1;
8302       else
8303         break;
8304     }
8305
8306   if (sw_if_index_set == 0)
8307     {
8308       errmsg ("missing vpp interface name. ");
8309       return -99;
8310     }
8311
8312   /* Construct the API message */
8313   M (BOND_DELETE, mp);
8314
8315   mp->sw_if_index = ntohl (sw_if_index);
8316
8317   /* send it... */
8318   S (mp);
8319
8320   /* Wait for a reply... */
8321   W (ret);
8322   return ret;
8323 }
8324
8325 static int
8326 api_bond_enslave (vat_main_t * vam)
8327 {
8328   unformat_input_t *i = vam->input;
8329   vl_api_bond_enslave_t *mp;
8330   u32 bond_sw_if_index;
8331   int ret;
8332   u8 is_passive;
8333   u8 is_long_timeout;
8334   u32 bond_sw_if_index_is_set = 0;
8335   u32 sw_if_index;
8336   u8 sw_if_index_is_set = 0;
8337
8338   /* Parse args required to build the message */
8339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340     {
8341       if (unformat (i, "sw_if_index %d", &sw_if_index))
8342         sw_if_index_is_set = 1;
8343       else if (unformat (i, "bond %u", &bond_sw_if_index))
8344         bond_sw_if_index_is_set = 1;
8345       else if (unformat (i, "passive %d", &is_passive))
8346         ;
8347       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8348         ;
8349       else
8350         break;
8351     }
8352
8353   if (bond_sw_if_index_is_set == 0)
8354     {
8355       errmsg ("Missing bond sw_if_index. ");
8356       return -99;
8357     }
8358   if (sw_if_index_is_set == 0)
8359     {
8360       errmsg ("Missing slave sw_if_index. ");
8361       return -99;
8362     }
8363
8364   /* Construct the API message */
8365   M (BOND_ENSLAVE, mp);
8366
8367   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8368   mp->sw_if_index = ntohl (sw_if_index);
8369   mp->is_long_timeout = is_long_timeout;
8370   mp->is_passive = is_passive;
8371
8372   /* send it... */
8373   S (mp);
8374
8375   /* Wait for a reply... */
8376   W (ret);
8377   return ret;
8378 }
8379
8380 static int
8381 api_bond_detach_slave (vat_main_t * vam)
8382 {
8383   unformat_input_t *i = vam->input;
8384   vl_api_bond_detach_slave_t *mp;
8385   u32 sw_if_index = ~0;
8386   u8 sw_if_index_set = 0;
8387   int ret;
8388
8389   /* Parse args required to build the message */
8390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8391     {
8392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8393         sw_if_index_set = 1;
8394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8395         sw_if_index_set = 1;
8396       else
8397         break;
8398     }
8399
8400   if (sw_if_index_set == 0)
8401     {
8402       errmsg ("missing vpp interface name. ");
8403       return -99;
8404     }
8405
8406   /* Construct the API message */
8407   M (BOND_DETACH_SLAVE, mp);
8408
8409   mp->sw_if_index = ntohl (sw_if_index);
8410
8411   /* send it... */
8412   S (mp);
8413
8414   /* Wait for a reply... */
8415   W (ret);
8416   return ret;
8417 }
8418
8419 static int
8420 api_ip_table_add_del (vat_main_t * vam)
8421 {
8422   unformat_input_t *i = vam->input;
8423   vl_api_ip_table_add_del_t *mp;
8424   u32 table_id = ~0;
8425   u8 is_ipv6 = 0;
8426   u8 is_add = 1;
8427   int ret = 0;
8428
8429   /* Parse args required to build the message */
8430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8431     {
8432       if (unformat (i, "ipv6"))
8433         is_ipv6 = 1;
8434       else if (unformat (i, "del"))
8435         is_add = 0;
8436       else if (unformat (i, "add"))
8437         is_add = 1;
8438       else if (unformat (i, "table %d", &table_id))
8439         ;
8440       else
8441         {
8442           clib_warning ("parse error '%U'", format_unformat_error, i);
8443           return -99;
8444         }
8445     }
8446
8447   if (~0 == table_id)
8448     {
8449       errmsg ("missing table-ID");
8450       return -99;
8451     }
8452
8453   /* Construct the API message */
8454   M (IP_TABLE_ADD_DEL, mp);
8455
8456   mp->table_id = ntohl (table_id);
8457   mp->is_ipv6 = is_ipv6;
8458   mp->is_add = is_add;
8459
8460   /* send it... */
8461   S (mp);
8462
8463   /* Wait for a reply... */
8464   W (ret);
8465
8466   return ret;
8467 }
8468
8469 static int
8470 api_ip_add_del_route (vat_main_t * vam)
8471 {
8472   unformat_input_t *i = vam->input;
8473   vl_api_ip_add_del_route_t *mp;
8474   u32 sw_if_index = ~0, vrf_id = 0;
8475   u8 is_ipv6 = 0;
8476   u8 is_local = 0, is_drop = 0;
8477   u8 is_unreach = 0, is_prohibit = 0;
8478   u8 is_add = 1;
8479   u32 next_hop_weight = 1;
8480   u8 is_multipath = 0;
8481   u8 address_set = 0;
8482   u8 address_length_set = 0;
8483   u32 next_hop_table_id = 0;
8484   u32 resolve_attempts = 0;
8485   u32 dst_address_length = 0;
8486   u8 next_hop_set = 0;
8487   ip4_address_t v4_dst_address, v4_next_hop_address;
8488   ip6_address_t v6_dst_address, v6_next_hop_address;
8489   int count = 1;
8490   int j;
8491   f64 before = 0;
8492   u32 random_add_del = 0;
8493   u32 *random_vector = 0;
8494   uword *random_hash;
8495   u32 random_seed = 0xdeaddabe;
8496   u32 classify_table_index = ~0;
8497   u8 is_classify = 0;
8498   u8 resolve_host = 0, resolve_attached = 0;
8499   mpls_label_t *next_hop_out_label_stack = NULL;
8500   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8501   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8502
8503   /* Parse args required to build the message */
8504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8505     {
8506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8507         ;
8508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8509         ;
8510       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8511         {
8512           address_set = 1;
8513           is_ipv6 = 0;
8514         }
8515       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8516         {
8517           address_set = 1;
8518           is_ipv6 = 1;
8519         }
8520       else if (unformat (i, "/%d", &dst_address_length))
8521         {
8522           address_length_set = 1;
8523         }
8524
8525       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8526                                          &v4_next_hop_address))
8527         {
8528           next_hop_set = 1;
8529         }
8530       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8531                                          &v6_next_hop_address))
8532         {
8533           next_hop_set = 1;
8534         }
8535       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8536         ;
8537       else if (unformat (i, "weight %d", &next_hop_weight))
8538         ;
8539       else if (unformat (i, "drop"))
8540         {
8541           is_drop = 1;
8542         }
8543       else if (unformat (i, "null-send-unreach"))
8544         {
8545           is_unreach = 1;
8546         }
8547       else if (unformat (i, "null-send-prohibit"))
8548         {
8549           is_prohibit = 1;
8550         }
8551       else if (unformat (i, "local"))
8552         {
8553           is_local = 1;
8554         }
8555       else if (unformat (i, "classify %d", &classify_table_index))
8556         {
8557           is_classify = 1;
8558         }
8559       else if (unformat (i, "del"))
8560         is_add = 0;
8561       else if (unformat (i, "add"))
8562         is_add = 1;
8563       else if (unformat (i, "resolve-via-host"))
8564         resolve_host = 1;
8565       else if (unformat (i, "resolve-via-attached"))
8566         resolve_attached = 1;
8567       else if (unformat (i, "multipath"))
8568         is_multipath = 1;
8569       else if (unformat (i, "vrf %d", &vrf_id))
8570         ;
8571       else if (unformat (i, "count %d", &count))
8572         ;
8573       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8574         ;
8575       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8576         ;
8577       else if (unformat (i, "out-label %d", &next_hop_out_label))
8578         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8579       else if (unformat (i, "via-label %d", &next_hop_via_label))
8580         ;
8581       else if (unformat (i, "random"))
8582         random_add_del = 1;
8583       else if (unformat (i, "seed %d", &random_seed))
8584         ;
8585       else
8586         {
8587           clib_warning ("parse error '%U'", format_unformat_error, i);
8588           return -99;
8589         }
8590     }
8591
8592   if (!next_hop_set && !is_drop && !is_local &&
8593       !is_classify && !is_unreach && !is_prohibit &&
8594       MPLS_LABEL_INVALID == next_hop_via_label)
8595     {
8596       errmsg
8597         ("next hop / local / drop / unreach / prohibit / classify not set");
8598       return -99;
8599     }
8600
8601   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8602     {
8603       errmsg ("next hop and next-hop via label set");
8604       return -99;
8605     }
8606   if (address_set == 0)
8607     {
8608       errmsg ("missing addresses");
8609       return -99;
8610     }
8611
8612   if (address_length_set == 0)
8613     {
8614       errmsg ("missing address length");
8615       return -99;
8616     }
8617
8618   /* Generate a pile of unique, random routes */
8619   if (random_add_del)
8620     {
8621       u32 this_random_address;
8622       random_hash = hash_create (count, sizeof (uword));
8623
8624       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8625       for (j = 0; j <= count; j++)
8626         {
8627           do
8628             {
8629               this_random_address = random_u32 (&random_seed);
8630               this_random_address =
8631                 clib_host_to_net_u32 (this_random_address);
8632             }
8633           while (hash_get (random_hash, this_random_address));
8634           vec_add1 (random_vector, this_random_address);
8635           hash_set (random_hash, this_random_address, 1);
8636         }
8637       hash_free (random_hash);
8638       v4_dst_address.as_u32 = random_vector[0];
8639     }
8640
8641   if (count > 1)
8642     {
8643       /* Turn on async mode */
8644       vam->async_mode = 1;
8645       vam->async_errors = 0;
8646       before = vat_time_now (vam);
8647     }
8648
8649   for (j = 0; j < count; j++)
8650     {
8651       /* Construct the API message */
8652       M2 (IP_ADD_DEL_ROUTE, mp,
8653           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8654
8655       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8656       mp->table_id = ntohl (vrf_id);
8657
8658       mp->is_add = is_add;
8659       mp->is_drop = is_drop;
8660       mp->is_unreach = is_unreach;
8661       mp->is_prohibit = is_prohibit;
8662       mp->is_ipv6 = is_ipv6;
8663       mp->is_local = is_local;
8664       mp->is_classify = is_classify;
8665       mp->is_multipath = is_multipath;
8666       mp->is_resolve_host = resolve_host;
8667       mp->is_resolve_attached = resolve_attached;
8668       mp->next_hop_weight = next_hop_weight;
8669       mp->dst_address_length = dst_address_length;
8670       mp->next_hop_table_id = ntohl (next_hop_table_id);
8671       mp->classify_table_index = ntohl (classify_table_index);
8672       mp->next_hop_via_label = ntohl (next_hop_via_label);
8673       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8674       if (0 != mp->next_hop_n_out_labels)
8675         {
8676           memcpy (mp->next_hop_out_label_stack,
8677                   next_hop_out_label_stack,
8678                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8679           vec_free (next_hop_out_label_stack);
8680         }
8681
8682       if (is_ipv6)
8683         {
8684           clib_memcpy (mp->dst_address, &v6_dst_address,
8685                        sizeof (v6_dst_address));
8686           if (next_hop_set)
8687             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8688                          sizeof (v6_next_hop_address));
8689           increment_v6_address (&v6_dst_address);
8690         }
8691       else
8692         {
8693           clib_memcpy (mp->dst_address, &v4_dst_address,
8694                        sizeof (v4_dst_address));
8695           if (next_hop_set)
8696             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8697                          sizeof (v4_next_hop_address));
8698           if (random_add_del)
8699             v4_dst_address.as_u32 = random_vector[j + 1];
8700           else
8701             increment_v4_address (&v4_dst_address);
8702         }
8703       /* send it... */
8704       S (mp);
8705       /* If we receive SIGTERM, stop now... */
8706       if (vam->do_exit)
8707         break;
8708     }
8709
8710   /* When testing multiple add/del ops, use a control-ping to sync */
8711   if (count > 1)
8712     {
8713       vl_api_control_ping_t *mp_ping;
8714       f64 after;
8715       f64 timeout;
8716
8717       /* Shut off async mode */
8718       vam->async_mode = 0;
8719
8720       MPING (CONTROL_PING, mp_ping);
8721       S (mp_ping);
8722
8723       timeout = vat_time_now (vam) + 1.0;
8724       while (vat_time_now (vam) < timeout)
8725         if (vam->result_ready == 1)
8726           goto out;
8727       vam->retval = -99;
8728
8729     out:
8730       if (vam->retval == -99)
8731         errmsg ("timeout");
8732
8733       if (vam->async_errors > 0)
8734         {
8735           errmsg ("%d asynchronous errors", vam->async_errors);
8736           vam->retval = -98;
8737         }
8738       vam->async_errors = 0;
8739       after = vat_time_now (vam);
8740
8741       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8742       if (j > 0)
8743         count = j;
8744
8745       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8746              count, after - before, count / (after - before));
8747     }
8748   else
8749     {
8750       int ret;
8751
8752       /* Wait for a reply... */
8753       W (ret);
8754       return ret;
8755     }
8756
8757   /* Return the good/bad news */
8758   return (vam->retval);
8759 }
8760
8761 static int
8762 api_ip_mroute_add_del (vat_main_t * vam)
8763 {
8764   unformat_input_t *i = vam->input;
8765   vl_api_ip_mroute_add_del_t *mp;
8766   u32 sw_if_index = ~0, vrf_id = 0;
8767   u8 is_ipv6 = 0;
8768   u8 is_local = 0;
8769   u8 is_add = 1;
8770   u8 address_set = 0;
8771   u32 grp_address_length = 0;
8772   ip4_address_t v4_grp_address, v4_src_address;
8773   ip6_address_t v6_grp_address, v6_src_address;
8774   mfib_itf_flags_t iflags = 0;
8775   mfib_entry_flags_t eflags = 0;
8776   int ret;
8777
8778   /* Parse args required to build the message */
8779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8780     {
8781       if (unformat (i, "sw_if_index %d", &sw_if_index))
8782         ;
8783       else if (unformat (i, "%U %U",
8784                          unformat_ip4_address, &v4_src_address,
8785                          unformat_ip4_address, &v4_grp_address))
8786         {
8787           grp_address_length = 64;
8788           address_set = 1;
8789           is_ipv6 = 0;
8790         }
8791       else if (unformat (i, "%U %U",
8792                          unformat_ip6_address, &v6_src_address,
8793                          unformat_ip6_address, &v6_grp_address))
8794         {
8795           grp_address_length = 256;
8796           address_set = 1;
8797           is_ipv6 = 1;
8798         }
8799       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8800         {
8801           memset (&v4_src_address, 0, sizeof (v4_src_address));
8802           grp_address_length = 32;
8803           address_set = 1;
8804           is_ipv6 = 0;
8805         }
8806       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8807         {
8808           memset (&v6_src_address, 0, sizeof (v6_src_address));
8809           grp_address_length = 128;
8810           address_set = 1;
8811           is_ipv6 = 1;
8812         }
8813       else if (unformat (i, "/%d", &grp_address_length))
8814         ;
8815       else if (unformat (i, "local"))
8816         {
8817           is_local = 1;
8818         }
8819       else if (unformat (i, "del"))
8820         is_add = 0;
8821       else if (unformat (i, "add"))
8822         is_add = 1;
8823       else if (unformat (i, "vrf %d", &vrf_id))
8824         ;
8825       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8826         ;
8827       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8828         ;
8829       else
8830         {
8831           clib_warning ("parse error '%U'", format_unformat_error, i);
8832           return -99;
8833         }
8834     }
8835
8836   if (address_set == 0)
8837     {
8838       errmsg ("missing addresses\n");
8839       return -99;
8840     }
8841
8842   /* Construct the API message */
8843   M (IP_MROUTE_ADD_DEL, mp);
8844
8845   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8846   mp->table_id = ntohl (vrf_id);
8847
8848   mp->is_add = is_add;
8849   mp->is_ipv6 = is_ipv6;
8850   mp->is_local = is_local;
8851   mp->itf_flags = ntohl (iflags);
8852   mp->entry_flags = ntohl (eflags);
8853   mp->grp_address_length = grp_address_length;
8854   mp->grp_address_length = ntohs (mp->grp_address_length);
8855
8856   if (is_ipv6)
8857     {
8858       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8859       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8860     }
8861   else
8862     {
8863       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8864       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8865
8866     }
8867
8868   /* send it... */
8869   S (mp);
8870   /* Wait for a reply... */
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_mpls_table_add_del (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_mpls_table_add_del_t *mp;
8880   u32 table_id = ~0;
8881   u8 is_add = 1;
8882   int ret = 0;
8883
8884   /* Parse args required to build the message */
8885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (i, "table %d", &table_id))
8888         ;
8889       else if (unformat (i, "del"))
8890         is_add = 0;
8891       else if (unformat (i, "add"))
8892         is_add = 1;
8893       else
8894         {
8895           clib_warning ("parse error '%U'", format_unformat_error, i);
8896           return -99;
8897         }
8898     }
8899
8900   if (~0 == table_id)
8901     {
8902       errmsg ("missing table-ID");
8903       return -99;
8904     }
8905
8906   /* Construct the API message */
8907   M (MPLS_TABLE_ADD_DEL, mp);
8908
8909   mp->mt_table_id = ntohl (table_id);
8910   mp->mt_is_add = is_add;
8911
8912   /* send it... */
8913   S (mp);
8914
8915   /* Wait for a reply... */
8916   W (ret);
8917
8918   return ret;
8919 }
8920
8921 static int
8922 api_mpls_route_add_del (vat_main_t * vam)
8923 {
8924   unformat_input_t *i = vam->input;
8925   vl_api_mpls_route_add_del_t *mp;
8926   u32 sw_if_index = ~0, table_id = 0;
8927   u8 is_add = 1;
8928   u32 next_hop_weight = 1;
8929   u8 is_multipath = 0;
8930   u32 next_hop_table_id = 0;
8931   u8 next_hop_set = 0;
8932   ip4_address_t v4_next_hop_address = {
8933     .as_u32 = 0,
8934   };
8935   ip6_address_t v6_next_hop_address = { {0} };
8936   int count = 1;
8937   int j;
8938   f64 before = 0;
8939   u32 classify_table_index = ~0;
8940   u8 is_classify = 0;
8941   u8 resolve_host = 0, resolve_attached = 0;
8942   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8943   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8944   mpls_label_t *next_hop_out_label_stack = NULL;
8945   mpls_label_t local_label = MPLS_LABEL_INVALID;
8946   u8 is_eos = 0;
8947   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8948
8949   /* Parse args required to build the message */
8950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8951     {
8952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8953         ;
8954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8955         ;
8956       else if (unformat (i, "%d", &local_label))
8957         ;
8958       else if (unformat (i, "eos"))
8959         is_eos = 1;
8960       else if (unformat (i, "non-eos"))
8961         is_eos = 0;
8962       else if (unformat (i, "via %U", unformat_ip4_address,
8963                          &v4_next_hop_address))
8964         {
8965           next_hop_set = 1;
8966           next_hop_proto = DPO_PROTO_IP4;
8967         }
8968       else if (unformat (i, "via %U", unformat_ip6_address,
8969                          &v6_next_hop_address))
8970         {
8971           next_hop_set = 1;
8972           next_hop_proto = DPO_PROTO_IP6;
8973         }
8974       else if (unformat (i, "weight %d", &next_hop_weight))
8975         ;
8976       else if (unformat (i, "classify %d", &classify_table_index))
8977         {
8978           is_classify = 1;
8979         }
8980       else if (unformat (i, "del"))
8981         is_add = 0;
8982       else if (unformat (i, "add"))
8983         is_add = 1;
8984       else if (unformat (i, "resolve-via-host"))
8985         resolve_host = 1;
8986       else if (unformat (i, "resolve-via-attached"))
8987         resolve_attached = 1;
8988       else if (unformat (i, "multipath"))
8989         is_multipath = 1;
8990       else if (unformat (i, "count %d", &count))
8991         ;
8992       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8993         {
8994           next_hop_set = 1;
8995           next_hop_proto = DPO_PROTO_IP4;
8996         }
8997       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8998         {
8999           next_hop_set = 1;
9000           next_hop_proto = DPO_PROTO_IP6;
9001         }
9002       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9003         ;
9004       else if (unformat (i, "via-label %d", &next_hop_via_label))
9005         ;
9006       else if (unformat (i, "out-label %d", &next_hop_out_label))
9007         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
9008       else
9009         {
9010           clib_warning ("parse error '%U'", format_unformat_error, i);
9011           return -99;
9012         }
9013     }
9014
9015   if (!next_hop_set && !is_classify)
9016     {
9017       errmsg ("next hop / classify not set");
9018       return -99;
9019     }
9020
9021   if (MPLS_LABEL_INVALID == local_label)
9022     {
9023       errmsg ("missing label");
9024       return -99;
9025     }
9026
9027   if (count > 1)
9028     {
9029       /* Turn on async mode */
9030       vam->async_mode = 1;
9031       vam->async_errors = 0;
9032       before = vat_time_now (vam);
9033     }
9034
9035   for (j = 0; j < count; j++)
9036     {
9037       /* Construct the API message */
9038       M2 (MPLS_ROUTE_ADD_DEL, mp,
9039           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
9040
9041       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9042       mp->mr_table_id = ntohl (table_id);
9043
9044       mp->mr_is_add = is_add;
9045       mp->mr_next_hop_proto = next_hop_proto;
9046       mp->mr_is_classify = is_classify;
9047       mp->mr_is_multipath = is_multipath;
9048       mp->mr_is_resolve_host = resolve_host;
9049       mp->mr_is_resolve_attached = resolve_attached;
9050       mp->mr_next_hop_weight = next_hop_weight;
9051       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9052       mp->mr_classify_table_index = ntohl (classify_table_index);
9053       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9054       mp->mr_label = ntohl (local_label);
9055       mp->mr_eos = is_eos;
9056
9057       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9058       if (0 != mp->mr_next_hop_n_out_labels)
9059         {
9060           memcpy (mp->mr_next_hop_out_label_stack,
9061                   next_hop_out_label_stack,
9062                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
9063           vec_free (next_hop_out_label_stack);
9064         }
9065
9066       if (next_hop_set)
9067         {
9068           if (DPO_PROTO_IP4 == next_hop_proto)
9069             {
9070               clib_memcpy (mp->mr_next_hop,
9071                            &v4_next_hop_address,
9072                            sizeof (v4_next_hop_address));
9073             }
9074           else if (DPO_PROTO_IP6 == next_hop_proto)
9075
9076             {
9077               clib_memcpy (mp->mr_next_hop,
9078                            &v6_next_hop_address,
9079                            sizeof (v6_next_hop_address));
9080             }
9081         }
9082       local_label++;
9083
9084       /* send it... */
9085       S (mp);
9086       /* If we receive SIGTERM, stop now... */
9087       if (vam->do_exit)
9088         break;
9089     }
9090
9091   /* When testing multiple add/del ops, use a control-ping to sync */
9092   if (count > 1)
9093     {
9094       vl_api_control_ping_t *mp_ping;
9095       f64 after;
9096       f64 timeout;
9097
9098       /* Shut off async mode */
9099       vam->async_mode = 0;
9100
9101       MPING (CONTROL_PING, mp_ping);
9102       S (mp_ping);
9103
9104       timeout = vat_time_now (vam) + 1.0;
9105       while (vat_time_now (vam) < timeout)
9106         if (vam->result_ready == 1)
9107           goto out;
9108       vam->retval = -99;
9109
9110     out:
9111       if (vam->retval == -99)
9112         errmsg ("timeout");
9113
9114       if (vam->async_errors > 0)
9115         {
9116           errmsg ("%d asynchronous errors", vam->async_errors);
9117           vam->retval = -98;
9118         }
9119       vam->async_errors = 0;
9120       after = vat_time_now (vam);
9121
9122       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9123       if (j > 0)
9124         count = j;
9125
9126       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9127              count, after - before, count / (after - before));
9128     }
9129   else
9130     {
9131       int ret;
9132
9133       /* Wait for a reply... */
9134       W (ret);
9135       return ret;
9136     }
9137
9138   /* Return the good/bad news */
9139   return (vam->retval);
9140 }
9141
9142 static int
9143 api_mpls_ip_bind_unbind (vat_main_t * vam)
9144 {
9145   unformat_input_t *i = vam->input;
9146   vl_api_mpls_ip_bind_unbind_t *mp;
9147   u32 ip_table_id = 0;
9148   u8 is_bind = 1;
9149   u8 is_ip4 = 1;
9150   ip4_address_t v4_address;
9151   ip6_address_t v6_address;
9152   u32 address_length;
9153   u8 address_set = 0;
9154   mpls_label_t local_label = MPLS_LABEL_INVALID;
9155   int ret;
9156
9157   /* Parse args required to build the message */
9158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (i, "%U/%d", unformat_ip4_address,
9161                     &v4_address, &address_length))
9162         {
9163           is_ip4 = 1;
9164           address_set = 1;
9165         }
9166       else if (unformat (i, "%U/%d", unformat_ip6_address,
9167                          &v6_address, &address_length))
9168         {
9169           is_ip4 = 0;
9170           address_set = 1;
9171         }
9172       else if (unformat (i, "%d", &local_label))
9173         ;
9174       else if (unformat (i, "table-id %d", &ip_table_id))
9175         ;
9176       else if (unformat (i, "unbind"))
9177         is_bind = 0;
9178       else if (unformat (i, "bind"))
9179         is_bind = 1;
9180       else
9181         {
9182           clib_warning ("parse error '%U'", format_unformat_error, i);
9183           return -99;
9184         }
9185     }
9186
9187   if (!address_set)
9188     {
9189       errmsg ("IP addres not set");
9190       return -99;
9191     }
9192
9193   if (MPLS_LABEL_INVALID == local_label)
9194     {
9195       errmsg ("missing label");
9196       return -99;
9197     }
9198
9199   /* Construct the API message */
9200   M (MPLS_IP_BIND_UNBIND, mp);
9201
9202   mp->mb_is_bind = is_bind;
9203   mp->mb_is_ip4 = is_ip4;
9204   mp->mb_ip_table_id = ntohl (ip_table_id);
9205   mp->mb_mpls_table_id = 0;
9206   mp->mb_label = ntohl (local_label);
9207   mp->mb_address_length = address_length;
9208
9209   if (is_ip4)
9210     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9211   else
9212     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9213
9214   /* send it... */
9215   S (mp);
9216
9217   /* Wait for a reply... */
9218   W (ret);
9219   return ret;
9220 }
9221
9222 static int
9223 api_bier_table_add_del (vat_main_t * vam)
9224 {
9225   unformat_input_t *i = vam->input;
9226   vl_api_bier_table_add_del_t *mp;
9227   u8 is_add = 1;
9228   u32 set = 0, sub_domain = 0, hdr_len = 3;
9229   mpls_label_t local_label = MPLS_LABEL_INVALID;
9230   int ret;
9231
9232   /* Parse args required to build the message */
9233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9234     {
9235       if (unformat (i, "sub-domain %d", &sub_domain))
9236         ;
9237       else if (unformat (i, "set %d", &set))
9238         ;
9239       else if (unformat (i, "label %d", &local_label))
9240         ;
9241       else if (unformat (i, "hdr-len %d", &hdr_len))
9242         ;
9243       else if (unformat (i, "add"))
9244         is_add = 1;
9245       else if (unformat (i, "del"))
9246         is_add = 0;
9247       else
9248         {
9249           clib_warning ("parse error '%U'", format_unformat_error, i);
9250           return -99;
9251         }
9252     }
9253
9254   if (MPLS_LABEL_INVALID == local_label)
9255     {
9256       errmsg ("missing label\n");
9257       return -99;
9258     }
9259
9260   /* Construct the API message */
9261   M (BIER_TABLE_ADD_DEL, mp);
9262
9263   mp->bt_is_add = is_add;
9264   mp->bt_label = ntohl (local_label);
9265   mp->bt_tbl_id.bt_set = set;
9266   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9267   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9268
9269   /* send it... */
9270   S (mp);
9271
9272   /* Wait for a reply... */
9273   W (ret);
9274
9275   return (ret);
9276 }
9277
9278 static int
9279 api_bier_route_add_del (vat_main_t * vam)
9280 {
9281   unformat_input_t *i = vam->input;
9282   vl_api_bier_route_add_del_t *mp;
9283   u8 is_add = 1;
9284   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9285   ip4_address_t v4_next_hop_address;
9286   ip6_address_t v6_next_hop_address;
9287   u8 next_hop_set = 0;
9288   u8 next_hop_proto_is_ip4 = 1;
9289   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9290   int ret;
9291
9292   /* Parse args required to build the message */
9293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9294     {
9295       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9296         {
9297           next_hop_proto_is_ip4 = 1;
9298           next_hop_set = 1;
9299         }
9300       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9301         {
9302           next_hop_proto_is_ip4 = 0;
9303           next_hop_set = 1;
9304         }
9305       if (unformat (i, "sub-domain %d", &sub_domain))
9306         ;
9307       else if (unformat (i, "set %d", &set))
9308         ;
9309       else if (unformat (i, "hdr-len %d", &hdr_len))
9310         ;
9311       else if (unformat (i, "bp %d", &bp))
9312         ;
9313       else if (unformat (i, "add"))
9314         is_add = 1;
9315       else if (unformat (i, "del"))
9316         is_add = 0;
9317       else if (unformat (i, "out-label %d", &next_hop_out_label))
9318         ;
9319       else
9320         {
9321           clib_warning ("parse error '%U'", format_unformat_error, i);
9322           return -99;
9323         }
9324     }
9325
9326   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9327     {
9328       errmsg ("next hop / label set\n");
9329       return -99;
9330     }
9331   if (0 == bp)
9332     {
9333       errmsg ("bit=position not set\n");
9334       return -99;
9335     }
9336
9337   /* Construct the API message */
9338   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9339
9340   mp->br_is_add = is_add;
9341   mp->br_tbl_id.bt_set = set;
9342   mp->br_tbl_id.bt_sub_domain = sub_domain;
9343   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9344   mp->br_bp = ntohs (bp);
9345   mp->br_n_paths = 1;
9346   mp->br_paths[0].n_labels = 1;
9347   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9348   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9349
9350   if (next_hop_proto_is_ip4)
9351     {
9352       clib_memcpy (mp->br_paths[0].next_hop,
9353                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9354     }
9355   else
9356     {
9357       clib_memcpy (mp->br_paths[0].next_hop,
9358                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9359     }
9360
9361   /* send it... */
9362   S (mp);
9363
9364   /* Wait for a reply... */
9365   W (ret);
9366
9367   return (ret);
9368 }
9369
9370 static int
9371 api_proxy_arp_add_del (vat_main_t * vam)
9372 {
9373   unformat_input_t *i = vam->input;
9374   vl_api_proxy_arp_add_del_t *mp;
9375   u32 vrf_id = 0;
9376   u8 is_add = 1;
9377   ip4_address_t lo, hi;
9378   u8 range_set = 0;
9379   int ret;
9380
9381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9382     {
9383       if (unformat (i, "vrf %d", &vrf_id))
9384         ;
9385       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9386                          unformat_ip4_address, &hi))
9387         range_set = 1;
9388       else if (unformat (i, "del"))
9389         is_add = 0;
9390       else
9391         {
9392           clib_warning ("parse error '%U'", format_unformat_error, i);
9393           return -99;
9394         }
9395     }
9396
9397   if (range_set == 0)
9398     {
9399       errmsg ("address range not set");
9400       return -99;
9401     }
9402
9403   M (PROXY_ARP_ADD_DEL, mp);
9404
9405   mp->vrf_id = ntohl (vrf_id);
9406   mp->is_add = is_add;
9407   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
9408   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
9409
9410   S (mp);
9411   W (ret);
9412   return ret;
9413 }
9414
9415 static int
9416 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9417 {
9418   unformat_input_t *i = vam->input;
9419   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9420   u32 sw_if_index;
9421   u8 enable = 1;
9422   u8 sw_if_index_set = 0;
9423   int ret;
9424
9425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9426     {
9427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9428         sw_if_index_set = 1;
9429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9430         sw_if_index_set = 1;
9431       else if (unformat (i, "enable"))
9432         enable = 1;
9433       else if (unformat (i, "disable"))
9434         enable = 0;
9435       else
9436         {
9437           clib_warning ("parse error '%U'", format_unformat_error, i);
9438           return -99;
9439         }
9440     }
9441
9442   if (sw_if_index_set == 0)
9443     {
9444       errmsg ("missing interface name or sw_if_index");
9445       return -99;
9446     }
9447
9448   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9449
9450   mp->sw_if_index = ntohl (sw_if_index);
9451   mp->enable_disable = enable;
9452
9453   S (mp);
9454   W (ret);
9455   return ret;
9456 }
9457
9458 static int
9459 api_mpls_tunnel_add_del (vat_main_t * vam)
9460 {
9461   unformat_input_t *i = vam->input;
9462   vl_api_mpls_tunnel_add_del_t *mp;
9463
9464   u8 is_add = 1;
9465   u8 l2_only = 0;
9466   u32 sw_if_index = ~0;
9467   u32 next_hop_sw_if_index = ~0;
9468   u32 next_hop_proto_is_ip4 = 1;
9469
9470   u32 next_hop_table_id = 0;
9471   ip4_address_t v4_next_hop_address = {
9472     .as_u32 = 0,
9473   };
9474   ip6_address_t v6_next_hop_address = { {0} };
9475   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9476   int ret;
9477
9478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9479     {
9480       if (unformat (i, "add"))
9481         is_add = 1;
9482       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9483         is_add = 0;
9484       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9485         ;
9486       else if (unformat (i, "via %U",
9487                          unformat_ip4_address, &v4_next_hop_address))
9488         {
9489           next_hop_proto_is_ip4 = 1;
9490         }
9491       else if (unformat (i, "via %U",
9492                          unformat_ip6_address, &v6_next_hop_address))
9493         {
9494           next_hop_proto_is_ip4 = 0;
9495         }
9496       else if (unformat (i, "l2-only"))
9497         l2_only = 1;
9498       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9499         ;
9500       else if (unformat (i, "out-label %d", &next_hop_out_label))
9501         vec_add1 (labels, ntohl (next_hop_out_label));
9502       else
9503         {
9504           clib_warning ("parse error '%U'", format_unformat_error, i);
9505           return -99;
9506         }
9507     }
9508
9509   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9510
9511   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9512   mp->mt_sw_if_index = ntohl (sw_if_index);
9513   mp->mt_is_add = is_add;
9514   mp->mt_l2_only = l2_only;
9515   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9516   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9517
9518   mp->mt_next_hop_n_out_labels = vec_len (labels);
9519
9520   if (0 != mp->mt_next_hop_n_out_labels)
9521     {
9522       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9523                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9524       vec_free (labels);
9525     }
9526
9527   if (next_hop_proto_is_ip4)
9528     {
9529       clib_memcpy (mp->mt_next_hop,
9530                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9531     }
9532   else
9533     {
9534       clib_memcpy (mp->mt_next_hop,
9535                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9536     }
9537
9538   S (mp);
9539   W (ret);
9540   return ret;
9541 }
9542
9543 static int
9544 api_sw_interface_set_unnumbered (vat_main_t * vam)
9545 {
9546   unformat_input_t *i = vam->input;
9547   vl_api_sw_interface_set_unnumbered_t *mp;
9548   u32 sw_if_index;
9549   u32 unnum_sw_index = ~0;
9550   u8 is_add = 1;
9551   u8 sw_if_index_set = 0;
9552   int ret;
9553
9554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9555     {
9556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9559         sw_if_index_set = 1;
9560       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9561         ;
9562       else if (unformat (i, "del"))
9563         is_add = 0;
9564       else
9565         {
9566           clib_warning ("parse error '%U'", format_unformat_error, i);
9567           return -99;
9568         }
9569     }
9570
9571   if (sw_if_index_set == 0)
9572     {
9573       errmsg ("missing interface name or sw_if_index");
9574       return -99;
9575     }
9576
9577   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9578
9579   mp->sw_if_index = ntohl (sw_if_index);
9580   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9581   mp->is_add = is_add;
9582
9583   S (mp);
9584   W (ret);
9585   return ret;
9586 }
9587
9588 static int
9589 api_ip_neighbor_add_del (vat_main_t * vam)
9590 {
9591   unformat_input_t *i = vam->input;
9592   vl_api_ip_neighbor_add_del_t *mp;
9593   u32 sw_if_index;
9594   u8 sw_if_index_set = 0;
9595   u8 is_add = 1;
9596   u8 is_static = 0;
9597   u8 is_no_fib_entry = 0;
9598   u8 mac_address[6];
9599   u8 mac_set = 0;
9600   u8 v4_address_set = 0;
9601   u8 v6_address_set = 0;
9602   ip4_address_t v4address;
9603   ip6_address_t v6address;
9604   int ret;
9605
9606   memset (mac_address, 0, sizeof (mac_address));
9607
9608   /* Parse args required to build the message */
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9612         {
9613           mac_set = 1;
9614         }
9615       else if (unformat (i, "del"))
9616         is_add = 0;
9617       else
9618         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9619         sw_if_index_set = 1;
9620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9621         sw_if_index_set = 1;
9622       else if (unformat (i, "is_static"))
9623         is_static = 1;
9624       else if (unformat (i, "no-fib-entry"))
9625         is_no_fib_entry = 1;
9626       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9627         v4_address_set = 1;
9628       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9629         v6_address_set = 1;
9630       else
9631         {
9632           clib_warning ("parse error '%U'", format_unformat_error, i);
9633           return -99;
9634         }
9635     }
9636
9637   if (sw_if_index_set == 0)
9638     {
9639       errmsg ("missing interface name or sw_if_index");
9640       return -99;
9641     }
9642   if (v4_address_set && v6_address_set)
9643     {
9644       errmsg ("both v4 and v6 addresses set");
9645       return -99;
9646     }
9647   if (!v4_address_set && !v6_address_set)
9648     {
9649       errmsg ("no address set");
9650       return -99;
9651     }
9652
9653   /* Construct the API message */
9654   M (IP_NEIGHBOR_ADD_DEL, mp);
9655
9656   mp->sw_if_index = ntohl (sw_if_index);
9657   mp->is_add = is_add;
9658   mp->is_static = is_static;
9659   mp->is_no_adj_fib = is_no_fib_entry;
9660   if (mac_set)
9661     clib_memcpy (mp->mac_address, mac_address, 6);
9662   if (v6_address_set)
9663     {
9664       mp->is_ipv6 = 1;
9665       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9666     }
9667   else
9668     {
9669       /* mp->is_ipv6 = 0; via memset in M macro above */
9670       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9671     }
9672
9673   /* send it... */
9674   S (mp);
9675
9676   /* Wait for a reply, return good/bad news  */
9677   W (ret);
9678   return ret;
9679 }
9680
9681 static int
9682 api_create_vlan_subif (vat_main_t * vam)
9683 {
9684   unformat_input_t *i = vam->input;
9685   vl_api_create_vlan_subif_t *mp;
9686   u32 sw_if_index;
9687   u8 sw_if_index_set = 0;
9688   u32 vlan_id;
9689   u8 vlan_id_set = 0;
9690   int ret;
9691
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "sw_if_index %d", &sw_if_index))
9695         sw_if_index_set = 1;
9696       else
9697         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9698         sw_if_index_set = 1;
9699       else if (unformat (i, "vlan %d", &vlan_id))
9700         vlan_id_set = 1;
9701       else
9702         {
9703           clib_warning ("parse error '%U'", format_unformat_error, i);
9704           return -99;
9705         }
9706     }
9707
9708   if (sw_if_index_set == 0)
9709     {
9710       errmsg ("missing interface name or sw_if_index");
9711       return -99;
9712     }
9713
9714   if (vlan_id_set == 0)
9715     {
9716       errmsg ("missing vlan_id");
9717       return -99;
9718     }
9719   M (CREATE_VLAN_SUBIF, mp);
9720
9721   mp->sw_if_index = ntohl (sw_if_index);
9722   mp->vlan_id = ntohl (vlan_id);
9723
9724   S (mp);
9725   W (ret);
9726   return ret;
9727 }
9728
9729 #define foreach_create_subif_bit                \
9730 _(no_tags)                                      \
9731 _(one_tag)                                      \
9732 _(two_tags)                                     \
9733 _(dot1ad)                                       \
9734 _(exact_match)                                  \
9735 _(default_sub)                                  \
9736 _(outer_vlan_id_any)                            \
9737 _(inner_vlan_id_any)
9738
9739 static int
9740 api_create_subif (vat_main_t * vam)
9741 {
9742   unformat_input_t *i = vam->input;
9743   vl_api_create_subif_t *mp;
9744   u32 sw_if_index;
9745   u8 sw_if_index_set = 0;
9746   u32 sub_id;
9747   u8 sub_id_set = 0;
9748   u32 no_tags = 0;
9749   u32 one_tag = 0;
9750   u32 two_tags = 0;
9751   u32 dot1ad = 0;
9752   u32 exact_match = 0;
9753   u32 default_sub = 0;
9754   u32 outer_vlan_id_any = 0;
9755   u32 inner_vlan_id_any = 0;
9756   u32 tmp;
9757   u16 outer_vlan_id = 0;
9758   u16 inner_vlan_id = 0;
9759   int ret;
9760
9761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9762     {
9763       if (unformat (i, "sw_if_index %d", &sw_if_index))
9764         sw_if_index_set = 1;
9765       else
9766         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9767         sw_if_index_set = 1;
9768       else if (unformat (i, "sub_id %d", &sub_id))
9769         sub_id_set = 1;
9770       else if (unformat (i, "outer_vlan_id %d", &tmp))
9771         outer_vlan_id = tmp;
9772       else if (unformat (i, "inner_vlan_id %d", &tmp))
9773         inner_vlan_id = tmp;
9774
9775 #define _(a) else if (unformat (i, #a)) a = 1 ;
9776       foreach_create_subif_bit
9777 #undef _
9778         else
9779         {
9780           clib_warning ("parse error '%U'", format_unformat_error, i);
9781           return -99;
9782         }
9783     }
9784
9785   if (sw_if_index_set == 0)
9786     {
9787       errmsg ("missing interface name or sw_if_index");
9788       return -99;
9789     }
9790
9791   if (sub_id_set == 0)
9792     {
9793       errmsg ("missing sub_id");
9794       return -99;
9795     }
9796   M (CREATE_SUBIF, mp);
9797
9798   mp->sw_if_index = ntohl (sw_if_index);
9799   mp->sub_id = ntohl (sub_id);
9800
9801 #define _(a) mp->a = a;
9802   foreach_create_subif_bit;
9803 #undef _
9804
9805   mp->outer_vlan_id = ntohs (outer_vlan_id);
9806   mp->inner_vlan_id = ntohs (inner_vlan_id);
9807
9808   S (mp);
9809   W (ret);
9810   return ret;
9811 }
9812
9813 static int
9814 api_oam_add_del (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   vl_api_oam_add_del_t *mp;
9818   u32 vrf_id = 0;
9819   u8 is_add = 1;
9820   ip4_address_t src, dst;
9821   u8 src_set = 0;
9822   u8 dst_set = 0;
9823   int ret;
9824
9825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (i, "vrf %d", &vrf_id))
9828         ;
9829       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9830         src_set = 1;
9831       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9832         dst_set = 1;
9833       else if (unformat (i, "del"))
9834         is_add = 0;
9835       else
9836         {
9837           clib_warning ("parse error '%U'", format_unformat_error, i);
9838           return -99;
9839         }
9840     }
9841
9842   if (src_set == 0)
9843     {
9844       errmsg ("missing src addr");
9845       return -99;
9846     }
9847
9848   if (dst_set == 0)
9849     {
9850       errmsg ("missing dst addr");
9851       return -99;
9852     }
9853
9854   M (OAM_ADD_DEL, mp);
9855
9856   mp->vrf_id = ntohl (vrf_id);
9857   mp->is_add = is_add;
9858   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9859   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9860
9861   S (mp);
9862   W (ret);
9863   return ret;
9864 }
9865
9866 static int
9867 api_reset_fib (vat_main_t * vam)
9868 {
9869   unformat_input_t *i = vam->input;
9870   vl_api_reset_fib_t *mp;
9871   u32 vrf_id = 0;
9872   u8 is_ipv6 = 0;
9873   u8 vrf_id_set = 0;
9874
9875   int ret;
9876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9877     {
9878       if (unformat (i, "vrf %d", &vrf_id))
9879         vrf_id_set = 1;
9880       else if (unformat (i, "ipv6"))
9881         is_ipv6 = 1;
9882       else
9883         {
9884           clib_warning ("parse error '%U'", format_unformat_error, i);
9885           return -99;
9886         }
9887     }
9888
9889   if (vrf_id_set == 0)
9890     {
9891       errmsg ("missing vrf id");
9892       return -99;
9893     }
9894
9895   M (RESET_FIB, mp);
9896
9897   mp->vrf_id = ntohl (vrf_id);
9898   mp->is_ipv6 = is_ipv6;
9899
9900   S (mp);
9901   W (ret);
9902   return ret;
9903 }
9904
9905 static int
9906 api_dhcp_proxy_config (vat_main_t * vam)
9907 {
9908   unformat_input_t *i = vam->input;
9909   vl_api_dhcp_proxy_config_t *mp;
9910   u32 rx_vrf_id = 0;
9911   u32 server_vrf_id = 0;
9912   u8 is_add = 1;
9913   u8 v4_address_set = 0;
9914   u8 v6_address_set = 0;
9915   ip4_address_t v4address;
9916   ip6_address_t v6address;
9917   u8 v4_src_address_set = 0;
9918   u8 v6_src_address_set = 0;
9919   ip4_address_t v4srcaddress;
9920   ip6_address_t v6srcaddress;
9921   int ret;
9922
9923   /* Parse args required to build the message */
9924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9925     {
9926       if (unformat (i, "del"))
9927         is_add = 0;
9928       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9929         ;
9930       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9931         ;
9932       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9933         v4_address_set = 1;
9934       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9935         v6_address_set = 1;
9936       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9937         v4_src_address_set = 1;
9938       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9939         v6_src_address_set = 1;
9940       else
9941         break;
9942     }
9943
9944   if (v4_address_set && v6_address_set)
9945     {
9946       errmsg ("both v4 and v6 server addresses set");
9947       return -99;
9948     }
9949   if (!v4_address_set && !v6_address_set)
9950     {
9951       errmsg ("no server addresses set");
9952       return -99;
9953     }
9954
9955   if (v4_src_address_set && v6_src_address_set)
9956     {
9957       errmsg ("both v4 and v6  src addresses set");
9958       return -99;
9959     }
9960   if (!v4_src_address_set && !v6_src_address_set)
9961     {
9962       errmsg ("no src addresses set");
9963       return -99;
9964     }
9965
9966   if (!(v4_src_address_set && v4_address_set) &&
9967       !(v6_src_address_set && v6_address_set))
9968     {
9969       errmsg ("no matching server and src addresses set");
9970       return -99;
9971     }
9972
9973   /* Construct the API message */
9974   M (DHCP_PROXY_CONFIG, mp);
9975
9976   mp->is_add = is_add;
9977   mp->rx_vrf_id = ntohl (rx_vrf_id);
9978   mp->server_vrf_id = ntohl (server_vrf_id);
9979   if (v6_address_set)
9980     {
9981       mp->is_ipv6 = 1;
9982       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9983       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9984     }
9985   else
9986     {
9987       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9988       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9989     }
9990
9991   /* send it... */
9992   S (mp);
9993
9994   /* Wait for a reply, return good/bad news  */
9995   W (ret);
9996   return ret;
9997 }
9998
9999 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10000 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10001
10002 static void
10003 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10004 {
10005   vat_main_t *vam = &vat_main;
10006   u32 i, count = mp->count;
10007   vl_api_dhcp_server_t *s;
10008
10009   if (mp->is_ipv6)
10010     print (vam->ofp,
10011            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10012            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10013            ntohl (mp->rx_vrf_id),
10014            format_ip6_address, mp->dhcp_src_address,
10015            mp->vss_type, mp->vss_vpn_ascii_id,
10016            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10017   else
10018     print (vam->ofp,
10019            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10020            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10021            ntohl (mp->rx_vrf_id),
10022            format_ip4_address, mp->dhcp_src_address,
10023            mp->vss_type, mp->vss_vpn_ascii_id,
10024            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10025
10026   for (i = 0; i < count; i++)
10027     {
10028       s = &mp->servers[i];
10029
10030       if (mp->is_ipv6)
10031         print (vam->ofp,
10032                " Server Table-ID %d, Server Address %U",
10033                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10034       else
10035         print (vam->ofp,
10036                " Server Table-ID %d, Server Address %U",
10037                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10038     }
10039 }
10040
10041 static void vl_api_dhcp_proxy_details_t_handler_json
10042   (vl_api_dhcp_proxy_details_t * mp)
10043 {
10044   vat_main_t *vam = &vat_main;
10045   vat_json_node_t *node = NULL;
10046   u32 i, count = mp->count;
10047   struct in_addr ip4;
10048   struct in6_addr ip6;
10049   vl_api_dhcp_server_t *s;
10050
10051   if (VAT_JSON_ARRAY != vam->json_tree.type)
10052     {
10053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10054       vat_json_init_array (&vam->json_tree);
10055     }
10056   node = vat_json_array_add (&vam->json_tree);
10057
10058   vat_json_init_object (node);
10059   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10060   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10061                              sizeof (mp->vss_type));
10062   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10063                                    mp->vss_vpn_ascii_id);
10064   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10065   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10066
10067   if (mp->is_ipv6)
10068     {
10069       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10070       vat_json_object_add_ip6 (node, "src_address", ip6);
10071     }
10072   else
10073     {
10074       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10075       vat_json_object_add_ip4 (node, "src_address", ip4);
10076     }
10077
10078   for (i = 0; i < count; i++)
10079     {
10080       s = &mp->servers[i];
10081
10082       vat_json_object_add_uint (node, "server-table-id",
10083                                 ntohl (s->server_vrf_id));
10084
10085       if (mp->is_ipv6)
10086         {
10087           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10088           vat_json_object_add_ip4 (node, "src_address", ip4);
10089         }
10090       else
10091         {
10092           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10093           vat_json_object_add_ip6 (node, "server_address", ip6);
10094         }
10095     }
10096 }
10097
10098 static int
10099 api_dhcp_proxy_dump (vat_main_t * vam)
10100 {
10101   unformat_input_t *i = vam->input;
10102   vl_api_control_ping_t *mp_ping;
10103   vl_api_dhcp_proxy_dump_t *mp;
10104   u8 is_ipv6 = 0;
10105   int ret;
10106
10107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10108     {
10109       if (unformat (i, "ipv6"))
10110         is_ipv6 = 1;
10111       else
10112         {
10113           clib_warning ("parse error '%U'", format_unformat_error, i);
10114           return -99;
10115         }
10116     }
10117
10118   M (DHCP_PROXY_DUMP, mp);
10119
10120   mp->is_ip6 = is_ipv6;
10121   S (mp);
10122
10123   /* Use a control ping for synchronization */
10124   MPING (CONTROL_PING, mp_ping);
10125   S (mp_ping);
10126
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_dhcp_proxy_set_vss (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_dhcp_proxy_set_vss_t *mp;
10136   u8 is_ipv6 = 0;
10137   u8 is_add = 1;
10138   u32 tbl_id = ~0;
10139   u8 vss_type = VSS_TYPE_DEFAULT;
10140   u8 *vpn_ascii_id = 0;
10141   u32 oui = 0;
10142   u32 fib_id = 0;
10143   int ret;
10144
10145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (i, "tbl_id %d", &tbl_id))
10148         ;
10149       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10150         vss_type = VSS_TYPE_ASCII;
10151       else if (unformat (i, "fib_id %d", &fib_id))
10152         vss_type = VSS_TYPE_VPN_ID;
10153       else if (unformat (i, "oui %d", &oui))
10154         vss_type = VSS_TYPE_VPN_ID;
10155       else if (unformat (i, "ipv6"))
10156         is_ipv6 = 1;
10157       else if (unformat (i, "del"))
10158         is_add = 0;
10159       else
10160         break;
10161     }
10162
10163   if (tbl_id == ~0)
10164     {
10165       errmsg ("missing tbl_id ");
10166       vec_free (vpn_ascii_id);
10167       return -99;
10168     }
10169
10170   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10171     {
10172       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10173       vec_free (vpn_ascii_id);
10174       return -99;
10175     }
10176
10177   M (DHCP_PROXY_SET_VSS, mp);
10178   mp->tbl_id = ntohl (tbl_id);
10179   mp->vss_type = vss_type;
10180   if (vpn_ascii_id)
10181     {
10182       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10183       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10184     }
10185   mp->vpn_index = ntohl (fib_id);
10186   mp->oui = ntohl (oui);
10187   mp->is_ipv6 = is_ipv6;
10188   mp->is_add = is_add;
10189
10190   S (mp);
10191   W (ret);
10192
10193   vec_free (vpn_ascii_id);
10194   return ret;
10195 }
10196
10197 static int
10198 api_dhcp_client_config (vat_main_t * vam)
10199 {
10200   unformat_input_t *i = vam->input;
10201   vl_api_dhcp_client_config_t *mp;
10202   u32 sw_if_index;
10203   u8 sw_if_index_set = 0;
10204   u8 is_add = 1;
10205   u8 *hostname = 0;
10206   u8 disable_event = 0;
10207   int ret;
10208
10209   /* Parse args required to build the message */
10210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10211     {
10212       if (unformat (i, "del"))
10213         is_add = 0;
10214       else
10215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10216         sw_if_index_set = 1;
10217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10218         sw_if_index_set = 1;
10219       else if (unformat (i, "hostname %s", &hostname))
10220         ;
10221       else if (unformat (i, "disable_event"))
10222         disable_event = 1;
10223       else
10224         break;
10225     }
10226
10227   if (sw_if_index_set == 0)
10228     {
10229       errmsg ("missing interface name or sw_if_index");
10230       return -99;
10231     }
10232
10233   if (vec_len (hostname) > 63)
10234     {
10235       errmsg ("hostname too long");
10236     }
10237   vec_add1 (hostname, 0);
10238
10239   /* Construct the API message */
10240   M (DHCP_CLIENT_CONFIG, mp);
10241
10242   mp->sw_if_index = htonl (sw_if_index);
10243   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10244   vec_free (hostname);
10245   mp->is_add = is_add;
10246   mp->want_dhcp_event = disable_event ? 0 : 1;
10247   mp->pid = htonl (getpid ());
10248
10249   /* send it... */
10250   S (mp);
10251
10252   /* Wait for a reply, return good/bad news  */
10253   W (ret);
10254   return ret;
10255 }
10256
10257 static int
10258 api_set_ip_flow_hash (vat_main_t * vam)
10259 {
10260   unformat_input_t *i = vam->input;
10261   vl_api_set_ip_flow_hash_t *mp;
10262   u32 vrf_id = 0;
10263   u8 is_ipv6 = 0;
10264   u8 vrf_id_set = 0;
10265   u8 src = 0;
10266   u8 dst = 0;
10267   u8 sport = 0;
10268   u8 dport = 0;
10269   u8 proto = 0;
10270   u8 reverse = 0;
10271   int ret;
10272
10273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10274     {
10275       if (unformat (i, "vrf %d", &vrf_id))
10276         vrf_id_set = 1;
10277       else if (unformat (i, "ipv6"))
10278         is_ipv6 = 1;
10279       else if (unformat (i, "src"))
10280         src = 1;
10281       else if (unformat (i, "dst"))
10282         dst = 1;
10283       else if (unformat (i, "sport"))
10284         sport = 1;
10285       else if (unformat (i, "dport"))
10286         dport = 1;
10287       else if (unformat (i, "proto"))
10288         proto = 1;
10289       else if (unformat (i, "reverse"))
10290         reverse = 1;
10291
10292       else
10293         {
10294           clib_warning ("parse error '%U'", format_unformat_error, i);
10295           return -99;
10296         }
10297     }
10298
10299   if (vrf_id_set == 0)
10300     {
10301       errmsg ("missing vrf id");
10302       return -99;
10303     }
10304
10305   M (SET_IP_FLOW_HASH, mp);
10306   mp->src = src;
10307   mp->dst = dst;
10308   mp->sport = sport;
10309   mp->dport = dport;
10310   mp->proto = proto;
10311   mp->reverse = reverse;
10312   mp->vrf_id = ntohl (vrf_id);
10313   mp->is_ipv6 = is_ipv6;
10314
10315   S (mp);
10316   W (ret);
10317   return ret;
10318 }
10319
10320 static int
10321 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10322 {
10323   unformat_input_t *i = vam->input;
10324   vl_api_sw_interface_ip6_enable_disable_t *mp;
10325   u32 sw_if_index;
10326   u8 sw_if_index_set = 0;
10327   u8 enable = 0;
10328   int ret;
10329
10330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10333         sw_if_index_set = 1;
10334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10335         sw_if_index_set = 1;
10336       else if (unformat (i, "enable"))
10337         enable = 1;
10338       else if (unformat (i, "disable"))
10339         enable = 0;
10340       else
10341         {
10342           clib_warning ("parse error '%U'", format_unformat_error, i);
10343           return -99;
10344         }
10345     }
10346
10347   if (sw_if_index_set == 0)
10348     {
10349       errmsg ("missing interface name or sw_if_index");
10350       return -99;
10351     }
10352
10353   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10354
10355   mp->sw_if_index = ntohl (sw_if_index);
10356   mp->enable = enable;
10357
10358   S (mp);
10359   W (ret);
10360   return ret;
10361 }
10362
10363 static int
10364 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10365 {
10366   unformat_input_t *i = vam->input;
10367   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10368   u32 sw_if_index;
10369   u8 sw_if_index_set = 0;
10370   u8 v6_address_set = 0;
10371   ip6_address_t v6address;
10372   int ret;
10373
10374   /* Parse args required to build the message */
10375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10376     {
10377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10378         sw_if_index_set = 1;
10379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10380         sw_if_index_set = 1;
10381       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10382         v6_address_set = 1;
10383       else
10384         break;
10385     }
10386
10387   if (sw_if_index_set == 0)
10388     {
10389       errmsg ("missing interface name or sw_if_index");
10390       return -99;
10391     }
10392   if (!v6_address_set)
10393     {
10394       errmsg ("no address set");
10395       return -99;
10396     }
10397
10398   /* Construct the API message */
10399   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10400
10401   mp->sw_if_index = ntohl (sw_if_index);
10402   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10403
10404   /* send it... */
10405   S (mp);
10406
10407   /* Wait for a reply, return good/bad news  */
10408   W (ret);
10409   return ret;
10410 }
10411
10412 static int
10413 api_ip6nd_proxy_add_del (vat_main_t * vam)
10414 {
10415   unformat_input_t *i = vam->input;
10416   vl_api_ip6nd_proxy_add_del_t *mp;
10417   u32 sw_if_index = ~0;
10418   u8 v6_address_set = 0;
10419   ip6_address_t v6address;
10420   u8 is_del = 0;
10421   int ret;
10422
10423   /* Parse args required to build the message */
10424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10425     {
10426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10427         ;
10428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10429         ;
10430       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10431         v6_address_set = 1;
10432       if (unformat (i, "del"))
10433         is_del = 1;
10434       else
10435         {
10436           clib_warning ("parse error '%U'", format_unformat_error, i);
10437           return -99;
10438         }
10439     }
10440
10441   if (sw_if_index == ~0)
10442     {
10443       errmsg ("missing interface name or sw_if_index");
10444       return -99;
10445     }
10446   if (!v6_address_set)
10447     {
10448       errmsg ("no address set");
10449       return -99;
10450     }
10451
10452   /* Construct the API message */
10453   M (IP6ND_PROXY_ADD_DEL, mp);
10454
10455   mp->is_del = is_del;
10456   mp->sw_if_index = ntohl (sw_if_index);
10457   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10458
10459   /* send it... */
10460   S (mp);
10461
10462   /* Wait for a reply, return good/bad news  */
10463   W (ret);
10464   return ret;
10465 }
10466
10467 static int
10468 api_ip6nd_proxy_dump (vat_main_t * vam)
10469 {
10470   vl_api_ip6nd_proxy_dump_t *mp;
10471   vl_api_control_ping_t *mp_ping;
10472   int ret;
10473
10474   M (IP6ND_PROXY_DUMP, mp);
10475
10476   S (mp);
10477
10478   /* Use a control ping for synchronization */
10479   MPING (CONTROL_PING, mp_ping);
10480   S (mp_ping);
10481
10482   W (ret);
10483   return ret;
10484 }
10485
10486 static void vl_api_ip6nd_proxy_details_t_handler
10487   (vl_api_ip6nd_proxy_details_t * mp)
10488 {
10489   vat_main_t *vam = &vat_main;
10490
10491   print (vam->ofp, "host %U sw_if_index %d",
10492          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10493 }
10494
10495 static void vl_api_ip6nd_proxy_details_t_handler_json
10496   (vl_api_ip6nd_proxy_details_t * mp)
10497 {
10498   vat_main_t *vam = &vat_main;
10499   struct in6_addr ip6;
10500   vat_json_node_t *node = NULL;
10501
10502   if (VAT_JSON_ARRAY != vam->json_tree.type)
10503     {
10504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10505       vat_json_init_array (&vam->json_tree);
10506     }
10507   node = vat_json_array_add (&vam->json_tree);
10508
10509   vat_json_init_object (node);
10510   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10511
10512   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10513   vat_json_object_add_ip6 (node, "host", ip6);
10514 }
10515
10516 static int
10517 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10518 {
10519   unformat_input_t *i = vam->input;
10520   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10521   u32 sw_if_index;
10522   u8 sw_if_index_set = 0;
10523   u32 address_length = 0;
10524   u8 v6_address_set = 0;
10525   ip6_address_t v6address;
10526   u8 use_default = 0;
10527   u8 no_advertise = 0;
10528   u8 off_link = 0;
10529   u8 no_autoconfig = 0;
10530   u8 no_onlink = 0;
10531   u8 is_no = 0;
10532   u32 val_lifetime = 0;
10533   u32 pref_lifetime = 0;
10534   int ret;
10535
10536   /* Parse args required to build the message */
10537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10538     {
10539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10540         sw_if_index_set = 1;
10541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10542         sw_if_index_set = 1;
10543       else if (unformat (i, "%U/%d",
10544                          unformat_ip6_address, &v6address, &address_length))
10545         v6_address_set = 1;
10546       else if (unformat (i, "val_life %d", &val_lifetime))
10547         ;
10548       else if (unformat (i, "pref_life %d", &pref_lifetime))
10549         ;
10550       else if (unformat (i, "def"))
10551         use_default = 1;
10552       else if (unformat (i, "noadv"))
10553         no_advertise = 1;
10554       else if (unformat (i, "offl"))
10555         off_link = 1;
10556       else if (unformat (i, "noauto"))
10557         no_autoconfig = 1;
10558       else if (unformat (i, "nolink"))
10559         no_onlink = 1;
10560       else if (unformat (i, "isno"))
10561         is_no = 1;
10562       else
10563         {
10564           clib_warning ("parse error '%U'", format_unformat_error, i);
10565           return -99;
10566         }
10567     }
10568
10569   if (sw_if_index_set == 0)
10570     {
10571       errmsg ("missing interface name or sw_if_index");
10572       return -99;
10573     }
10574   if (!v6_address_set)
10575     {
10576       errmsg ("no address set");
10577       return -99;
10578     }
10579
10580   /* Construct the API message */
10581   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10582
10583   mp->sw_if_index = ntohl (sw_if_index);
10584   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10585   mp->address_length = address_length;
10586   mp->use_default = use_default;
10587   mp->no_advertise = no_advertise;
10588   mp->off_link = off_link;
10589   mp->no_autoconfig = no_autoconfig;
10590   mp->no_onlink = no_onlink;
10591   mp->is_no = is_no;
10592   mp->val_lifetime = ntohl (val_lifetime);
10593   mp->pref_lifetime = ntohl (pref_lifetime);
10594
10595   /* send it... */
10596   S (mp);
10597
10598   /* Wait for a reply, return good/bad news  */
10599   W (ret);
10600   return ret;
10601 }
10602
10603 static int
10604 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10605 {
10606   unformat_input_t *i = vam->input;
10607   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10608   u32 sw_if_index;
10609   u8 sw_if_index_set = 0;
10610   u8 suppress = 0;
10611   u8 managed = 0;
10612   u8 other = 0;
10613   u8 ll_option = 0;
10614   u8 send_unicast = 0;
10615   u8 cease = 0;
10616   u8 is_no = 0;
10617   u8 default_router = 0;
10618   u32 max_interval = 0;
10619   u32 min_interval = 0;
10620   u32 lifetime = 0;
10621   u32 initial_count = 0;
10622   u32 initial_interval = 0;
10623   int ret;
10624
10625
10626   /* Parse args required to build the message */
10627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10628     {
10629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10630         sw_if_index_set = 1;
10631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10632         sw_if_index_set = 1;
10633       else if (unformat (i, "maxint %d", &max_interval))
10634         ;
10635       else if (unformat (i, "minint %d", &min_interval))
10636         ;
10637       else if (unformat (i, "life %d", &lifetime))
10638         ;
10639       else if (unformat (i, "count %d", &initial_count))
10640         ;
10641       else if (unformat (i, "interval %d", &initial_interval))
10642         ;
10643       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10644         suppress = 1;
10645       else if (unformat (i, "managed"))
10646         managed = 1;
10647       else if (unformat (i, "other"))
10648         other = 1;
10649       else if (unformat (i, "ll"))
10650         ll_option = 1;
10651       else if (unformat (i, "send"))
10652         send_unicast = 1;
10653       else if (unformat (i, "cease"))
10654         cease = 1;
10655       else if (unformat (i, "isno"))
10656         is_no = 1;
10657       else if (unformat (i, "def"))
10658         default_router = 1;
10659       else
10660         {
10661           clib_warning ("parse error '%U'", format_unformat_error, i);
10662           return -99;
10663         }
10664     }
10665
10666   if (sw_if_index_set == 0)
10667     {
10668       errmsg ("missing interface name or sw_if_index");
10669       return -99;
10670     }
10671
10672   /* Construct the API message */
10673   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10674
10675   mp->sw_if_index = ntohl (sw_if_index);
10676   mp->max_interval = ntohl (max_interval);
10677   mp->min_interval = ntohl (min_interval);
10678   mp->lifetime = ntohl (lifetime);
10679   mp->initial_count = ntohl (initial_count);
10680   mp->initial_interval = ntohl (initial_interval);
10681   mp->suppress = suppress;
10682   mp->managed = managed;
10683   mp->other = other;
10684   mp->ll_option = ll_option;
10685   mp->send_unicast = send_unicast;
10686   mp->cease = cease;
10687   mp->is_no = is_no;
10688   mp->default_router = default_router;
10689
10690   /* send it... */
10691   S (mp);
10692
10693   /* Wait for a reply, return good/bad news  */
10694   W (ret);
10695   return ret;
10696 }
10697
10698 static int
10699 api_set_arp_neighbor_limit (vat_main_t * vam)
10700 {
10701   unformat_input_t *i = vam->input;
10702   vl_api_set_arp_neighbor_limit_t *mp;
10703   u32 arp_nbr_limit;
10704   u8 limit_set = 0;
10705   u8 is_ipv6 = 0;
10706   int ret;
10707
10708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10709     {
10710       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10711         limit_set = 1;
10712       else if (unformat (i, "ipv6"))
10713         is_ipv6 = 1;
10714       else
10715         {
10716           clib_warning ("parse error '%U'", format_unformat_error, i);
10717           return -99;
10718         }
10719     }
10720
10721   if (limit_set == 0)
10722     {
10723       errmsg ("missing limit value");
10724       return -99;
10725     }
10726
10727   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10728
10729   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10730   mp->is_ipv6 = is_ipv6;
10731
10732   S (mp);
10733   W (ret);
10734   return ret;
10735 }
10736
10737 static int
10738 api_l2_patch_add_del (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_l2_patch_add_del_t *mp;
10742   u32 rx_sw_if_index;
10743   u8 rx_sw_if_index_set = 0;
10744   u32 tx_sw_if_index;
10745   u8 tx_sw_if_index_set = 0;
10746   u8 is_add = 1;
10747   int ret;
10748
10749   /* Parse args required to build the message */
10750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10751     {
10752       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10753         rx_sw_if_index_set = 1;
10754       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10755         tx_sw_if_index_set = 1;
10756       else if (unformat (i, "rx"))
10757         {
10758           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10759             {
10760               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10761                             &rx_sw_if_index))
10762                 rx_sw_if_index_set = 1;
10763             }
10764           else
10765             break;
10766         }
10767       else if (unformat (i, "tx"))
10768         {
10769           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10770             {
10771               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10772                             &tx_sw_if_index))
10773                 tx_sw_if_index_set = 1;
10774             }
10775           else
10776             break;
10777         }
10778       else if (unformat (i, "del"))
10779         is_add = 0;
10780       else
10781         break;
10782     }
10783
10784   if (rx_sw_if_index_set == 0)
10785     {
10786       errmsg ("missing rx interface name or rx_sw_if_index");
10787       return -99;
10788     }
10789
10790   if (tx_sw_if_index_set == 0)
10791     {
10792       errmsg ("missing tx interface name or tx_sw_if_index");
10793       return -99;
10794     }
10795
10796   M (L2_PATCH_ADD_DEL, mp);
10797
10798   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10799   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10800   mp->is_add = is_add;
10801
10802   S (mp);
10803   W (ret);
10804   return ret;
10805 }
10806
10807 u8 is_del;
10808 u8 localsid_addr[16];
10809 u8 end_psp;
10810 u8 behavior;
10811 u32 sw_if_index;
10812 u32 vlan_index;
10813 u32 fib_table;
10814 u8 nh_addr[16];
10815
10816 static int
10817 api_sr_localsid_add_del (vat_main_t * vam)
10818 {
10819   unformat_input_t *i = vam->input;
10820   vl_api_sr_localsid_add_del_t *mp;
10821
10822   u8 is_del;
10823   ip6_address_t localsid;
10824   u8 end_psp = 0;
10825   u8 behavior = ~0;
10826   u32 sw_if_index;
10827   u32 fib_table = ~(u32) 0;
10828   ip6_address_t next_hop;
10829
10830   bool nexthop_set = 0;
10831
10832   int ret;
10833
10834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10835     {
10836       if (unformat (i, "del"))
10837         is_del = 1;
10838       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10839       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10840         nexthop_set = 1;
10841       else if (unformat (i, "behavior %u", &behavior));
10842       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10843       else if (unformat (i, "fib-table %u", &fib_table));
10844       else if (unformat (i, "end.psp %u", &behavior));
10845       else
10846         break;
10847     }
10848
10849   M (SR_LOCALSID_ADD_DEL, mp);
10850
10851   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10852   if (nexthop_set)
10853     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10854   mp->behavior = behavior;
10855   mp->sw_if_index = ntohl (sw_if_index);
10856   mp->fib_table = ntohl (fib_table);
10857   mp->end_psp = end_psp;
10858   mp->is_del = is_del;
10859
10860   S (mp);
10861   W (ret);
10862   return ret;
10863 }
10864
10865 static int
10866 api_ioam_enable (vat_main_t * vam)
10867 {
10868   unformat_input_t *input = vam->input;
10869   vl_api_ioam_enable_t *mp;
10870   u32 id = 0;
10871   int has_trace_option = 0;
10872   int has_pot_option = 0;
10873   int has_seqno_option = 0;
10874   int has_analyse_option = 0;
10875   int ret;
10876
10877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (unformat (input, "trace"))
10880         has_trace_option = 1;
10881       else if (unformat (input, "pot"))
10882         has_pot_option = 1;
10883       else if (unformat (input, "seqno"))
10884         has_seqno_option = 1;
10885       else if (unformat (input, "analyse"))
10886         has_analyse_option = 1;
10887       else
10888         break;
10889     }
10890   M (IOAM_ENABLE, mp);
10891   mp->id = htons (id);
10892   mp->seqno = has_seqno_option;
10893   mp->analyse = has_analyse_option;
10894   mp->pot_enable = has_pot_option;
10895   mp->trace_enable = has_trace_option;
10896
10897   S (mp);
10898   W (ret);
10899   return ret;
10900 }
10901
10902
10903 static int
10904 api_ioam_disable (vat_main_t * vam)
10905 {
10906   vl_api_ioam_disable_t *mp;
10907   int ret;
10908
10909   M (IOAM_DISABLE, mp);
10910   S (mp);
10911   W (ret);
10912   return ret;
10913 }
10914
10915 #define foreach_tcp_proto_field                 \
10916 _(src_port)                                     \
10917 _(dst_port)
10918
10919 #define foreach_udp_proto_field                 \
10920 _(src_port)                                     \
10921 _(dst_port)
10922
10923 #define foreach_ip4_proto_field                 \
10924 _(src_address)                                  \
10925 _(dst_address)                                  \
10926 _(tos)                                          \
10927 _(length)                                       \
10928 _(fragment_id)                                  \
10929 _(ttl)                                          \
10930 _(protocol)                                     \
10931 _(checksum)
10932
10933 typedef struct
10934 {
10935   u16 src_port, dst_port;
10936 } tcpudp_header_t;
10937
10938 #if VPP_API_TEST_BUILTIN == 0
10939 uword
10940 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10941 {
10942   u8 **maskp = va_arg (*args, u8 **);
10943   u8 *mask = 0;
10944   u8 found_something = 0;
10945   tcp_header_t *tcp;
10946
10947 #define _(a) u8 a=0;
10948   foreach_tcp_proto_field;
10949 #undef _
10950
10951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10952     {
10953       if (0);
10954 #define _(a) else if (unformat (input, #a)) a=1;
10955       foreach_tcp_proto_field
10956 #undef _
10957         else
10958         break;
10959     }
10960
10961 #define _(a) found_something += a;
10962   foreach_tcp_proto_field;
10963 #undef _
10964
10965   if (found_something == 0)
10966     return 0;
10967
10968   vec_validate (mask, sizeof (*tcp) - 1);
10969
10970   tcp = (tcp_header_t *) mask;
10971
10972 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10973   foreach_tcp_proto_field;
10974 #undef _
10975
10976   *maskp = mask;
10977   return 1;
10978 }
10979
10980 uword
10981 unformat_udp_mask (unformat_input_t * input, va_list * args)
10982 {
10983   u8 **maskp = va_arg (*args, u8 **);
10984   u8 *mask = 0;
10985   u8 found_something = 0;
10986   udp_header_t *udp;
10987
10988 #define _(a) u8 a=0;
10989   foreach_udp_proto_field;
10990 #undef _
10991
10992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10993     {
10994       if (0);
10995 #define _(a) else if (unformat (input, #a)) a=1;
10996       foreach_udp_proto_field
10997 #undef _
10998         else
10999         break;
11000     }
11001
11002 #define _(a) found_something += a;
11003   foreach_udp_proto_field;
11004 #undef _
11005
11006   if (found_something == 0)
11007     return 0;
11008
11009   vec_validate (mask, sizeof (*udp) - 1);
11010
11011   udp = (udp_header_t *) mask;
11012
11013 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11014   foreach_udp_proto_field;
11015 #undef _
11016
11017   *maskp = mask;
11018   return 1;
11019 }
11020
11021 uword
11022 unformat_l4_mask (unformat_input_t * input, va_list * args)
11023 {
11024   u8 **maskp = va_arg (*args, u8 **);
11025   u16 src_port = 0, dst_port = 0;
11026   tcpudp_header_t *tcpudp;
11027
11028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11031         return 1;
11032       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11033         return 1;
11034       else if (unformat (input, "src_port"))
11035         src_port = 0xFFFF;
11036       else if (unformat (input, "dst_port"))
11037         dst_port = 0xFFFF;
11038       else
11039         return 0;
11040     }
11041
11042   if (!src_port && !dst_port)
11043     return 0;
11044
11045   u8 *mask = 0;
11046   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11047
11048   tcpudp = (tcpudp_header_t *) mask;
11049   tcpudp->src_port = src_port;
11050   tcpudp->dst_port = dst_port;
11051
11052   *maskp = mask;
11053
11054   return 1;
11055 }
11056
11057 uword
11058 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11059 {
11060   u8 **maskp = va_arg (*args, u8 **);
11061   u8 *mask = 0;
11062   u8 found_something = 0;
11063   ip4_header_t *ip;
11064
11065 #define _(a) u8 a=0;
11066   foreach_ip4_proto_field;
11067 #undef _
11068   u8 version = 0;
11069   u8 hdr_length = 0;
11070
11071
11072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11073     {
11074       if (unformat (input, "version"))
11075         version = 1;
11076       else if (unformat (input, "hdr_length"))
11077         hdr_length = 1;
11078       else if (unformat (input, "src"))
11079         src_address = 1;
11080       else if (unformat (input, "dst"))
11081         dst_address = 1;
11082       else if (unformat (input, "proto"))
11083         protocol = 1;
11084
11085 #define _(a) else if (unformat (input, #a)) a=1;
11086       foreach_ip4_proto_field
11087 #undef _
11088         else
11089         break;
11090     }
11091
11092 #define _(a) found_something += a;
11093   foreach_ip4_proto_field;
11094 #undef _
11095
11096   if (found_something == 0)
11097     return 0;
11098
11099   vec_validate (mask, sizeof (*ip) - 1);
11100
11101   ip = (ip4_header_t *) mask;
11102
11103 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11104   foreach_ip4_proto_field;
11105 #undef _
11106
11107   ip->ip_version_and_header_length = 0;
11108
11109   if (version)
11110     ip->ip_version_and_header_length |= 0xF0;
11111
11112   if (hdr_length)
11113     ip->ip_version_and_header_length |= 0x0F;
11114
11115   *maskp = mask;
11116   return 1;
11117 }
11118
11119 #define foreach_ip6_proto_field                 \
11120 _(src_address)                                  \
11121 _(dst_address)                                  \
11122 _(payload_length)                               \
11123 _(hop_limit)                                    \
11124 _(protocol)
11125
11126 uword
11127 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11128 {
11129   u8 **maskp = va_arg (*args, u8 **);
11130   u8 *mask = 0;
11131   u8 found_something = 0;
11132   ip6_header_t *ip;
11133   u32 ip_version_traffic_class_and_flow_label;
11134
11135 #define _(a) u8 a=0;
11136   foreach_ip6_proto_field;
11137 #undef _
11138   u8 version = 0;
11139   u8 traffic_class = 0;
11140   u8 flow_label = 0;
11141
11142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11143     {
11144       if (unformat (input, "version"))
11145         version = 1;
11146       else if (unformat (input, "traffic-class"))
11147         traffic_class = 1;
11148       else if (unformat (input, "flow-label"))
11149         flow_label = 1;
11150       else if (unformat (input, "src"))
11151         src_address = 1;
11152       else if (unformat (input, "dst"))
11153         dst_address = 1;
11154       else if (unformat (input, "proto"))
11155         protocol = 1;
11156
11157 #define _(a) else if (unformat (input, #a)) a=1;
11158       foreach_ip6_proto_field
11159 #undef _
11160         else
11161         break;
11162     }
11163
11164 #define _(a) found_something += a;
11165   foreach_ip6_proto_field;
11166 #undef _
11167
11168   if (found_something == 0)
11169     return 0;
11170
11171   vec_validate (mask, sizeof (*ip) - 1);
11172
11173   ip = (ip6_header_t *) mask;
11174
11175 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11176   foreach_ip6_proto_field;
11177 #undef _
11178
11179   ip_version_traffic_class_and_flow_label = 0;
11180
11181   if (version)
11182     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11183
11184   if (traffic_class)
11185     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11186
11187   if (flow_label)
11188     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11189
11190   ip->ip_version_traffic_class_and_flow_label =
11191     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11192
11193   *maskp = mask;
11194   return 1;
11195 }
11196
11197 uword
11198 unformat_l3_mask (unformat_input_t * input, va_list * args)
11199 {
11200   u8 **maskp = va_arg (*args, u8 **);
11201
11202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11205         return 1;
11206       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11207         return 1;
11208       else
11209         break;
11210     }
11211   return 0;
11212 }
11213
11214 uword
11215 unformat_l2_mask (unformat_input_t * input, va_list * args)
11216 {
11217   u8 **maskp = va_arg (*args, u8 **);
11218   u8 *mask = 0;
11219   u8 src = 0;
11220   u8 dst = 0;
11221   u8 proto = 0;
11222   u8 tag1 = 0;
11223   u8 tag2 = 0;
11224   u8 ignore_tag1 = 0;
11225   u8 ignore_tag2 = 0;
11226   u8 cos1 = 0;
11227   u8 cos2 = 0;
11228   u8 dot1q = 0;
11229   u8 dot1ad = 0;
11230   int len = 14;
11231
11232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11233     {
11234       if (unformat (input, "src"))
11235         src = 1;
11236       else if (unformat (input, "dst"))
11237         dst = 1;
11238       else if (unformat (input, "proto"))
11239         proto = 1;
11240       else if (unformat (input, "tag1"))
11241         tag1 = 1;
11242       else if (unformat (input, "tag2"))
11243         tag2 = 1;
11244       else if (unformat (input, "ignore-tag1"))
11245         ignore_tag1 = 1;
11246       else if (unformat (input, "ignore-tag2"))
11247         ignore_tag2 = 1;
11248       else if (unformat (input, "cos1"))
11249         cos1 = 1;
11250       else if (unformat (input, "cos2"))
11251         cos2 = 1;
11252       else if (unformat (input, "dot1q"))
11253         dot1q = 1;
11254       else if (unformat (input, "dot1ad"))
11255         dot1ad = 1;
11256       else
11257         break;
11258     }
11259   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11260        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11261     return 0;
11262
11263   if (tag1 || ignore_tag1 || cos1 || dot1q)
11264     len = 18;
11265   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11266     len = 22;
11267
11268   vec_validate (mask, len - 1);
11269
11270   if (dst)
11271     memset (mask, 0xff, 6);
11272
11273   if (src)
11274     memset (mask + 6, 0xff, 6);
11275
11276   if (tag2 || dot1ad)
11277     {
11278       /* inner vlan tag */
11279       if (tag2)
11280         {
11281           mask[19] = 0xff;
11282           mask[18] = 0x0f;
11283         }
11284       if (cos2)
11285         mask[18] |= 0xe0;
11286       if (proto)
11287         mask[21] = mask[20] = 0xff;
11288       if (tag1)
11289         {
11290           mask[15] = 0xff;
11291           mask[14] = 0x0f;
11292         }
11293       if (cos1)
11294         mask[14] |= 0xe0;
11295       *maskp = mask;
11296       return 1;
11297     }
11298   if (tag1 | dot1q)
11299     {
11300       if (tag1)
11301         {
11302           mask[15] = 0xff;
11303           mask[14] = 0x0f;
11304         }
11305       if (cos1)
11306         mask[14] |= 0xe0;
11307       if (proto)
11308         mask[16] = mask[17] = 0xff;
11309
11310       *maskp = mask;
11311       return 1;
11312     }
11313   if (cos2)
11314     mask[18] |= 0xe0;
11315   if (cos1)
11316     mask[14] |= 0xe0;
11317   if (proto)
11318     mask[12] = mask[13] = 0xff;
11319
11320   *maskp = mask;
11321   return 1;
11322 }
11323
11324 uword
11325 unformat_classify_mask (unformat_input_t * input, va_list * args)
11326 {
11327   u8 **maskp = va_arg (*args, u8 **);
11328   u32 *skipp = va_arg (*args, u32 *);
11329   u32 *matchp = va_arg (*args, u32 *);
11330   u32 match;
11331   u8 *mask = 0;
11332   u8 *l2 = 0;
11333   u8 *l3 = 0;
11334   u8 *l4 = 0;
11335   int i;
11336
11337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11338     {
11339       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11340         ;
11341       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11342         ;
11343       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11344         ;
11345       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11346         ;
11347       else
11348         break;
11349     }
11350
11351   if (l4 && !l3)
11352     {
11353       vec_free (mask);
11354       vec_free (l2);
11355       vec_free (l4);
11356       return 0;
11357     }
11358
11359   if (mask || l2 || l3 || l4)
11360     {
11361       if (l2 || l3 || l4)
11362         {
11363           /* "With a free Ethernet header in every package" */
11364           if (l2 == 0)
11365             vec_validate (l2, 13);
11366           mask = l2;
11367           if (vec_len (l3))
11368             {
11369               vec_append (mask, l3);
11370               vec_free (l3);
11371             }
11372           if (vec_len (l4))
11373             {
11374               vec_append (mask, l4);
11375               vec_free (l4);
11376             }
11377         }
11378
11379       /* Scan forward looking for the first significant mask octet */
11380       for (i = 0; i < vec_len (mask); i++)
11381         if (mask[i])
11382           break;
11383
11384       /* compute (skip, match) params */
11385       *skipp = i / sizeof (u32x4);
11386       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11387
11388       /* Pad mask to an even multiple of the vector size */
11389       while (vec_len (mask) % sizeof (u32x4))
11390         vec_add1 (mask, 0);
11391
11392       match = vec_len (mask) / sizeof (u32x4);
11393
11394       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11395         {
11396           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11397           if (*tmp || *(tmp + 1))
11398             break;
11399           match--;
11400         }
11401       if (match == 0)
11402         clib_warning ("BUG: match 0");
11403
11404       _vec_len (mask) = match * sizeof (u32x4);
11405
11406       *matchp = match;
11407       *maskp = mask;
11408
11409       return 1;
11410     }
11411
11412   return 0;
11413 }
11414 #endif /* VPP_API_TEST_BUILTIN */
11415
11416 #define foreach_l2_next                         \
11417 _(drop, DROP)                                   \
11418 _(ethernet, ETHERNET_INPUT)                     \
11419 _(ip4, IP4_INPUT)                               \
11420 _(ip6, IP6_INPUT)
11421
11422 uword
11423 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11424 {
11425   u32 *miss_next_indexp = va_arg (*args, u32 *);
11426   u32 next_index = 0;
11427   u32 tmp;
11428
11429 #define _(n,N) \
11430   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11431   foreach_l2_next;
11432 #undef _
11433
11434   if (unformat (input, "%d", &tmp))
11435     {
11436       next_index = tmp;
11437       goto out;
11438     }
11439
11440   return 0;
11441
11442 out:
11443   *miss_next_indexp = next_index;
11444   return 1;
11445 }
11446
11447 #define foreach_ip_next                         \
11448 _(drop, DROP)                                   \
11449 _(local, LOCAL)                                 \
11450 _(rewrite, REWRITE)
11451
11452 uword
11453 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11454 {
11455   u32 *miss_next_indexp = va_arg (*args, u32 *);
11456   u32 next_index = 0;
11457   u32 tmp;
11458
11459 #define _(n,N) \
11460   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11461   foreach_ip_next;
11462 #undef _
11463
11464   if (unformat (input, "%d", &tmp))
11465     {
11466       next_index = tmp;
11467       goto out;
11468     }
11469
11470   return 0;
11471
11472 out:
11473   *miss_next_indexp = next_index;
11474   return 1;
11475 }
11476
11477 #define foreach_acl_next                        \
11478 _(deny, DENY)
11479
11480 uword
11481 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11482 {
11483   u32 *miss_next_indexp = va_arg (*args, u32 *);
11484   u32 next_index = 0;
11485   u32 tmp;
11486
11487 #define _(n,N) \
11488   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11489   foreach_acl_next;
11490 #undef _
11491
11492   if (unformat (input, "permit"))
11493     {
11494       next_index = ~0;
11495       goto out;
11496     }
11497   else if (unformat (input, "%d", &tmp))
11498     {
11499       next_index = tmp;
11500       goto out;
11501     }
11502
11503   return 0;
11504
11505 out:
11506   *miss_next_indexp = next_index;
11507   return 1;
11508 }
11509
11510 uword
11511 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11512 {
11513   u32 *r = va_arg (*args, u32 *);
11514
11515   if (unformat (input, "conform-color"))
11516     *r = POLICE_CONFORM;
11517   else if (unformat (input, "exceed-color"))
11518     *r = POLICE_EXCEED;
11519   else
11520     return 0;
11521
11522   return 1;
11523 }
11524
11525 static int
11526 api_classify_add_del_table (vat_main_t * vam)
11527 {
11528   unformat_input_t *i = vam->input;
11529   vl_api_classify_add_del_table_t *mp;
11530
11531   u32 nbuckets = 2;
11532   u32 skip = ~0;
11533   u32 match = ~0;
11534   int is_add = 1;
11535   int del_chain = 0;
11536   u32 table_index = ~0;
11537   u32 next_table_index = ~0;
11538   u32 miss_next_index = ~0;
11539   u32 memory_size = 32 << 20;
11540   u8 *mask = 0;
11541   u32 current_data_flag = 0;
11542   int current_data_offset = 0;
11543   int ret;
11544
11545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11546     {
11547       if (unformat (i, "del"))
11548         is_add = 0;
11549       else if (unformat (i, "del-chain"))
11550         {
11551           is_add = 0;
11552           del_chain = 1;
11553         }
11554       else if (unformat (i, "buckets %d", &nbuckets))
11555         ;
11556       else if (unformat (i, "memory_size %d", &memory_size))
11557         ;
11558       else if (unformat (i, "skip %d", &skip))
11559         ;
11560       else if (unformat (i, "match %d", &match))
11561         ;
11562       else if (unformat (i, "table %d", &table_index))
11563         ;
11564       else if (unformat (i, "mask %U", unformat_classify_mask,
11565                          &mask, &skip, &match))
11566         ;
11567       else if (unformat (i, "next-table %d", &next_table_index))
11568         ;
11569       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11570                          &miss_next_index))
11571         ;
11572       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11573                          &miss_next_index))
11574         ;
11575       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11576                          &miss_next_index))
11577         ;
11578       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11579         ;
11580       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11581         ;
11582       else
11583         break;
11584     }
11585
11586   if (is_add && mask == 0)
11587     {
11588       errmsg ("Mask required");
11589       return -99;
11590     }
11591
11592   if (is_add && skip == ~0)
11593     {
11594       errmsg ("skip count required");
11595       return -99;
11596     }
11597
11598   if (is_add && match == ~0)
11599     {
11600       errmsg ("match count required");
11601       return -99;
11602     }
11603
11604   if (!is_add && table_index == ~0)
11605     {
11606       errmsg ("table index required for delete");
11607       return -99;
11608     }
11609
11610   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11611
11612   mp->is_add = is_add;
11613   mp->del_chain = del_chain;
11614   mp->table_index = ntohl (table_index);
11615   mp->nbuckets = ntohl (nbuckets);
11616   mp->memory_size = ntohl (memory_size);
11617   mp->skip_n_vectors = ntohl (skip);
11618   mp->match_n_vectors = ntohl (match);
11619   mp->next_table_index = ntohl (next_table_index);
11620   mp->miss_next_index = ntohl (miss_next_index);
11621   mp->current_data_flag = ntohl (current_data_flag);
11622   mp->current_data_offset = ntohl (current_data_offset);
11623   clib_memcpy (mp->mask, mask, vec_len (mask));
11624
11625   vec_free (mask);
11626
11627   S (mp);
11628   W (ret);
11629   return ret;
11630 }
11631
11632 #if VPP_API_TEST_BUILTIN == 0
11633 uword
11634 unformat_l4_match (unformat_input_t * input, va_list * args)
11635 {
11636   u8 **matchp = va_arg (*args, u8 **);
11637
11638   u8 *proto_header = 0;
11639   int src_port = 0;
11640   int dst_port = 0;
11641
11642   tcpudp_header_t h;
11643
11644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11645     {
11646       if (unformat (input, "src_port %d", &src_port))
11647         ;
11648       else if (unformat (input, "dst_port %d", &dst_port))
11649         ;
11650       else
11651         return 0;
11652     }
11653
11654   h.src_port = clib_host_to_net_u16 (src_port);
11655   h.dst_port = clib_host_to_net_u16 (dst_port);
11656   vec_validate (proto_header, sizeof (h) - 1);
11657   memcpy (proto_header, &h, sizeof (h));
11658
11659   *matchp = proto_header;
11660
11661   return 1;
11662 }
11663
11664 uword
11665 unformat_ip4_match (unformat_input_t * input, va_list * args)
11666 {
11667   u8 **matchp = va_arg (*args, u8 **);
11668   u8 *match = 0;
11669   ip4_header_t *ip;
11670   int version = 0;
11671   u32 version_val;
11672   int hdr_length = 0;
11673   u32 hdr_length_val;
11674   int src = 0, dst = 0;
11675   ip4_address_t src_val, dst_val;
11676   int proto = 0;
11677   u32 proto_val;
11678   int tos = 0;
11679   u32 tos_val;
11680   int length = 0;
11681   u32 length_val;
11682   int fragment_id = 0;
11683   u32 fragment_id_val;
11684   int ttl = 0;
11685   int ttl_val;
11686   int checksum = 0;
11687   u32 checksum_val;
11688
11689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11690     {
11691       if (unformat (input, "version %d", &version_val))
11692         version = 1;
11693       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11694         hdr_length = 1;
11695       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11696         src = 1;
11697       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11698         dst = 1;
11699       else if (unformat (input, "proto %d", &proto_val))
11700         proto = 1;
11701       else if (unformat (input, "tos %d", &tos_val))
11702         tos = 1;
11703       else if (unformat (input, "length %d", &length_val))
11704         length = 1;
11705       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11706         fragment_id = 1;
11707       else if (unformat (input, "ttl %d", &ttl_val))
11708         ttl = 1;
11709       else if (unformat (input, "checksum %d", &checksum_val))
11710         checksum = 1;
11711       else
11712         break;
11713     }
11714
11715   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11716       + ttl + checksum == 0)
11717     return 0;
11718
11719   /*
11720    * Aligned because we use the real comparison functions
11721    */
11722   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11723
11724   ip = (ip4_header_t *) match;
11725
11726   /* These are realistically matched in practice */
11727   if (src)
11728     ip->src_address.as_u32 = src_val.as_u32;
11729
11730   if (dst)
11731     ip->dst_address.as_u32 = dst_val.as_u32;
11732
11733   if (proto)
11734     ip->protocol = proto_val;
11735
11736
11737   /* These are not, but they're included for completeness */
11738   if (version)
11739     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11740
11741   if (hdr_length)
11742     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11743
11744   if (tos)
11745     ip->tos = tos_val;
11746
11747   if (length)
11748     ip->length = clib_host_to_net_u16 (length_val);
11749
11750   if (ttl)
11751     ip->ttl = ttl_val;
11752
11753   if (checksum)
11754     ip->checksum = clib_host_to_net_u16 (checksum_val);
11755
11756   *matchp = match;
11757   return 1;
11758 }
11759
11760 uword
11761 unformat_ip6_match (unformat_input_t * input, va_list * args)
11762 {
11763   u8 **matchp = va_arg (*args, u8 **);
11764   u8 *match = 0;
11765   ip6_header_t *ip;
11766   int version = 0;
11767   u32 version_val;
11768   u8 traffic_class = 0;
11769   u32 traffic_class_val = 0;
11770   u8 flow_label = 0;
11771   u8 flow_label_val;
11772   int src = 0, dst = 0;
11773   ip6_address_t src_val, dst_val;
11774   int proto = 0;
11775   u32 proto_val;
11776   int payload_length = 0;
11777   u32 payload_length_val;
11778   int hop_limit = 0;
11779   int hop_limit_val;
11780   u32 ip_version_traffic_class_and_flow_label;
11781
11782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11783     {
11784       if (unformat (input, "version %d", &version_val))
11785         version = 1;
11786       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11787         traffic_class = 1;
11788       else if (unformat (input, "flow_label %d", &flow_label_val))
11789         flow_label = 1;
11790       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11791         src = 1;
11792       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11793         dst = 1;
11794       else if (unformat (input, "proto %d", &proto_val))
11795         proto = 1;
11796       else if (unformat (input, "payload_length %d", &payload_length_val))
11797         payload_length = 1;
11798       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11799         hop_limit = 1;
11800       else
11801         break;
11802     }
11803
11804   if (version + traffic_class + flow_label + src + dst + proto +
11805       payload_length + hop_limit == 0)
11806     return 0;
11807
11808   /*
11809    * Aligned because we use the real comparison functions
11810    */
11811   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11812
11813   ip = (ip6_header_t *) match;
11814
11815   if (src)
11816     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11817
11818   if (dst)
11819     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11820
11821   if (proto)
11822     ip->protocol = proto_val;
11823
11824   ip_version_traffic_class_and_flow_label = 0;
11825
11826   if (version)
11827     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11828
11829   if (traffic_class)
11830     ip_version_traffic_class_and_flow_label |=
11831       (traffic_class_val & 0xFF) << 20;
11832
11833   if (flow_label)
11834     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11835
11836   ip->ip_version_traffic_class_and_flow_label =
11837     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11838
11839   if (payload_length)
11840     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11841
11842   if (hop_limit)
11843     ip->hop_limit = hop_limit_val;
11844
11845   *matchp = match;
11846   return 1;
11847 }
11848
11849 uword
11850 unformat_l3_match (unformat_input_t * input, va_list * args)
11851 {
11852   u8 **matchp = va_arg (*args, u8 **);
11853
11854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11857         return 1;
11858       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11859         return 1;
11860       else
11861         break;
11862     }
11863   return 0;
11864 }
11865
11866 uword
11867 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11868 {
11869   u8 *tagp = va_arg (*args, u8 *);
11870   u32 tag;
11871
11872   if (unformat (input, "%d", &tag))
11873     {
11874       tagp[0] = (tag >> 8) & 0x0F;
11875       tagp[1] = tag & 0xFF;
11876       return 1;
11877     }
11878
11879   return 0;
11880 }
11881
11882 uword
11883 unformat_l2_match (unformat_input_t * input, va_list * args)
11884 {
11885   u8 **matchp = va_arg (*args, u8 **);
11886   u8 *match = 0;
11887   u8 src = 0;
11888   u8 src_val[6];
11889   u8 dst = 0;
11890   u8 dst_val[6];
11891   u8 proto = 0;
11892   u16 proto_val;
11893   u8 tag1 = 0;
11894   u8 tag1_val[2];
11895   u8 tag2 = 0;
11896   u8 tag2_val[2];
11897   int len = 14;
11898   u8 ignore_tag1 = 0;
11899   u8 ignore_tag2 = 0;
11900   u8 cos1 = 0;
11901   u8 cos2 = 0;
11902   u32 cos1_val = 0;
11903   u32 cos2_val = 0;
11904
11905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11908         src = 1;
11909       else
11910         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11911         dst = 1;
11912       else if (unformat (input, "proto %U",
11913                          unformat_ethernet_type_host_byte_order, &proto_val))
11914         proto = 1;
11915       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11916         tag1 = 1;
11917       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11918         tag2 = 1;
11919       else if (unformat (input, "ignore-tag1"))
11920         ignore_tag1 = 1;
11921       else if (unformat (input, "ignore-tag2"))
11922         ignore_tag2 = 1;
11923       else if (unformat (input, "cos1 %d", &cos1_val))
11924         cos1 = 1;
11925       else if (unformat (input, "cos2 %d", &cos2_val))
11926         cos2 = 1;
11927       else
11928         break;
11929     }
11930   if ((src + dst + proto + tag1 + tag2 +
11931        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11932     return 0;
11933
11934   if (tag1 || ignore_tag1 || cos1)
11935     len = 18;
11936   if (tag2 || ignore_tag2 || cos2)
11937     len = 22;
11938
11939   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11940
11941   if (dst)
11942     clib_memcpy (match, dst_val, 6);
11943
11944   if (src)
11945     clib_memcpy (match + 6, src_val, 6);
11946
11947   if (tag2)
11948     {
11949       /* inner vlan tag */
11950       match[19] = tag2_val[1];
11951       match[18] = tag2_val[0];
11952       if (cos2)
11953         match[18] |= (cos2_val & 0x7) << 5;
11954       if (proto)
11955         {
11956           match[21] = proto_val & 0xff;
11957           match[20] = proto_val >> 8;
11958         }
11959       if (tag1)
11960         {
11961           match[15] = tag1_val[1];
11962           match[14] = tag1_val[0];
11963         }
11964       if (cos1)
11965         match[14] |= (cos1_val & 0x7) << 5;
11966       *matchp = match;
11967       return 1;
11968     }
11969   if (tag1)
11970     {
11971       match[15] = tag1_val[1];
11972       match[14] = tag1_val[0];
11973       if (proto)
11974         {
11975           match[17] = proto_val & 0xff;
11976           match[16] = proto_val >> 8;
11977         }
11978       if (cos1)
11979         match[14] |= (cos1_val & 0x7) << 5;
11980
11981       *matchp = match;
11982       return 1;
11983     }
11984   if (cos2)
11985     match[18] |= (cos2_val & 0x7) << 5;
11986   if (cos1)
11987     match[14] |= (cos1_val & 0x7) << 5;
11988   if (proto)
11989     {
11990       match[13] = proto_val & 0xff;
11991       match[12] = proto_val >> 8;
11992     }
11993
11994   *matchp = match;
11995   return 1;
11996 }
11997 #endif
11998
11999 uword
12000 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12001 {
12002   u8 **matchp = va_arg (*args, u8 **);
12003   u32 skip_n_vectors = va_arg (*args, u32);
12004   u32 match_n_vectors = va_arg (*args, u32);
12005
12006   u8 *match = 0;
12007   u8 *l2 = 0;
12008   u8 *l3 = 0;
12009   u8 *l4 = 0;
12010
12011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12012     {
12013       if (unformat (input, "hex %U", unformat_hex_string, &match))
12014         ;
12015       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12016         ;
12017       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12018         ;
12019       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12020         ;
12021       else
12022         break;
12023     }
12024
12025   if (l4 && !l3)
12026     {
12027       vec_free (match);
12028       vec_free (l2);
12029       vec_free (l4);
12030       return 0;
12031     }
12032
12033   if (match || l2 || l3 || l4)
12034     {
12035       if (l2 || l3 || l4)
12036         {
12037           /* "Win a free Ethernet header in every packet" */
12038           if (l2 == 0)
12039             vec_validate_aligned (l2, 13, sizeof (u32x4));
12040           match = l2;
12041           if (vec_len (l3))
12042             {
12043               vec_append_aligned (match, l3, sizeof (u32x4));
12044               vec_free (l3);
12045             }
12046           if (vec_len (l4))
12047             {
12048               vec_append_aligned (match, l4, sizeof (u32x4));
12049               vec_free (l4);
12050             }
12051         }
12052
12053       /* Make sure the vector is big enough even if key is all 0's */
12054       vec_validate_aligned
12055         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12056          sizeof (u32x4));
12057
12058       /* Set size, include skipped vectors */
12059       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12060
12061       *matchp = match;
12062
12063       return 1;
12064     }
12065
12066   return 0;
12067 }
12068
12069 static int
12070 api_classify_add_del_session (vat_main_t * vam)
12071 {
12072   unformat_input_t *i = vam->input;
12073   vl_api_classify_add_del_session_t *mp;
12074   int is_add = 1;
12075   u32 table_index = ~0;
12076   u32 hit_next_index = ~0;
12077   u32 opaque_index = ~0;
12078   u8 *match = 0;
12079   i32 advance = 0;
12080   u32 skip_n_vectors = 0;
12081   u32 match_n_vectors = 0;
12082   u32 action = 0;
12083   u32 metadata = 0;
12084   int ret;
12085
12086   /*
12087    * Warning: you have to supply skip_n and match_n
12088    * because the API client cant simply look at the classify
12089    * table object.
12090    */
12091
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "del"))
12095         is_add = 0;
12096       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12097                          &hit_next_index))
12098         ;
12099       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12100                          &hit_next_index))
12101         ;
12102       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12103                          &hit_next_index))
12104         ;
12105       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12106         ;
12107       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12108         ;
12109       else if (unformat (i, "opaque-index %d", &opaque_index))
12110         ;
12111       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12112         ;
12113       else if (unformat (i, "match_n %d", &match_n_vectors))
12114         ;
12115       else if (unformat (i, "match %U", api_unformat_classify_match,
12116                          &match, skip_n_vectors, match_n_vectors))
12117         ;
12118       else if (unformat (i, "advance %d", &advance))
12119         ;
12120       else if (unformat (i, "table-index %d", &table_index))
12121         ;
12122       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12123         action = 1;
12124       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12125         action = 2;
12126       else if (unformat (i, "action %d", &action))
12127         ;
12128       else if (unformat (i, "metadata %d", &metadata))
12129         ;
12130       else
12131         break;
12132     }
12133
12134   if (table_index == ~0)
12135     {
12136       errmsg ("Table index required");
12137       return -99;
12138     }
12139
12140   if (is_add && match == 0)
12141     {
12142       errmsg ("Match value required");
12143       return -99;
12144     }
12145
12146   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12147
12148   mp->is_add = is_add;
12149   mp->table_index = ntohl (table_index);
12150   mp->hit_next_index = ntohl (hit_next_index);
12151   mp->opaque_index = ntohl (opaque_index);
12152   mp->advance = ntohl (advance);
12153   mp->action = action;
12154   mp->metadata = ntohl (metadata);
12155   clib_memcpy (mp->match, match, vec_len (match));
12156   vec_free (match);
12157
12158   S (mp);
12159   W (ret);
12160   return ret;
12161 }
12162
12163 static int
12164 api_classify_set_interface_ip_table (vat_main_t * vam)
12165 {
12166   unformat_input_t *i = vam->input;
12167   vl_api_classify_set_interface_ip_table_t *mp;
12168   u32 sw_if_index;
12169   int sw_if_index_set;
12170   u32 table_index = ~0;
12171   u8 is_ipv6 = 0;
12172   int ret;
12173
12174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12175     {
12176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12177         sw_if_index_set = 1;
12178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12179         sw_if_index_set = 1;
12180       else if (unformat (i, "table %d", &table_index))
12181         ;
12182       else
12183         {
12184           clib_warning ("parse error '%U'", format_unformat_error, i);
12185           return -99;
12186         }
12187     }
12188
12189   if (sw_if_index_set == 0)
12190     {
12191       errmsg ("missing interface name or sw_if_index");
12192       return -99;
12193     }
12194
12195
12196   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12197
12198   mp->sw_if_index = ntohl (sw_if_index);
12199   mp->table_index = ntohl (table_index);
12200   mp->is_ipv6 = is_ipv6;
12201
12202   S (mp);
12203   W (ret);
12204   return ret;
12205 }
12206
12207 static int
12208 api_classify_set_interface_l2_tables (vat_main_t * vam)
12209 {
12210   unformat_input_t *i = vam->input;
12211   vl_api_classify_set_interface_l2_tables_t *mp;
12212   u32 sw_if_index;
12213   int sw_if_index_set;
12214   u32 ip4_table_index = ~0;
12215   u32 ip6_table_index = ~0;
12216   u32 other_table_index = ~0;
12217   u32 is_input = 1;
12218   int ret;
12219
12220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12221     {
12222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12223         sw_if_index_set = 1;
12224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12225         sw_if_index_set = 1;
12226       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12227         ;
12228       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12229         ;
12230       else if (unformat (i, "other-table %d", &other_table_index))
12231         ;
12232       else if (unformat (i, "is-input %d", &is_input))
12233         ;
12234       else
12235         {
12236           clib_warning ("parse error '%U'", format_unformat_error, i);
12237           return -99;
12238         }
12239     }
12240
12241   if (sw_if_index_set == 0)
12242     {
12243       errmsg ("missing interface name or sw_if_index");
12244       return -99;
12245     }
12246
12247
12248   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12249
12250   mp->sw_if_index = ntohl (sw_if_index);
12251   mp->ip4_table_index = ntohl (ip4_table_index);
12252   mp->ip6_table_index = ntohl (ip6_table_index);
12253   mp->other_table_index = ntohl (other_table_index);
12254   mp->is_input = (u8) is_input;
12255
12256   S (mp);
12257   W (ret);
12258   return ret;
12259 }
12260
12261 static int
12262 api_set_ipfix_exporter (vat_main_t * vam)
12263 {
12264   unformat_input_t *i = vam->input;
12265   vl_api_set_ipfix_exporter_t *mp;
12266   ip4_address_t collector_address;
12267   u8 collector_address_set = 0;
12268   u32 collector_port = ~0;
12269   ip4_address_t src_address;
12270   u8 src_address_set = 0;
12271   u32 vrf_id = ~0;
12272   u32 path_mtu = ~0;
12273   u32 template_interval = ~0;
12274   u8 udp_checksum = 0;
12275   int ret;
12276
12277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12278     {
12279       if (unformat (i, "collector_address %U", unformat_ip4_address,
12280                     &collector_address))
12281         collector_address_set = 1;
12282       else if (unformat (i, "collector_port %d", &collector_port))
12283         ;
12284       else if (unformat (i, "src_address %U", unformat_ip4_address,
12285                          &src_address))
12286         src_address_set = 1;
12287       else if (unformat (i, "vrf_id %d", &vrf_id))
12288         ;
12289       else if (unformat (i, "path_mtu %d", &path_mtu))
12290         ;
12291       else if (unformat (i, "template_interval %d", &template_interval))
12292         ;
12293       else if (unformat (i, "udp_checksum"))
12294         udp_checksum = 1;
12295       else
12296         break;
12297     }
12298
12299   if (collector_address_set == 0)
12300     {
12301       errmsg ("collector_address required");
12302       return -99;
12303     }
12304
12305   if (src_address_set == 0)
12306     {
12307       errmsg ("src_address required");
12308       return -99;
12309     }
12310
12311   M (SET_IPFIX_EXPORTER, mp);
12312
12313   memcpy (mp->collector_address, collector_address.data,
12314           sizeof (collector_address.data));
12315   mp->collector_port = htons ((u16) collector_port);
12316   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12317   mp->vrf_id = htonl (vrf_id);
12318   mp->path_mtu = htonl (path_mtu);
12319   mp->template_interval = htonl (template_interval);
12320   mp->udp_checksum = udp_checksum;
12321
12322   S (mp);
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_set_ipfix_classify_stream (vat_main_t * vam)
12329 {
12330   unformat_input_t *i = vam->input;
12331   vl_api_set_ipfix_classify_stream_t *mp;
12332   u32 domain_id = 0;
12333   u32 src_port = UDP_DST_PORT_ipfix;
12334   int ret;
12335
12336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12337     {
12338       if (unformat (i, "domain %d", &domain_id))
12339         ;
12340       else if (unformat (i, "src_port %d", &src_port))
12341         ;
12342       else
12343         {
12344           errmsg ("unknown input `%U'", format_unformat_error, i);
12345           return -99;
12346         }
12347     }
12348
12349   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12350
12351   mp->domain_id = htonl (domain_id);
12352   mp->src_port = htons ((u16) src_port);
12353
12354   S (mp);
12355   W (ret);
12356   return ret;
12357 }
12358
12359 static int
12360 api_ipfix_classify_table_add_del (vat_main_t * vam)
12361 {
12362   unformat_input_t *i = vam->input;
12363   vl_api_ipfix_classify_table_add_del_t *mp;
12364   int is_add = -1;
12365   u32 classify_table_index = ~0;
12366   u8 ip_version = 0;
12367   u8 transport_protocol = 255;
12368   int ret;
12369
12370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (i, "add"))
12373         is_add = 1;
12374       else if (unformat (i, "del"))
12375         is_add = 0;
12376       else if (unformat (i, "table %d", &classify_table_index))
12377         ;
12378       else if (unformat (i, "ip4"))
12379         ip_version = 4;
12380       else if (unformat (i, "ip6"))
12381         ip_version = 6;
12382       else if (unformat (i, "tcp"))
12383         transport_protocol = 6;
12384       else if (unformat (i, "udp"))
12385         transport_protocol = 17;
12386       else
12387         {
12388           errmsg ("unknown input `%U'", format_unformat_error, i);
12389           return -99;
12390         }
12391     }
12392
12393   if (is_add == -1)
12394     {
12395       errmsg ("expecting: add|del");
12396       return -99;
12397     }
12398   if (classify_table_index == ~0)
12399     {
12400       errmsg ("classifier table not specified");
12401       return -99;
12402     }
12403   if (ip_version == 0)
12404     {
12405       errmsg ("IP version not specified");
12406       return -99;
12407     }
12408
12409   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12410
12411   mp->is_add = is_add;
12412   mp->table_id = htonl (classify_table_index);
12413   mp->ip_version = ip_version;
12414   mp->transport_protocol = transport_protocol;
12415
12416   S (mp);
12417   W (ret);
12418   return ret;
12419 }
12420
12421 static int
12422 api_get_node_index (vat_main_t * vam)
12423 {
12424   unformat_input_t *i = vam->input;
12425   vl_api_get_node_index_t *mp;
12426   u8 *name = 0;
12427   int ret;
12428
12429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (i, "node %s", &name))
12432         ;
12433       else
12434         break;
12435     }
12436   if (name == 0)
12437     {
12438       errmsg ("node name required");
12439       return -99;
12440     }
12441   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12442     {
12443       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12444       return -99;
12445     }
12446
12447   M (GET_NODE_INDEX, mp);
12448   clib_memcpy (mp->node_name, name, vec_len (name));
12449   vec_free (name);
12450
12451   S (mp);
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static int
12457 api_get_next_index (vat_main_t * vam)
12458 {
12459   unformat_input_t *i = vam->input;
12460   vl_api_get_next_index_t *mp;
12461   u8 *node_name = 0, *next_node_name = 0;
12462   int ret;
12463
12464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12465     {
12466       if (unformat (i, "node-name %s", &node_name))
12467         ;
12468       else if (unformat (i, "next-node-name %s", &next_node_name))
12469         break;
12470     }
12471
12472   if (node_name == 0)
12473     {
12474       errmsg ("node name required");
12475       return -99;
12476     }
12477   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12478     {
12479       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12480       return -99;
12481     }
12482
12483   if (next_node_name == 0)
12484     {
12485       errmsg ("next node name required");
12486       return -99;
12487     }
12488   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12489     {
12490       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12491       return -99;
12492     }
12493
12494   M (GET_NEXT_INDEX, mp);
12495   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12496   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12497   vec_free (node_name);
12498   vec_free (next_node_name);
12499
12500   S (mp);
12501   W (ret);
12502   return ret;
12503 }
12504
12505 static int
12506 api_add_node_next (vat_main_t * vam)
12507 {
12508   unformat_input_t *i = vam->input;
12509   vl_api_add_node_next_t *mp;
12510   u8 *name = 0;
12511   u8 *next = 0;
12512   int ret;
12513
12514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12515     {
12516       if (unformat (i, "node %s", &name))
12517         ;
12518       else if (unformat (i, "next %s", &next))
12519         ;
12520       else
12521         break;
12522     }
12523   if (name == 0)
12524     {
12525       errmsg ("node name required");
12526       return -99;
12527     }
12528   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12529     {
12530       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12531       return -99;
12532     }
12533   if (next == 0)
12534     {
12535       errmsg ("next node required");
12536       return -99;
12537     }
12538   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12539     {
12540       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12541       return -99;
12542     }
12543
12544   M (ADD_NODE_NEXT, mp);
12545   clib_memcpy (mp->node_name, name, vec_len (name));
12546   clib_memcpy (mp->next_name, next, vec_len (next));
12547   vec_free (name);
12548   vec_free (next);
12549
12550   S (mp);
12551   W (ret);
12552   return ret;
12553 }
12554
12555 static int
12556 api_l2tpv3_create_tunnel (vat_main_t * vam)
12557 {
12558   unformat_input_t *i = vam->input;
12559   ip6_address_t client_address, our_address;
12560   int client_address_set = 0;
12561   int our_address_set = 0;
12562   u32 local_session_id = 0;
12563   u32 remote_session_id = 0;
12564   u64 local_cookie = 0;
12565   u64 remote_cookie = 0;
12566   u8 l2_sublayer_present = 0;
12567   vl_api_l2tpv3_create_tunnel_t *mp;
12568   int ret;
12569
12570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12571     {
12572       if (unformat (i, "client_address %U", unformat_ip6_address,
12573                     &client_address))
12574         client_address_set = 1;
12575       else if (unformat (i, "our_address %U", unformat_ip6_address,
12576                          &our_address))
12577         our_address_set = 1;
12578       else if (unformat (i, "local_session_id %d", &local_session_id))
12579         ;
12580       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12581         ;
12582       else if (unformat (i, "local_cookie %lld", &local_cookie))
12583         ;
12584       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12585         ;
12586       else if (unformat (i, "l2-sublayer-present"))
12587         l2_sublayer_present = 1;
12588       else
12589         break;
12590     }
12591
12592   if (client_address_set == 0)
12593     {
12594       errmsg ("client_address required");
12595       return -99;
12596     }
12597
12598   if (our_address_set == 0)
12599     {
12600       errmsg ("our_address required");
12601       return -99;
12602     }
12603
12604   M (L2TPV3_CREATE_TUNNEL, mp);
12605
12606   clib_memcpy (mp->client_address, client_address.as_u8,
12607                sizeof (mp->client_address));
12608
12609   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12610
12611   mp->local_session_id = ntohl (local_session_id);
12612   mp->remote_session_id = ntohl (remote_session_id);
12613   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12614   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12615   mp->l2_sublayer_present = l2_sublayer_present;
12616   mp->is_ipv6 = 1;
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static int
12624 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12625 {
12626   unformat_input_t *i = vam->input;
12627   u32 sw_if_index;
12628   u8 sw_if_index_set = 0;
12629   u64 new_local_cookie = 0;
12630   u64 new_remote_cookie = 0;
12631   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12632   int ret;
12633
12634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12635     {
12636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12637         sw_if_index_set = 1;
12638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12639         sw_if_index_set = 1;
12640       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12641         ;
12642       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12643         ;
12644       else
12645         break;
12646     }
12647
12648   if (sw_if_index_set == 0)
12649     {
12650       errmsg ("missing interface name or sw_if_index");
12651       return -99;
12652     }
12653
12654   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12655
12656   mp->sw_if_index = ntohl (sw_if_index);
12657   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12658   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static int
12666 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12667 {
12668   unformat_input_t *i = vam->input;
12669   vl_api_l2tpv3_interface_enable_disable_t *mp;
12670   u32 sw_if_index;
12671   u8 sw_if_index_set = 0;
12672   u8 enable_disable = 1;
12673   int ret;
12674
12675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12676     {
12677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12678         sw_if_index_set = 1;
12679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12680         sw_if_index_set = 1;
12681       else if (unformat (i, "enable"))
12682         enable_disable = 1;
12683       else if (unformat (i, "disable"))
12684         enable_disable = 0;
12685       else
12686         break;
12687     }
12688
12689   if (sw_if_index_set == 0)
12690     {
12691       errmsg ("missing interface name or sw_if_index");
12692       return -99;
12693     }
12694
12695   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12696
12697   mp->sw_if_index = ntohl (sw_if_index);
12698   mp->enable_disable = enable_disable;
12699
12700   S (mp);
12701   W (ret);
12702   return ret;
12703 }
12704
12705 static int
12706 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12707 {
12708   unformat_input_t *i = vam->input;
12709   vl_api_l2tpv3_set_lookup_key_t *mp;
12710   u8 key = ~0;
12711   int ret;
12712
12713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12714     {
12715       if (unformat (i, "lookup_v6_src"))
12716         key = L2T_LOOKUP_SRC_ADDRESS;
12717       else if (unformat (i, "lookup_v6_dst"))
12718         key = L2T_LOOKUP_DST_ADDRESS;
12719       else if (unformat (i, "lookup_session_id"))
12720         key = L2T_LOOKUP_SESSION_ID;
12721       else
12722         break;
12723     }
12724
12725   if (key == (u8) ~ 0)
12726     {
12727       errmsg ("l2tp session lookup key unset");
12728       return -99;
12729     }
12730
12731   M (L2TPV3_SET_LOOKUP_KEY, mp);
12732
12733   mp->key = key;
12734
12735   S (mp);
12736   W (ret);
12737   return ret;
12738 }
12739
12740 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12741   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12742 {
12743   vat_main_t *vam = &vat_main;
12744
12745   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12746          format_ip6_address, mp->our_address,
12747          format_ip6_address, mp->client_address,
12748          clib_net_to_host_u32 (mp->sw_if_index));
12749
12750   print (vam->ofp,
12751          "   local cookies %016llx %016llx remote cookie %016llx",
12752          clib_net_to_host_u64 (mp->local_cookie[0]),
12753          clib_net_to_host_u64 (mp->local_cookie[1]),
12754          clib_net_to_host_u64 (mp->remote_cookie));
12755
12756   print (vam->ofp, "   local session-id %d remote session-id %d",
12757          clib_net_to_host_u32 (mp->local_session_id),
12758          clib_net_to_host_u32 (mp->remote_session_id));
12759
12760   print (vam->ofp, "   l2 specific sublayer %s\n",
12761          mp->l2_sublayer_present ? "preset" : "absent");
12762
12763 }
12764
12765 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12766   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12767 {
12768   vat_main_t *vam = &vat_main;
12769   vat_json_node_t *node = NULL;
12770   struct in6_addr addr;
12771
12772   if (VAT_JSON_ARRAY != vam->json_tree.type)
12773     {
12774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12775       vat_json_init_array (&vam->json_tree);
12776     }
12777   node = vat_json_array_add (&vam->json_tree);
12778
12779   vat_json_init_object (node);
12780
12781   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12782   vat_json_object_add_ip6 (node, "our_address", addr);
12783   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12784   vat_json_object_add_ip6 (node, "client_address", addr);
12785
12786   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12787   vat_json_init_array (lc);
12788   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12789   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12790   vat_json_object_add_uint (node, "remote_cookie",
12791                             clib_net_to_host_u64 (mp->remote_cookie));
12792
12793   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12794   vat_json_object_add_uint (node, "local_session_id",
12795                             clib_net_to_host_u32 (mp->local_session_id));
12796   vat_json_object_add_uint (node, "remote_session_id",
12797                             clib_net_to_host_u32 (mp->remote_session_id));
12798   vat_json_object_add_string_copy (node, "l2_sublayer",
12799                                    mp->l2_sublayer_present ? (u8 *) "present"
12800                                    : (u8 *) "absent");
12801 }
12802
12803 static int
12804 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12805 {
12806   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12807   vl_api_control_ping_t *mp_ping;
12808   int ret;
12809
12810   /* Get list of l2tpv3-tunnel interfaces */
12811   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12812   S (mp);
12813
12814   /* Use a control ping for synchronization */
12815   MPING (CONTROL_PING, mp_ping);
12816   S (mp_ping);
12817
12818   W (ret);
12819   return ret;
12820 }
12821
12822
12823 static void vl_api_sw_interface_tap_details_t_handler
12824   (vl_api_sw_interface_tap_details_t * mp)
12825 {
12826   vat_main_t *vam = &vat_main;
12827
12828   print (vam->ofp, "%-16s %d",
12829          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12830 }
12831
12832 static void vl_api_sw_interface_tap_details_t_handler_json
12833   (vl_api_sw_interface_tap_details_t * mp)
12834 {
12835   vat_main_t *vam = &vat_main;
12836   vat_json_node_t *node = NULL;
12837
12838   if (VAT_JSON_ARRAY != vam->json_tree.type)
12839     {
12840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12841       vat_json_init_array (&vam->json_tree);
12842     }
12843   node = vat_json_array_add (&vam->json_tree);
12844
12845   vat_json_init_object (node);
12846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12847   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12848 }
12849
12850 static int
12851 api_sw_interface_tap_dump (vat_main_t * vam)
12852 {
12853   vl_api_sw_interface_tap_dump_t *mp;
12854   vl_api_control_ping_t *mp_ping;
12855   int ret;
12856
12857   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12858   /* Get list of tap interfaces */
12859   M (SW_INTERFACE_TAP_DUMP, mp);
12860   S (mp);
12861
12862   /* Use a control ping for synchronization */
12863   MPING (CONTROL_PING, mp_ping);
12864   S (mp_ping);
12865
12866   W (ret);
12867   return ret;
12868 }
12869
12870 static void vl_api_sw_interface_tap_v2_details_t_handler
12871   (vl_api_sw_interface_tap_v2_details_t * mp)
12872 {
12873   vat_main_t *vam = &vat_main;
12874
12875   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12876                     mp->host_ip4_prefix_len);
12877   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12878                     mp->host_ip6_prefix_len);
12879
12880   print (vam->ofp,
12881          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12882          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12883          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12884          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12885          mp->host_bridge, ip4, ip6);
12886
12887   vec_free (ip4);
12888   vec_free (ip6);
12889 }
12890
12891 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12892   (vl_api_sw_interface_tap_v2_details_t * mp)
12893 {
12894   vat_main_t *vam = &vat_main;
12895   vat_json_node_t *node = NULL;
12896
12897   if (VAT_JSON_ARRAY != vam->json_tree.type)
12898     {
12899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12900       vat_json_init_array (&vam->json_tree);
12901     }
12902   node = vat_json_array_add (&vam->json_tree);
12903
12904   vat_json_init_object (node);
12905   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12906   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12907   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12908   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12909   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12910   vat_json_object_add_string_copy (node, "host_mac_addr",
12911                                    format (0, "%U", format_ethernet_address,
12912                                            &mp->host_mac_addr));
12913   vat_json_object_add_string_copy (node, "host_namespace",
12914                                    mp->host_namespace);
12915   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12916   vat_json_object_add_string_copy (node, "host_ip4_addr",
12917                                    format (0, "%U/%d", format_ip4_address,
12918                                            mp->host_ip4_addr,
12919                                            mp->host_ip4_prefix_len));
12920   vat_json_object_add_string_copy (node, "host_ip6_addr",
12921                                    format (0, "%U/%d", format_ip6_address,
12922                                            mp->host_ip6_addr,
12923                                            mp->host_ip6_prefix_len));
12924
12925 }
12926
12927 static int
12928 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12929 {
12930   vl_api_sw_interface_tap_v2_dump_t *mp;
12931   vl_api_control_ping_t *mp_ping;
12932   int ret;
12933
12934   print (vam->ofp,
12935          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12936          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12937          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12938          "host_ip6_addr");
12939
12940   /* Get list of tap interfaces */
12941   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12942   S (mp);
12943
12944   /* Use a control ping for synchronization */
12945   MPING (CONTROL_PING, mp_ping);
12946   S (mp_ping);
12947
12948   W (ret);
12949   return ret;
12950 }
12951
12952 static uword unformat_vxlan_decap_next
12953   (unformat_input_t * input, va_list * args)
12954 {
12955   u32 *result = va_arg (*args, u32 *);
12956   u32 tmp;
12957
12958   if (unformat (input, "l2"))
12959     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12960   else if (unformat (input, "%d", &tmp))
12961     *result = tmp;
12962   else
12963     return 0;
12964   return 1;
12965 }
12966
12967 static int
12968 api_vxlan_add_del_tunnel (vat_main_t * vam)
12969 {
12970   unformat_input_t *line_input = vam->input;
12971   vl_api_vxlan_add_del_tunnel_t *mp;
12972   ip46_address_t src, dst;
12973   u8 is_add = 1;
12974   u8 ipv4_set = 0, ipv6_set = 0;
12975   u8 src_set = 0;
12976   u8 dst_set = 0;
12977   u8 grp_set = 0;
12978   u32 instance = ~0;
12979   u32 mcast_sw_if_index = ~0;
12980   u32 encap_vrf_id = 0;
12981   u32 decap_next_index = ~0;
12982   u32 vni = 0;
12983   int ret;
12984
12985   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12986   memset (&src, 0, sizeof src);
12987   memset (&dst, 0, sizeof dst);
12988
12989   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat (line_input, "del"))
12992         is_add = 0;
12993       else if (unformat (line_input, "instance %d", &instance))
12994         ;
12995       else
12996         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12997         {
12998           ipv4_set = 1;
12999           src_set = 1;
13000         }
13001       else
13002         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13003         {
13004           ipv4_set = 1;
13005           dst_set = 1;
13006         }
13007       else
13008         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13009         {
13010           ipv6_set = 1;
13011           src_set = 1;
13012         }
13013       else
13014         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13015         {
13016           ipv6_set = 1;
13017           dst_set = 1;
13018         }
13019       else if (unformat (line_input, "group %U %U",
13020                          unformat_ip4_address, &dst.ip4,
13021                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13022         {
13023           grp_set = dst_set = 1;
13024           ipv4_set = 1;
13025         }
13026       else if (unformat (line_input, "group %U",
13027                          unformat_ip4_address, &dst.ip4))
13028         {
13029           grp_set = dst_set = 1;
13030           ipv4_set = 1;
13031         }
13032       else if (unformat (line_input, "group %U %U",
13033                          unformat_ip6_address, &dst.ip6,
13034                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13035         {
13036           grp_set = dst_set = 1;
13037           ipv6_set = 1;
13038         }
13039       else if (unformat (line_input, "group %U",
13040                          unformat_ip6_address, &dst.ip6))
13041         {
13042           grp_set = dst_set = 1;
13043           ipv6_set = 1;
13044         }
13045       else
13046         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13047         ;
13048       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13049         ;
13050       else if (unformat (line_input, "decap-next %U",
13051                          unformat_vxlan_decap_next, &decap_next_index))
13052         ;
13053       else if (unformat (line_input, "vni %d", &vni))
13054         ;
13055       else
13056         {
13057           errmsg ("parse error '%U'", format_unformat_error, line_input);
13058           return -99;
13059         }
13060     }
13061
13062   if (src_set == 0)
13063     {
13064       errmsg ("tunnel src address not specified");
13065       return -99;
13066     }
13067   if (dst_set == 0)
13068     {
13069       errmsg ("tunnel dst address not specified");
13070       return -99;
13071     }
13072
13073   if (grp_set && !ip46_address_is_multicast (&dst))
13074     {
13075       errmsg ("tunnel group address not multicast");
13076       return -99;
13077     }
13078   if (grp_set && mcast_sw_if_index == ~0)
13079     {
13080       errmsg ("tunnel nonexistent multicast device");
13081       return -99;
13082     }
13083   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13084     {
13085       errmsg ("tunnel dst address must be unicast");
13086       return -99;
13087     }
13088
13089
13090   if (ipv4_set && ipv6_set)
13091     {
13092       errmsg ("both IPv4 and IPv6 addresses specified");
13093       return -99;
13094     }
13095
13096   if ((vni == 0) || (vni >> 24))
13097     {
13098       errmsg ("vni not specified or out of range");
13099       return -99;
13100     }
13101
13102   M (VXLAN_ADD_DEL_TUNNEL, mp);
13103
13104   if (ipv6_set)
13105     {
13106       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13107       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13108     }
13109   else
13110     {
13111       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13112       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13113     }
13114
13115   mp->instance = htonl (instance);
13116   mp->encap_vrf_id = ntohl (encap_vrf_id);
13117   mp->decap_next_index = ntohl (decap_next_index);
13118   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13119   mp->vni = ntohl (vni);
13120   mp->is_add = is_add;
13121   mp->is_ipv6 = ipv6_set;
13122
13123   S (mp);
13124   W (ret);
13125   return ret;
13126 }
13127
13128 static void vl_api_vxlan_tunnel_details_t_handler
13129   (vl_api_vxlan_tunnel_details_t * mp)
13130 {
13131   vat_main_t *vam = &vat_main;
13132   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13133   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13134
13135   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13136          ntohl (mp->sw_if_index),
13137          ntohl (mp->instance),
13138          format_ip46_address, &src, IP46_TYPE_ANY,
13139          format_ip46_address, &dst, IP46_TYPE_ANY,
13140          ntohl (mp->encap_vrf_id),
13141          ntohl (mp->decap_next_index), ntohl (mp->vni),
13142          ntohl (mp->mcast_sw_if_index));
13143 }
13144
13145 static void vl_api_vxlan_tunnel_details_t_handler_json
13146   (vl_api_vxlan_tunnel_details_t * mp)
13147 {
13148   vat_main_t *vam = &vat_main;
13149   vat_json_node_t *node = NULL;
13150
13151   if (VAT_JSON_ARRAY != vam->json_tree.type)
13152     {
13153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13154       vat_json_init_array (&vam->json_tree);
13155     }
13156   node = vat_json_array_add (&vam->json_tree);
13157
13158   vat_json_init_object (node);
13159   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13160
13161   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13162
13163   if (mp->is_ipv6)
13164     {
13165       struct in6_addr ip6;
13166
13167       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13168       vat_json_object_add_ip6 (node, "src_address", ip6);
13169       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13170       vat_json_object_add_ip6 (node, "dst_address", ip6);
13171     }
13172   else
13173     {
13174       struct in_addr ip4;
13175
13176       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13177       vat_json_object_add_ip4 (node, "src_address", ip4);
13178       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13179       vat_json_object_add_ip4 (node, "dst_address", ip4);
13180     }
13181   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13182   vat_json_object_add_uint (node, "decap_next_index",
13183                             ntohl (mp->decap_next_index));
13184   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13185   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13186   vat_json_object_add_uint (node, "mcast_sw_if_index",
13187                             ntohl (mp->mcast_sw_if_index));
13188 }
13189
13190 static int
13191 api_vxlan_tunnel_dump (vat_main_t * vam)
13192 {
13193   unformat_input_t *i = vam->input;
13194   vl_api_vxlan_tunnel_dump_t *mp;
13195   vl_api_control_ping_t *mp_ping;
13196   u32 sw_if_index;
13197   u8 sw_if_index_set = 0;
13198   int ret;
13199
13200   /* Parse args required to build the message */
13201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13202     {
13203       if (unformat (i, "sw_if_index %d", &sw_if_index))
13204         sw_if_index_set = 1;
13205       else
13206         break;
13207     }
13208
13209   if (sw_if_index_set == 0)
13210     {
13211       sw_if_index = ~0;
13212     }
13213
13214   if (!vam->json_output)
13215     {
13216       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13217              "sw_if_index", "instance", "src_address", "dst_address",
13218              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13219     }
13220
13221   /* Get list of vxlan-tunnel interfaces */
13222   M (VXLAN_TUNNEL_DUMP, mp);
13223
13224   mp->sw_if_index = htonl (sw_if_index);
13225
13226   S (mp);
13227
13228   /* Use a control ping for synchronization */
13229   MPING (CONTROL_PING, mp_ping);
13230   S (mp_ping);
13231
13232   W (ret);
13233   return ret;
13234 }
13235
13236 static uword unformat_geneve_decap_next
13237   (unformat_input_t * input, va_list * args)
13238 {
13239   u32 *result = va_arg (*args, u32 *);
13240   u32 tmp;
13241
13242   if (unformat (input, "l2"))
13243     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13244   else if (unformat (input, "%d", &tmp))
13245     *result = tmp;
13246   else
13247     return 0;
13248   return 1;
13249 }
13250
13251 static int
13252 api_geneve_add_del_tunnel (vat_main_t * vam)
13253 {
13254   unformat_input_t *line_input = vam->input;
13255   vl_api_geneve_add_del_tunnel_t *mp;
13256   ip46_address_t src, dst;
13257   u8 is_add = 1;
13258   u8 ipv4_set = 0, ipv6_set = 0;
13259   u8 src_set = 0;
13260   u8 dst_set = 0;
13261   u8 grp_set = 0;
13262   u32 mcast_sw_if_index = ~0;
13263   u32 encap_vrf_id = 0;
13264   u32 decap_next_index = ~0;
13265   u32 vni = 0;
13266   int ret;
13267
13268   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13269   memset (&src, 0, sizeof src);
13270   memset (&dst, 0, sizeof dst);
13271
13272   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13273     {
13274       if (unformat (line_input, "del"))
13275         is_add = 0;
13276       else
13277         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13278         {
13279           ipv4_set = 1;
13280           src_set = 1;
13281         }
13282       else
13283         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13284         {
13285           ipv4_set = 1;
13286           dst_set = 1;
13287         }
13288       else
13289         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13290         {
13291           ipv6_set = 1;
13292           src_set = 1;
13293         }
13294       else
13295         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13296         {
13297           ipv6_set = 1;
13298           dst_set = 1;
13299         }
13300       else if (unformat (line_input, "group %U %U",
13301                          unformat_ip4_address, &dst.ip4,
13302                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13303         {
13304           grp_set = dst_set = 1;
13305           ipv4_set = 1;
13306         }
13307       else if (unformat (line_input, "group %U",
13308                          unformat_ip4_address, &dst.ip4))
13309         {
13310           grp_set = dst_set = 1;
13311           ipv4_set = 1;
13312         }
13313       else if (unformat (line_input, "group %U %U",
13314                          unformat_ip6_address, &dst.ip6,
13315                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13316         {
13317           grp_set = dst_set = 1;
13318           ipv6_set = 1;
13319         }
13320       else if (unformat (line_input, "group %U",
13321                          unformat_ip6_address, &dst.ip6))
13322         {
13323           grp_set = dst_set = 1;
13324           ipv6_set = 1;
13325         }
13326       else
13327         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13328         ;
13329       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13330         ;
13331       else if (unformat (line_input, "decap-next %U",
13332                          unformat_geneve_decap_next, &decap_next_index))
13333         ;
13334       else if (unformat (line_input, "vni %d", &vni))
13335         ;
13336       else
13337         {
13338           errmsg ("parse error '%U'", format_unformat_error, line_input);
13339           return -99;
13340         }
13341     }
13342
13343   if (src_set == 0)
13344     {
13345       errmsg ("tunnel src address not specified");
13346       return -99;
13347     }
13348   if (dst_set == 0)
13349     {
13350       errmsg ("tunnel dst address not specified");
13351       return -99;
13352     }
13353
13354   if (grp_set && !ip46_address_is_multicast (&dst))
13355     {
13356       errmsg ("tunnel group address not multicast");
13357       return -99;
13358     }
13359   if (grp_set && mcast_sw_if_index == ~0)
13360     {
13361       errmsg ("tunnel nonexistent multicast device");
13362       return -99;
13363     }
13364   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13365     {
13366       errmsg ("tunnel dst address must be unicast");
13367       return -99;
13368     }
13369
13370
13371   if (ipv4_set && ipv6_set)
13372     {
13373       errmsg ("both IPv4 and IPv6 addresses specified");
13374       return -99;
13375     }
13376
13377   if ((vni == 0) || (vni >> 24))
13378     {
13379       errmsg ("vni not specified or out of range");
13380       return -99;
13381     }
13382
13383   M (GENEVE_ADD_DEL_TUNNEL, mp);
13384
13385   if (ipv6_set)
13386     {
13387       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13388       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13389     }
13390   else
13391     {
13392       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13393       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13394     }
13395   mp->encap_vrf_id = ntohl (encap_vrf_id);
13396   mp->decap_next_index = ntohl (decap_next_index);
13397   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13398   mp->vni = ntohl (vni);
13399   mp->is_add = is_add;
13400   mp->is_ipv6 = ipv6_set;
13401
13402   S (mp);
13403   W (ret);
13404   return ret;
13405 }
13406
13407 static void vl_api_geneve_tunnel_details_t_handler
13408   (vl_api_geneve_tunnel_details_t * mp)
13409 {
13410   vat_main_t *vam = &vat_main;
13411   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13412   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13413
13414   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13415          ntohl (mp->sw_if_index),
13416          format_ip46_address, &src, IP46_TYPE_ANY,
13417          format_ip46_address, &dst, IP46_TYPE_ANY,
13418          ntohl (mp->encap_vrf_id),
13419          ntohl (mp->decap_next_index), ntohl (mp->vni),
13420          ntohl (mp->mcast_sw_if_index));
13421 }
13422
13423 static void vl_api_geneve_tunnel_details_t_handler_json
13424   (vl_api_geneve_tunnel_details_t * mp)
13425 {
13426   vat_main_t *vam = &vat_main;
13427   vat_json_node_t *node = NULL;
13428
13429   if (VAT_JSON_ARRAY != vam->json_tree.type)
13430     {
13431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13432       vat_json_init_array (&vam->json_tree);
13433     }
13434   node = vat_json_array_add (&vam->json_tree);
13435
13436   vat_json_init_object (node);
13437   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13438   if (mp->is_ipv6)
13439     {
13440       struct in6_addr ip6;
13441
13442       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13443       vat_json_object_add_ip6 (node, "src_address", ip6);
13444       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13445       vat_json_object_add_ip6 (node, "dst_address", ip6);
13446     }
13447   else
13448     {
13449       struct in_addr ip4;
13450
13451       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13452       vat_json_object_add_ip4 (node, "src_address", ip4);
13453       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13454       vat_json_object_add_ip4 (node, "dst_address", ip4);
13455     }
13456   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13457   vat_json_object_add_uint (node, "decap_next_index",
13458                             ntohl (mp->decap_next_index));
13459   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13460   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13461   vat_json_object_add_uint (node, "mcast_sw_if_index",
13462                             ntohl (mp->mcast_sw_if_index));
13463 }
13464
13465 static int
13466 api_geneve_tunnel_dump (vat_main_t * vam)
13467 {
13468   unformat_input_t *i = vam->input;
13469   vl_api_geneve_tunnel_dump_t *mp;
13470   vl_api_control_ping_t *mp_ping;
13471   u32 sw_if_index;
13472   u8 sw_if_index_set = 0;
13473   int ret;
13474
13475   /* Parse args required to build the message */
13476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13477     {
13478       if (unformat (i, "sw_if_index %d", &sw_if_index))
13479         sw_if_index_set = 1;
13480       else
13481         break;
13482     }
13483
13484   if (sw_if_index_set == 0)
13485     {
13486       sw_if_index = ~0;
13487     }
13488
13489   if (!vam->json_output)
13490     {
13491       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13492              "sw_if_index", "local_address", "remote_address",
13493              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13494     }
13495
13496   /* Get list of geneve-tunnel interfaces */
13497   M (GENEVE_TUNNEL_DUMP, mp);
13498
13499   mp->sw_if_index = htonl (sw_if_index);
13500
13501   S (mp);
13502
13503   /* Use a control ping for synchronization */
13504   M (CONTROL_PING, mp_ping);
13505   S (mp_ping);
13506
13507   W (ret);
13508   return ret;
13509 }
13510
13511 static int
13512 api_gre_add_del_tunnel (vat_main_t * vam)
13513 {
13514   unformat_input_t *line_input = vam->input;
13515   vl_api_gre_add_del_tunnel_t *mp;
13516   ip4_address_t src4, dst4;
13517   ip6_address_t src6, dst6;
13518   u8 is_add = 1;
13519   u8 ipv4_set = 0;
13520   u8 ipv6_set = 0;
13521   u8 t_type = GRE_TUNNEL_TYPE_L3;
13522   u8 src_set = 0;
13523   u8 dst_set = 0;
13524   u32 outer_fib_id = 0;
13525   u32 session_id = 0;
13526   u32 instance = ~0;
13527   int ret;
13528
13529   memset (&src4, 0, sizeof src4);
13530   memset (&dst4, 0, sizeof dst4);
13531   memset (&src6, 0, sizeof src6);
13532   memset (&dst6, 0, sizeof dst6);
13533
13534   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13535     {
13536       if (unformat (line_input, "del"))
13537         is_add = 0;
13538       else if (unformat (line_input, "instance %d", &instance))
13539         ;
13540       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13541         {
13542           src_set = 1;
13543           ipv4_set = 1;
13544         }
13545       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13546         {
13547           dst_set = 1;
13548           ipv4_set = 1;
13549         }
13550       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13551         {
13552           src_set = 1;
13553           ipv6_set = 1;
13554         }
13555       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13556         {
13557           dst_set = 1;
13558           ipv6_set = 1;
13559         }
13560       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13561         ;
13562       else if (unformat (line_input, "teb"))
13563         t_type = GRE_TUNNEL_TYPE_TEB;
13564       else if (unformat (line_input, "erspan %d", &session_id))
13565         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13566       else
13567         {
13568           errmsg ("parse error '%U'", format_unformat_error, line_input);
13569           return -99;
13570         }
13571     }
13572
13573   if (src_set == 0)
13574     {
13575       errmsg ("tunnel src address not specified");
13576       return -99;
13577     }
13578   if (dst_set == 0)
13579     {
13580       errmsg ("tunnel dst address not specified");
13581       return -99;
13582     }
13583   if (ipv4_set && ipv6_set)
13584     {
13585       errmsg ("both IPv4 and IPv6 addresses specified");
13586       return -99;
13587     }
13588
13589
13590   M (GRE_ADD_DEL_TUNNEL, mp);
13591
13592   if (ipv4_set)
13593     {
13594       clib_memcpy (&mp->src_address, &src4, 4);
13595       clib_memcpy (&mp->dst_address, &dst4, 4);
13596     }
13597   else
13598     {
13599       clib_memcpy (&mp->src_address, &src6, 16);
13600       clib_memcpy (&mp->dst_address, &dst6, 16);
13601     }
13602   mp->instance = htonl (instance);
13603   mp->outer_fib_id = htonl (outer_fib_id);
13604   mp->is_add = is_add;
13605   mp->session_id = htons ((u16) session_id);
13606   mp->tunnel_type = t_type;
13607   mp->is_ipv6 = ipv6_set;
13608
13609   S (mp);
13610   W (ret);
13611   return ret;
13612 }
13613
13614 static void vl_api_gre_tunnel_details_t_handler
13615   (vl_api_gre_tunnel_details_t * mp)
13616 {
13617   vat_main_t *vam = &vat_main;
13618   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13619   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13620
13621   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13622          ntohl (mp->sw_if_index),
13623          ntohl (mp->instance),
13624          format_ip46_address, &src, IP46_TYPE_ANY,
13625          format_ip46_address, &dst, IP46_TYPE_ANY,
13626          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13627 }
13628
13629 static void vl_api_gre_tunnel_details_t_handler_json
13630   (vl_api_gre_tunnel_details_t * mp)
13631 {
13632   vat_main_t *vam = &vat_main;
13633   vat_json_node_t *node = NULL;
13634   struct in_addr ip4;
13635   struct in6_addr ip6;
13636
13637   if (VAT_JSON_ARRAY != vam->json_tree.type)
13638     {
13639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13640       vat_json_init_array (&vam->json_tree);
13641     }
13642   node = vat_json_array_add (&vam->json_tree);
13643
13644   vat_json_init_object (node);
13645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13646   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13647   if (!mp->is_ipv6)
13648     {
13649       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13650       vat_json_object_add_ip4 (node, "src_address", ip4);
13651       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13652       vat_json_object_add_ip4 (node, "dst_address", ip4);
13653     }
13654   else
13655     {
13656       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13657       vat_json_object_add_ip6 (node, "src_address", ip6);
13658       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13659       vat_json_object_add_ip6 (node, "dst_address", ip6);
13660     }
13661   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13662   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13663   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13664   vat_json_object_add_uint (node, "session_id", mp->session_id);
13665 }
13666
13667 static int
13668 api_gre_tunnel_dump (vat_main_t * vam)
13669 {
13670   unformat_input_t *i = vam->input;
13671   vl_api_gre_tunnel_dump_t *mp;
13672   vl_api_control_ping_t *mp_ping;
13673   u32 sw_if_index;
13674   u8 sw_if_index_set = 0;
13675   int ret;
13676
13677   /* Parse args required to build the message */
13678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13679     {
13680       if (unformat (i, "sw_if_index %d", &sw_if_index))
13681         sw_if_index_set = 1;
13682       else
13683         break;
13684     }
13685
13686   if (sw_if_index_set == 0)
13687     {
13688       sw_if_index = ~0;
13689     }
13690
13691   if (!vam->json_output)
13692     {
13693       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13694              "sw_if_index", "instance", "src_address", "dst_address",
13695              "tunnel_type", "outer_fib_id", "session_id");
13696     }
13697
13698   /* Get list of gre-tunnel interfaces */
13699   M (GRE_TUNNEL_DUMP, mp);
13700
13701   mp->sw_if_index = htonl (sw_if_index);
13702
13703   S (mp);
13704
13705   /* Use a control ping for synchronization */
13706   MPING (CONTROL_PING, mp_ping);
13707   S (mp_ping);
13708
13709   W (ret);
13710   return ret;
13711 }
13712
13713 static int
13714 api_l2_fib_clear_table (vat_main_t * vam)
13715 {
13716 //  unformat_input_t * i = vam->input;
13717   vl_api_l2_fib_clear_table_t *mp;
13718   int ret;
13719
13720   M (L2_FIB_CLEAR_TABLE, mp);
13721
13722   S (mp);
13723   W (ret);
13724   return ret;
13725 }
13726
13727 static int
13728 api_l2_interface_efp_filter (vat_main_t * vam)
13729 {
13730   unformat_input_t *i = vam->input;
13731   vl_api_l2_interface_efp_filter_t *mp;
13732   u32 sw_if_index;
13733   u8 enable = 1;
13734   u8 sw_if_index_set = 0;
13735   int ret;
13736
13737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13738     {
13739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13740         sw_if_index_set = 1;
13741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13742         sw_if_index_set = 1;
13743       else if (unformat (i, "enable"))
13744         enable = 1;
13745       else if (unformat (i, "disable"))
13746         enable = 0;
13747       else
13748         {
13749           clib_warning ("parse error '%U'", format_unformat_error, i);
13750           return -99;
13751         }
13752     }
13753
13754   if (sw_if_index_set == 0)
13755     {
13756       errmsg ("missing sw_if_index");
13757       return -99;
13758     }
13759
13760   M (L2_INTERFACE_EFP_FILTER, mp);
13761
13762   mp->sw_if_index = ntohl (sw_if_index);
13763   mp->enable_disable = enable;
13764
13765   S (mp);
13766   W (ret);
13767   return ret;
13768 }
13769
13770 #define foreach_vtr_op                          \
13771 _("disable",  L2_VTR_DISABLED)                  \
13772 _("push-1",  L2_VTR_PUSH_1)                     \
13773 _("push-2",  L2_VTR_PUSH_2)                     \
13774 _("pop-1",  L2_VTR_POP_1)                       \
13775 _("pop-2",  L2_VTR_POP_2)                       \
13776 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13777 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13778 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13779 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13780
13781 static int
13782 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13783 {
13784   unformat_input_t *i = vam->input;
13785   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13786   u32 sw_if_index;
13787   u8 sw_if_index_set = 0;
13788   u8 vtr_op_set = 0;
13789   u32 vtr_op = 0;
13790   u32 push_dot1q = 1;
13791   u32 tag1 = ~0;
13792   u32 tag2 = ~0;
13793   int ret;
13794
13795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13796     {
13797       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13798         sw_if_index_set = 1;
13799       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13800         sw_if_index_set = 1;
13801       else if (unformat (i, "vtr_op %d", &vtr_op))
13802         vtr_op_set = 1;
13803 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13804       foreach_vtr_op
13805 #undef _
13806         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13807         ;
13808       else if (unformat (i, "tag1 %d", &tag1))
13809         ;
13810       else if (unformat (i, "tag2 %d", &tag2))
13811         ;
13812       else
13813         {
13814           clib_warning ("parse error '%U'", format_unformat_error, i);
13815           return -99;
13816         }
13817     }
13818
13819   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13820     {
13821       errmsg ("missing vtr operation or sw_if_index");
13822       return -99;
13823     }
13824
13825   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13826   mp->sw_if_index = ntohl (sw_if_index);
13827   mp->vtr_op = ntohl (vtr_op);
13828   mp->push_dot1q = ntohl (push_dot1q);
13829   mp->tag1 = ntohl (tag1);
13830   mp->tag2 = ntohl (tag2);
13831
13832   S (mp);
13833   W (ret);
13834   return ret;
13835 }
13836
13837 static int
13838 api_create_vhost_user_if (vat_main_t * vam)
13839 {
13840   unformat_input_t *i = vam->input;
13841   vl_api_create_vhost_user_if_t *mp;
13842   u8 *file_name;
13843   u8 is_server = 0;
13844   u8 file_name_set = 0;
13845   u32 custom_dev_instance = ~0;
13846   u8 hwaddr[6];
13847   u8 use_custom_mac = 0;
13848   u8 *tag = 0;
13849   int ret;
13850
13851   /* Shut up coverity */
13852   memset (hwaddr, 0, sizeof (hwaddr));
13853
13854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13855     {
13856       if (unformat (i, "socket %s", &file_name))
13857         {
13858           file_name_set = 1;
13859         }
13860       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13861         ;
13862       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13863         use_custom_mac = 1;
13864       else if (unformat (i, "server"))
13865         is_server = 1;
13866       else if (unformat (i, "tag %s", &tag))
13867         ;
13868       else
13869         break;
13870     }
13871
13872   if (file_name_set == 0)
13873     {
13874       errmsg ("missing socket file name");
13875       return -99;
13876     }
13877
13878   if (vec_len (file_name) > 255)
13879     {
13880       errmsg ("socket file name too long");
13881       return -99;
13882     }
13883   vec_add1 (file_name, 0);
13884
13885   M (CREATE_VHOST_USER_IF, mp);
13886
13887   mp->is_server = is_server;
13888   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13889   vec_free (file_name);
13890   if (custom_dev_instance != ~0)
13891     {
13892       mp->renumber = 1;
13893       mp->custom_dev_instance = ntohl (custom_dev_instance);
13894     }
13895   mp->use_custom_mac = use_custom_mac;
13896   clib_memcpy (mp->mac_address, hwaddr, 6);
13897   if (tag)
13898     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13899   vec_free (tag);
13900
13901   S (mp);
13902   W (ret);
13903   return ret;
13904 }
13905
13906 static int
13907 api_modify_vhost_user_if (vat_main_t * vam)
13908 {
13909   unformat_input_t *i = vam->input;
13910   vl_api_modify_vhost_user_if_t *mp;
13911   u8 *file_name;
13912   u8 is_server = 0;
13913   u8 file_name_set = 0;
13914   u32 custom_dev_instance = ~0;
13915   u8 sw_if_index_set = 0;
13916   u32 sw_if_index = (u32) ~ 0;
13917   int ret;
13918
13919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13920     {
13921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13922         sw_if_index_set = 1;
13923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13924         sw_if_index_set = 1;
13925       else if (unformat (i, "socket %s", &file_name))
13926         {
13927           file_name_set = 1;
13928         }
13929       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13930         ;
13931       else if (unformat (i, "server"))
13932         is_server = 1;
13933       else
13934         break;
13935     }
13936
13937   if (sw_if_index_set == 0)
13938     {
13939       errmsg ("missing sw_if_index or interface name");
13940       return -99;
13941     }
13942
13943   if (file_name_set == 0)
13944     {
13945       errmsg ("missing socket file name");
13946       return -99;
13947     }
13948
13949   if (vec_len (file_name) > 255)
13950     {
13951       errmsg ("socket file name too long");
13952       return -99;
13953     }
13954   vec_add1 (file_name, 0);
13955
13956   M (MODIFY_VHOST_USER_IF, mp);
13957
13958   mp->sw_if_index = ntohl (sw_if_index);
13959   mp->is_server = is_server;
13960   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13961   vec_free (file_name);
13962   if (custom_dev_instance != ~0)
13963     {
13964       mp->renumber = 1;
13965       mp->custom_dev_instance = ntohl (custom_dev_instance);
13966     }
13967
13968   S (mp);
13969   W (ret);
13970   return ret;
13971 }
13972
13973 static int
13974 api_delete_vhost_user_if (vat_main_t * vam)
13975 {
13976   unformat_input_t *i = vam->input;
13977   vl_api_delete_vhost_user_if_t *mp;
13978   u32 sw_if_index = ~0;
13979   u8 sw_if_index_set = 0;
13980   int ret;
13981
13982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13983     {
13984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13985         sw_if_index_set = 1;
13986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13987         sw_if_index_set = 1;
13988       else
13989         break;
13990     }
13991
13992   if (sw_if_index_set == 0)
13993     {
13994       errmsg ("missing sw_if_index or interface name");
13995       return -99;
13996     }
13997
13998
13999   M (DELETE_VHOST_USER_IF, mp);
14000
14001   mp->sw_if_index = ntohl (sw_if_index);
14002
14003   S (mp);
14004   W (ret);
14005   return ret;
14006 }
14007
14008 static void vl_api_sw_interface_vhost_user_details_t_handler
14009   (vl_api_sw_interface_vhost_user_details_t * mp)
14010 {
14011   vat_main_t *vam = &vat_main;
14012
14013   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14014          (char *) mp->interface_name,
14015          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14016          clib_net_to_host_u64 (mp->features), mp->is_server,
14017          ntohl (mp->num_regions), (char *) mp->sock_filename);
14018   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14019 }
14020
14021 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14022   (vl_api_sw_interface_vhost_user_details_t * mp)
14023 {
14024   vat_main_t *vam = &vat_main;
14025   vat_json_node_t *node = NULL;
14026
14027   if (VAT_JSON_ARRAY != vam->json_tree.type)
14028     {
14029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14030       vat_json_init_array (&vam->json_tree);
14031     }
14032   node = vat_json_array_add (&vam->json_tree);
14033
14034   vat_json_init_object (node);
14035   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14036   vat_json_object_add_string_copy (node, "interface_name",
14037                                    mp->interface_name);
14038   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14039                             ntohl (mp->virtio_net_hdr_sz));
14040   vat_json_object_add_uint (node, "features",
14041                             clib_net_to_host_u64 (mp->features));
14042   vat_json_object_add_uint (node, "is_server", mp->is_server);
14043   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14044   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14045   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14046 }
14047
14048 static int
14049 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14050 {
14051   vl_api_sw_interface_vhost_user_dump_t *mp;
14052   vl_api_control_ping_t *mp_ping;
14053   int ret;
14054   print (vam->ofp,
14055          "Interface name            idx hdr_sz features server regions filename");
14056
14057   /* Get list of vhost-user interfaces */
14058   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14059   S (mp);
14060
14061   /* Use a control ping for synchronization */
14062   MPING (CONTROL_PING, mp_ping);
14063   S (mp_ping);
14064
14065   W (ret);
14066   return ret;
14067 }
14068
14069 static int
14070 api_show_version (vat_main_t * vam)
14071 {
14072   vl_api_show_version_t *mp;
14073   int ret;
14074
14075   M (SHOW_VERSION, mp);
14076
14077   S (mp);
14078   W (ret);
14079   return ret;
14080 }
14081
14082
14083 static int
14084 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14085 {
14086   unformat_input_t *line_input = vam->input;
14087   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14088   ip4_address_t local4, remote4;
14089   ip6_address_t local6, remote6;
14090   u8 is_add = 1;
14091   u8 ipv4_set = 0, ipv6_set = 0;
14092   u8 local_set = 0;
14093   u8 remote_set = 0;
14094   u8 grp_set = 0;
14095   u32 mcast_sw_if_index = ~0;
14096   u32 encap_vrf_id = 0;
14097   u32 decap_vrf_id = 0;
14098   u8 protocol = ~0;
14099   u32 vni;
14100   u8 vni_set = 0;
14101   int ret;
14102
14103   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14104   memset (&local4, 0, sizeof local4);
14105   memset (&remote4, 0, sizeof remote4);
14106   memset (&local6, 0, sizeof local6);
14107   memset (&remote6, 0, sizeof remote6);
14108
14109   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14110     {
14111       if (unformat (line_input, "del"))
14112         is_add = 0;
14113       else if (unformat (line_input, "local %U",
14114                          unformat_ip4_address, &local4))
14115         {
14116           local_set = 1;
14117           ipv4_set = 1;
14118         }
14119       else if (unformat (line_input, "remote %U",
14120                          unformat_ip4_address, &remote4))
14121         {
14122           remote_set = 1;
14123           ipv4_set = 1;
14124         }
14125       else if (unformat (line_input, "local %U",
14126                          unformat_ip6_address, &local6))
14127         {
14128           local_set = 1;
14129           ipv6_set = 1;
14130         }
14131       else if (unformat (line_input, "remote %U",
14132                          unformat_ip6_address, &remote6))
14133         {
14134           remote_set = 1;
14135           ipv6_set = 1;
14136         }
14137       else if (unformat (line_input, "group %U %U",
14138                          unformat_ip4_address, &remote4,
14139                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14140         {
14141           grp_set = remote_set = 1;
14142           ipv4_set = 1;
14143         }
14144       else if (unformat (line_input, "group %U",
14145                          unformat_ip4_address, &remote4))
14146         {
14147           grp_set = remote_set = 1;
14148           ipv4_set = 1;
14149         }
14150       else if (unformat (line_input, "group %U %U",
14151                          unformat_ip6_address, &remote6,
14152                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14153         {
14154           grp_set = remote_set = 1;
14155           ipv6_set = 1;
14156         }
14157       else if (unformat (line_input, "group %U",
14158                          unformat_ip6_address, &remote6))
14159         {
14160           grp_set = remote_set = 1;
14161           ipv6_set = 1;
14162         }
14163       else
14164         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14165         ;
14166       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14167         ;
14168       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14169         ;
14170       else if (unformat (line_input, "vni %d", &vni))
14171         vni_set = 1;
14172       else if (unformat (line_input, "next-ip4"))
14173         protocol = 1;
14174       else if (unformat (line_input, "next-ip6"))
14175         protocol = 2;
14176       else if (unformat (line_input, "next-ethernet"))
14177         protocol = 3;
14178       else if (unformat (line_input, "next-nsh"))
14179         protocol = 4;
14180       else
14181         {
14182           errmsg ("parse error '%U'", format_unformat_error, line_input);
14183           return -99;
14184         }
14185     }
14186
14187   if (local_set == 0)
14188     {
14189       errmsg ("tunnel local address not specified");
14190       return -99;
14191     }
14192   if (remote_set == 0)
14193     {
14194       errmsg ("tunnel remote address not specified");
14195       return -99;
14196     }
14197   if (grp_set && mcast_sw_if_index == ~0)
14198     {
14199       errmsg ("tunnel nonexistent multicast device");
14200       return -99;
14201     }
14202   if (ipv4_set && ipv6_set)
14203     {
14204       errmsg ("both IPv4 and IPv6 addresses specified");
14205       return -99;
14206     }
14207
14208   if (vni_set == 0)
14209     {
14210       errmsg ("vni not specified");
14211       return -99;
14212     }
14213
14214   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14215
14216
14217   if (ipv6_set)
14218     {
14219       clib_memcpy (&mp->local, &local6, sizeof (local6));
14220       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14221     }
14222   else
14223     {
14224       clib_memcpy (&mp->local, &local4, sizeof (local4));
14225       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14226     }
14227
14228   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14229   mp->encap_vrf_id = ntohl (encap_vrf_id);
14230   mp->decap_vrf_id = ntohl (decap_vrf_id);
14231   mp->protocol = protocol;
14232   mp->vni = ntohl (vni);
14233   mp->is_add = is_add;
14234   mp->is_ipv6 = ipv6_set;
14235
14236   S (mp);
14237   W (ret);
14238   return ret;
14239 }
14240
14241 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14242   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14243 {
14244   vat_main_t *vam = &vat_main;
14245   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14246   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14247
14248   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14249          ntohl (mp->sw_if_index),
14250          format_ip46_address, &local, IP46_TYPE_ANY,
14251          format_ip46_address, &remote, IP46_TYPE_ANY,
14252          ntohl (mp->vni), mp->protocol,
14253          ntohl (mp->mcast_sw_if_index),
14254          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14255 }
14256
14257
14258 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14259   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14260 {
14261   vat_main_t *vam = &vat_main;
14262   vat_json_node_t *node = NULL;
14263   struct in_addr ip4;
14264   struct in6_addr ip6;
14265
14266   if (VAT_JSON_ARRAY != vam->json_tree.type)
14267     {
14268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14269       vat_json_init_array (&vam->json_tree);
14270     }
14271   node = vat_json_array_add (&vam->json_tree);
14272
14273   vat_json_init_object (node);
14274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14275   if (mp->is_ipv6)
14276     {
14277       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14278       vat_json_object_add_ip6 (node, "local", ip6);
14279       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14280       vat_json_object_add_ip6 (node, "remote", ip6);
14281     }
14282   else
14283     {
14284       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14285       vat_json_object_add_ip4 (node, "local", ip4);
14286       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14287       vat_json_object_add_ip4 (node, "remote", ip4);
14288     }
14289   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14290   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14291   vat_json_object_add_uint (node, "mcast_sw_if_index",
14292                             ntohl (mp->mcast_sw_if_index));
14293   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14294   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14295   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14296 }
14297
14298 static int
14299 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14300 {
14301   unformat_input_t *i = vam->input;
14302   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14303   vl_api_control_ping_t *mp_ping;
14304   u32 sw_if_index;
14305   u8 sw_if_index_set = 0;
14306   int ret;
14307
14308   /* Parse args required to build the message */
14309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14310     {
14311       if (unformat (i, "sw_if_index %d", &sw_if_index))
14312         sw_if_index_set = 1;
14313       else
14314         break;
14315     }
14316
14317   if (sw_if_index_set == 0)
14318     {
14319       sw_if_index = ~0;
14320     }
14321
14322   if (!vam->json_output)
14323     {
14324       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14325              "sw_if_index", "local", "remote", "vni",
14326              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14327     }
14328
14329   /* Get list of vxlan-tunnel interfaces */
14330   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14331
14332   mp->sw_if_index = htonl (sw_if_index);
14333
14334   S (mp);
14335
14336   /* Use a control ping for synchronization */
14337   MPING (CONTROL_PING, mp_ping);
14338   S (mp_ping);
14339
14340   W (ret);
14341   return ret;
14342 }
14343
14344 static void vl_api_l2_fib_table_details_t_handler
14345   (vl_api_l2_fib_table_details_t * mp)
14346 {
14347   vat_main_t *vam = &vat_main;
14348
14349   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14350          "       %d       %d     %d",
14351          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14352          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14353          mp->bvi_mac);
14354 }
14355
14356 static void vl_api_l2_fib_table_details_t_handler_json
14357   (vl_api_l2_fib_table_details_t * mp)
14358 {
14359   vat_main_t *vam = &vat_main;
14360   vat_json_node_t *node = NULL;
14361
14362   if (VAT_JSON_ARRAY != vam->json_tree.type)
14363     {
14364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14365       vat_json_init_array (&vam->json_tree);
14366     }
14367   node = vat_json_array_add (&vam->json_tree);
14368
14369   vat_json_init_object (node);
14370   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14371   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14372   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14373   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14374   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14375   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14376 }
14377
14378 static int
14379 api_l2_fib_table_dump (vat_main_t * vam)
14380 {
14381   unformat_input_t *i = vam->input;
14382   vl_api_l2_fib_table_dump_t *mp;
14383   vl_api_control_ping_t *mp_ping;
14384   u32 bd_id;
14385   u8 bd_id_set = 0;
14386   int ret;
14387
14388   /* Parse args required to build the message */
14389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (i, "bd_id %d", &bd_id))
14392         bd_id_set = 1;
14393       else
14394         break;
14395     }
14396
14397   if (bd_id_set == 0)
14398     {
14399       errmsg ("missing bridge domain");
14400       return -99;
14401     }
14402
14403   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14404
14405   /* Get list of l2 fib entries */
14406   M (L2_FIB_TABLE_DUMP, mp);
14407
14408   mp->bd_id = ntohl (bd_id);
14409   S (mp);
14410
14411   /* Use a control ping for synchronization */
14412   MPING (CONTROL_PING, mp_ping);
14413   S (mp_ping);
14414
14415   W (ret);
14416   return ret;
14417 }
14418
14419
14420 static int
14421 api_interface_name_renumber (vat_main_t * vam)
14422 {
14423   unformat_input_t *line_input = vam->input;
14424   vl_api_interface_name_renumber_t *mp;
14425   u32 sw_if_index = ~0;
14426   u32 new_show_dev_instance = ~0;
14427   int ret;
14428
14429   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14430     {
14431       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14432                     &sw_if_index))
14433         ;
14434       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14435         ;
14436       else if (unformat (line_input, "new_show_dev_instance %d",
14437                          &new_show_dev_instance))
14438         ;
14439       else
14440         break;
14441     }
14442
14443   if (sw_if_index == ~0)
14444     {
14445       errmsg ("missing interface name or sw_if_index");
14446       return -99;
14447     }
14448
14449   if (new_show_dev_instance == ~0)
14450     {
14451       errmsg ("missing new_show_dev_instance");
14452       return -99;
14453     }
14454
14455   M (INTERFACE_NAME_RENUMBER, mp);
14456
14457   mp->sw_if_index = ntohl (sw_if_index);
14458   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14459
14460   S (mp);
14461   W (ret);
14462   return ret;
14463 }
14464
14465 static int
14466 api_want_ip4_arp_events (vat_main_t * vam)
14467 {
14468   unformat_input_t *line_input = vam->input;
14469   vl_api_want_ip4_arp_events_t *mp;
14470   ip4_address_t address;
14471   int address_set = 0;
14472   u32 enable_disable = 1;
14473   int ret;
14474
14475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14476     {
14477       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14478         address_set = 1;
14479       else if (unformat (line_input, "del"))
14480         enable_disable = 0;
14481       else
14482         break;
14483     }
14484
14485   if (address_set == 0)
14486     {
14487       errmsg ("missing addresses");
14488       return -99;
14489     }
14490
14491   M (WANT_IP4_ARP_EVENTS, mp);
14492   mp->enable_disable = enable_disable;
14493   mp->pid = htonl (getpid ());
14494   mp->address = address.as_u32;
14495
14496   S (mp);
14497   W (ret);
14498   return ret;
14499 }
14500
14501 static int
14502 api_want_ip6_nd_events (vat_main_t * vam)
14503 {
14504   unformat_input_t *line_input = vam->input;
14505   vl_api_want_ip6_nd_events_t *mp;
14506   ip6_address_t address;
14507   int address_set = 0;
14508   u32 enable_disable = 1;
14509   int ret;
14510
14511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14512     {
14513       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14514         address_set = 1;
14515       else if (unformat (line_input, "del"))
14516         enable_disable = 0;
14517       else
14518         break;
14519     }
14520
14521   if (address_set == 0)
14522     {
14523       errmsg ("missing addresses");
14524       return -99;
14525     }
14526
14527   M (WANT_IP6_ND_EVENTS, mp);
14528   mp->enable_disable = enable_disable;
14529   mp->pid = htonl (getpid ());
14530   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14531
14532   S (mp);
14533   W (ret);
14534   return ret;
14535 }
14536
14537 static int
14538 api_want_l2_macs_events (vat_main_t * vam)
14539 {
14540   unformat_input_t *line_input = vam->input;
14541   vl_api_want_l2_macs_events_t *mp;
14542   u8 enable_disable = 1;
14543   u32 scan_delay = 0;
14544   u32 max_macs_in_event = 0;
14545   u32 learn_limit = 0;
14546   int ret;
14547
14548   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14549     {
14550       if (unformat (line_input, "learn-limit %d", &learn_limit))
14551         ;
14552       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14553         ;
14554       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14555         ;
14556       else if (unformat (line_input, "disable"))
14557         enable_disable = 0;
14558       else
14559         break;
14560     }
14561
14562   M (WANT_L2_MACS_EVENTS, mp);
14563   mp->enable_disable = enable_disable;
14564   mp->pid = htonl (getpid ());
14565   mp->learn_limit = htonl (learn_limit);
14566   mp->scan_delay = (u8) scan_delay;
14567   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14568   S (mp);
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static int
14574 api_input_acl_set_interface (vat_main_t * vam)
14575 {
14576   unformat_input_t *i = vam->input;
14577   vl_api_input_acl_set_interface_t *mp;
14578   u32 sw_if_index;
14579   int sw_if_index_set;
14580   u32 ip4_table_index = ~0;
14581   u32 ip6_table_index = ~0;
14582   u32 l2_table_index = ~0;
14583   u8 is_add = 1;
14584   int ret;
14585
14586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14587     {
14588       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14589         sw_if_index_set = 1;
14590       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14591         sw_if_index_set = 1;
14592       else if (unformat (i, "del"))
14593         is_add = 0;
14594       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14595         ;
14596       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14597         ;
14598       else if (unformat (i, "l2-table %d", &l2_table_index))
14599         ;
14600       else
14601         {
14602           clib_warning ("parse error '%U'", format_unformat_error, i);
14603           return -99;
14604         }
14605     }
14606
14607   if (sw_if_index_set == 0)
14608     {
14609       errmsg ("missing interface name or sw_if_index");
14610       return -99;
14611     }
14612
14613   M (INPUT_ACL_SET_INTERFACE, mp);
14614
14615   mp->sw_if_index = ntohl (sw_if_index);
14616   mp->ip4_table_index = ntohl (ip4_table_index);
14617   mp->ip6_table_index = ntohl (ip6_table_index);
14618   mp->l2_table_index = ntohl (l2_table_index);
14619   mp->is_add = is_add;
14620
14621   S (mp);
14622   W (ret);
14623   return ret;
14624 }
14625
14626 static int
14627 api_output_acl_set_interface (vat_main_t * vam)
14628 {
14629   unformat_input_t *i = vam->input;
14630   vl_api_output_acl_set_interface_t *mp;
14631   u32 sw_if_index;
14632   int sw_if_index_set;
14633   u32 ip4_table_index = ~0;
14634   u32 ip6_table_index = ~0;
14635   u32 l2_table_index = ~0;
14636   u8 is_add = 1;
14637   int ret;
14638
14639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14640     {
14641       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14642         sw_if_index_set = 1;
14643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14644         sw_if_index_set = 1;
14645       else if (unformat (i, "del"))
14646         is_add = 0;
14647       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14648         ;
14649       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14650         ;
14651       else if (unformat (i, "l2-table %d", &l2_table_index))
14652         ;
14653       else
14654         {
14655           clib_warning ("parse error '%U'", format_unformat_error, i);
14656           return -99;
14657         }
14658     }
14659
14660   if (sw_if_index_set == 0)
14661     {
14662       errmsg ("missing interface name or sw_if_index");
14663       return -99;
14664     }
14665
14666   M (OUTPUT_ACL_SET_INTERFACE, mp);
14667
14668   mp->sw_if_index = ntohl (sw_if_index);
14669   mp->ip4_table_index = ntohl (ip4_table_index);
14670   mp->ip6_table_index = ntohl (ip6_table_index);
14671   mp->l2_table_index = ntohl (l2_table_index);
14672   mp->is_add = is_add;
14673
14674   S (mp);
14675   W (ret);
14676   return ret;
14677 }
14678
14679 static int
14680 api_ip_address_dump (vat_main_t * vam)
14681 {
14682   unformat_input_t *i = vam->input;
14683   vl_api_ip_address_dump_t *mp;
14684   vl_api_control_ping_t *mp_ping;
14685   u32 sw_if_index = ~0;
14686   u8 sw_if_index_set = 0;
14687   u8 ipv4_set = 0;
14688   u8 ipv6_set = 0;
14689   int ret;
14690
14691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14692     {
14693       if (unformat (i, "sw_if_index %d", &sw_if_index))
14694         sw_if_index_set = 1;
14695       else
14696         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14697         sw_if_index_set = 1;
14698       else if (unformat (i, "ipv4"))
14699         ipv4_set = 1;
14700       else if (unformat (i, "ipv6"))
14701         ipv6_set = 1;
14702       else
14703         break;
14704     }
14705
14706   if (ipv4_set && ipv6_set)
14707     {
14708       errmsg ("ipv4 and ipv6 flags cannot be both set");
14709       return -99;
14710     }
14711
14712   if ((!ipv4_set) && (!ipv6_set))
14713     {
14714       errmsg ("no ipv4 nor ipv6 flag set");
14715       return -99;
14716     }
14717
14718   if (sw_if_index_set == 0)
14719     {
14720       errmsg ("missing interface name or sw_if_index");
14721       return -99;
14722     }
14723
14724   vam->current_sw_if_index = sw_if_index;
14725   vam->is_ipv6 = ipv6_set;
14726
14727   M (IP_ADDRESS_DUMP, mp);
14728   mp->sw_if_index = ntohl (sw_if_index);
14729   mp->is_ipv6 = ipv6_set;
14730   S (mp);
14731
14732   /* Use a control ping for synchronization */
14733   MPING (CONTROL_PING, mp_ping);
14734   S (mp_ping);
14735
14736   W (ret);
14737   return ret;
14738 }
14739
14740 static int
14741 api_ip_dump (vat_main_t * vam)
14742 {
14743   vl_api_ip_dump_t *mp;
14744   vl_api_control_ping_t *mp_ping;
14745   unformat_input_t *in = vam->input;
14746   int ipv4_set = 0;
14747   int ipv6_set = 0;
14748   int is_ipv6;
14749   int i;
14750   int ret;
14751
14752   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14753     {
14754       if (unformat (in, "ipv4"))
14755         ipv4_set = 1;
14756       else if (unformat (in, "ipv6"))
14757         ipv6_set = 1;
14758       else
14759         break;
14760     }
14761
14762   if (ipv4_set && ipv6_set)
14763     {
14764       errmsg ("ipv4 and ipv6 flags cannot be both set");
14765       return -99;
14766     }
14767
14768   if ((!ipv4_set) && (!ipv6_set))
14769     {
14770       errmsg ("no ipv4 nor ipv6 flag set");
14771       return -99;
14772     }
14773
14774   is_ipv6 = ipv6_set;
14775   vam->is_ipv6 = is_ipv6;
14776
14777   /* free old data */
14778   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14779     {
14780       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14781     }
14782   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14783
14784   M (IP_DUMP, mp);
14785   mp->is_ipv6 = ipv6_set;
14786   S (mp);
14787
14788   /* Use a control ping for synchronization */
14789   MPING (CONTROL_PING, mp_ping);
14790   S (mp_ping);
14791
14792   W (ret);
14793   return ret;
14794 }
14795
14796 static int
14797 api_ipsec_spd_add_del (vat_main_t * vam)
14798 {
14799   unformat_input_t *i = vam->input;
14800   vl_api_ipsec_spd_add_del_t *mp;
14801   u32 spd_id = ~0;
14802   u8 is_add = 1;
14803   int ret;
14804
14805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14806     {
14807       if (unformat (i, "spd_id %d", &spd_id))
14808         ;
14809       else if (unformat (i, "del"))
14810         is_add = 0;
14811       else
14812         {
14813           clib_warning ("parse error '%U'", format_unformat_error, i);
14814           return -99;
14815         }
14816     }
14817   if (spd_id == ~0)
14818     {
14819       errmsg ("spd_id must be set");
14820       return -99;
14821     }
14822
14823   M (IPSEC_SPD_ADD_DEL, mp);
14824
14825   mp->spd_id = ntohl (spd_id);
14826   mp->is_add = is_add;
14827
14828   S (mp);
14829   W (ret);
14830   return ret;
14831 }
14832
14833 static int
14834 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14835 {
14836   unformat_input_t *i = vam->input;
14837   vl_api_ipsec_interface_add_del_spd_t *mp;
14838   u32 sw_if_index;
14839   u8 sw_if_index_set = 0;
14840   u32 spd_id = (u32) ~ 0;
14841   u8 is_add = 1;
14842   int ret;
14843
14844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14845     {
14846       if (unformat (i, "del"))
14847         is_add = 0;
14848       else if (unformat (i, "spd_id %d", &spd_id))
14849         ;
14850       else
14851         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14852         sw_if_index_set = 1;
14853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14854         sw_if_index_set = 1;
14855       else
14856         {
14857           clib_warning ("parse error '%U'", format_unformat_error, i);
14858           return -99;
14859         }
14860
14861     }
14862
14863   if (spd_id == (u32) ~ 0)
14864     {
14865       errmsg ("spd_id must be set");
14866       return -99;
14867     }
14868
14869   if (sw_if_index_set == 0)
14870     {
14871       errmsg ("missing interface name or sw_if_index");
14872       return -99;
14873     }
14874
14875   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14876
14877   mp->spd_id = ntohl (spd_id);
14878   mp->sw_if_index = ntohl (sw_if_index);
14879   mp->is_add = is_add;
14880
14881   S (mp);
14882   W (ret);
14883   return ret;
14884 }
14885
14886 static int
14887 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14888 {
14889   unformat_input_t *i = vam->input;
14890   vl_api_ipsec_spd_add_del_entry_t *mp;
14891   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14892   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14893   i32 priority = 0;
14894   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14895   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14896   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14897   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14898   int ret;
14899
14900   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14901   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14902   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14903   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14904   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14905   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14906
14907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14908     {
14909       if (unformat (i, "del"))
14910         is_add = 0;
14911       if (unformat (i, "outbound"))
14912         is_outbound = 1;
14913       if (unformat (i, "inbound"))
14914         is_outbound = 0;
14915       else if (unformat (i, "spd_id %d", &spd_id))
14916         ;
14917       else if (unformat (i, "sa_id %d", &sa_id))
14918         ;
14919       else if (unformat (i, "priority %d", &priority))
14920         ;
14921       else if (unformat (i, "protocol %d", &protocol))
14922         ;
14923       else if (unformat (i, "lport_start %d", &lport_start))
14924         ;
14925       else if (unformat (i, "lport_stop %d", &lport_stop))
14926         ;
14927       else if (unformat (i, "rport_start %d", &rport_start))
14928         ;
14929       else if (unformat (i, "rport_stop %d", &rport_stop))
14930         ;
14931       else
14932         if (unformat
14933             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14934         {
14935           is_ipv6 = 0;
14936           is_ip_any = 0;
14937         }
14938       else
14939         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14940         {
14941           is_ipv6 = 0;
14942           is_ip_any = 0;
14943         }
14944       else
14945         if (unformat
14946             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14947         {
14948           is_ipv6 = 0;
14949           is_ip_any = 0;
14950         }
14951       else
14952         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14953         {
14954           is_ipv6 = 0;
14955           is_ip_any = 0;
14956         }
14957       else
14958         if (unformat
14959             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14960         {
14961           is_ipv6 = 1;
14962           is_ip_any = 0;
14963         }
14964       else
14965         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14966         {
14967           is_ipv6 = 1;
14968           is_ip_any = 0;
14969         }
14970       else
14971         if (unformat
14972             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14973         {
14974           is_ipv6 = 1;
14975           is_ip_any = 0;
14976         }
14977       else
14978         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14979         {
14980           is_ipv6 = 1;
14981           is_ip_any = 0;
14982         }
14983       else
14984         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14985         {
14986           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14987             {
14988               clib_warning ("unsupported action: 'resolve'");
14989               return -99;
14990             }
14991         }
14992       else
14993         {
14994           clib_warning ("parse error '%U'", format_unformat_error, i);
14995           return -99;
14996         }
14997
14998     }
14999
15000   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15001
15002   mp->spd_id = ntohl (spd_id);
15003   mp->priority = ntohl (priority);
15004   mp->is_outbound = is_outbound;
15005
15006   mp->is_ipv6 = is_ipv6;
15007   if (is_ipv6 || is_ip_any)
15008     {
15009       clib_memcpy (mp->remote_address_start, &raddr6_start,
15010                    sizeof (ip6_address_t));
15011       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15012                    sizeof (ip6_address_t));
15013       clib_memcpy (mp->local_address_start, &laddr6_start,
15014                    sizeof (ip6_address_t));
15015       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15016                    sizeof (ip6_address_t));
15017     }
15018   else
15019     {
15020       clib_memcpy (mp->remote_address_start, &raddr4_start,
15021                    sizeof (ip4_address_t));
15022       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15023                    sizeof (ip4_address_t));
15024       clib_memcpy (mp->local_address_start, &laddr4_start,
15025                    sizeof (ip4_address_t));
15026       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15027                    sizeof (ip4_address_t));
15028     }
15029   mp->protocol = (u8) protocol;
15030   mp->local_port_start = ntohs ((u16) lport_start);
15031   mp->local_port_stop = ntohs ((u16) lport_stop);
15032   mp->remote_port_start = ntohs ((u16) rport_start);
15033   mp->remote_port_stop = ntohs ((u16) rport_stop);
15034   mp->policy = (u8) policy;
15035   mp->sa_id = ntohl (sa_id);
15036   mp->is_add = is_add;
15037   mp->is_ip_any = is_ip_any;
15038   S (mp);
15039   W (ret);
15040   return ret;
15041 }
15042
15043 static int
15044 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15045 {
15046   unformat_input_t *i = vam->input;
15047   vl_api_ipsec_sad_add_del_entry_t *mp;
15048   u32 sad_id = 0, spi = 0;
15049   u8 *ck = 0, *ik = 0;
15050   u8 is_add = 1;
15051
15052   u8 protocol = IPSEC_PROTOCOL_AH;
15053   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15054   u32 crypto_alg = 0, integ_alg = 0;
15055   ip4_address_t tun_src4;
15056   ip4_address_t tun_dst4;
15057   ip6_address_t tun_src6;
15058   ip6_address_t tun_dst6;
15059   int ret;
15060
15061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (i, "del"))
15064         is_add = 0;
15065       else if (unformat (i, "sad_id %d", &sad_id))
15066         ;
15067       else if (unformat (i, "spi %d", &spi))
15068         ;
15069       else if (unformat (i, "esp"))
15070         protocol = IPSEC_PROTOCOL_ESP;
15071       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15072         {
15073           is_tunnel = 1;
15074           is_tunnel_ipv6 = 0;
15075         }
15076       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15077         {
15078           is_tunnel = 1;
15079           is_tunnel_ipv6 = 0;
15080         }
15081       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15082         {
15083           is_tunnel = 1;
15084           is_tunnel_ipv6 = 1;
15085         }
15086       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15087         {
15088           is_tunnel = 1;
15089           is_tunnel_ipv6 = 1;
15090         }
15091       else
15092         if (unformat
15093             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15094         {
15095           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
15096               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15097             {
15098               clib_warning ("unsupported crypto-alg: '%U'",
15099                             format_ipsec_crypto_alg, crypto_alg);
15100               return -99;
15101             }
15102         }
15103       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15104         ;
15105       else
15106         if (unformat
15107             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15108         {
15109           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
15110               integ_alg >= IPSEC_INTEG_N_ALG)
15111             {
15112               clib_warning ("unsupported integ-alg: '%U'",
15113                             format_ipsec_integ_alg, integ_alg);
15114               return -99;
15115             }
15116         }
15117       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15118         ;
15119       else
15120         {
15121           clib_warning ("parse error '%U'", format_unformat_error, i);
15122           return -99;
15123         }
15124
15125     }
15126
15127   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15128
15129   mp->sad_id = ntohl (sad_id);
15130   mp->is_add = is_add;
15131   mp->protocol = protocol;
15132   mp->spi = ntohl (spi);
15133   mp->is_tunnel = is_tunnel;
15134   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15135   mp->crypto_algorithm = crypto_alg;
15136   mp->integrity_algorithm = integ_alg;
15137   mp->crypto_key_length = vec_len (ck);
15138   mp->integrity_key_length = vec_len (ik);
15139
15140   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15141     mp->crypto_key_length = sizeof (mp->crypto_key);
15142
15143   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15144     mp->integrity_key_length = sizeof (mp->integrity_key);
15145
15146   if (ck)
15147     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15148   if (ik)
15149     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15150
15151   if (is_tunnel)
15152     {
15153       if (is_tunnel_ipv6)
15154         {
15155           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15156                        sizeof (ip6_address_t));
15157           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15158                        sizeof (ip6_address_t));
15159         }
15160       else
15161         {
15162           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15163                        sizeof (ip4_address_t));
15164           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15165                        sizeof (ip4_address_t));
15166         }
15167     }
15168
15169   S (mp);
15170   W (ret);
15171   return ret;
15172 }
15173
15174 static int
15175 api_ipsec_sa_set_key (vat_main_t * vam)
15176 {
15177   unformat_input_t *i = vam->input;
15178   vl_api_ipsec_sa_set_key_t *mp;
15179   u32 sa_id;
15180   u8 *ck = 0, *ik = 0;
15181   int ret;
15182
15183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15184     {
15185       if (unformat (i, "sa_id %d", &sa_id))
15186         ;
15187       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15188         ;
15189       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15190         ;
15191       else
15192         {
15193           clib_warning ("parse error '%U'", format_unformat_error, i);
15194           return -99;
15195         }
15196     }
15197
15198   M (IPSEC_SA_SET_KEY, mp);
15199
15200   mp->sa_id = ntohl (sa_id);
15201   mp->crypto_key_length = vec_len (ck);
15202   mp->integrity_key_length = vec_len (ik);
15203
15204   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15205     mp->crypto_key_length = sizeof (mp->crypto_key);
15206
15207   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15208     mp->integrity_key_length = sizeof (mp->integrity_key);
15209
15210   if (ck)
15211     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15212   if (ik)
15213     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15214
15215   S (mp);
15216   W (ret);
15217   return ret;
15218 }
15219
15220 static int
15221 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15222 {
15223   unformat_input_t *i = vam->input;
15224   vl_api_ipsec_tunnel_if_add_del_t *mp;
15225   u32 local_spi = 0, remote_spi = 0;
15226   u32 crypto_alg = 0, integ_alg = 0;
15227   u8 *lck = NULL, *rck = NULL;
15228   u8 *lik = NULL, *rik = NULL;
15229   ip4_address_t local_ip = { {0} };
15230   ip4_address_t remote_ip = { {0} };
15231   u8 is_add = 1;
15232   u8 esn = 0;
15233   u8 anti_replay = 0;
15234   int ret;
15235
15236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15237     {
15238       if (unformat (i, "del"))
15239         is_add = 0;
15240       else if (unformat (i, "esn"))
15241         esn = 1;
15242       else if (unformat (i, "anti_replay"))
15243         anti_replay = 1;
15244       else if (unformat (i, "local_spi %d", &local_spi))
15245         ;
15246       else if (unformat (i, "remote_spi %d", &remote_spi))
15247         ;
15248       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15249         ;
15250       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15251         ;
15252       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15253         ;
15254       else
15255         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15256         ;
15257       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15258         ;
15259       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15260         ;
15261       else
15262         if (unformat
15263             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15264         {
15265           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
15266               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15267             {
15268               errmsg ("unsupported crypto-alg: '%U'\n",
15269                       format_ipsec_crypto_alg, crypto_alg);
15270               return -99;
15271             }
15272         }
15273       else
15274         if (unformat
15275             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15276         {
15277           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
15278               integ_alg >= IPSEC_INTEG_N_ALG)
15279             {
15280               errmsg ("unsupported integ-alg: '%U'\n",
15281                       format_ipsec_integ_alg, integ_alg);
15282               return -99;
15283             }
15284         }
15285       else
15286         {
15287           errmsg ("parse error '%U'\n", format_unformat_error, i);
15288           return -99;
15289         }
15290     }
15291
15292   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15293
15294   mp->is_add = is_add;
15295   mp->esn = esn;
15296   mp->anti_replay = anti_replay;
15297
15298   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15299   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15300
15301   mp->local_spi = htonl (local_spi);
15302   mp->remote_spi = htonl (remote_spi);
15303   mp->crypto_alg = (u8) crypto_alg;
15304
15305   mp->local_crypto_key_len = 0;
15306   if (lck)
15307     {
15308       mp->local_crypto_key_len = vec_len (lck);
15309       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15310         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15311       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15312     }
15313
15314   mp->remote_crypto_key_len = 0;
15315   if (rck)
15316     {
15317       mp->remote_crypto_key_len = vec_len (rck);
15318       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15319         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15320       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15321     }
15322
15323   mp->integ_alg = (u8) integ_alg;
15324
15325   mp->local_integ_key_len = 0;
15326   if (lik)
15327     {
15328       mp->local_integ_key_len = vec_len (lik);
15329       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15330         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15331       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15332     }
15333
15334   mp->remote_integ_key_len = 0;
15335   if (rik)
15336     {
15337       mp->remote_integ_key_len = vec_len (rik);
15338       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15339         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15340       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15341     }
15342
15343   S (mp);
15344   W (ret);
15345   return ret;
15346 }
15347
15348 static void
15349 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15350 {
15351   vat_main_t *vam = &vat_main;
15352
15353   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15354          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15355          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15356          "tunnel_src_addr %U tunnel_dst_addr %U "
15357          "salt %u seq_outbound %lu last_seq_inbound %lu "
15358          "replay_window %lu total_data_size %lu\n",
15359          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15360          mp->protocol,
15361          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15362          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15363          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15364          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15365          mp->tunnel_src_addr,
15366          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15367          mp->tunnel_dst_addr,
15368          ntohl (mp->salt),
15369          clib_net_to_host_u64 (mp->seq_outbound),
15370          clib_net_to_host_u64 (mp->last_seq_inbound),
15371          clib_net_to_host_u64 (mp->replay_window),
15372          clib_net_to_host_u64 (mp->total_data_size));
15373 }
15374
15375 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15376 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15377
15378 static void vl_api_ipsec_sa_details_t_handler_json
15379   (vl_api_ipsec_sa_details_t * mp)
15380 {
15381   vat_main_t *vam = &vat_main;
15382   vat_json_node_t *node = NULL;
15383   struct in_addr src_ip4, dst_ip4;
15384   struct in6_addr src_ip6, dst_ip6;
15385
15386   if (VAT_JSON_ARRAY != vam->json_tree.type)
15387     {
15388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15389       vat_json_init_array (&vam->json_tree);
15390     }
15391   node = vat_json_array_add (&vam->json_tree);
15392
15393   vat_json_init_object (node);
15394   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15396   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15397   vat_json_object_add_uint (node, "proto", mp->protocol);
15398   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15399   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15400   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15401   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15402   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15403   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15404   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15405                              mp->crypto_key_len);
15406   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15407                              mp->integ_key_len);
15408   if (mp->is_tunnel_ip6)
15409     {
15410       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15411       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15412       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15413       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15414     }
15415   else
15416     {
15417       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15418       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15419       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15420       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15421     }
15422   vat_json_object_add_uint (node, "replay_window",
15423                             clib_net_to_host_u64 (mp->replay_window));
15424   vat_json_object_add_uint (node, "total_data_size",
15425                             clib_net_to_host_u64 (mp->total_data_size));
15426
15427 }
15428
15429 static int
15430 api_ipsec_sa_dump (vat_main_t * vam)
15431 {
15432   unformat_input_t *i = vam->input;
15433   vl_api_ipsec_sa_dump_t *mp;
15434   vl_api_control_ping_t *mp_ping;
15435   u32 sa_id = ~0;
15436   int ret;
15437
15438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15439     {
15440       if (unformat (i, "sa_id %d", &sa_id))
15441         ;
15442       else
15443         {
15444           clib_warning ("parse error '%U'", format_unformat_error, i);
15445           return -99;
15446         }
15447     }
15448
15449   M (IPSEC_SA_DUMP, mp);
15450
15451   mp->sa_id = ntohl (sa_id);
15452
15453   S (mp);
15454
15455   /* Use a control ping for synchronization */
15456   M (CONTROL_PING, mp_ping);
15457   S (mp_ping);
15458
15459   W (ret);
15460   return ret;
15461 }
15462
15463 static int
15464 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15465 {
15466   unformat_input_t *i = vam->input;
15467   vl_api_ipsec_tunnel_if_set_key_t *mp;
15468   u32 sw_if_index = ~0;
15469   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15470   u8 *key = 0;
15471   u32 alg = ~0;
15472   int ret;
15473
15474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15477         ;
15478       else
15479         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15480         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15481       else
15482         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15483         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15484       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15485         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15486       else
15487         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15488         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15489       else if (unformat (i, "%U", unformat_hex_string, &key))
15490         ;
15491       else
15492         {
15493           clib_warning ("parse error '%U'", format_unformat_error, i);
15494           return -99;
15495         }
15496     }
15497
15498   if (sw_if_index == ~0)
15499     {
15500       errmsg ("interface must be specified");
15501       return -99;
15502     }
15503
15504   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15505     {
15506       errmsg ("key type must be specified");
15507       return -99;
15508     }
15509
15510   if (alg == ~0)
15511     {
15512       errmsg ("algorithm must be specified");
15513       return -99;
15514     }
15515
15516   if (vec_len (key) == 0)
15517     {
15518       errmsg ("key must be specified");
15519       return -99;
15520     }
15521
15522   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15523
15524   mp->sw_if_index = htonl (sw_if_index);
15525   mp->alg = alg;
15526   mp->key_type = key_type;
15527   mp->key_len = vec_len (key);
15528   clib_memcpy (mp->key, key, vec_len (key));
15529
15530   S (mp);
15531   W (ret);
15532
15533   return ret;
15534 }
15535
15536 static int
15537 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15538 {
15539   unformat_input_t *i = vam->input;
15540   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15541   u32 sw_if_index = ~0;
15542   u32 sa_id = ~0;
15543   u8 is_outbound = (u8) ~ 0;
15544   int ret;
15545
15546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15547     {
15548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15549         ;
15550       else if (unformat (i, "sa_id %d", &sa_id))
15551         ;
15552       else if (unformat (i, "outbound"))
15553         is_outbound = 1;
15554       else if (unformat (i, "inbound"))
15555         is_outbound = 0;
15556       else
15557         {
15558           clib_warning ("parse error '%U'", format_unformat_error, i);
15559           return -99;
15560         }
15561     }
15562
15563   if (sw_if_index == ~0)
15564     {
15565       errmsg ("interface must be specified");
15566       return -99;
15567     }
15568
15569   if (sa_id == ~0)
15570     {
15571       errmsg ("SA ID must be specified");
15572       return -99;
15573     }
15574
15575   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15576
15577   mp->sw_if_index = htonl (sw_if_index);
15578   mp->sa_id = htonl (sa_id);
15579   mp->is_outbound = is_outbound;
15580
15581   S (mp);
15582   W (ret);
15583
15584   return ret;
15585 }
15586
15587 static int
15588 api_ikev2_profile_add_del (vat_main_t * vam)
15589 {
15590   unformat_input_t *i = vam->input;
15591   vl_api_ikev2_profile_add_del_t *mp;
15592   u8 is_add = 1;
15593   u8 *name = 0;
15594   int ret;
15595
15596   const char *valid_chars = "a-zA-Z0-9_";
15597
15598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15599     {
15600       if (unformat (i, "del"))
15601         is_add = 0;
15602       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15603         vec_add1 (name, 0);
15604       else
15605         {
15606           errmsg ("parse error '%U'", format_unformat_error, i);
15607           return -99;
15608         }
15609     }
15610
15611   if (!vec_len (name))
15612     {
15613       errmsg ("profile name must be specified");
15614       return -99;
15615     }
15616
15617   if (vec_len (name) > 64)
15618     {
15619       errmsg ("profile name too long");
15620       return -99;
15621     }
15622
15623   M (IKEV2_PROFILE_ADD_DEL, mp);
15624
15625   clib_memcpy (mp->name, name, vec_len (name));
15626   mp->is_add = is_add;
15627   vec_free (name);
15628
15629   S (mp);
15630   W (ret);
15631   return ret;
15632 }
15633
15634 static int
15635 api_ikev2_profile_set_auth (vat_main_t * vam)
15636 {
15637   unformat_input_t *i = vam->input;
15638   vl_api_ikev2_profile_set_auth_t *mp;
15639   u8 *name = 0;
15640   u8 *data = 0;
15641   u32 auth_method = 0;
15642   u8 is_hex = 0;
15643   int ret;
15644
15645   const char *valid_chars = "a-zA-Z0-9_";
15646
15647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15648     {
15649       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15650         vec_add1 (name, 0);
15651       else if (unformat (i, "auth_method %U",
15652                          unformat_ikev2_auth_method, &auth_method))
15653         ;
15654       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15655         is_hex = 1;
15656       else if (unformat (i, "auth_data %v", &data))
15657         ;
15658       else
15659         {
15660           errmsg ("parse error '%U'", format_unformat_error, i);
15661           return -99;
15662         }
15663     }
15664
15665   if (!vec_len (name))
15666     {
15667       errmsg ("profile name must be specified");
15668       return -99;
15669     }
15670
15671   if (vec_len (name) > 64)
15672     {
15673       errmsg ("profile name too long");
15674       return -99;
15675     }
15676
15677   if (!vec_len (data))
15678     {
15679       errmsg ("auth_data must be specified");
15680       return -99;
15681     }
15682
15683   if (!auth_method)
15684     {
15685       errmsg ("auth_method must be specified");
15686       return -99;
15687     }
15688
15689   M (IKEV2_PROFILE_SET_AUTH, mp);
15690
15691   mp->is_hex = is_hex;
15692   mp->auth_method = (u8) auth_method;
15693   mp->data_len = vec_len (data);
15694   clib_memcpy (mp->name, name, vec_len (name));
15695   clib_memcpy (mp->data, data, vec_len (data));
15696   vec_free (name);
15697   vec_free (data);
15698
15699   S (mp);
15700   W (ret);
15701   return ret;
15702 }
15703
15704 static int
15705 api_ikev2_profile_set_id (vat_main_t * vam)
15706 {
15707   unformat_input_t *i = vam->input;
15708   vl_api_ikev2_profile_set_id_t *mp;
15709   u8 *name = 0;
15710   u8 *data = 0;
15711   u8 is_local = 0;
15712   u32 id_type = 0;
15713   ip4_address_t ip4;
15714   int ret;
15715
15716   const char *valid_chars = "a-zA-Z0-9_";
15717
15718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15719     {
15720       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15721         vec_add1 (name, 0);
15722       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15723         ;
15724       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15725         {
15726           data = vec_new (u8, 4);
15727           clib_memcpy (data, ip4.as_u8, 4);
15728         }
15729       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15730         ;
15731       else if (unformat (i, "id_data %v", &data))
15732         ;
15733       else if (unformat (i, "local"))
15734         is_local = 1;
15735       else if (unformat (i, "remote"))
15736         is_local = 0;
15737       else
15738         {
15739           errmsg ("parse error '%U'", format_unformat_error, i);
15740           return -99;
15741         }
15742     }
15743
15744   if (!vec_len (name))
15745     {
15746       errmsg ("profile name must be specified");
15747       return -99;
15748     }
15749
15750   if (vec_len (name) > 64)
15751     {
15752       errmsg ("profile name too long");
15753       return -99;
15754     }
15755
15756   if (!vec_len (data))
15757     {
15758       errmsg ("id_data must be specified");
15759       return -99;
15760     }
15761
15762   if (!id_type)
15763     {
15764       errmsg ("id_type must be specified");
15765       return -99;
15766     }
15767
15768   M (IKEV2_PROFILE_SET_ID, mp);
15769
15770   mp->is_local = is_local;
15771   mp->id_type = (u8) id_type;
15772   mp->data_len = vec_len (data);
15773   clib_memcpy (mp->name, name, vec_len (name));
15774   clib_memcpy (mp->data, data, vec_len (data));
15775   vec_free (name);
15776   vec_free (data);
15777
15778   S (mp);
15779   W (ret);
15780   return ret;
15781 }
15782
15783 static int
15784 api_ikev2_profile_set_ts (vat_main_t * vam)
15785 {
15786   unformat_input_t *i = vam->input;
15787   vl_api_ikev2_profile_set_ts_t *mp;
15788   u8 *name = 0;
15789   u8 is_local = 0;
15790   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15791   ip4_address_t start_addr, end_addr;
15792
15793   const char *valid_chars = "a-zA-Z0-9_";
15794   int ret;
15795
15796   start_addr.as_u32 = 0;
15797   end_addr.as_u32 = (u32) ~ 0;
15798
15799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15800     {
15801       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15802         vec_add1 (name, 0);
15803       else if (unformat (i, "protocol %d", &proto))
15804         ;
15805       else if (unformat (i, "start_port %d", &start_port))
15806         ;
15807       else if (unformat (i, "end_port %d", &end_port))
15808         ;
15809       else
15810         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15811         ;
15812       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15813         ;
15814       else if (unformat (i, "local"))
15815         is_local = 1;
15816       else if (unformat (i, "remote"))
15817         is_local = 0;
15818       else
15819         {
15820           errmsg ("parse error '%U'", format_unformat_error, i);
15821           return -99;
15822         }
15823     }
15824
15825   if (!vec_len (name))
15826     {
15827       errmsg ("profile name must be specified");
15828       return -99;
15829     }
15830
15831   if (vec_len (name) > 64)
15832     {
15833       errmsg ("profile name too long");
15834       return -99;
15835     }
15836
15837   M (IKEV2_PROFILE_SET_TS, mp);
15838
15839   mp->is_local = is_local;
15840   mp->proto = (u8) proto;
15841   mp->start_port = (u16) start_port;
15842   mp->end_port = (u16) end_port;
15843   mp->start_addr = start_addr.as_u32;
15844   mp->end_addr = end_addr.as_u32;
15845   clib_memcpy (mp->name, name, vec_len (name));
15846   vec_free (name);
15847
15848   S (mp);
15849   W (ret);
15850   return ret;
15851 }
15852
15853 static int
15854 api_ikev2_set_local_key (vat_main_t * vam)
15855 {
15856   unformat_input_t *i = vam->input;
15857   vl_api_ikev2_set_local_key_t *mp;
15858   u8 *file = 0;
15859   int ret;
15860
15861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15862     {
15863       if (unformat (i, "file %v", &file))
15864         vec_add1 (file, 0);
15865       else
15866         {
15867           errmsg ("parse error '%U'", format_unformat_error, i);
15868           return -99;
15869         }
15870     }
15871
15872   if (!vec_len (file))
15873     {
15874       errmsg ("RSA key file must be specified");
15875       return -99;
15876     }
15877
15878   if (vec_len (file) > 256)
15879     {
15880       errmsg ("file name too long");
15881       return -99;
15882     }
15883
15884   M (IKEV2_SET_LOCAL_KEY, mp);
15885
15886   clib_memcpy (mp->key_file, file, vec_len (file));
15887   vec_free (file);
15888
15889   S (mp);
15890   W (ret);
15891   return ret;
15892 }
15893
15894 static int
15895 api_ikev2_set_responder (vat_main_t * vam)
15896 {
15897   unformat_input_t *i = vam->input;
15898   vl_api_ikev2_set_responder_t *mp;
15899   int ret;
15900   u8 *name = 0;
15901   u32 sw_if_index = ~0;
15902   ip4_address_t address;
15903
15904   const char *valid_chars = "a-zA-Z0-9_";
15905
15906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15907     {
15908       if (unformat
15909           (i, "%U interface %d address %U", unformat_token, valid_chars,
15910            &name, &sw_if_index, unformat_ip4_address, &address))
15911         vec_add1 (name, 0);
15912       else
15913         {
15914           errmsg ("parse error '%U'", format_unformat_error, i);
15915           return -99;
15916         }
15917     }
15918
15919   if (!vec_len (name))
15920     {
15921       errmsg ("profile name must be specified");
15922       return -99;
15923     }
15924
15925   if (vec_len (name) > 64)
15926     {
15927       errmsg ("profile name too long");
15928       return -99;
15929     }
15930
15931   M (IKEV2_SET_RESPONDER, mp);
15932
15933   clib_memcpy (mp->name, name, vec_len (name));
15934   vec_free (name);
15935
15936   mp->sw_if_index = sw_if_index;
15937   clib_memcpy (mp->address, &address, sizeof (address));
15938
15939   S (mp);
15940   W (ret);
15941   return ret;
15942 }
15943
15944 static int
15945 api_ikev2_set_ike_transforms (vat_main_t * vam)
15946 {
15947   unformat_input_t *i = vam->input;
15948   vl_api_ikev2_set_ike_transforms_t *mp;
15949   int ret;
15950   u8 *name = 0;
15951   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15952
15953   const char *valid_chars = "a-zA-Z0-9_";
15954
15955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15956     {
15957       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15958                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15959         vec_add1 (name, 0);
15960       else
15961         {
15962           errmsg ("parse error '%U'", format_unformat_error, i);
15963           return -99;
15964         }
15965     }
15966
15967   if (!vec_len (name))
15968     {
15969       errmsg ("profile name must be specified");
15970       return -99;
15971     }
15972
15973   if (vec_len (name) > 64)
15974     {
15975       errmsg ("profile name too long");
15976       return -99;
15977     }
15978
15979   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15980
15981   clib_memcpy (mp->name, name, vec_len (name));
15982   vec_free (name);
15983   mp->crypto_alg = crypto_alg;
15984   mp->crypto_key_size = crypto_key_size;
15985   mp->integ_alg = integ_alg;
15986   mp->dh_group = dh_group;
15987
15988   S (mp);
15989   W (ret);
15990   return ret;
15991 }
15992
15993
15994 static int
15995 api_ikev2_set_esp_transforms (vat_main_t * vam)
15996 {
15997   unformat_input_t *i = vam->input;
15998   vl_api_ikev2_set_esp_transforms_t *mp;
15999   int ret;
16000   u8 *name = 0;
16001   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16002
16003   const char *valid_chars = "a-zA-Z0-9_";
16004
16005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16006     {
16007       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16008                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16009         vec_add1 (name, 0);
16010       else
16011         {
16012           errmsg ("parse error '%U'", format_unformat_error, i);
16013           return -99;
16014         }
16015     }
16016
16017   if (!vec_len (name))
16018     {
16019       errmsg ("profile name must be specified");
16020       return -99;
16021     }
16022
16023   if (vec_len (name) > 64)
16024     {
16025       errmsg ("profile name too long");
16026       return -99;
16027     }
16028
16029   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16030
16031   clib_memcpy (mp->name, name, vec_len (name));
16032   vec_free (name);
16033   mp->crypto_alg = crypto_alg;
16034   mp->crypto_key_size = crypto_key_size;
16035   mp->integ_alg = integ_alg;
16036   mp->dh_group = dh_group;
16037
16038   S (mp);
16039   W (ret);
16040   return ret;
16041 }
16042
16043 static int
16044 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16045 {
16046   unformat_input_t *i = vam->input;
16047   vl_api_ikev2_set_sa_lifetime_t *mp;
16048   int ret;
16049   u8 *name = 0;
16050   u64 lifetime, lifetime_maxdata;
16051   u32 lifetime_jitter, handover;
16052
16053   const char *valid_chars = "a-zA-Z0-9_";
16054
16055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16056     {
16057       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16058                     &lifetime, &lifetime_jitter, &handover,
16059                     &lifetime_maxdata))
16060         vec_add1 (name, 0);
16061       else
16062         {
16063           errmsg ("parse error '%U'", format_unformat_error, i);
16064           return -99;
16065         }
16066     }
16067
16068   if (!vec_len (name))
16069     {
16070       errmsg ("profile name must be specified");
16071       return -99;
16072     }
16073
16074   if (vec_len (name) > 64)
16075     {
16076       errmsg ("profile name too long");
16077       return -99;
16078     }
16079
16080   M (IKEV2_SET_SA_LIFETIME, mp);
16081
16082   clib_memcpy (mp->name, name, vec_len (name));
16083   vec_free (name);
16084   mp->lifetime = lifetime;
16085   mp->lifetime_jitter = lifetime_jitter;
16086   mp->handover = handover;
16087   mp->lifetime_maxdata = lifetime_maxdata;
16088
16089   S (mp);
16090   W (ret);
16091   return ret;
16092 }
16093
16094 static int
16095 api_ikev2_initiate_sa_init (vat_main_t * vam)
16096 {
16097   unformat_input_t *i = vam->input;
16098   vl_api_ikev2_initiate_sa_init_t *mp;
16099   int ret;
16100   u8 *name = 0;
16101
16102   const char *valid_chars = "a-zA-Z0-9_";
16103
16104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16107         vec_add1 (name, 0);
16108       else
16109         {
16110           errmsg ("parse error '%U'", format_unformat_error, i);
16111           return -99;
16112         }
16113     }
16114
16115   if (!vec_len (name))
16116     {
16117       errmsg ("profile name must be specified");
16118       return -99;
16119     }
16120
16121   if (vec_len (name) > 64)
16122     {
16123       errmsg ("profile name too long");
16124       return -99;
16125     }
16126
16127   M (IKEV2_INITIATE_SA_INIT, mp);
16128
16129   clib_memcpy (mp->name, name, vec_len (name));
16130   vec_free (name);
16131
16132   S (mp);
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16139 {
16140   unformat_input_t *i = vam->input;
16141   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16142   int ret;
16143   u64 ispi;
16144
16145
16146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (i, "%lx", &ispi))
16149         ;
16150       else
16151         {
16152           errmsg ("parse error '%U'", format_unformat_error, i);
16153           return -99;
16154         }
16155     }
16156
16157   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16158
16159   mp->ispi = ispi;
16160
16161   S (mp);
16162   W (ret);
16163   return ret;
16164 }
16165
16166 static int
16167 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16168 {
16169   unformat_input_t *i = vam->input;
16170   vl_api_ikev2_initiate_del_child_sa_t *mp;
16171   int ret;
16172   u32 ispi;
16173
16174
16175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16176     {
16177       if (unformat (i, "%x", &ispi))
16178         ;
16179       else
16180         {
16181           errmsg ("parse error '%U'", format_unformat_error, i);
16182           return -99;
16183         }
16184     }
16185
16186   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16187
16188   mp->ispi = ispi;
16189
16190   S (mp);
16191   W (ret);
16192   return ret;
16193 }
16194
16195 static int
16196 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16197 {
16198   unformat_input_t *i = vam->input;
16199   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16200   int ret;
16201   u32 ispi;
16202
16203
16204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16205     {
16206       if (unformat (i, "%x", &ispi))
16207         ;
16208       else
16209         {
16210           errmsg ("parse error '%U'", format_unformat_error, i);
16211           return -99;
16212         }
16213     }
16214
16215   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16216
16217   mp->ispi = ispi;
16218
16219   S (mp);
16220   W (ret);
16221   return ret;
16222 }
16223
16224 /*
16225  * MAP
16226  */
16227 static int
16228 api_map_add_domain (vat_main_t * vam)
16229 {
16230   unformat_input_t *i = vam->input;
16231   vl_api_map_add_domain_t *mp;
16232
16233   ip4_address_t ip4_prefix;
16234   ip6_address_t ip6_prefix;
16235   ip6_address_t ip6_src;
16236   u32 num_m_args = 0;
16237   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16238     0, psid_length = 0;
16239   u8 is_translation = 0;
16240   u32 mtu = 0;
16241   u32 ip6_src_len = 128;
16242   int ret;
16243
16244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16247                     &ip4_prefix, &ip4_prefix_len))
16248         num_m_args++;
16249       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16250                          &ip6_prefix, &ip6_prefix_len))
16251         num_m_args++;
16252       else
16253         if (unformat
16254             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16255              &ip6_src_len))
16256         num_m_args++;
16257       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16258         num_m_args++;
16259       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16260         num_m_args++;
16261       else if (unformat (i, "psid-offset %d", &psid_offset))
16262         num_m_args++;
16263       else if (unformat (i, "psid-len %d", &psid_length))
16264         num_m_args++;
16265       else if (unformat (i, "mtu %d", &mtu))
16266         num_m_args++;
16267       else if (unformat (i, "map-t"))
16268         is_translation = 1;
16269       else
16270         {
16271           clib_warning ("parse error '%U'", format_unformat_error, i);
16272           return -99;
16273         }
16274     }
16275
16276   if (num_m_args < 3)
16277     {
16278       errmsg ("mandatory argument(s) missing");
16279       return -99;
16280     }
16281
16282   /* Construct the API message */
16283   M (MAP_ADD_DOMAIN, mp);
16284
16285   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16286   mp->ip4_prefix_len = ip4_prefix_len;
16287
16288   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16289   mp->ip6_prefix_len = ip6_prefix_len;
16290
16291   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16292   mp->ip6_src_prefix_len = ip6_src_len;
16293
16294   mp->ea_bits_len = ea_bits_len;
16295   mp->psid_offset = psid_offset;
16296   mp->psid_length = psid_length;
16297   mp->is_translation = is_translation;
16298   mp->mtu = htons (mtu);
16299
16300   /* send it... */
16301   S (mp);
16302
16303   /* Wait for a reply, return good/bad news  */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 static int
16309 api_map_del_domain (vat_main_t * vam)
16310 {
16311   unformat_input_t *i = vam->input;
16312   vl_api_map_del_domain_t *mp;
16313
16314   u32 num_m_args = 0;
16315   u32 index;
16316   int ret;
16317
16318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16319     {
16320       if (unformat (i, "index %d", &index))
16321         num_m_args++;
16322       else
16323         {
16324           clib_warning ("parse error '%U'", format_unformat_error, i);
16325           return -99;
16326         }
16327     }
16328
16329   if (num_m_args != 1)
16330     {
16331       errmsg ("mandatory argument(s) missing");
16332       return -99;
16333     }
16334
16335   /* Construct the API message */
16336   M (MAP_DEL_DOMAIN, mp);
16337
16338   mp->index = ntohl (index);
16339
16340   /* send it... */
16341   S (mp);
16342
16343   /* Wait for a reply, return good/bad news  */
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_map_add_del_rule (vat_main_t * vam)
16350 {
16351   unformat_input_t *i = vam->input;
16352   vl_api_map_add_del_rule_t *mp;
16353   u8 is_add = 1;
16354   ip6_address_t ip6_dst;
16355   u32 num_m_args = 0, index, psid = 0;
16356   int ret;
16357
16358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16359     {
16360       if (unformat (i, "index %d", &index))
16361         num_m_args++;
16362       else if (unformat (i, "psid %d", &psid))
16363         num_m_args++;
16364       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16365         num_m_args++;
16366       else if (unformat (i, "del"))
16367         {
16368           is_add = 0;
16369         }
16370       else
16371         {
16372           clib_warning ("parse error '%U'", format_unformat_error, i);
16373           return -99;
16374         }
16375     }
16376
16377   /* Construct the API message */
16378   M (MAP_ADD_DEL_RULE, mp);
16379
16380   mp->index = ntohl (index);
16381   mp->is_add = is_add;
16382   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16383   mp->psid = ntohs (psid);
16384
16385   /* send it... */
16386   S (mp);
16387
16388   /* Wait for a reply, return good/bad news  */
16389   W (ret);
16390   return ret;
16391 }
16392
16393 static int
16394 api_map_domain_dump (vat_main_t * vam)
16395 {
16396   vl_api_map_domain_dump_t *mp;
16397   vl_api_control_ping_t *mp_ping;
16398   int ret;
16399
16400   /* Construct the API message */
16401   M (MAP_DOMAIN_DUMP, mp);
16402
16403   /* send it... */
16404   S (mp);
16405
16406   /* Use a control ping for synchronization */
16407   MPING (CONTROL_PING, mp_ping);
16408   S (mp_ping);
16409
16410   W (ret);
16411   return ret;
16412 }
16413
16414 static int
16415 api_map_rule_dump (vat_main_t * vam)
16416 {
16417   unformat_input_t *i = vam->input;
16418   vl_api_map_rule_dump_t *mp;
16419   vl_api_control_ping_t *mp_ping;
16420   u32 domain_index = ~0;
16421   int ret;
16422
16423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16424     {
16425       if (unformat (i, "index %u", &domain_index))
16426         ;
16427       else
16428         break;
16429     }
16430
16431   if (domain_index == ~0)
16432     {
16433       clib_warning ("parse error: domain index expected");
16434       return -99;
16435     }
16436
16437   /* Construct the API message */
16438   M (MAP_RULE_DUMP, mp);
16439
16440   mp->domain_index = htonl (domain_index);
16441
16442   /* send it... */
16443   S (mp);
16444
16445   /* Use a control ping for synchronization */
16446   MPING (CONTROL_PING, mp_ping);
16447   S (mp_ping);
16448
16449   W (ret);
16450   return ret;
16451 }
16452
16453 static void vl_api_map_add_domain_reply_t_handler
16454   (vl_api_map_add_domain_reply_t * mp)
16455 {
16456   vat_main_t *vam = &vat_main;
16457   i32 retval = ntohl (mp->retval);
16458
16459   if (vam->async_mode)
16460     {
16461       vam->async_errors += (retval < 0);
16462     }
16463   else
16464     {
16465       vam->retval = retval;
16466       vam->result_ready = 1;
16467     }
16468 }
16469
16470 static void vl_api_map_add_domain_reply_t_handler_json
16471   (vl_api_map_add_domain_reply_t * mp)
16472 {
16473   vat_main_t *vam = &vat_main;
16474   vat_json_node_t node;
16475
16476   vat_json_init_object (&node);
16477   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16478   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16479
16480   vat_json_print (vam->ofp, &node);
16481   vat_json_free (&node);
16482
16483   vam->retval = ntohl (mp->retval);
16484   vam->result_ready = 1;
16485 }
16486
16487 static int
16488 api_get_first_msg_id (vat_main_t * vam)
16489 {
16490   vl_api_get_first_msg_id_t *mp;
16491   unformat_input_t *i = vam->input;
16492   u8 *name;
16493   u8 name_set = 0;
16494   int ret;
16495
16496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16497     {
16498       if (unformat (i, "client %s", &name))
16499         name_set = 1;
16500       else
16501         break;
16502     }
16503
16504   if (name_set == 0)
16505     {
16506       errmsg ("missing client name");
16507       return -99;
16508     }
16509   vec_add1 (name, 0);
16510
16511   if (vec_len (name) > 63)
16512     {
16513       errmsg ("client name too long");
16514       return -99;
16515     }
16516
16517   M (GET_FIRST_MSG_ID, mp);
16518   clib_memcpy (mp->name, name, vec_len (name));
16519   S (mp);
16520   W (ret);
16521   return ret;
16522 }
16523
16524 static int
16525 api_cop_interface_enable_disable (vat_main_t * vam)
16526 {
16527   unformat_input_t *line_input = vam->input;
16528   vl_api_cop_interface_enable_disable_t *mp;
16529   u32 sw_if_index = ~0;
16530   u8 enable_disable = 1;
16531   int ret;
16532
16533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16534     {
16535       if (unformat (line_input, "disable"))
16536         enable_disable = 0;
16537       if (unformat (line_input, "enable"))
16538         enable_disable = 1;
16539       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16540                          vam, &sw_if_index))
16541         ;
16542       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16543         ;
16544       else
16545         break;
16546     }
16547
16548   if (sw_if_index == ~0)
16549     {
16550       errmsg ("missing interface name or sw_if_index");
16551       return -99;
16552     }
16553
16554   /* Construct the API message */
16555   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16556   mp->sw_if_index = ntohl (sw_if_index);
16557   mp->enable_disable = enable_disable;
16558
16559   /* send it... */
16560   S (mp);
16561   /* Wait for the reply */
16562   W (ret);
16563   return ret;
16564 }
16565
16566 static int
16567 api_cop_whitelist_enable_disable (vat_main_t * vam)
16568 {
16569   unformat_input_t *line_input = vam->input;
16570   vl_api_cop_whitelist_enable_disable_t *mp;
16571   u32 sw_if_index = ~0;
16572   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16573   u32 fib_id = 0;
16574   int ret;
16575
16576   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16577     {
16578       if (unformat (line_input, "ip4"))
16579         ip4 = 1;
16580       else if (unformat (line_input, "ip6"))
16581         ip6 = 1;
16582       else if (unformat (line_input, "default"))
16583         default_cop = 1;
16584       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16585                          vam, &sw_if_index))
16586         ;
16587       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16588         ;
16589       else if (unformat (line_input, "fib-id %d", &fib_id))
16590         ;
16591       else
16592         break;
16593     }
16594
16595   if (sw_if_index == ~0)
16596     {
16597       errmsg ("missing interface name or sw_if_index");
16598       return -99;
16599     }
16600
16601   /* Construct the API message */
16602   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16603   mp->sw_if_index = ntohl (sw_if_index);
16604   mp->fib_id = ntohl (fib_id);
16605   mp->ip4 = ip4;
16606   mp->ip6 = ip6;
16607   mp->default_cop = default_cop;
16608
16609   /* send it... */
16610   S (mp);
16611   /* Wait for the reply */
16612   W (ret);
16613   return ret;
16614 }
16615
16616 static int
16617 api_get_node_graph (vat_main_t * vam)
16618 {
16619   vl_api_get_node_graph_t *mp;
16620   int ret;
16621
16622   M (GET_NODE_GRAPH, mp);
16623
16624   /* send it... */
16625   S (mp);
16626   /* Wait for the reply */
16627   W (ret);
16628   return ret;
16629 }
16630
16631 /* *INDENT-OFF* */
16632 /** Used for parsing LISP eids */
16633 typedef CLIB_PACKED(struct{
16634   u8 addr[16];   /**< eid address */
16635   u32 len;       /**< prefix length if IP */
16636   u8 type;      /**< type of eid */
16637 }) lisp_eid_vat_t;
16638 /* *INDENT-ON* */
16639
16640 static uword
16641 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16642 {
16643   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16644
16645   memset (a, 0, sizeof (a[0]));
16646
16647   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16648     {
16649       a->type = 0;              /* ipv4 type */
16650     }
16651   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16652     {
16653       a->type = 1;              /* ipv6 type */
16654     }
16655   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16656     {
16657       a->type = 2;              /* mac type */
16658     }
16659   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16660     {
16661       a->type = 3;              /* NSH type */
16662       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16663       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16664     }
16665   else
16666     {
16667       return 0;
16668     }
16669
16670   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16671     {
16672       return 0;
16673     }
16674
16675   return 1;
16676 }
16677
16678 static int
16679 lisp_eid_size_vat (u8 type)
16680 {
16681   switch (type)
16682     {
16683     case 0:
16684       return 4;
16685     case 1:
16686       return 16;
16687     case 2:
16688       return 6;
16689     case 3:
16690       return 5;
16691     }
16692   return 0;
16693 }
16694
16695 static void
16696 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16697 {
16698   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16699 }
16700
16701 static int
16702 api_one_add_del_locator_set (vat_main_t * vam)
16703 {
16704   unformat_input_t *input = vam->input;
16705   vl_api_one_add_del_locator_set_t *mp;
16706   u8 is_add = 1;
16707   u8 *locator_set_name = NULL;
16708   u8 locator_set_name_set = 0;
16709   vl_api_local_locator_t locator, *locators = 0;
16710   u32 sw_if_index, priority, weight;
16711   u32 data_len = 0;
16712
16713   int ret;
16714   /* Parse args required to build the message */
16715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16716     {
16717       if (unformat (input, "del"))
16718         {
16719           is_add = 0;
16720         }
16721       else if (unformat (input, "locator-set %s", &locator_set_name))
16722         {
16723           locator_set_name_set = 1;
16724         }
16725       else if (unformat (input, "sw_if_index %u p %u w %u",
16726                          &sw_if_index, &priority, &weight))
16727         {
16728           locator.sw_if_index = htonl (sw_if_index);
16729           locator.priority = priority;
16730           locator.weight = weight;
16731           vec_add1 (locators, locator);
16732         }
16733       else
16734         if (unformat
16735             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16736              &sw_if_index, &priority, &weight))
16737         {
16738           locator.sw_if_index = htonl (sw_if_index);
16739           locator.priority = priority;
16740           locator.weight = weight;
16741           vec_add1 (locators, locator);
16742         }
16743       else
16744         break;
16745     }
16746
16747   if (locator_set_name_set == 0)
16748     {
16749       errmsg ("missing locator-set name");
16750       vec_free (locators);
16751       return -99;
16752     }
16753
16754   if (vec_len (locator_set_name) > 64)
16755     {
16756       errmsg ("locator-set name too long");
16757       vec_free (locator_set_name);
16758       vec_free (locators);
16759       return -99;
16760     }
16761   vec_add1 (locator_set_name, 0);
16762
16763   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16764
16765   /* Construct the API message */
16766   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16767
16768   mp->is_add = is_add;
16769   clib_memcpy (mp->locator_set_name, locator_set_name,
16770                vec_len (locator_set_name));
16771   vec_free (locator_set_name);
16772
16773   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16774   if (locators)
16775     clib_memcpy (mp->locators, locators, data_len);
16776   vec_free (locators);
16777
16778   /* send it... */
16779   S (mp);
16780
16781   /* Wait for a reply... */
16782   W (ret);
16783   return ret;
16784 }
16785
16786 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16787
16788 static int
16789 api_one_add_del_locator (vat_main_t * vam)
16790 {
16791   unformat_input_t *input = vam->input;
16792   vl_api_one_add_del_locator_t *mp;
16793   u32 tmp_if_index = ~0;
16794   u32 sw_if_index = ~0;
16795   u8 sw_if_index_set = 0;
16796   u8 sw_if_index_if_name_set = 0;
16797   u32 priority = ~0;
16798   u8 priority_set = 0;
16799   u32 weight = ~0;
16800   u8 weight_set = 0;
16801   u8 is_add = 1;
16802   u8 *locator_set_name = NULL;
16803   u8 locator_set_name_set = 0;
16804   int ret;
16805
16806   /* Parse args required to build the message */
16807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16808     {
16809       if (unformat (input, "del"))
16810         {
16811           is_add = 0;
16812         }
16813       else if (unformat (input, "locator-set %s", &locator_set_name))
16814         {
16815           locator_set_name_set = 1;
16816         }
16817       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16818                          &tmp_if_index))
16819         {
16820           sw_if_index_if_name_set = 1;
16821           sw_if_index = tmp_if_index;
16822         }
16823       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16824         {
16825           sw_if_index_set = 1;
16826           sw_if_index = tmp_if_index;
16827         }
16828       else if (unformat (input, "p %d", &priority))
16829         {
16830           priority_set = 1;
16831         }
16832       else if (unformat (input, "w %d", &weight))
16833         {
16834           weight_set = 1;
16835         }
16836       else
16837         break;
16838     }
16839
16840   if (locator_set_name_set == 0)
16841     {
16842       errmsg ("missing locator-set name");
16843       return -99;
16844     }
16845
16846   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16847     {
16848       errmsg ("missing sw_if_index");
16849       vec_free (locator_set_name);
16850       return -99;
16851     }
16852
16853   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16854     {
16855       errmsg ("cannot use both params interface name and sw_if_index");
16856       vec_free (locator_set_name);
16857       return -99;
16858     }
16859
16860   if (priority_set == 0)
16861     {
16862       errmsg ("missing locator-set priority");
16863       vec_free (locator_set_name);
16864       return -99;
16865     }
16866
16867   if (weight_set == 0)
16868     {
16869       errmsg ("missing locator-set weight");
16870       vec_free (locator_set_name);
16871       return -99;
16872     }
16873
16874   if (vec_len (locator_set_name) > 64)
16875     {
16876       errmsg ("locator-set name too long");
16877       vec_free (locator_set_name);
16878       return -99;
16879     }
16880   vec_add1 (locator_set_name, 0);
16881
16882   /* Construct the API message */
16883   M (ONE_ADD_DEL_LOCATOR, mp);
16884
16885   mp->is_add = is_add;
16886   mp->sw_if_index = ntohl (sw_if_index);
16887   mp->priority = priority;
16888   mp->weight = weight;
16889   clib_memcpy (mp->locator_set_name, locator_set_name,
16890                vec_len (locator_set_name));
16891   vec_free (locator_set_name);
16892
16893   /* send it... */
16894   S (mp);
16895
16896   /* Wait for a reply... */
16897   W (ret);
16898   return ret;
16899 }
16900
16901 #define api_lisp_add_del_locator api_one_add_del_locator
16902
16903 uword
16904 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16905 {
16906   u32 *key_id = va_arg (*args, u32 *);
16907   u8 *s = 0;
16908
16909   if (unformat (input, "%s", &s))
16910     {
16911       if (!strcmp ((char *) s, "sha1"))
16912         key_id[0] = HMAC_SHA_1_96;
16913       else if (!strcmp ((char *) s, "sha256"))
16914         key_id[0] = HMAC_SHA_256_128;
16915       else
16916         {
16917           clib_warning ("invalid key_id: '%s'", s);
16918           key_id[0] = HMAC_NO_KEY;
16919         }
16920     }
16921   else
16922     return 0;
16923
16924   vec_free (s);
16925   return 1;
16926 }
16927
16928 static int
16929 api_one_add_del_local_eid (vat_main_t * vam)
16930 {
16931   unformat_input_t *input = vam->input;
16932   vl_api_one_add_del_local_eid_t *mp;
16933   u8 is_add = 1;
16934   u8 eid_set = 0;
16935   lisp_eid_vat_t _eid, *eid = &_eid;
16936   u8 *locator_set_name = 0;
16937   u8 locator_set_name_set = 0;
16938   u32 vni = 0;
16939   u16 key_id = 0;
16940   u8 *key = 0;
16941   int ret;
16942
16943   /* Parse args required to build the message */
16944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16945     {
16946       if (unformat (input, "del"))
16947         {
16948           is_add = 0;
16949         }
16950       else if (unformat (input, "vni %d", &vni))
16951         {
16952           ;
16953         }
16954       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16955         {
16956           eid_set = 1;
16957         }
16958       else if (unformat (input, "locator-set %s", &locator_set_name))
16959         {
16960           locator_set_name_set = 1;
16961         }
16962       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16963         ;
16964       else if (unformat (input, "secret-key %_%v%_", &key))
16965         ;
16966       else
16967         break;
16968     }
16969
16970   if (locator_set_name_set == 0)
16971     {
16972       errmsg ("missing locator-set name");
16973       return -99;
16974     }
16975
16976   if (0 == eid_set)
16977     {
16978       errmsg ("EID address not set!");
16979       vec_free (locator_set_name);
16980       return -99;
16981     }
16982
16983   if (key && (0 == key_id))
16984     {
16985       errmsg ("invalid key_id!");
16986       return -99;
16987     }
16988
16989   if (vec_len (key) > 64)
16990     {
16991       errmsg ("key too long");
16992       vec_free (key);
16993       return -99;
16994     }
16995
16996   if (vec_len (locator_set_name) > 64)
16997     {
16998       errmsg ("locator-set name too long");
16999       vec_free (locator_set_name);
17000       return -99;
17001     }
17002   vec_add1 (locator_set_name, 0);
17003
17004   /* Construct the API message */
17005   M (ONE_ADD_DEL_LOCAL_EID, mp);
17006
17007   mp->is_add = is_add;
17008   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17009   mp->eid_type = eid->type;
17010   mp->prefix_len = eid->len;
17011   mp->vni = clib_host_to_net_u32 (vni);
17012   mp->key_id = clib_host_to_net_u16 (key_id);
17013   clib_memcpy (mp->locator_set_name, locator_set_name,
17014                vec_len (locator_set_name));
17015   clib_memcpy (mp->key, key, vec_len (key));
17016
17017   vec_free (locator_set_name);
17018   vec_free (key);
17019
17020   /* send it... */
17021   S (mp);
17022
17023   /* Wait for a reply... */
17024   W (ret);
17025   return ret;
17026 }
17027
17028 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17029
17030 static int
17031 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17032 {
17033   u32 dp_table = 0, vni = 0;;
17034   unformat_input_t *input = vam->input;
17035   vl_api_gpe_add_del_fwd_entry_t *mp;
17036   u8 is_add = 1;
17037   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17038   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17039   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17040   u32 action = ~0, w;
17041   ip4_address_t rmt_rloc4, lcl_rloc4;
17042   ip6_address_t rmt_rloc6, lcl_rloc6;
17043   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17044   int ret;
17045
17046   memset (&rloc, 0, sizeof (rloc));
17047
17048   /* Parse args required to build the message */
17049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17050     {
17051       if (unformat (input, "del"))
17052         is_add = 0;
17053       else if (unformat (input, "add"))
17054         is_add = 1;
17055       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17056         {
17057           rmt_eid_set = 1;
17058         }
17059       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17060         {
17061           lcl_eid_set = 1;
17062         }
17063       else if (unformat (input, "vrf %d", &dp_table))
17064         ;
17065       else if (unformat (input, "bd %d", &dp_table))
17066         ;
17067       else if (unformat (input, "vni %d", &vni))
17068         ;
17069       else if (unformat (input, "w %d", &w))
17070         {
17071           if (!curr_rloc)
17072             {
17073               errmsg ("No RLOC configured for setting priority/weight!");
17074               return -99;
17075             }
17076           curr_rloc->weight = w;
17077         }
17078       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17079                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17080         {
17081           rloc.is_ip4 = 1;
17082
17083           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17084           rloc.weight = 0;
17085           vec_add1 (lcl_locs, rloc);
17086
17087           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17088           vec_add1 (rmt_locs, rloc);
17089           /* weight saved in rmt loc */
17090           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17091         }
17092       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17093                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17094         {
17095           rloc.is_ip4 = 0;
17096           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17097           rloc.weight = 0;
17098           vec_add1 (lcl_locs, rloc);
17099
17100           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17101           vec_add1 (rmt_locs, rloc);
17102           /* weight saved in rmt loc */
17103           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17104         }
17105       else if (unformat (input, "action %d", &action))
17106         {
17107           ;
17108         }
17109       else
17110         {
17111           clib_warning ("parse error '%U'", format_unformat_error, input);
17112           return -99;
17113         }
17114     }
17115
17116   if (!rmt_eid_set)
17117     {
17118       errmsg ("remote eid addresses not set");
17119       return -99;
17120     }
17121
17122   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17123     {
17124       errmsg ("eid types don't match");
17125       return -99;
17126     }
17127
17128   if (0 == rmt_locs && (u32) ~ 0 == action)
17129     {
17130       errmsg ("action not set for negative mapping");
17131       return -99;
17132     }
17133
17134   /* Construct the API message */
17135   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17136       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17137
17138   mp->is_add = is_add;
17139   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17140   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17141   mp->eid_type = rmt_eid->type;
17142   mp->dp_table = clib_host_to_net_u32 (dp_table);
17143   mp->vni = clib_host_to_net_u32 (vni);
17144   mp->rmt_len = rmt_eid->len;
17145   mp->lcl_len = lcl_eid->len;
17146   mp->action = action;
17147
17148   if (0 != rmt_locs && 0 != lcl_locs)
17149     {
17150       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17151       clib_memcpy (mp->locs, lcl_locs,
17152                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17153
17154       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17155       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17156                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17157     }
17158   vec_free (lcl_locs);
17159   vec_free (rmt_locs);
17160
17161   /* send it... */
17162   S (mp);
17163
17164   /* Wait for a reply... */
17165   W (ret);
17166   return ret;
17167 }
17168
17169 static int
17170 api_one_add_del_map_server (vat_main_t * vam)
17171 {
17172   unformat_input_t *input = vam->input;
17173   vl_api_one_add_del_map_server_t *mp;
17174   u8 is_add = 1;
17175   u8 ipv4_set = 0;
17176   u8 ipv6_set = 0;
17177   ip4_address_t ipv4;
17178   ip6_address_t ipv6;
17179   int ret;
17180
17181   /* Parse args required to build the message */
17182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17183     {
17184       if (unformat (input, "del"))
17185         {
17186           is_add = 0;
17187         }
17188       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17189         {
17190           ipv4_set = 1;
17191         }
17192       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17193         {
17194           ipv6_set = 1;
17195         }
17196       else
17197         break;
17198     }
17199
17200   if (ipv4_set && ipv6_set)
17201     {
17202       errmsg ("both eid v4 and v6 addresses set");
17203       return -99;
17204     }
17205
17206   if (!ipv4_set && !ipv6_set)
17207     {
17208       errmsg ("eid addresses not set");
17209       return -99;
17210     }
17211
17212   /* Construct the API message */
17213   M (ONE_ADD_DEL_MAP_SERVER, mp);
17214
17215   mp->is_add = is_add;
17216   if (ipv6_set)
17217     {
17218       mp->is_ipv6 = 1;
17219       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17220     }
17221   else
17222     {
17223       mp->is_ipv6 = 0;
17224       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17225     }
17226
17227   /* send it... */
17228   S (mp);
17229
17230   /* Wait for a reply... */
17231   W (ret);
17232   return ret;
17233 }
17234
17235 #define api_lisp_add_del_map_server api_one_add_del_map_server
17236
17237 static int
17238 api_one_add_del_map_resolver (vat_main_t * vam)
17239 {
17240   unformat_input_t *input = vam->input;
17241   vl_api_one_add_del_map_resolver_t *mp;
17242   u8 is_add = 1;
17243   u8 ipv4_set = 0;
17244   u8 ipv6_set = 0;
17245   ip4_address_t ipv4;
17246   ip6_address_t ipv6;
17247   int ret;
17248
17249   /* Parse args required to build the message */
17250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17251     {
17252       if (unformat (input, "del"))
17253         {
17254           is_add = 0;
17255         }
17256       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17257         {
17258           ipv4_set = 1;
17259         }
17260       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17261         {
17262           ipv6_set = 1;
17263         }
17264       else
17265         break;
17266     }
17267
17268   if (ipv4_set && ipv6_set)
17269     {
17270       errmsg ("both eid v4 and v6 addresses set");
17271       return -99;
17272     }
17273
17274   if (!ipv4_set && !ipv6_set)
17275     {
17276       errmsg ("eid addresses not set");
17277       return -99;
17278     }
17279
17280   /* Construct the API message */
17281   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17282
17283   mp->is_add = is_add;
17284   if (ipv6_set)
17285     {
17286       mp->is_ipv6 = 1;
17287       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17288     }
17289   else
17290     {
17291       mp->is_ipv6 = 0;
17292       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17293     }
17294
17295   /* send it... */
17296   S (mp);
17297
17298   /* Wait for a reply... */
17299   W (ret);
17300   return ret;
17301 }
17302
17303 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17304
17305 static int
17306 api_lisp_gpe_enable_disable (vat_main_t * vam)
17307 {
17308   unformat_input_t *input = vam->input;
17309   vl_api_gpe_enable_disable_t *mp;
17310   u8 is_set = 0;
17311   u8 is_en = 1;
17312   int ret;
17313
17314   /* Parse args required to build the message */
17315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17316     {
17317       if (unformat (input, "enable"))
17318         {
17319           is_set = 1;
17320           is_en = 1;
17321         }
17322       else if (unformat (input, "disable"))
17323         {
17324           is_set = 1;
17325           is_en = 0;
17326         }
17327       else
17328         break;
17329     }
17330
17331   if (is_set == 0)
17332     {
17333       errmsg ("Value not set");
17334       return -99;
17335     }
17336
17337   /* Construct the API message */
17338   M (GPE_ENABLE_DISABLE, mp);
17339
17340   mp->is_en = is_en;
17341
17342   /* send it... */
17343   S (mp);
17344
17345   /* Wait for a reply... */
17346   W (ret);
17347   return ret;
17348 }
17349
17350 static int
17351 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17352 {
17353   unformat_input_t *input = vam->input;
17354   vl_api_one_rloc_probe_enable_disable_t *mp;
17355   u8 is_set = 0;
17356   u8 is_en = 0;
17357   int ret;
17358
17359   /* Parse args required to build the message */
17360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17361     {
17362       if (unformat (input, "enable"))
17363         {
17364           is_set = 1;
17365           is_en = 1;
17366         }
17367       else if (unformat (input, "disable"))
17368         is_set = 1;
17369       else
17370         break;
17371     }
17372
17373   if (!is_set)
17374     {
17375       errmsg ("Value not set");
17376       return -99;
17377     }
17378
17379   /* Construct the API message */
17380   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17381
17382   mp->is_enabled = is_en;
17383
17384   /* send it... */
17385   S (mp);
17386
17387   /* Wait for a reply... */
17388   W (ret);
17389   return ret;
17390 }
17391
17392 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17393
17394 static int
17395 api_one_map_register_enable_disable (vat_main_t * vam)
17396 {
17397   unformat_input_t *input = vam->input;
17398   vl_api_one_map_register_enable_disable_t *mp;
17399   u8 is_set = 0;
17400   u8 is_en = 0;
17401   int ret;
17402
17403   /* Parse args required to build the message */
17404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17405     {
17406       if (unformat (input, "enable"))
17407         {
17408           is_set = 1;
17409           is_en = 1;
17410         }
17411       else if (unformat (input, "disable"))
17412         is_set = 1;
17413       else
17414         break;
17415     }
17416
17417   if (!is_set)
17418     {
17419       errmsg ("Value not set");
17420       return -99;
17421     }
17422
17423   /* Construct the API message */
17424   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17425
17426   mp->is_enabled = is_en;
17427
17428   /* send it... */
17429   S (mp);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17437
17438 static int
17439 api_one_enable_disable (vat_main_t * vam)
17440 {
17441   unformat_input_t *input = vam->input;
17442   vl_api_one_enable_disable_t *mp;
17443   u8 is_set = 0;
17444   u8 is_en = 0;
17445   int ret;
17446
17447   /* Parse args required to build the message */
17448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (input, "enable"))
17451         {
17452           is_set = 1;
17453           is_en = 1;
17454         }
17455       else if (unformat (input, "disable"))
17456         {
17457           is_set = 1;
17458         }
17459       else
17460         break;
17461     }
17462
17463   if (!is_set)
17464     {
17465       errmsg ("Value not set");
17466       return -99;
17467     }
17468
17469   /* Construct the API message */
17470   M (ONE_ENABLE_DISABLE, mp);
17471
17472   mp->is_en = is_en;
17473
17474   /* send it... */
17475   S (mp);
17476
17477   /* Wait for a reply... */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 #define api_lisp_enable_disable api_one_enable_disable
17483
17484 static int
17485 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17486 {
17487   unformat_input_t *input = vam->input;
17488   vl_api_one_enable_disable_xtr_mode_t *mp;
17489   u8 is_set = 0;
17490   u8 is_en = 0;
17491   int ret;
17492
17493   /* Parse args required to build the message */
17494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17495     {
17496       if (unformat (input, "enable"))
17497         {
17498           is_set = 1;
17499           is_en = 1;
17500         }
17501       else if (unformat (input, "disable"))
17502         {
17503           is_set = 1;
17504         }
17505       else
17506         break;
17507     }
17508
17509   if (!is_set)
17510     {
17511       errmsg ("Value not set");
17512       return -99;
17513     }
17514
17515   /* Construct the API message */
17516   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17517
17518   mp->is_en = is_en;
17519
17520   /* send it... */
17521   S (mp);
17522
17523   /* Wait for a reply... */
17524   W (ret);
17525   return ret;
17526 }
17527
17528 static int
17529 api_one_show_xtr_mode (vat_main_t * vam)
17530 {
17531   vl_api_one_show_xtr_mode_t *mp;
17532   int ret;
17533
17534   /* Construct the API message */
17535   M (ONE_SHOW_XTR_MODE, mp);
17536
17537   /* send it... */
17538   S (mp);
17539
17540   /* Wait for a reply... */
17541   W (ret);
17542   return ret;
17543 }
17544
17545 static int
17546 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17547 {
17548   unformat_input_t *input = vam->input;
17549   vl_api_one_enable_disable_pitr_mode_t *mp;
17550   u8 is_set = 0;
17551   u8 is_en = 0;
17552   int ret;
17553
17554   /* Parse args required to build the message */
17555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17556     {
17557       if (unformat (input, "enable"))
17558         {
17559           is_set = 1;
17560           is_en = 1;
17561         }
17562       else if (unformat (input, "disable"))
17563         {
17564           is_set = 1;
17565         }
17566       else
17567         break;
17568     }
17569
17570   if (!is_set)
17571     {
17572       errmsg ("Value not set");
17573       return -99;
17574     }
17575
17576   /* Construct the API message */
17577   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17578
17579   mp->is_en = is_en;
17580
17581   /* send it... */
17582   S (mp);
17583
17584   /* Wait for a reply... */
17585   W (ret);
17586   return ret;
17587 }
17588
17589 static int
17590 api_one_show_pitr_mode (vat_main_t * vam)
17591 {
17592   vl_api_one_show_pitr_mode_t *mp;
17593   int ret;
17594
17595   /* Construct the API message */
17596   M (ONE_SHOW_PITR_MODE, mp);
17597
17598   /* send it... */
17599   S (mp);
17600
17601   /* Wait for a reply... */
17602   W (ret);
17603   return ret;
17604 }
17605
17606 static int
17607 api_one_enable_disable_petr_mode (vat_main_t * vam)
17608 {
17609   unformat_input_t *input = vam->input;
17610   vl_api_one_enable_disable_petr_mode_t *mp;
17611   u8 is_set = 0;
17612   u8 is_en = 0;
17613   int ret;
17614
17615   /* Parse args required to build the message */
17616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17617     {
17618       if (unformat (input, "enable"))
17619         {
17620           is_set = 1;
17621           is_en = 1;
17622         }
17623       else if (unformat (input, "disable"))
17624         {
17625           is_set = 1;
17626         }
17627       else
17628         break;
17629     }
17630
17631   if (!is_set)
17632     {
17633       errmsg ("Value not set");
17634       return -99;
17635     }
17636
17637   /* Construct the API message */
17638   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17639
17640   mp->is_en = is_en;
17641
17642   /* send it... */
17643   S (mp);
17644
17645   /* Wait for a reply... */
17646   W (ret);
17647   return ret;
17648 }
17649
17650 static int
17651 api_one_show_petr_mode (vat_main_t * vam)
17652 {
17653   vl_api_one_show_petr_mode_t *mp;
17654   int ret;
17655
17656   /* Construct the API message */
17657   M (ONE_SHOW_PETR_MODE, mp);
17658
17659   /* send it... */
17660   S (mp);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 static int
17668 api_show_one_map_register_state (vat_main_t * vam)
17669 {
17670   vl_api_show_one_map_register_state_t *mp;
17671   int ret;
17672
17673   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17674
17675   /* send */
17676   S (mp);
17677
17678   /* wait for reply */
17679   W (ret);
17680   return ret;
17681 }
17682
17683 #define api_show_lisp_map_register_state api_show_one_map_register_state
17684
17685 static int
17686 api_show_one_rloc_probe_state (vat_main_t * vam)
17687 {
17688   vl_api_show_one_rloc_probe_state_t *mp;
17689   int ret;
17690
17691   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17692
17693   /* send */
17694   S (mp);
17695
17696   /* wait for reply */
17697   W (ret);
17698   return ret;
17699 }
17700
17701 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17702
17703 static int
17704 api_one_add_del_ndp_entry (vat_main_t * vam)
17705 {
17706   vl_api_one_add_del_ndp_entry_t *mp;
17707   unformat_input_t *input = vam->input;
17708   u8 is_add = 1;
17709   u8 mac_set = 0;
17710   u8 bd_set = 0;
17711   u8 ip_set = 0;
17712   u8 mac[6] = { 0, };
17713   u8 ip6[16] = { 0, };
17714   u32 bd = ~0;
17715   int ret;
17716
17717   /* Parse args required to build the message */
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "del"))
17721         is_add = 0;
17722       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17723         mac_set = 1;
17724       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17725         ip_set = 1;
17726       else if (unformat (input, "bd %d", &bd))
17727         bd_set = 1;
17728       else
17729         {
17730           errmsg ("parse error '%U'", format_unformat_error, input);
17731           return -99;
17732         }
17733     }
17734
17735   if (!bd_set || !ip_set || (!mac_set && is_add))
17736     {
17737       errmsg ("Missing BD, IP or MAC!");
17738       return -99;
17739     }
17740
17741   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17742   mp->is_add = is_add;
17743   clib_memcpy (mp->mac, mac, 6);
17744   mp->bd = clib_host_to_net_u32 (bd);
17745   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17746
17747   /* send */
17748   S (mp);
17749
17750   /* wait for reply */
17751   W (ret);
17752   return ret;
17753 }
17754
17755 static int
17756 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17757 {
17758   vl_api_one_add_del_l2_arp_entry_t *mp;
17759   unformat_input_t *input = vam->input;
17760   u8 is_add = 1;
17761   u8 mac_set = 0;
17762   u8 bd_set = 0;
17763   u8 ip_set = 0;
17764   u8 mac[6] = { 0, };
17765   u32 ip4 = 0, bd = ~0;
17766   int ret;
17767
17768   /* Parse args required to build the message */
17769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17770     {
17771       if (unformat (input, "del"))
17772         is_add = 0;
17773       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17774         mac_set = 1;
17775       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17776         ip_set = 1;
17777       else if (unformat (input, "bd %d", &bd))
17778         bd_set = 1;
17779       else
17780         {
17781           errmsg ("parse error '%U'", format_unformat_error, input);
17782           return -99;
17783         }
17784     }
17785
17786   if (!bd_set || !ip_set || (!mac_set && is_add))
17787     {
17788       errmsg ("Missing BD, IP or MAC!");
17789       return -99;
17790     }
17791
17792   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17793   mp->is_add = is_add;
17794   clib_memcpy (mp->mac, mac, 6);
17795   mp->bd = clib_host_to_net_u32 (bd);
17796   mp->ip4 = ip4;
17797
17798   /* send */
17799   S (mp);
17800
17801   /* wait for reply */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 static int
17807 api_one_ndp_bd_get (vat_main_t * vam)
17808 {
17809   vl_api_one_ndp_bd_get_t *mp;
17810   int ret;
17811
17812   M (ONE_NDP_BD_GET, mp);
17813
17814   /* send */
17815   S (mp);
17816
17817   /* wait for reply */
17818   W (ret);
17819   return ret;
17820 }
17821
17822 static int
17823 api_one_ndp_entries_get (vat_main_t * vam)
17824 {
17825   vl_api_one_ndp_entries_get_t *mp;
17826   unformat_input_t *input = vam->input;
17827   u8 bd_set = 0;
17828   u32 bd = ~0;
17829   int ret;
17830
17831   /* Parse args required to build the message */
17832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17833     {
17834       if (unformat (input, "bd %d", &bd))
17835         bd_set = 1;
17836       else
17837         {
17838           errmsg ("parse error '%U'", format_unformat_error, input);
17839           return -99;
17840         }
17841     }
17842
17843   if (!bd_set)
17844     {
17845       errmsg ("Expected bridge domain!");
17846       return -99;
17847     }
17848
17849   M (ONE_NDP_ENTRIES_GET, mp);
17850   mp->bd = clib_host_to_net_u32 (bd);
17851
17852   /* send */
17853   S (mp);
17854
17855   /* wait for reply */
17856   W (ret);
17857   return ret;
17858 }
17859
17860 static int
17861 api_one_l2_arp_bd_get (vat_main_t * vam)
17862 {
17863   vl_api_one_l2_arp_bd_get_t *mp;
17864   int ret;
17865
17866   M (ONE_L2_ARP_BD_GET, mp);
17867
17868   /* send */
17869   S (mp);
17870
17871   /* wait for reply */
17872   W (ret);
17873   return ret;
17874 }
17875
17876 static int
17877 api_one_l2_arp_entries_get (vat_main_t * vam)
17878 {
17879   vl_api_one_l2_arp_entries_get_t *mp;
17880   unformat_input_t *input = vam->input;
17881   u8 bd_set = 0;
17882   u32 bd = ~0;
17883   int ret;
17884
17885   /* Parse args required to build the message */
17886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17887     {
17888       if (unformat (input, "bd %d", &bd))
17889         bd_set = 1;
17890       else
17891         {
17892           errmsg ("parse error '%U'", format_unformat_error, input);
17893           return -99;
17894         }
17895     }
17896
17897   if (!bd_set)
17898     {
17899       errmsg ("Expected bridge domain!");
17900       return -99;
17901     }
17902
17903   M (ONE_L2_ARP_ENTRIES_GET, mp);
17904   mp->bd = clib_host_to_net_u32 (bd);
17905
17906   /* send */
17907   S (mp);
17908
17909   /* wait for reply */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 static int
17915 api_one_stats_enable_disable (vat_main_t * vam)
17916 {
17917   vl_api_one_stats_enable_disable_t *mp;
17918   unformat_input_t *input = vam->input;
17919   u8 is_set = 0;
17920   u8 is_en = 0;
17921   int ret;
17922
17923   /* Parse args required to build the message */
17924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17925     {
17926       if (unformat (input, "enable"))
17927         {
17928           is_set = 1;
17929           is_en = 1;
17930         }
17931       else if (unformat (input, "disable"))
17932         {
17933           is_set = 1;
17934         }
17935       else
17936         break;
17937     }
17938
17939   if (!is_set)
17940     {
17941       errmsg ("Value not set");
17942       return -99;
17943     }
17944
17945   M (ONE_STATS_ENABLE_DISABLE, mp);
17946   mp->is_en = is_en;
17947
17948   /* send */
17949   S (mp);
17950
17951   /* wait for reply */
17952   W (ret);
17953   return ret;
17954 }
17955
17956 static int
17957 api_show_one_stats_enable_disable (vat_main_t * vam)
17958 {
17959   vl_api_show_one_stats_enable_disable_t *mp;
17960   int ret;
17961
17962   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17963
17964   /* send */
17965   S (mp);
17966
17967   /* wait for reply */
17968   W (ret);
17969   return ret;
17970 }
17971
17972 static int
17973 api_show_one_map_request_mode (vat_main_t * vam)
17974 {
17975   vl_api_show_one_map_request_mode_t *mp;
17976   int ret;
17977
17978   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17979
17980   /* send */
17981   S (mp);
17982
17983   /* wait for reply */
17984   W (ret);
17985   return ret;
17986 }
17987
17988 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17989
17990 static int
17991 api_one_map_request_mode (vat_main_t * vam)
17992 {
17993   unformat_input_t *input = vam->input;
17994   vl_api_one_map_request_mode_t *mp;
17995   u8 mode = 0;
17996   int ret;
17997
17998   /* Parse args required to build the message */
17999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18000     {
18001       if (unformat (input, "dst-only"))
18002         mode = 0;
18003       else if (unformat (input, "src-dst"))
18004         mode = 1;
18005       else
18006         {
18007           errmsg ("parse error '%U'", format_unformat_error, input);
18008           return -99;
18009         }
18010     }
18011
18012   M (ONE_MAP_REQUEST_MODE, mp);
18013
18014   mp->mode = mode;
18015
18016   /* send */
18017   S (mp);
18018
18019   /* wait for reply */
18020   W (ret);
18021   return ret;
18022 }
18023
18024 #define api_lisp_map_request_mode api_one_map_request_mode
18025
18026 /**
18027  * Enable/disable ONE proxy ITR.
18028  *
18029  * @param vam vpp API test context
18030  * @return return code
18031  */
18032 static int
18033 api_one_pitr_set_locator_set (vat_main_t * vam)
18034 {
18035   u8 ls_name_set = 0;
18036   unformat_input_t *input = vam->input;
18037   vl_api_one_pitr_set_locator_set_t *mp;
18038   u8 is_add = 1;
18039   u8 *ls_name = 0;
18040   int ret;
18041
18042   /* Parse args required to build the message */
18043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18044     {
18045       if (unformat (input, "del"))
18046         is_add = 0;
18047       else if (unformat (input, "locator-set %s", &ls_name))
18048         ls_name_set = 1;
18049       else
18050         {
18051           errmsg ("parse error '%U'", format_unformat_error, input);
18052           return -99;
18053         }
18054     }
18055
18056   if (!ls_name_set)
18057     {
18058       errmsg ("locator-set name not set!");
18059       return -99;
18060     }
18061
18062   M (ONE_PITR_SET_LOCATOR_SET, mp);
18063
18064   mp->is_add = is_add;
18065   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18066   vec_free (ls_name);
18067
18068   /* send */
18069   S (mp);
18070
18071   /* wait for reply */
18072   W (ret);
18073   return ret;
18074 }
18075
18076 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18077
18078 static int
18079 api_one_nsh_set_locator_set (vat_main_t * vam)
18080 {
18081   u8 ls_name_set = 0;
18082   unformat_input_t *input = vam->input;
18083   vl_api_one_nsh_set_locator_set_t *mp;
18084   u8 is_add = 1;
18085   u8 *ls_name = 0;
18086   int ret;
18087
18088   /* Parse args required to build the message */
18089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18090     {
18091       if (unformat (input, "del"))
18092         is_add = 0;
18093       else if (unformat (input, "ls %s", &ls_name))
18094         ls_name_set = 1;
18095       else
18096         {
18097           errmsg ("parse error '%U'", format_unformat_error, input);
18098           return -99;
18099         }
18100     }
18101
18102   if (!ls_name_set && is_add)
18103     {
18104       errmsg ("locator-set name not set!");
18105       return -99;
18106     }
18107
18108   M (ONE_NSH_SET_LOCATOR_SET, mp);
18109
18110   mp->is_add = is_add;
18111   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18112   vec_free (ls_name);
18113
18114   /* send */
18115   S (mp);
18116
18117   /* wait for reply */
18118   W (ret);
18119   return ret;
18120 }
18121
18122 static int
18123 api_show_one_pitr (vat_main_t * vam)
18124 {
18125   vl_api_show_one_pitr_t *mp;
18126   int ret;
18127
18128   if (!vam->json_output)
18129     {
18130       print (vam->ofp, "%=20s", "lisp status:");
18131     }
18132
18133   M (SHOW_ONE_PITR, mp);
18134   /* send it... */
18135   S (mp);
18136
18137   /* Wait for a reply... */
18138   W (ret);
18139   return ret;
18140 }
18141
18142 #define api_show_lisp_pitr api_show_one_pitr
18143
18144 static int
18145 api_one_use_petr (vat_main_t * vam)
18146 {
18147   unformat_input_t *input = vam->input;
18148   vl_api_one_use_petr_t *mp;
18149   u8 is_add = 0;
18150   ip_address_t ip;
18151   int ret;
18152
18153   memset (&ip, 0, sizeof (ip));
18154
18155   /* Parse args required to build the message */
18156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18157     {
18158       if (unformat (input, "disable"))
18159         is_add = 0;
18160       else
18161         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18162         {
18163           is_add = 1;
18164           ip_addr_version (&ip) = IP4;
18165         }
18166       else
18167         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18168         {
18169           is_add = 1;
18170           ip_addr_version (&ip) = IP6;
18171         }
18172       else
18173         {
18174           errmsg ("parse error '%U'", format_unformat_error, input);
18175           return -99;
18176         }
18177     }
18178
18179   M (ONE_USE_PETR, mp);
18180
18181   mp->is_add = is_add;
18182   if (is_add)
18183     {
18184       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18185       if (mp->is_ip4)
18186         clib_memcpy (mp->address, &ip, 4);
18187       else
18188         clib_memcpy (mp->address, &ip, 16);
18189     }
18190
18191   /* send */
18192   S (mp);
18193
18194   /* wait for reply */
18195   W (ret);
18196   return ret;
18197 }
18198
18199 #define api_lisp_use_petr api_one_use_petr
18200
18201 static int
18202 api_show_one_nsh_mapping (vat_main_t * vam)
18203 {
18204   vl_api_show_one_use_petr_t *mp;
18205   int ret;
18206
18207   if (!vam->json_output)
18208     {
18209       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18210     }
18211
18212   M (SHOW_ONE_NSH_MAPPING, mp);
18213   /* send it... */
18214   S (mp);
18215
18216   /* Wait for a reply... */
18217   W (ret);
18218   return ret;
18219 }
18220
18221 static int
18222 api_show_one_use_petr (vat_main_t * vam)
18223 {
18224   vl_api_show_one_use_petr_t *mp;
18225   int ret;
18226
18227   if (!vam->json_output)
18228     {
18229       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18230     }
18231
18232   M (SHOW_ONE_USE_PETR, mp);
18233   /* send it... */
18234   S (mp);
18235
18236   /* Wait for a reply... */
18237   W (ret);
18238   return ret;
18239 }
18240
18241 #define api_show_lisp_use_petr api_show_one_use_petr
18242
18243 /**
18244  * Add/delete mapping between vni and vrf
18245  */
18246 static int
18247 api_one_eid_table_add_del_map (vat_main_t * vam)
18248 {
18249   unformat_input_t *input = vam->input;
18250   vl_api_one_eid_table_add_del_map_t *mp;
18251   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18252   u32 vni, vrf, bd_index;
18253   int ret;
18254
18255   /* Parse args required to build the message */
18256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18257     {
18258       if (unformat (input, "del"))
18259         is_add = 0;
18260       else if (unformat (input, "vrf %d", &vrf))
18261         vrf_set = 1;
18262       else if (unformat (input, "bd_index %d", &bd_index))
18263         bd_index_set = 1;
18264       else if (unformat (input, "vni %d", &vni))
18265         vni_set = 1;
18266       else
18267         break;
18268     }
18269
18270   if (!vni_set || (!vrf_set && !bd_index_set))
18271     {
18272       errmsg ("missing arguments!");
18273       return -99;
18274     }
18275
18276   if (vrf_set && bd_index_set)
18277     {
18278       errmsg ("error: both vrf and bd entered!");
18279       return -99;
18280     }
18281
18282   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18283
18284   mp->is_add = is_add;
18285   mp->vni = htonl (vni);
18286   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18287   mp->is_l2 = bd_index_set;
18288
18289   /* send */
18290   S (mp);
18291
18292   /* wait for reply */
18293   W (ret);
18294   return ret;
18295 }
18296
18297 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18298
18299 uword
18300 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18301 {
18302   u32 *action = va_arg (*args, u32 *);
18303   u8 *s = 0;
18304
18305   if (unformat (input, "%s", &s))
18306     {
18307       if (!strcmp ((char *) s, "no-action"))
18308         action[0] = 0;
18309       else if (!strcmp ((char *) s, "natively-forward"))
18310         action[0] = 1;
18311       else if (!strcmp ((char *) s, "send-map-request"))
18312         action[0] = 2;
18313       else if (!strcmp ((char *) s, "drop"))
18314         action[0] = 3;
18315       else
18316         {
18317           clib_warning ("invalid action: '%s'", s);
18318           action[0] = 3;
18319         }
18320     }
18321   else
18322     return 0;
18323
18324   vec_free (s);
18325   return 1;
18326 }
18327
18328 /**
18329  * Add/del remote mapping to/from ONE control plane
18330  *
18331  * @param vam vpp API test context
18332  * @return return code
18333  */
18334 static int
18335 api_one_add_del_remote_mapping (vat_main_t * vam)
18336 {
18337   unformat_input_t *input = vam->input;
18338   vl_api_one_add_del_remote_mapping_t *mp;
18339   u32 vni = 0;
18340   lisp_eid_vat_t _eid, *eid = &_eid;
18341   lisp_eid_vat_t _seid, *seid = &_seid;
18342   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18343   u32 action = ~0, p, w, data_len;
18344   ip4_address_t rloc4;
18345   ip6_address_t rloc6;
18346   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18347   int ret;
18348
18349   memset (&rloc, 0, sizeof (rloc));
18350
18351   /* Parse args required to build the message */
18352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18353     {
18354       if (unformat (input, "del-all"))
18355         {
18356           del_all = 1;
18357         }
18358       else if (unformat (input, "del"))
18359         {
18360           is_add = 0;
18361         }
18362       else if (unformat (input, "add"))
18363         {
18364           is_add = 1;
18365         }
18366       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18367         {
18368           eid_set = 1;
18369         }
18370       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18371         {
18372           seid_set = 1;
18373         }
18374       else if (unformat (input, "vni %d", &vni))
18375         {
18376           ;
18377         }
18378       else if (unformat (input, "p %d w %d", &p, &w))
18379         {
18380           if (!curr_rloc)
18381             {
18382               errmsg ("No RLOC configured for setting priority/weight!");
18383               return -99;
18384             }
18385           curr_rloc->priority = p;
18386           curr_rloc->weight = w;
18387         }
18388       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18389         {
18390           rloc.is_ip4 = 1;
18391           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18392           vec_add1 (rlocs, rloc);
18393           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18394         }
18395       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18396         {
18397           rloc.is_ip4 = 0;
18398           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18399           vec_add1 (rlocs, rloc);
18400           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18401         }
18402       else if (unformat (input, "action %U",
18403                          unformat_negative_mapping_action, &action))
18404         {
18405           ;
18406         }
18407       else
18408         {
18409           clib_warning ("parse error '%U'", format_unformat_error, input);
18410           return -99;
18411         }
18412     }
18413
18414   if (0 == eid_set)
18415     {
18416       errmsg ("missing params!");
18417       return -99;
18418     }
18419
18420   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18421     {
18422       errmsg ("no action set for negative map-reply!");
18423       return -99;
18424     }
18425
18426   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18427
18428   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18429   mp->is_add = is_add;
18430   mp->vni = htonl (vni);
18431   mp->action = (u8) action;
18432   mp->is_src_dst = seid_set;
18433   mp->eid_len = eid->len;
18434   mp->seid_len = seid->len;
18435   mp->del_all = del_all;
18436   mp->eid_type = eid->type;
18437   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18438   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18439
18440   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18441   clib_memcpy (mp->rlocs, rlocs, data_len);
18442   vec_free (rlocs);
18443
18444   /* send it... */
18445   S (mp);
18446
18447   /* Wait for a reply... */
18448   W (ret);
18449   return ret;
18450 }
18451
18452 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18453
18454 /**
18455  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18456  * forwarding entries in data-plane accordingly.
18457  *
18458  * @param vam vpp API test context
18459  * @return return code
18460  */
18461 static int
18462 api_one_add_del_adjacency (vat_main_t * vam)
18463 {
18464   unformat_input_t *input = vam->input;
18465   vl_api_one_add_del_adjacency_t *mp;
18466   u32 vni = 0;
18467   ip4_address_t leid4, reid4;
18468   ip6_address_t leid6, reid6;
18469   u8 reid_mac[6] = { 0 };
18470   u8 leid_mac[6] = { 0 };
18471   u8 reid_type, leid_type;
18472   u32 leid_len = 0, reid_len = 0, len;
18473   u8 is_add = 1;
18474   int ret;
18475
18476   leid_type = reid_type = (u8) ~ 0;
18477
18478   /* Parse args required to build the message */
18479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18480     {
18481       if (unformat (input, "del"))
18482         {
18483           is_add = 0;
18484         }
18485       else if (unformat (input, "add"))
18486         {
18487           is_add = 1;
18488         }
18489       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18490                          &reid4, &len))
18491         {
18492           reid_type = 0;        /* ipv4 */
18493           reid_len = len;
18494         }
18495       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18496                          &reid6, &len))
18497         {
18498           reid_type = 1;        /* ipv6 */
18499           reid_len = len;
18500         }
18501       else if (unformat (input, "reid %U", unformat_ethernet_address,
18502                          reid_mac))
18503         {
18504           reid_type = 2;        /* mac */
18505         }
18506       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18507                          &leid4, &len))
18508         {
18509           leid_type = 0;        /* ipv4 */
18510           leid_len = len;
18511         }
18512       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18513                          &leid6, &len))
18514         {
18515           leid_type = 1;        /* ipv6 */
18516           leid_len = len;
18517         }
18518       else if (unformat (input, "leid %U", unformat_ethernet_address,
18519                          leid_mac))
18520         {
18521           leid_type = 2;        /* mac */
18522         }
18523       else if (unformat (input, "vni %d", &vni))
18524         {
18525           ;
18526         }
18527       else
18528         {
18529           errmsg ("parse error '%U'", format_unformat_error, input);
18530           return -99;
18531         }
18532     }
18533
18534   if ((u8) ~ 0 == reid_type)
18535     {
18536       errmsg ("missing params!");
18537       return -99;
18538     }
18539
18540   if (leid_type != reid_type)
18541     {
18542       errmsg ("remote and local EIDs are of different types!");
18543       return -99;
18544     }
18545
18546   M (ONE_ADD_DEL_ADJACENCY, mp);
18547   mp->is_add = is_add;
18548   mp->vni = htonl (vni);
18549   mp->leid_len = leid_len;
18550   mp->reid_len = reid_len;
18551   mp->eid_type = reid_type;
18552
18553   switch (mp->eid_type)
18554     {
18555     case 0:
18556       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18557       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18558       break;
18559     case 1:
18560       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18561       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18562       break;
18563     case 2:
18564       clib_memcpy (mp->leid, leid_mac, 6);
18565       clib_memcpy (mp->reid, reid_mac, 6);
18566       break;
18567     default:
18568       errmsg ("unknown EID type %d!", mp->eid_type);
18569       return 0;
18570     }
18571
18572   /* send it... */
18573   S (mp);
18574
18575   /* Wait for a reply... */
18576   W (ret);
18577   return ret;
18578 }
18579
18580 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18581
18582 uword
18583 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18584 {
18585   u32 *mode = va_arg (*args, u32 *);
18586
18587   if (unformat (input, "lisp"))
18588     *mode = 0;
18589   else if (unformat (input, "vxlan"))
18590     *mode = 1;
18591   else
18592     return 0;
18593
18594   return 1;
18595 }
18596
18597 static int
18598 api_gpe_get_encap_mode (vat_main_t * vam)
18599 {
18600   vl_api_gpe_get_encap_mode_t *mp;
18601   int ret;
18602
18603   /* Construct the API message */
18604   M (GPE_GET_ENCAP_MODE, mp);
18605
18606   /* send it... */
18607   S (mp);
18608
18609   /* Wait for a reply... */
18610   W (ret);
18611   return ret;
18612 }
18613
18614 static int
18615 api_gpe_set_encap_mode (vat_main_t * vam)
18616 {
18617   unformat_input_t *input = vam->input;
18618   vl_api_gpe_set_encap_mode_t *mp;
18619   int ret;
18620   u32 mode = 0;
18621
18622   /* Parse args required to build the message */
18623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18624     {
18625       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18626         ;
18627       else
18628         break;
18629     }
18630
18631   /* Construct the API message */
18632   M (GPE_SET_ENCAP_MODE, mp);
18633
18634   mp->mode = mode;
18635
18636   /* send it... */
18637   S (mp);
18638
18639   /* Wait for a reply... */
18640   W (ret);
18641   return ret;
18642 }
18643
18644 static int
18645 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18646 {
18647   unformat_input_t *input = vam->input;
18648   vl_api_gpe_add_del_iface_t *mp;
18649   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18650   u32 dp_table = 0, vni = 0;
18651   int ret;
18652
18653   /* Parse args required to build the message */
18654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18655     {
18656       if (unformat (input, "up"))
18657         {
18658           action_set = 1;
18659           is_add = 1;
18660         }
18661       else if (unformat (input, "down"))
18662         {
18663           action_set = 1;
18664           is_add = 0;
18665         }
18666       else if (unformat (input, "table_id %d", &dp_table))
18667         {
18668           dp_table_set = 1;
18669         }
18670       else if (unformat (input, "bd_id %d", &dp_table))
18671         {
18672           dp_table_set = 1;
18673           is_l2 = 1;
18674         }
18675       else if (unformat (input, "vni %d", &vni))
18676         {
18677           vni_set = 1;
18678         }
18679       else
18680         break;
18681     }
18682
18683   if (action_set == 0)
18684     {
18685       errmsg ("Action not set");
18686       return -99;
18687     }
18688   if (dp_table_set == 0 || vni_set == 0)
18689     {
18690       errmsg ("vni and dp_table must be set");
18691       return -99;
18692     }
18693
18694   /* Construct the API message */
18695   M (GPE_ADD_DEL_IFACE, mp);
18696
18697   mp->is_add = is_add;
18698   mp->dp_table = clib_host_to_net_u32 (dp_table);
18699   mp->is_l2 = is_l2;
18700   mp->vni = clib_host_to_net_u32 (vni);
18701
18702   /* send it... */
18703   S (mp);
18704
18705   /* Wait for a reply... */
18706   W (ret);
18707   return ret;
18708 }
18709
18710 static int
18711 api_one_map_register_fallback_threshold (vat_main_t * vam)
18712 {
18713   unformat_input_t *input = vam->input;
18714   vl_api_one_map_register_fallback_threshold_t *mp;
18715   u32 value = 0;
18716   u8 is_set = 0;
18717   int ret;
18718
18719   /* Parse args required to build the message */
18720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18721     {
18722       if (unformat (input, "%u", &value))
18723         is_set = 1;
18724       else
18725         {
18726           clib_warning ("parse error '%U'", format_unformat_error, input);
18727           return -99;
18728         }
18729     }
18730
18731   if (!is_set)
18732     {
18733       errmsg ("fallback threshold value is missing!");
18734       return -99;
18735     }
18736
18737   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18738   mp->value = clib_host_to_net_u32 (value);
18739
18740   /* send it... */
18741   S (mp);
18742
18743   /* Wait for a reply... */
18744   W (ret);
18745   return ret;
18746 }
18747
18748 static int
18749 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18750 {
18751   vl_api_show_one_map_register_fallback_threshold_t *mp;
18752   int ret;
18753
18754   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18755
18756   /* send it... */
18757   S (mp);
18758
18759   /* Wait for a reply... */
18760   W (ret);
18761   return ret;
18762 }
18763
18764 uword
18765 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18766 {
18767   u32 *proto = va_arg (*args, u32 *);
18768
18769   if (unformat (input, "udp"))
18770     *proto = 1;
18771   else if (unformat (input, "api"))
18772     *proto = 2;
18773   else
18774     return 0;
18775
18776   return 1;
18777 }
18778
18779 static int
18780 api_one_set_transport_protocol (vat_main_t * vam)
18781 {
18782   unformat_input_t *input = vam->input;
18783   vl_api_one_set_transport_protocol_t *mp;
18784   u8 is_set = 0;
18785   u32 protocol = 0;
18786   int ret;
18787
18788   /* Parse args required to build the message */
18789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18790     {
18791       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18792         is_set = 1;
18793       else
18794         {
18795           clib_warning ("parse error '%U'", format_unformat_error, input);
18796           return -99;
18797         }
18798     }
18799
18800   if (!is_set)
18801     {
18802       errmsg ("Transport protocol missing!");
18803       return -99;
18804     }
18805
18806   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18807   mp->protocol = (u8) protocol;
18808
18809   /* send it... */
18810   S (mp);
18811
18812   /* Wait for a reply... */
18813   W (ret);
18814   return ret;
18815 }
18816
18817 static int
18818 api_one_get_transport_protocol (vat_main_t * vam)
18819 {
18820   vl_api_one_get_transport_protocol_t *mp;
18821   int ret;
18822
18823   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18824
18825   /* send it... */
18826   S (mp);
18827
18828   /* Wait for a reply... */
18829   W (ret);
18830   return ret;
18831 }
18832
18833 static int
18834 api_one_map_register_set_ttl (vat_main_t * vam)
18835 {
18836   unformat_input_t *input = vam->input;
18837   vl_api_one_map_register_set_ttl_t *mp;
18838   u32 ttl = 0;
18839   u8 is_set = 0;
18840   int ret;
18841
18842   /* Parse args required to build the message */
18843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18844     {
18845       if (unformat (input, "%u", &ttl))
18846         is_set = 1;
18847       else
18848         {
18849           clib_warning ("parse error '%U'", format_unformat_error, input);
18850           return -99;
18851         }
18852     }
18853
18854   if (!is_set)
18855     {
18856       errmsg ("TTL value missing!");
18857       return -99;
18858     }
18859
18860   M (ONE_MAP_REGISTER_SET_TTL, mp);
18861   mp->ttl = clib_host_to_net_u32 (ttl);
18862
18863   /* send it... */
18864   S (mp);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 static int
18872 api_show_one_map_register_ttl (vat_main_t * vam)
18873 {
18874   vl_api_show_one_map_register_ttl_t *mp;
18875   int ret;
18876
18877   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 /**
18888  * Add/del map request itr rlocs from ONE control plane and updates
18889  *
18890  * @param vam vpp API test context
18891  * @return return code
18892  */
18893 static int
18894 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18895 {
18896   unformat_input_t *input = vam->input;
18897   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18898   u8 *locator_set_name = 0;
18899   u8 locator_set_name_set = 0;
18900   u8 is_add = 1;
18901   int ret;
18902
18903   /* Parse args required to build the message */
18904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18905     {
18906       if (unformat (input, "del"))
18907         {
18908           is_add = 0;
18909         }
18910       else if (unformat (input, "%_%v%_", &locator_set_name))
18911         {
18912           locator_set_name_set = 1;
18913         }
18914       else
18915         {
18916           clib_warning ("parse error '%U'", format_unformat_error, input);
18917           return -99;
18918         }
18919     }
18920
18921   if (is_add && !locator_set_name_set)
18922     {
18923       errmsg ("itr-rloc is not set!");
18924       return -99;
18925     }
18926
18927   if (is_add && vec_len (locator_set_name) > 64)
18928     {
18929       errmsg ("itr-rloc locator-set name too long");
18930       vec_free (locator_set_name);
18931       return -99;
18932     }
18933
18934   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18935   mp->is_add = is_add;
18936   if (is_add)
18937     {
18938       clib_memcpy (mp->locator_set_name, locator_set_name,
18939                    vec_len (locator_set_name));
18940     }
18941   else
18942     {
18943       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18944     }
18945   vec_free (locator_set_name);
18946
18947   /* send it... */
18948   S (mp);
18949
18950   /* Wait for a reply... */
18951   W (ret);
18952   return ret;
18953 }
18954
18955 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18956
18957 static int
18958 api_one_locator_dump (vat_main_t * vam)
18959 {
18960   unformat_input_t *input = vam->input;
18961   vl_api_one_locator_dump_t *mp;
18962   vl_api_control_ping_t *mp_ping;
18963   u8 is_index_set = 0, is_name_set = 0;
18964   u8 *ls_name = 0;
18965   u32 ls_index = ~0;
18966   int ret;
18967
18968   /* Parse args required to build the message */
18969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18970     {
18971       if (unformat (input, "ls_name %_%v%_", &ls_name))
18972         {
18973           is_name_set = 1;
18974         }
18975       else if (unformat (input, "ls_index %d", &ls_index))
18976         {
18977           is_index_set = 1;
18978         }
18979       else
18980         {
18981           errmsg ("parse error '%U'", format_unformat_error, input);
18982           return -99;
18983         }
18984     }
18985
18986   if (!is_index_set && !is_name_set)
18987     {
18988       errmsg ("error: expected one of index or name!");
18989       return -99;
18990     }
18991
18992   if (is_index_set && is_name_set)
18993     {
18994       errmsg ("error: only one param expected!");
18995       return -99;
18996     }
18997
18998   if (vec_len (ls_name) > 62)
18999     {
19000       errmsg ("error: locator set name too long!");
19001       return -99;
19002     }
19003
19004   if (!vam->json_output)
19005     {
19006       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19007     }
19008
19009   M (ONE_LOCATOR_DUMP, mp);
19010   mp->is_index_set = is_index_set;
19011
19012   if (is_index_set)
19013     mp->ls_index = clib_host_to_net_u32 (ls_index);
19014   else
19015     {
19016       vec_add1 (ls_name, 0);
19017       strncpy ((char *) mp->ls_name, (char *) ls_name,
19018                sizeof (mp->ls_name) - 1);
19019     }
19020
19021   /* send it... */
19022   S (mp);
19023
19024   /* Use a control ping for synchronization */
19025   MPING (CONTROL_PING, mp_ping);
19026   S (mp_ping);
19027
19028   /* Wait for a reply... */
19029   W (ret);
19030   return ret;
19031 }
19032
19033 #define api_lisp_locator_dump api_one_locator_dump
19034
19035 static int
19036 api_one_locator_set_dump (vat_main_t * vam)
19037 {
19038   vl_api_one_locator_set_dump_t *mp;
19039   vl_api_control_ping_t *mp_ping;
19040   unformat_input_t *input = vam->input;
19041   u8 filter = 0;
19042   int ret;
19043
19044   /* Parse args required to build the message */
19045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19046     {
19047       if (unformat (input, "local"))
19048         {
19049           filter = 1;
19050         }
19051       else if (unformat (input, "remote"))
19052         {
19053           filter = 2;
19054         }
19055       else
19056         {
19057           errmsg ("parse error '%U'", format_unformat_error, input);
19058           return -99;
19059         }
19060     }
19061
19062   if (!vam->json_output)
19063     {
19064       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19065     }
19066
19067   M (ONE_LOCATOR_SET_DUMP, mp);
19068
19069   mp->filter = filter;
19070
19071   /* send it... */
19072   S (mp);
19073
19074   /* Use a control ping for synchronization */
19075   MPING (CONTROL_PING, mp_ping);
19076   S (mp_ping);
19077
19078   /* Wait for a reply... */
19079   W (ret);
19080   return ret;
19081 }
19082
19083 #define api_lisp_locator_set_dump api_one_locator_set_dump
19084
19085 static int
19086 api_one_eid_table_map_dump (vat_main_t * vam)
19087 {
19088   u8 is_l2 = 0;
19089   u8 mode_set = 0;
19090   unformat_input_t *input = vam->input;
19091   vl_api_one_eid_table_map_dump_t *mp;
19092   vl_api_control_ping_t *mp_ping;
19093   int ret;
19094
19095   /* Parse args required to build the message */
19096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19097     {
19098       if (unformat (input, "l2"))
19099         {
19100           is_l2 = 1;
19101           mode_set = 1;
19102         }
19103       else if (unformat (input, "l3"))
19104         {
19105           is_l2 = 0;
19106           mode_set = 1;
19107         }
19108       else
19109         {
19110           errmsg ("parse error '%U'", format_unformat_error, input);
19111           return -99;
19112         }
19113     }
19114
19115   if (!mode_set)
19116     {
19117       errmsg ("expected one of 'l2' or 'l3' parameter!");
19118       return -99;
19119     }
19120
19121   if (!vam->json_output)
19122     {
19123       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19124     }
19125
19126   M (ONE_EID_TABLE_MAP_DUMP, mp);
19127   mp->is_l2 = is_l2;
19128
19129   /* send it... */
19130   S (mp);
19131
19132   /* Use a control ping for synchronization */
19133   MPING (CONTROL_PING, mp_ping);
19134   S (mp_ping);
19135
19136   /* Wait for a reply... */
19137   W (ret);
19138   return ret;
19139 }
19140
19141 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19142
19143 static int
19144 api_one_eid_table_vni_dump (vat_main_t * vam)
19145 {
19146   vl_api_one_eid_table_vni_dump_t *mp;
19147   vl_api_control_ping_t *mp_ping;
19148   int ret;
19149
19150   if (!vam->json_output)
19151     {
19152       print (vam->ofp, "VNI");
19153     }
19154
19155   M (ONE_EID_TABLE_VNI_DUMP, mp);
19156
19157   /* send it... */
19158   S (mp);
19159
19160   /* Use a control ping for synchronization */
19161   MPING (CONTROL_PING, mp_ping);
19162   S (mp_ping);
19163
19164   /* Wait for a reply... */
19165   W (ret);
19166   return ret;
19167 }
19168
19169 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19170
19171 static int
19172 api_one_eid_table_dump (vat_main_t * vam)
19173 {
19174   unformat_input_t *i = vam->input;
19175   vl_api_one_eid_table_dump_t *mp;
19176   vl_api_control_ping_t *mp_ping;
19177   struct in_addr ip4;
19178   struct in6_addr ip6;
19179   u8 mac[6];
19180   u8 eid_type = ~0, eid_set = 0;
19181   u32 prefix_length = ~0, t, vni = 0;
19182   u8 filter = 0;
19183   int ret;
19184   lisp_nsh_api_t nsh;
19185
19186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19187     {
19188       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19189         {
19190           eid_set = 1;
19191           eid_type = 0;
19192           prefix_length = t;
19193         }
19194       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19195         {
19196           eid_set = 1;
19197           eid_type = 1;
19198           prefix_length = t;
19199         }
19200       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19201         {
19202           eid_set = 1;
19203           eid_type = 2;
19204         }
19205       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19206         {
19207           eid_set = 1;
19208           eid_type = 3;
19209         }
19210       else if (unformat (i, "vni %d", &t))
19211         {
19212           vni = t;
19213         }
19214       else if (unformat (i, "local"))
19215         {
19216           filter = 1;
19217         }
19218       else if (unformat (i, "remote"))
19219         {
19220           filter = 2;
19221         }
19222       else
19223         {
19224           errmsg ("parse error '%U'", format_unformat_error, i);
19225           return -99;
19226         }
19227     }
19228
19229   if (!vam->json_output)
19230     {
19231       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19232              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19233     }
19234
19235   M (ONE_EID_TABLE_DUMP, mp);
19236
19237   mp->filter = filter;
19238   if (eid_set)
19239     {
19240       mp->eid_set = 1;
19241       mp->vni = htonl (vni);
19242       mp->eid_type = eid_type;
19243       switch (eid_type)
19244         {
19245         case 0:
19246           mp->prefix_length = prefix_length;
19247           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19248           break;
19249         case 1:
19250           mp->prefix_length = prefix_length;
19251           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19252           break;
19253         case 2:
19254           clib_memcpy (mp->eid, mac, sizeof (mac));
19255           break;
19256         case 3:
19257           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19258           break;
19259         default:
19260           errmsg ("unknown EID type %d!", eid_type);
19261           return -99;
19262         }
19263     }
19264
19265   /* send it... */
19266   S (mp);
19267
19268   /* Use a control ping for synchronization */
19269   MPING (CONTROL_PING, mp_ping);
19270   S (mp_ping);
19271
19272   /* Wait for a reply... */
19273   W (ret);
19274   return ret;
19275 }
19276
19277 #define api_lisp_eid_table_dump api_one_eid_table_dump
19278
19279 static int
19280 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19281 {
19282   unformat_input_t *i = vam->input;
19283   vl_api_gpe_fwd_entries_get_t *mp;
19284   u8 vni_set = 0;
19285   u32 vni = ~0;
19286   int ret;
19287
19288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19289     {
19290       if (unformat (i, "vni %d", &vni))
19291         {
19292           vni_set = 1;
19293         }
19294       else
19295         {
19296           errmsg ("parse error '%U'", format_unformat_error, i);
19297           return -99;
19298         }
19299     }
19300
19301   if (!vni_set)
19302     {
19303       errmsg ("vni not set!");
19304       return -99;
19305     }
19306
19307   if (!vam->json_output)
19308     {
19309       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19310              "leid", "reid");
19311     }
19312
19313   M (GPE_FWD_ENTRIES_GET, mp);
19314   mp->vni = clib_host_to_net_u32 (vni);
19315
19316   /* send it... */
19317   S (mp);
19318
19319   /* Wait for a reply... */
19320   W (ret);
19321   return ret;
19322 }
19323
19324 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19325 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19326 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19327 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19328 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19329 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19330 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19331 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19332
19333 static int
19334 api_one_adjacencies_get (vat_main_t * vam)
19335 {
19336   unformat_input_t *i = vam->input;
19337   vl_api_one_adjacencies_get_t *mp;
19338   u8 vni_set = 0;
19339   u32 vni = ~0;
19340   int ret;
19341
19342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19343     {
19344       if (unformat (i, "vni %d", &vni))
19345         {
19346           vni_set = 1;
19347         }
19348       else
19349         {
19350           errmsg ("parse error '%U'", format_unformat_error, i);
19351           return -99;
19352         }
19353     }
19354
19355   if (!vni_set)
19356     {
19357       errmsg ("vni not set!");
19358       return -99;
19359     }
19360
19361   if (!vam->json_output)
19362     {
19363       print (vam->ofp, "%s %40s", "leid", "reid");
19364     }
19365
19366   M (ONE_ADJACENCIES_GET, mp);
19367   mp->vni = clib_host_to_net_u32 (vni);
19368
19369   /* send it... */
19370   S (mp);
19371
19372   /* Wait for a reply... */
19373   W (ret);
19374   return ret;
19375 }
19376
19377 #define api_lisp_adjacencies_get api_one_adjacencies_get
19378
19379 static int
19380 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19381 {
19382   unformat_input_t *i = vam->input;
19383   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19384   int ret;
19385   u8 ip_family_set = 0, is_ip4 = 1;
19386
19387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19388     {
19389       if (unformat (i, "ip4"))
19390         {
19391           ip_family_set = 1;
19392           is_ip4 = 1;
19393         }
19394       else if (unformat (i, "ip6"))
19395         {
19396           ip_family_set = 1;
19397           is_ip4 = 0;
19398         }
19399       else
19400         {
19401           errmsg ("parse error '%U'", format_unformat_error, i);
19402           return -99;
19403         }
19404     }
19405
19406   if (!ip_family_set)
19407     {
19408       errmsg ("ip family not set!");
19409       return -99;
19410     }
19411
19412   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19413   mp->is_ip4 = is_ip4;
19414
19415   /* send it... */
19416   S (mp);
19417
19418   /* Wait for a reply... */
19419   W (ret);
19420   return ret;
19421 }
19422
19423 static int
19424 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19425 {
19426   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19427   int ret;
19428
19429   if (!vam->json_output)
19430     {
19431       print (vam->ofp, "VNIs");
19432     }
19433
19434   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19435
19436   /* send it... */
19437   S (mp);
19438
19439   /* Wait for a reply... */
19440   W (ret);
19441   return ret;
19442 }
19443
19444 static int
19445 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19446 {
19447   unformat_input_t *i = vam->input;
19448   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19449   int ret = 0;
19450   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19451   struct in_addr ip4;
19452   struct in6_addr ip6;
19453   u32 table_id = 0, nh_sw_if_index = ~0;
19454
19455   memset (&ip4, 0, sizeof (ip4));
19456   memset (&ip6, 0, sizeof (ip6));
19457
19458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19459     {
19460       if (unformat (i, "del"))
19461         is_add = 0;
19462       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19463                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19464         {
19465           ip_set = 1;
19466           is_ip4 = 1;
19467         }
19468       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19469                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19470         {
19471           ip_set = 1;
19472           is_ip4 = 0;
19473         }
19474       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19475         {
19476           ip_set = 1;
19477           is_ip4 = 1;
19478           nh_sw_if_index = ~0;
19479         }
19480       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19481         {
19482           ip_set = 1;
19483           is_ip4 = 0;
19484           nh_sw_if_index = ~0;
19485         }
19486       else if (unformat (i, "table %d", &table_id))
19487         ;
19488       else
19489         {
19490           errmsg ("parse error '%U'", format_unformat_error, i);
19491           return -99;
19492         }
19493     }
19494
19495   if (!ip_set)
19496     {
19497       errmsg ("nh addr not set!");
19498       return -99;
19499     }
19500
19501   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19502   mp->is_add = is_add;
19503   mp->table_id = clib_host_to_net_u32 (table_id);
19504   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19505   mp->is_ip4 = is_ip4;
19506   if (is_ip4)
19507     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19508   else
19509     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19510
19511   /* send it... */
19512   S (mp);
19513
19514   /* Wait for a reply... */
19515   W (ret);
19516   return ret;
19517 }
19518
19519 static int
19520 api_one_map_server_dump (vat_main_t * vam)
19521 {
19522   vl_api_one_map_server_dump_t *mp;
19523   vl_api_control_ping_t *mp_ping;
19524   int ret;
19525
19526   if (!vam->json_output)
19527     {
19528       print (vam->ofp, "%=20s", "Map server");
19529     }
19530
19531   M (ONE_MAP_SERVER_DUMP, mp);
19532   /* send it... */
19533   S (mp);
19534
19535   /* Use a control ping for synchronization */
19536   MPING (CONTROL_PING, mp_ping);
19537   S (mp_ping);
19538
19539   /* Wait for a reply... */
19540   W (ret);
19541   return ret;
19542 }
19543
19544 #define api_lisp_map_server_dump api_one_map_server_dump
19545
19546 static int
19547 api_one_map_resolver_dump (vat_main_t * vam)
19548 {
19549   vl_api_one_map_resolver_dump_t *mp;
19550   vl_api_control_ping_t *mp_ping;
19551   int ret;
19552
19553   if (!vam->json_output)
19554     {
19555       print (vam->ofp, "%=20s", "Map resolver");
19556     }
19557
19558   M (ONE_MAP_RESOLVER_DUMP, mp);
19559   /* send it... */
19560   S (mp);
19561
19562   /* Use a control ping for synchronization */
19563   MPING (CONTROL_PING, mp_ping);
19564   S (mp_ping);
19565
19566   /* Wait for a reply... */
19567   W (ret);
19568   return ret;
19569 }
19570
19571 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19572
19573 static int
19574 api_one_stats_flush (vat_main_t * vam)
19575 {
19576   vl_api_one_stats_flush_t *mp;
19577   int ret = 0;
19578
19579   M (ONE_STATS_FLUSH, mp);
19580   S (mp);
19581   W (ret);
19582   return ret;
19583 }
19584
19585 static int
19586 api_one_stats_dump (vat_main_t * vam)
19587 {
19588   vl_api_one_stats_dump_t *mp;
19589   vl_api_control_ping_t *mp_ping;
19590   int ret;
19591
19592   M (ONE_STATS_DUMP, mp);
19593   /* send it... */
19594   S (mp);
19595
19596   /* Use a control ping for synchronization */
19597   MPING (CONTROL_PING, mp_ping);
19598   S (mp_ping);
19599
19600   /* Wait for a reply... */
19601   W (ret);
19602   return ret;
19603 }
19604
19605 static int
19606 api_show_one_status (vat_main_t * vam)
19607 {
19608   vl_api_show_one_status_t *mp;
19609   int ret;
19610
19611   if (!vam->json_output)
19612     {
19613       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19614     }
19615
19616   M (SHOW_ONE_STATUS, mp);
19617   /* send it... */
19618   S (mp);
19619   /* Wait for a reply... */
19620   W (ret);
19621   return ret;
19622 }
19623
19624 #define api_show_lisp_status api_show_one_status
19625
19626 static int
19627 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19628 {
19629   vl_api_gpe_fwd_entry_path_dump_t *mp;
19630   vl_api_control_ping_t *mp_ping;
19631   unformat_input_t *i = vam->input;
19632   u32 fwd_entry_index = ~0;
19633   int ret;
19634
19635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19636     {
19637       if (unformat (i, "index %d", &fwd_entry_index))
19638         ;
19639       else
19640         break;
19641     }
19642
19643   if (~0 == fwd_entry_index)
19644     {
19645       errmsg ("no index specified!");
19646       return -99;
19647     }
19648
19649   if (!vam->json_output)
19650     {
19651       print (vam->ofp, "first line");
19652     }
19653
19654   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19655
19656   /* send it... */
19657   S (mp);
19658   /* Use a control ping for synchronization */
19659   MPING (CONTROL_PING, mp_ping);
19660   S (mp_ping);
19661
19662   /* Wait for a reply... */
19663   W (ret);
19664   return ret;
19665 }
19666
19667 static int
19668 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19669 {
19670   vl_api_one_get_map_request_itr_rlocs_t *mp;
19671   int ret;
19672
19673   if (!vam->json_output)
19674     {
19675       print (vam->ofp, "%=20s", "itr-rlocs:");
19676     }
19677
19678   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19679   /* send it... */
19680   S (mp);
19681   /* Wait for a reply... */
19682   W (ret);
19683   return ret;
19684 }
19685
19686 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19687
19688 static int
19689 api_af_packet_create (vat_main_t * vam)
19690 {
19691   unformat_input_t *i = vam->input;
19692   vl_api_af_packet_create_t *mp;
19693   u8 *host_if_name = 0;
19694   u8 hw_addr[6];
19695   u8 random_hw_addr = 1;
19696   int ret;
19697
19698   memset (hw_addr, 0, sizeof (hw_addr));
19699
19700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19701     {
19702       if (unformat (i, "name %s", &host_if_name))
19703         vec_add1 (host_if_name, 0);
19704       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19705         random_hw_addr = 0;
19706       else
19707         break;
19708     }
19709
19710   if (!vec_len (host_if_name))
19711     {
19712       errmsg ("host-interface name must be specified");
19713       return -99;
19714     }
19715
19716   if (vec_len (host_if_name) > 64)
19717     {
19718       errmsg ("host-interface name too long");
19719       return -99;
19720     }
19721
19722   M (AF_PACKET_CREATE, mp);
19723
19724   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19725   clib_memcpy (mp->hw_addr, hw_addr, 6);
19726   mp->use_random_hw_addr = random_hw_addr;
19727   vec_free (host_if_name);
19728
19729   S (mp);
19730
19731   /* *INDENT-OFF* */
19732   W2 (ret,
19733       ({
19734         if (ret == 0)
19735           fprintf (vam->ofp ? vam->ofp : stderr,
19736                    " new sw_if_index = %d\n", vam->sw_if_index);
19737       }));
19738   /* *INDENT-ON* */
19739   return ret;
19740 }
19741
19742 static int
19743 api_af_packet_delete (vat_main_t * vam)
19744 {
19745   unformat_input_t *i = vam->input;
19746   vl_api_af_packet_delete_t *mp;
19747   u8 *host_if_name = 0;
19748   int ret;
19749
19750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19751     {
19752       if (unformat (i, "name %s", &host_if_name))
19753         vec_add1 (host_if_name, 0);
19754       else
19755         break;
19756     }
19757
19758   if (!vec_len (host_if_name))
19759     {
19760       errmsg ("host-interface name must be specified");
19761       return -99;
19762     }
19763
19764   if (vec_len (host_if_name) > 64)
19765     {
19766       errmsg ("host-interface name too long");
19767       return -99;
19768     }
19769
19770   M (AF_PACKET_DELETE, mp);
19771
19772   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19773   vec_free (host_if_name);
19774
19775   S (mp);
19776   W (ret);
19777   return ret;
19778 }
19779
19780 static int
19781 api_policer_add_del (vat_main_t * vam)
19782 {
19783   unformat_input_t *i = vam->input;
19784   vl_api_policer_add_del_t *mp;
19785   u8 is_add = 1;
19786   u8 *name = 0;
19787   u32 cir = 0;
19788   u32 eir = 0;
19789   u64 cb = 0;
19790   u64 eb = 0;
19791   u8 rate_type = 0;
19792   u8 round_type = 0;
19793   u8 type = 0;
19794   u8 color_aware = 0;
19795   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19796   int ret;
19797
19798   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19799   conform_action.dscp = 0;
19800   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19801   exceed_action.dscp = 0;
19802   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19803   violate_action.dscp = 0;
19804
19805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19806     {
19807       if (unformat (i, "del"))
19808         is_add = 0;
19809       else if (unformat (i, "name %s", &name))
19810         vec_add1 (name, 0);
19811       else if (unformat (i, "cir %u", &cir))
19812         ;
19813       else if (unformat (i, "eir %u", &eir))
19814         ;
19815       else if (unformat (i, "cb %u", &cb))
19816         ;
19817       else if (unformat (i, "eb %u", &eb))
19818         ;
19819       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19820                          &rate_type))
19821         ;
19822       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19823                          &round_type))
19824         ;
19825       else if (unformat (i, "type %U", unformat_policer_type, &type))
19826         ;
19827       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19828                          &conform_action))
19829         ;
19830       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19831                          &exceed_action))
19832         ;
19833       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19834                          &violate_action))
19835         ;
19836       else if (unformat (i, "color-aware"))
19837         color_aware = 1;
19838       else
19839         break;
19840     }
19841
19842   if (!vec_len (name))
19843     {
19844       errmsg ("policer name must be specified");
19845       return -99;
19846     }
19847
19848   if (vec_len (name) > 64)
19849     {
19850       errmsg ("policer name too long");
19851       return -99;
19852     }
19853
19854   M (POLICER_ADD_DEL, mp);
19855
19856   clib_memcpy (mp->name, name, vec_len (name));
19857   vec_free (name);
19858   mp->is_add = is_add;
19859   mp->cir = ntohl (cir);
19860   mp->eir = ntohl (eir);
19861   mp->cb = clib_net_to_host_u64 (cb);
19862   mp->eb = clib_net_to_host_u64 (eb);
19863   mp->rate_type = rate_type;
19864   mp->round_type = round_type;
19865   mp->type = type;
19866   mp->conform_action_type = conform_action.action_type;
19867   mp->conform_dscp = conform_action.dscp;
19868   mp->exceed_action_type = exceed_action.action_type;
19869   mp->exceed_dscp = exceed_action.dscp;
19870   mp->violate_action_type = violate_action.action_type;
19871   mp->violate_dscp = violate_action.dscp;
19872   mp->color_aware = color_aware;
19873
19874   S (mp);
19875   W (ret);
19876   return ret;
19877 }
19878
19879 static int
19880 api_policer_dump (vat_main_t * vam)
19881 {
19882   unformat_input_t *i = vam->input;
19883   vl_api_policer_dump_t *mp;
19884   vl_api_control_ping_t *mp_ping;
19885   u8 *match_name = 0;
19886   u8 match_name_valid = 0;
19887   int ret;
19888
19889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19890     {
19891       if (unformat (i, "name %s", &match_name))
19892         {
19893           vec_add1 (match_name, 0);
19894           match_name_valid = 1;
19895         }
19896       else
19897         break;
19898     }
19899
19900   M (POLICER_DUMP, mp);
19901   mp->match_name_valid = match_name_valid;
19902   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19903   vec_free (match_name);
19904   /* send it... */
19905   S (mp);
19906
19907   /* Use a control ping for synchronization */
19908   MPING (CONTROL_PING, mp_ping);
19909   S (mp_ping);
19910
19911   /* Wait for a reply... */
19912   W (ret);
19913   return ret;
19914 }
19915
19916 static int
19917 api_policer_classify_set_interface (vat_main_t * vam)
19918 {
19919   unformat_input_t *i = vam->input;
19920   vl_api_policer_classify_set_interface_t *mp;
19921   u32 sw_if_index;
19922   int sw_if_index_set;
19923   u32 ip4_table_index = ~0;
19924   u32 ip6_table_index = ~0;
19925   u32 l2_table_index = ~0;
19926   u8 is_add = 1;
19927   int ret;
19928
19929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19930     {
19931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19932         sw_if_index_set = 1;
19933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19934         sw_if_index_set = 1;
19935       else if (unformat (i, "del"))
19936         is_add = 0;
19937       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19938         ;
19939       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19940         ;
19941       else if (unformat (i, "l2-table %d", &l2_table_index))
19942         ;
19943       else
19944         {
19945           clib_warning ("parse error '%U'", format_unformat_error, i);
19946           return -99;
19947         }
19948     }
19949
19950   if (sw_if_index_set == 0)
19951     {
19952       errmsg ("missing interface name or sw_if_index");
19953       return -99;
19954     }
19955
19956   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19957
19958   mp->sw_if_index = ntohl (sw_if_index);
19959   mp->ip4_table_index = ntohl (ip4_table_index);
19960   mp->ip6_table_index = ntohl (ip6_table_index);
19961   mp->l2_table_index = ntohl (l2_table_index);
19962   mp->is_add = is_add;
19963
19964   S (mp);
19965   W (ret);
19966   return ret;
19967 }
19968
19969 static int
19970 api_policer_classify_dump (vat_main_t * vam)
19971 {
19972   unformat_input_t *i = vam->input;
19973   vl_api_policer_classify_dump_t *mp;
19974   vl_api_control_ping_t *mp_ping;
19975   u8 type = POLICER_CLASSIFY_N_TABLES;
19976   int ret;
19977
19978   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19979     ;
19980   else
19981     {
19982       errmsg ("classify table type must be specified");
19983       return -99;
19984     }
19985
19986   if (!vam->json_output)
19987     {
19988       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19989     }
19990
19991   M (POLICER_CLASSIFY_DUMP, mp);
19992   mp->type = type;
19993   /* send it... */
19994   S (mp);
19995
19996   /* Use a control ping for synchronization */
19997   MPING (CONTROL_PING, mp_ping);
19998   S (mp_ping);
19999
20000   /* Wait for a reply... */
20001   W (ret);
20002   return ret;
20003 }
20004
20005 static int
20006 api_netmap_create (vat_main_t * vam)
20007 {
20008   unformat_input_t *i = vam->input;
20009   vl_api_netmap_create_t *mp;
20010   u8 *if_name = 0;
20011   u8 hw_addr[6];
20012   u8 random_hw_addr = 1;
20013   u8 is_pipe = 0;
20014   u8 is_master = 0;
20015   int ret;
20016
20017   memset (hw_addr, 0, sizeof (hw_addr));
20018
20019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20020     {
20021       if (unformat (i, "name %s", &if_name))
20022         vec_add1 (if_name, 0);
20023       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20024         random_hw_addr = 0;
20025       else if (unformat (i, "pipe"))
20026         is_pipe = 1;
20027       else if (unformat (i, "master"))
20028         is_master = 1;
20029       else if (unformat (i, "slave"))
20030         is_master = 0;
20031       else
20032         break;
20033     }
20034
20035   if (!vec_len (if_name))
20036     {
20037       errmsg ("interface name must be specified");
20038       return -99;
20039     }
20040
20041   if (vec_len (if_name) > 64)
20042     {
20043       errmsg ("interface name too long");
20044       return -99;
20045     }
20046
20047   M (NETMAP_CREATE, mp);
20048
20049   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20050   clib_memcpy (mp->hw_addr, hw_addr, 6);
20051   mp->use_random_hw_addr = random_hw_addr;
20052   mp->is_pipe = is_pipe;
20053   mp->is_master = is_master;
20054   vec_free (if_name);
20055
20056   S (mp);
20057   W (ret);
20058   return ret;
20059 }
20060
20061 static int
20062 api_netmap_delete (vat_main_t * vam)
20063 {
20064   unformat_input_t *i = vam->input;
20065   vl_api_netmap_delete_t *mp;
20066   u8 *if_name = 0;
20067   int ret;
20068
20069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20070     {
20071       if (unformat (i, "name %s", &if_name))
20072         vec_add1 (if_name, 0);
20073       else
20074         break;
20075     }
20076
20077   if (!vec_len (if_name))
20078     {
20079       errmsg ("interface name must be specified");
20080       return -99;
20081     }
20082
20083   if (vec_len (if_name) > 64)
20084     {
20085       errmsg ("interface name too long");
20086       return -99;
20087     }
20088
20089   M (NETMAP_DELETE, mp);
20090
20091   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20092   vec_free (if_name);
20093
20094   S (mp);
20095   W (ret);
20096   return ret;
20097 }
20098
20099 static void
20100 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20101 {
20102   if (fp->afi == IP46_TYPE_IP6)
20103     print (vam->ofp,
20104            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20105            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20106            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20107            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20108            format_ip6_address, fp->next_hop);
20109   else if (fp->afi == IP46_TYPE_IP4)
20110     print (vam->ofp,
20111            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20112            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20113            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20114            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20115            format_ip4_address, fp->next_hop);
20116 }
20117
20118 static void
20119 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20120                                  vl_api_fib_path_t * fp)
20121 {
20122   struct in_addr ip4;
20123   struct in6_addr ip6;
20124
20125   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20126   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20127   vat_json_object_add_uint (node, "is_local", fp->is_local);
20128   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20129   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20130   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20131   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20132   if (fp->afi == IP46_TYPE_IP4)
20133     {
20134       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20135       vat_json_object_add_ip4 (node, "next_hop", ip4);
20136     }
20137   else if (fp->afi == IP46_TYPE_IP6)
20138     {
20139       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20140       vat_json_object_add_ip6 (node, "next_hop", ip6);
20141     }
20142 }
20143
20144 static void
20145 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20146 {
20147   vat_main_t *vam = &vat_main;
20148   int count = ntohl (mp->mt_count);
20149   vl_api_fib_path_t *fp;
20150   i32 i;
20151
20152   print (vam->ofp, "[%d]: sw_if_index %d via:",
20153          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20154   fp = mp->mt_paths;
20155   for (i = 0; i < count; i++)
20156     {
20157       vl_api_mpls_fib_path_print (vam, fp);
20158       fp++;
20159     }
20160
20161   print (vam->ofp, "");
20162 }
20163
20164 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20165 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20166
20167 static void
20168 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20169 {
20170   vat_main_t *vam = &vat_main;
20171   vat_json_node_t *node = NULL;
20172   int count = ntohl (mp->mt_count);
20173   vl_api_fib_path_t *fp;
20174   i32 i;
20175
20176   if (VAT_JSON_ARRAY != vam->json_tree.type)
20177     {
20178       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20179       vat_json_init_array (&vam->json_tree);
20180     }
20181   node = vat_json_array_add (&vam->json_tree);
20182
20183   vat_json_init_object (node);
20184   vat_json_object_add_uint (node, "tunnel_index",
20185                             ntohl (mp->mt_tunnel_index));
20186   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20187
20188   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20189
20190   fp = mp->mt_paths;
20191   for (i = 0; i < count; i++)
20192     {
20193       vl_api_mpls_fib_path_json_print (node, fp);
20194       fp++;
20195     }
20196 }
20197
20198 static int
20199 api_mpls_tunnel_dump (vat_main_t * vam)
20200 {
20201   vl_api_mpls_tunnel_dump_t *mp;
20202   vl_api_control_ping_t *mp_ping;
20203   i32 index = -1;
20204   int ret;
20205
20206   /* Parse args required to build the message */
20207   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20208     {
20209       if (!unformat (vam->input, "tunnel_index %d", &index))
20210         {
20211           index = -1;
20212           break;
20213         }
20214     }
20215
20216   print (vam->ofp, "  tunnel_index %d", index);
20217
20218   M (MPLS_TUNNEL_DUMP, mp);
20219   mp->tunnel_index = htonl (index);
20220   S (mp);
20221
20222   /* Use a control ping for synchronization */
20223   MPING (CONTROL_PING, mp_ping);
20224   S (mp_ping);
20225
20226   W (ret);
20227   return ret;
20228 }
20229
20230 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20231 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20232
20233
20234 static void
20235 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20236 {
20237   vat_main_t *vam = &vat_main;
20238   int count = ntohl (mp->count);
20239   vl_api_fib_path_t *fp;
20240   int i;
20241
20242   print (vam->ofp,
20243          "table-id %d, label %u, ess_bit %u",
20244          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20245   fp = mp->path;
20246   for (i = 0; i < count; i++)
20247     {
20248       vl_api_mpls_fib_path_print (vam, fp);
20249       fp++;
20250     }
20251 }
20252
20253 static void vl_api_mpls_fib_details_t_handler_json
20254   (vl_api_mpls_fib_details_t * mp)
20255 {
20256   vat_main_t *vam = &vat_main;
20257   int count = ntohl (mp->count);
20258   vat_json_node_t *node = NULL;
20259   vl_api_fib_path_t *fp;
20260   int i;
20261
20262   if (VAT_JSON_ARRAY != vam->json_tree.type)
20263     {
20264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20265       vat_json_init_array (&vam->json_tree);
20266     }
20267   node = vat_json_array_add (&vam->json_tree);
20268
20269   vat_json_init_object (node);
20270   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20271   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20272   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20273   vat_json_object_add_uint (node, "path_count", count);
20274   fp = mp->path;
20275   for (i = 0; i < count; i++)
20276     {
20277       vl_api_mpls_fib_path_json_print (node, fp);
20278       fp++;
20279     }
20280 }
20281
20282 static int
20283 api_mpls_fib_dump (vat_main_t * vam)
20284 {
20285   vl_api_mpls_fib_dump_t *mp;
20286   vl_api_control_ping_t *mp_ping;
20287   int ret;
20288
20289   M (MPLS_FIB_DUMP, mp);
20290   S (mp);
20291
20292   /* Use a control ping for synchronization */
20293   MPING (CONTROL_PING, mp_ping);
20294   S (mp_ping);
20295
20296   W (ret);
20297   return ret;
20298 }
20299
20300 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20301 #define vl_api_ip_fib_details_t_print vl_noop_handler
20302
20303 static void
20304 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20305 {
20306   vat_main_t *vam = &vat_main;
20307   int count = ntohl (mp->count);
20308   vl_api_fib_path_t *fp;
20309   int i;
20310
20311   print (vam->ofp,
20312          "table-id %d, prefix %U/%d",
20313          ntohl (mp->table_id), format_ip4_address, mp->address,
20314          mp->address_length);
20315   fp = mp->path;
20316   for (i = 0; i < count; i++)
20317     {
20318       if (fp->afi == IP46_TYPE_IP6)
20319         print (vam->ofp,
20320                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20321                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20322                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20323                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20324                format_ip6_address, fp->next_hop);
20325       else if (fp->afi == IP46_TYPE_IP4)
20326         print (vam->ofp,
20327                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20328                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20329                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20330                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20331                format_ip4_address, fp->next_hop);
20332       fp++;
20333     }
20334 }
20335
20336 static void vl_api_ip_fib_details_t_handler_json
20337   (vl_api_ip_fib_details_t * mp)
20338 {
20339   vat_main_t *vam = &vat_main;
20340   int count = ntohl (mp->count);
20341   vat_json_node_t *node = NULL;
20342   struct in_addr ip4;
20343   struct in6_addr ip6;
20344   vl_api_fib_path_t *fp;
20345   int i;
20346
20347   if (VAT_JSON_ARRAY != vam->json_tree.type)
20348     {
20349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20350       vat_json_init_array (&vam->json_tree);
20351     }
20352   node = vat_json_array_add (&vam->json_tree);
20353
20354   vat_json_init_object (node);
20355   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20356   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20357   vat_json_object_add_ip4 (node, "prefix", ip4);
20358   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20359   vat_json_object_add_uint (node, "path_count", count);
20360   fp = mp->path;
20361   for (i = 0; i < count; i++)
20362     {
20363       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20364       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20365       vat_json_object_add_uint (node, "is_local", fp->is_local);
20366       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20367       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20368       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20369       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20370       if (fp->afi == IP46_TYPE_IP4)
20371         {
20372           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20373           vat_json_object_add_ip4 (node, "next_hop", ip4);
20374         }
20375       else if (fp->afi == IP46_TYPE_IP6)
20376         {
20377           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20378           vat_json_object_add_ip6 (node, "next_hop", ip6);
20379         }
20380     }
20381 }
20382
20383 static int
20384 api_ip_fib_dump (vat_main_t * vam)
20385 {
20386   vl_api_ip_fib_dump_t *mp;
20387   vl_api_control_ping_t *mp_ping;
20388   int ret;
20389
20390   M (IP_FIB_DUMP, mp);
20391   S (mp);
20392
20393   /* Use a control ping for synchronization */
20394   MPING (CONTROL_PING, mp_ping);
20395   S (mp_ping);
20396
20397   W (ret);
20398   return ret;
20399 }
20400
20401 static int
20402 api_ip_mfib_dump (vat_main_t * vam)
20403 {
20404   vl_api_ip_mfib_dump_t *mp;
20405   vl_api_control_ping_t *mp_ping;
20406   int ret;
20407
20408   M (IP_MFIB_DUMP, mp);
20409   S (mp);
20410
20411   /* Use a control ping for synchronization */
20412   MPING (CONTROL_PING, mp_ping);
20413   S (mp_ping);
20414
20415   W (ret);
20416   return ret;
20417 }
20418
20419 static void vl_api_ip_neighbor_details_t_handler
20420   (vl_api_ip_neighbor_details_t * mp)
20421 {
20422   vat_main_t *vam = &vat_main;
20423
20424   print (vam->ofp, "%c %U %U",
20425          (mp->is_static) ? 'S' : 'D',
20426          format_ethernet_address, &mp->mac_address,
20427          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20428          &mp->ip_address);
20429 }
20430
20431 static void vl_api_ip_neighbor_details_t_handler_json
20432   (vl_api_ip_neighbor_details_t * mp)
20433 {
20434
20435   vat_main_t *vam = &vat_main;
20436   vat_json_node_t *node;
20437   struct in_addr ip4;
20438   struct in6_addr ip6;
20439
20440   if (VAT_JSON_ARRAY != vam->json_tree.type)
20441     {
20442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20443       vat_json_init_array (&vam->json_tree);
20444     }
20445   node = vat_json_array_add (&vam->json_tree);
20446
20447   vat_json_init_object (node);
20448   vat_json_object_add_string_copy (node, "flag",
20449                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20450                                    "dynamic");
20451
20452   vat_json_object_add_string_copy (node, "link_layer",
20453                                    format (0, "%U", format_ethernet_address,
20454                                            &mp->mac_address));
20455
20456   if (mp->is_ipv6)
20457     {
20458       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20459       vat_json_object_add_ip6 (node, "ip_address", ip6);
20460     }
20461   else
20462     {
20463       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20464       vat_json_object_add_ip4 (node, "ip_address", ip4);
20465     }
20466 }
20467
20468 static int
20469 api_ip_neighbor_dump (vat_main_t * vam)
20470 {
20471   unformat_input_t *i = vam->input;
20472   vl_api_ip_neighbor_dump_t *mp;
20473   vl_api_control_ping_t *mp_ping;
20474   u8 is_ipv6 = 0;
20475   u32 sw_if_index = ~0;
20476   int ret;
20477
20478   /* Parse args required to build the message */
20479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20480     {
20481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20482         ;
20483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20484         ;
20485       else if (unformat (i, "ip6"))
20486         is_ipv6 = 1;
20487       else
20488         break;
20489     }
20490
20491   if (sw_if_index == ~0)
20492     {
20493       errmsg ("missing interface name or sw_if_index");
20494       return -99;
20495     }
20496
20497   M (IP_NEIGHBOR_DUMP, mp);
20498   mp->is_ipv6 = (u8) is_ipv6;
20499   mp->sw_if_index = ntohl (sw_if_index);
20500   S (mp);
20501
20502   /* Use a control ping for synchronization */
20503   MPING (CONTROL_PING, mp_ping);
20504   S (mp_ping);
20505
20506   W (ret);
20507   return ret;
20508 }
20509
20510 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20511 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20512
20513 static void
20514 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20515 {
20516   vat_main_t *vam = &vat_main;
20517   int count = ntohl (mp->count);
20518   vl_api_fib_path_t *fp;
20519   int i;
20520
20521   print (vam->ofp,
20522          "table-id %d, prefix %U/%d",
20523          ntohl (mp->table_id), format_ip6_address, mp->address,
20524          mp->address_length);
20525   fp = mp->path;
20526   for (i = 0; i < count; i++)
20527     {
20528       if (fp->afi == IP46_TYPE_IP6)
20529         print (vam->ofp,
20530                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20531                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20532                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20533                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20534                format_ip6_address, fp->next_hop);
20535       else if (fp->afi == IP46_TYPE_IP4)
20536         print (vam->ofp,
20537                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20538                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20539                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20540                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20541                format_ip4_address, fp->next_hop);
20542       fp++;
20543     }
20544 }
20545
20546 static void vl_api_ip6_fib_details_t_handler_json
20547   (vl_api_ip6_fib_details_t * mp)
20548 {
20549   vat_main_t *vam = &vat_main;
20550   int count = ntohl (mp->count);
20551   vat_json_node_t *node = NULL;
20552   struct in_addr ip4;
20553   struct in6_addr ip6;
20554   vl_api_fib_path_t *fp;
20555   int i;
20556
20557   if (VAT_JSON_ARRAY != vam->json_tree.type)
20558     {
20559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20560       vat_json_init_array (&vam->json_tree);
20561     }
20562   node = vat_json_array_add (&vam->json_tree);
20563
20564   vat_json_init_object (node);
20565   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20566   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20567   vat_json_object_add_ip6 (node, "prefix", ip6);
20568   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20569   vat_json_object_add_uint (node, "path_count", count);
20570   fp = mp->path;
20571   for (i = 0; i < count; i++)
20572     {
20573       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20574       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20575       vat_json_object_add_uint (node, "is_local", fp->is_local);
20576       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20577       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20578       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20579       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20580       if (fp->afi == IP46_TYPE_IP4)
20581         {
20582           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20583           vat_json_object_add_ip4 (node, "next_hop", ip4);
20584         }
20585       else if (fp->afi == IP46_TYPE_IP6)
20586         {
20587           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20588           vat_json_object_add_ip6 (node, "next_hop", ip6);
20589         }
20590     }
20591 }
20592
20593 static int
20594 api_ip6_fib_dump (vat_main_t * vam)
20595 {
20596   vl_api_ip6_fib_dump_t *mp;
20597   vl_api_control_ping_t *mp_ping;
20598   int ret;
20599
20600   M (IP6_FIB_DUMP, mp);
20601   S (mp);
20602
20603   /* Use a control ping for synchronization */
20604   MPING (CONTROL_PING, mp_ping);
20605   S (mp_ping);
20606
20607   W (ret);
20608   return ret;
20609 }
20610
20611 static int
20612 api_ip6_mfib_dump (vat_main_t * vam)
20613 {
20614   vl_api_ip6_mfib_dump_t *mp;
20615   vl_api_control_ping_t *mp_ping;
20616   int ret;
20617
20618   M (IP6_MFIB_DUMP, mp);
20619   S (mp);
20620
20621   /* Use a control ping for synchronization */
20622   MPING (CONTROL_PING, mp_ping);
20623   S (mp_ping);
20624
20625   W (ret);
20626   return ret;
20627 }
20628
20629 int
20630 api_classify_table_ids (vat_main_t * vam)
20631 {
20632   vl_api_classify_table_ids_t *mp;
20633   int ret;
20634
20635   /* Construct the API message */
20636   M (CLASSIFY_TABLE_IDS, mp);
20637   mp->context = 0;
20638
20639   S (mp);
20640   W (ret);
20641   return ret;
20642 }
20643
20644 int
20645 api_classify_table_by_interface (vat_main_t * vam)
20646 {
20647   unformat_input_t *input = vam->input;
20648   vl_api_classify_table_by_interface_t *mp;
20649
20650   u32 sw_if_index = ~0;
20651   int ret;
20652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20653     {
20654       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20655         ;
20656       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20657         ;
20658       else
20659         break;
20660     }
20661   if (sw_if_index == ~0)
20662     {
20663       errmsg ("missing interface name or sw_if_index");
20664       return -99;
20665     }
20666
20667   /* Construct the API message */
20668   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20669   mp->context = 0;
20670   mp->sw_if_index = ntohl (sw_if_index);
20671
20672   S (mp);
20673   W (ret);
20674   return ret;
20675 }
20676
20677 int
20678 api_classify_table_info (vat_main_t * vam)
20679 {
20680   unformat_input_t *input = vam->input;
20681   vl_api_classify_table_info_t *mp;
20682
20683   u32 table_id = ~0;
20684   int ret;
20685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20686     {
20687       if (unformat (input, "table_id %d", &table_id))
20688         ;
20689       else
20690         break;
20691     }
20692   if (table_id == ~0)
20693     {
20694       errmsg ("missing table id");
20695       return -99;
20696     }
20697
20698   /* Construct the API message */
20699   M (CLASSIFY_TABLE_INFO, mp);
20700   mp->context = 0;
20701   mp->table_id = ntohl (table_id);
20702
20703   S (mp);
20704   W (ret);
20705   return ret;
20706 }
20707
20708 int
20709 api_classify_session_dump (vat_main_t * vam)
20710 {
20711   unformat_input_t *input = vam->input;
20712   vl_api_classify_session_dump_t *mp;
20713   vl_api_control_ping_t *mp_ping;
20714
20715   u32 table_id = ~0;
20716   int ret;
20717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20718     {
20719       if (unformat (input, "table_id %d", &table_id))
20720         ;
20721       else
20722         break;
20723     }
20724   if (table_id == ~0)
20725     {
20726       errmsg ("missing table id");
20727       return -99;
20728     }
20729
20730   /* Construct the API message */
20731   M (CLASSIFY_SESSION_DUMP, mp);
20732   mp->context = 0;
20733   mp->table_id = ntohl (table_id);
20734   S (mp);
20735
20736   /* Use a control ping for synchronization */
20737   MPING (CONTROL_PING, mp_ping);
20738   S (mp_ping);
20739
20740   W (ret);
20741   return ret;
20742 }
20743
20744 static void
20745 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20746 {
20747   vat_main_t *vam = &vat_main;
20748
20749   print (vam->ofp, "collector_address %U, collector_port %d, "
20750          "src_address %U, vrf_id %d, path_mtu %u, "
20751          "template_interval %u, udp_checksum %d",
20752          format_ip4_address, mp->collector_address,
20753          ntohs (mp->collector_port),
20754          format_ip4_address, mp->src_address,
20755          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20756          ntohl (mp->template_interval), mp->udp_checksum);
20757
20758   vam->retval = 0;
20759   vam->result_ready = 1;
20760 }
20761
20762 static void
20763   vl_api_ipfix_exporter_details_t_handler_json
20764   (vl_api_ipfix_exporter_details_t * mp)
20765 {
20766   vat_main_t *vam = &vat_main;
20767   vat_json_node_t node;
20768   struct in_addr collector_address;
20769   struct in_addr src_address;
20770
20771   vat_json_init_object (&node);
20772   clib_memcpy (&collector_address, &mp->collector_address,
20773                sizeof (collector_address));
20774   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20775   vat_json_object_add_uint (&node, "collector_port",
20776                             ntohs (mp->collector_port));
20777   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20778   vat_json_object_add_ip4 (&node, "src_address", src_address);
20779   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20780   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20781   vat_json_object_add_uint (&node, "template_interval",
20782                             ntohl (mp->template_interval));
20783   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20784
20785   vat_json_print (vam->ofp, &node);
20786   vat_json_free (&node);
20787   vam->retval = 0;
20788   vam->result_ready = 1;
20789 }
20790
20791 int
20792 api_ipfix_exporter_dump (vat_main_t * vam)
20793 {
20794   vl_api_ipfix_exporter_dump_t *mp;
20795   int ret;
20796
20797   /* Construct the API message */
20798   M (IPFIX_EXPORTER_DUMP, mp);
20799   mp->context = 0;
20800
20801   S (mp);
20802   W (ret);
20803   return ret;
20804 }
20805
20806 static int
20807 api_ipfix_classify_stream_dump (vat_main_t * vam)
20808 {
20809   vl_api_ipfix_classify_stream_dump_t *mp;
20810   int ret;
20811
20812   /* Construct the API message */
20813   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20814   mp->context = 0;
20815
20816   S (mp);
20817   W (ret);
20818   return ret;
20819   /* NOTREACHED */
20820   return 0;
20821 }
20822
20823 static void
20824   vl_api_ipfix_classify_stream_details_t_handler
20825   (vl_api_ipfix_classify_stream_details_t * mp)
20826 {
20827   vat_main_t *vam = &vat_main;
20828   print (vam->ofp, "domain_id %d, src_port %d",
20829          ntohl (mp->domain_id), ntohs (mp->src_port));
20830   vam->retval = 0;
20831   vam->result_ready = 1;
20832 }
20833
20834 static void
20835   vl_api_ipfix_classify_stream_details_t_handler_json
20836   (vl_api_ipfix_classify_stream_details_t * mp)
20837 {
20838   vat_main_t *vam = &vat_main;
20839   vat_json_node_t node;
20840
20841   vat_json_init_object (&node);
20842   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20843   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20844
20845   vat_json_print (vam->ofp, &node);
20846   vat_json_free (&node);
20847   vam->retval = 0;
20848   vam->result_ready = 1;
20849 }
20850
20851 static int
20852 api_ipfix_classify_table_dump (vat_main_t * vam)
20853 {
20854   vl_api_ipfix_classify_table_dump_t *mp;
20855   vl_api_control_ping_t *mp_ping;
20856   int ret;
20857
20858   if (!vam->json_output)
20859     {
20860       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20861              "transport_protocol");
20862     }
20863
20864   /* Construct the API message */
20865   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20866
20867   /* send it... */
20868   S (mp);
20869
20870   /* Use a control ping for synchronization */
20871   MPING (CONTROL_PING, mp_ping);
20872   S (mp_ping);
20873
20874   W (ret);
20875   return ret;
20876 }
20877
20878 static void
20879   vl_api_ipfix_classify_table_details_t_handler
20880   (vl_api_ipfix_classify_table_details_t * mp)
20881 {
20882   vat_main_t *vam = &vat_main;
20883   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20884          mp->transport_protocol);
20885 }
20886
20887 static void
20888   vl_api_ipfix_classify_table_details_t_handler_json
20889   (vl_api_ipfix_classify_table_details_t * mp)
20890 {
20891   vat_json_node_t *node = NULL;
20892   vat_main_t *vam = &vat_main;
20893
20894   if (VAT_JSON_ARRAY != vam->json_tree.type)
20895     {
20896       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20897       vat_json_init_array (&vam->json_tree);
20898     }
20899
20900   node = vat_json_array_add (&vam->json_tree);
20901   vat_json_init_object (node);
20902
20903   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20904   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20905   vat_json_object_add_uint (node, "transport_protocol",
20906                             mp->transport_protocol);
20907 }
20908
20909 static int
20910 api_sw_interface_span_enable_disable (vat_main_t * vam)
20911 {
20912   unformat_input_t *i = vam->input;
20913   vl_api_sw_interface_span_enable_disable_t *mp;
20914   u32 src_sw_if_index = ~0;
20915   u32 dst_sw_if_index = ~0;
20916   u8 state = 3;
20917   int ret;
20918   u8 is_l2 = 0;
20919
20920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20921     {
20922       if (unformat
20923           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20924         ;
20925       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20926         ;
20927       else
20928         if (unformat
20929             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20930         ;
20931       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20932         ;
20933       else if (unformat (i, "disable"))
20934         state = 0;
20935       else if (unformat (i, "rx"))
20936         state = 1;
20937       else if (unformat (i, "tx"))
20938         state = 2;
20939       else if (unformat (i, "both"))
20940         state = 3;
20941       else if (unformat (i, "l2"))
20942         is_l2 = 1;
20943       else
20944         break;
20945     }
20946
20947   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20948
20949   mp->sw_if_index_from = htonl (src_sw_if_index);
20950   mp->sw_if_index_to = htonl (dst_sw_if_index);
20951   mp->state = state;
20952   mp->is_l2 = is_l2;
20953
20954   S (mp);
20955   W (ret);
20956   return ret;
20957 }
20958
20959 static void
20960 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20961                                             * mp)
20962 {
20963   vat_main_t *vam = &vat_main;
20964   u8 *sw_if_from_name = 0;
20965   u8 *sw_if_to_name = 0;
20966   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20967   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20968   char *states[] = { "none", "rx", "tx", "both" };
20969   hash_pair_t *p;
20970
20971   /* *INDENT-OFF* */
20972   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20973   ({
20974     if ((u32) p->value[0] == sw_if_index_from)
20975       {
20976         sw_if_from_name = (u8 *)(p->key);
20977         if (sw_if_to_name)
20978           break;
20979       }
20980     if ((u32) p->value[0] == sw_if_index_to)
20981       {
20982         sw_if_to_name = (u8 *)(p->key);
20983         if (sw_if_from_name)
20984           break;
20985       }
20986   }));
20987   /* *INDENT-ON* */
20988   print (vam->ofp, "%20s => %20s (%s) %s",
20989          sw_if_from_name, sw_if_to_name, states[mp->state],
20990          mp->is_l2 ? "l2" : "device");
20991 }
20992
20993 static void
20994   vl_api_sw_interface_span_details_t_handler_json
20995   (vl_api_sw_interface_span_details_t * mp)
20996 {
20997   vat_main_t *vam = &vat_main;
20998   vat_json_node_t *node = NULL;
20999   u8 *sw_if_from_name = 0;
21000   u8 *sw_if_to_name = 0;
21001   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21002   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21003   hash_pair_t *p;
21004
21005   /* *INDENT-OFF* */
21006   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21007   ({
21008     if ((u32) p->value[0] == sw_if_index_from)
21009       {
21010         sw_if_from_name = (u8 *)(p->key);
21011         if (sw_if_to_name)
21012           break;
21013       }
21014     if ((u32) p->value[0] == sw_if_index_to)
21015       {
21016         sw_if_to_name = (u8 *)(p->key);
21017         if (sw_if_from_name)
21018           break;
21019       }
21020   }));
21021   /* *INDENT-ON* */
21022
21023   if (VAT_JSON_ARRAY != vam->json_tree.type)
21024     {
21025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21026       vat_json_init_array (&vam->json_tree);
21027     }
21028   node = vat_json_array_add (&vam->json_tree);
21029
21030   vat_json_init_object (node);
21031   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21032   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21033   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21034   if (0 != sw_if_to_name)
21035     {
21036       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21037     }
21038   vat_json_object_add_uint (node, "state", mp->state);
21039   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21040 }
21041
21042 static int
21043 api_sw_interface_span_dump (vat_main_t * vam)
21044 {
21045   unformat_input_t *input = vam->input;
21046   vl_api_sw_interface_span_dump_t *mp;
21047   vl_api_control_ping_t *mp_ping;
21048   u8 is_l2 = 0;
21049   int ret;
21050
21051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21052     {
21053       if (unformat (input, "l2"))
21054         is_l2 = 1;
21055       else
21056         break;
21057     }
21058
21059   M (SW_INTERFACE_SPAN_DUMP, mp);
21060   mp->is_l2 = is_l2;
21061   S (mp);
21062
21063   /* Use a control ping for synchronization */
21064   MPING (CONTROL_PING, mp_ping);
21065   S (mp_ping);
21066
21067   W (ret);
21068   return ret;
21069 }
21070
21071 int
21072 api_pg_create_interface (vat_main_t * vam)
21073 {
21074   unformat_input_t *input = vam->input;
21075   vl_api_pg_create_interface_t *mp;
21076
21077   u32 if_id = ~0;
21078   int ret;
21079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21080     {
21081       if (unformat (input, "if_id %d", &if_id))
21082         ;
21083       else
21084         break;
21085     }
21086   if (if_id == ~0)
21087     {
21088       errmsg ("missing pg interface index");
21089       return -99;
21090     }
21091
21092   /* Construct the API message */
21093   M (PG_CREATE_INTERFACE, mp);
21094   mp->context = 0;
21095   mp->interface_id = ntohl (if_id);
21096
21097   S (mp);
21098   W (ret);
21099   return ret;
21100 }
21101
21102 int
21103 api_pg_capture (vat_main_t * vam)
21104 {
21105   unformat_input_t *input = vam->input;
21106   vl_api_pg_capture_t *mp;
21107
21108   u32 if_id = ~0;
21109   u8 enable = 1;
21110   u32 count = 1;
21111   u8 pcap_file_set = 0;
21112   u8 *pcap_file = 0;
21113   int ret;
21114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21115     {
21116       if (unformat (input, "if_id %d", &if_id))
21117         ;
21118       else if (unformat (input, "pcap %s", &pcap_file))
21119         pcap_file_set = 1;
21120       else if (unformat (input, "count %d", &count))
21121         ;
21122       else if (unformat (input, "disable"))
21123         enable = 0;
21124       else
21125         break;
21126     }
21127   if (if_id == ~0)
21128     {
21129       errmsg ("missing pg interface index");
21130       return -99;
21131     }
21132   if (pcap_file_set > 0)
21133     {
21134       if (vec_len (pcap_file) > 255)
21135         {
21136           errmsg ("pcap file name is too long");
21137           return -99;
21138         }
21139     }
21140
21141   u32 name_len = vec_len (pcap_file);
21142   /* Construct the API message */
21143   M (PG_CAPTURE, mp);
21144   mp->context = 0;
21145   mp->interface_id = ntohl (if_id);
21146   mp->is_enabled = enable;
21147   mp->count = ntohl (count);
21148   mp->pcap_name_length = ntohl (name_len);
21149   if (pcap_file_set != 0)
21150     {
21151       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21152     }
21153   vec_free (pcap_file);
21154
21155   S (mp);
21156   W (ret);
21157   return ret;
21158 }
21159
21160 int
21161 api_pg_enable_disable (vat_main_t * vam)
21162 {
21163   unformat_input_t *input = vam->input;
21164   vl_api_pg_enable_disable_t *mp;
21165
21166   u8 enable = 1;
21167   u8 stream_name_set = 0;
21168   u8 *stream_name = 0;
21169   int ret;
21170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21171     {
21172       if (unformat (input, "stream %s", &stream_name))
21173         stream_name_set = 1;
21174       else if (unformat (input, "disable"))
21175         enable = 0;
21176       else
21177         break;
21178     }
21179
21180   if (stream_name_set > 0)
21181     {
21182       if (vec_len (stream_name) > 255)
21183         {
21184           errmsg ("stream name too long");
21185           return -99;
21186         }
21187     }
21188
21189   u32 name_len = vec_len (stream_name);
21190   /* Construct the API message */
21191   M (PG_ENABLE_DISABLE, mp);
21192   mp->context = 0;
21193   mp->is_enabled = enable;
21194   if (stream_name_set != 0)
21195     {
21196       mp->stream_name_length = ntohl (name_len);
21197       clib_memcpy (mp->stream_name, stream_name, name_len);
21198     }
21199   vec_free (stream_name);
21200
21201   S (mp);
21202   W (ret);
21203   return ret;
21204 }
21205
21206 int
21207 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21208 {
21209   unformat_input_t *input = vam->input;
21210   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21211
21212   u16 *low_ports = 0;
21213   u16 *high_ports = 0;
21214   u16 this_low;
21215   u16 this_hi;
21216   ip4_address_t ip4_addr;
21217   ip6_address_t ip6_addr;
21218   u32 length;
21219   u32 tmp, tmp2;
21220   u8 prefix_set = 0;
21221   u32 vrf_id = ~0;
21222   u8 is_add = 1;
21223   u8 is_ipv6 = 0;
21224   int ret;
21225
21226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21227     {
21228       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21229         {
21230           prefix_set = 1;
21231         }
21232       else
21233         if (unformat
21234             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21235         {
21236           prefix_set = 1;
21237           is_ipv6 = 1;
21238         }
21239       else if (unformat (input, "vrf %d", &vrf_id))
21240         ;
21241       else if (unformat (input, "del"))
21242         is_add = 0;
21243       else if (unformat (input, "port %d", &tmp))
21244         {
21245           if (tmp == 0 || tmp > 65535)
21246             {
21247               errmsg ("port %d out of range", tmp);
21248               return -99;
21249             }
21250           this_low = tmp;
21251           this_hi = this_low + 1;
21252           vec_add1 (low_ports, this_low);
21253           vec_add1 (high_ports, this_hi);
21254         }
21255       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21256         {
21257           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21258             {
21259               errmsg ("incorrect range parameters");
21260               return -99;
21261             }
21262           this_low = tmp;
21263           /* Note: in debug CLI +1 is added to high before
21264              passing to real fn that does "the work"
21265              (ip_source_and_port_range_check_add_del).
21266              This fn is a wrapper around the binary API fn a
21267              control plane will call, which expects this increment
21268              to have occurred. Hence letting the binary API control
21269              plane fn do the increment for consistency between VAT
21270              and other control planes.
21271            */
21272           this_hi = tmp2;
21273           vec_add1 (low_ports, this_low);
21274           vec_add1 (high_ports, this_hi);
21275         }
21276       else
21277         break;
21278     }
21279
21280   if (prefix_set == 0)
21281     {
21282       errmsg ("<address>/<mask> not specified");
21283       return -99;
21284     }
21285
21286   if (vrf_id == ~0)
21287     {
21288       errmsg ("VRF ID required, not specified");
21289       return -99;
21290     }
21291
21292   if (vrf_id == 0)
21293     {
21294       errmsg
21295         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21296       return -99;
21297     }
21298
21299   if (vec_len (low_ports) == 0)
21300     {
21301       errmsg ("At least one port or port range required");
21302       return -99;
21303     }
21304
21305   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21306
21307   mp->is_add = is_add;
21308
21309   if (is_ipv6)
21310     {
21311       mp->is_ipv6 = 1;
21312       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21313     }
21314   else
21315     {
21316       mp->is_ipv6 = 0;
21317       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21318     }
21319
21320   mp->mask_length = length;
21321   mp->number_of_ranges = vec_len (low_ports);
21322
21323   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21324   vec_free (low_ports);
21325
21326   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21327   vec_free (high_ports);
21328
21329   mp->vrf_id = ntohl (vrf_id);
21330
21331   S (mp);
21332   W (ret);
21333   return ret;
21334 }
21335
21336 int
21337 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21338 {
21339   unformat_input_t *input = vam->input;
21340   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21341   u32 sw_if_index = ~0;
21342   int vrf_set = 0;
21343   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21344   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21345   u8 is_add = 1;
21346   int ret;
21347
21348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21349     {
21350       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21351         ;
21352       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21353         ;
21354       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21355         vrf_set = 1;
21356       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21357         vrf_set = 1;
21358       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21359         vrf_set = 1;
21360       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21361         vrf_set = 1;
21362       else if (unformat (input, "del"))
21363         is_add = 0;
21364       else
21365         break;
21366     }
21367
21368   if (sw_if_index == ~0)
21369     {
21370       errmsg ("Interface required but not specified");
21371       return -99;
21372     }
21373
21374   if (vrf_set == 0)
21375     {
21376       errmsg ("VRF ID required but not specified");
21377       return -99;
21378     }
21379
21380   if (tcp_out_vrf_id == 0
21381       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21382     {
21383       errmsg
21384         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21385       return -99;
21386     }
21387
21388   /* Construct the API message */
21389   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21390
21391   mp->sw_if_index = ntohl (sw_if_index);
21392   mp->is_add = is_add;
21393   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21394   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21395   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21396   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21397
21398   /* send it... */
21399   S (mp);
21400
21401   /* Wait for a reply... */
21402   W (ret);
21403   return ret;
21404 }
21405
21406 static int
21407 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21408 {
21409   unformat_input_t *i = vam->input;
21410   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21411   u32 local_sa_id = 0;
21412   u32 remote_sa_id = 0;
21413   ip4_address_t src_address;
21414   ip4_address_t dst_address;
21415   u8 is_add = 1;
21416   int ret;
21417
21418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21419     {
21420       if (unformat (i, "local_sa %d", &local_sa_id))
21421         ;
21422       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21423         ;
21424       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21425         ;
21426       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21427         ;
21428       else if (unformat (i, "del"))
21429         is_add = 0;
21430       else
21431         {
21432           clib_warning ("parse error '%U'", format_unformat_error, i);
21433           return -99;
21434         }
21435     }
21436
21437   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21438
21439   mp->local_sa_id = ntohl (local_sa_id);
21440   mp->remote_sa_id = ntohl (remote_sa_id);
21441   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21442   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21443   mp->is_add = is_add;
21444
21445   S (mp);
21446   W (ret);
21447   return ret;
21448 }
21449
21450 static int
21451 api_punt (vat_main_t * vam)
21452 {
21453   unformat_input_t *i = vam->input;
21454   vl_api_punt_t *mp;
21455   u32 ipv = ~0;
21456   u32 protocol = ~0;
21457   u32 port = ~0;
21458   int is_add = 1;
21459   int ret;
21460
21461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21462     {
21463       if (unformat (i, "ip %d", &ipv))
21464         ;
21465       else if (unformat (i, "protocol %d", &protocol))
21466         ;
21467       else if (unformat (i, "port %d", &port))
21468         ;
21469       else if (unformat (i, "del"))
21470         is_add = 0;
21471       else
21472         {
21473           clib_warning ("parse error '%U'", format_unformat_error, i);
21474           return -99;
21475         }
21476     }
21477
21478   M (PUNT, mp);
21479
21480   mp->is_add = (u8) is_add;
21481   mp->ipv = (u8) ipv;
21482   mp->l4_protocol = (u8) protocol;
21483   mp->l4_port = htons ((u16) port);
21484
21485   S (mp);
21486   W (ret);
21487   return ret;
21488 }
21489
21490 static void vl_api_ipsec_gre_tunnel_details_t_handler
21491   (vl_api_ipsec_gre_tunnel_details_t * mp)
21492 {
21493   vat_main_t *vam = &vat_main;
21494
21495   print (vam->ofp, "%11d%15U%15U%14d%14d",
21496          ntohl (mp->sw_if_index),
21497          format_ip4_address, &mp->src_address,
21498          format_ip4_address, &mp->dst_address,
21499          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21500 }
21501
21502 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21503   (vl_api_ipsec_gre_tunnel_details_t * mp)
21504 {
21505   vat_main_t *vam = &vat_main;
21506   vat_json_node_t *node = NULL;
21507   struct in_addr ip4;
21508
21509   if (VAT_JSON_ARRAY != vam->json_tree.type)
21510     {
21511       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21512       vat_json_init_array (&vam->json_tree);
21513     }
21514   node = vat_json_array_add (&vam->json_tree);
21515
21516   vat_json_init_object (node);
21517   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21518   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21519   vat_json_object_add_ip4 (node, "src_address", ip4);
21520   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21521   vat_json_object_add_ip4 (node, "dst_address", ip4);
21522   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21523   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21524 }
21525
21526 static int
21527 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21528 {
21529   unformat_input_t *i = vam->input;
21530   vl_api_ipsec_gre_tunnel_dump_t *mp;
21531   vl_api_control_ping_t *mp_ping;
21532   u32 sw_if_index;
21533   u8 sw_if_index_set = 0;
21534   int ret;
21535
21536   /* Parse args required to build the message */
21537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21538     {
21539       if (unformat (i, "sw_if_index %d", &sw_if_index))
21540         sw_if_index_set = 1;
21541       else
21542         break;
21543     }
21544
21545   if (sw_if_index_set == 0)
21546     {
21547       sw_if_index = ~0;
21548     }
21549
21550   if (!vam->json_output)
21551     {
21552       print (vam->ofp, "%11s%15s%15s%14s%14s",
21553              "sw_if_index", "src_address", "dst_address",
21554              "local_sa_id", "remote_sa_id");
21555     }
21556
21557   /* Get list of gre-tunnel interfaces */
21558   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21559
21560   mp->sw_if_index = htonl (sw_if_index);
21561
21562   S (mp);
21563
21564   /* Use a control ping for synchronization */
21565   MPING (CONTROL_PING, mp_ping);
21566   S (mp_ping);
21567
21568   W (ret);
21569   return ret;
21570 }
21571
21572 static int
21573 api_delete_subif (vat_main_t * vam)
21574 {
21575   unformat_input_t *i = vam->input;
21576   vl_api_delete_subif_t *mp;
21577   u32 sw_if_index = ~0;
21578   int ret;
21579
21580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21581     {
21582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21583         ;
21584       if (unformat (i, "sw_if_index %d", &sw_if_index))
21585         ;
21586       else
21587         break;
21588     }
21589
21590   if (sw_if_index == ~0)
21591     {
21592       errmsg ("missing sw_if_index");
21593       return -99;
21594     }
21595
21596   /* Construct the API message */
21597   M (DELETE_SUBIF, mp);
21598   mp->sw_if_index = ntohl (sw_if_index);
21599
21600   S (mp);
21601   W (ret);
21602   return ret;
21603 }
21604
21605 #define foreach_pbb_vtr_op      \
21606 _("disable",  L2_VTR_DISABLED)  \
21607 _("pop",  L2_VTR_POP_2)         \
21608 _("push",  L2_VTR_PUSH_2)
21609
21610 static int
21611 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21612 {
21613   unformat_input_t *i = vam->input;
21614   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21615   u32 sw_if_index = ~0, vtr_op = ~0;
21616   u16 outer_tag = ~0;
21617   u8 dmac[6], smac[6];
21618   u8 dmac_set = 0, smac_set = 0;
21619   u16 vlanid = 0;
21620   u32 sid = ~0;
21621   u32 tmp;
21622   int ret;
21623
21624   /* Shut up coverity */
21625   memset (dmac, 0, sizeof (dmac));
21626   memset (smac, 0, sizeof (smac));
21627
21628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21629     {
21630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21631         ;
21632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21633         ;
21634       else if (unformat (i, "vtr_op %d", &vtr_op))
21635         ;
21636 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21637       foreach_pbb_vtr_op
21638 #undef _
21639         else if (unformat (i, "translate_pbb_stag"))
21640         {
21641           if (unformat (i, "%d", &tmp))
21642             {
21643               vtr_op = L2_VTR_TRANSLATE_2_1;
21644               outer_tag = tmp;
21645             }
21646           else
21647             {
21648               errmsg
21649                 ("translate_pbb_stag operation requires outer tag definition");
21650               return -99;
21651             }
21652         }
21653       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21654         dmac_set++;
21655       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21656         smac_set++;
21657       else if (unformat (i, "sid %d", &sid))
21658         ;
21659       else if (unformat (i, "vlanid %d", &tmp))
21660         vlanid = tmp;
21661       else
21662         {
21663           clib_warning ("parse error '%U'", format_unformat_error, i);
21664           return -99;
21665         }
21666     }
21667
21668   if ((sw_if_index == ~0) || (vtr_op == ~0))
21669     {
21670       errmsg ("missing sw_if_index or vtr operation");
21671       return -99;
21672     }
21673   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21674       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21675     {
21676       errmsg
21677         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21678       return -99;
21679     }
21680
21681   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21682   mp->sw_if_index = ntohl (sw_if_index);
21683   mp->vtr_op = ntohl (vtr_op);
21684   mp->outer_tag = ntohs (outer_tag);
21685   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21686   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21687   mp->b_vlanid = ntohs (vlanid);
21688   mp->i_sid = ntohl (sid);
21689
21690   S (mp);
21691   W (ret);
21692   return ret;
21693 }
21694
21695 static int
21696 api_flow_classify_set_interface (vat_main_t * vam)
21697 {
21698   unformat_input_t *i = vam->input;
21699   vl_api_flow_classify_set_interface_t *mp;
21700   u32 sw_if_index;
21701   int sw_if_index_set;
21702   u32 ip4_table_index = ~0;
21703   u32 ip6_table_index = ~0;
21704   u8 is_add = 1;
21705   int ret;
21706
21707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21708     {
21709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21710         sw_if_index_set = 1;
21711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21712         sw_if_index_set = 1;
21713       else if (unformat (i, "del"))
21714         is_add = 0;
21715       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21716         ;
21717       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21718         ;
21719       else
21720         {
21721           clib_warning ("parse error '%U'", format_unformat_error, i);
21722           return -99;
21723         }
21724     }
21725
21726   if (sw_if_index_set == 0)
21727     {
21728       errmsg ("missing interface name or sw_if_index");
21729       return -99;
21730     }
21731
21732   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21733
21734   mp->sw_if_index = ntohl (sw_if_index);
21735   mp->ip4_table_index = ntohl (ip4_table_index);
21736   mp->ip6_table_index = ntohl (ip6_table_index);
21737   mp->is_add = is_add;
21738
21739   S (mp);
21740   W (ret);
21741   return ret;
21742 }
21743
21744 static int
21745 api_flow_classify_dump (vat_main_t * vam)
21746 {
21747   unformat_input_t *i = vam->input;
21748   vl_api_flow_classify_dump_t *mp;
21749   vl_api_control_ping_t *mp_ping;
21750   u8 type = FLOW_CLASSIFY_N_TABLES;
21751   int ret;
21752
21753   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21754     ;
21755   else
21756     {
21757       errmsg ("classify table type must be specified");
21758       return -99;
21759     }
21760
21761   if (!vam->json_output)
21762     {
21763       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21764     }
21765
21766   M (FLOW_CLASSIFY_DUMP, mp);
21767   mp->type = type;
21768   /* send it... */
21769   S (mp);
21770
21771   /* Use a control ping for synchronization */
21772   MPING (CONTROL_PING, mp_ping);
21773   S (mp_ping);
21774
21775   /* Wait for a reply... */
21776   W (ret);
21777   return ret;
21778 }
21779
21780 static int
21781 api_feature_enable_disable (vat_main_t * vam)
21782 {
21783   unformat_input_t *i = vam->input;
21784   vl_api_feature_enable_disable_t *mp;
21785   u8 *arc_name = 0;
21786   u8 *feature_name = 0;
21787   u32 sw_if_index = ~0;
21788   u8 enable = 1;
21789   int ret;
21790
21791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21792     {
21793       if (unformat (i, "arc_name %s", &arc_name))
21794         ;
21795       else if (unformat (i, "feature_name %s", &feature_name))
21796         ;
21797       else
21798         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21799         ;
21800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21801         ;
21802       else if (unformat (i, "disable"))
21803         enable = 0;
21804       else
21805         break;
21806     }
21807
21808   if (arc_name == 0)
21809     {
21810       errmsg ("missing arc name");
21811       return -99;
21812     }
21813   if (vec_len (arc_name) > 63)
21814     {
21815       errmsg ("arc name too long");
21816     }
21817
21818   if (feature_name == 0)
21819     {
21820       errmsg ("missing feature name");
21821       return -99;
21822     }
21823   if (vec_len (feature_name) > 63)
21824     {
21825       errmsg ("feature name too long");
21826     }
21827
21828   if (sw_if_index == ~0)
21829     {
21830       errmsg ("missing interface name or sw_if_index");
21831       return -99;
21832     }
21833
21834   /* Construct the API message */
21835   M (FEATURE_ENABLE_DISABLE, mp);
21836   mp->sw_if_index = ntohl (sw_if_index);
21837   mp->enable = enable;
21838   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21839   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21840   vec_free (arc_name);
21841   vec_free (feature_name);
21842
21843   S (mp);
21844   W (ret);
21845   return ret;
21846 }
21847
21848 static int
21849 api_sw_interface_tag_add_del (vat_main_t * vam)
21850 {
21851   unformat_input_t *i = vam->input;
21852   vl_api_sw_interface_tag_add_del_t *mp;
21853   u32 sw_if_index = ~0;
21854   u8 *tag = 0;
21855   u8 enable = 1;
21856   int ret;
21857
21858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21859     {
21860       if (unformat (i, "tag %s", &tag))
21861         ;
21862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21863         ;
21864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21865         ;
21866       else if (unformat (i, "del"))
21867         enable = 0;
21868       else
21869         break;
21870     }
21871
21872   if (sw_if_index == ~0)
21873     {
21874       errmsg ("missing interface name or sw_if_index");
21875       return -99;
21876     }
21877
21878   if (enable && (tag == 0))
21879     {
21880       errmsg ("no tag specified");
21881       return -99;
21882     }
21883
21884   /* Construct the API message */
21885   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21886   mp->sw_if_index = ntohl (sw_if_index);
21887   mp->is_add = enable;
21888   if (enable)
21889     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21890   vec_free (tag);
21891
21892   S (mp);
21893   W (ret);
21894   return ret;
21895 }
21896
21897 static void vl_api_l2_xconnect_details_t_handler
21898   (vl_api_l2_xconnect_details_t * mp)
21899 {
21900   vat_main_t *vam = &vat_main;
21901
21902   print (vam->ofp, "%15d%15d",
21903          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21904 }
21905
21906 static void vl_api_l2_xconnect_details_t_handler_json
21907   (vl_api_l2_xconnect_details_t * mp)
21908 {
21909   vat_main_t *vam = &vat_main;
21910   vat_json_node_t *node = NULL;
21911
21912   if (VAT_JSON_ARRAY != vam->json_tree.type)
21913     {
21914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21915       vat_json_init_array (&vam->json_tree);
21916     }
21917   node = vat_json_array_add (&vam->json_tree);
21918
21919   vat_json_init_object (node);
21920   vat_json_object_add_uint (node, "rx_sw_if_index",
21921                             ntohl (mp->rx_sw_if_index));
21922   vat_json_object_add_uint (node, "tx_sw_if_index",
21923                             ntohl (mp->tx_sw_if_index));
21924 }
21925
21926 static int
21927 api_l2_xconnect_dump (vat_main_t * vam)
21928 {
21929   vl_api_l2_xconnect_dump_t *mp;
21930   vl_api_control_ping_t *mp_ping;
21931   int ret;
21932
21933   if (!vam->json_output)
21934     {
21935       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21936     }
21937
21938   M (L2_XCONNECT_DUMP, mp);
21939
21940   S (mp);
21941
21942   /* Use a control ping for synchronization */
21943   MPING (CONTROL_PING, mp_ping);
21944   S (mp_ping);
21945
21946   W (ret);
21947   return ret;
21948 }
21949
21950 static int
21951 api_sw_interface_set_mtu (vat_main_t * vam)
21952 {
21953   unformat_input_t *i = vam->input;
21954   vl_api_sw_interface_set_mtu_t *mp;
21955   u32 sw_if_index = ~0;
21956   u32 mtu = 0;
21957   int ret;
21958
21959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21960     {
21961       if (unformat (i, "mtu %d", &mtu))
21962         ;
21963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21964         ;
21965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21966         ;
21967       else
21968         break;
21969     }
21970
21971   if (sw_if_index == ~0)
21972     {
21973       errmsg ("missing interface name or sw_if_index");
21974       return -99;
21975     }
21976
21977   if (mtu == 0)
21978     {
21979       errmsg ("no mtu specified");
21980       return -99;
21981     }
21982
21983   /* Construct the API message */
21984   M (SW_INTERFACE_SET_MTU, mp);
21985   mp->sw_if_index = ntohl (sw_if_index);
21986   mp->mtu = ntohs ((u16) mtu);
21987
21988   S (mp);
21989   W (ret);
21990   return ret;
21991 }
21992
21993 static int
21994 api_p2p_ethernet_add (vat_main_t * vam)
21995 {
21996   unformat_input_t *i = vam->input;
21997   vl_api_p2p_ethernet_add_t *mp;
21998   u32 parent_if_index = ~0;
21999   u32 sub_id = ~0;
22000   u8 remote_mac[6];
22001   u8 mac_set = 0;
22002   int ret;
22003
22004   memset (remote_mac, 0, sizeof (remote_mac));
22005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22006     {
22007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22008         ;
22009       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22010         ;
22011       else
22012         if (unformat
22013             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22014         mac_set++;
22015       else if (unformat (i, "sub_id %d", &sub_id))
22016         ;
22017       else
22018         {
22019           clib_warning ("parse error '%U'", format_unformat_error, i);
22020           return -99;
22021         }
22022     }
22023
22024   if (parent_if_index == ~0)
22025     {
22026       errmsg ("missing interface name or sw_if_index");
22027       return -99;
22028     }
22029   if (mac_set == 0)
22030     {
22031       errmsg ("missing remote mac address");
22032       return -99;
22033     }
22034   if (sub_id == ~0)
22035     {
22036       errmsg ("missing sub-interface id");
22037       return -99;
22038     }
22039
22040   M (P2P_ETHERNET_ADD, mp);
22041   mp->parent_if_index = ntohl (parent_if_index);
22042   mp->subif_id = ntohl (sub_id);
22043   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22044
22045   S (mp);
22046   W (ret);
22047   return ret;
22048 }
22049
22050 static int
22051 api_p2p_ethernet_del (vat_main_t * vam)
22052 {
22053   unformat_input_t *i = vam->input;
22054   vl_api_p2p_ethernet_del_t *mp;
22055   u32 parent_if_index = ~0;
22056   u8 remote_mac[6];
22057   u8 mac_set = 0;
22058   int ret;
22059
22060   memset (remote_mac, 0, sizeof (remote_mac));
22061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22062     {
22063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22064         ;
22065       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22066         ;
22067       else
22068         if (unformat
22069             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22070         mac_set++;
22071       else
22072         {
22073           clib_warning ("parse error '%U'", format_unformat_error, i);
22074           return -99;
22075         }
22076     }
22077
22078   if (parent_if_index == ~0)
22079     {
22080       errmsg ("missing interface name or sw_if_index");
22081       return -99;
22082     }
22083   if (mac_set == 0)
22084     {
22085       errmsg ("missing remote mac address");
22086       return -99;
22087     }
22088
22089   M (P2P_ETHERNET_DEL, mp);
22090   mp->parent_if_index = ntohl (parent_if_index);
22091   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22092
22093   S (mp);
22094   W (ret);
22095   return ret;
22096 }
22097
22098 static int
22099 api_lldp_config (vat_main_t * vam)
22100 {
22101   unformat_input_t *i = vam->input;
22102   vl_api_lldp_config_t *mp;
22103   int tx_hold = 0;
22104   int tx_interval = 0;
22105   u8 *sys_name = NULL;
22106   int ret;
22107
22108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22109     {
22110       if (unformat (i, "system-name %s", &sys_name))
22111         ;
22112       else if (unformat (i, "tx-hold %d", &tx_hold))
22113         ;
22114       else if (unformat (i, "tx-interval %d", &tx_interval))
22115         ;
22116       else
22117         {
22118           clib_warning ("parse error '%U'", format_unformat_error, i);
22119           return -99;
22120         }
22121     }
22122
22123   vec_add1 (sys_name, 0);
22124
22125   M (LLDP_CONFIG, mp);
22126   mp->tx_hold = htonl (tx_hold);
22127   mp->tx_interval = htonl (tx_interval);
22128   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22129   vec_free (sys_name);
22130
22131   S (mp);
22132   W (ret);
22133   return ret;
22134 }
22135
22136 static int
22137 api_sw_interface_set_lldp (vat_main_t * vam)
22138 {
22139   unformat_input_t *i = vam->input;
22140   vl_api_sw_interface_set_lldp_t *mp;
22141   u32 sw_if_index = ~0;
22142   u32 enable = 1;
22143   u8 *port_desc = NULL, *mgmt_oid = NULL;
22144   ip4_address_t ip4_addr;
22145   ip6_address_t ip6_addr;
22146   int ret;
22147
22148   memset (&ip4_addr, 0, sizeof (ip4_addr));
22149   memset (&ip6_addr, 0, sizeof (ip6_addr));
22150
22151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22152     {
22153       if (unformat (i, "disable"))
22154         enable = 0;
22155       else
22156         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22157         ;
22158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22159         ;
22160       else if (unformat (i, "port-desc %s", &port_desc))
22161         ;
22162       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22163         ;
22164       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22165         ;
22166       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22167         ;
22168       else
22169         break;
22170     }
22171
22172   if (sw_if_index == ~0)
22173     {
22174       errmsg ("missing interface name or sw_if_index");
22175       return -99;
22176     }
22177
22178   /* Construct the API message */
22179   vec_add1 (port_desc, 0);
22180   vec_add1 (mgmt_oid, 0);
22181   M (SW_INTERFACE_SET_LLDP, mp);
22182   mp->sw_if_index = ntohl (sw_if_index);
22183   mp->enable = enable;
22184   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22185   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22186   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22187   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22188   vec_free (port_desc);
22189   vec_free (mgmt_oid);
22190
22191   S (mp);
22192   W (ret);
22193   return ret;
22194 }
22195
22196 static int
22197 api_tcp_configure_src_addresses (vat_main_t * vam)
22198 {
22199   vl_api_tcp_configure_src_addresses_t *mp;
22200   unformat_input_t *i = vam->input;
22201   ip4_address_t v4first, v4last;
22202   ip6_address_t v6first, v6last;
22203   u8 range_set = 0;
22204   u32 vrf_id = 0;
22205   int ret;
22206
22207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22208     {
22209       if (unformat (i, "%U - %U",
22210                     unformat_ip4_address, &v4first,
22211                     unformat_ip4_address, &v4last))
22212         {
22213           if (range_set)
22214             {
22215               errmsg ("one range per message (range already set)");
22216               return -99;
22217             }
22218           range_set = 1;
22219         }
22220       else if (unformat (i, "%U - %U",
22221                          unformat_ip6_address, &v6first,
22222                          unformat_ip6_address, &v6last))
22223         {
22224           if (range_set)
22225             {
22226               errmsg ("one range per message (range already set)");
22227               return -99;
22228             }
22229           range_set = 2;
22230         }
22231       else if (unformat (i, "vrf %d", &vrf_id))
22232         ;
22233       else
22234         break;
22235     }
22236
22237   if (range_set == 0)
22238     {
22239       errmsg ("address range not set");
22240       return -99;
22241     }
22242
22243   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22244   mp->vrf_id = ntohl (vrf_id);
22245   /* ipv6? */
22246   if (range_set == 2)
22247     {
22248       mp->is_ipv6 = 1;
22249       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22250       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22251     }
22252   else
22253     {
22254       mp->is_ipv6 = 0;
22255       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22256       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22257     }
22258   S (mp);
22259   W (ret);
22260   return ret;
22261 }
22262
22263 static void vl_api_app_namespace_add_del_reply_t_handler
22264   (vl_api_app_namespace_add_del_reply_t * mp)
22265 {
22266   vat_main_t *vam = &vat_main;
22267   i32 retval = ntohl (mp->retval);
22268   if (vam->async_mode)
22269     {
22270       vam->async_errors += (retval < 0);
22271     }
22272   else
22273     {
22274       vam->retval = retval;
22275       if (retval == 0)
22276         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22277       vam->result_ready = 1;
22278     }
22279 }
22280
22281 static void vl_api_app_namespace_add_del_reply_t_handler_json
22282   (vl_api_app_namespace_add_del_reply_t * mp)
22283 {
22284   vat_main_t *vam = &vat_main;
22285   vat_json_node_t node;
22286
22287   vat_json_init_object (&node);
22288   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22289   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22290
22291   vat_json_print (vam->ofp, &node);
22292   vat_json_free (&node);
22293
22294   vam->retval = ntohl (mp->retval);
22295   vam->result_ready = 1;
22296 }
22297
22298 static int
22299 api_app_namespace_add_del (vat_main_t * vam)
22300 {
22301   vl_api_app_namespace_add_del_t *mp;
22302   unformat_input_t *i = vam->input;
22303   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22304   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22305   u64 secret;
22306   int ret;
22307
22308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22309     {
22310       if (unformat (i, "id %_%v%_", &ns_id))
22311         ;
22312       else if (unformat (i, "secret %lu", &secret))
22313         secret_set = 1;
22314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22315         sw_if_index_set = 1;
22316       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22317         ;
22318       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22319         ;
22320       else
22321         break;
22322     }
22323   if (!ns_id || !secret_set || !sw_if_index_set)
22324     {
22325       errmsg ("namespace id, secret and sw_if_index must be set");
22326       return -99;
22327     }
22328   if (vec_len (ns_id) > 64)
22329     {
22330       errmsg ("namespace id too long");
22331       return -99;
22332     }
22333   M (APP_NAMESPACE_ADD_DEL, mp);
22334
22335   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22336   mp->namespace_id_len = vec_len (ns_id);
22337   mp->secret = clib_host_to_net_u64 (secret);
22338   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22339   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22340   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22341   vec_free (ns_id);
22342   S (mp);
22343   W (ret);
22344   return ret;
22345 }
22346
22347 static int
22348 api_memfd_segment_create (vat_main_t * vam)
22349 {
22350 #if VPP_API_TEST_BUILTIN == 0
22351   unformat_input_t *i = vam->input;
22352   vl_api_memfd_segment_create_t *mp;
22353   u64 size = 64 << 20;
22354   int ret;
22355
22356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22357     {
22358       if (unformat (i, "size %U", unformat_memory_size, &size))
22359         ;
22360       else
22361         break;
22362     }
22363
22364   M (MEMFD_SEGMENT_CREATE, mp);
22365   mp->requested_size = size;
22366   S (mp);
22367   W (ret);
22368   return ret;
22369
22370 #else
22371   errmsg ("memfd_segment_create (builtin) not supported");
22372   return -99;
22373 #endif
22374 }
22375
22376 static int
22377 api_sock_init_shm (vat_main_t * vam)
22378 {
22379 #if VPP_API_TEST_BUILTIN == 0
22380   unformat_input_t *i = vam->input;
22381   vl_api_shm_elem_config_t *config = 0;
22382   u64 size = 64 << 20;
22383   int rv;
22384
22385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22386     {
22387       if (unformat (i, "size %U", unformat_memory_size, &size))
22388         ;
22389       else
22390         break;
22391     }
22392
22393   /* Try customized config to see if it works */
22394   vec_validate (config, 3);
22395   config[0].type = VL_API_VLIB_RING;
22396   config[0].count = 256;
22397   config[0].size = 256;
22398   config[1].type = VL_API_CLIENT_RING;
22399   config[1].count = 256;
22400   config[1].size = 1024;
22401   config[2].type = VL_API_CLIENT_RING;
22402   config[2].count = 8;
22403   config[2].size = 4096;
22404   config[3].type = VL_API_QUEUE;
22405   config[3].count = 256;
22406   config[3].size = sizeof (uword);
22407   rv = vl_socket_client_init_shm (config);
22408   if (!rv)
22409     vam->client_index_invalid = 1;
22410   return rv;
22411 #else
22412   return -99;
22413 #endif
22414 }
22415
22416 static int
22417 api_dns_enable_disable (vat_main_t * vam)
22418 {
22419   unformat_input_t *line_input = vam->input;
22420   vl_api_dns_enable_disable_t *mp;
22421   u8 enable_disable = 1;
22422   int ret;
22423
22424   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22425     {
22426       if (unformat (line_input, "disable"))
22427         enable_disable = 0;
22428       if (unformat (line_input, "enable"))
22429         enable_disable = 1;
22430       else
22431         break;
22432     }
22433
22434   /* Construct the API message */
22435   M (DNS_ENABLE_DISABLE, mp);
22436   mp->enable = enable_disable;
22437
22438   /* send it... */
22439   S (mp);
22440   /* Wait for the reply */
22441   W (ret);
22442   return ret;
22443 }
22444
22445 static int
22446 api_dns_resolve_name (vat_main_t * vam)
22447 {
22448   unformat_input_t *line_input = vam->input;
22449   vl_api_dns_resolve_name_t *mp;
22450   u8 *name = 0;
22451   int ret;
22452
22453   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22454     {
22455       if (unformat (line_input, "%s", &name))
22456         ;
22457       else
22458         break;
22459     }
22460
22461   if (vec_len (name) > 127)
22462     {
22463       errmsg ("name too long");
22464       return -99;
22465     }
22466
22467   /* Construct the API message */
22468   M (DNS_RESOLVE_NAME, mp);
22469   memcpy (mp->name, name, vec_len (name));
22470   vec_free (name);
22471
22472   /* send it... */
22473   S (mp);
22474   /* Wait for the reply */
22475   W (ret);
22476   return ret;
22477 }
22478
22479 static int
22480 api_dns_resolve_ip (vat_main_t * vam)
22481 {
22482   unformat_input_t *line_input = vam->input;
22483   vl_api_dns_resolve_ip_t *mp;
22484   int is_ip6 = -1;
22485   ip4_address_t addr4;
22486   ip6_address_t addr6;
22487   int ret;
22488
22489   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22490     {
22491       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22492         is_ip6 = 1;
22493       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22494         is_ip6 = 0;
22495       else
22496         break;
22497     }
22498
22499   if (is_ip6 == -1)
22500     {
22501       errmsg ("missing address");
22502       return -99;
22503     }
22504
22505   /* Construct the API message */
22506   M (DNS_RESOLVE_IP, mp);
22507   mp->is_ip6 = is_ip6;
22508   if (is_ip6)
22509     memcpy (mp->address, &addr6, sizeof (addr6));
22510   else
22511     memcpy (mp->address, &addr4, sizeof (addr4));
22512
22513   /* send it... */
22514   S (mp);
22515   /* Wait for the reply */
22516   W (ret);
22517   return ret;
22518 }
22519
22520 static int
22521 api_dns_name_server_add_del (vat_main_t * vam)
22522 {
22523   unformat_input_t *i = vam->input;
22524   vl_api_dns_name_server_add_del_t *mp;
22525   u8 is_add = 1;
22526   ip6_address_t ip6_server;
22527   ip4_address_t ip4_server;
22528   int ip6_set = 0;
22529   int ip4_set = 0;
22530   int ret = 0;
22531
22532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22533     {
22534       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22535         ip6_set = 1;
22536       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22537         ip4_set = 1;
22538       else if (unformat (i, "del"))
22539         is_add = 0;
22540       else
22541         {
22542           clib_warning ("parse error '%U'", format_unformat_error, i);
22543           return -99;
22544         }
22545     }
22546
22547   if (ip4_set && ip6_set)
22548     {
22549       errmsg ("Only one server address allowed per message");
22550       return -99;
22551     }
22552   if ((ip4_set + ip6_set) == 0)
22553     {
22554       errmsg ("Server address required");
22555       return -99;
22556     }
22557
22558   /* Construct the API message */
22559   M (DNS_NAME_SERVER_ADD_DEL, mp);
22560
22561   if (ip6_set)
22562     {
22563       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22564       mp->is_ip6 = 1;
22565     }
22566   else
22567     {
22568       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22569       mp->is_ip6 = 0;
22570     }
22571
22572   mp->is_add = is_add;
22573
22574   /* send it... */
22575   S (mp);
22576
22577   /* Wait for a reply, return good/bad news  */
22578   W (ret);
22579   return ret;
22580 }
22581
22582 static void
22583 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22584 {
22585   vat_main_t *vam = &vat_main;
22586
22587   if (mp->is_ip4)
22588     {
22589       print (vam->ofp,
22590              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22591              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22592              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22593              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22594              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22595              clib_net_to_host_u32 (mp->action_index), mp->tag);
22596     }
22597   else
22598     {
22599       print (vam->ofp,
22600              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22601              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22602              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22603              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22604              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22605              clib_net_to_host_u32 (mp->action_index), mp->tag);
22606     }
22607 }
22608
22609 static void
22610 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22611                                              mp)
22612 {
22613   vat_main_t *vam = &vat_main;
22614   vat_json_node_t *node = NULL;
22615   struct in6_addr ip6;
22616   struct in_addr ip4;
22617
22618   if (VAT_JSON_ARRAY != vam->json_tree.type)
22619     {
22620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22621       vat_json_init_array (&vam->json_tree);
22622     }
22623   node = vat_json_array_add (&vam->json_tree);
22624   vat_json_init_object (node);
22625
22626   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22627   vat_json_object_add_uint (node, "appns_index",
22628                             clib_net_to_host_u32 (mp->appns_index));
22629   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22630   vat_json_object_add_uint (node, "scope", mp->scope);
22631   vat_json_object_add_uint (node, "action_index",
22632                             clib_net_to_host_u32 (mp->action_index));
22633   vat_json_object_add_uint (node, "lcl_port",
22634                             clib_net_to_host_u16 (mp->lcl_port));
22635   vat_json_object_add_uint (node, "rmt_port",
22636                             clib_net_to_host_u16 (mp->rmt_port));
22637   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22638   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22639   vat_json_object_add_string_copy (node, "tag", mp->tag);
22640   if (mp->is_ip4)
22641     {
22642       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22643       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22644       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22645       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22646     }
22647   else
22648     {
22649       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22650       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22651       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22652       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22653     }
22654 }
22655
22656 static int
22657 api_session_rule_add_del (vat_main_t * vam)
22658 {
22659   vl_api_session_rule_add_del_t *mp;
22660   unformat_input_t *i = vam->input;
22661   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22662   u32 appns_index = 0, scope = 0;
22663   ip4_address_t lcl_ip4, rmt_ip4;
22664   ip6_address_t lcl_ip6, rmt_ip6;
22665   u8 is_ip4 = 1, conn_set = 0;
22666   u8 is_add = 1, *tag = 0;
22667   int ret;
22668
22669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22670     {
22671       if (unformat (i, "del"))
22672         is_add = 0;
22673       else if (unformat (i, "add"))
22674         ;
22675       else if (unformat (i, "proto tcp"))
22676         proto = 0;
22677       else if (unformat (i, "proto udp"))
22678         proto = 1;
22679       else if (unformat (i, "appns %d", &appns_index))
22680         ;
22681       else if (unformat (i, "scope %d", &scope))
22682         ;
22683       else if (unformat (i, "tag %_%v%_", &tag))
22684         ;
22685       else
22686         if (unformat
22687             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22688              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22689              &rmt_port))
22690         {
22691           is_ip4 = 1;
22692           conn_set = 1;
22693         }
22694       else
22695         if (unformat
22696             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22697              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22698              &rmt_port))
22699         {
22700           is_ip4 = 0;
22701           conn_set = 1;
22702         }
22703       else if (unformat (i, "action %d", &action))
22704         ;
22705       else
22706         break;
22707     }
22708   if (proto == ~0 || !conn_set || action == ~0)
22709     {
22710       errmsg ("transport proto, connection and action must be set");
22711       return -99;
22712     }
22713
22714   if (scope > 3)
22715     {
22716       errmsg ("scope should be 0-3");
22717       return -99;
22718     }
22719
22720   M (SESSION_RULE_ADD_DEL, mp);
22721
22722   mp->is_ip4 = is_ip4;
22723   mp->transport_proto = proto;
22724   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22725   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22726   mp->lcl_plen = lcl_plen;
22727   mp->rmt_plen = rmt_plen;
22728   mp->action_index = clib_host_to_net_u32 (action);
22729   mp->appns_index = clib_host_to_net_u32 (appns_index);
22730   mp->scope = scope;
22731   mp->is_add = is_add;
22732   if (is_ip4)
22733     {
22734       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22735       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22736     }
22737   else
22738     {
22739       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22740       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22741     }
22742   if (tag)
22743     {
22744       clib_memcpy (mp->tag, tag, vec_len (tag));
22745       vec_free (tag);
22746     }
22747
22748   S (mp);
22749   W (ret);
22750   return ret;
22751 }
22752
22753 static int
22754 api_session_rules_dump (vat_main_t * vam)
22755 {
22756   vl_api_session_rules_dump_t *mp;
22757   vl_api_control_ping_t *mp_ping;
22758   int ret;
22759
22760   if (!vam->json_output)
22761     {
22762       print (vam->ofp, "%=20s", "Session Rules");
22763     }
22764
22765   M (SESSION_RULES_DUMP, mp);
22766   /* send it... */
22767   S (mp);
22768
22769   /* Use a control ping for synchronization */
22770   MPING (CONTROL_PING, mp_ping);
22771   S (mp_ping);
22772
22773   /* Wait for a reply... */
22774   W (ret);
22775   return ret;
22776 }
22777
22778 static int
22779 api_ip_container_proxy_add_del (vat_main_t * vam)
22780 {
22781   vl_api_ip_container_proxy_add_del_t *mp;
22782   unformat_input_t *i = vam->input;
22783   u32 plen = ~0, sw_if_index = ~0;
22784   ip4_address_t ip4;
22785   ip6_address_t ip6;
22786   u8 is_ip4 = 1;
22787   u8 is_add = 1;
22788   int ret;
22789
22790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22791     {
22792       if (unformat (i, "del"))
22793         is_add = 0;
22794       else if (unformat (i, "add"))
22795         ;
22796       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22797         {
22798           is_ip4 = 1;
22799           plen = 32;
22800         }
22801       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22802         {
22803           is_ip4 = 0;
22804           plen = 128;
22805         }
22806       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22807         ;
22808       else
22809         break;
22810     }
22811   if (sw_if_index == ~0 || plen == ~0)
22812     {
22813       errmsg ("address and sw_if_index must be set");
22814       return -99;
22815     }
22816
22817   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22818
22819   mp->is_ip4 = is_ip4;
22820   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22821   mp->plen = plen;
22822   mp->is_add = is_add;
22823   if (is_ip4)
22824     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22825   else
22826     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22827
22828   S (mp);
22829   W (ret);
22830   return ret;
22831 }
22832
22833 static int
22834 q_or_quit (vat_main_t * vam)
22835 {
22836 #if VPP_API_TEST_BUILTIN == 0
22837   longjmp (vam->jump_buf, 1);
22838 #endif
22839   return 0;                     /* not so much */
22840 }
22841
22842 static int
22843 q (vat_main_t * vam)
22844 {
22845   return q_or_quit (vam);
22846 }
22847
22848 static int
22849 quit (vat_main_t * vam)
22850 {
22851   return q_or_quit (vam);
22852 }
22853
22854 static int
22855 comment (vat_main_t * vam)
22856 {
22857   return 0;
22858 }
22859
22860 static int
22861 cmd_cmp (void *a1, void *a2)
22862 {
22863   u8 **c1 = a1;
22864   u8 **c2 = a2;
22865
22866   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22867 }
22868
22869 static int
22870 help (vat_main_t * vam)
22871 {
22872   u8 **cmds = 0;
22873   u8 *name = 0;
22874   hash_pair_t *p;
22875   unformat_input_t *i = vam->input;
22876   int j;
22877
22878   if (unformat (i, "%s", &name))
22879     {
22880       uword *hs;
22881
22882       vec_add1 (name, 0);
22883
22884       hs = hash_get_mem (vam->help_by_name, name);
22885       if (hs)
22886         print (vam->ofp, "usage: %s %s", name, hs[0]);
22887       else
22888         print (vam->ofp, "No such msg / command '%s'", name);
22889       vec_free (name);
22890       return 0;
22891     }
22892
22893   print (vam->ofp, "Help is available for the following:");
22894
22895     /* *INDENT-OFF* */
22896     hash_foreach_pair (p, vam->function_by_name,
22897     ({
22898       vec_add1 (cmds, (u8 *)(p->key));
22899     }));
22900     /* *INDENT-ON* */
22901
22902   vec_sort_with_function (cmds, cmd_cmp);
22903
22904   for (j = 0; j < vec_len (cmds); j++)
22905     print (vam->ofp, "%s", cmds[j]);
22906
22907   vec_free (cmds);
22908   return 0;
22909 }
22910
22911 static int
22912 set (vat_main_t * vam)
22913 {
22914   u8 *name = 0, *value = 0;
22915   unformat_input_t *i = vam->input;
22916
22917   if (unformat (i, "%s", &name))
22918     {
22919       /* The input buffer is a vector, not a string. */
22920       value = vec_dup (i->buffer);
22921       vec_delete (value, i->index, 0);
22922       /* Almost certainly has a trailing newline */
22923       if (value[vec_len (value) - 1] == '\n')
22924         value[vec_len (value) - 1] = 0;
22925       /* Make sure it's a proper string, one way or the other */
22926       vec_add1 (value, 0);
22927       (void) clib_macro_set_value (&vam->macro_main,
22928                                    (char *) name, (char *) value);
22929     }
22930   else
22931     errmsg ("usage: set <name> <value>");
22932
22933   vec_free (name);
22934   vec_free (value);
22935   return 0;
22936 }
22937
22938 static int
22939 unset (vat_main_t * vam)
22940 {
22941   u8 *name = 0;
22942
22943   if (unformat (vam->input, "%s", &name))
22944     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22945       errmsg ("unset: %s wasn't set", name);
22946   vec_free (name);
22947   return 0;
22948 }
22949
22950 typedef struct
22951 {
22952   u8 *name;
22953   u8 *value;
22954 } macro_sort_t;
22955
22956
22957 static int
22958 macro_sort_cmp (void *a1, void *a2)
22959 {
22960   macro_sort_t *s1 = a1;
22961   macro_sort_t *s2 = a2;
22962
22963   return strcmp ((char *) (s1->name), (char *) (s2->name));
22964 }
22965
22966 static int
22967 dump_macro_table (vat_main_t * vam)
22968 {
22969   macro_sort_t *sort_me = 0, *sm;
22970   int i;
22971   hash_pair_t *p;
22972
22973     /* *INDENT-OFF* */
22974     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22975     ({
22976       vec_add2 (sort_me, sm, 1);
22977       sm->name = (u8 *)(p->key);
22978       sm->value = (u8 *) (p->value[0]);
22979     }));
22980     /* *INDENT-ON* */
22981
22982   vec_sort_with_function (sort_me, macro_sort_cmp);
22983
22984   if (vec_len (sort_me))
22985     print (vam->ofp, "%-15s%s", "Name", "Value");
22986   else
22987     print (vam->ofp, "The macro table is empty...");
22988
22989   for (i = 0; i < vec_len (sort_me); i++)
22990     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22991   return 0;
22992 }
22993
22994 static int
22995 dump_node_table (vat_main_t * vam)
22996 {
22997   int i, j;
22998   vlib_node_t *node, *next_node;
22999
23000   if (vec_len (vam->graph_nodes) == 0)
23001     {
23002       print (vam->ofp, "Node table empty, issue get_node_graph...");
23003       return 0;
23004     }
23005
23006   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23007     {
23008       node = vam->graph_nodes[i];
23009       print (vam->ofp, "[%d] %s", i, node->name);
23010       for (j = 0; j < vec_len (node->next_nodes); j++)
23011         {
23012           if (node->next_nodes[j] != ~0)
23013             {
23014               next_node = vam->graph_nodes[node->next_nodes[j]];
23015               print (vam->ofp, "  [%d] %s", j, next_node->name);
23016             }
23017         }
23018     }
23019   return 0;
23020 }
23021
23022 static int
23023 value_sort_cmp (void *a1, void *a2)
23024 {
23025   name_sort_t *n1 = a1;
23026   name_sort_t *n2 = a2;
23027
23028   if (n1->value < n2->value)
23029     return -1;
23030   if (n1->value > n2->value)
23031     return 1;
23032   return 0;
23033 }
23034
23035
23036 static int
23037 dump_msg_api_table (vat_main_t * vam)
23038 {
23039   api_main_t *am = &api_main;
23040   name_sort_t *nses = 0, *ns;
23041   hash_pair_t *hp;
23042   int i;
23043
23044   /* *INDENT-OFF* */
23045   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23046   ({
23047     vec_add2 (nses, ns, 1);
23048     ns->name = (u8 *)(hp->key);
23049     ns->value = (u32) hp->value[0];
23050   }));
23051   /* *INDENT-ON* */
23052
23053   vec_sort_with_function (nses, value_sort_cmp);
23054
23055   for (i = 0; i < vec_len (nses); i++)
23056     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23057   vec_free (nses);
23058   return 0;
23059 }
23060
23061 static int
23062 get_msg_id (vat_main_t * vam)
23063 {
23064   u8 *name_and_crc;
23065   u32 message_index;
23066
23067   if (unformat (vam->input, "%s", &name_and_crc))
23068     {
23069       message_index = vl_msg_api_get_msg_index (name_and_crc);
23070       if (message_index == ~0)
23071         {
23072           print (vam->ofp, " '%s' not found", name_and_crc);
23073           return 0;
23074         }
23075       print (vam->ofp, " '%s' has message index %d",
23076              name_and_crc, message_index);
23077       return 0;
23078     }
23079   errmsg ("name_and_crc required...");
23080   return 0;
23081 }
23082
23083 static int
23084 search_node_table (vat_main_t * vam)
23085 {
23086   unformat_input_t *line_input = vam->input;
23087   u8 *node_to_find;
23088   int j;
23089   vlib_node_t *node, *next_node;
23090   uword *p;
23091
23092   if (vam->graph_node_index_by_name == 0)
23093     {
23094       print (vam->ofp, "Node table empty, issue get_node_graph...");
23095       return 0;
23096     }
23097
23098   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23099     {
23100       if (unformat (line_input, "%s", &node_to_find))
23101         {
23102           vec_add1 (node_to_find, 0);
23103           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23104           if (p == 0)
23105             {
23106               print (vam->ofp, "%s not found...", node_to_find);
23107               goto out;
23108             }
23109           node = vam->graph_nodes[p[0]];
23110           print (vam->ofp, "[%d] %s", p[0], node->name);
23111           for (j = 0; j < vec_len (node->next_nodes); j++)
23112             {
23113               if (node->next_nodes[j] != ~0)
23114                 {
23115                   next_node = vam->graph_nodes[node->next_nodes[j]];
23116                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23117                 }
23118             }
23119         }
23120
23121       else
23122         {
23123           clib_warning ("parse error '%U'", format_unformat_error,
23124                         line_input);
23125           return -99;
23126         }
23127
23128     out:
23129       vec_free (node_to_find);
23130
23131     }
23132
23133   return 0;
23134 }
23135
23136
23137 static int
23138 script (vat_main_t * vam)
23139 {
23140 #if (VPP_API_TEST_BUILTIN==0)
23141   u8 *s = 0;
23142   char *save_current_file;
23143   unformat_input_t save_input;
23144   jmp_buf save_jump_buf;
23145   u32 save_line_number;
23146
23147   FILE *new_fp, *save_ifp;
23148
23149   if (unformat (vam->input, "%s", &s))
23150     {
23151       new_fp = fopen ((char *) s, "r");
23152       if (new_fp == 0)
23153         {
23154           errmsg ("Couldn't open script file %s", s);
23155           vec_free (s);
23156           return -99;
23157         }
23158     }
23159   else
23160     {
23161       errmsg ("Missing script name");
23162       return -99;
23163     }
23164
23165   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23166   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23167   save_ifp = vam->ifp;
23168   save_line_number = vam->input_line_number;
23169   save_current_file = (char *) vam->current_file;
23170
23171   vam->input_line_number = 0;
23172   vam->ifp = new_fp;
23173   vam->current_file = s;
23174   do_one_file (vam);
23175
23176   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23177   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23178   vam->ifp = save_ifp;
23179   vam->input_line_number = save_line_number;
23180   vam->current_file = (u8 *) save_current_file;
23181   vec_free (s);
23182
23183   return 0;
23184 #else
23185   clib_warning ("use the exec command...");
23186   return -99;
23187 #endif
23188 }
23189
23190 static int
23191 echo (vat_main_t * vam)
23192 {
23193   print (vam->ofp, "%v", vam->input->buffer);
23194   return 0;
23195 }
23196
23197 /* List of API message constructors, CLI names map to api_xxx */
23198 #define foreach_vpe_api_msg                                             \
23199 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23200 _(sw_interface_dump,"")                                                 \
23201 _(sw_interface_set_flags,                                               \
23202   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23203 _(sw_interface_add_del_address,                                         \
23204   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23205 _(sw_interface_set_rx_mode,                                             \
23206   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23207 _(sw_interface_set_table,                                               \
23208   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23209 _(sw_interface_set_mpls_enable,                                         \
23210   "<intfc> | sw_if_index [disable | dis]")                              \
23211 _(sw_interface_set_vpath,                                               \
23212   "<intfc> | sw_if_index <id> enable | disable")                        \
23213 _(sw_interface_set_vxlan_bypass,                                        \
23214   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23215 _(sw_interface_set_geneve_bypass,                                       \
23216   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23217 _(sw_interface_set_l2_xconnect,                                         \
23218   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23219   "enable | disable")                                                   \
23220 _(sw_interface_set_l2_bridge,                                           \
23221   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23222   "[shg <split-horizon-group>] [bvi]\n"                                 \
23223   "enable | disable")                                                   \
23224 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23225 _(bridge_domain_add_del,                                                \
23226   "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") \
23227 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23228 _(l2fib_add_del,                                                        \
23229   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23230 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23231 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23232 _(l2_flags,                                                             \
23233   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23234 _(bridge_flags,                                                         \
23235   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23236 _(tap_connect,                                                          \
23237   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23238 _(tap_modify,                                                           \
23239   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23240 _(tap_delete,                                                           \
23241   "<vpp-if-name> | sw_if_index <id>")                                   \
23242 _(sw_interface_tap_dump, "")                                            \
23243 _(tap_create_v2,                                                        \
23244   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23245 _(tap_delete_v2,                                                        \
23246   "<vpp-if-name> | sw_if_index <id>")                                   \
23247 _(sw_interface_tap_v2_dump, "")                                         \
23248 _(bond_create,                                                          \
23249   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23250   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23251 _(bond_delete,                                                          \
23252   "<vpp-if-name> | sw_if_index <id>")                                   \
23253 _(bond_enslave,                                                         \
23254   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23255 _(bond_detach_slave,                                                    \
23256   "sw_if_index <n>")                                                    \
23257 _(sw_interface_bond_dump, "")                                           \
23258 _(sw_interface_slave_dump,                                              \
23259   "<vpp-if-name> | sw_if_index <id>")                                   \
23260 _(ip_table_add_del,                                                     \
23261   "table-id <n> [ipv6]\n")                                              \
23262 _(ip_add_del_route,                                                     \
23263   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23264   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23265   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23266   "[multipath] [count <n>]")                                            \
23267 _(ip_mroute_add_del,                                                    \
23268   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23269   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23270 _(mpls_table_add_del,                                                   \
23271   "table-id <n>\n")                                                     \
23272 _(mpls_route_add_del,                                                   \
23273   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23274   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23275   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23276   "[multipath] [count <n>]")                                            \
23277 _(mpls_ip_bind_unbind,                                                  \
23278   "<label> <addr/len>")                                                 \
23279 _(mpls_tunnel_add_del,                                                  \
23280   " via <addr> [table-id <n>]\n"                                        \
23281   "sw_if_index <id>] [l2]  [del]")                                      \
23282 _(bier_table_add_del,                                                   \
23283   "<label> <sub-domain> <set> <bsl> [del]")                             \
23284 _(bier_route_add_del,                                                   \
23285   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23286   "[<intfc> | sw_if_index <id>]"                                        \
23287   "[weight <n>] [del] [multipath]")                                     \
23288 _(proxy_arp_add_del,                                                    \
23289   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23290 _(proxy_arp_intfc_enable_disable,                                       \
23291   "<intfc> | sw_if_index <id> enable | disable")                        \
23292 _(sw_interface_set_unnumbered,                                          \
23293   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23294 _(ip_neighbor_add_del,                                                  \
23295   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23296   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23297 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23298 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23299   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23300   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23301   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23302 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23303 _(reset_fib, "vrf <n> [ipv6]")                                          \
23304 _(dhcp_proxy_config,                                                    \
23305   "svr <v46-address> src <v46-address>\n"                               \
23306    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23307 _(dhcp_proxy_set_vss,                                                   \
23308   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23309 _(dhcp_proxy_dump, "ip6")                                               \
23310 _(dhcp_client_config,                                                   \
23311   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23312 _(set_ip_flow_hash,                                                     \
23313   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23314 _(sw_interface_ip6_enable_disable,                                      \
23315   "<intfc> | sw_if_index <id> enable | disable")                        \
23316 _(sw_interface_ip6_set_link_local_address,                              \
23317   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23318 _(ip6nd_proxy_add_del,                                                  \
23319   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23320 _(ip6nd_proxy_dump, "")                                                 \
23321 _(sw_interface_ip6nd_ra_prefix,                                         \
23322   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23323   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23324   "[nolink] [isno]")                                                    \
23325 _(sw_interface_ip6nd_ra_config,                                         \
23326   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23327   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23328   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23329 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23330 _(l2_patch_add_del,                                                     \
23331   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23332   "enable | disable")                                                   \
23333 _(sr_localsid_add_del,                                                  \
23334   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23335   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23336 _(classify_add_del_table,                                               \
23337   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23338   " [del] [del-chain] mask <mask-value>\n"                              \
23339   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23340   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23341 _(classify_add_del_session,                                             \
23342   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23343   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23344   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23345   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23346 _(classify_set_interface_ip_table,                                      \
23347   "<intfc> | sw_if_index <nn> table <nn>")                              \
23348 _(classify_set_interface_l2_tables,                                     \
23349   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23350   "  [other-table <nn>]")                                               \
23351 _(get_node_index, "node <node-name")                                    \
23352 _(add_node_next, "node <node-name> next <next-node-name>")              \
23353 _(l2tpv3_create_tunnel,                                                 \
23354   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23355   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23356   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23357 _(l2tpv3_set_tunnel_cookies,                                            \
23358   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23359   "[new_remote_cookie <nn>]\n")                                         \
23360 _(l2tpv3_interface_enable_disable,                                      \
23361   "<intfc> | sw_if_index <nn> enable | disable")                        \
23362 _(l2tpv3_set_lookup_key,                                                \
23363   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23364 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23365 _(vxlan_add_del_tunnel,                                                 \
23366   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23367   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23368   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23369 _(geneve_add_del_tunnel,                                                \
23370   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23371   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23372   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23373 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23374 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23375 _(gre_add_del_tunnel,                                                   \
23376   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23377   "[teb | erspan <session-id>] [del]")                                  \
23378 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23379 _(l2_fib_clear_table, "")                                               \
23380 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23381 _(l2_interface_vlan_tag_rewrite,                                        \
23382   "<intfc> | sw_if_index <nn> \n"                                       \
23383   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23384   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23385 _(create_vhost_user_if,                                                 \
23386         "socket <filename> [server] [renumber <dev_instance>] "         \
23387         "[mac <mac_address>]")                                          \
23388 _(modify_vhost_user_if,                                                 \
23389         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23390         "[server] [renumber <dev_instance>]")                           \
23391 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23392 _(sw_interface_vhost_user_dump, "")                                     \
23393 _(show_version, "")                                                     \
23394 _(vxlan_gpe_add_del_tunnel,                                             \
23395   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23396   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23397   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23398   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23399 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23400 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23401 _(interface_name_renumber,                                              \
23402   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23403 _(input_acl_set_interface,                                              \
23404   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23405   "  [l2-table <nn>] [del]")                                            \
23406 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23407 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23408 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23409 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23410 _(ip_dump, "ipv4 | ipv6")                                               \
23411 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23412 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23413   "  spid_id <n> ")                                                     \
23414 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23415   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23416   "  integ_alg <alg> integ_key <hex>")                                  \
23417 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23418   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23419   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23420   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23421 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23422 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23423   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23424   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23425   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
23426 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23427 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23428   "  <alg> <hex>\n")                                                    \
23429 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23430 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23431 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23432   "(auth_data 0x<data> | auth_data <data>)")                            \
23433 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23434   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23435 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23436   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23437   "(local|remote)")                                                     \
23438 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23439 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23440 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23441 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23442 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23443 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23444 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23445 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23446 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23447 _(delete_loopback,"sw_if_index <nn>")                                   \
23448 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23449 _(map_add_domain,                                                       \
23450   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23451   "ip6-src <ip6addr> "                                                  \
23452   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23453 _(map_del_domain, "index <n>")                                          \
23454 _(map_add_del_rule,                                                     \
23455   "index <n> psid <n> dst <ip6addr> [del]")                             \
23456 _(map_domain_dump, "")                                                  \
23457 _(map_rule_dump, "index <map-domain>")                                  \
23458 _(want_interface_events,  "enable|disable")                             \
23459 _(want_stats,"enable|disable")                                          \
23460 _(get_first_msg_id, "client <name>")                                    \
23461 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23462 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23463   "fib-id <nn> [ip4][ip6][default]")                                    \
23464 _(get_node_graph, " ")                                                  \
23465 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23466 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23467 _(ioam_disable, "")                                                     \
23468 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23469                             " sw_if_index <sw_if_index> p <priority> "  \
23470                             "w <weight>] [del]")                        \
23471 _(one_add_del_locator, "locator-set <locator_name> "                    \
23472                         "iface <intf> | sw_if_index <sw_if_index> "     \
23473                         "p <priority> w <weight> [del]")                \
23474 _(one_add_del_local_eid,"vni <vni> eid "                                \
23475                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23476                          "locator-set <locator_name> [del]"             \
23477                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23478 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23479 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23480 _(one_enable_disable, "enable|disable")                                 \
23481 _(one_map_register_enable_disable, "enable|disable")                    \
23482 _(one_map_register_fallback_threshold, "<value>")                       \
23483 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23484 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23485                                "[seid <seid>] "                         \
23486                                "rloc <locator> p <prio> "               \
23487                                "w <weight> [rloc <loc> ... ] "          \
23488                                "action <action> [del-all]")             \
23489 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23490                           "<local-eid>")                                \
23491 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23492 _(one_use_petr, "ip-address> | disable")                                \
23493 _(one_map_request_mode, "src-dst|dst-only")                             \
23494 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23495 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23496 _(one_locator_set_dump, "[local | remote]")                             \
23497 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23498 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23499                        "[local] | [remote]")                            \
23500 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23501 _(one_ndp_bd_get, "")                                                   \
23502 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23503 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23504 _(one_l2_arp_bd_get, "")                                                \
23505 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23506 _(one_stats_enable_disable, "enable|disalbe")                           \
23507 _(show_one_stats_enable_disable, "")                                    \
23508 _(one_eid_table_vni_dump, "")                                           \
23509 _(one_eid_table_map_dump, "l2|l3")                                      \
23510 _(one_map_resolver_dump, "")                                            \
23511 _(one_map_server_dump, "")                                              \
23512 _(one_adjacencies_get, "vni <vni>")                                     \
23513 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23514 _(show_one_rloc_probe_state, "")                                        \
23515 _(show_one_map_register_state, "")                                      \
23516 _(show_one_status, "")                                                  \
23517 _(one_stats_dump, "")                                                   \
23518 _(one_stats_flush, "")                                                  \
23519 _(one_get_map_request_itr_rlocs, "")                                    \
23520 _(one_map_register_set_ttl, "<ttl>")                                    \
23521 _(one_set_transport_protocol, "udp|api")                                \
23522 _(one_get_transport_protocol, "")                                       \
23523 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23524 _(one_show_xtr_mode, "")                                                \
23525 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23526 _(one_show_pitr_mode, "")                                               \
23527 _(one_enable_disable_petr_mode, "enable|disable")                       \
23528 _(one_show_petr_mode, "")                                               \
23529 _(show_one_nsh_mapping, "")                                             \
23530 _(show_one_pitr, "")                                                    \
23531 _(show_one_use_petr, "")                                                \
23532 _(show_one_map_request_mode, "")                                        \
23533 _(show_one_map_register_ttl, "")                                        \
23534 _(show_one_map_register_fallback_threshold, "")                         \
23535 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23536                             " sw_if_index <sw_if_index> p <priority> "  \
23537                             "w <weight>] [del]")                        \
23538 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23539                         "iface <intf> | sw_if_index <sw_if_index> "     \
23540                         "p <priority> w <weight> [del]")                \
23541 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23542                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23543                          "locator-set <locator_name> [del]"             \
23544                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23545 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23546 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23547 _(lisp_enable_disable, "enable|disable")                                \
23548 _(lisp_map_register_enable_disable, "enable|disable")                   \
23549 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23550 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23551                                "[seid <seid>] "                         \
23552                                "rloc <locator> p <prio> "               \
23553                                "w <weight> [rloc <loc> ... ] "          \
23554                                "action <action> [del-all]")             \
23555 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23556                           "<local-eid>")                                \
23557 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23558 _(lisp_use_petr, "<ip-address> | disable")                              \
23559 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23560 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23561 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23562 _(lisp_locator_set_dump, "[local | remote]")                            \
23563 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23564 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23565                        "[local] | [remote]")                            \
23566 _(lisp_eid_table_vni_dump, "")                                          \
23567 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23568 _(lisp_map_resolver_dump, "")                                           \
23569 _(lisp_map_server_dump, "")                                             \
23570 _(lisp_adjacencies_get, "vni <vni>")                                    \
23571 _(gpe_fwd_entry_vnis_get, "")                                           \
23572 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23573 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23574                                 "[table <table-id>]")                   \
23575 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23576 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23577 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23578 _(gpe_get_encap_mode, "")                                               \
23579 _(lisp_gpe_add_del_iface, "up|down")                                    \
23580 _(lisp_gpe_enable_disable, "enable|disable")                            \
23581 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23582   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23583 _(show_lisp_rloc_probe_state, "")                                       \
23584 _(show_lisp_map_register_state, "")                                     \
23585 _(show_lisp_status, "")                                                 \
23586 _(lisp_get_map_request_itr_rlocs, "")                                   \
23587 _(show_lisp_pitr, "")                                                   \
23588 _(show_lisp_use_petr, "")                                               \
23589 _(show_lisp_map_request_mode, "")                                       \
23590 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23591 _(af_packet_delete, "name <host interface name>")                       \
23592 _(policer_add_del, "name <policer name> <params> [del]")                \
23593 _(policer_dump, "[name <policer name>]")                                \
23594 _(policer_classify_set_interface,                                       \
23595   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23596   "  [l2-table <nn>] [del]")                                            \
23597 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23598 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23599     "[master|slave]")                                                   \
23600 _(netmap_delete, "name <interface name>")                               \
23601 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23602 _(mpls_fib_dump, "")                                                    \
23603 _(classify_table_ids, "")                                               \
23604 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23605 _(classify_table_info, "table_id <nn>")                                 \
23606 _(classify_session_dump, "table_id <nn>")                               \
23607 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23608     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23609     "[template_interval <nn>] [udp_checksum]")                          \
23610 _(ipfix_exporter_dump, "")                                              \
23611 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23612 _(ipfix_classify_stream_dump, "")                                       \
23613 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23614 _(ipfix_classify_table_dump, "")                                        \
23615 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23616 _(sw_interface_span_dump, "[l2]")                                           \
23617 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23618 _(pg_create_interface, "if_id <nn>")                                    \
23619 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23620 _(pg_enable_disable, "[stream <id>] disable")                           \
23621 _(ip_source_and_port_range_check_add_del,                               \
23622   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23623 _(ip_source_and_port_range_check_interface_add_del,                     \
23624   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23625   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23626 _(ipsec_gre_add_del_tunnel,                                             \
23627   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23628 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23629 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23630 _(l2_interface_pbb_tag_rewrite,                                         \
23631   "<intfc> | sw_if_index <nn> \n"                                       \
23632   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23633   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23634 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23635 _(flow_classify_set_interface,                                          \
23636   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23637 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23638 _(ip_fib_dump, "")                                                      \
23639 _(ip_mfib_dump, "")                                                     \
23640 _(ip6_fib_dump, "")                                                     \
23641 _(ip6_mfib_dump, "")                                                    \
23642 _(feature_enable_disable, "arc_name <arc_name> "                        \
23643   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23644 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23645 "[disable]")                                                            \
23646 _(l2_xconnect_dump, "")                                                 \
23647 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23648 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23649 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23650 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23651 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23652 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23653 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23654   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23655 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23656 _(memfd_segment_create,"size <nnn>")                                    \
23657 _(sock_init_shm, "size <nnn>")                                          \
23658 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23659 _(dns_enable_disable, "[enable][disable]")                              \
23660 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23661 _(dns_resolve_name, "<hostname>")                                       \
23662 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23663 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23664 _(dns_resolve_name, "<hostname>")                                       \
23665 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23666   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23667 _(session_rules_dump, "")                                               \
23668 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23669 _(output_acl_set_interface,                                             \
23670   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23671   "  [l2-table <nn>] [del]")                                            \
23672
23673 /* List of command functions, CLI names map directly to functions */
23674 #define foreach_cli_function                                    \
23675 _(comment, "usage: comment <ignore-rest-of-line>")              \
23676 _(dump_interface_table, "usage: dump_interface_table")          \
23677 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23678 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23679 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23680 _(dump_stats_table, "usage: dump_stats_table")                  \
23681 _(dump_macro_table, "usage: dump_macro_table ")                 \
23682 _(dump_node_table, "usage: dump_node_table")                    \
23683 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23684 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23685 _(echo, "usage: echo <message>")                                \
23686 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23687 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23688 _(help, "usage: help")                                          \
23689 _(q, "usage: quit")                                             \
23690 _(quit, "usage: quit")                                          \
23691 _(search_node_table, "usage: search_node_table <name>...")      \
23692 _(set, "usage: set <variable-name> <value>")                    \
23693 _(script, "usage: script <file-name>")                          \
23694 _(unset, "usage: unset <variable-name>")
23695 #define _(N,n)                                  \
23696     static void vl_api_##n##_t_handler_uni      \
23697     (vl_api_##n##_t * mp)                       \
23698     {                                           \
23699         vat_main_t * vam = &vat_main;           \
23700         if (vam->json_output) {                 \
23701             vl_api_##n##_t_handler_json(mp);    \
23702         } else {                                \
23703             vl_api_##n##_t_handler(mp);         \
23704         }                                       \
23705     }
23706 foreach_vpe_api_reply_msg;
23707 #if VPP_API_TEST_BUILTIN == 0
23708 foreach_standalone_reply_msg;
23709 #endif
23710 #undef _
23711
23712 void
23713 vat_api_hookup (vat_main_t * vam)
23714 {
23715 #define _(N,n)                                                  \
23716     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23717                            vl_api_##n##_t_handler_uni,          \
23718                            vl_noop_handler,                     \
23719                            vl_api_##n##_t_endian,               \
23720                            vl_api_##n##_t_print,                \
23721                            sizeof(vl_api_##n##_t), 1);
23722   foreach_vpe_api_reply_msg;
23723 #if VPP_API_TEST_BUILTIN == 0
23724   foreach_standalone_reply_msg;
23725 #endif
23726 #undef _
23727
23728 #if (VPP_API_TEST_BUILTIN==0)
23729   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23730
23731   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23732
23733   vam->function_by_name = hash_create_string (0, sizeof (uword));
23734
23735   vam->help_by_name = hash_create_string (0, sizeof (uword));
23736 #endif
23737
23738   /* API messages we can send */
23739 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23740   foreach_vpe_api_msg;
23741 #undef _
23742
23743   /* Help strings */
23744 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23745   foreach_vpe_api_msg;
23746 #undef _
23747
23748   /* CLI functions */
23749 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23750   foreach_cli_function;
23751 #undef _
23752
23753   /* Help strings */
23754 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23755   foreach_cli_function;
23756 #undef _
23757 }
23758
23759 #if VPP_API_TEST_BUILTIN
23760 static clib_error_t *
23761 vat_api_hookup_shim (vlib_main_t * vm)
23762 {
23763   vat_api_hookup (&vat_main);
23764   return 0;
23765 }
23766
23767 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23768 #endif
23769
23770 /*
23771  * fd.io coding-style-patch-verification: ON
23772  *
23773  * Local Variables:
23774  * eval: (c-set-style "gnu")
23775  * End:
23776  */