Allow an IPsec tunnel interface to be renumbered
[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 _(ip_probe_neighbor_reply)                              \
5573 _(want_ip4_arp_events_reply)                            \
5574 _(want_ip6_nd_events_reply)                             \
5575 _(want_l2_macs_events_reply)                            \
5576 _(input_acl_set_interface_reply)                        \
5577 _(ipsec_spd_add_del_reply)                              \
5578 _(ipsec_interface_add_del_spd_reply)                    \
5579 _(ipsec_spd_add_del_entry_reply)                        \
5580 _(ipsec_sad_add_del_entry_reply)                        \
5581 _(ipsec_sa_set_key_reply)                               \
5582 _(ipsec_tunnel_if_add_del_reply)                        \
5583 _(ipsec_tunnel_if_set_key_reply)                        \
5584 _(ipsec_tunnel_if_set_sa_reply)                         \
5585 _(ikev2_profile_add_del_reply)                          \
5586 _(ikev2_profile_set_auth_reply)                         \
5587 _(ikev2_profile_set_id_reply)                           \
5588 _(ikev2_profile_set_ts_reply)                           \
5589 _(ikev2_set_local_key_reply)                            \
5590 _(ikev2_set_responder_reply)                            \
5591 _(ikev2_set_ike_transforms_reply)                       \
5592 _(ikev2_set_esp_transforms_reply)                       \
5593 _(ikev2_set_sa_lifetime_reply)                          \
5594 _(ikev2_initiate_sa_init_reply)                         \
5595 _(ikev2_initiate_del_ike_sa_reply)                      \
5596 _(ikev2_initiate_del_child_sa_reply)                    \
5597 _(ikev2_initiate_rekey_child_sa_reply)                  \
5598 _(delete_loopback_reply)                                \
5599 _(bd_ip_mac_add_del_reply)                              \
5600 _(map_del_domain_reply)                                 \
5601 _(map_add_del_rule_reply)                               \
5602 _(want_interface_events_reply)                          \
5603 _(want_stats_reply)                                     \
5604 _(cop_interface_enable_disable_reply)                   \
5605 _(cop_whitelist_enable_disable_reply)                   \
5606 _(sw_interface_clear_stats_reply)                       \
5607 _(ioam_enable_reply)                                    \
5608 _(ioam_disable_reply)                                   \
5609 _(one_add_del_locator_reply)                            \
5610 _(one_add_del_local_eid_reply)                          \
5611 _(one_add_del_remote_mapping_reply)                     \
5612 _(one_add_del_adjacency_reply)                          \
5613 _(one_add_del_map_resolver_reply)                       \
5614 _(one_add_del_map_server_reply)                         \
5615 _(one_enable_disable_reply)                             \
5616 _(one_rloc_probe_enable_disable_reply)                  \
5617 _(one_map_register_enable_disable_reply)                \
5618 _(one_map_register_set_ttl_reply)                       \
5619 _(one_set_transport_protocol_reply)                     \
5620 _(one_map_register_fallback_threshold_reply)            \
5621 _(one_pitr_set_locator_set_reply)                       \
5622 _(one_map_request_mode_reply)                           \
5623 _(one_add_del_map_request_itr_rlocs_reply)              \
5624 _(one_eid_table_add_del_map_reply)                      \
5625 _(one_use_petr_reply)                                   \
5626 _(one_stats_enable_disable_reply)                       \
5627 _(one_add_del_l2_arp_entry_reply)                       \
5628 _(one_add_del_ndp_entry_reply)                          \
5629 _(one_stats_flush_reply)                                \
5630 _(one_enable_disable_xtr_mode_reply)                    \
5631 _(one_enable_disable_pitr_mode_reply)                   \
5632 _(one_enable_disable_petr_mode_reply)                   \
5633 _(gpe_enable_disable_reply)                             \
5634 _(gpe_set_encap_mode_reply)                             \
5635 _(gpe_add_del_iface_reply)                              \
5636 _(gpe_add_del_native_fwd_rpath_reply)                   \
5637 _(af_packet_delete_reply)                               \
5638 _(policer_classify_set_interface_reply)                 \
5639 _(netmap_create_reply)                                  \
5640 _(netmap_delete_reply)                                  \
5641 _(set_ipfix_exporter_reply)                             \
5642 _(set_ipfix_classify_stream_reply)                      \
5643 _(ipfix_classify_table_add_del_reply)                   \
5644 _(flow_classify_set_interface_reply)                    \
5645 _(sw_interface_span_enable_disable_reply)               \
5646 _(pg_capture_reply)                                     \
5647 _(pg_enable_disable_reply)                              \
5648 _(ip_source_and_port_range_check_add_del_reply)         \
5649 _(ip_source_and_port_range_check_interface_add_del_reply)\
5650 _(delete_subif_reply)                                   \
5651 _(l2_interface_pbb_tag_rewrite_reply)                   \
5652 _(punt_reply)                                           \
5653 _(feature_enable_disable_reply)                         \
5654 _(sw_interface_tag_add_del_reply)                       \
5655 _(sw_interface_set_mtu_reply)                           \
5656 _(p2p_ethernet_add_reply)                               \
5657 _(p2p_ethernet_del_reply)                               \
5658 _(lldp_config_reply)                                    \
5659 _(sw_interface_set_lldp_reply)                          \
5660 _(tcp_configure_src_addresses_reply)                    \
5661 _(dns_enable_disable_reply)                             \
5662 _(dns_name_server_add_del_reply)                        \
5663 _(session_rule_add_del_reply)                           \
5664 _(ip_container_proxy_add_del_reply)                     \
5665 _(output_acl_set_interface_reply)
5666
5667 #define _(n)                                    \
5668     static void vl_api_##n##_t_handler          \
5669     (vl_api_##n##_t * mp)                       \
5670     {                                           \
5671         vat_main_t * vam = &vat_main;           \
5672         i32 retval = ntohl(mp->retval);         \
5673         if (vam->async_mode) {                  \
5674             vam->async_errors += (retval < 0);  \
5675         } else {                                \
5676             vam->retval = retval;               \
5677             vam->result_ready = 1;              \
5678         }                                       \
5679     }
5680 foreach_standard_reply_retval_handler;
5681 #undef _
5682
5683 #define _(n)                                    \
5684     static void vl_api_##n##_t_handler_json     \
5685     (vl_api_##n##_t * mp)                       \
5686     {                                           \
5687         vat_main_t * vam = &vat_main;           \
5688         vat_json_node_t node;                   \
5689         vat_json_init_object(&node);            \
5690         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5691         vat_json_print(vam->ofp, &node);        \
5692         vam->retval = ntohl(mp->retval);        \
5693         vam->result_ready = 1;                  \
5694     }
5695 foreach_standard_reply_retval_handler;
5696 #undef _
5697
5698 /*
5699  * Table of message reply handlers, must include boilerplate handlers
5700  * we just generated
5701  */
5702
5703 #define foreach_vpe_api_reply_msg                                       \
5704 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5705 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5706 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5707 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5708 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5709 _(CLI_REPLY, cli_reply)                                                 \
5710 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5711 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5712   sw_interface_add_del_address_reply)                                   \
5713 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5714 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5715 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5716 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5717 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5718 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5719 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5720 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5721   sw_interface_set_l2_xconnect_reply)                                   \
5722 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5723   sw_interface_set_l2_bridge_reply)                                     \
5724 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5725 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5726 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5727 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5728 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5729 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5730 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5731 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5732 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5733 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5734 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5735 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5736 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5737 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5738 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5739 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5740 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5741 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5742 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5743 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5744 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5745 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5746 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5747 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5748 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5749 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5750 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5751 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5752 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5753 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5754 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5755   proxy_arp_intfc_enable_disable_reply)                                 \
5756 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5757 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5758   sw_interface_set_unnumbered_reply)                                    \
5759 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5760 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5761 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5762 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5763 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5764 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5765 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5766 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5767 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5768 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5769 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5770   sw_interface_ip6_enable_disable_reply)                                \
5771 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5772   sw_interface_ip6_set_link_local_address_reply)                        \
5773 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5774 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5775 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5776   sw_interface_ip6nd_ra_prefix_reply)                                   \
5777 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5778   sw_interface_ip6nd_ra_config_reply)                                   \
5779 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5780 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5781 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5782 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5783 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5784 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5785 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5786 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5787 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5788 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5789 classify_set_interface_ip_table_reply)                                  \
5790 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5791   classify_set_interface_l2_tables_reply)                               \
5792 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5793 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5794 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5795 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5796 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5797   l2tpv3_interface_enable_disable_reply)                                \
5798 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5799 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5800 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5801 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5802 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5803 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5804 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5805 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5806 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5807 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5808 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5809 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5810 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5811 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5812 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5813 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5814 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5815 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5816 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5817 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5818 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5819 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5820 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5821 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5822 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5823 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5824 _(L2_MACS_EVENT, l2_macs_event)                                         \
5825 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5826 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5827 _(IP_DETAILS, ip_details)                                               \
5828 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5829 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5830 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5831 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5832 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5833 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5834 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5835 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5836 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5837 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5838 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5839 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5840 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5841 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5842 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5843 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5844 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5845 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5846 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5847 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5848 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5849 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5850 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5851 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5852 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5853 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5854 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5855 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5856 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5857 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5858 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5859 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5860 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5861 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5862 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5863 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5864 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5865 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5866 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5867 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5868 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5869 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5870 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5871 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5872 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5873 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5874 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5875 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5876   one_map_register_enable_disable_reply)                                \
5877 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5878 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5879 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5880 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5881   one_map_register_fallback_threshold_reply)                            \
5882 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5883   one_rloc_probe_enable_disable_reply)                                  \
5884 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5885 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5886 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5887 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5888 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5889 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5890 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5891 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5892 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5893 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5894 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5895 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5896 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5897 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5898 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5899 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5900   show_one_stats_enable_disable_reply)                                  \
5901 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5902 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5903 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5904 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5905 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5906 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5907 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5908 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5909   one_enable_disable_pitr_mode_reply)                                   \
5910 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5911   one_enable_disable_petr_mode_reply)                                   \
5912 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5913 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5914 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5915 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5916 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5917 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5918 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5919 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5920 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5921 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5922 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5923 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5924   gpe_add_del_native_fwd_rpath_reply)                                   \
5925 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5926   gpe_fwd_entry_path_details)                                           \
5927 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5928 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5929   one_add_del_map_request_itr_rlocs_reply)                              \
5930 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5931   one_get_map_request_itr_rlocs_reply)                                  \
5932 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5933 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5934 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5935 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5936 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5937 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5938   show_one_map_register_state_reply)                                    \
5939 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5940 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5941   show_one_map_register_fallback_threshold_reply)                       \
5942 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5943 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5944 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5945 _(POLICER_DETAILS, policer_details)                                     \
5946 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5947 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5948 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5949 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5950 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5951 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5952 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5953 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5954 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5955 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5956 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5957 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5958 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5959 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5960 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5961 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5962 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5963 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5964 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5965 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5966 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5967 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5968 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5969 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5970 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5971  ip_source_and_port_range_check_add_del_reply)                          \
5972 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5973  ip_source_and_port_range_check_interface_add_del_reply)                \
5974 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5975 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5976 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5977 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5978 _(PUNT_REPLY, punt_reply)                                               \
5979 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5980 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5981 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5982 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5983 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5984 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5985 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5986 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5987 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5988 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5989 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5990 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5991 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5992 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5993 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5994 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5995 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5996 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5997 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5998 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5999 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
6000 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
6001
6002 #define foreach_standalone_reply_msg                                    \
6003 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
6004 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
6005 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
6006 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
6007 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
6008 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
6009 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
6010 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
6011
6012 typedef struct
6013 {
6014   u8 *name;
6015   u32 value;
6016 } name_sort_t;
6017
6018
6019 #define STR_VTR_OP_CASE(op)     \
6020     case L2_VTR_ ## op:         \
6021         return "" # op;
6022
6023 static const char *
6024 str_vtr_op (u32 vtr_op)
6025 {
6026   switch (vtr_op)
6027     {
6028       STR_VTR_OP_CASE (DISABLED);
6029       STR_VTR_OP_CASE (PUSH_1);
6030       STR_VTR_OP_CASE (PUSH_2);
6031       STR_VTR_OP_CASE (POP_1);
6032       STR_VTR_OP_CASE (POP_2);
6033       STR_VTR_OP_CASE (TRANSLATE_1_1);
6034       STR_VTR_OP_CASE (TRANSLATE_1_2);
6035       STR_VTR_OP_CASE (TRANSLATE_2_1);
6036       STR_VTR_OP_CASE (TRANSLATE_2_2);
6037     }
6038
6039   return "UNKNOWN";
6040 }
6041
6042 static int
6043 dump_sub_interface_table (vat_main_t * vam)
6044 {
6045   const sw_interface_subif_t *sub = NULL;
6046
6047   if (vam->json_output)
6048     {
6049       clib_warning
6050         ("JSON output supported only for VPE API calls and dump_stats_table");
6051       return -99;
6052     }
6053
6054   print (vam->ofp,
6055          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
6056          "Interface", "sw_if_index",
6057          "sub id", "dot1ad", "tags", "outer id",
6058          "inner id", "exact", "default", "outer any", "inner any");
6059
6060   vec_foreach (sub, vam->sw_if_subif_table)
6061   {
6062     print (vam->ofp,
6063            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
6064            sub->interface_name,
6065            sub->sw_if_index,
6066            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
6067            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6068            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6069            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6070     if (sub->vtr_op != L2_VTR_DISABLED)
6071       {
6072         print (vam->ofp,
6073                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6074                "tag1: %d tag2: %d ]",
6075                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6076                sub->vtr_tag1, sub->vtr_tag2);
6077       }
6078   }
6079
6080   return 0;
6081 }
6082
6083 static int
6084 name_sort_cmp (void *a1, void *a2)
6085 {
6086   name_sort_t *n1 = a1;
6087   name_sort_t *n2 = a2;
6088
6089   return strcmp ((char *) n1->name, (char *) n2->name);
6090 }
6091
6092 static int
6093 dump_interface_table (vat_main_t * vam)
6094 {
6095   hash_pair_t *p;
6096   name_sort_t *nses = 0, *ns;
6097
6098   if (vam->json_output)
6099     {
6100       clib_warning
6101         ("JSON output supported only for VPE API calls and dump_stats_table");
6102       return -99;
6103     }
6104
6105   /* *INDENT-OFF* */
6106   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6107   ({
6108     vec_add2 (nses, ns, 1);
6109     ns->name = (u8 *)(p->key);
6110     ns->value = (u32) p->value[0];
6111   }));
6112   /* *INDENT-ON* */
6113
6114   vec_sort_with_function (nses, name_sort_cmp);
6115
6116   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6117   vec_foreach (ns, nses)
6118   {
6119     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6120   }
6121   vec_free (nses);
6122   return 0;
6123 }
6124
6125 static int
6126 dump_ip_table (vat_main_t * vam, int is_ipv6)
6127 {
6128   const ip_details_t *det = NULL;
6129   const ip_address_details_t *address = NULL;
6130   u32 i = ~0;
6131
6132   print (vam->ofp, "%-12s", "sw_if_index");
6133
6134   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6135   {
6136     i++;
6137     if (!det->present)
6138       {
6139         continue;
6140       }
6141     print (vam->ofp, "%-12d", i);
6142     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6143     if (!det->addr)
6144       {
6145         continue;
6146       }
6147     vec_foreach (address, det->addr)
6148     {
6149       print (vam->ofp,
6150              "            %-30U%-13d",
6151              is_ipv6 ? format_ip6_address : format_ip4_address,
6152              address->ip, address->prefix_length);
6153     }
6154   }
6155
6156   return 0;
6157 }
6158
6159 static int
6160 dump_ipv4_table (vat_main_t * vam)
6161 {
6162   if (vam->json_output)
6163     {
6164       clib_warning
6165         ("JSON output supported only for VPE API calls and dump_stats_table");
6166       return -99;
6167     }
6168
6169   return dump_ip_table (vam, 0);
6170 }
6171
6172 static int
6173 dump_ipv6_table (vat_main_t * vam)
6174 {
6175   if (vam->json_output)
6176     {
6177       clib_warning
6178         ("JSON output supported only for VPE API calls and dump_stats_table");
6179       return -99;
6180     }
6181
6182   return dump_ip_table (vam, 1);
6183 }
6184
6185 static char *
6186 counter_type_to_str (u8 counter_type, u8 is_combined)
6187 {
6188   if (!is_combined)
6189     {
6190       switch (counter_type)
6191         {
6192         case VNET_INTERFACE_COUNTER_DROP:
6193           return "drop";
6194         case VNET_INTERFACE_COUNTER_PUNT:
6195           return "punt";
6196         case VNET_INTERFACE_COUNTER_IP4:
6197           return "ip4";
6198         case VNET_INTERFACE_COUNTER_IP6:
6199           return "ip6";
6200         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6201           return "rx-no-buf";
6202         case VNET_INTERFACE_COUNTER_RX_MISS:
6203           return "rx-miss";
6204         case VNET_INTERFACE_COUNTER_RX_ERROR:
6205           return "rx-error";
6206         case VNET_INTERFACE_COUNTER_TX_ERROR:
6207           return "tx-error";
6208         default:
6209           return "INVALID-COUNTER-TYPE";
6210         }
6211     }
6212   else
6213     {
6214       switch (counter_type)
6215         {
6216         case VNET_INTERFACE_COUNTER_RX:
6217           return "rx";
6218         case VNET_INTERFACE_COUNTER_TX:
6219           return "tx";
6220         default:
6221           return "INVALID-COUNTER-TYPE";
6222         }
6223     }
6224 }
6225
6226 static int
6227 dump_stats_table (vat_main_t * vam)
6228 {
6229   vat_json_node_t node;
6230   vat_json_node_t *msg_array;
6231   vat_json_node_t *msg;
6232   vat_json_node_t *counter_array;
6233   vat_json_node_t *counter;
6234   interface_counter_t c;
6235   u64 packets;
6236   ip4_fib_counter_t *c4;
6237   ip6_fib_counter_t *c6;
6238   ip4_nbr_counter_t *n4;
6239   ip6_nbr_counter_t *n6;
6240   int i, j;
6241
6242   if (!vam->json_output)
6243     {
6244       clib_warning ("dump_stats_table supported only in JSON format");
6245       return -99;
6246     }
6247
6248   vat_json_init_object (&node);
6249
6250   /* interface counters */
6251   msg_array = vat_json_object_add (&node, "interface_counters");
6252   vat_json_init_array (msg_array);
6253   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6254     {
6255       msg = vat_json_array_add (msg_array);
6256       vat_json_init_object (msg);
6257       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6258                                        (u8 *) counter_type_to_str (i, 0));
6259       vat_json_object_add_int (msg, "is_combined", 0);
6260       counter_array = vat_json_object_add (msg, "data");
6261       vat_json_init_array (counter_array);
6262       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6263         {
6264           packets = vam->simple_interface_counters[i][j];
6265           vat_json_array_add_uint (counter_array, packets);
6266         }
6267     }
6268   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6269     {
6270       msg = vat_json_array_add (msg_array);
6271       vat_json_init_object (msg);
6272       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6273                                        (u8 *) counter_type_to_str (i, 1));
6274       vat_json_object_add_int (msg, "is_combined", 1);
6275       counter_array = vat_json_object_add (msg, "data");
6276       vat_json_init_array (counter_array);
6277       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6278         {
6279           c = vam->combined_interface_counters[i][j];
6280           counter = vat_json_array_add (counter_array);
6281           vat_json_init_object (counter);
6282           vat_json_object_add_uint (counter, "packets", c.packets);
6283           vat_json_object_add_uint (counter, "bytes", c.bytes);
6284         }
6285     }
6286
6287   /* ip4 fib counters */
6288   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6289   vat_json_init_array (msg_array);
6290   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6291     {
6292       msg = vat_json_array_add (msg_array);
6293       vat_json_init_object (msg);
6294       vat_json_object_add_uint (msg, "vrf_id",
6295                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6296       counter_array = vat_json_object_add (msg, "c");
6297       vat_json_init_array (counter_array);
6298       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6299         {
6300           counter = vat_json_array_add (counter_array);
6301           vat_json_init_object (counter);
6302           c4 = &vam->ip4_fib_counters[i][j];
6303           vat_json_object_add_ip4 (counter, "address", c4->address);
6304           vat_json_object_add_uint (counter, "address_length",
6305                                     c4->address_length);
6306           vat_json_object_add_uint (counter, "packets", c4->packets);
6307           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6308         }
6309     }
6310
6311   /* ip6 fib counters */
6312   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6313   vat_json_init_array (msg_array);
6314   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6315     {
6316       msg = vat_json_array_add (msg_array);
6317       vat_json_init_object (msg);
6318       vat_json_object_add_uint (msg, "vrf_id",
6319                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6320       counter_array = vat_json_object_add (msg, "c");
6321       vat_json_init_array (counter_array);
6322       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6323         {
6324           counter = vat_json_array_add (counter_array);
6325           vat_json_init_object (counter);
6326           c6 = &vam->ip6_fib_counters[i][j];
6327           vat_json_object_add_ip6 (counter, "address", c6->address);
6328           vat_json_object_add_uint (counter, "address_length",
6329                                     c6->address_length);
6330           vat_json_object_add_uint (counter, "packets", c6->packets);
6331           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6332         }
6333     }
6334
6335   /* ip4 nbr counters */
6336   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6337   vat_json_init_array (msg_array);
6338   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6339     {
6340       msg = vat_json_array_add (msg_array);
6341       vat_json_init_object (msg);
6342       vat_json_object_add_uint (msg, "sw_if_index", i);
6343       counter_array = vat_json_object_add (msg, "c");
6344       vat_json_init_array (counter_array);
6345       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6346         {
6347           counter = vat_json_array_add (counter_array);
6348           vat_json_init_object (counter);
6349           n4 = &vam->ip4_nbr_counters[i][j];
6350           vat_json_object_add_ip4 (counter, "address", n4->address);
6351           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6352           vat_json_object_add_uint (counter, "packets", n4->packets);
6353           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6354         }
6355     }
6356
6357   /* ip6 nbr counters */
6358   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6359   vat_json_init_array (msg_array);
6360   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6361     {
6362       msg = vat_json_array_add (msg_array);
6363       vat_json_init_object (msg);
6364       vat_json_object_add_uint (msg, "sw_if_index", i);
6365       counter_array = vat_json_object_add (msg, "c");
6366       vat_json_init_array (counter_array);
6367       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6368         {
6369           counter = vat_json_array_add (counter_array);
6370           vat_json_init_object (counter);
6371           n6 = &vam->ip6_nbr_counters[i][j];
6372           vat_json_object_add_ip6 (counter, "address", n6->address);
6373           vat_json_object_add_uint (counter, "packets", n6->packets);
6374           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6375         }
6376     }
6377
6378   vat_json_print (vam->ofp, &node);
6379   vat_json_free (&node);
6380
6381   return 0;
6382 }
6383
6384 /*
6385  * Pass CLI buffers directly in the CLI_INBAND API message,
6386  * instead of an additional shared memory area.
6387  */
6388 static int
6389 exec_inband (vat_main_t * vam)
6390 {
6391   vl_api_cli_inband_t *mp;
6392   unformat_input_t *i = vam->input;
6393   int ret;
6394
6395   if (vec_len (i->buffer) == 0)
6396     return -1;
6397
6398   if (vam->exec_mode == 0 && unformat (i, "mode"))
6399     {
6400       vam->exec_mode = 1;
6401       return 0;
6402     }
6403   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6404     {
6405       vam->exec_mode = 0;
6406       return 0;
6407     }
6408
6409   /*
6410    * In order for the CLI command to work, it
6411    * must be a vector ending in \n, not a C-string ending
6412    * in \n\0.
6413    */
6414   u32 len = vec_len (vam->input->buffer);
6415   M2 (CLI_INBAND, mp, len);
6416   clib_memcpy (mp->cmd, vam->input->buffer, len);
6417   mp->length = htonl (len);
6418
6419   S (mp);
6420   W (ret);
6421   /* json responses may or may not include a useful reply... */
6422   if (vec_len (vam->cmd_reply))
6423     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6424   return ret;
6425 }
6426
6427 int
6428 exec (vat_main_t * vam)
6429 {
6430   return exec_inband (vam);
6431 }
6432
6433 static int
6434 api_create_loopback (vat_main_t * vam)
6435 {
6436   unformat_input_t *i = vam->input;
6437   vl_api_create_loopback_t *mp;
6438   vl_api_create_loopback_instance_t *mp_lbi;
6439   u8 mac_address[6];
6440   u8 mac_set = 0;
6441   u8 is_specified = 0;
6442   u32 user_instance = 0;
6443   int ret;
6444
6445   memset (mac_address, 0, sizeof (mac_address));
6446
6447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6448     {
6449       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6450         mac_set = 1;
6451       if (unformat (i, "instance %d", &user_instance))
6452         is_specified = 1;
6453       else
6454         break;
6455     }
6456
6457   if (is_specified)
6458     {
6459       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6460       mp_lbi->is_specified = is_specified;
6461       if (is_specified)
6462         mp_lbi->user_instance = htonl (user_instance);
6463       if (mac_set)
6464         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6465       S (mp_lbi);
6466     }
6467   else
6468     {
6469       /* Construct the API message */
6470       M (CREATE_LOOPBACK, mp);
6471       if (mac_set)
6472         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6473       S (mp);
6474     }
6475
6476   W (ret);
6477   return ret;
6478 }
6479
6480 static int
6481 api_delete_loopback (vat_main_t * vam)
6482 {
6483   unformat_input_t *i = vam->input;
6484   vl_api_delete_loopback_t *mp;
6485   u32 sw_if_index = ~0;
6486   int ret;
6487
6488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6489     {
6490       if (unformat (i, "sw_if_index %d", &sw_if_index))
6491         ;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index == ~0)
6497     {
6498       errmsg ("missing sw_if_index");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (DELETE_LOOPBACK, mp);
6504   mp->sw_if_index = ntohl (sw_if_index);
6505
6506   S (mp);
6507   W (ret);
6508   return ret;
6509 }
6510
6511 static int
6512 api_want_stats (vat_main_t * vam)
6513 {
6514   unformat_input_t *i = vam->input;
6515   vl_api_want_stats_t *mp;
6516   int enable = -1;
6517   int ret;
6518
6519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520     {
6521       if (unformat (i, "enable"))
6522         enable = 1;
6523       else if (unformat (i, "disable"))
6524         enable = 0;
6525       else
6526         break;
6527     }
6528
6529   if (enable == -1)
6530     {
6531       errmsg ("missing enable|disable");
6532       return -99;
6533     }
6534
6535   M (WANT_STATS, mp);
6536   mp->enable_disable = enable;
6537
6538   S (mp);
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_want_interface_events (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_want_interface_events_t *mp;
6548   int enable = -1;
6549   int ret;
6550
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "enable"))
6554         enable = 1;
6555       else if (unformat (i, "disable"))
6556         enable = 0;
6557       else
6558         break;
6559     }
6560
6561   if (enable == -1)
6562     {
6563       errmsg ("missing enable|disable");
6564       return -99;
6565     }
6566
6567   M (WANT_INTERFACE_EVENTS, mp);
6568   mp->enable_disable = enable;
6569
6570   vam->interface_event_display = enable;
6571
6572   S (mp);
6573   W (ret);
6574   return ret;
6575 }
6576
6577
6578 /* Note: non-static, called once to set up the initial intfc table */
6579 int
6580 api_sw_interface_dump (vat_main_t * vam)
6581 {
6582   vl_api_sw_interface_dump_t *mp;
6583   vl_api_control_ping_t *mp_ping;
6584   hash_pair_t *p;
6585   name_sort_t *nses = 0, *ns;
6586   sw_interface_subif_t *sub = NULL;
6587   int ret;
6588
6589   /* Toss the old name table */
6590   /* *INDENT-OFF* */
6591   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6592   ({
6593     vec_add2 (nses, ns, 1);
6594     ns->name = (u8 *)(p->key);
6595     ns->value = (u32) p->value[0];
6596   }));
6597   /* *INDENT-ON* */
6598
6599   hash_free (vam->sw_if_index_by_interface_name);
6600
6601   vec_foreach (ns, nses) vec_free (ns->name);
6602
6603   vec_free (nses);
6604
6605   vec_foreach (sub, vam->sw_if_subif_table)
6606   {
6607     vec_free (sub->interface_name);
6608   }
6609   vec_free (vam->sw_if_subif_table);
6610
6611   /* recreate the interface name hash table */
6612   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6613
6614   /*
6615    * Ask for all interface names. Otherwise, the epic catalog of
6616    * name filters becomes ridiculously long, and vat ends up needing
6617    * to be taught about new interface types.
6618    */
6619   M (SW_INTERFACE_DUMP, mp);
6620   S (mp);
6621
6622   /* Use a control ping for synchronization */
6623   MPING (CONTROL_PING, mp_ping);
6624   S (mp_ping);
6625
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_sw_interface_set_flags (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_sw_interface_set_flags_t *mp;
6635   u32 sw_if_index;
6636   u8 sw_if_index_set = 0;
6637   u8 admin_up = 0;
6638   int ret;
6639
6640   /* Parse args required to build the message */
6641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6642     {
6643       if (unformat (i, "admin-up"))
6644         admin_up = 1;
6645       else if (unformat (i, "admin-down"))
6646         admin_up = 0;
6647       else
6648         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6649         sw_if_index_set = 1;
6650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6651         sw_if_index_set = 1;
6652       else
6653         break;
6654     }
6655
6656   if (sw_if_index_set == 0)
6657     {
6658       errmsg ("missing interface name or sw_if_index");
6659       return -99;
6660     }
6661
6662   /* Construct the API message */
6663   M (SW_INTERFACE_SET_FLAGS, mp);
6664   mp->sw_if_index = ntohl (sw_if_index);
6665   mp->admin_up_down = admin_up;
6666
6667   /* send it... */
6668   S (mp);
6669
6670   /* Wait for a reply, return the good/bad news... */
6671   W (ret);
6672   return ret;
6673 }
6674
6675 static int
6676 api_sw_interface_set_rx_mode (vat_main_t * vam)
6677 {
6678   unformat_input_t *i = vam->input;
6679   vl_api_sw_interface_set_rx_mode_t *mp;
6680   u32 sw_if_index;
6681   u8 sw_if_index_set = 0;
6682   int ret;
6683   u8 queue_id_valid = 0;
6684   u32 queue_id;
6685   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "queue %d", &queue_id))
6691         queue_id_valid = 1;
6692       else if (unformat (i, "polling"))
6693         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6694       else if (unformat (i, "interrupt"))
6695         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6696       else if (unformat (i, "adaptive"))
6697         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6698       else
6699         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6700         sw_if_index_set = 1;
6701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6702         sw_if_index_set = 1;
6703       else
6704         break;
6705     }
6706
6707   if (sw_if_index_set == 0)
6708     {
6709       errmsg ("missing interface name or sw_if_index");
6710       return -99;
6711     }
6712   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6713     {
6714       errmsg ("missing rx-mode");
6715       return -99;
6716     }
6717
6718   /* Construct the API message */
6719   M (SW_INTERFACE_SET_RX_MODE, mp);
6720   mp->sw_if_index = ntohl (sw_if_index);
6721   mp->mode = mode;
6722   mp->queue_id_valid = queue_id_valid;
6723   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6724
6725   /* send it... */
6726   S (mp);
6727
6728   /* Wait for a reply, return the good/bad news... */
6729   W (ret);
6730   return ret;
6731 }
6732
6733 static int
6734 api_sw_interface_clear_stats (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_clear_stats_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   int ret;
6741
6742   /* Parse args required to build the message */
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else
6750         break;
6751     }
6752
6753   /* Construct the API message */
6754   M (SW_INTERFACE_CLEAR_STATS, mp);
6755
6756   if (sw_if_index_set == 1)
6757     mp->sw_if_index = ntohl (sw_if_index);
6758   else
6759     mp->sw_if_index = ~0;
6760
6761   /* send it... */
6762   S (mp);
6763
6764   /* Wait for a reply, return the good/bad news... */
6765   W (ret);
6766   return ret;
6767 }
6768
6769 static int
6770 api_sw_interface_add_del_address (vat_main_t * vam)
6771 {
6772   unformat_input_t *i = vam->input;
6773   vl_api_sw_interface_add_del_address_t *mp;
6774   u32 sw_if_index;
6775   u8 sw_if_index_set = 0;
6776   u8 is_add = 1, del_all = 0;
6777   u32 address_length = 0;
6778   u8 v4_address_set = 0;
6779   u8 v6_address_set = 0;
6780   ip4_address_t v4address;
6781   ip6_address_t v6address;
6782   int ret;
6783
6784   /* Parse args required to build the message */
6785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6786     {
6787       if (unformat (i, "del-all"))
6788         del_all = 1;
6789       else if (unformat (i, "del"))
6790         is_add = 0;
6791       else
6792         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6793         sw_if_index_set = 1;
6794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6795         sw_if_index_set = 1;
6796       else if (unformat (i, "%U/%d",
6797                          unformat_ip4_address, &v4address, &address_length))
6798         v4_address_set = 1;
6799       else if (unformat (i, "%U/%d",
6800                          unformat_ip6_address, &v6address, &address_length))
6801         v6_address_set = 1;
6802       else
6803         break;
6804     }
6805
6806   if (sw_if_index_set == 0)
6807     {
6808       errmsg ("missing interface name or sw_if_index");
6809       return -99;
6810     }
6811   if (v4_address_set && v6_address_set)
6812     {
6813       errmsg ("both v4 and v6 addresses set");
6814       return -99;
6815     }
6816   if (!v4_address_set && !v6_address_set && !del_all)
6817     {
6818       errmsg ("no addresses set");
6819       return -99;
6820     }
6821
6822   /* Construct the API message */
6823   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6824
6825   mp->sw_if_index = ntohl (sw_if_index);
6826   mp->is_add = is_add;
6827   mp->del_all = del_all;
6828   if (v6_address_set)
6829     {
6830       mp->is_ipv6 = 1;
6831       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6832     }
6833   else
6834     {
6835       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6836     }
6837   mp->address_length = address_length;
6838
6839   /* send it... */
6840   S (mp);
6841
6842   /* Wait for a reply, return good/bad news  */
6843   W (ret);
6844   return ret;
6845 }
6846
6847 static int
6848 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_sw_interface_set_mpls_enable_t *mp;
6852   u32 sw_if_index;
6853   u8 sw_if_index_set = 0;
6854   u8 enable = 1;
6855   int ret;
6856
6857   /* Parse args required to build the message */
6858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6859     {
6860       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6861         sw_if_index_set = 1;
6862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6863         sw_if_index_set = 1;
6864       else if (unformat (i, "disable"))
6865         enable = 0;
6866       else if (unformat (i, "dis"))
6867         enable = 0;
6868       else
6869         break;
6870     }
6871
6872   if (sw_if_index_set == 0)
6873     {
6874       errmsg ("missing interface name or sw_if_index");
6875       return -99;
6876     }
6877
6878   /* Construct the API message */
6879   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6880
6881   mp->sw_if_index = ntohl (sw_if_index);
6882   mp->enable = enable;
6883
6884   /* send it... */
6885   S (mp);
6886
6887   /* Wait for a reply... */
6888   W (ret);
6889   return ret;
6890 }
6891
6892 static int
6893 api_sw_interface_set_table (vat_main_t * vam)
6894 {
6895   unformat_input_t *i = vam->input;
6896   vl_api_sw_interface_set_table_t *mp;
6897   u32 sw_if_index, vrf_id = 0;
6898   u8 sw_if_index_set = 0;
6899   u8 is_ipv6 = 0;
6900   int ret;
6901
6902   /* Parse args required to build the message */
6903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6904     {
6905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6906         sw_if_index_set = 1;
6907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6908         sw_if_index_set = 1;
6909       else if (unformat (i, "vrf %d", &vrf_id))
6910         ;
6911       else if (unformat (i, "ipv6"))
6912         is_ipv6 = 1;
6913       else
6914         break;
6915     }
6916
6917   if (sw_if_index_set == 0)
6918     {
6919       errmsg ("missing interface name or sw_if_index");
6920       return -99;
6921     }
6922
6923   /* Construct the API message */
6924   M (SW_INTERFACE_SET_TABLE, mp);
6925
6926   mp->sw_if_index = ntohl (sw_if_index);
6927   mp->is_ipv6 = is_ipv6;
6928   mp->vrf_id = ntohl (vrf_id);
6929
6930   /* send it... */
6931   S (mp);
6932
6933   /* Wait for a reply... */
6934   W (ret);
6935   return ret;
6936 }
6937
6938 static void vl_api_sw_interface_get_table_reply_t_handler
6939   (vl_api_sw_interface_get_table_reply_t * mp)
6940 {
6941   vat_main_t *vam = &vat_main;
6942
6943   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6944
6945   vam->retval = ntohl (mp->retval);
6946   vam->result_ready = 1;
6947
6948 }
6949
6950 static void vl_api_sw_interface_get_table_reply_t_handler_json
6951   (vl_api_sw_interface_get_table_reply_t * mp)
6952 {
6953   vat_main_t *vam = &vat_main;
6954   vat_json_node_t node;
6955
6956   vat_json_init_object (&node);
6957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6958   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6959
6960   vat_json_print (vam->ofp, &node);
6961   vat_json_free (&node);
6962
6963   vam->retval = ntohl (mp->retval);
6964   vam->result_ready = 1;
6965 }
6966
6967 static int
6968 api_sw_interface_get_table (vat_main_t * vam)
6969 {
6970   unformat_input_t *i = vam->input;
6971   vl_api_sw_interface_get_table_t *mp;
6972   u32 sw_if_index;
6973   u8 sw_if_index_set = 0;
6974   u8 is_ipv6 = 0;
6975   int ret;
6976
6977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978     {
6979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6980         sw_if_index_set = 1;
6981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6982         sw_if_index_set = 1;
6983       else if (unformat (i, "ipv6"))
6984         is_ipv6 = 1;
6985       else
6986         break;
6987     }
6988
6989   if (sw_if_index_set == 0)
6990     {
6991       errmsg ("missing interface name or sw_if_index");
6992       return -99;
6993     }
6994
6995   M (SW_INTERFACE_GET_TABLE, mp);
6996   mp->sw_if_index = htonl (sw_if_index);
6997   mp->is_ipv6 = is_ipv6;
6998
6999   S (mp);
7000   W (ret);
7001   return ret;
7002 }
7003
7004 static int
7005 api_sw_interface_set_vpath (vat_main_t * vam)
7006 {
7007   unformat_input_t *i = vam->input;
7008   vl_api_sw_interface_set_vpath_t *mp;
7009   u32 sw_if_index = 0;
7010   u8 sw_if_index_set = 0;
7011   u8 is_enable = 0;
7012   int ret;
7013
7014   /* Parse args required to build the message */
7015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7016     {
7017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7018         sw_if_index_set = 1;
7019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7020         sw_if_index_set = 1;
7021       else if (unformat (i, "enable"))
7022         is_enable = 1;
7023       else if (unformat (i, "disable"))
7024         is_enable = 0;
7025       else
7026         break;
7027     }
7028
7029   if (sw_if_index_set == 0)
7030     {
7031       errmsg ("missing interface name or sw_if_index");
7032       return -99;
7033     }
7034
7035   /* Construct the API message */
7036   M (SW_INTERFACE_SET_VPATH, mp);
7037
7038   mp->sw_if_index = ntohl (sw_if_index);
7039   mp->enable = is_enable;
7040
7041   /* send it... */
7042   S (mp);
7043
7044   /* Wait for a reply... */
7045   W (ret);
7046   return ret;
7047 }
7048
7049 static int
7050 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7051 {
7052   unformat_input_t *i = vam->input;
7053   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7054   u32 sw_if_index = 0;
7055   u8 sw_if_index_set = 0;
7056   u8 is_enable = 1;
7057   u8 is_ipv6 = 0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7066         sw_if_index_set = 1;
7067       else if (unformat (i, "enable"))
7068         is_enable = 1;
7069       else if (unformat (i, "disable"))
7070         is_enable = 0;
7071       else if (unformat (i, "ip4"))
7072         is_ipv6 = 0;
7073       else if (unformat (i, "ip6"))
7074         is_ipv6 = 1;
7075       else
7076         break;
7077     }
7078
7079   if (sw_if_index_set == 0)
7080     {
7081       errmsg ("missing interface name or sw_if_index");
7082       return -99;
7083     }
7084
7085   /* Construct the API message */
7086   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7087
7088   mp->sw_if_index = ntohl (sw_if_index);
7089   mp->enable = is_enable;
7090   mp->is_ipv6 = is_ipv6;
7091
7092   /* send it... */
7093   S (mp);
7094
7095   /* Wait for a reply... */
7096   W (ret);
7097   return ret;
7098 }
7099
7100 static int
7101 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7102 {
7103   unformat_input_t *i = vam->input;
7104   vl_api_sw_interface_set_geneve_bypass_t *mp;
7105   u32 sw_if_index = 0;
7106   u8 sw_if_index_set = 0;
7107   u8 is_enable = 1;
7108   u8 is_ipv6 = 0;
7109   int ret;
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7115         sw_if_index_set = 1;
7116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7117         sw_if_index_set = 1;
7118       else if (unformat (i, "enable"))
7119         is_enable = 1;
7120       else if (unformat (i, "disable"))
7121         is_enable = 0;
7122       else if (unformat (i, "ip4"))
7123         is_ipv6 = 0;
7124       else if (unformat (i, "ip6"))
7125         is_ipv6 = 1;
7126       else
7127         break;
7128     }
7129
7130   if (sw_if_index_set == 0)
7131     {
7132       errmsg ("missing interface name or sw_if_index");
7133       return -99;
7134     }
7135
7136   /* Construct the API message */
7137   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7138
7139   mp->sw_if_index = ntohl (sw_if_index);
7140   mp->enable = is_enable;
7141   mp->is_ipv6 = is_ipv6;
7142
7143   /* send it... */
7144   S (mp);
7145
7146   /* Wait for a reply... */
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_sw_interface_set_l2_xconnect_t *mp;
7156   u32 rx_sw_if_index;
7157   u8 rx_sw_if_index_set = 0;
7158   u32 tx_sw_if_index;
7159   u8 tx_sw_if_index_set = 0;
7160   u8 enable = 1;
7161   int ret;
7162
7163   /* Parse args required to build the message */
7164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7165     {
7166       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7167         rx_sw_if_index_set = 1;
7168       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7169         tx_sw_if_index_set = 1;
7170       else if (unformat (i, "rx"))
7171         {
7172           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7173             {
7174               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7175                             &rx_sw_if_index))
7176                 rx_sw_if_index_set = 1;
7177             }
7178           else
7179             break;
7180         }
7181       else if (unformat (i, "tx"))
7182         {
7183           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184             {
7185               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7186                             &tx_sw_if_index))
7187                 tx_sw_if_index_set = 1;
7188             }
7189           else
7190             break;
7191         }
7192       else if (unformat (i, "enable"))
7193         enable = 1;
7194       else if (unformat (i, "disable"))
7195         enable = 0;
7196       else
7197         break;
7198     }
7199
7200   if (rx_sw_if_index_set == 0)
7201     {
7202       errmsg ("missing rx interface name or rx_sw_if_index");
7203       return -99;
7204     }
7205
7206   if (enable && (tx_sw_if_index_set == 0))
7207     {
7208       errmsg ("missing tx interface name or tx_sw_if_index");
7209       return -99;
7210     }
7211
7212   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7213
7214   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7215   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7216   mp->enable = enable;
7217
7218   S (mp);
7219   W (ret);
7220   return ret;
7221 }
7222
7223 static int
7224 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7225 {
7226   unformat_input_t *i = vam->input;
7227   vl_api_sw_interface_set_l2_bridge_t *mp;
7228   u32 rx_sw_if_index;
7229   u8 rx_sw_if_index_set = 0;
7230   u32 bd_id;
7231   u8 bd_id_set = 0;
7232   u8 bvi = 0;
7233   u32 shg = 0;
7234   u8 enable = 1;
7235   int ret;
7236
7237   /* Parse args required to build the message */
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7241         rx_sw_if_index_set = 1;
7242       else if (unformat (i, "bd_id %d", &bd_id))
7243         bd_id_set = 1;
7244       else
7245         if (unformat
7246             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7247         rx_sw_if_index_set = 1;
7248       else if (unformat (i, "shg %d", &shg))
7249         ;
7250       else if (unformat (i, "bvi"))
7251         bvi = 1;
7252       else if (unformat (i, "enable"))
7253         enable = 1;
7254       else if (unformat (i, "disable"))
7255         enable = 0;
7256       else
7257         break;
7258     }
7259
7260   if (rx_sw_if_index_set == 0)
7261     {
7262       errmsg ("missing rx interface name or sw_if_index");
7263       return -99;
7264     }
7265
7266   if (enable && (bd_id_set == 0))
7267     {
7268       errmsg ("missing bridge domain");
7269       return -99;
7270     }
7271
7272   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7273
7274   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7275   mp->bd_id = ntohl (bd_id);
7276   mp->shg = (u8) shg;
7277   mp->bvi = bvi;
7278   mp->enable = enable;
7279
7280   S (mp);
7281   W (ret);
7282   return ret;
7283 }
7284
7285 static int
7286 api_bridge_domain_dump (vat_main_t * vam)
7287 {
7288   unformat_input_t *i = vam->input;
7289   vl_api_bridge_domain_dump_t *mp;
7290   vl_api_control_ping_t *mp_ping;
7291   u32 bd_id = ~0;
7292   int ret;
7293
7294   /* Parse args required to build the message */
7295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7296     {
7297       if (unformat (i, "bd_id %d", &bd_id))
7298         ;
7299       else
7300         break;
7301     }
7302
7303   M (BRIDGE_DOMAIN_DUMP, mp);
7304   mp->bd_id = ntohl (bd_id);
7305   S (mp);
7306
7307   /* Use a control ping for synchronization */
7308   MPING (CONTROL_PING, mp_ping);
7309   S (mp_ping);
7310
7311   W (ret);
7312   return ret;
7313 }
7314
7315 static int
7316 api_bridge_domain_add_del (vat_main_t * vam)
7317 {
7318   unformat_input_t *i = vam->input;
7319   vl_api_bridge_domain_add_del_t *mp;
7320   u32 bd_id = ~0;
7321   u8 is_add = 1;
7322   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7323   u8 *bd_tag = NULL;
7324   u32 mac_age = 0;
7325   int ret;
7326
7327   /* Parse args required to build the message */
7328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7329     {
7330       if (unformat (i, "bd_id %d", &bd_id))
7331         ;
7332       else if (unformat (i, "flood %d", &flood))
7333         ;
7334       else if (unformat (i, "uu-flood %d", &uu_flood))
7335         ;
7336       else if (unformat (i, "forward %d", &forward))
7337         ;
7338       else if (unformat (i, "learn %d", &learn))
7339         ;
7340       else if (unformat (i, "arp-term %d", &arp_term))
7341         ;
7342       else if (unformat (i, "mac-age %d", &mac_age))
7343         ;
7344       else if (unformat (i, "bd-tag %s", &bd_tag))
7345         ;
7346       else if (unformat (i, "del"))
7347         {
7348           is_add = 0;
7349           flood = uu_flood = forward = learn = 0;
7350         }
7351       else
7352         break;
7353     }
7354
7355   if (bd_id == ~0)
7356     {
7357       errmsg ("missing bridge domain");
7358       ret = -99;
7359       goto done;
7360     }
7361
7362   if (mac_age > 255)
7363     {
7364       errmsg ("mac age must be less than 256 ");
7365       ret = -99;
7366       goto done;
7367     }
7368
7369   if ((bd_tag) && (vec_len (bd_tag) > 63))
7370     {
7371       errmsg ("bd-tag cannot be longer than 63");
7372       ret = -99;
7373       goto done;
7374     }
7375
7376   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7377
7378   mp->bd_id = ntohl (bd_id);
7379   mp->flood = flood;
7380   mp->uu_flood = uu_flood;
7381   mp->forward = forward;
7382   mp->learn = learn;
7383   mp->arp_term = arp_term;
7384   mp->is_add = is_add;
7385   mp->mac_age = (u8) mac_age;
7386   if (bd_tag)
7387     {
7388       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7389       mp->bd_tag[vec_len (bd_tag)] = 0;
7390     }
7391   S (mp);
7392   W (ret);
7393
7394 done:
7395   vec_free (bd_tag);
7396   return ret;
7397 }
7398
7399 static int
7400 api_l2fib_flush_bd (vat_main_t * vam)
7401 {
7402   unformat_input_t *i = vam->input;
7403   vl_api_l2fib_flush_bd_t *mp;
7404   u32 bd_id = ~0;
7405   int ret;
7406
7407   /* Parse args required to build the message */
7408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7409     {
7410       if (unformat (i, "bd_id %d", &bd_id));
7411       else
7412         break;
7413     }
7414
7415   if (bd_id == ~0)
7416     {
7417       errmsg ("missing bridge domain");
7418       return -99;
7419     }
7420
7421   M (L2FIB_FLUSH_BD, mp);
7422
7423   mp->bd_id = htonl (bd_id);
7424
7425   S (mp);
7426   W (ret);
7427   return ret;
7428 }
7429
7430 static int
7431 api_l2fib_flush_int (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_l2fib_flush_int_t *mp;
7435   u32 sw_if_index = ~0;
7436   int ret;
7437
7438   /* Parse args required to build the message */
7439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7440     {
7441       if (unformat (i, "sw_if_index %d", &sw_if_index));
7442       else
7443         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7444       else
7445         break;
7446     }
7447
7448   if (sw_if_index == ~0)
7449     {
7450       errmsg ("missing interface name or sw_if_index");
7451       return -99;
7452     }
7453
7454   M (L2FIB_FLUSH_INT, mp);
7455
7456   mp->sw_if_index = ntohl (sw_if_index);
7457
7458   S (mp);
7459   W (ret);
7460   return ret;
7461 }
7462
7463 static int
7464 api_l2fib_add_del (vat_main_t * vam)
7465 {
7466   unformat_input_t *i = vam->input;
7467   vl_api_l2fib_add_del_t *mp;
7468   f64 timeout;
7469   u8 mac[6] = { 0 };
7470   u8 mac_set = 0;
7471   u32 bd_id;
7472   u8 bd_id_set = 0;
7473   u32 sw_if_index = ~0;
7474   u8 sw_if_index_set = 0;
7475   u8 is_add = 1;
7476   u8 static_mac = 0;
7477   u8 filter_mac = 0;
7478   u8 bvi_mac = 0;
7479   int count = 1;
7480   f64 before = 0;
7481   int j;
7482
7483   /* Parse args required to build the message */
7484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7485     {
7486       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7487         mac_set = 1;
7488       else if (unformat (i, "bd_id %d", &bd_id))
7489         bd_id_set = 1;
7490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7491         sw_if_index_set = 1;
7492       else if (unformat (i, "sw_if"))
7493         {
7494           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7495             {
7496               if (unformat
7497                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7498                 sw_if_index_set = 1;
7499             }
7500           else
7501             break;
7502         }
7503       else if (unformat (i, "static"))
7504         static_mac = 1;
7505       else if (unformat (i, "filter"))
7506         {
7507           filter_mac = 1;
7508           static_mac = 1;
7509         }
7510       else if (unformat (i, "bvi"))
7511         {
7512           bvi_mac = 1;
7513           static_mac = 1;
7514         }
7515       else if (unformat (i, "del"))
7516         is_add = 0;
7517       else if (unformat (i, "count %d", &count))
7518         ;
7519       else
7520         break;
7521     }
7522
7523   if (mac_set == 0)
7524     {
7525       errmsg ("missing mac address");
7526       return -99;
7527     }
7528
7529   if (bd_id_set == 0)
7530     {
7531       errmsg ("missing bridge domain");
7532       return -99;
7533     }
7534
7535   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7536     {
7537       errmsg ("missing interface name or sw_if_index");
7538       return -99;
7539     }
7540
7541   if (count > 1)
7542     {
7543       /* Turn on async mode */
7544       vam->async_mode = 1;
7545       vam->async_errors = 0;
7546       before = vat_time_now (vam);
7547     }
7548
7549   for (j = 0; j < count; j++)
7550     {
7551       M (L2FIB_ADD_DEL, mp);
7552
7553       clib_memcpy (mp->mac, mac, 6);
7554       mp->bd_id = ntohl (bd_id);
7555       mp->is_add = is_add;
7556
7557       if (is_add)
7558         {
7559           mp->sw_if_index = ntohl (sw_if_index);
7560           mp->static_mac = static_mac;
7561           mp->filter_mac = filter_mac;
7562           mp->bvi_mac = bvi_mac;
7563         }
7564       increment_mac_address (mac);
7565       /* send it... */
7566       S (mp);
7567     }
7568
7569   if (count > 1)
7570     {
7571       vl_api_control_ping_t *mp_ping;
7572       f64 after;
7573
7574       /* Shut off async mode */
7575       vam->async_mode = 0;
7576
7577       MPING (CONTROL_PING, mp_ping);
7578       S (mp_ping);
7579
7580       timeout = vat_time_now (vam) + 1.0;
7581       while (vat_time_now (vam) < timeout)
7582         if (vam->result_ready == 1)
7583           goto out;
7584       vam->retval = -99;
7585
7586     out:
7587       if (vam->retval == -99)
7588         errmsg ("timeout");
7589
7590       if (vam->async_errors > 0)
7591         {
7592           errmsg ("%d asynchronous errors", vam->async_errors);
7593           vam->retval = -98;
7594         }
7595       vam->async_errors = 0;
7596       after = vat_time_now (vam);
7597
7598       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7599              count, after - before, count / (after - before));
7600     }
7601   else
7602     {
7603       int ret;
7604
7605       /* Wait for a reply... */
7606       W (ret);
7607       return ret;
7608     }
7609   /* Return the good/bad news */
7610   return (vam->retval);
7611 }
7612
7613 static int
7614 api_bridge_domain_set_mac_age (vat_main_t * vam)
7615 {
7616   unformat_input_t *i = vam->input;
7617   vl_api_bridge_domain_set_mac_age_t *mp;
7618   u32 bd_id = ~0;
7619   u32 mac_age = 0;
7620   int ret;
7621
7622   /* Parse args required to build the message */
7623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7624     {
7625       if (unformat (i, "bd_id %d", &bd_id));
7626       else if (unformat (i, "mac-age %d", &mac_age));
7627       else
7628         break;
7629     }
7630
7631   if (bd_id == ~0)
7632     {
7633       errmsg ("missing bridge domain");
7634       return -99;
7635     }
7636
7637   if (mac_age > 255)
7638     {
7639       errmsg ("mac age must be less than 256 ");
7640       return -99;
7641     }
7642
7643   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7644
7645   mp->bd_id = htonl (bd_id);
7646   mp->mac_age = (u8) mac_age;
7647
7648   S (mp);
7649   W (ret);
7650   return ret;
7651 }
7652
7653 static int
7654 api_l2_flags (vat_main_t * vam)
7655 {
7656   unformat_input_t *i = vam->input;
7657   vl_api_l2_flags_t *mp;
7658   u32 sw_if_index;
7659   u32 flags = 0;
7660   u8 sw_if_index_set = 0;
7661   u8 is_set = 0;
7662   int ret;
7663
7664   /* Parse args required to build the message */
7665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7666     {
7667       if (unformat (i, "sw_if_index %d", &sw_if_index))
7668         sw_if_index_set = 1;
7669       else if (unformat (i, "sw_if"))
7670         {
7671           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672             {
7673               if (unformat
7674                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7675                 sw_if_index_set = 1;
7676             }
7677           else
7678             break;
7679         }
7680       else if (unformat (i, "learn"))
7681         flags |= L2_LEARN;
7682       else if (unformat (i, "forward"))
7683         flags |= L2_FWD;
7684       else if (unformat (i, "flood"))
7685         flags |= L2_FLOOD;
7686       else if (unformat (i, "uu-flood"))
7687         flags |= L2_UU_FLOOD;
7688       else if (unformat (i, "arp-term"))
7689         flags |= L2_ARP_TERM;
7690       else if (unformat (i, "off"))
7691         is_set = 0;
7692       else if (unformat (i, "disable"))
7693         is_set = 0;
7694       else
7695         break;
7696     }
7697
7698   if (sw_if_index_set == 0)
7699     {
7700       errmsg ("missing interface name or sw_if_index");
7701       return -99;
7702     }
7703
7704   M (L2_FLAGS, mp);
7705
7706   mp->sw_if_index = ntohl (sw_if_index);
7707   mp->feature_bitmap = ntohl (flags);
7708   mp->is_set = is_set;
7709
7710   S (mp);
7711   W (ret);
7712   return ret;
7713 }
7714
7715 static int
7716 api_bridge_flags (vat_main_t * vam)
7717 {
7718   unformat_input_t *i = vam->input;
7719   vl_api_bridge_flags_t *mp;
7720   u32 bd_id;
7721   u8 bd_id_set = 0;
7722   u8 is_set = 1;
7723   u32 flags = 0;
7724   int ret;
7725
7726   /* Parse args required to build the message */
7727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7728     {
7729       if (unformat (i, "bd_id %d", &bd_id))
7730         bd_id_set = 1;
7731       else if (unformat (i, "learn"))
7732         flags |= L2_LEARN;
7733       else if (unformat (i, "forward"))
7734         flags |= L2_FWD;
7735       else if (unformat (i, "flood"))
7736         flags |= L2_FLOOD;
7737       else if (unformat (i, "uu-flood"))
7738         flags |= L2_UU_FLOOD;
7739       else if (unformat (i, "arp-term"))
7740         flags |= L2_ARP_TERM;
7741       else if (unformat (i, "off"))
7742         is_set = 0;
7743       else if (unformat (i, "disable"))
7744         is_set = 0;
7745       else
7746         break;
7747     }
7748
7749   if (bd_id_set == 0)
7750     {
7751       errmsg ("missing bridge domain");
7752       return -99;
7753     }
7754
7755   M (BRIDGE_FLAGS, mp);
7756
7757   mp->bd_id = ntohl (bd_id);
7758   mp->feature_bitmap = ntohl (flags);
7759   mp->is_set = is_set;
7760
7761   S (mp);
7762   W (ret);
7763   return ret;
7764 }
7765
7766 static int
7767 api_bd_ip_mac_add_del (vat_main_t * vam)
7768 {
7769   unformat_input_t *i = vam->input;
7770   vl_api_bd_ip_mac_add_del_t *mp;
7771   u32 bd_id;
7772   u8 is_ipv6 = 0;
7773   u8 is_add = 1;
7774   u8 bd_id_set = 0;
7775   u8 ip_set = 0;
7776   u8 mac_set = 0;
7777   ip4_address_t v4addr;
7778   ip6_address_t v6addr;
7779   u8 macaddr[6];
7780   int ret;
7781
7782
7783   /* Parse args required to build the message */
7784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (i, "bd_id %d", &bd_id))
7787         {
7788           bd_id_set++;
7789         }
7790       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7791         {
7792           ip_set++;
7793         }
7794       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7795         {
7796           ip_set++;
7797           is_ipv6++;
7798         }
7799       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7800         {
7801           mac_set++;
7802         }
7803       else if (unformat (i, "del"))
7804         is_add = 0;
7805       else
7806         break;
7807     }
7808
7809   if (bd_id_set == 0)
7810     {
7811       errmsg ("missing bridge domain");
7812       return -99;
7813     }
7814   else if (ip_set == 0)
7815     {
7816       errmsg ("missing IP address");
7817       return -99;
7818     }
7819   else if (mac_set == 0)
7820     {
7821       errmsg ("missing MAC address");
7822       return -99;
7823     }
7824
7825   M (BD_IP_MAC_ADD_DEL, mp);
7826
7827   mp->bd_id = ntohl (bd_id);
7828   mp->is_ipv6 = is_ipv6;
7829   mp->is_add = is_add;
7830   if (is_ipv6)
7831     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7832   else
7833     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7834   clib_memcpy (mp->mac_address, macaddr, 6);
7835   S (mp);
7836   W (ret);
7837   return ret;
7838 }
7839
7840 static int
7841 api_tap_connect (vat_main_t * vam)
7842 {
7843   unformat_input_t *i = vam->input;
7844   vl_api_tap_connect_t *mp;
7845   u8 mac_address[6];
7846   u8 random_mac = 1;
7847   u8 name_set = 0;
7848   u8 *tap_name;
7849   u8 *tag = 0;
7850   ip4_address_t ip4_address;
7851   u32 ip4_mask_width;
7852   int ip4_address_set = 0;
7853   ip6_address_t ip6_address;
7854   u32 ip6_mask_width;
7855   int ip6_address_set = 0;
7856   int ret;
7857
7858   memset (mac_address, 0, sizeof (mac_address));
7859
7860   /* Parse args required to build the message */
7861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7862     {
7863       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7864         {
7865           random_mac = 0;
7866         }
7867       else if (unformat (i, "random-mac"))
7868         random_mac = 1;
7869       else if (unformat (i, "tapname %s", &tap_name))
7870         name_set = 1;
7871       else if (unformat (i, "tag %s", &tag))
7872         ;
7873       else if (unformat (i, "address %U/%d",
7874                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7875         ip4_address_set = 1;
7876       else if (unformat (i, "address %U/%d",
7877                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7878         ip6_address_set = 1;
7879       else
7880         break;
7881     }
7882
7883   if (name_set == 0)
7884     {
7885       errmsg ("missing tap name");
7886       return -99;
7887     }
7888   if (vec_len (tap_name) > 63)
7889     {
7890       errmsg ("tap name too long");
7891       return -99;
7892     }
7893   vec_add1 (tap_name, 0);
7894
7895   if (vec_len (tag) > 63)
7896     {
7897       errmsg ("tag too long");
7898       return -99;
7899     }
7900
7901   /* Construct the API message */
7902   M (TAP_CONNECT, mp);
7903
7904   mp->use_random_mac = random_mac;
7905   clib_memcpy (mp->mac_address, mac_address, 6);
7906   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7907   if (tag)
7908     clib_memcpy (mp->tag, tag, vec_len (tag));
7909
7910   if (ip4_address_set)
7911     {
7912       mp->ip4_address_set = 1;
7913       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7914       mp->ip4_mask_width = ip4_mask_width;
7915     }
7916   if (ip6_address_set)
7917     {
7918       mp->ip6_address_set = 1;
7919       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7920       mp->ip6_mask_width = ip6_mask_width;
7921     }
7922
7923   vec_free (tap_name);
7924   vec_free (tag);
7925
7926   /* send it... */
7927   S (mp);
7928
7929   /* Wait for a reply... */
7930   W (ret);
7931   return ret;
7932 }
7933
7934 static int
7935 api_tap_modify (vat_main_t * vam)
7936 {
7937   unformat_input_t *i = vam->input;
7938   vl_api_tap_modify_t *mp;
7939   u8 mac_address[6];
7940   u8 random_mac = 1;
7941   u8 name_set = 0;
7942   u8 *tap_name;
7943   u32 sw_if_index = ~0;
7944   u8 sw_if_index_set = 0;
7945   int ret;
7946
7947   memset (mac_address, 0, sizeof (mac_address));
7948
7949   /* Parse args required to build the message */
7950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7951     {
7952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7953         sw_if_index_set = 1;
7954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7955         sw_if_index_set = 1;
7956       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7957         {
7958           random_mac = 0;
7959         }
7960       else if (unformat (i, "random-mac"))
7961         random_mac = 1;
7962       else if (unformat (i, "tapname %s", &tap_name))
7963         name_set = 1;
7964       else
7965         break;
7966     }
7967
7968   if (sw_if_index_set == 0)
7969     {
7970       errmsg ("missing vpp interface name");
7971       return -99;
7972     }
7973   if (name_set == 0)
7974     {
7975       errmsg ("missing tap name");
7976       return -99;
7977     }
7978   if (vec_len (tap_name) > 63)
7979     {
7980       errmsg ("tap name too long");
7981     }
7982   vec_add1 (tap_name, 0);
7983
7984   /* Construct the API message */
7985   M (TAP_MODIFY, mp);
7986
7987   mp->use_random_mac = random_mac;
7988   mp->sw_if_index = ntohl (sw_if_index);
7989   clib_memcpy (mp->mac_address, mac_address, 6);
7990   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7991   vec_free (tap_name);
7992
7993   /* send it... */
7994   S (mp);
7995
7996   /* Wait for a reply... */
7997   W (ret);
7998   return ret;
7999 }
8000
8001 static int
8002 api_tap_delete (vat_main_t * vam)
8003 {
8004   unformat_input_t *i = vam->input;
8005   vl_api_tap_delete_t *mp;
8006   u32 sw_if_index = ~0;
8007   u8 sw_if_index_set = 0;
8008   int ret;
8009
8010   /* Parse args required to build the message */
8011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8012     {
8013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8014         sw_if_index_set = 1;
8015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8016         sw_if_index_set = 1;
8017       else
8018         break;
8019     }
8020
8021   if (sw_if_index_set == 0)
8022     {
8023       errmsg ("missing vpp interface name");
8024       return -99;
8025     }
8026
8027   /* Construct the API message */
8028   M (TAP_DELETE, mp);
8029
8030   mp->sw_if_index = ntohl (sw_if_index);
8031
8032   /* send it... */
8033   S (mp);
8034
8035   /* Wait for a reply... */
8036   W (ret);
8037   return ret;
8038 }
8039
8040 static int
8041 api_tap_create_v2 (vat_main_t * vam)
8042 {
8043   unformat_input_t *i = vam->input;
8044   vl_api_tap_create_v2_t *mp;
8045   u8 mac_address[6];
8046   u8 random_mac = 1;
8047   u32 id = ~0;
8048   u8 *host_if_name = 0;
8049   u8 *host_ns = 0;
8050   u8 host_mac_addr[6];
8051   u8 host_mac_addr_set = 0;
8052   u8 *host_bridge = 0;
8053   ip4_address_t host_ip4_addr;
8054   ip4_address_t host_ip4_gw;
8055   u8 host_ip4_gw_set = 0;
8056   u32 host_ip4_prefix_len = 0;
8057   ip6_address_t host_ip6_addr;
8058   ip6_address_t host_ip6_gw;
8059   u8 host_ip6_gw_set = 0;
8060   u32 host_ip6_prefix_len = 0;
8061   int ret;
8062   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8063
8064   memset (mac_address, 0, sizeof (mac_address));
8065
8066   /* Parse args required to build the message */
8067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8070         {
8071           random_mac = 0;
8072         }
8073       else if (unformat (i, "id %u", &id))
8074         ;
8075       else if (unformat (i, "host-if-name %s", &host_if_name))
8076         ;
8077       else if (unformat (i, "host-ns %s", &host_ns))
8078         ;
8079       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8080                          host_mac_addr))
8081         host_mac_addr_set = 1;
8082       else if (unformat (i, "host-bridge %s", &host_bridge))
8083         ;
8084       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8085                          &host_ip4_addr, &host_ip4_prefix_len))
8086         ;
8087       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8088                          &host_ip6_addr, &host_ip6_prefix_len))
8089         ;
8090       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8091                          &host_ip4_gw))
8092         host_ip4_gw_set = 1;
8093       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8094                          &host_ip6_gw))
8095         host_ip6_gw_set = 1;
8096       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8097         ;
8098       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8099         ;
8100       else
8101         break;
8102     }
8103
8104   if (vec_len (host_if_name) > 63)
8105     {
8106       errmsg ("tap name too long. ");
8107       return -99;
8108     }
8109   if (vec_len (host_ns) > 63)
8110     {
8111       errmsg ("host name space too long. ");
8112       return -99;
8113     }
8114   if (vec_len (host_bridge) > 63)
8115     {
8116       errmsg ("host bridge name too long. ");
8117       return -99;
8118     }
8119   if (host_ip4_prefix_len > 32)
8120     {
8121       errmsg ("host ip4 prefix length not valid. ");
8122       return -99;
8123     }
8124   if (host_ip6_prefix_len > 128)
8125     {
8126       errmsg ("host ip6 prefix length not valid. ");
8127       return -99;
8128     }
8129   if (!is_pow2 (rx_ring_sz))
8130     {
8131       errmsg ("rx ring size must be power of 2. ");
8132       return -99;
8133     }
8134   if (rx_ring_sz > 32768)
8135     {
8136       errmsg ("rx ring size must be 32768 or lower. ");
8137       return -99;
8138     }
8139   if (!is_pow2 (tx_ring_sz))
8140     {
8141       errmsg ("tx ring size must be power of 2. ");
8142       return -99;
8143     }
8144   if (tx_ring_sz > 32768)
8145     {
8146       errmsg ("tx ring size must be 32768 or lower. ");
8147       return -99;
8148     }
8149
8150   /* Construct the API message */
8151   M (TAP_CREATE_V2, mp);
8152
8153   mp->use_random_mac = random_mac;
8154
8155   mp->id = ntohl (id);
8156   mp->host_namespace_set = host_ns != 0;
8157   mp->host_bridge_set = host_bridge != 0;
8158   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8159   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8160   mp->rx_ring_sz = ntohs (rx_ring_sz);
8161   mp->tx_ring_sz = ntohs (tx_ring_sz);
8162
8163   if (random_mac == 0)
8164     clib_memcpy (mp->mac_address, mac_address, 6);
8165   if (host_mac_addr_set)
8166     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8167   if (host_if_name)
8168     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8169   if (host_ns)
8170     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8171   if (host_bridge)
8172     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8173   if (host_ip4_prefix_len)
8174     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8175   if (host_ip4_prefix_len)
8176     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8177   if (host_ip4_gw_set)
8178     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8179   if (host_ip6_gw_set)
8180     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8181
8182   vec_free (host_ns);
8183   vec_free (host_if_name);
8184   vec_free (host_bridge);
8185
8186   /* send it... */
8187   S (mp);
8188
8189   /* Wait for a reply... */
8190   W (ret);
8191   return ret;
8192 }
8193
8194 static int
8195 api_tap_delete_v2 (vat_main_t * vam)
8196 {
8197   unformat_input_t *i = vam->input;
8198   vl_api_tap_delete_v2_t *mp;
8199   u32 sw_if_index = ~0;
8200   u8 sw_if_index_set = 0;
8201   int ret;
8202
8203   /* Parse args required to build the message */
8204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8205     {
8206       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8207         sw_if_index_set = 1;
8208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8209         sw_if_index_set = 1;
8210       else
8211         break;
8212     }
8213
8214   if (sw_if_index_set == 0)
8215     {
8216       errmsg ("missing vpp interface name. ");
8217       return -99;
8218     }
8219
8220   /* Construct the API message */
8221   M (TAP_DELETE_V2, mp);
8222
8223   mp->sw_if_index = ntohl (sw_if_index);
8224
8225   /* send it... */
8226   S (mp);
8227
8228   /* Wait for a reply... */
8229   W (ret);
8230   return ret;
8231 }
8232
8233 static int
8234 api_bond_create (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_bond_create_t *mp;
8238   u8 mac_address[6];
8239   u8 custom_mac = 0;
8240   int ret;
8241   u8 mode;
8242   u8 lb;
8243   u8 mode_is_set = 0;
8244
8245   memset (mac_address, 0, sizeof (mac_address));
8246   lb = BOND_LB_L2;
8247
8248   /* Parse args required to build the message */
8249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8250     {
8251       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8252         mode_is_set = 1;
8253       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8254                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8255         ;
8256       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8257                          mac_address))
8258         custom_mac = 1;
8259       else
8260         break;
8261     }
8262
8263   if (mode_is_set == 0)
8264     {
8265       errmsg ("Missing bond mode. ");
8266       return -99;
8267     }
8268
8269   /* Construct the API message */
8270   M (BOND_CREATE, mp);
8271
8272   mp->use_custom_mac = custom_mac;
8273
8274   mp->mode = mode;
8275   mp->lb = lb;
8276
8277   if (custom_mac)
8278     clib_memcpy (mp->mac_address, mac_address, 6);
8279
8280   /* send it... */
8281   S (mp);
8282
8283   /* Wait for a reply... */
8284   W (ret);
8285   return ret;
8286 }
8287
8288 static int
8289 api_bond_delete (vat_main_t * vam)
8290 {
8291   unformat_input_t *i = vam->input;
8292   vl_api_bond_delete_t *mp;
8293   u32 sw_if_index = ~0;
8294   u8 sw_if_index_set = 0;
8295   int ret;
8296
8297   /* Parse args required to build the message */
8298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8299     {
8300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8301         sw_if_index_set = 1;
8302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8303         sw_if_index_set = 1;
8304       else
8305         break;
8306     }
8307
8308   if (sw_if_index_set == 0)
8309     {
8310       errmsg ("missing vpp interface name. ");
8311       return -99;
8312     }
8313
8314   /* Construct the API message */
8315   M (BOND_DELETE, mp);
8316
8317   mp->sw_if_index = ntohl (sw_if_index);
8318
8319   /* send it... */
8320   S (mp);
8321
8322   /* Wait for a reply... */
8323   W (ret);
8324   return ret;
8325 }
8326
8327 static int
8328 api_bond_enslave (vat_main_t * vam)
8329 {
8330   unformat_input_t *i = vam->input;
8331   vl_api_bond_enslave_t *mp;
8332   u32 bond_sw_if_index;
8333   int ret;
8334   u8 is_passive;
8335   u8 is_long_timeout;
8336   u32 bond_sw_if_index_is_set = 0;
8337   u32 sw_if_index;
8338   u8 sw_if_index_is_set = 0;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "sw_if_index %d", &sw_if_index))
8344         sw_if_index_is_set = 1;
8345       else if (unformat (i, "bond %u", &bond_sw_if_index))
8346         bond_sw_if_index_is_set = 1;
8347       else if (unformat (i, "passive %d", &is_passive))
8348         ;
8349       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8350         ;
8351       else
8352         break;
8353     }
8354
8355   if (bond_sw_if_index_is_set == 0)
8356     {
8357       errmsg ("Missing bond sw_if_index. ");
8358       return -99;
8359     }
8360   if (sw_if_index_is_set == 0)
8361     {
8362       errmsg ("Missing slave sw_if_index. ");
8363       return -99;
8364     }
8365
8366   /* Construct the API message */
8367   M (BOND_ENSLAVE, mp);
8368
8369   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8370   mp->sw_if_index = ntohl (sw_if_index);
8371   mp->is_long_timeout = is_long_timeout;
8372   mp->is_passive = is_passive;
8373
8374   /* send it... */
8375   S (mp);
8376
8377   /* Wait for a reply... */
8378   W (ret);
8379   return ret;
8380 }
8381
8382 static int
8383 api_bond_detach_slave (vat_main_t * vam)
8384 {
8385   unformat_input_t *i = vam->input;
8386   vl_api_bond_detach_slave_t *mp;
8387   u32 sw_if_index = ~0;
8388   u8 sw_if_index_set = 0;
8389   int ret;
8390
8391   /* Parse args required to build the message */
8392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8393     {
8394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8395         sw_if_index_set = 1;
8396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8397         sw_if_index_set = 1;
8398       else
8399         break;
8400     }
8401
8402   if (sw_if_index_set == 0)
8403     {
8404       errmsg ("missing vpp interface name. ");
8405       return -99;
8406     }
8407
8408   /* Construct the API message */
8409   M (BOND_DETACH_SLAVE, mp);
8410
8411   mp->sw_if_index = ntohl (sw_if_index);
8412
8413   /* send it... */
8414   S (mp);
8415
8416   /* Wait for a reply... */
8417   W (ret);
8418   return ret;
8419 }
8420
8421 static int
8422 api_ip_table_add_del (vat_main_t * vam)
8423 {
8424   unformat_input_t *i = vam->input;
8425   vl_api_ip_table_add_del_t *mp;
8426   u32 table_id = ~0;
8427   u8 is_ipv6 = 0;
8428   u8 is_add = 1;
8429   int ret = 0;
8430
8431   /* Parse args required to build the message */
8432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8433     {
8434       if (unformat (i, "ipv6"))
8435         is_ipv6 = 1;
8436       else if (unformat (i, "del"))
8437         is_add = 0;
8438       else if (unformat (i, "add"))
8439         is_add = 1;
8440       else if (unformat (i, "table %d", &table_id))
8441         ;
8442       else
8443         {
8444           clib_warning ("parse error '%U'", format_unformat_error, i);
8445           return -99;
8446         }
8447     }
8448
8449   if (~0 == table_id)
8450     {
8451       errmsg ("missing table-ID");
8452       return -99;
8453     }
8454
8455   /* Construct the API message */
8456   M (IP_TABLE_ADD_DEL, mp);
8457
8458   mp->table_id = ntohl (table_id);
8459   mp->is_ipv6 = is_ipv6;
8460   mp->is_add = is_add;
8461
8462   /* send it... */
8463   S (mp);
8464
8465   /* Wait for a reply... */
8466   W (ret);
8467
8468   return ret;
8469 }
8470
8471 static int
8472 api_ip_add_del_route (vat_main_t * vam)
8473 {
8474   unformat_input_t *i = vam->input;
8475   vl_api_ip_add_del_route_t *mp;
8476   u32 sw_if_index = ~0, vrf_id = 0;
8477   u8 is_ipv6 = 0;
8478   u8 is_local = 0, is_drop = 0;
8479   u8 is_unreach = 0, is_prohibit = 0;
8480   u8 is_add = 1;
8481   u32 next_hop_weight = 1;
8482   u8 is_multipath = 0;
8483   u8 address_set = 0;
8484   u8 address_length_set = 0;
8485   u32 next_hop_table_id = 0;
8486   u32 resolve_attempts = 0;
8487   u32 dst_address_length = 0;
8488   u8 next_hop_set = 0;
8489   ip4_address_t v4_dst_address, v4_next_hop_address;
8490   ip6_address_t v6_dst_address, v6_next_hop_address;
8491   int count = 1;
8492   int j;
8493   f64 before = 0;
8494   u32 random_add_del = 0;
8495   u32 *random_vector = 0;
8496   uword *random_hash;
8497   u32 random_seed = 0xdeaddabe;
8498   u32 classify_table_index = ~0;
8499   u8 is_classify = 0;
8500   u8 resolve_host = 0, resolve_attached = 0;
8501   mpls_label_t *next_hop_out_label_stack = NULL;
8502   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8503   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8504
8505   /* Parse args required to build the message */
8506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8509         ;
8510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8511         ;
8512       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8513         {
8514           address_set = 1;
8515           is_ipv6 = 0;
8516         }
8517       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8518         {
8519           address_set = 1;
8520           is_ipv6 = 1;
8521         }
8522       else if (unformat (i, "/%d", &dst_address_length))
8523         {
8524           address_length_set = 1;
8525         }
8526
8527       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8528                                          &v4_next_hop_address))
8529         {
8530           next_hop_set = 1;
8531         }
8532       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8533                                          &v6_next_hop_address))
8534         {
8535           next_hop_set = 1;
8536         }
8537       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8538         ;
8539       else if (unformat (i, "weight %d", &next_hop_weight))
8540         ;
8541       else if (unformat (i, "drop"))
8542         {
8543           is_drop = 1;
8544         }
8545       else if (unformat (i, "null-send-unreach"))
8546         {
8547           is_unreach = 1;
8548         }
8549       else if (unformat (i, "null-send-prohibit"))
8550         {
8551           is_prohibit = 1;
8552         }
8553       else if (unformat (i, "local"))
8554         {
8555           is_local = 1;
8556         }
8557       else if (unformat (i, "classify %d", &classify_table_index))
8558         {
8559           is_classify = 1;
8560         }
8561       else if (unformat (i, "del"))
8562         is_add = 0;
8563       else if (unformat (i, "add"))
8564         is_add = 1;
8565       else if (unformat (i, "resolve-via-host"))
8566         resolve_host = 1;
8567       else if (unformat (i, "resolve-via-attached"))
8568         resolve_attached = 1;
8569       else if (unformat (i, "multipath"))
8570         is_multipath = 1;
8571       else if (unformat (i, "vrf %d", &vrf_id))
8572         ;
8573       else if (unformat (i, "count %d", &count))
8574         ;
8575       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8576         ;
8577       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8578         ;
8579       else if (unformat (i, "out-label %d", &next_hop_out_label))
8580         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8581       else if (unformat (i, "via-label %d", &next_hop_via_label))
8582         ;
8583       else if (unformat (i, "random"))
8584         random_add_del = 1;
8585       else if (unformat (i, "seed %d", &random_seed))
8586         ;
8587       else
8588         {
8589           clib_warning ("parse error '%U'", format_unformat_error, i);
8590           return -99;
8591         }
8592     }
8593
8594   if (!next_hop_set && !is_drop && !is_local &&
8595       !is_classify && !is_unreach && !is_prohibit &&
8596       MPLS_LABEL_INVALID == next_hop_via_label)
8597     {
8598       errmsg
8599         ("next hop / local / drop / unreach / prohibit / classify not set");
8600       return -99;
8601     }
8602
8603   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8604     {
8605       errmsg ("next hop and next-hop via label set");
8606       return -99;
8607     }
8608   if (address_set == 0)
8609     {
8610       errmsg ("missing addresses");
8611       return -99;
8612     }
8613
8614   if (address_length_set == 0)
8615     {
8616       errmsg ("missing address length");
8617       return -99;
8618     }
8619
8620   /* Generate a pile of unique, random routes */
8621   if (random_add_del)
8622     {
8623       u32 this_random_address;
8624       random_hash = hash_create (count, sizeof (uword));
8625
8626       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8627       for (j = 0; j <= count; j++)
8628         {
8629           do
8630             {
8631               this_random_address = random_u32 (&random_seed);
8632               this_random_address =
8633                 clib_host_to_net_u32 (this_random_address);
8634             }
8635           while (hash_get (random_hash, this_random_address));
8636           vec_add1 (random_vector, this_random_address);
8637           hash_set (random_hash, this_random_address, 1);
8638         }
8639       hash_free (random_hash);
8640       v4_dst_address.as_u32 = random_vector[0];
8641     }
8642
8643   if (count > 1)
8644     {
8645       /* Turn on async mode */
8646       vam->async_mode = 1;
8647       vam->async_errors = 0;
8648       before = vat_time_now (vam);
8649     }
8650
8651   for (j = 0; j < count; j++)
8652     {
8653       /* Construct the API message */
8654       M2 (IP_ADD_DEL_ROUTE, mp,
8655           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8656
8657       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8658       mp->table_id = ntohl (vrf_id);
8659
8660       mp->is_add = is_add;
8661       mp->is_drop = is_drop;
8662       mp->is_unreach = is_unreach;
8663       mp->is_prohibit = is_prohibit;
8664       mp->is_ipv6 = is_ipv6;
8665       mp->is_local = is_local;
8666       mp->is_classify = is_classify;
8667       mp->is_multipath = is_multipath;
8668       mp->is_resolve_host = resolve_host;
8669       mp->is_resolve_attached = resolve_attached;
8670       mp->next_hop_weight = next_hop_weight;
8671       mp->dst_address_length = dst_address_length;
8672       mp->next_hop_table_id = ntohl (next_hop_table_id);
8673       mp->classify_table_index = ntohl (classify_table_index);
8674       mp->next_hop_via_label = ntohl (next_hop_via_label);
8675       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8676       if (0 != mp->next_hop_n_out_labels)
8677         {
8678           memcpy (mp->next_hop_out_label_stack,
8679                   next_hop_out_label_stack,
8680                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8681           vec_free (next_hop_out_label_stack);
8682         }
8683
8684       if (is_ipv6)
8685         {
8686           clib_memcpy (mp->dst_address, &v6_dst_address,
8687                        sizeof (v6_dst_address));
8688           if (next_hop_set)
8689             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8690                          sizeof (v6_next_hop_address));
8691           increment_v6_address (&v6_dst_address);
8692         }
8693       else
8694         {
8695           clib_memcpy (mp->dst_address, &v4_dst_address,
8696                        sizeof (v4_dst_address));
8697           if (next_hop_set)
8698             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8699                          sizeof (v4_next_hop_address));
8700           if (random_add_del)
8701             v4_dst_address.as_u32 = random_vector[j + 1];
8702           else
8703             increment_v4_address (&v4_dst_address);
8704         }
8705       /* send it... */
8706       S (mp);
8707       /* If we receive SIGTERM, stop now... */
8708       if (vam->do_exit)
8709         break;
8710     }
8711
8712   /* When testing multiple add/del ops, use a control-ping to sync */
8713   if (count > 1)
8714     {
8715       vl_api_control_ping_t *mp_ping;
8716       f64 after;
8717       f64 timeout;
8718
8719       /* Shut off async mode */
8720       vam->async_mode = 0;
8721
8722       MPING (CONTROL_PING, mp_ping);
8723       S (mp_ping);
8724
8725       timeout = vat_time_now (vam) + 1.0;
8726       while (vat_time_now (vam) < timeout)
8727         if (vam->result_ready == 1)
8728           goto out;
8729       vam->retval = -99;
8730
8731     out:
8732       if (vam->retval == -99)
8733         errmsg ("timeout");
8734
8735       if (vam->async_errors > 0)
8736         {
8737           errmsg ("%d asynchronous errors", vam->async_errors);
8738           vam->retval = -98;
8739         }
8740       vam->async_errors = 0;
8741       after = vat_time_now (vam);
8742
8743       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8744       if (j > 0)
8745         count = j;
8746
8747       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8748              count, after - before, count / (after - before));
8749     }
8750   else
8751     {
8752       int ret;
8753
8754       /* Wait for a reply... */
8755       W (ret);
8756       return ret;
8757     }
8758
8759   /* Return the good/bad news */
8760   return (vam->retval);
8761 }
8762
8763 static int
8764 api_ip_mroute_add_del (vat_main_t * vam)
8765 {
8766   unformat_input_t *i = vam->input;
8767   vl_api_ip_mroute_add_del_t *mp;
8768   u32 sw_if_index = ~0, vrf_id = 0;
8769   u8 is_ipv6 = 0;
8770   u8 is_local = 0;
8771   u8 is_add = 1;
8772   u8 address_set = 0;
8773   u32 grp_address_length = 0;
8774   ip4_address_t v4_grp_address, v4_src_address;
8775   ip6_address_t v6_grp_address, v6_src_address;
8776   mfib_itf_flags_t iflags = 0;
8777   mfib_entry_flags_t eflags = 0;
8778   int ret;
8779
8780   /* Parse args required to build the message */
8781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8782     {
8783       if (unformat (i, "sw_if_index %d", &sw_if_index))
8784         ;
8785       else if (unformat (i, "%U %U",
8786                          unformat_ip4_address, &v4_src_address,
8787                          unformat_ip4_address, &v4_grp_address))
8788         {
8789           grp_address_length = 64;
8790           address_set = 1;
8791           is_ipv6 = 0;
8792         }
8793       else if (unformat (i, "%U %U",
8794                          unformat_ip6_address, &v6_src_address,
8795                          unformat_ip6_address, &v6_grp_address))
8796         {
8797           grp_address_length = 256;
8798           address_set = 1;
8799           is_ipv6 = 1;
8800         }
8801       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8802         {
8803           memset (&v4_src_address, 0, sizeof (v4_src_address));
8804           grp_address_length = 32;
8805           address_set = 1;
8806           is_ipv6 = 0;
8807         }
8808       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8809         {
8810           memset (&v6_src_address, 0, sizeof (v6_src_address));
8811           grp_address_length = 128;
8812           address_set = 1;
8813           is_ipv6 = 1;
8814         }
8815       else if (unformat (i, "/%d", &grp_address_length))
8816         ;
8817       else if (unformat (i, "local"))
8818         {
8819           is_local = 1;
8820         }
8821       else if (unformat (i, "del"))
8822         is_add = 0;
8823       else if (unformat (i, "add"))
8824         is_add = 1;
8825       else if (unformat (i, "vrf %d", &vrf_id))
8826         ;
8827       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8828         ;
8829       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8830         ;
8831       else
8832         {
8833           clib_warning ("parse error '%U'", format_unformat_error, i);
8834           return -99;
8835         }
8836     }
8837
8838   if (address_set == 0)
8839     {
8840       errmsg ("missing addresses\n");
8841       return -99;
8842     }
8843
8844   /* Construct the API message */
8845   M (IP_MROUTE_ADD_DEL, mp);
8846
8847   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8848   mp->table_id = ntohl (vrf_id);
8849
8850   mp->is_add = is_add;
8851   mp->is_ipv6 = is_ipv6;
8852   mp->is_local = is_local;
8853   mp->itf_flags = ntohl (iflags);
8854   mp->entry_flags = ntohl (eflags);
8855   mp->grp_address_length = grp_address_length;
8856   mp->grp_address_length = ntohs (mp->grp_address_length);
8857
8858   if (is_ipv6)
8859     {
8860       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8861       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8862     }
8863   else
8864     {
8865       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8866       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8867
8868     }
8869
8870   /* send it... */
8871   S (mp);
8872   /* Wait for a reply... */
8873   W (ret);
8874   return ret;
8875 }
8876
8877 static int
8878 api_mpls_table_add_del (vat_main_t * vam)
8879 {
8880   unformat_input_t *i = vam->input;
8881   vl_api_mpls_table_add_del_t *mp;
8882   u32 table_id = ~0;
8883   u8 is_add = 1;
8884   int ret = 0;
8885
8886   /* Parse args required to build the message */
8887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (i, "table %d", &table_id))
8890         ;
8891       else if (unformat (i, "del"))
8892         is_add = 0;
8893       else if (unformat (i, "add"))
8894         is_add = 1;
8895       else
8896         {
8897           clib_warning ("parse error '%U'", format_unformat_error, i);
8898           return -99;
8899         }
8900     }
8901
8902   if (~0 == table_id)
8903     {
8904       errmsg ("missing table-ID");
8905       return -99;
8906     }
8907
8908   /* Construct the API message */
8909   M (MPLS_TABLE_ADD_DEL, mp);
8910
8911   mp->mt_table_id = ntohl (table_id);
8912   mp->mt_is_add = is_add;
8913
8914   /* send it... */
8915   S (mp);
8916
8917   /* Wait for a reply... */
8918   W (ret);
8919
8920   return ret;
8921 }
8922
8923 static int
8924 api_mpls_route_add_del (vat_main_t * vam)
8925 {
8926   unformat_input_t *i = vam->input;
8927   vl_api_mpls_route_add_del_t *mp;
8928   u32 sw_if_index = ~0, table_id = 0;
8929   u8 is_add = 1;
8930   u32 next_hop_weight = 1;
8931   u8 is_multipath = 0;
8932   u32 next_hop_table_id = 0;
8933   u8 next_hop_set = 0;
8934   ip4_address_t v4_next_hop_address = {
8935     .as_u32 = 0,
8936   };
8937   ip6_address_t v6_next_hop_address = { {0} };
8938   int count = 1;
8939   int j;
8940   f64 before = 0;
8941   u32 classify_table_index = ~0;
8942   u8 is_classify = 0;
8943   u8 resolve_host = 0, resolve_attached = 0;
8944   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8945   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8946   mpls_label_t *next_hop_out_label_stack = NULL;
8947   mpls_label_t local_label = MPLS_LABEL_INVALID;
8948   u8 is_eos = 0;
8949   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8950
8951   /* Parse args required to build the message */
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8955         ;
8956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8957         ;
8958       else if (unformat (i, "%d", &local_label))
8959         ;
8960       else if (unformat (i, "eos"))
8961         is_eos = 1;
8962       else if (unformat (i, "non-eos"))
8963         is_eos = 0;
8964       else if (unformat (i, "via %U", unformat_ip4_address,
8965                          &v4_next_hop_address))
8966         {
8967           next_hop_set = 1;
8968           next_hop_proto = DPO_PROTO_IP4;
8969         }
8970       else if (unformat (i, "via %U", unformat_ip6_address,
8971                          &v6_next_hop_address))
8972         {
8973           next_hop_set = 1;
8974           next_hop_proto = DPO_PROTO_IP6;
8975         }
8976       else if (unformat (i, "weight %d", &next_hop_weight))
8977         ;
8978       else if (unformat (i, "classify %d", &classify_table_index))
8979         {
8980           is_classify = 1;
8981         }
8982       else if (unformat (i, "del"))
8983         is_add = 0;
8984       else if (unformat (i, "add"))
8985         is_add = 1;
8986       else if (unformat (i, "resolve-via-host"))
8987         resolve_host = 1;
8988       else if (unformat (i, "resolve-via-attached"))
8989         resolve_attached = 1;
8990       else if (unformat (i, "multipath"))
8991         is_multipath = 1;
8992       else if (unformat (i, "count %d", &count))
8993         ;
8994       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8995         {
8996           next_hop_set = 1;
8997           next_hop_proto = DPO_PROTO_IP4;
8998         }
8999       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
9000         {
9001           next_hop_set = 1;
9002           next_hop_proto = DPO_PROTO_IP6;
9003         }
9004       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9005         ;
9006       else if (unformat (i, "via-label %d", &next_hop_via_label))
9007         ;
9008       else if (unformat (i, "out-label %d", &next_hop_out_label))
9009         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
9010       else
9011         {
9012           clib_warning ("parse error '%U'", format_unformat_error, i);
9013           return -99;
9014         }
9015     }
9016
9017   if (!next_hop_set && !is_classify)
9018     {
9019       errmsg ("next hop / classify not set");
9020       return -99;
9021     }
9022
9023   if (MPLS_LABEL_INVALID == local_label)
9024     {
9025       errmsg ("missing label");
9026       return -99;
9027     }
9028
9029   if (count > 1)
9030     {
9031       /* Turn on async mode */
9032       vam->async_mode = 1;
9033       vam->async_errors = 0;
9034       before = vat_time_now (vam);
9035     }
9036
9037   for (j = 0; j < count; j++)
9038     {
9039       /* Construct the API message */
9040       M2 (MPLS_ROUTE_ADD_DEL, mp,
9041           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
9042
9043       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9044       mp->mr_table_id = ntohl (table_id);
9045
9046       mp->mr_is_add = is_add;
9047       mp->mr_next_hop_proto = next_hop_proto;
9048       mp->mr_is_classify = is_classify;
9049       mp->mr_is_multipath = is_multipath;
9050       mp->mr_is_resolve_host = resolve_host;
9051       mp->mr_is_resolve_attached = resolve_attached;
9052       mp->mr_next_hop_weight = next_hop_weight;
9053       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9054       mp->mr_classify_table_index = ntohl (classify_table_index);
9055       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9056       mp->mr_label = ntohl (local_label);
9057       mp->mr_eos = is_eos;
9058
9059       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9060       if (0 != mp->mr_next_hop_n_out_labels)
9061         {
9062           memcpy (mp->mr_next_hop_out_label_stack,
9063                   next_hop_out_label_stack,
9064                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
9065           vec_free (next_hop_out_label_stack);
9066         }
9067
9068       if (next_hop_set)
9069         {
9070           if (DPO_PROTO_IP4 == next_hop_proto)
9071             {
9072               clib_memcpy (mp->mr_next_hop,
9073                            &v4_next_hop_address,
9074                            sizeof (v4_next_hop_address));
9075             }
9076           else if (DPO_PROTO_IP6 == next_hop_proto)
9077
9078             {
9079               clib_memcpy (mp->mr_next_hop,
9080                            &v6_next_hop_address,
9081                            sizeof (v6_next_hop_address));
9082             }
9083         }
9084       local_label++;
9085
9086       /* send it... */
9087       S (mp);
9088       /* If we receive SIGTERM, stop now... */
9089       if (vam->do_exit)
9090         break;
9091     }
9092
9093   /* When testing multiple add/del ops, use a control-ping to sync */
9094   if (count > 1)
9095     {
9096       vl_api_control_ping_t *mp_ping;
9097       f64 after;
9098       f64 timeout;
9099
9100       /* Shut off async mode */
9101       vam->async_mode = 0;
9102
9103       MPING (CONTROL_PING, mp_ping);
9104       S (mp_ping);
9105
9106       timeout = vat_time_now (vam) + 1.0;
9107       while (vat_time_now (vam) < timeout)
9108         if (vam->result_ready == 1)
9109           goto out;
9110       vam->retval = -99;
9111
9112     out:
9113       if (vam->retval == -99)
9114         errmsg ("timeout");
9115
9116       if (vam->async_errors > 0)
9117         {
9118           errmsg ("%d asynchronous errors", vam->async_errors);
9119           vam->retval = -98;
9120         }
9121       vam->async_errors = 0;
9122       after = vat_time_now (vam);
9123
9124       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9125       if (j > 0)
9126         count = j;
9127
9128       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9129              count, after - before, count / (after - before));
9130     }
9131   else
9132     {
9133       int ret;
9134
9135       /* Wait for a reply... */
9136       W (ret);
9137       return ret;
9138     }
9139
9140   /* Return the good/bad news */
9141   return (vam->retval);
9142 }
9143
9144 static int
9145 api_mpls_ip_bind_unbind (vat_main_t * vam)
9146 {
9147   unformat_input_t *i = vam->input;
9148   vl_api_mpls_ip_bind_unbind_t *mp;
9149   u32 ip_table_id = 0;
9150   u8 is_bind = 1;
9151   u8 is_ip4 = 1;
9152   ip4_address_t v4_address;
9153   ip6_address_t v6_address;
9154   u32 address_length;
9155   u8 address_set = 0;
9156   mpls_label_t local_label = MPLS_LABEL_INVALID;
9157   int ret;
9158
9159   /* Parse args required to build the message */
9160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9161     {
9162       if (unformat (i, "%U/%d", unformat_ip4_address,
9163                     &v4_address, &address_length))
9164         {
9165           is_ip4 = 1;
9166           address_set = 1;
9167         }
9168       else if (unformat (i, "%U/%d", unformat_ip6_address,
9169                          &v6_address, &address_length))
9170         {
9171           is_ip4 = 0;
9172           address_set = 1;
9173         }
9174       else if (unformat (i, "%d", &local_label))
9175         ;
9176       else if (unformat (i, "table-id %d", &ip_table_id))
9177         ;
9178       else if (unformat (i, "unbind"))
9179         is_bind = 0;
9180       else if (unformat (i, "bind"))
9181         is_bind = 1;
9182       else
9183         {
9184           clib_warning ("parse error '%U'", format_unformat_error, i);
9185           return -99;
9186         }
9187     }
9188
9189   if (!address_set)
9190     {
9191       errmsg ("IP addres not set");
9192       return -99;
9193     }
9194
9195   if (MPLS_LABEL_INVALID == local_label)
9196     {
9197       errmsg ("missing label");
9198       return -99;
9199     }
9200
9201   /* Construct the API message */
9202   M (MPLS_IP_BIND_UNBIND, mp);
9203
9204   mp->mb_is_bind = is_bind;
9205   mp->mb_is_ip4 = is_ip4;
9206   mp->mb_ip_table_id = ntohl (ip_table_id);
9207   mp->mb_mpls_table_id = 0;
9208   mp->mb_label = ntohl (local_label);
9209   mp->mb_address_length = address_length;
9210
9211   if (is_ip4)
9212     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9213   else
9214     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9215
9216   /* send it... */
9217   S (mp);
9218
9219   /* Wait for a reply... */
9220   W (ret);
9221   return ret;
9222 }
9223
9224 static int
9225 api_bier_table_add_del (vat_main_t * vam)
9226 {
9227   unformat_input_t *i = vam->input;
9228   vl_api_bier_table_add_del_t *mp;
9229   u8 is_add = 1;
9230   u32 set = 0, sub_domain = 0, hdr_len = 3;
9231   mpls_label_t local_label = MPLS_LABEL_INVALID;
9232   int ret;
9233
9234   /* Parse args required to build the message */
9235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9236     {
9237       if (unformat (i, "sub-domain %d", &sub_domain))
9238         ;
9239       else if (unformat (i, "set %d", &set))
9240         ;
9241       else if (unformat (i, "label %d", &local_label))
9242         ;
9243       else if (unformat (i, "hdr-len %d", &hdr_len))
9244         ;
9245       else if (unformat (i, "add"))
9246         is_add = 1;
9247       else if (unformat (i, "del"))
9248         is_add = 0;
9249       else
9250         {
9251           clib_warning ("parse error '%U'", format_unformat_error, i);
9252           return -99;
9253         }
9254     }
9255
9256   if (MPLS_LABEL_INVALID == local_label)
9257     {
9258       errmsg ("missing label\n");
9259       return -99;
9260     }
9261
9262   /* Construct the API message */
9263   M (BIER_TABLE_ADD_DEL, mp);
9264
9265   mp->bt_is_add = is_add;
9266   mp->bt_label = ntohl (local_label);
9267   mp->bt_tbl_id.bt_set = set;
9268   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9269   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9270
9271   /* send it... */
9272   S (mp);
9273
9274   /* Wait for a reply... */
9275   W (ret);
9276
9277   return (ret);
9278 }
9279
9280 static int
9281 api_bier_route_add_del (vat_main_t * vam)
9282 {
9283   unformat_input_t *i = vam->input;
9284   vl_api_bier_route_add_del_t *mp;
9285   u8 is_add = 1;
9286   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9287   ip4_address_t v4_next_hop_address;
9288   ip6_address_t v6_next_hop_address;
9289   u8 next_hop_set = 0;
9290   u8 next_hop_proto_is_ip4 = 1;
9291   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9292   int ret;
9293
9294   /* Parse args required to build the message */
9295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9296     {
9297       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9298         {
9299           next_hop_proto_is_ip4 = 1;
9300           next_hop_set = 1;
9301         }
9302       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9303         {
9304           next_hop_proto_is_ip4 = 0;
9305           next_hop_set = 1;
9306         }
9307       if (unformat (i, "sub-domain %d", &sub_domain))
9308         ;
9309       else if (unformat (i, "set %d", &set))
9310         ;
9311       else if (unformat (i, "hdr-len %d", &hdr_len))
9312         ;
9313       else if (unformat (i, "bp %d", &bp))
9314         ;
9315       else if (unformat (i, "add"))
9316         is_add = 1;
9317       else if (unformat (i, "del"))
9318         is_add = 0;
9319       else if (unformat (i, "out-label %d", &next_hop_out_label))
9320         ;
9321       else
9322         {
9323           clib_warning ("parse error '%U'", format_unformat_error, i);
9324           return -99;
9325         }
9326     }
9327
9328   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9329     {
9330       errmsg ("next hop / label set\n");
9331       return -99;
9332     }
9333   if (0 == bp)
9334     {
9335       errmsg ("bit=position not set\n");
9336       return -99;
9337     }
9338
9339   /* Construct the API message */
9340   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9341
9342   mp->br_is_add = is_add;
9343   mp->br_tbl_id.bt_set = set;
9344   mp->br_tbl_id.bt_sub_domain = sub_domain;
9345   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9346   mp->br_bp = ntohs (bp);
9347   mp->br_n_paths = 1;
9348   mp->br_paths[0].n_labels = 1;
9349   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9350   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9351
9352   if (next_hop_proto_is_ip4)
9353     {
9354       clib_memcpy (mp->br_paths[0].next_hop,
9355                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9356     }
9357   else
9358     {
9359       clib_memcpy (mp->br_paths[0].next_hop,
9360                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9361     }
9362
9363   /* send it... */
9364   S (mp);
9365
9366   /* Wait for a reply... */
9367   W (ret);
9368
9369   return (ret);
9370 }
9371
9372 static int
9373 api_proxy_arp_add_del (vat_main_t * vam)
9374 {
9375   unformat_input_t *i = vam->input;
9376   vl_api_proxy_arp_add_del_t *mp;
9377   u32 vrf_id = 0;
9378   u8 is_add = 1;
9379   ip4_address_t lo, hi;
9380   u8 range_set = 0;
9381   int ret;
9382
9383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9384     {
9385       if (unformat (i, "vrf %d", &vrf_id))
9386         ;
9387       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9388                          unformat_ip4_address, &hi))
9389         range_set = 1;
9390       else if (unformat (i, "del"))
9391         is_add = 0;
9392       else
9393         {
9394           clib_warning ("parse error '%U'", format_unformat_error, i);
9395           return -99;
9396         }
9397     }
9398
9399   if (range_set == 0)
9400     {
9401       errmsg ("address range not set");
9402       return -99;
9403     }
9404
9405   M (PROXY_ARP_ADD_DEL, mp);
9406
9407   mp->vrf_id = ntohl (vrf_id);
9408   mp->is_add = is_add;
9409   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
9410   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
9411
9412   S (mp);
9413   W (ret);
9414   return ret;
9415 }
9416
9417 static int
9418 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9419 {
9420   unformat_input_t *i = vam->input;
9421   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9422   u32 sw_if_index;
9423   u8 enable = 1;
9424   u8 sw_if_index_set = 0;
9425   int ret;
9426
9427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9428     {
9429       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9430         sw_if_index_set = 1;
9431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9432         sw_if_index_set = 1;
9433       else if (unformat (i, "enable"))
9434         enable = 1;
9435       else if (unformat (i, "disable"))
9436         enable = 0;
9437       else
9438         {
9439           clib_warning ("parse error '%U'", format_unformat_error, i);
9440           return -99;
9441         }
9442     }
9443
9444   if (sw_if_index_set == 0)
9445     {
9446       errmsg ("missing interface name or sw_if_index");
9447       return -99;
9448     }
9449
9450   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9451
9452   mp->sw_if_index = ntohl (sw_if_index);
9453   mp->enable_disable = enable;
9454
9455   S (mp);
9456   W (ret);
9457   return ret;
9458 }
9459
9460 static int
9461 api_mpls_tunnel_add_del (vat_main_t * vam)
9462 {
9463   unformat_input_t *i = vam->input;
9464   vl_api_mpls_tunnel_add_del_t *mp;
9465
9466   u8 is_add = 1;
9467   u8 l2_only = 0;
9468   u32 sw_if_index = ~0;
9469   u32 next_hop_sw_if_index = ~0;
9470   u32 next_hop_proto_is_ip4 = 1;
9471
9472   u32 next_hop_table_id = 0;
9473   ip4_address_t v4_next_hop_address = {
9474     .as_u32 = 0,
9475   };
9476   ip6_address_t v6_next_hop_address = { {0} };
9477   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9478   int ret;
9479
9480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9481     {
9482       if (unformat (i, "add"))
9483         is_add = 1;
9484       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9485         is_add = 0;
9486       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9487         ;
9488       else if (unformat (i, "via %U",
9489                          unformat_ip4_address, &v4_next_hop_address))
9490         {
9491           next_hop_proto_is_ip4 = 1;
9492         }
9493       else if (unformat (i, "via %U",
9494                          unformat_ip6_address, &v6_next_hop_address))
9495         {
9496           next_hop_proto_is_ip4 = 0;
9497         }
9498       else if (unformat (i, "l2-only"))
9499         l2_only = 1;
9500       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9501         ;
9502       else if (unformat (i, "out-label %d", &next_hop_out_label))
9503         vec_add1 (labels, ntohl (next_hop_out_label));
9504       else
9505         {
9506           clib_warning ("parse error '%U'", format_unformat_error, i);
9507           return -99;
9508         }
9509     }
9510
9511   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9512
9513   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9514   mp->mt_sw_if_index = ntohl (sw_if_index);
9515   mp->mt_is_add = is_add;
9516   mp->mt_l2_only = l2_only;
9517   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9518   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9519
9520   mp->mt_next_hop_n_out_labels = vec_len (labels);
9521
9522   if (0 != mp->mt_next_hop_n_out_labels)
9523     {
9524       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9525                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9526       vec_free (labels);
9527     }
9528
9529   if (next_hop_proto_is_ip4)
9530     {
9531       clib_memcpy (mp->mt_next_hop,
9532                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9533     }
9534   else
9535     {
9536       clib_memcpy (mp->mt_next_hop,
9537                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9538     }
9539
9540   S (mp);
9541   W (ret);
9542   return ret;
9543 }
9544
9545 static int
9546 api_sw_interface_set_unnumbered (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_sw_interface_set_unnumbered_t *mp;
9550   u32 sw_if_index;
9551   u32 unnum_sw_index = ~0;
9552   u8 is_add = 1;
9553   u8 sw_if_index_set = 0;
9554   int ret;
9555
9556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9559         sw_if_index_set = 1;
9560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9561         sw_if_index_set = 1;
9562       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9563         ;
9564       else if (unformat (i, "del"))
9565         is_add = 0;
9566       else
9567         {
9568           clib_warning ("parse error '%U'", format_unformat_error, i);
9569           return -99;
9570         }
9571     }
9572
9573   if (sw_if_index_set == 0)
9574     {
9575       errmsg ("missing interface name or sw_if_index");
9576       return -99;
9577     }
9578
9579   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9580
9581   mp->sw_if_index = ntohl (sw_if_index);
9582   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9583   mp->is_add = is_add;
9584
9585   S (mp);
9586   W (ret);
9587   return ret;
9588 }
9589
9590 static int
9591 api_ip_neighbor_add_del (vat_main_t * vam)
9592 {
9593   unformat_input_t *i = vam->input;
9594   vl_api_ip_neighbor_add_del_t *mp;
9595   u32 sw_if_index;
9596   u8 sw_if_index_set = 0;
9597   u8 is_add = 1;
9598   u8 is_static = 0;
9599   u8 is_no_fib_entry = 0;
9600   u8 mac_address[6];
9601   u8 mac_set = 0;
9602   u8 v4_address_set = 0;
9603   u8 v6_address_set = 0;
9604   ip4_address_t v4address;
9605   ip6_address_t v6address;
9606   int ret;
9607
9608   memset (mac_address, 0, sizeof (mac_address));
9609
9610   /* Parse args required to build the message */
9611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9612     {
9613       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9614         {
9615           mac_set = 1;
9616         }
9617       else if (unformat (i, "del"))
9618         is_add = 0;
9619       else
9620         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9621         sw_if_index_set = 1;
9622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9623         sw_if_index_set = 1;
9624       else if (unformat (i, "is_static"))
9625         is_static = 1;
9626       else if (unformat (i, "no-fib-entry"))
9627         is_no_fib_entry = 1;
9628       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9629         v4_address_set = 1;
9630       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9631         v6_address_set = 1;
9632       else
9633         {
9634           clib_warning ("parse error '%U'", format_unformat_error, i);
9635           return -99;
9636         }
9637     }
9638
9639   if (sw_if_index_set == 0)
9640     {
9641       errmsg ("missing interface name or sw_if_index");
9642       return -99;
9643     }
9644   if (v4_address_set && v6_address_set)
9645     {
9646       errmsg ("both v4 and v6 addresses set");
9647       return -99;
9648     }
9649   if (!v4_address_set && !v6_address_set)
9650     {
9651       errmsg ("no address set");
9652       return -99;
9653     }
9654
9655   /* Construct the API message */
9656   M (IP_NEIGHBOR_ADD_DEL, mp);
9657
9658   mp->sw_if_index = ntohl (sw_if_index);
9659   mp->is_add = is_add;
9660   mp->is_static = is_static;
9661   mp->is_no_adj_fib = is_no_fib_entry;
9662   if (mac_set)
9663     clib_memcpy (mp->mac_address, mac_address, 6);
9664   if (v6_address_set)
9665     {
9666       mp->is_ipv6 = 1;
9667       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9668     }
9669   else
9670     {
9671       /* mp->is_ipv6 = 0; via memset in M macro above */
9672       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9673     }
9674
9675   /* send it... */
9676   S (mp);
9677
9678   /* Wait for a reply, return good/bad news  */
9679   W (ret);
9680   return ret;
9681 }
9682
9683 static int
9684 api_create_vlan_subif (vat_main_t * vam)
9685 {
9686   unformat_input_t *i = vam->input;
9687   vl_api_create_vlan_subif_t *mp;
9688   u32 sw_if_index;
9689   u8 sw_if_index_set = 0;
9690   u32 vlan_id;
9691   u8 vlan_id_set = 0;
9692   int ret;
9693
9694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (i, "sw_if_index %d", &sw_if_index))
9697         sw_if_index_set = 1;
9698       else
9699         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9700         sw_if_index_set = 1;
9701       else if (unformat (i, "vlan %d", &vlan_id))
9702         vlan_id_set = 1;
9703       else
9704         {
9705           clib_warning ("parse error '%U'", format_unformat_error, i);
9706           return -99;
9707         }
9708     }
9709
9710   if (sw_if_index_set == 0)
9711     {
9712       errmsg ("missing interface name or sw_if_index");
9713       return -99;
9714     }
9715
9716   if (vlan_id_set == 0)
9717     {
9718       errmsg ("missing vlan_id");
9719       return -99;
9720     }
9721   M (CREATE_VLAN_SUBIF, mp);
9722
9723   mp->sw_if_index = ntohl (sw_if_index);
9724   mp->vlan_id = ntohl (vlan_id);
9725
9726   S (mp);
9727   W (ret);
9728   return ret;
9729 }
9730
9731 #define foreach_create_subif_bit                \
9732 _(no_tags)                                      \
9733 _(one_tag)                                      \
9734 _(two_tags)                                     \
9735 _(dot1ad)                                       \
9736 _(exact_match)                                  \
9737 _(default_sub)                                  \
9738 _(outer_vlan_id_any)                            \
9739 _(inner_vlan_id_any)
9740
9741 static int
9742 api_create_subif (vat_main_t * vam)
9743 {
9744   unformat_input_t *i = vam->input;
9745   vl_api_create_subif_t *mp;
9746   u32 sw_if_index;
9747   u8 sw_if_index_set = 0;
9748   u32 sub_id;
9749   u8 sub_id_set = 0;
9750   u32 no_tags = 0;
9751   u32 one_tag = 0;
9752   u32 two_tags = 0;
9753   u32 dot1ad = 0;
9754   u32 exact_match = 0;
9755   u32 default_sub = 0;
9756   u32 outer_vlan_id_any = 0;
9757   u32 inner_vlan_id_any = 0;
9758   u32 tmp;
9759   u16 outer_vlan_id = 0;
9760   u16 inner_vlan_id = 0;
9761   int ret;
9762
9763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9764     {
9765       if (unformat (i, "sw_if_index %d", &sw_if_index))
9766         sw_if_index_set = 1;
9767       else
9768         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9769         sw_if_index_set = 1;
9770       else if (unformat (i, "sub_id %d", &sub_id))
9771         sub_id_set = 1;
9772       else if (unformat (i, "outer_vlan_id %d", &tmp))
9773         outer_vlan_id = tmp;
9774       else if (unformat (i, "inner_vlan_id %d", &tmp))
9775         inner_vlan_id = tmp;
9776
9777 #define _(a) else if (unformat (i, #a)) a = 1 ;
9778       foreach_create_subif_bit
9779 #undef _
9780         else
9781         {
9782           clib_warning ("parse error '%U'", format_unformat_error, i);
9783           return -99;
9784         }
9785     }
9786
9787   if (sw_if_index_set == 0)
9788     {
9789       errmsg ("missing interface name or sw_if_index");
9790       return -99;
9791     }
9792
9793   if (sub_id_set == 0)
9794     {
9795       errmsg ("missing sub_id");
9796       return -99;
9797     }
9798   M (CREATE_SUBIF, mp);
9799
9800   mp->sw_if_index = ntohl (sw_if_index);
9801   mp->sub_id = ntohl (sub_id);
9802
9803 #define _(a) mp->a = a;
9804   foreach_create_subif_bit;
9805 #undef _
9806
9807   mp->outer_vlan_id = ntohs (outer_vlan_id);
9808   mp->inner_vlan_id = ntohs (inner_vlan_id);
9809
9810   S (mp);
9811   W (ret);
9812   return ret;
9813 }
9814
9815 static int
9816 api_oam_add_del (vat_main_t * vam)
9817 {
9818   unformat_input_t *i = vam->input;
9819   vl_api_oam_add_del_t *mp;
9820   u32 vrf_id = 0;
9821   u8 is_add = 1;
9822   ip4_address_t src, dst;
9823   u8 src_set = 0;
9824   u8 dst_set = 0;
9825   int ret;
9826
9827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (i, "vrf %d", &vrf_id))
9830         ;
9831       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9832         src_set = 1;
9833       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9834         dst_set = 1;
9835       else if (unformat (i, "del"))
9836         is_add = 0;
9837       else
9838         {
9839           clib_warning ("parse error '%U'", format_unformat_error, i);
9840           return -99;
9841         }
9842     }
9843
9844   if (src_set == 0)
9845     {
9846       errmsg ("missing src addr");
9847       return -99;
9848     }
9849
9850   if (dst_set == 0)
9851     {
9852       errmsg ("missing dst addr");
9853       return -99;
9854     }
9855
9856   M (OAM_ADD_DEL, mp);
9857
9858   mp->vrf_id = ntohl (vrf_id);
9859   mp->is_add = is_add;
9860   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9861   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9862
9863   S (mp);
9864   W (ret);
9865   return ret;
9866 }
9867
9868 static int
9869 api_reset_fib (vat_main_t * vam)
9870 {
9871   unformat_input_t *i = vam->input;
9872   vl_api_reset_fib_t *mp;
9873   u32 vrf_id = 0;
9874   u8 is_ipv6 = 0;
9875   u8 vrf_id_set = 0;
9876
9877   int ret;
9878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9879     {
9880       if (unformat (i, "vrf %d", &vrf_id))
9881         vrf_id_set = 1;
9882       else if (unformat (i, "ipv6"))
9883         is_ipv6 = 1;
9884       else
9885         {
9886           clib_warning ("parse error '%U'", format_unformat_error, i);
9887           return -99;
9888         }
9889     }
9890
9891   if (vrf_id_set == 0)
9892     {
9893       errmsg ("missing vrf id");
9894       return -99;
9895     }
9896
9897   M (RESET_FIB, mp);
9898
9899   mp->vrf_id = ntohl (vrf_id);
9900   mp->is_ipv6 = is_ipv6;
9901
9902   S (mp);
9903   W (ret);
9904   return ret;
9905 }
9906
9907 static int
9908 api_dhcp_proxy_config (vat_main_t * vam)
9909 {
9910   unformat_input_t *i = vam->input;
9911   vl_api_dhcp_proxy_config_t *mp;
9912   u32 rx_vrf_id = 0;
9913   u32 server_vrf_id = 0;
9914   u8 is_add = 1;
9915   u8 v4_address_set = 0;
9916   u8 v6_address_set = 0;
9917   ip4_address_t v4address;
9918   ip6_address_t v6address;
9919   u8 v4_src_address_set = 0;
9920   u8 v6_src_address_set = 0;
9921   ip4_address_t v4srcaddress;
9922   ip6_address_t v6srcaddress;
9923   int ret;
9924
9925   /* Parse args required to build the message */
9926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9927     {
9928       if (unformat (i, "del"))
9929         is_add = 0;
9930       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9931         ;
9932       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9933         ;
9934       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9935         v4_address_set = 1;
9936       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9937         v6_address_set = 1;
9938       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9939         v4_src_address_set = 1;
9940       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9941         v6_src_address_set = 1;
9942       else
9943         break;
9944     }
9945
9946   if (v4_address_set && v6_address_set)
9947     {
9948       errmsg ("both v4 and v6 server addresses set");
9949       return -99;
9950     }
9951   if (!v4_address_set && !v6_address_set)
9952     {
9953       errmsg ("no server addresses set");
9954       return -99;
9955     }
9956
9957   if (v4_src_address_set && v6_src_address_set)
9958     {
9959       errmsg ("both v4 and v6  src addresses set");
9960       return -99;
9961     }
9962   if (!v4_src_address_set && !v6_src_address_set)
9963     {
9964       errmsg ("no src addresses set");
9965       return -99;
9966     }
9967
9968   if (!(v4_src_address_set && v4_address_set) &&
9969       !(v6_src_address_set && v6_address_set))
9970     {
9971       errmsg ("no matching server and src addresses set");
9972       return -99;
9973     }
9974
9975   /* Construct the API message */
9976   M (DHCP_PROXY_CONFIG, mp);
9977
9978   mp->is_add = is_add;
9979   mp->rx_vrf_id = ntohl (rx_vrf_id);
9980   mp->server_vrf_id = ntohl (server_vrf_id);
9981   if (v6_address_set)
9982     {
9983       mp->is_ipv6 = 1;
9984       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9985       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9986     }
9987   else
9988     {
9989       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9990       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9991     }
9992
9993   /* send it... */
9994   S (mp);
9995
9996   /* Wait for a reply, return good/bad news  */
9997   W (ret);
9998   return ret;
9999 }
10000
10001 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10002 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10003
10004 static void
10005 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10006 {
10007   vat_main_t *vam = &vat_main;
10008   u32 i, count = mp->count;
10009   vl_api_dhcp_server_t *s;
10010
10011   if (mp->is_ipv6)
10012     print (vam->ofp,
10013            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10014            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10015            ntohl (mp->rx_vrf_id),
10016            format_ip6_address, mp->dhcp_src_address,
10017            mp->vss_type, mp->vss_vpn_ascii_id,
10018            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10019   else
10020     print (vam->ofp,
10021            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10022            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10023            ntohl (mp->rx_vrf_id),
10024            format_ip4_address, mp->dhcp_src_address,
10025            mp->vss_type, mp->vss_vpn_ascii_id,
10026            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10027
10028   for (i = 0; i < count; i++)
10029     {
10030       s = &mp->servers[i];
10031
10032       if (mp->is_ipv6)
10033         print (vam->ofp,
10034                " Server Table-ID %d, Server Address %U",
10035                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10036       else
10037         print (vam->ofp,
10038                " Server Table-ID %d, Server Address %U",
10039                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10040     }
10041 }
10042
10043 static void vl_api_dhcp_proxy_details_t_handler_json
10044   (vl_api_dhcp_proxy_details_t * mp)
10045 {
10046   vat_main_t *vam = &vat_main;
10047   vat_json_node_t *node = NULL;
10048   u32 i, count = mp->count;
10049   struct in_addr ip4;
10050   struct in6_addr ip6;
10051   vl_api_dhcp_server_t *s;
10052
10053   if (VAT_JSON_ARRAY != vam->json_tree.type)
10054     {
10055       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10056       vat_json_init_array (&vam->json_tree);
10057     }
10058   node = vat_json_array_add (&vam->json_tree);
10059
10060   vat_json_init_object (node);
10061   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10062   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10063                              sizeof (mp->vss_type));
10064   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10065                                    mp->vss_vpn_ascii_id);
10066   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10067   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10068
10069   if (mp->is_ipv6)
10070     {
10071       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10072       vat_json_object_add_ip6 (node, "src_address", ip6);
10073     }
10074   else
10075     {
10076       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10077       vat_json_object_add_ip4 (node, "src_address", ip4);
10078     }
10079
10080   for (i = 0; i < count; i++)
10081     {
10082       s = &mp->servers[i];
10083
10084       vat_json_object_add_uint (node, "server-table-id",
10085                                 ntohl (s->server_vrf_id));
10086
10087       if (mp->is_ipv6)
10088         {
10089           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10090           vat_json_object_add_ip4 (node, "src_address", ip4);
10091         }
10092       else
10093         {
10094           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10095           vat_json_object_add_ip6 (node, "server_address", ip6);
10096         }
10097     }
10098 }
10099
10100 static int
10101 api_dhcp_proxy_dump (vat_main_t * vam)
10102 {
10103   unformat_input_t *i = vam->input;
10104   vl_api_control_ping_t *mp_ping;
10105   vl_api_dhcp_proxy_dump_t *mp;
10106   u8 is_ipv6 = 0;
10107   int ret;
10108
10109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10110     {
10111       if (unformat (i, "ipv6"))
10112         is_ipv6 = 1;
10113       else
10114         {
10115           clib_warning ("parse error '%U'", format_unformat_error, i);
10116           return -99;
10117         }
10118     }
10119
10120   M (DHCP_PROXY_DUMP, mp);
10121
10122   mp->is_ip6 = is_ipv6;
10123   S (mp);
10124
10125   /* Use a control ping for synchronization */
10126   MPING (CONTROL_PING, mp_ping);
10127   S (mp_ping);
10128
10129   W (ret);
10130   return ret;
10131 }
10132
10133 static int
10134 api_dhcp_proxy_set_vss (vat_main_t * vam)
10135 {
10136   unformat_input_t *i = vam->input;
10137   vl_api_dhcp_proxy_set_vss_t *mp;
10138   u8 is_ipv6 = 0;
10139   u8 is_add = 1;
10140   u32 tbl_id = ~0;
10141   u8 vss_type = VSS_TYPE_DEFAULT;
10142   u8 *vpn_ascii_id = 0;
10143   u32 oui = 0;
10144   u32 fib_id = 0;
10145   int ret;
10146
10147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (i, "tbl_id %d", &tbl_id))
10150         ;
10151       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10152         vss_type = VSS_TYPE_ASCII;
10153       else if (unformat (i, "fib_id %d", &fib_id))
10154         vss_type = VSS_TYPE_VPN_ID;
10155       else if (unformat (i, "oui %d", &oui))
10156         vss_type = VSS_TYPE_VPN_ID;
10157       else if (unformat (i, "ipv6"))
10158         is_ipv6 = 1;
10159       else if (unformat (i, "del"))
10160         is_add = 0;
10161       else
10162         break;
10163     }
10164
10165   if (tbl_id == ~0)
10166     {
10167       errmsg ("missing tbl_id ");
10168       vec_free (vpn_ascii_id);
10169       return -99;
10170     }
10171
10172   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10173     {
10174       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10175       vec_free (vpn_ascii_id);
10176       return -99;
10177     }
10178
10179   M (DHCP_PROXY_SET_VSS, mp);
10180   mp->tbl_id = ntohl (tbl_id);
10181   mp->vss_type = vss_type;
10182   if (vpn_ascii_id)
10183     {
10184       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10185       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10186     }
10187   mp->vpn_index = ntohl (fib_id);
10188   mp->oui = ntohl (oui);
10189   mp->is_ipv6 = is_ipv6;
10190   mp->is_add = is_add;
10191
10192   S (mp);
10193   W (ret);
10194
10195   vec_free (vpn_ascii_id);
10196   return ret;
10197 }
10198
10199 static int
10200 api_dhcp_client_config (vat_main_t * vam)
10201 {
10202   unformat_input_t *i = vam->input;
10203   vl_api_dhcp_client_config_t *mp;
10204   u32 sw_if_index;
10205   u8 sw_if_index_set = 0;
10206   u8 is_add = 1;
10207   u8 *hostname = 0;
10208   u8 disable_event = 0;
10209   int ret;
10210
10211   /* Parse args required to build the message */
10212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10213     {
10214       if (unformat (i, "del"))
10215         is_add = 0;
10216       else
10217         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10218         sw_if_index_set = 1;
10219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10220         sw_if_index_set = 1;
10221       else if (unformat (i, "hostname %s", &hostname))
10222         ;
10223       else if (unformat (i, "disable_event"))
10224         disable_event = 1;
10225       else
10226         break;
10227     }
10228
10229   if (sw_if_index_set == 0)
10230     {
10231       errmsg ("missing interface name or sw_if_index");
10232       return -99;
10233     }
10234
10235   if (vec_len (hostname) > 63)
10236     {
10237       errmsg ("hostname too long");
10238     }
10239   vec_add1 (hostname, 0);
10240
10241   /* Construct the API message */
10242   M (DHCP_CLIENT_CONFIG, mp);
10243
10244   mp->sw_if_index = htonl (sw_if_index);
10245   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10246   vec_free (hostname);
10247   mp->is_add = is_add;
10248   mp->want_dhcp_event = disable_event ? 0 : 1;
10249   mp->pid = htonl (getpid ());
10250
10251   /* send it... */
10252   S (mp);
10253
10254   /* Wait for a reply, return good/bad news  */
10255   W (ret);
10256   return ret;
10257 }
10258
10259 static int
10260 api_set_ip_flow_hash (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   vl_api_set_ip_flow_hash_t *mp;
10264   u32 vrf_id = 0;
10265   u8 is_ipv6 = 0;
10266   u8 vrf_id_set = 0;
10267   u8 src = 0;
10268   u8 dst = 0;
10269   u8 sport = 0;
10270   u8 dport = 0;
10271   u8 proto = 0;
10272   u8 reverse = 0;
10273   int ret;
10274
10275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10276     {
10277       if (unformat (i, "vrf %d", &vrf_id))
10278         vrf_id_set = 1;
10279       else if (unformat (i, "ipv6"))
10280         is_ipv6 = 1;
10281       else if (unformat (i, "src"))
10282         src = 1;
10283       else if (unformat (i, "dst"))
10284         dst = 1;
10285       else if (unformat (i, "sport"))
10286         sport = 1;
10287       else if (unformat (i, "dport"))
10288         dport = 1;
10289       else if (unformat (i, "proto"))
10290         proto = 1;
10291       else if (unformat (i, "reverse"))
10292         reverse = 1;
10293
10294       else
10295         {
10296           clib_warning ("parse error '%U'", format_unformat_error, i);
10297           return -99;
10298         }
10299     }
10300
10301   if (vrf_id_set == 0)
10302     {
10303       errmsg ("missing vrf id");
10304       return -99;
10305     }
10306
10307   M (SET_IP_FLOW_HASH, mp);
10308   mp->src = src;
10309   mp->dst = dst;
10310   mp->sport = sport;
10311   mp->dport = dport;
10312   mp->proto = proto;
10313   mp->reverse = reverse;
10314   mp->vrf_id = ntohl (vrf_id);
10315   mp->is_ipv6 = is_ipv6;
10316
10317   S (mp);
10318   W (ret);
10319   return ret;
10320 }
10321
10322 static int
10323 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_sw_interface_ip6_enable_disable_t *mp;
10327   u32 sw_if_index;
10328   u8 sw_if_index_set = 0;
10329   u8 enable = 0;
10330   int ret;
10331
10332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10333     {
10334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10335         sw_if_index_set = 1;
10336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10337         sw_if_index_set = 1;
10338       else if (unformat (i, "enable"))
10339         enable = 1;
10340       else if (unformat (i, "disable"))
10341         enable = 0;
10342       else
10343         {
10344           clib_warning ("parse error '%U'", format_unformat_error, i);
10345           return -99;
10346         }
10347     }
10348
10349   if (sw_if_index_set == 0)
10350     {
10351       errmsg ("missing interface name or sw_if_index");
10352       return -99;
10353     }
10354
10355   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10356
10357   mp->sw_if_index = ntohl (sw_if_index);
10358   mp->enable = enable;
10359
10360   S (mp);
10361   W (ret);
10362   return ret;
10363 }
10364
10365 static int
10366 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10367 {
10368   unformat_input_t *i = vam->input;
10369   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10370   u32 sw_if_index;
10371   u8 sw_if_index_set = 0;
10372   u8 v6_address_set = 0;
10373   ip6_address_t v6address;
10374   int ret;
10375
10376   /* Parse args required to build the message */
10377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10378     {
10379       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10380         sw_if_index_set = 1;
10381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10382         sw_if_index_set = 1;
10383       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10384         v6_address_set = 1;
10385       else
10386         break;
10387     }
10388
10389   if (sw_if_index_set == 0)
10390     {
10391       errmsg ("missing interface name or sw_if_index");
10392       return -99;
10393     }
10394   if (!v6_address_set)
10395     {
10396       errmsg ("no address set");
10397       return -99;
10398     }
10399
10400   /* Construct the API message */
10401   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10402
10403   mp->sw_if_index = ntohl (sw_if_index);
10404   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10405
10406   /* send it... */
10407   S (mp);
10408
10409   /* Wait for a reply, return good/bad news  */
10410   W (ret);
10411   return ret;
10412 }
10413
10414 static int
10415 api_ip6nd_proxy_add_del (vat_main_t * vam)
10416 {
10417   unformat_input_t *i = vam->input;
10418   vl_api_ip6nd_proxy_add_del_t *mp;
10419   u32 sw_if_index = ~0;
10420   u8 v6_address_set = 0;
10421   ip6_address_t v6address;
10422   u8 is_del = 0;
10423   int ret;
10424
10425   /* Parse args required to build the message */
10426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10427     {
10428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10429         ;
10430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10431         ;
10432       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10433         v6_address_set = 1;
10434       if (unformat (i, "del"))
10435         is_del = 1;
10436       else
10437         {
10438           clib_warning ("parse error '%U'", format_unformat_error, i);
10439           return -99;
10440         }
10441     }
10442
10443   if (sw_if_index == ~0)
10444     {
10445       errmsg ("missing interface name or sw_if_index");
10446       return -99;
10447     }
10448   if (!v6_address_set)
10449     {
10450       errmsg ("no address set");
10451       return -99;
10452     }
10453
10454   /* Construct the API message */
10455   M (IP6ND_PROXY_ADD_DEL, mp);
10456
10457   mp->is_del = is_del;
10458   mp->sw_if_index = ntohl (sw_if_index);
10459   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10460
10461   /* send it... */
10462   S (mp);
10463
10464   /* Wait for a reply, return good/bad news  */
10465   W (ret);
10466   return ret;
10467 }
10468
10469 static int
10470 api_ip6nd_proxy_dump (vat_main_t * vam)
10471 {
10472   vl_api_ip6nd_proxy_dump_t *mp;
10473   vl_api_control_ping_t *mp_ping;
10474   int ret;
10475
10476   M (IP6ND_PROXY_DUMP, mp);
10477
10478   S (mp);
10479
10480   /* Use a control ping for synchronization */
10481   MPING (CONTROL_PING, mp_ping);
10482   S (mp_ping);
10483
10484   W (ret);
10485   return ret;
10486 }
10487
10488 static void vl_api_ip6nd_proxy_details_t_handler
10489   (vl_api_ip6nd_proxy_details_t * mp)
10490 {
10491   vat_main_t *vam = &vat_main;
10492
10493   print (vam->ofp, "host %U sw_if_index %d",
10494          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10495 }
10496
10497 static void vl_api_ip6nd_proxy_details_t_handler_json
10498   (vl_api_ip6nd_proxy_details_t * mp)
10499 {
10500   vat_main_t *vam = &vat_main;
10501   struct in6_addr ip6;
10502   vat_json_node_t *node = NULL;
10503
10504   if (VAT_JSON_ARRAY != vam->json_tree.type)
10505     {
10506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10507       vat_json_init_array (&vam->json_tree);
10508     }
10509   node = vat_json_array_add (&vam->json_tree);
10510
10511   vat_json_init_object (node);
10512   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10513
10514   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10515   vat_json_object_add_ip6 (node, "host", ip6);
10516 }
10517
10518 static int
10519 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10520 {
10521   unformat_input_t *i = vam->input;
10522   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10523   u32 sw_if_index;
10524   u8 sw_if_index_set = 0;
10525   u32 address_length = 0;
10526   u8 v6_address_set = 0;
10527   ip6_address_t v6address;
10528   u8 use_default = 0;
10529   u8 no_advertise = 0;
10530   u8 off_link = 0;
10531   u8 no_autoconfig = 0;
10532   u8 no_onlink = 0;
10533   u8 is_no = 0;
10534   u32 val_lifetime = 0;
10535   u32 pref_lifetime = 0;
10536   int ret;
10537
10538   /* Parse args required to build the message */
10539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10540     {
10541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10542         sw_if_index_set = 1;
10543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10544         sw_if_index_set = 1;
10545       else if (unformat (i, "%U/%d",
10546                          unformat_ip6_address, &v6address, &address_length))
10547         v6_address_set = 1;
10548       else if (unformat (i, "val_life %d", &val_lifetime))
10549         ;
10550       else if (unformat (i, "pref_life %d", &pref_lifetime))
10551         ;
10552       else if (unformat (i, "def"))
10553         use_default = 1;
10554       else if (unformat (i, "noadv"))
10555         no_advertise = 1;
10556       else if (unformat (i, "offl"))
10557         off_link = 1;
10558       else if (unformat (i, "noauto"))
10559         no_autoconfig = 1;
10560       else if (unformat (i, "nolink"))
10561         no_onlink = 1;
10562       else if (unformat (i, "isno"))
10563         is_no = 1;
10564       else
10565         {
10566           clib_warning ("parse error '%U'", format_unformat_error, i);
10567           return -99;
10568         }
10569     }
10570
10571   if (sw_if_index_set == 0)
10572     {
10573       errmsg ("missing interface name or sw_if_index");
10574       return -99;
10575     }
10576   if (!v6_address_set)
10577     {
10578       errmsg ("no address set");
10579       return -99;
10580     }
10581
10582   /* Construct the API message */
10583   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10584
10585   mp->sw_if_index = ntohl (sw_if_index);
10586   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10587   mp->address_length = address_length;
10588   mp->use_default = use_default;
10589   mp->no_advertise = no_advertise;
10590   mp->off_link = off_link;
10591   mp->no_autoconfig = no_autoconfig;
10592   mp->no_onlink = no_onlink;
10593   mp->is_no = is_no;
10594   mp->val_lifetime = ntohl (val_lifetime);
10595   mp->pref_lifetime = ntohl (pref_lifetime);
10596
10597   /* send it... */
10598   S (mp);
10599
10600   /* Wait for a reply, return good/bad news  */
10601   W (ret);
10602   return ret;
10603 }
10604
10605 static int
10606 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10607 {
10608   unformat_input_t *i = vam->input;
10609   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10610   u32 sw_if_index;
10611   u8 sw_if_index_set = 0;
10612   u8 suppress = 0;
10613   u8 managed = 0;
10614   u8 other = 0;
10615   u8 ll_option = 0;
10616   u8 send_unicast = 0;
10617   u8 cease = 0;
10618   u8 is_no = 0;
10619   u8 default_router = 0;
10620   u32 max_interval = 0;
10621   u32 min_interval = 0;
10622   u32 lifetime = 0;
10623   u32 initial_count = 0;
10624   u32 initial_interval = 0;
10625   int ret;
10626
10627
10628   /* Parse args required to build the message */
10629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10630     {
10631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10632         sw_if_index_set = 1;
10633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10634         sw_if_index_set = 1;
10635       else if (unformat (i, "maxint %d", &max_interval))
10636         ;
10637       else if (unformat (i, "minint %d", &min_interval))
10638         ;
10639       else if (unformat (i, "life %d", &lifetime))
10640         ;
10641       else if (unformat (i, "count %d", &initial_count))
10642         ;
10643       else if (unformat (i, "interval %d", &initial_interval))
10644         ;
10645       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10646         suppress = 1;
10647       else if (unformat (i, "managed"))
10648         managed = 1;
10649       else if (unformat (i, "other"))
10650         other = 1;
10651       else if (unformat (i, "ll"))
10652         ll_option = 1;
10653       else if (unformat (i, "send"))
10654         send_unicast = 1;
10655       else if (unformat (i, "cease"))
10656         cease = 1;
10657       else if (unformat (i, "isno"))
10658         is_no = 1;
10659       else if (unformat (i, "def"))
10660         default_router = 1;
10661       else
10662         {
10663           clib_warning ("parse error '%U'", format_unformat_error, i);
10664           return -99;
10665         }
10666     }
10667
10668   if (sw_if_index_set == 0)
10669     {
10670       errmsg ("missing interface name or sw_if_index");
10671       return -99;
10672     }
10673
10674   /* Construct the API message */
10675   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10676
10677   mp->sw_if_index = ntohl (sw_if_index);
10678   mp->max_interval = ntohl (max_interval);
10679   mp->min_interval = ntohl (min_interval);
10680   mp->lifetime = ntohl (lifetime);
10681   mp->initial_count = ntohl (initial_count);
10682   mp->initial_interval = ntohl (initial_interval);
10683   mp->suppress = suppress;
10684   mp->managed = managed;
10685   mp->other = other;
10686   mp->ll_option = ll_option;
10687   mp->send_unicast = send_unicast;
10688   mp->cease = cease;
10689   mp->is_no = is_no;
10690   mp->default_router = default_router;
10691
10692   /* send it... */
10693   S (mp);
10694
10695   /* Wait for a reply, return good/bad news  */
10696   W (ret);
10697   return ret;
10698 }
10699
10700 static int
10701 api_set_arp_neighbor_limit (vat_main_t * vam)
10702 {
10703   unformat_input_t *i = vam->input;
10704   vl_api_set_arp_neighbor_limit_t *mp;
10705   u32 arp_nbr_limit;
10706   u8 limit_set = 0;
10707   u8 is_ipv6 = 0;
10708   int ret;
10709
10710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10711     {
10712       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10713         limit_set = 1;
10714       else if (unformat (i, "ipv6"))
10715         is_ipv6 = 1;
10716       else
10717         {
10718           clib_warning ("parse error '%U'", format_unformat_error, i);
10719           return -99;
10720         }
10721     }
10722
10723   if (limit_set == 0)
10724     {
10725       errmsg ("missing limit value");
10726       return -99;
10727     }
10728
10729   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10730
10731   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10732   mp->is_ipv6 = is_ipv6;
10733
10734   S (mp);
10735   W (ret);
10736   return ret;
10737 }
10738
10739 static int
10740 api_l2_patch_add_del (vat_main_t * vam)
10741 {
10742   unformat_input_t *i = vam->input;
10743   vl_api_l2_patch_add_del_t *mp;
10744   u32 rx_sw_if_index;
10745   u8 rx_sw_if_index_set = 0;
10746   u32 tx_sw_if_index;
10747   u8 tx_sw_if_index_set = 0;
10748   u8 is_add = 1;
10749   int ret;
10750
10751   /* Parse args required to build the message */
10752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10753     {
10754       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10755         rx_sw_if_index_set = 1;
10756       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10757         tx_sw_if_index_set = 1;
10758       else if (unformat (i, "rx"))
10759         {
10760           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10761             {
10762               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10763                             &rx_sw_if_index))
10764                 rx_sw_if_index_set = 1;
10765             }
10766           else
10767             break;
10768         }
10769       else if (unformat (i, "tx"))
10770         {
10771           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10772             {
10773               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10774                             &tx_sw_if_index))
10775                 tx_sw_if_index_set = 1;
10776             }
10777           else
10778             break;
10779         }
10780       else if (unformat (i, "del"))
10781         is_add = 0;
10782       else
10783         break;
10784     }
10785
10786   if (rx_sw_if_index_set == 0)
10787     {
10788       errmsg ("missing rx interface name or rx_sw_if_index");
10789       return -99;
10790     }
10791
10792   if (tx_sw_if_index_set == 0)
10793     {
10794       errmsg ("missing tx interface name or tx_sw_if_index");
10795       return -99;
10796     }
10797
10798   M (L2_PATCH_ADD_DEL, mp);
10799
10800   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10801   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10802   mp->is_add = is_add;
10803
10804   S (mp);
10805   W (ret);
10806   return ret;
10807 }
10808
10809 u8 is_del;
10810 u8 localsid_addr[16];
10811 u8 end_psp;
10812 u8 behavior;
10813 u32 sw_if_index;
10814 u32 vlan_index;
10815 u32 fib_table;
10816 u8 nh_addr[16];
10817
10818 static int
10819 api_sr_localsid_add_del (vat_main_t * vam)
10820 {
10821   unformat_input_t *i = vam->input;
10822   vl_api_sr_localsid_add_del_t *mp;
10823
10824   u8 is_del;
10825   ip6_address_t localsid;
10826   u8 end_psp = 0;
10827   u8 behavior = ~0;
10828   u32 sw_if_index;
10829   u32 fib_table = ~(u32) 0;
10830   ip6_address_t next_hop;
10831
10832   bool nexthop_set = 0;
10833
10834   int ret;
10835
10836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (unformat (i, "del"))
10839         is_del = 1;
10840       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10841       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10842         nexthop_set = 1;
10843       else if (unformat (i, "behavior %u", &behavior));
10844       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10845       else if (unformat (i, "fib-table %u", &fib_table));
10846       else if (unformat (i, "end.psp %u", &behavior));
10847       else
10848         break;
10849     }
10850
10851   M (SR_LOCALSID_ADD_DEL, mp);
10852
10853   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10854   if (nexthop_set)
10855     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10856   mp->behavior = behavior;
10857   mp->sw_if_index = ntohl (sw_if_index);
10858   mp->fib_table = ntohl (fib_table);
10859   mp->end_psp = end_psp;
10860   mp->is_del = is_del;
10861
10862   S (mp);
10863   W (ret);
10864   return ret;
10865 }
10866
10867 static int
10868 api_ioam_enable (vat_main_t * vam)
10869 {
10870   unformat_input_t *input = vam->input;
10871   vl_api_ioam_enable_t *mp;
10872   u32 id = 0;
10873   int has_trace_option = 0;
10874   int has_pot_option = 0;
10875   int has_seqno_option = 0;
10876   int has_analyse_option = 0;
10877   int ret;
10878
10879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10880     {
10881       if (unformat (input, "trace"))
10882         has_trace_option = 1;
10883       else if (unformat (input, "pot"))
10884         has_pot_option = 1;
10885       else if (unformat (input, "seqno"))
10886         has_seqno_option = 1;
10887       else if (unformat (input, "analyse"))
10888         has_analyse_option = 1;
10889       else
10890         break;
10891     }
10892   M (IOAM_ENABLE, mp);
10893   mp->id = htons (id);
10894   mp->seqno = has_seqno_option;
10895   mp->analyse = has_analyse_option;
10896   mp->pot_enable = has_pot_option;
10897   mp->trace_enable = has_trace_option;
10898
10899   S (mp);
10900   W (ret);
10901   return ret;
10902 }
10903
10904
10905 static int
10906 api_ioam_disable (vat_main_t * vam)
10907 {
10908   vl_api_ioam_disable_t *mp;
10909   int ret;
10910
10911   M (IOAM_DISABLE, mp);
10912   S (mp);
10913   W (ret);
10914   return ret;
10915 }
10916
10917 #define foreach_tcp_proto_field                 \
10918 _(src_port)                                     \
10919 _(dst_port)
10920
10921 #define foreach_udp_proto_field                 \
10922 _(src_port)                                     \
10923 _(dst_port)
10924
10925 #define foreach_ip4_proto_field                 \
10926 _(src_address)                                  \
10927 _(dst_address)                                  \
10928 _(tos)                                          \
10929 _(length)                                       \
10930 _(fragment_id)                                  \
10931 _(ttl)                                          \
10932 _(protocol)                                     \
10933 _(checksum)
10934
10935 typedef struct
10936 {
10937   u16 src_port, dst_port;
10938 } tcpudp_header_t;
10939
10940 #if VPP_API_TEST_BUILTIN == 0
10941 uword
10942 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10943 {
10944   u8 **maskp = va_arg (*args, u8 **);
10945   u8 *mask = 0;
10946   u8 found_something = 0;
10947   tcp_header_t *tcp;
10948
10949 #define _(a) u8 a=0;
10950   foreach_tcp_proto_field;
10951 #undef _
10952
10953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (0);
10956 #define _(a) else if (unformat (input, #a)) a=1;
10957       foreach_tcp_proto_field
10958 #undef _
10959         else
10960         break;
10961     }
10962
10963 #define _(a) found_something += a;
10964   foreach_tcp_proto_field;
10965 #undef _
10966
10967   if (found_something == 0)
10968     return 0;
10969
10970   vec_validate (mask, sizeof (*tcp) - 1);
10971
10972   tcp = (tcp_header_t *) mask;
10973
10974 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10975   foreach_tcp_proto_field;
10976 #undef _
10977
10978   *maskp = mask;
10979   return 1;
10980 }
10981
10982 uword
10983 unformat_udp_mask (unformat_input_t * input, va_list * args)
10984 {
10985   u8 **maskp = va_arg (*args, u8 **);
10986   u8 *mask = 0;
10987   u8 found_something = 0;
10988   udp_header_t *udp;
10989
10990 #define _(a) u8 a=0;
10991   foreach_udp_proto_field;
10992 #undef _
10993
10994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10995     {
10996       if (0);
10997 #define _(a) else if (unformat (input, #a)) a=1;
10998       foreach_udp_proto_field
10999 #undef _
11000         else
11001         break;
11002     }
11003
11004 #define _(a) found_something += a;
11005   foreach_udp_proto_field;
11006 #undef _
11007
11008   if (found_something == 0)
11009     return 0;
11010
11011   vec_validate (mask, sizeof (*udp) - 1);
11012
11013   udp = (udp_header_t *) mask;
11014
11015 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11016   foreach_udp_proto_field;
11017 #undef _
11018
11019   *maskp = mask;
11020   return 1;
11021 }
11022
11023 uword
11024 unformat_l4_mask (unformat_input_t * input, va_list * args)
11025 {
11026   u8 **maskp = va_arg (*args, u8 **);
11027   u16 src_port = 0, dst_port = 0;
11028   tcpudp_header_t *tcpudp;
11029
11030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11031     {
11032       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11033         return 1;
11034       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11035         return 1;
11036       else if (unformat (input, "src_port"))
11037         src_port = 0xFFFF;
11038       else if (unformat (input, "dst_port"))
11039         dst_port = 0xFFFF;
11040       else
11041         return 0;
11042     }
11043
11044   if (!src_port && !dst_port)
11045     return 0;
11046
11047   u8 *mask = 0;
11048   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11049
11050   tcpudp = (tcpudp_header_t *) mask;
11051   tcpudp->src_port = src_port;
11052   tcpudp->dst_port = dst_port;
11053
11054   *maskp = mask;
11055
11056   return 1;
11057 }
11058
11059 uword
11060 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11061 {
11062   u8 **maskp = va_arg (*args, u8 **);
11063   u8 *mask = 0;
11064   u8 found_something = 0;
11065   ip4_header_t *ip;
11066
11067 #define _(a) u8 a=0;
11068   foreach_ip4_proto_field;
11069 #undef _
11070   u8 version = 0;
11071   u8 hdr_length = 0;
11072
11073
11074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11075     {
11076       if (unformat (input, "version"))
11077         version = 1;
11078       else if (unformat (input, "hdr_length"))
11079         hdr_length = 1;
11080       else if (unformat (input, "src"))
11081         src_address = 1;
11082       else if (unformat (input, "dst"))
11083         dst_address = 1;
11084       else if (unformat (input, "proto"))
11085         protocol = 1;
11086
11087 #define _(a) else if (unformat (input, #a)) a=1;
11088       foreach_ip4_proto_field
11089 #undef _
11090         else
11091         break;
11092     }
11093
11094 #define _(a) found_something += a;
11095   foreach_ip4_proto_field;
11096 #undef _
11097
11098   if (found_something == 0)
11099     return 0;
11100
11101   vec_validate (mask, sizeof (*ip) - 1);
11102
11103   ip = (ip4_header_t *) mask;
11104
11105 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11106   foreach_ip4_proto_field;
11107 #undef _
11108
11109   ip->ip_version_and_header_length = 0;
11110
11111   if (version)
11112     ip->ip_version_and_header_length |= 0xF0;
11113
11114   if (hdr_length)
11115     ip->ip_version_and_header_length |= 0x0F;
11116
11117   *maskp = mask;
11118   return 1;
11119 }
11120
11121 #define foreach_ip6_proto_field                 \
11122 _(src_address)                                  \
11123 _(dst_address)                                  \
11124 _(payload_length)                               \
11125 _(hop_limit)                                    \
11126 _(protocol)
11127
11128 uword
11129 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11130 {
11131   u8 **maskp = va_arg (*args, u8 **);
11132   u8 *mask = 0;
11133   u8 found_something = 0;
11134   ip6_header_t *ip;
11135   u32 ip_version_traffic_class_and_flow_label;
11136
11137 #define _(a) u8 a=0;
11138   foreach_ip6_proto_field;
11139 #undef _
11140   u8 version = 0;
11141   u8 traffic_class = 0;
11142   u8 flow_label = 0;
11143
11144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11145     {
11146       if (unformat (input, "version"))
11147         version = 1;
11148       else if (unformat (input, "traffic-class"))
11149         traffic_class = 1;
11150       else if (unformat (input, "flow-label"))
11151         flow_label = 1;
11152       else if (unformat (input, "src"))
11153         src_address = 1;
11154       else if (unformat (input, "dst"))
11155         dst_address = 1;
11156       else if (unformat (input, "proto"))
11157         protocol = 1;
11158
11159 #define _(a) else if (unformat (input, #a)) a=1;
11160       foreach_ip6_proto_field
11161 #undef _
11162         else
11163         break;
11164     }
11165
11166 #define _(a) found_something += a;
11167   foreach_ip6_proto_field;
11168 #undef _
11169
11170   if (found_something == 0)
11171     return 0;
11172
11173   vec_validate (mask, sizeof (*ip) - 1);
11174
11175   ip = (ip6_header_t *) mask;
11176
11177 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11178   foreach_ip6_proto_field;
11179 #undef _
11180
11181   ip_version_traffic_class_and_flow_label = 0;
11182
11183   if (version)
11184     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11185
11186   if (traffic_class)
11187     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11188
11189   if (flow_label)
11190     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11191
11192   ip->ip_version_traffic_class_and_flow_label =
11193     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11194
11195   *maskp = mask;
11196   return 1;
11197 }
11198
11199 uword
11200 unformat_l3_mask (unformat_input_t * input, va_list * args)
11201 {
11202   u8 **maskp = va_arg (*args, u8 **);
11203
11204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11205     {
11206       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11207         return 1;
11208       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11209         return 1;
11210       else
11211         break;
11212     }
11213   return 0;
11214 }
11215
11216 uword
11217 unformat_l2_mask (unformat_input_t * input, va_list * args)
11218 {
11219   u8 **maskp = va_arg (*args, u8 **);
11220   u8 *mask = 0;
11221   u8 src = 0;
11222   u8 dst = 0;
11223   u8 proto = 0;
11224   u8 tag1 = 0;
11225   u8 tag2 = 0;
11226   u8 ignore_tag1 = 0;
11227   u8 ignore_tag2 = 0;
11228   u8 cos1 = 0;
11229   u8 cos2 = 0;
11230   u8 dot1q = 0;
11231   u8 dot1ad = 0;
11232   int len = 14;
11233
11234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11235     {
11236       if (unformat (input, "src"))
11237         src = 1;
11238       else if (unformat (input, "dst"))
11239         dst = 1;
11240       else if (unformat (input, "proto"))
11241         proto = 1;
11242       else if (unformat (input, "tag1"))
11243         tag1 = 1;
11244       else if (unformat (input, "tag2"))
11245         tag2 = 1;
11246       else if (unformat (input, "ignore-tag1"))
11247         ignore_tag1 = 1;
11248       else if (unformat (input, "ignore-tag2"))
11249         ignore_tag2 = 1;
11250       else if (unformat (input, "cos1"))
11251         cos1 = 1;
11252       else if (unformat (input, "cos2"))
11253         cos2 = 1;
11254       else if (unformat (input, "dot1q"))
11255         dot1q = 1;
11256       else if (unformat (input, "dot1ad"))
11257         dot1ad = 1;
11258       else
11259         break;
11260     }
11261   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11262        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11263     return 0;
11264
11265   if (tag1 || ignore_tag1 || cos1 || dot1q)
11266     len = 18;
11267   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11268     len = 22;
11269
11270   vec_validate (mask, len - 1);
11271
11272   if (dst)
11273     memset (mask, 0xff, 6);
11274
11275   if (src)
11276     memset (mask + 6, 0xff, 6);
11277
11278   if (tag2 || dot1ad)
11279     {
11280       /* inner vlan tag */
11281       if (tag2)
11282         {
11283           mask[19] = 0xff;
11284           mask[18] = 0x0f;
11285         }
11286       if (cos2)
11287         mask[18] |= 0xe0;
11288       if (proto)
11289         mask[21] = mask[20] = 0xff;
11290       if (tag1)
11291         {
11292           mask[15] = 0xff;
11293           mask[14] = 0x0f;
11294         }
11295       if (cos1)
11296         mask[14] |= 0xe0;
11297       *maskp = mask;
11298       return 1;
11299     }
11300   if (tag1 | dot1q)
11301     {
11302       if (tag1)
11303         {
11304           mask[15] = 0xff;
11305           mask[14] = 0x0f;
11306         }
11307       if (cos1)
11308         mask[14] |= 0xe0;
11309       if (proto)
11310         mask[16] = mask[17] = 0xff;
11311
11312       *maskp = mask;
11313       return 1;
11314     }
11315   if (cos2)
11316     mask[18] |= 0xe0;
11317   if (cos1)
11318     mask[14] |= 0xe0;
11319   if (proto)
11320     mask[12] = mask[13] = 0xff;
11321
11322   *maskp = mask;
11323   return 1;
11324 }
11325
11326 uword
11327 unformat_classify_mask (unformat_input_t * input, va_list * args)
11328 {
11329   u8 **maskp = va_arg (*args, u8 **);
11330   u32 *skipp = va_arg (*args, u32 *);
11331   u32 *matchp = va_arg (*args, u32 *);
11332   u32 match;
11333   u8 *mask = 0;
11334   u8 *l2 = 0;
11335   u8 *l3 = 0;
11336   u8 *l4 = 0;
11337   int i;
11338
11339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11340     {
11341       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11342         ;
11343       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11344         ;
11345       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11346         ;
11347       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11348         ;
11349       else
11350         break;
11351     }
11352
11353   if (l4 && !l3)
11354     {
11355       vec_free (mask);
11356       vec_free (l2);
11357       vec_free (l4);
11358       return 0;
11359     }
11360
11361   if (mask || l2 || l3 || l4)
11362     {
11363       if (l2 || l3 || l4)
11364         {
11365           /* "With a free Ethernet header in every package" */
11366           if (l2 == 0)
11367             vec_validate (l2, 13);
11368           mask = l2;
11369           if (vec_len (l3))
11370             {
11371               vec_append (mask, l3);
11372               vec_free (l3);
11373             }
11374           if (vec_len (l4))
11375             {
11376               vec_append (mask, l4);
11377               vec_free (l4);
11378             }
11379         }
11380
11381       /* Scan forward looking for the first significant mask octet */
11382       for (i = 0; i < vec_len (mask); i++)
11383         if (mask[i])
11384           break;
11385
11386       /* compute (skip, match) params */
11387       *skipp = i / sizeof (u32x4);
11388       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11389
11390       /* Pad mask to an even multiple of the vector size */
11391       while (vec_len (mask) % sizeof (u32x4))
11392         vec_add1 (mask, 0);
11393
11394       match = vec_len (mask) / sizeof (u32x4);
11395
11396       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11397         {
11398           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11399           if (*tmp || *(tmp + 1))
11400             break;
11401           match--;
11402         }
11403       if (match == 0)
11404         clib_warning ("BUG: match 0");
11405
11406       _vec_len (mask) = match * sizeof (u32x4);
11407
11408       *matchp = match;
11409       *maskp = mask;
11410
11411       return 1;
11412     }
11413
11414   return 0;
11415 }
11416 #endif /* VPP_API_TEST_BUILTIN */
11417
11418 #define foreach_l2_next                         \
11419 _(drop, DROP)                                   \
11420 _(ethernet, ETHERNET_INPUT)                     \
11421 _(ip4, IP4_INPUT)                               \
11422 _(ip6, IP6_INPUT)
11423
11424 uword
11425 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11426 {
11427   u32 *miss_next_indexp = va_arg (*args, u32 *);
11428   u32 next_index = 0;
11429   u32 tmp;
11430
11431 #define _(n,N) \
11432   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11433   foreach_l2_next;
11434 #undef _
11435
11436   if (unformat (input, "%d", &tmp))
11437     {
11438       next_index = tmp;
11439       goto out;
11440     }
11441
11442   return 0;
11443
11444 out:
11445   *miss_next_indexp = next_index;
11446   return 1;
11447 }
11448
11449 #define foreach_ip_next                         \
11450 _(drop, DROP)                                   \
11451 _(local, LOCAL)                                 \
11452 _(rewrite, REWRITE)
11453
11454 uword
11455 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11456 {
11457   u32 *miss_next_indexp = va_arg (*args, u32 *);
11458   u32 next_index = 0;
11459   u32 tmp;
11460
11461 #define _(n,N) \
11462   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11463   foreach_ip_next;
11464 #undef _
11465
11466   if (unformat (input, "%d", &tmp))
11467     {
11468       next_index = tmp;
11469       goto out;
11470     }
11471
11472   return 0;
11473
11474 out:
11475   *miss_next_indexp = next_index;
11476   return 1;
11477 }
11478
11479 #define foreach_acl_next                        \
11480 _(deny, DENY)
11481
11482 uword
11483 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11484 {
11485   u32 *miss_next_indexp = va_arg (*args, u32 *);
11486   u32 next_index = 0;
11487   u32 tmp;
11488
11489 #define _(n,N) \
11490   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11491   foreach_acl_next;
11492 #undef _
11493
11494   if (unformat (input, "permit"))
11495     {
11496       next_index = ~0;
11497       goto out;
11498     }
11499   else if (unformat (input, "%d", &tmp))
11500     {
11501       next_index = tmp;
11502       goto out;
11503     }
11504
11505   return 0;
11506
11507 out:
11508   *miss_next_indexp = next_index;
11509   return 1;
11510 }
11511
11512 uword
11513 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11514 {
11515   u32 *r = va_arg (*args, u32 *);
11516
11517   if (unformat (input, "conform-color"))
11518     *r = POLICE_CONFORM;
11519   else if (unformat (input, "exceed-color"))
11520     *r = POLICE_EXCEED;
11521   else
11522     return 0;
11523
11524   return 1;
11525 }
11526
11527 static int
11528 api_classify_add_del_table (vat_main_t * vam)
11529 {
11530   unformat_input_t *i = vam->input;
11531   vl_api_classify_add_del_table_t *mp;
11532
11533   u32 nbuckets = 2;
11534   u32 skip = ~0;
11535   u32 match = ~0;
11536   int is_add = 1;
11537   int del_chain = 0;
11538   u32 table_index = ~0;
11539   u32 next_table_index = ~0;
11540   u32 miss_next_index = ~0;
11541   u32 memory_size = 32 << 20;
11542   u8 *mask = 0;
11543   u32 current_data_flag = 0;
11544   int current_data_offset = 0;
11545   int ret;
11546
11547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11548     {
11549       if (unformat (i, "del"))
11550         is_add = 0;
11551       else if (unformat (i, "del-chain"))
11552         {
11553           is_add = 0;
11554           del_chain = 1;
11555         }
11556       else if (unformat (i, "buckets %d", &nbuckets))
11557         ;
11558       else if (unformat (i, "memory_size %d", &memory_size))
11559         ;
11560       else if (unformat (i, "skip %d", &skip))
11561         ;
11562       else if (unformat (i, "match %d", &match))
11563         ;
11564       else if (unformat (i, "table %d", &table_index))
11565         ;
11566       else if (unformat (i, "mask %U", unformat_classify_mask,
11567                          &mask, &skip, &match))
11568         ;
11569       else if (unformat (i, "next-table %d", &next_table_index))
11570         ;
11571       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11572                          &miss_next_index))
11573         ;
11574       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11575                          &miss_next_index))
11576         ;
11577       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11578                          &miss_next_index))
11579         ;
11580       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11581         ;
11582       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11583         ;
11584       else
11585         break;
11586     }
11587
11588   if (is_add && mask == 0)
11589     {
11590       errmsg ("Mask required");
11591       return -99;
11592     }
11593
11594   if (is_add && skip == ~0)
11595     {
11596       errmsg ("skip count required");
11597       return -99;
11598     }
11599
11600   if (is_add && match == ~0)
11601     {
11602       errmsg ("match count required");
11603       return -99;
11604     }
11605
11606   if (!is_add && table_index == ~0)
11607     {
11608       errmsg ("table index required for delete");
11609       return -99;
11610     }
11611
11612   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11613
11614   mp->is_add = is_add;
11615   mp->del_chain = del_chain;
11616   mp->table_index = ntohl (table_index);
11617   mp->nbuckets = ntohl (nbuckets);
11618   mp->memory_size = ntohl (memory_size);
11619   mp->skip_n_vectors = ntohl (skip);
11620   mp->match_n_vectors = ntohl (match);
11621   mp->next_table_index = ntohl (next_table_index);
11622   mp->miss_next_index = ntohl (miss_next_index);
11623   mp->current_data_flag = ntohl (current_data_flag);
11624   mp->current_data_offset = ntohl (current_data_offset);
11625   clib_memcpy (mp->mask, mask, vec_len (mask));
11626
11627   vec_free (mask);
11628
11629   S (mp);
11630   W (ret);
11631   return ret;
11632 }
11633
11634 #if VPP_API_TEST_BUILTIN == 0
11635 uword
11636 unformat_l4_match (unformat_input_t * input, va_list * args)
11637 {
11638   u8 **matchp = va_arg (*args, u8 **);
11639
11640   u8 *proto_header = 0;
11641   int src_port = 0;
11642   int dst_port = 0;
11643
11644   tcpudp_header_t h;
11645
11646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (input, "src_port %d", &src_port))
11649         ;
11650       else if (unformat (input, "dst_port %d", &dst_port))
11651         ;
11652       else
11653         return 0;
11654     }
11655
11656   h.src_port = clib_host_to_net_u16 (src_port);
11657   h.dst_port = clib_host_to_net_u16 (dst_port);
11658   vec_validate (proto_header, sizeof (h) - 1);
11659   memcpy (proto_header, &h, sizeof (h));
11660
11661   *matchp = proto_header;
11662
11663   return 1;
11664 }
11665
11666 uword
11667 unformat_ip4_match (unformat_input_t * input, va_list * args)
11668 {
11669   u8 **matchp = va_arg (*args, u8 **);
11670   u8 *match = 0;
11671   ip4_header_t *ip;
11672   int version = 0;
11673   u32 version_val;
11674   int hdr_length = 0;
11675   u32 hdr_length_val;
11676   int src = 0, dst = 0;
11677   ip4_address_t src_val, dst_val;
11678   int proto = 0;
11679   u32 proto_val;
11680   int tos = 0;
11681   u32 tos_val;
11682   int length = 0;
11683   u32 length_val;
11684   int fragment_id = 0;
11685   u32 fragment_id_val;
11686   int ttl = 0;
11687   int ttl_val;
11688   int checksum = 0;
11689   u32 checksum_val;
11690
11691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11692     {
11693       if (unformat (input, "version %d", &version_val))
11694         version = 1;
11695       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11696         hdr_length = 1;
11697       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11698         src = 1;
11699       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11700         dst = 1;
11701       else if (unformat (input, "proto %d", &proto_val))
11702         proto = 1;
11703       else if (unformat (input, "tos %d", &tos_val))
11704         tos = 1;
11705       else if (unformat (input, "length %d", &length_val))
11706         length = 1;
11707       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11708         fragment_id = 1;
11709       else if (unformat (input, "ttl %d", &ttl_val))
11710         ttl = 1;
11711       else if (unformat (input, "checksum %d", &checksum_val))
11712         checksum = 1;
11713       else
11714         break;
11715     }
11716
11717   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11718       + ttl + checksum == 0)
11719     return 0;
11720
11721   /*
11722    * Aligned because we use the real comparison functions
11723    */
11724   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11725
11726   ip = (ip4_header_t *) match;
11727
11728   /* These are realistically matched in practice */
11729   if (src)
11730     ip->src_address.as_u32 = src_val.as_u32;
11731
11732   if (dst)
11733     ip->dst_address.as_u32 = dst_val.as_u32;
11734
11735   if (proto)
11736     ip->protocol = proto_val;
11737
11738
11739   /* These are not, but they're included for completeness */
11740   if (version)
11741     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11742
11743   if (hdr_length)
11744     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11745
11746   if (tos)
11747     ip->tos = tos_val;
11748
11749   if (length)
11750     ip->length = clib_host_to_net_u16 (length_val);
11751
11752   if (ttl)
11753     ip->ttl = ttl_val;
11754
11755   if (checksum)
11756     ip->checksum = clib_host_to_net_u16 (checksum_val);
11757
11758   *matchp = match;
11759   return 1;
11760 }
11761
11762 uword
11763 unformat_ip6_match (unformat_input_t * input, va_list * args)
11764 {
11765   u8 **matchp = va_arg (*args, u8 **);
11766   u8 *match = 0;
11767   ip6_header_t *ip;
11768   int version = 0;
11769   u32 version_val;
11770   u8 traffic_class = 0;
11771   u32 traffic_class_val = 0;
11772   u8 flow_label = 0;
11773   u8 flow_label_val;
11774   int src = 0, dst = 0;
11775   ip6_address_t src_val, dst_val;
11776   int proto = 0;
11777   u32 proto_val;
11778   int payload_length = 0;
11779   u32 payload_length_val;
11780   int hop_limit = 0;
11781   int hop_limit_val;
11782   u32 ip_version_traffic_class_and_flow_label;
11783
11784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11785     {
11786       if (unformat (input, "version %d", &version_val))
11787         version = 1;
11788       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11789         traffic_class = 1;
11790       else if (unformat (input, "flow_label %d", &flow_label_val))
11791         flow_label = 1;
11792       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11793         src = 1;
11794       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11795         dst = 1;
11796       else if (unformat (input, "proto %d", &proto_val))
11797         proto = 1;
11798       else if (unformat (input, "payload_length %d", &payload_length_val))
11799         payload_length = 1;
11800       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11801         hop_limit = 1;
11802       else
11803         break;
11804     }
11805
11806   if (version + traffic_class + flow_label + src + dst + proto +
11807       payload_length + hop_limit == 0)
11808     return 0;
11809
11810   /*
11811    * Aligned because we use the real comparison functions
11812    */
11813   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11814
11815   ip = (ip6_header_t *) match;
11816
11817   if (src)
11818     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11819
11820   if (dst)
11821     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11822
11823   if (proto)
11824     ip->protocol = proto_val;
11825
11826   ip_version_traffic_class_and_flow_label = 0;
11827
11828   if (version)
11829     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11830
11831   if (traffic_class)
11832     ip_version_traffic_class_and_flow_label |=
11833       (traffic_class_val & 0xFF) << 20;
11834
11835   if (flow_label)
11836     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11837
11838   ip->ip_version_traffic_class_and_flow_label =
11839     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11840
11841   if (payload_length)
11842     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11843
11844   if (hop_limit)
11845     ip->hop_limit = hop_limit_val;
11846
11847   *matchp = match;
11848   return 1;
11849 }
11850
11851 uword
11852 unformat_l3_match (unformat_input_t * input, va_list * args)
11853 {
11854   u8 **matchp = va_arg (*args, u8 **);
11855
11856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11857     {
11858       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11859         return 1;
11860       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11861         return 1;
11862       else
11863         break;
11864     }
11865   return 0;
11866 }
11867
11868 uword
11869 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11870 {
11871   u8 *tagp = va_arg (*args, u8 *);
11872   u32 tag;
11873
11874   if (unformat (input, "%d", &tag))
11875     {
11876       tagp[0] = (tag >> 8) & 0x0F;
11877       tagp[1] = tag & 0xFF;
11878       return 1;
11879     }
11880
11881   return 0;
11882 }
11883
11884 uword
11885 unformat_l2_match (unformat_input_t * input, va_list * args)
11886 {
11887   u8 **matchp = va_arg (*args, u8 **);
11888   u8 *match = 0;
11889   u8 src = 0;
11890   u8 src_val[6];
11891   u8 dst = 0;
11892   u8 dst_val[6];
11893   u8 proto = 0;
11894   u16 proto_val;
11895   u8 tag1 = 0;
11896   u8 tag1_val[2];
11897   u8 tag2 = 0;
11898   u8 tag2_val[2];
11899   int len = 14;
11900   u8 ignore_tag1 = 0;
11901   u8 ignore_tag2 = 0;
11902   u8 cos1 = 0;
11903   u8 cos2 = 0;
11904   u32 cos1_val = 0;
11905   u32 cos2_val = 0;
11906
11907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11908     {
11909       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11910         src = 1;
11911       else
11912         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11913         dst = 1;
11914       else if (unformat (input, "proto %U",
11915                          unformat_ethernet_type_host_byte_order, &proto_val))
11916         proto = 1;
11917       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11918         tag1 = 1;
11919       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11920         tag2 = 1;
11921       else if (unformat (input, "ignore-tag1"))
11922         ignore_tag1 = 1;
11923       else if (unformat (input, "ignore-tag2"))
11924         ignore_tag2 = 1;
11925       else if (unformat (input, "cos1 %d", &cos1_val))
11926         cos1 = 1;
11927       else if (unformat (input, "cos2 %d", &cos2_val))
11928         cos2 = 1;
11929       else
11930         break;
11931     }
11932   if ((src + dst + proto + tag1 + tag2 +
11933        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11934     return 0;
11935
11936   if (tag1 || ignore_tag1 || cos1)
11937     len = 18;
11938   if (tag2 || ignore_tag2 || cos2)
11939     len = 22;
11940
11941   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11942
11943   if (dst)
11944     clib_memcpy (match, dst_val, 6);
11945
11946   if (src)
11947     clib_memcpy (match + 6, src_val, 6);
11948
11949   if (tag2)
11950     {
11951       /* inner vlan tag */
11952       match[19] = tag2_val[1];
11953       match[18] = tag2_val[0];
11954       if (cos2)
11955         match[18] |= (cos2_val & 0x7) << 5;
11956       if (proto)
11957         {
11958           match[21] = proto_val & 0xff;
11959           match[20] = proto_val >> 8;
11960         }
11961       if (tag1)
11962         {
11963           match[15] = tag1_val[1];
11964           match[14] = tag1_val[0];
11965         }
11966       if (cos1)
11967         match[14] |= (cos1_val & 0x7) << 5;
11968       *matchp = match;
11969       return 1;
11970     }
11971   if (tag1)
11972     {
11973       match[15] = tag1_val[1];
11974       match[14] = tag1_val[0];
11975       if (proto)
11976         {
11977           match[17] = proto_val & 0xff;
11978           match[16] = proto_val >> 8;
11979         }
11980       if (cos1)
11981         match[14] |= (cos1_val & 0x7) << 5;
11982
11983       *matchp = match;
11984       return 1;
11985     }
11986   if (cos2)
11987     match[18] |= (cos2_val & 0x7) << 5;
11988   if (cos1)
11989     match[14] |= (cos1_val & 0x7) << 5;
11990   if (proto)
11991     {
11992       match[13] = proto_val & 0xff;
11993       match[12] = proto_val >> 8;
11994     }
11995
11996   *matchp = match;
11997   return 1;
11998 }
11999 #endif
12000
12001 uword
12002 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12003 {
12004   u8 **matchp = va_arg (*args, u8 **);
12005   u32 skip_n_vectors = va_arg (*args, u32);
12006   u32 match_n_vectors = va_arg (*args, u32);
12007
12008   u8 *match = 0;
12009   u8 *l2 = 0;
12010   u8 *l3 = 0;
12011   u8 *l4 = 0;
12012
12013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12014     {
12015       if (unformat (input, "hex %U", unformat_hex_string, &match))
12016         ;
12017       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12018         ;
12019       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12020         ;
12021       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12022         ;
12023       else
12024         break;
12025     }
12026
12027   if (l4 && !l3)
12028     {
12029       vec_free (match);
12030       vec_free (l2);
12031       vec_free (l4);
12032       return 0;
12033     }
12034
12035   if (match || l2 || l3 || l4)
12036     {
12037       if (l2 || l3 || l4)
12038         {
12039           /* "Win a free Ethernet header in every packet" */
12040           if (l2 == 0)
12041             vec_validate_aligned (l2, 13, sizeof (u32x4));
12042           match = l2;
12043           if (vec_len (l3))
12044             {
12045               vec_append_aligned (match, l3, sizeof (u32x4));
12046               vec_free (l3);
12047             }
12048           if (vec_len (l4))
12049             {
12050               vec_append_aligned (match, l4, sizeof (u32x4));
12051               vec_free (l4);
12052             }
12053         }
12054
12055       /* Make sure the vector is big enough even if key is all 0's */
12056       vec_validate_aligned
12057         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12058          sizeof (u32x4));
12059
12060       /* Set size, include skipped vectors */
12061       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12062
12063       *matchp = match;
12064
12065       return 1;
12066     }
12067
12068   return 0;
12069 }
12070
12071 static int
12072 api_classify_add_del_session (vat_main_t * vam)
12073 {
12074   unformat_input_t *i = vam->input;
12075   vl_api_classify_add_del_session_t *mp;
12076   int is_add = 1;
12077   u32 table_index = ~0;
12078   u32 hit_next_index = ~0;
12079   u32 opaque_index = ~0;
12080   u8 *match = 0;
12081   i32 advance = 0;
12082   u32 skip_n_vectors = 0;
12083   u32 match_n_vectors = 0;
12084   u32 action = 0;
12085   u32 metadata = 0;
12086   int ret;
12087
12088   /*
12089    * Warning: you have to supply skip_n and match_n
12090    * because the API client cant simply look at the classify
12091    * table object.
12092    */
12093
12094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12095     {
12096       if (unformat (i, "del"))
12097         is_add = 0;
12098       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12099                          &hit_next_index))
12100         ;
12101       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12102                          &hit_next_index))
12103         ;
12104       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12105                          &hit_next_index))
12106         ;
12107       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12108         ;
12109       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12110         ;
12111       else if (unformat (i, "opaque-index %d", &opaque_index))
12112         ;
12113       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12114         ;
12115       else if (unformat (i, "match_n %d", &match_n_vectors))
12116         ;
12117       else if (unformat (i, "match %U", api_unformat_classify_match,
12118                          &match, skip_n_vectors, match_n_vectors))
12119         ;
12120       else if (unformat (i, "advance %d", &advance))
12121         ;
12122       else if (unformat (i, "table-index %d", &table_index))
12123         ;
12124       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12125         action = 1;
12126       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12127         action = 2;
12128       else if (unformat (i, "action %d", &action))
12129         ;
12130       else if (unformat (i, "metadata %d", &metadata))
12131         ;
12132       else
12133         break;
12134     }
12135
12136   if (table_index == ~0)
12137     {
12138       errmsg ("Table index required");
12139       return -99;
12140     }
12141
12142   if (is_add && match == 0)
12143     {
12144       errmsg ("Match value required");
12145       return -99;
12146     }
12147
12148   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12149
12150   mp->is_add = is_add;
12151   mp->table_index = ntohl (table_index);
12152   mp->hit_next_index = ntohl (hit_next_index);
12153   mp->opaque_index = ntohl (opaque_index);
12154   mp->advance = ntohl (advance);
12155   mp->action = action;
12156   mp->metadata = ntohl (metadata);
12157   clib_memcpy (mp->match, match, vec_len (match));
12158   vec_free (match);
12159
12160   S (mp);
12161   W (ret);
12162   return ret;
12163 }
12164
12165 static int
12166 api_classify_set_interface_ip_table (vat_main_t * vam)
12167 {
12168   unformat_input_t *i = vam->input;
12169   vl_api_classify_set_interface_ip_table_t *mp;
12170   u32 sw_if_index;
12171   int sw_if_index_set;
12172   u32 table_index = ~0;
12173   u8 is_ipv6 = 0;
12174   int ret;
12175
12176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12177     {
12178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12179         sw_if_index_set = 1;
12180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12181         sw_if_index_set = 1;
12182       else if (unformat (i, "table %d", &table_index))
12183         ;
12184       else
12185         {
12186           clib_warning ("parse error '%U'", format_unformat_error, i);
12187           return -99;
12188         }
12189     }
12190
12191   if (sw_if_index_set == 0)
12192     {
12193       errmsg ("missing interface name or sw_if_index");
12194       return -99;
12195     }
12196
12197
12198   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12199
12200   mp->sw_if_index = ntohl (sw_if_index);
12201   mp->table_index = ntohl (table_index);
12202   mp->is_ipv6 = is_ipv6;
12203
12204   S (mp);
12205   W (ret);
12206   return ret;
12207 }
12208
12209 static int
12210 api_classify_set_interface_l2_tables (vat_main_t * vam)
12211 {
12212   unformat_input_t *i = vam->input;
12213   vl_api_classify_set_interface_l2_tables_t *mp;
12214   u32 sw_if_index;
12215   int sw_if_index_set;
12216   u32 ip4_table_index = ~0;
12217   u32 ip6_table_index = ~0;
12218   u32 other_table_index = ~0;
12219   u32 is_input = 1;
12220   int ret;
12221
12222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12225         sw_if_index_set = 1;
12226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12227         sw_if_index_set = 1;
12228       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12229         ;
12230       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12231         ;
12232       else if (unformat (i, "other-table %d", &other_table_index))
12233         ;
12234       else if (unformat (i, "is-input %d", &is_input))
12235         ;
12236       else
12237         {
12238           clib_warning ("parse error '%U'", format_unformat_error, i);
12239           return -99;
12240         }
12241     }
12242
12243   if (sw_if_index_set == 0)
12244     {
12245       errmsg ("missing interface name or sw_if_index");
12246       return -99;
12247     }
12248
12249
12250   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12251
12252   mp->sw_if_index = ntohl (sw_if_index);
12253   mp->ip4_table_index = ntohl (ip4_table_index);
12254   mp->ip6_table_index = ntohl (ip6_table_index);
12255   mp->other_table_index = ntohl (other_table_index);
12256   mp->is_input = (u8) is_input;
12257
12258   S (mp);
12259   W (ret);
12260   return ret;
12261 }
12262
12263 static int
12264 api_set_ipfix_exporter (vat_main_t * vam)
12265 {
12266   unformat_input_t *i = vam->input;
12267   vl_api_set_ipfix_exporter_t *mp;
12268   ip4_address_t collector_address;
12269   u8 collector_address_set = 0;
12270   u32 collector_port = ~0;
12271   ip4_address_t src_address;
12272   u8 src_address_set = 0;
12273   u32 vrf_id = ~0;
12274   u32 path_mtu = ~0;
12275   u32 template_interval = ~0;
12276   u8 udp_checksum = 0;
12277   int ret;
12278
12279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12280     {
12281       if (unformat (i, "collector_address %U", unformat_ip4_address,
12282                     &collector_address))
12283         collector_address_set = 1;
12284       else if (unformat (i, "collector_port %d", &collector_port))
12285         ;
12286       else if (unformat (i, "src_address %U", unformat_ip4_address,
12287                          &src_address))
12288         src_address_set = 1;
12289       else if (unformat (i, "vrf_id %d", &vrf_id))
12290         ;
12291       else if (unformat (i, "path_mtu %d", &path_mtu))
12292         ;
12293       else if (unformat (i, "template_interval %d", &template_interval))
12294         ;
12295       else if (unformat (i, "udp_checksum"))
12296         udp_checksum = 1;
12297       else
12298         break;
12299     }
12300
12301   if (collector_address_set == 0)
12302     {
12303       errmsg ("collector_address required");
12304       return -99;
12305     }
12306
12307   if (src_address_set == 0)
12308     {
12309       errmsg ("src_address required");
12310       return -99;
12311     }
12312
12313   M (SET_IPFIX_EXPORTER, mp);
12314
12315   memcpy (mp->collector_address, collector_address.data,
12316           sizeof (collector_address.data));
12317   mp->collector_port = htons ((u16) collector_port);
12318   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12319   mp->vrf_id = htonl (vrf_id);
12320   mp->path_mtu = htonl (path_mtu);
12321   mp->template_interval = htonl (template_interval);
12322   mp->udp_checksum = udp_checksum;
12323
12324   S (mp);
12325   W (ret);
12326   return ret;
12327 }
12328
12329 static int
12330 api_set_ipfix_classify_stream (vat_main_t * vam)
12331 {
12332   unformat_input_t *i = vam->input;
12333   vl_api_set_ipfix_classify_stream_t *mp;
12334   u32 domain_id = 0;
12335   u32 src_port = UDP_DST_PORT_ipfix;
12336   int ret;
12337
12338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12339     {
12340       if (unformat (i, "domain %d", &domain_id))
12341         ;
12342       else if (unformat (i, "src_port %d", &src_port))
12343         ;
12344       else
12345         {
12346           errmsg ("unknown input `%U'", format_unformat_error, i);
12347           return -99;
12348         }
12349     }
12350
12351   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12352
12353   mp->domain_id = htonl (domain_id);
12354   mp->src_port = htons ((u16) src_port);
12355
12356   S (mp);
12357   W (ret);
12358   return ret;
12359 }
12360
12361 static int
12362 api_ipfix_classify_table_add_del (vat_main_t * vam)
12363 {
12364   unformat_input_t *i = vam->input;
12365   vl_api_ipfix_classify_table_add_del_t *mp;
12366   int is_add = -1;
12367   u32 classify_table_index = ~0;
12368   u8 ip_version = 0;
12369   u8 transport_protocol = 255;
12370   int ret;
12371
12372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (i, "add"))
12375         is_add = 1;
12376       else if (unformat (i, "del"))
12377         is_add = 0;
12378       else if (unformat (i, "table %d", &classify_table_index))
12379         ;
12380       else if (unformat (i, "ip4"))
12381         ip_version = 4;
12382       else if (unformat (i, "ip6"))
12383         ip_version = 6;
12384       else if (unformat (i, "tcp"))
12385         transport_protocol = 6;
12386       else if (unformat (i, "udp"))
12387         transport_protocol = 17;
12388       else
12389         {
12390           errmsg ("unknown input `%U'", format_unformat_error, i);
12391           return -99;
12392         }
12393     }
12394
12395   if (is_add == -1)
12396     {
12397       errmsg ("expecting: add|del");
12398       return -99;
12399     }
12400   if (classify_table_index == ~0)
12401     {
12402       errmsg ("classifier table not specified");
12403       return -99;
12404     }
12405   if (ip_version == 0)
12406     {
12407       errmsg ("IP version not specified");
12408       return -99;
12409     }
12410
12411   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12412
12413   mp->is_add = is_add;
12414   mp->table_id = htonl (classify_table_index);
12415   mp->ip_version = ip_version;
12416   mp->transport_protocol = transport_protocol;
12417
12418   S (mp);
12419   W (ret);
12420   return ret;
12421 }
12422
12423 static int
12424 api_get_node_index (vat_main_t * vam)
12425 {
12426   unformat_input_t *i = vam->input;
12427   vl_api_get_node_index_t *mp;
12428   u8 *name = 0;
12429   int ret;
12430
12431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12432     {
12433       if (unformat (i, "node %s", &name))
12434         ;
12435       else
12436         break;
12437     }
12438   if (name == 0)
12439     {
12440       errmsg ("node name required");
12441       return -99;
12442     }
12443   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12444     {
12445       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12446       return -99;
12447     }
12448
12449   M (GET_NODE_INDEX, mp);
12450   clib_memcpy (mp->node_name, name, vec_len (name));
12451   vec_free (name);
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static int
12459 api_get_next_index (vat_main_t * vam)
12460 {
12461   unformat_input_t *i = vam->input;
12462   vl_api_get_next_index_t *mp;
12463   u8 *node_name = 0, *next_node_name = 0;
12464   int ret;
12465
12466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12467     {
12468       if (unformat (i, "node-name %s", &node_name))
12469         ;
12470       else if (unformat (i, "next-node-name %s", &next_node_name))
12471         break;
12472     }
12473
12474   if (node_name == 0)
12475     {
12476       errmsg ("node name required");
12477       return -99;
12478     }
12479   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12480     {
12481       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12482       return -99;
12483     }
12484
12485   if (next_node_name == 0)
12486     {
12487       errmsg ("next node name required");
12488       return -99;
12489     }
12490   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12491     {
12492       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12493       return -99;
12494     }
12495
12496   M (GET_NEXT_INDEX, mp);
12497   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12498   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12499   vec_free (node_name);
12500   vec_free (next_node_name);
12501
12502   S (mp);
12503   W (ret);
12504   return ret;
12505 }
12506
12507 static int
12508 api_add_node_next (vat_main_t * vam)
12509 {
12510   unformat_input_t *i = vam->input;
12511   vl_api_add_node_next_t *mp;
12512   u8 *name = 0;
12513   u8 *next = 0;
12514   int ret;
12515
12516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12517     {
12518       if (unformat (i, "node %s", &name))
12519         ;
12520       else if (unformat (i, "next %s", &next))
12521         ;
12522       else
12523         break;
12524     }
12525   if (name == 0)
12526     {
12527       errmsg ("node name required");
12528       return -99;
12529     }
12530   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12531     {
12532       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12533       return -99;
12534     }
12535   if (next == 0)
12536     {
12537       errmsg ("next node required");
12538       return -99;
12539     }
12540   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12541     {
12542       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12543       return -99;
12544     }
12545
12546   M (ADD_NODE_NEXT, mp);
12547   clib_memcpy (mp->node_name, name, vec_len (name));
12548   clib_memcpy (mp->next_name, next, vec_len (next));
12549   vec_free (name);
12550   vec_free (next);
12551
12552   S (mp);
12553   W (ret);
12554   return ret;
12555 }
12556
12557 static int
12558 api_l2tpv3_create_tunnel (vat_main_t * vam)
12559 {
12560   unformat_input_t *i = vam->input;
12561   ip6_address_t client_address, our_address;
12562   int client_address_set = 0;
12563   int our_address_set = 0;
12564   u32 local_session_id = 0;
12565   u32 remote_session_id = 0;
12566   u64 local_cookie = 0;
12567   u64 remote_cookie = 0;
12568   u8 l2_sublayer_present = 0;
12569   vl_api_l2tpv3_create_tunnel_t *mp;
12570   int ret;
12571
12572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12573     {
12574       if (unformat (i, "client_address %U", unformat_ip6_address,
12575                     &client_address))
12576         client_address_set = 1;
12577       else if (unformat (i, "our_address %U", unformat_ip6_address,
12578                          &our_address))
12579         our_address_set = 1;
12580       else if (unformat (i, "local_session_id %d", &local_session_id))
12581         ;
12582       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12583         ;
12584       else if (unformat (i, "local_cookie %lld", &local_cookie))
12585         ;
12586       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12587         ;
12588       else if (unformat (i, "l2-sublayer-present"))
12589         l2_sublayer_present = 1;
12590       else
12591         break;
12592     }
12593
12594   if (client_address_set == 0)
12595     {
12596       errmsg ("client_address required");
12597       return -99;
12598     }
12599
12600   if (our_address_set == 0)
12601     {
12602       errmsg ("our_address required");
12603       return -99;
12604     }
12605
12606   M (L2TPV3_CREATE_TUNNEL, mp);
12607
12608   clib_memcpy (mp->client_address, client_address.as_u8,
12609                sizeof (mp->client_address));
12610
12611   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12612
12613   mp->local_session_id = ntohl (local_session_id);
12614   mp->remote_session_id = ntohl (remote_session_id);
12615   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12616   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12617   mp->l2_sublayer_present = l2_sublayer_present;
12618   mp->is_ipv6 = 1;
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static int
12626 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12627 {
12628   unformat_input_t *i = vam->input;
12629   u32 sw_if_index;
12630   u8 sw_if_index_set = 0;
12631   u64 new_local_cookie = 0;
12632   u64 new_remote_cookie = 0;
12633   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12634   int ret;
12635
12636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12637     {
12638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12639         sw_if_index_set = 1;
12640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12641         sw_if_index_set = 1;
12642       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12643         ;
12644       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12645         ;
12646       else
12647         break;
12648     }
12649
12650   if (sw_if_index_set == 0)
12651     {
12652       errmsg ("missing interface name or sw_if_index");
12653       return -99;
12654     }
12655
12656   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12657
12658   mp->sw_if_index = ntohl (sw_if_index);
12659   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12660   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12661
12662   S (mp);
12663   W (ret);
12664   return ret;
12665 }
12666
12667 static int
12668 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12669 {
12670   unformat_input_t *i = vam->input;
12671   vl_api_l2tpv3_interface_enable_disable_t *mp;
12672   u32 sw_if_index;
12673   u8 sw_if_index_set = 0;
12674   u8 enable_disable = 1;
12675   int ret;
12676
12677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12678     {
12679       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12680         sw_if_index_set = 1;
12681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12682         sw_if_index_set = 1;
12683       else if (unformat (i, "enable"))
12684         enable_disable = 1;
12685       else if (unformat (i, "disable"))
12686         enable_disable = 0;
12687       else
12688         break;
12689     }
12690
12691   if (sw_if_index_set == 0)
12692     {
12693       errmsg ("missing interface name or sw_if_index");
12694       return -99;
12695     }
12696
12697   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12698
12699   mp->sw_if_index = ntohl (sw_if_index);
12700   mp->enable_disable = enable_disable;
12701
12702   S (mp);
12703   W (ret);
12704   return ret;
12705 }
12706
12707 static int
12708 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12709 {
12710   unformat_input_t *i = vam->input;
12711   vl_api_l2tpv3_set_lookup_key_t *mp;
12712   u8 key = ~0;
12713   int ret;
12714
12715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12716     {
12717       if (unformat (i, "lookup_v6_src"))
12718         key = L2T_LOOKUP_SRC_ADDRESS;
12719       else if (unformat (i, "lookup_v6_dst"))
12720         key = L2T_LOOKUP_DST_ADDRESS;
12721       else if (unformat (i, "lookup_session_id"))
12722         key = L2T_LOOKUP_SESSION_ID;
12723       else
12724         break;
12725     }
12726
12727   if (key == (u8) ~ 0)
12728     {
12729       errmsg ("l2tp session lookup key unset");
12730       return -99;
12731     }
12732
12733   M (L2TPV3_SET_LOOKUP_KEY, mp);
12734
12735   mp->key = key;
12736
12737   S (mp);
12738   W (ret);
12739   return ret;
12740 }
12741
12742 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12743   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12744 {
12745   vat_main_t *vam = &vat_main;
12746
12747   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12748          format_ip6_address, mp->our_address,
12749          format_ip6_address, mp->client_address,
12750          clib_net_to_host_u32 (mp->sw_if_index));
12751
12752   print (vam->ofp,
12753          "   local cookies %016llx %016llx remote cookie %016llx",
12754          clib_net_to_host_u64 (mp->local_cookie[0]),
12755          clib_net_to_host_u64 (mp->local_cookie[1]),
12756          clib_net_to_host_u64 (mp->remote_cookie));
12757
12758   print (vam->ofp, "   local session-id %d remote session-id %d",
12759          clib_net_to_host_u32 (mp->local_session_id),
12760          clib_net_to_host_u32 (mp->remote_session_id));
12761
12762   print (vam->ofp, "   l2 specific sublayer %s\n",
12763          mp->l2_sublayer_present ? "preset" : "absent");
12764
12765 }
12766
12767 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12768   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12769 {
12770   vat_main_t *vam = &vat_main;
12771   vat_json_node_t *node = NULL;
12772   struct in6_addr addr;
12773
12774   if (VAT_JSON_ARRAY != vam->json_tree.type)
12775     {
12776       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12777       vat_json_init_array (&vam->json_tree);
12778     }
12779   node = vat_json_array_add (&vam->json_tree);
12780
12781   vat_json_init_object (node);
12782
12783   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12784   vat_json_object_add_ip6 (node, "our_address", addr);
12785   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12786   vat_json_object_add_ip6 (node, "client_address", addr);
12787
12788   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12789   vat_json_init_array (lc);
12790   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12791   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12792   vat_json_object_add_uint (node, "remote_cookie",
12793                             clib_net_to_host_u64 (mp->remote_cookie));
12794
12795   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12796   vat_json_object_add_uint (node, "local_session_id",
12797                             clib_net_to_host_u32 (mp->local_session_id));
12798   vat_json_object_add_uint (node, "remote_session_id",
12799                             clib_net_to_host_u32 (mp->remote_session_id));
12800   vat_json_object_add_string_copy (node, "l2_sublayer",
12801                                    mp->l2_sublayer_present ? (u8 *) "present"
12802                                    : (u8 *) "absent");
12803 }
12804
12805 static int
12806 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12807 {
12808   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12809   vl_api_control_ping_t *mp_ping;
12810   int ret;
12811
12812   /* Get list of l2tpv3-tunnel interfaces */
12813   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12814   S (mp);
12815
12816   /* Use a control ping for synchronization */
12817   MPING (CONTROL_PING, mp_ping);
12818   S (mp_ping);
12819
12820   W (ret);
12821   return ret;
12822 }
12823
12824
12825 static void vl_api_sw_interface_tap_details_t_handler
12826   (vl_api_sw_interface_tap_details_t * mp)
12827 {
12828   vat_main_t *vam = &vat_main;
12829
12830   print (vam->ofp, "%-16s %d",
12831          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12832 }
12833
12834 static void vl_api_sw_interface_tap_details_t_handler_json
12835   (vl_api_sw_interface_tap_details_t * mp)
12836 {
12837   vat_main_t *vam = &vat_main;
12838   vat_json_node_t *node = NULL;
12839
12840   if (VAT_JSON_ARRAY != vam->json_tree.type)
12841     {
12842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12843       vat_json_init_array (&vam->json_tree);
12844     }
12845   node = vat_json_array_add (&vam->json_tree);
12846
12847   vat_json_init_object (node);
12848   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12849   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12850 }
12851
12852 static int
12853 api_sw_interface_tap_dump (vat_main_t * vam)
12854 {
12855   vl_api_sw_interface_tap_dump_t *mp;
12856   vl_api_control_ping_t *mp_ping;
12857   int ret;
12858
12859   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12860   /* Get list of tap interfaces */
12861   M (SW_INTERFACE_TAP_DUMP, mp);
12862   S (mp);
12863
12864   /* Use a control ping for synchronization */
12865   MPING (CONTROL_PING, mp_ping);
12866   S (mp_ping);
12867
12868   W (ret);
12869   return ret;
12870 }
12871
12872 static void vl_api_sw_interface_tap_v2_details_t_handler
12873   (vl_api_sw_interface_tap_v2_details_t * mp)
12874 {
12875   vat_main_t *vam = &vat_main;
12876
12877   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12878                     mp->host_ip4_prefix_len);
12879   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12880                     mp->host_ip6_prefix_len);
12881
12882   print (vam->ofp,
12883          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12884          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12885          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12886          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12887          mp->host_bridge, ip4, ip6);
12888
12889   vec_free (ip4);
12890   vec_free (ip6);
12891 }
12892
12893 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12894   (vl_api_sw_interface_tap_v2_details_t * mp)
12895 {
12896   vat_main_t *vam = &vat_main;
12897   vat_json_node_t *node = NULL;
12898
12899   if (VAT_JSON_ARRAY != vam->json_tree.type)
12900     {
12901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12902       vat_json_init_array (&vam->json_tree);
12903     }
12904   node = vat_json_array_add (&vam->json_tree);
12905
12906   vat_json_init_object (node);
12907   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12908   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12909   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12910   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12911   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12912   vat_json_object_add_string_copy (node, "host_mac_addr",
12913                                    format (0, "%U", format_ethernet_address,
12914                                            &mp->host_mac_addr));
12915   vat_json_object_add_string_copy (node, "host_namespace",
12916                                    mp->host_namespace);
12917   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12918   vat_json_object_add_string_copy (node, "host_ip4_addr",
12919                                    format (0, "%U/%d", format_ip4_address,
12920                                            mp->host_ip4_addr,
12921                                            mp->host_ip4_prefix_len));
12922   vat_json_object_add_string_copy (node, "host_ip6_addr",
12923                                    format (0, "%U/%d", format_ip6_address,
12924                                            mp->host_ip6_addr,
12925                                            mp->host_ip6_prefix_len));
12926
12927 }
12928
12929 static int
12930 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12931 {
12932   vl_api_sw_interface_tap_v2_dump_t *mp;
12933   vl_api_control_ping_t *mp_ping;
12934   int ret;
12935
12936   print (vam->ofp,
12937          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12938          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12939          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12940          "host_ip6_addr");
12941
12942   /* Get list of tap interfaces */
12943   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12944   S (mp);
12945
12946   /* Use a control ping for synchronization */
12947   MPING (CONTROL_PING, mp_ping);
12948   S (mp_ping);
12949
12950   W (ret);
12951   return ret;
12952 }
12953
12954 static uword unformat_vxlan_decap_next
12955   (unformat_input_t * input, va_list * args)
12956 {
12957   u32 *result = va_arg (*args, u32 *);
12958   u32 tmp;
12959
12960   if (unformat (input, "l2"))
12961     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12962   else if (unformat (input, "%d", &tmp))
12963     *result = tmp;
12964   else
12965     return 0;
12966   return 1;
12967 }
12968
12969 static int
12970 api_vxlan_add_del_tunnel (vat_main_t * vam)
12971 {
12972   unformat_input_t *line_input = vam->input;
12973   vl_api_vxlan_add_del_tunnel_t *mp;
12974   ip46_address_t src, dst;
12975   u8 is_add = 1;
12976   u8 ipv4_set = 0, ipv6_set = 0;
12977   u8 src_set = 0;
12978   u8 dst_set = 0;
12979   u8 grp_set = 0;
12980   u32 instance = ~0;
12981   u32 mcast_sw_if_index = ~0;
12982   u32 encap_vrf_id = 0;
12983   u32 decap_next_index = ~0;
12984   u32 vni = 0;
12985   int ret;
12986
12987   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12988   memset (&src, 0, sizeof src);
12989   memset (&dst, 0, sizeof dst);
12990
12991   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12992     {
12993       if (unformat (line_input, "del"))
12994         is_add = 0;
12995       else if (unformat (line_input, "instance %d", &instance))
12996         ;
12997       else
12998         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12999         {
13000           ipv4_set = 1;
13001           src_set = 1;
13002         }
13003       else
13004         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13005         {
13006           ipv4_set = 1;
13007           dst_set = 1;
13008         }
13009       else
13010         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13011         {
13012           ipv6_set = 1;
13013           src_set = 1;
13014         }
13015       else
13016         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13017         {
13018           ipv6_set = 1;
13019           dst_set = 1;
13020         }
13021       else if (unformat (line_input, "group %U %U",
13022                          unformat_ip4_address, &dst.ip4,
13023                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13024         {
13025           grp_set = dst_set = 1;
13026           ipv4_set = 1;
13027         }
13028       else if (unformat (line_input, "group %U",
13029                          unformat_ip4_address, &dst.ip4))
13030         {
13031           grp_set = dst_set = 1;
13032           ipv4_set = 1;
13033         }
13034       else if (unformat (line_input, "group %U %U",
13035                          unformat_ip6_address, &dst.ip6,
13036                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13037         {
13038           grp_set = dst_set = 1;
13039           ipv6_set = 1;
13040         }
13041       else if (unformat (line_input, "group %U",
13042                          unformat_ip6_address, &dst.ip6))
13043         {
13044           grp_set = dst_set = 1;
13045           ipv6_set = 1;
13046         }
13047       else
13048         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13049         ;
13050       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13051         ;
13052       else if (unformat (line_input, "decap-next %U",
13053                          unformat_vxlan_decap_next, &decap_next_index))
13054         ;
13055       else if (unformat (line_input, "vni %d", &vni))
13056         ;
13057       else
13058         {
13059           errmsg ("parse error '%U'", format_unformat_error, line_input);
13060           return -99;
13061         }
13062     }
13063
13064   if (src_set == 0)
13065     {
13066       errmsg ("tunnel src address not specified");
13067       return -99;
13068     }
13069   if (dst_set == 0)
13070     {
13071       errmsg ("tunnel dst address not specified");
13072       return -99;
13073     }
13074
13075   if (grp_set && !ip46_address_is_multicast (&dst))
13076     {
13077       errmsg ("tunnel group address not multicast");
13078       return -99;
13079     }
13080   if (grp_set && mcast_sw_if_index == ~0)
13081     {
13082       errmsg ("tunnel nonexistent multicast device");
13083       return -99;
13084     }
13085   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13086     {
13087       errmsg ("tunnel dst address must be unicast");
13088       return -99;
13089     }
13090
13091
13092   if (ipv4_set && ipv6_set)
13093     {
13094       errmsg ("both IPv4 and IPv6 addresses specified");
13095       return -99;
13096     }
13097
13098   if ((vni == 0) || (vni >> 24))
13099     {
13100       errmsg ("vni not specified or out of range");
13101       return -99;
13102     }
13103
13104   M (VXLAN_ADD_DEL_TUNNEL, mp);
13105
13106   if (ipv6_set)
13107     {
13108       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13109       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13110     }
13111   else
13112     {
13113       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13114       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13115     }
13116
13117   mp->instance = htonl (instance);
13118   mp->encap_vrf_id = ntohl (encap_vrf_id);
13119   mp->decap_next_index = ntohl (decap_next_index);
13120   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13121   mp->vni = ntohl (vni);
13122   mp->is_add = is_add;
13123   mp->is_ipv6 = ipv6_set;
13124
13125   S (mp);
13126   W (ret);
13127   return ret;
13128 }
13129
13130 static void vl_api_vxlan_tunnel_details_t_handler
13131   (vl_api_vxlan_tunnel_details_t * mp)
13132 {
13133   vat_main_t *vam = &vat_main;
13134   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13135   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13136
13137   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13138          ntohl (mp->sw_if_index),
13139          ntohl (mp->instance),
13140          format_ip46_address, &src, IP46_TYPE_ANY,
13141          format_ip46_address, &dst, IP46_TYPE_ANY,
13142          ntohl (mp->encap_vrf_id),
13143          ntohl (mp->decap_next_index), ntohl (mp->vni),
13144          ntohl (mp->mcast_sw_if_index));
13145 }
13146
13147 static void vl_api_vxlan_tunnel_details_t_handler_json
13148   (vl_api_vxlan_tunnel_details_t * mp)
13149 {
13150   vat_main_t *vam = &vat_main;
13151   vat_json_node_t *node = NULL;
13152
13153   if (VAT_JSON_ARRAY != vam->json_tree.type)
13154     {
13155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13156       vat_json_init_array (&vam->json_tree);
13157     }
13158   node = vat_json_array_add (&vam->json_tree);
13159
13160   vat_json_init_object (node);
13161   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13162
13163   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13164
13165   if (mp->is_ipv6)
13166     {
13167       struct in6_addr ip6;
13168
13169       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13170       vat_json_object_add_ip6 (node, "src_address", ip6);
13171       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13172       vat_json_object_add_ip6 (node, "dst_address", ip6);
13173     }
13174   else
13175     {
13176       struct in_addr ip4;
13177
13178       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13179       vat_json_object_add_ip4 (node, "src_address", ip4);
13180       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13181       vat_json_object_add_ip4 (node, "dst_address", ip4);
13182     }
13183   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13184   vat_json_object_add_uint (node, "decap_next_index",
13185                             ntohl (mp->decap_next_index));
13186   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13187   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13188   vat_json_object_add_uint (node, "mcast_sw_if_index",
13189                             ntohl (mp->mcast_sw_if_index));
13190 }
13191
13192 static int
13193 api_vxlan_tunnel_dump (vat_main_t * vam)
13194 {
13195   unformat_input_t *i = vam->input;
13196   vl_api_vxlan_tunnel_dump_t *mp;
13197   vl_api_control_ping_t *mp_ping;
13198   u32 sw_if_index;
13199   u8 sw_if_index_set = 0;
13200   int ret;
13201
13202   /* Parse args required to build the message */
13203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13204     {
13205       if (unformat (i, "sw_if_index %d", &sw_if_index))
13206         sw_if_index_set = 1;
13207       else
13208         break;
13209     }
13210
13211   if (sw_if_index_set == 0)
13212     {
13213       sw_if_index = ~0;
13214     }
13215
13216   if (!vam->json_output)
13217     {
13218       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13219              "sw_if_index", "instance", "src_address", "dst_address",
13220              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13221     }
13222
13223   /* Get list of vxlan-tunnel interfaces */
13224   M (VXLAN_TUNNEL_DUMP, mp);
13225
13226   mp->sw_if_index = htonl (sw_if_index);
13227
13228   S (mp);
13229
13230   /* Use a control ping for synchronization */
13231   MPING (CONTROL_PING, mp_ping);
13232   S (mp_ping);
13233
13234   W (ret);
13235   return ret;
13236 }
13237
13238 static uword unformat_geneve_decap_next
13239   (unformat_input_t * input, va_list * args)
13240 {
13241   u32 *result = va_arg (*args, u32 *);
13242   u32 tmp;
13243
13244   if (unformat (input, "l2"))
13245     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13246   else if (unformat (input, "%d", &tmp))
13247     *result = tmp;
13248   else
13249     return 0;
13250   return 1;
13251 }
13252
13253 static int
13254 api_geneve_add_del_tunnel (vat_main_t * vam)
13255 {
13256   unformat_input_t *line_input = vam->input;
13257   vl_api_geneve_add_del_tunnel_t *mp;
13258   ip46_address_t src, dst;
13259   u8 is_add = 1;
13260   u8 ipv4_set = 0, ipv6_set = 0;
13261   u8 src_set = 0;
13262   u8 dst_set = 0;
13263   u8 grp_set = 0;
13264   u32 mcast_sw_if_index = ~0;
13265   u32 encap_vrf_id = 0;
13266   u32 decap_next_index = ~0;
13267   u32 vni = 0;
13268   int ret;
13269
13270   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13271   memset (&src, 0, sizeof src);
13272   memset (&dst, 0, sizeof dst);
13273
13274   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13275     {
13276       if (unformat (line_input, "del"))
13277         is_add = 0;
13278       else
13279         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13280         {
13281           ipv4_set = 1;
13282           src_set = 1;
13283         }
13284       else
13285         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13286         {
13287           ipv4_set = 1;
13288           dst_set = 1;
13289         }
13290       else
13291         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13292         {
13293           ipv6_set = 1;
13294           src_set = 1;
13295         }
13296       else
13297         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13298         {
13299           ipv6_set = 1;
13300           dst_set = 1;
13301         }
13302       else if (unformat (line_input, "group %U %U",
13303                          unformat_ip4_address, &dst.ip4,
13304                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13305         {
13306           grp_set = dst_set = 1;
13307           ipv4_set = 1;
13308         }
13309       else if (unformat (line_input, "group %U",
13310                          unformat_ip4_address, &dst.ip4))
13311         {
13312           grp_set = dst_set = 1;
13313           ipv4_set = 1;
13314         }
13315       else if (unformat (line_input, "group %U %U",
13316                          unformat_ip6_address, &dst.ip6,
13317                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13318         {
13319           grp_set = dst_set = 1;
13320           ipv6_set = 1;
13321         }
13322       else if (unformat (line_input, "group %U",
13323                          unformat_ip6_address, &dst.ip6))
13324         {
13325           grp_set = dst_set = 1;
13326           ipv6_set = 1;
13327         }
13328       else
13329         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13330         ;
13331       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13332         ;
13333       else if (unformat (line_input, "decap-next %U",
13334                          unformat_geneve_decap_next, &decap_next_index))
13335         ;
13336       else if (unformat (line_input, "vni %d", &vni))
13337         ;
13338       else
13339         {
13340           errmsg ("parse error '%U'", format_unformat_error, line_input);
13341           return -99;
13342         }
13343     }
13344
13345   if (src_set == 0)
13346     {
13347       errmsg ("tunnel src address not specified");
13348       return -99;
13349     }
13350   if (dst_set == 0)
13351     {
13352       errmsg ("tunnel dst address not specified");
13353       return -99;
13354     }
13355
13356   if (grp_set && !ip46_address_is_multicast (&dst))
13357     {
13358       errmsg ("tunnel group address not multicast");
13359       return -99;
13360     }
13361   if (grp_set && mcast_sw_if_index == ~0)
13362     {
13363       errmsg ("tunnel nonexistent multicast device");
13364       return -99;
13365     }
13366   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13367     {
13368       errmsg ("tunnel dst address must be unicast");
13369       return -99;
13370     }
13371
13372
13373   if (ipv4_set && ipv6_set)
13374     {
13375       errmsg ("both IPv4 and IPv6 addresses specified");
13376       return -99;
13377     }
13378
13379   if ((vni == 0) || (vni >> 24))
13380     {
13381       errmsg ("vni not specified or out of range");
13382       return -99;
13383     }
13384
13385   M (GENEVE_ADD_DEL_TUNNEL, mp);
13386
13387   if (ipv6_set)
13388     {
13389       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13390       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13391     }
13392   else
13393     {
13394       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13395       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13396     }
13397   mp->encap_vrf_id = ntohl (encap_vrf_id);
13398   mp->decap_next_index = ntohl (decap_next_index);
13399   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13400   mp->vni = ntohl (vni);
13401   mp->is_add = is_add;
13402   mp->is_ipv6 = ipv6_set;
13403
13404   S (mp);
13405   W (ret);
13406   return ret;
13407 }
13408
13409 static void vl_api_geneve_tunnel_details_t_handler
13410   (vl_api_geneve_tunnel_details_t * mp)
13411 {
13412   vat_main_t *vam = &vat_main;
13413   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13414   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13415
13416   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13417          ntohl (mp->sw_if_index),
13418          format_ip46_address, &src, IP46_TYPE_ANY,
13419          format_ip46_address, &dst, IP46_TYPE_ANY,
13420          ntohl (mp->encap_vrf_id),
13421          ntohl (mp->decap_next_index), ntohl (mp->vni),
13422          ntohl (mp->mcast_sw_if_index));
13423 }
13424
13425 static void vl_api_geneve_tunnel_details_t_handler_json
13426   (vl_api_geneve_tunnel_details_t * mp)
13427 {
13428   vat_main_t *vam = &vat_main;
13429   vat_json_node_t *node = NULL;
13430
13431   if (VAT_JSON_ARRAY != vam->json_tree.type)
13432     {
13433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13434       vat_json_init_array (&vam->json_tree);
13435     }
13436   node = vat_json_array_add (&vam->json_tree);
13437
13438   vat_json_init_object (node);
13439   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13440   if (mp->is_ipv6)
13441     {
13442       struct in6_addr ip6;
13443
13444       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13445       vat_json_object_add_ip6 (node, "src_address", ip6);
13446       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13447       vat_json_object_add_ip6 (node, "dst_address", ip6);
13448     }
13449   else
13450     {
13451       struct in_addr ip4;
13452
13453       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13454       vat_json_object_add_ip4 (node, "src_address", ip4);
13455       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13456       vat_json_object_add_ip4 (node, "dst_address", ip4);
13457     }
13458   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13459   vat_json_object_add_uint (node, "decap_next_index",
13460                             ntohl (mp->decap_next_index));
13461   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13462   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13463   vat_json_object_add_uint (node, "mcast_sw_if_index",
13464                             ntohl (mp->mcast_sw_if_index));
13465 }
13466
13467 static int
13468 api_geneve_tunnel_dump (vat_main_t * vam)
13469 {
13470   unformat_input_t *i = vam->input;
13471   vl_api_geneve_tunnel_dump_t *mp;
13472   vl_api_control_ping_t *mp_ping;
13473   u32 sw_if_index;
13474   u8 sw_if_index_set = 0;
13475   int ret;
13476
13477   /* Parse args required to build the message */
13478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13479     {
13480       if (unformat (i, "sw_if_index %d", &sw_if_index))
13481         sw_if_index_set = 1;
13482       else
13483         break;
13484     }
13485
13486   if (sw_if_index_set == 0)
13487     {
13488       sw_if_index = ~0;
13489     }
13490
13491   if (!vam->json_output)
13492     {
13493       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13494              "sw_if_index", "local_address", "remote_address",
13495              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13496     }
13497
13498   /* Get list of geneve-tunnel interfaces */
13499   M (GENEVE_TUNNEL_DUMP, mp);
13500
13501   mp->sw_if_index = htonl (sw_if_index);
13502
13503   S (mp);
13504
13505   /* Use a control ping for synchronization */
13506   M (CONTROL_PING, mp_ping);
13507   S (mp_ping);
13508
13509   W (ret);
13510   return ret;
13511 }
13512
13513 static int
13514 api_gre_add_del_tunnel (vat_main_t * vam)
13515 {
13516   unformat_input_t *line_input = vam->input;
13517   vl_api_gre_add_del_tunnel_t *mp;
13518   ip4_address_t src4, dst4;
13519   ip6_address_t src6, dst6;
13520   u8 is_add = 1;
13521   u8 ipv4_set = 0;
13522   u8 ipv6_set = 0;
13523   u8 t_type = GRE_TUNNEL_TYPE_L3;
13524   u8 src_set = 0;
13525   u8 dst_set = 0;
13526   u32 outer_fib_id = 0;
13527   u32 session_id = 0;
13528   u32 instance = ~0;
13529   int ret;
13530
13531   memset (&src4, 0, sizeof src4);
13532   memset (&dst4, 0, sizeof dst4);
13533   memset (&src6, 0, sizeof src6);
13534   memset (&dst6, 0, sizeof dst6);
13535
13536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13537     {
13538       if (unformat (line_input, "del"))
13539         is_add = 0;
13540       else if (unformat (line_input, "instance %d", &instance))
13541         ;
13542       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13543         {
13544           src_set = 1;
13545           ipv4_set = 1;
13546         }
13547       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13548         {
13549           dst_set = 1;
13550           ipv4_set = 1;
13551         }
13552       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13553         {
13554           src_set = 1;
13555           ipv6_set = 1;
13556         }
13557       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13558         {
13559           dst_set = 1;
13560           ipv6_set = 1;
13561         }
13562       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13563         ;
13564       else if (unformat (line_input, "teb"))
13565         t_type = GRE_TUNNEL_TYPE_TEB;
13566       else if (unformat (line_input, "erspan %d", &session_id))
13567         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13568       else
13569         {
13570           errmsg ("parse error '%U'", format_unformat_error, line_input);
13571           return -99;
13572         }
13573     }
13574
13575   if (src_set == 0)
13576     {
13577       errmsg ("tunnel src address not specified");
13578       return -99;
13579     }
13580   if (dst_set == 0)
13581     {
13582       errmsg ("tunnel dst address not specified");
13583       return -99;
13584     }
13585   if (ipv4_set && ipv6_set)
13586     {
13587       errmsg ("both IPv4 and IPv6 addresses specified");
13588       return -99;
13589     }
13590
13591
13592   M (GRE_ADD_DEL_TUNNEL, mp);
13593
13594   if (ipv4_set)
13595     {
13596       clib_memcpy (&mp->src_address, &src4, 4);
13597       clib_memcpy (&mp->dst_address, &dst4, 4);
13598     }
13599   else
13600     {
13601       clib_memcpy (&mp->src_address, &src6, 16);
13602       clib_memcpy (&mp->dst_address, &dst6, 16);
13603     }
13604   mp->instance = htonl (instance);
13605   mp->outer_fib_id = htonl (outer_fib_id);
13606   mp->is_add = is_add;
13607   mp->session_id = htons ((u16) session_id);
13608   mp->tunnel_type = t_type;
13609   mp->is_ipv6 = ipv6_set;
13610
13611   S (mp);
13612   W (ret);
13613   return ret;
13614 }
13615
13616 static void vl_api_gre_tunnel_details_t_handler
13617   (vl_api_gre_tunnel_details_t * mp)
13618 {
13619   vat_main_t *vam = &vat_main;
13620   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13621   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13622
13623   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13624          ntohl (mp->sw_if_index),
13625          ntohl (mp->instance),
13626          format_ip46_address, &src, IP46_TYPE_ANY,
13627          format_ip46_address, &dst, IP46_TYPE_ANY,
13628          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13629 }
13630
13631 static void vl_api_gre_tunnel_details_t_handler_json
13632   (vl_api_gre_tunnel_details_t * mp)
13633 {
13634   vat_main_t *vam = &vat_main;
13635   vat_json_node_t *node = NULL;
13636   struct in_addr ip4;
13637   struct in6_addr ip6;
13638
13639   if (VAT_JSON_ARRAY != vam->json_tree.type)
13640     {
13641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13642       vat_json_init_array (&vam->json_tree);
13643     }
13644   node = vat_json_array_add (&vam->json_tree);
13645
13646   vat_json_init_object (node);
13647   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13648   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13649   if (!mp->is_ipv6)
13650     {
13651       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13652       vat_json_object_add_ip4 (node, "src_address", ip4);
13653       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13654       vat_json_object_add_ip4 (node, "dst_address", ip4);
13655     }
13656   else
13657     {
13658       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13659       vat_json_object_add_ip6 (node, "src_address", ip6);
13660       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13661       vat_json_object_add_ip6 (node, "dst_address", ip6);
13662     }
13663   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13664   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13665   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13666   vat_json_object_add_uint (node, "session_id", mp->session_id);
13667 }
13668
13669 static int
13670 api_gre_tunnel_dump (vat_main_t * vam)
13671 {
13672   unformat_input_t *i = vam->input;
13673   vl_api_gre_tunnel_dump_t *mp;
13674   vl_api_control_ping_t *mp_ping;
13675   u32 sw_if_index;
13676   u8 sw_if_index_set = 0;
13677   int ret;
13678
13679   /* Parse args required to build the message */
13680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13681     {
13682       if (unformat (i, "sw_if_index %d", &sw_if_index))
13683         sw_if_index_set = 1;
13684       else
13685         break;
13686     }
13687
13688   if (sw_if_index_set == 0)
13689     {
13690       sw_if_index = ~0;
13691     }
13692
13693   if (!vam->json_output)
13694     {
13695       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13696              "sw_if_index", "instance", "src_address", "dst_address",
13697              "tunnel_type", "outer_fib_id", "session_id");
13698     }
13699
13700   /* Get list of gre-tunnel interfaces */
13701   M (GRE_TUNNEL_DUMP, mp);
13702
13703   mp->sw_if_index = htonl (sw_if_index);
13704
13705   S (mp);
13706
13707   /* Use a control ping for synchronization */
13708   MPING (CONTROL_PING, mp_ping);
13709   S (mp_ping);
13710
13711   W (ret);
13712   return ret;
13713 }
13714
13715 static int
13716 api_l2_fib_clear_table (vat_main_t * vam)
13717 {
13718 //  unformat_input_t * i = vam->input;
13719   vl_api_l2_fib_clear_table_t *mp;
13720   int ret;
13721
13722   M (L2_FIB_CLEAR_TABLE, mp);
13723
13724   S (mp);
13725   W (ret);
13726   return ret;
13727 }
13728
13729 static int
13730 api_l2_interface_efp_filter (vat_main_t * vam)
13731 {
13732   unformat_input_t *i = vam->input;
13733   vl_api_l2_interface_efp_filter_t *mp;
13734   u32 sw_if_index;
13735   u8 enable = 1;
13736   u8 sw_if_index_set = 0;
13737   int ret;
13738
13739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13740     {
13741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13742         sw_if_index_set = 1;
13743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13744         sw_if_index_set = 1;
13745       else if (unformat (i, "enable"))
13746         enable = 1;
13747       else if (unformat (i, "disable"))
13748         enable = 0;
13749       else
13750         {
13751           clib_warning ("parse error '%U'", format_unformat_error, i);
13752           return -99;
13753         }
13754     }
13755
13756   if (sw_if_index_set == 0)
13757     {
13758       errmsg ("missing sw_if_index");
13759       return -99;
13760     }
13761
13762   M (L2_INTERFACE_EFP_FILTER, mp);
13763
13764   mp->sw_if_index = ntohl (sw_if_index);
13765   mp->enable_disable = enable;
13766
13767   S (mp);
13768   W (ret);
13769   return ret;
13770 }
13771
13772 #define foreach_vtr_op                          \
13773 _("disable",  L2_VTR_DISABLED)                  \
13774 _("push-1",  L2_VTR_PUSH_1)                     \
13775 _("push-2",  L2_VTR_PUSH_2)                     \
13776 _("pop-1",  L2_VTR_POP_1)                       \
13777 _("pop-2",  L2_VTR_POP_2)                       \
13778 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13779 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13780 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13781 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13782
13783 static int
13784 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13785 {
13786   unformat_input_t *i = vam->input;
13787   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13788   u32 sw_if_index;
13789   u8 sw_if_index_set = 0;
13790   u8 vtr_op_set = 0;
13791   u32 vtr_op = 0;
13792   u32 push_dot1q = 1;
13793   u32 tag1 = ~0;
13794   u32 tag2 = ~0;
13795   int ret;
13796
13797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13798     {
13799       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13800         sw_if_index_set = 1;
13801       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13802         sw_if_index_set = 1;
13803       else if (unformat (i, "vtr_op %d", &vtr_op))
13804         vtr_op_set = 1;
13805 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13806       foreach_vtr_op
13807 #undef _
13808         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13809         ;
13810       else if (unformat (i, "tag1 %d", &tag1))
13811         ;
13812       else if (unformat (i, "tag2 %d", &tag2))
13813         ;
13814       else
13815         {
13816           clib_warning ("parse error '%U'", format_unformat_error, i);
13817           return -99;
13818         }
13819     }
13820
13821   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13822     {
13823       errmsg ("missing vtr operation or sw_if_index");
13824       return -99;
13825     }
13826
13827   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13828   mp->sw_if_index = ntohl (sw_if_index);
13829   mp->vtr_op = ntohl (vtr_op);
13830   mp->push_dot1q = ntohl (push_dot1q);
13831   mp->tag1 = ntohl (tag1);
13832   mp->tag2 = ntohl (tag2);
13833
13834   S (mp);
13835   W (ret);
13836   return ret;
13837 }
13838
13839 static int
13840 api_create_vhost_user_if (vat_main_t * vam)
13841 {
13842   unformat_input_t *i = vam->input;
13843   vl_api_create_vhost_user_if_t *mp;
13844   u8 *file_name;
13845   u8 is_server = 0;
13846   u8 file_name_set = 0;
13847   u32 custom_dev_instance = ~0;
13848   u8 hwaddr[6];
13849   u8 use_custom_mac = 0;
13850   u8 *tag = 0;
13851   int ret;
13852
13853   /* Shut up coverity */
13854   memset (hwaddr, 0, sizeof (hwaddr));
13855
13856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13857     {
13858       if (unformat (i, "socket %s", &file_name))
13859         {
13860           file_name_set = 1;
13861         }
13862       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13863         ;
13864       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13865         use_custom_mac = 1;
13866       else if (unformat (i, "server"))
13867         is_server = 1;
13868       else if (unformat (i, "tag %s", &tag))
13869         ;
13870       else
13871         break;
13872     }
13873
13874   if (file_name_set == 0)
13875     {
13876       errmsg ("missing socket file name");
13877       return -99;
13878     }
13879
13880   if (vec_len (file_name) > 255)
13881     {
13882       errmsg ("socket file name too long");
13883       return -99;
13884     }
13885   vec_add1 (file_name, 0);
13886
13887   M (CREATE_VHOST_USER_IF, mp);
13888
13889   mp->is_server = is_server;
13890   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13891   vec_free (file_name);
13892   if (custom_dev_instance != ~0)
13893     {
13894       mp->renumber = 1;
13895       mp->custom_dev_instance = ntohl (custom_dev_instance);
13896     }
13897   mp->use_custom_mac = use_custom_mac;
13898   clib_memcpy (mp->mac_address, hwaddr, 6);
13899   if (tag)
13900     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13901   vec_free (tag);
13902
13903   S (mp);
13904   W (ret);
13905   return ret;
13906 }
13907
13908 static int
13909 api_modify_vhost_user_if (vat_main_t * vam)
13910 {
13911   unformat_input_t *i = vam->input;
13912   vl_api_modify_vhost_user_if_t *mp;
13913   u8 *file_name;
13914   u8 is_server = 0;
13915   u8 file_name_set = 0;
13916   u32 custom_dev_instance = ~0;
13917   u8 sw_if_index_set = 0;
13918   u32 sw_if_index = (u32) ~ 0;
13919   int ret;
13920
13921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13924         sw_if_index_set = 1;
13925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13926         sw_if_index_set = 1;
13927       else if (unformat (i, "socket %s", &file_name))
13928         {
13929           file_name_set = 1;
13930         }
13931       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13932         ;
13933       else if (unformat (i, "server"))
13934         is_server = 1;
13935       else
13936         break;
13937     }
13938
13939   if (sw_if_index_set == 0)
13940     {
13941       errmsg ("missing sw_if_index or interface name");
13942       return -99;
13943     }
13944
13945   if (file_name_set == 0)
13946     {
13947       errmsg ("missing socket file name");
13948       return -99;
13949     }
13950
13951   if (vec_len (file_name) > 255)
13952     {
13953       errmsg ("socket file name too long");
13954       return -99;
13955     }
13956   vec_add1 (file_name, 0);
13957
13958   M (MODIFY_VHOST_USER_IF, mp);
13959
13960   mp->sw_if_index = ntohl (sw_if_index);
13961   mp->is_server = is_server;
13962   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13963   vec_free (file_name);
13964   if (custom_dev_instance != ~0)
13965     {
13966       mp->renumber = 1;
13967       mp->custom_dev_instance = ntohl (custom_dev_instance);
13968     }
13969
13970   S (mp);
13971   W (ret);
13972   return ret;
13973 }
13974
13975 static int
13976 api_delete_vhost_user_if (vat_main_t * vam)
13977 {
13978   unformat_input_t *i = vam->input;
13979   vl_api_delete_vhost_user_if_t *mp;
13980   u32 sw_if_index = ~0;
13981   u8 sw_if_index_set = 0;
13982   int ret;
13983
13984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13985     {
13986       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13987         sw_if_index_set = 1;
13988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13989         sw_if_index_set = 1;
13990       else
13991         break;
13992     }
13993
13994   if (sw_if_index_set == 0)
13995     {
13996       errmsg ("missing sw_if_index or interface name");
13997       return -99;
13998     }
13999
14000
14001   M (DELETE_VHOST_USER_IF, mp);
14002
14003   mp->sw_if_index = ntohl (sw_if_index);
14004
14005   S (mp);
14006   W (ret);
14007   return ret;
14008 }
14009
14010 static void vl_api_sw_interface_vhost_user_details_t_handler
14011   (vl_api_sw_interface_vhost_user_details_t * mp)
14012 {
14013   vat_main_t *vam = &vat_main;
14014
14015   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14016          (char *) mp->interface_name,
14017          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14018          clib_net_to_host_u64 (mp->features), mp->is_server,
14019          ntohl (mp->num_regions), (char *) mp->sock_filename);
14020   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14021 }
14022
14023 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14024   (vl_api_sw_interface_vhost_user_details_t * mp)
14025 {
14026   vat_main_t *vam = &vat_main;
14027   vat_json_node_t *node = NULL;
14028
14029   if (VAT_JSON_ARRAY != vam->json_tree.type)
14030     {
14031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14032       vat_json_init_array (&vam->json_tree);
14033     }
14034   node = vat_json_array_add (&vam->json_tree);
14035
14036   vat_json_init_object (node);
14037   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14038   vat_json_object_add_string_copy (node, "interface_name",
14039                                    mp->interface_name);
14040   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14041                             ntohl (mp->virtio_net_hdr_sz));
14042   vat_json_object_add_uint (node, "features",
14043                             clib_net_to_host_u64 (mp->features));
14044   vat_json_object_add_uint (node, "is_server", mp->is_server);
14045   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14046   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14047   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14048 }
14049
14050 static int
14051 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14052 {
14053   vl_api_sw_interface_vhost_user_dump_t *mp;
14054   vl_api_control_ping_t *mp_ping;
14055   int ret;
14056   print (vam->ofp,
14057          "Interface name            idx hdr_sz features server regions filename");
14058
14059   /* Get list of vhost-user interfaces */
14060   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14061   S (mp);
14062
14063   /* Use a control ping for synchronization */
14064   MPING (CONTROL_PING, mp_ping);
14065   S (mp_ping);
14066
14067   W (ret);
14068   return ret;
14069 }
14070
14071 static int
14072 api_show_version (vat_main_t * vam)
14073 {
14074   vl_api_show_version_t *mp;
14075   int ret;
14076
14077   M (SHOW_VERSION, mp);
14078
14079   S (mp);
14080   W (ret);
14081   return ret;
14082 }
14083
14084
14085 static int
14086 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14087 {
14088   unformat_input_t *line_input = vam->input;
14089   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14090   ip4_address_t local4, remote4;
14091   ip6_address_t local6, remote6;
14092   u8 is_add = 1;
14093   u8 ipv4_set = 0, ipv6_set = 0;
14094   u8 local_set = 0;
14095   u8 remote_set = 0;
14096   u8 grp_set = 0;
14097   u32 mcast_sw_if_index = ~0;
14098   u32 encap_vrf_id = 0;
14099   u32 decap_vrf_id = 0;
14100   u8 protocol = ~0;
14101   u32 vni;
14102   u8 vni_set = 0;
14103   int ret;
14104
14105   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14106   memset (&local4, 0, sizeof local4);
14107   memset (&remote4, 0, sizeof remote4);
14108   memset (&local6, 0, sizeof local6);
14109   memset (&remote6, 0, sizeof remote6);
14110
14111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (line_input, "del"))
14114         is_add = 0;
14115       else if (unformat (line_input, "local %U",
14116                          unformat_ip4_address, &local4))
14117         {
14118           local_set = 1;
14119           ipv4_set = 1;
14120         }
14121       else if (unformat (line_input, "remote %U",
14122                          unformat_ip4_address, &remote4))
14123         {
14124           remote_set = 1;
14125           ipv4_set = 1;
14126         }
14127       else if (unformat (line_input, "local %U",
14128                          unformat_ip6_address, &local6))
14129         {
14130           local_set = 1;
14131           ipv6_set = 1;
14132         }
14133       else if (unformat (line_input, "remote %U",
14134                          unformat_ip6_address, &remote6))
14135         {
14136           remote_set = 1;
14137           ipv6_set = 1;
14138         }
14139       else if (unformat (line_input, "group %U %U",
14140                          unformat_ip4_address, &remote4,
14141                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14142         {
14143           grp_set = remote_set = 1;
14144           ipv4_set = 1;
14145         }
14146       else if (unformat (line_input, "group %U",
14147                          unformat_ip4_address, &remote4))
14148         {
14149           grp_set = remote_set = 1;
14150           ipv4_set = 1;
14151         }
14152       else if (unformat (line_input, "group %U %U",
14153                          unformat_ip6_address, &remote6,
14154                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14155         {
14156           grp_set = remote_set = 1;
14157           ipv6_set = 1;
14158         }
14159       else if (unformat (line_input, "group %U",
14160                          unformat_ip6_address, &remote6))
14161         {
14162           grp_set = remote_set = 1;
14163           ipv6_set = 1;
14164         }
14165       else
14166         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14167         ;
14168       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14169         ;
14170       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14171         ;
14172       else if (unformat (line_input, "vni %d", &vni))
14173         vni_set = 1;
14174       else if (unformat (line_input, "next-ip4"))
14175         protocol = 1;
14176       else if (unformat (line_input, "next-ip6"))
14177         protocol = 2;
14178       else if (unformat (line_input, "next-ethernet"))
14179         protocol = 3;
14180       else if (unformat (line_input, "next-nsh"))
14181         protocol = 4;
14182       else
14183         {
14184           errmsg ("parse error '%U'", format_unformat_error, line_input);
14185           return -99;
14186         }
14187     }
14188
14189   if (local_set == 0)
14190     {
14191       errmsg ("tunnel local address not specified");
14192       return -99;
14193     }
14194   if (remote_set == 0)
14195     {
14196       errmsg ("tunnel remote address not specified");
14197       return -99;
14198     }
14199   if (grp_set && mcast_sw_if_index == ~0)
14200     {
14201       errmsg ("tunnel nonexistent multicast device");
14202       return -99;
14203     }
14204   if (ipv4_set && ipv6_set)
14205     {
14206       errmsg ("both IPv4 and IPv6 addresses specified");
14207       return -99;
14208     }
14209
14210   if (vni_set == 0)
14211     {
14212       errmsg ("vni not specified");
14213       return -99;
14214     }
14215
14216   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14217
14218
14219   if (ipv6_set)
14220     {
14221       clib_memcpy (&mp->local, &local6, sizeof (local6));
14222       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14223     }
14224   else
14225     {
14226       clib_memcpy (&mp->local, &local4, sizeof (local4));
14227       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14228     }
14229
14230   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14231   mp->encap_vrf_id = ntohl (encap_vrf_id);
14232   mp->decap_vrf_id = ntohl (decap_vrf_id);
14233   mp->protocol = protocol;
14234   mp->vni = ntohl (vni);
14235   mp->is_add = is_add;
14236   mp->is_ipv6 = ipv6_set;
14237
14238   S (mp);
14239   W (ret);
14240   return ret;
14241 }
14242
14243 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14244   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14245 {
14246   vat_main_t *vam = &vat_main;
14247   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14248   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14249
14250   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14251          ntohl (mp->sw_if_index),
14252          format_ip46_address, &local, IP46_TYPE_ANY,
14253          format_ip46_address, &remote, IP46_TYPE_ANY,
14254          ntohl (mp->vni), mp->protocol,
14255          ntohl (mp->mcast_sw_if_index),
14256          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14257 }
14258
14259
14260 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14261   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14262 {
14263   vat_main_t *vam = &vat_main;
14264   vat_json_node_t *node = NULL;
14265   struct in_addr ip4;
14266   struct in6_addr ip6;
14267
14268   if (VAT_JSON_ARRAY != vam->json_tree.type)
14269     {
14270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14271       vat_json_init_array (&vam->json_tree);
14272     }
14273   node = vat_json_array_add (&vam->json_tree);
14274
14275   vat_json_init_object (node);
14276   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14277   if (mp->is_ipv6)
14278     {
14279       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14280       vat_json_object_add_ip6 (node, "local", ip6);
14281       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14282       vat_json_object_add_ip6 (node, "remote", ip6);
14283     }
14284   else
14285     {
14286       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14287       vat_json_object_add_ip4 (node, "local", ip4);
14288       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14289       vat_json_object_add_ip4 (node, "remote", ip4);
14290     }
14291   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14292   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14293   vat_json_object_add_uint (node, "mcast_sw_if_index",
14294                             ntohl (mp->mcast_sw_if_index));
14295   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14296   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14297   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14298 }
14299
14300 static int
14301 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14302 {
14303   unformat_input_t *i = vam->input;
14304   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14305   vl_api_control_ping_t *mp_ping;
14306   u32 sw_if_index;
14307   u8 sw_if_index_set = 0;
14308   int ret;
14309
14310   /* Parse args required to build the message */
14311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (i, "sw_if_index %d", &sw_if_index))
14314         sw_if_index_set = 1;
14315       else
14316         break;
14317     }
14318
14319   if (sw_if_index_set == 0)
14320     {
14321       sw_if_index = ~0;
14322     }
14323
14324   if (!vam->json_output)
14325     {
14326       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14327              "sw_if_index", "local", "remote", "vni",
14328              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14329     }
14330
14331   /* Get list of vxlan-tunnel interfaces */
14332   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14333
14334   mp->sw_if_index = htonl (sw_if_index);
14335
14336   S (mp);
14337
14338   /* Use a control ping for synchronization */
14339   MPING (CONTROL_PING, mp_ping);
14340   S (mp_ping);
14341
14342   W (ret);
14343   return ret;
14344 }
14345
14346 static void vl_api_l2_fib_table_details_t_handler
14347   (vl_api_l2_fib_table_details_t * mp)
14348 {
14349   vat_main_t *vam = &vat_main;
14350
14351   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14352          "       %d       %d     %d",
14353          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14354          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14355          mp->bvi_mac);
14356 }
14357
14358 static void vl_api_l2_fib_table_details_t_handler_json
14359   (vl_api_l2_fib_table_details_t * mp)
14360 {
14361   vat_main_t *vam = &vat_main;
14362   vat_json_node_t *node = NULL;
14363
14364   if (VAT_JSON_ARRAY != vam->json_tree.type)
14365     {
14366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14367       vat_json_init_array (&vam->json_tree);
14368     }
14369   node = vat_json_array_add (&vam->json_tree);
14370
14371   vat_json_init_object (node);
14372   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14373   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14374   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14375   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14376   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14377   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14378 }
14379
14380 static int
14381 api_l2_fib_table_dump (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_l2_fib_table_dump_t *mp;
14385   vl_api_control_ping_t *mp_ping;
14386   u32 bd_id;
14387   u8 bd_id_set = 0;
14388   int ret;
14389
14390   /* Parse args required to build the message */
14391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14392     {
14393       if (unformat (i, "bd_id %d", &bd_id))
14394         bd_id_set = 1;
14395       else
14396         break;
14397     }
14398
14399   if (bd_id_set == 0)
14400     {
14401       errmsg ("missing bridge domain");
14402       return -99;
14403     }
14404
14405   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14406
14407   /* Get list of l2 fib entries */
14408   M (L2_FIB_TABLE_DUMP, mp);
14409
14410   mp->bd_id = ntohl (bd_id);
14411   S (mp);
14412
14413   /* Use a control ping for synchronization */
14414   MPING (CONTROL_PING, mp_ping);
14415   S (mp_ping);
14416
14417   W (ret);
14418   return ret;
14419 }
14420
14421
14422 static int
14423 api_interface_name_renumber (vat_main_t * vam)
14424 {
14425   unformat_input_t *line_input = vam->input;
14426   vl_api_interface_name_renumber_t *mp;
14427   u32 sw_if_index = ~0;
14428   u32 new_show_dev_instance = ~0;
14429   int ret;
14430
14431   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14434                     &sw_if_index))
14435         ;
14436       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14437         ;
14438       else if (unformat (line_input, "new_show_dev_instance %d",
14439                          &new_show_dev_instance))
14440         ;
14441       else
14442         break;
14443     }
14444
14445   if (sw_if_index == ~0)
14446     {
14447       errmsg ("missing interface name or sw_if_index");
14448       return -99;
14449     }
14450
14451   if (new_show_dev_instance == ~0)
14452     {
14453       errmsg ("missing new_show_dev_instance");
14454       return -99;
14455     }
14456
14457   M (INTERFACE_NAME_RENUMBER, mp);
14458
14459   mp->sw_if_index = ntohl (sw_if_index);
14460   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14461
14462   S (mp);
14463   W (ret);
14464   return ret;
14465 }
14466
14467 static int
14468 api_ip_probe_neighbor (vat_main_t * vam)
14469 {
14470   unformat_input_t *i = vam->input;
14471   vl_api_ip_probe_neighbor_t *mp;
14472   u8 int_set = 0;
14473   u8 adr_set = 0;
14474   u8 is_ipv6 = 0;
14475   u8 dst_adr[16];
14476   u32 sw_if_index;
14477   int ret;
14478
14479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14480     {
14481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14482         int_set = 1;
14483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14484         int_set = 1;
14485       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14486         adr_set = 1;
14487       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14488         {
14489           adr_set = 1;
14490           is_ipv6 = 1;
14491         }
14492       else
14493         break;
14494     }
14495
14496   if (int_set == 0)
14497     {
14498       errmsg ("missing interface");
14499       return -99;
14500     }
14501
14502   if (adr_set == 0)
14503     {
14504       errmsg ("missing addresses");
14505       return -99;
14506     }
14507
14508   M (IP_PROBE_NEIGHBOR, mp);
14509
14510   mp->sw_if_index = ntohl (sw_if_index);
14511   mp->is_ipv6 = is_ipv6;
14512   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14513
14514   S (mp);
14515   W (ret);
14516   return ret;
14517 }
14518
14519 static int
14520 api_want_ip4_arp_events (vat_main_t * vam)
14521 {
14522   unformat_input_t *line_input = vam->input;
14523   vl_api_want_ip4_arp_events_t *mp;
14524   ip4_address_t address;
14525   int address_set = 0;
14526   u32 enable_disable = 1;
14527   int ret;
14528
14529   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14530     {
14531       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14532         address_set = 1;
14533       else if (unformat (line_input, "del"))
14534         enable_disable = 0;
14535       else
14536         break;
14537     }
14538
14539   if (address_set == 0)
14540     {
14541       errmsg ("missing addresses");
14542       return -99;
14543     }
14544
14545   M (WANT_IP4_ARP_EVENTS, mp);
14546   mp->enable_disable = enable_disable;
14547   mp->pid = htonl (getpid ());
14548   mp->address = address.as_u32;
14549
14550   S (mp);
14551   W (ret);
14552   return ret;
14553 }
14554
14555 static int
14556 api_want_ip6_nd_events (vat_main_t * vam)
14557 {
14558   unformat_input_t *line_input = vam->input;
14559   vl_api_want_ip6_nd_events_t *mp;
14560   ip6_address_t address;
14561   int address_set = 0;
14562   u32 enable_disable = 1;
14563   int ret;
14564
14565   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14566     {
14567       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14568         address_set = 1;
14569       else if (unformat (line_input, "del"))
14570         enable_disable = 0;
14571       else
14572         break;
14573     }
14574
14575   if (address_set == 0)
14576     {
14577       errmsg ("missing addresses");
14578       return -99;
14579     }
14580
14581   M (WANT_IP6_ND_EVENTS, mp);
14582   mp->enable_disable = enable_disable;
14583   mp->pid = htonl (getpid ());
14584   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14585
14586   S (mp);
14587   W (ret);
14588   return ret;
14589 }
14590
14591 static int
14592 api_want_l2_macs_events (vat_main_t * vam)
14593 {
14594   unformat_input_t *line_input = vam->input;
14595   vl_api_want_l2_macs_events_t *mp;
14596   u8 enable_disable = 1;
14597   u32 scan_delay = 0;
14598   u32 max_macs_in_event = 0;
14599   u32 learn_limit = 0;
14600   int ret;
14601
14602   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14603     {
14604       if (unformat (line_input, "learn-limit %d", &learn_limit))
14605         ;
14606       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14607         ;
14608       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14609         ;
14610       else if (unformat (line_input, "disable"))
14611         enable_disable = 0;
14612       else
14613         break;
14614     }
14615
14616   M (WANT_L2_MACS_EVENTS, mp);
14617   mp->enable_disable = enable_disable;
14618   mp->pid = htonl (getpid ());
14619   mp->learn_limit = htonl (learn_limit);
14620   mp->scan_delay = (u8) scan_delay;
14621   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14622   S (mp);
14623   W (ret);
14624   return ret;
14625 }
14626
14627 static int
14628 api_input_acl_set_interface (vat_main_t * vam)
14629 {
14630   unformat_input_t *i = vam->input;
14631   vl_api_input_acl_set_interface_t *mp;
14632   u32 sw_if_index;
14633   int sw_if_index_set;
14634   u32 ip4_table_index = ~0;
14635   u32 ip6_table_index = ~0;
14636   u32 l2_table_index = ~0;
14637   u8 is_add = 1;
14638   int ret;
14639
14640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14641     {
14642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14643         sw_if_index_set = 1;
14644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14645         sw_if_index_set = 1;
14646       else if (unformat (i, "del"))
14647         is_add = 0;
14648       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14649         ;
14650       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14651         ;
14652       else if (unformat (i, "l2-table %d", &l2_table_index))
14653         ;
14654       else
14655         {
14656           clib_warning ("parse error '%U'", format_unformat_error, i);
14657           return -99;
14658         }
14659     }
14660
14661   if (sw_if_index_set == 0)
14662     {
14663       errmsg ("missing interface name or sw_if_index");
14664       return -99;
14665     }
14666
14667   M (INPUT_ACL_SET_INTERFACE, mp);
14668
14669   mp->sw_if_index = ntohl (sw_if_index);
14670   mp->ip4_table_index = ntohl (ip4_table_index);
14671   mp->ip6_table_index = ntohl (ip6_table_index);
14672   mp->l2_table_index = ntohl (l2_table_index);
14673   mp->is_add = is_add;
14674
14675   S (mp);
14676   W (ret);
14677   return ret;
14678 }
14679
14680 static int
14681 api_output_acl_set_interface (vat_main_t * vam)
14682 {
14683   unformat_input_t *i = vam->input;
14684   vl_api_output_acl_set_interface_t *mp;
14685   u32 sw_if_index;
14686   int sw_if_index_set;
14687   u32 ip4_table_index = ~0;
14688   u32 ip6_table_index = ~0;
14689   u32 l2_table_index = ~0;
14690   u8 is_add = 1;
14691   int ret;
14692
14693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14694     {
14695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14696         sw_if_index_set = 1;
14697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14698         sw_if_index_set = 1;
14699       else if (unformat (i, "del"))
14700         is_add = 0;
14701       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14702         ;
14703       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14704         ;
14705       else if (unformat (i, "l2-table %d", &l2_table_index))
14706         ;
14707       else
14708         {
14709           clib_warning ("parse error '%U'", format_unformat_error, i);
14710           return -99;
14711         }
14712     }
14713
14714   if (sw_if_index_set == 0)
14715     {
14716       errmsg ("missing interface name or sw_if_index");
14717       return -99;
14718     }
14719
14720   M (OUTPUT_ACL_SET_INTERFACE, mp);
14721
14722   mp->sw_if_index = ntohl (sw_if_index);
14723   mp->ip4_table_index = ntohl (ip4_table_index);
14724   mp->ip6_table_index = ntohl (ip6_table_index);
14725   mp->l2_table_index = ntohl (l2_table_index);
14726   mp->is_add = is_add;
14727
14728   S (mp);
14729   W (ret);
14730   return ret;
14731 }
14732
14733 static int
14734 api_ip_address_dump (vat_main_t * vam)
14735 {
14736   unformat_input_t *i = vam->input;
14737   vl_api_ip_address_dump_t *mp;
14738   vl_api_control_ping_t *mp_ping;
14739   u32 sw_if_index = ~0;
14740   u8 sw_if_index_set = 0;
14741   u8 ipv4_set = 0;
14742   u8 ipv6_set = 0;
14743   int ret;
14744
14745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14746     {
14747       if (unformat (i, "sw_if_index %d", &sw_if_index))
14748         sw_if_index_set = 1;
14749       else
14750         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14751         sw_if_index_set = 1;
14752       else if (unformat (i, "ipv4"))
14753         ipv4_set = 1;
14754       else if (unformat (i, "ipv6"))
14755         ipv6_set = 1;
14756       else
14757         break;
14758     }
14759
14760   if (ipv4_set && ipv6_set)
14761     {
14762       errmsg ("ipv4 and ipv6 flags cannot be both set");
14763       return -99;
14764     }
14765
14766   if ((!ipv4_set) && (!ipv6_set))
14767     {
14768       errmsg ("no ipv4 nor ipv6 flag set");
14769       return -99;
14770     }
14771
14772   if (sw_if_index_set == 0)
14773     {
14774       errmsg ("missing interface name or sw_if_index");
14775       return -99;
14776     }
14777
14778   vam->current_sw_if_index = sw_if_index;
14779   vam->is_ipv6 = ipv6_set;
14780
14781   M (IP_ADDRESS_DUMP, mp);
14782   mp->sw_if_index = ntohl (sw_if_index);
14783   mp->is_ipv6 = ipv6_set;
14784   S (mp);
14785
14786   /* Use a control ping for synchronization */
14787   MPING (CONTROL_PING, mp_ping);
14788   S (mp_ping);
14789
14790   W (ret);
14791   return ret;
14792 }
14793
14794 static int
14795 api_ip_dump (vat_main_t * vam)
14796 {
14797   vl_api_ip_dump_t *mp;
14798   vl_api_control_ping_t *mp_ping;
14799   unformat_input_t *in = vam->input;
14800   int ipv4_set = 0;
14801   int ipv6_set = 0;
14802   int is_ipv6;
14803   int i;
14804   int ret;
14805
14806   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14807     {
14808       if (unformat (in, "ipv4"))
14809         ipv4_set = 1;
14810       else if (unformat (in, "ipv6"))
14811         ipv6_set = 1;
14812       else
14813         break;
14814     }
14815
14816   if (ipv4_set && ipv6_set)
14817     {
14818       errmsg ("ipv4 and ipv6 flags cannot be both set");
14819       return -99;
14820     }
14821
14822   if ((!ipv4_set) && (!ipv6_set))
14823     {
14824       errmsg ("no ipv4 nor ipv6 flag set");
14825       return -99;
14826     }
14827
14828   is_ipv6 = ipv6_set;
14829   vam->is_ipv6 = is_ipv6;
14830
14831   /* free old data */
14832   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14833     {
14834       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14835     }
14836   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14837
14838   M (IP_DUMP, mp);
14839   mp->is_ipv6 = ipv6_set;
14840   S (mp);
14841
14842   /* Use a control ping for synchronization */
14843   MPING (CONTROL_PING, mp_ping);
14844   S (mp_ping);
14845
14846   W (ret);
14847   return ret;
14848 }
14849
14850 static int
14851 api_ipsec_spd_add_del (vat_main_t * vam)
14852 {
14853   unformat_input_t *i = vam->input;
14854   vl_api_ipsec_spd_add_del_t *mp;
14855   u32 spd_id = ~0;
14856   u8 is_add = 1;
14857   int ret;
14858
14859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14860     {
14861       if (unformat (i, "spd_id %d", &spd_id))
14862         ;
14863       else if (unformat (i, "del"))
14864         is_add = 0;
14865       else
14866         {
14867           clib_warning ("parse error '%U'", format_unformat_error, i);
14868           return -99;
14869         }
14870     }
14871   if (spd_id == ~0)
14872     {
14873       errmsg ("spd_id must be set");
14874       return -99;
14875     }
14876
14877   M (IPSEC_SPD_ADD_DEL, mp);
14878
14879   mp->spd_id = ntohl (spd_id);
14880   mp->is_add = is_add;
14881
14882   S (mp);
14883   W (ret);
14884   return ret;
14885 }
14886
14887 static int
14888 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14889 {
14890   unformat_input_t *i = vam->input;
14891   vl_api_ipsec_interface_add_del_spd_t *mp;
14892   u32 sw_if_index;
14893   u8 sw_if_index_set = 0;
14894   u32 spd_id = (u32) ~ 0;
14895   u8 is_add = 1;
14896   int ret;
14897
14898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14899     {
14900       if (unformat (i, "del"))
14901         is_add = 0;
14902       else if (unformat (i, "spd_id %d", &spd_id))
14903         ;
14904       else
14905         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14906         sw_if_index_set = 1;
14907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14908         sw_if_index_set = 1;
14909       else
14910         {
14911           clib_warning ("parse error '%U'", format_unformat_error, i);
14912           return -99;
14913         }
14914
14915     }
14916
14917   if (spd_id == (u32) ~ 0)
14918     {
14919       errmsg ("spd_id must be set");
14920       return -99;
14921     }
14922
14923   if (sw_if_index_set == 0)
14924     {
14925       errmsg ("missing interface name or sw_if_index");
14926       return -99;
14927     }
14928
14929   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14930
14931   mp->spd_id = ntohl (spd_id);
14932   mp->sw_if_index = ntohl (sw_if_index);
14933   mp->is_add = is_add;
14934
14935   S (mp);
14936   W (ret);
14937   return ret;
14938 }
14939
14940 static int
14941 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14942 {
14943   unformat_input_t *i = vam->input;
14944   vl_api_ipsec_spd_add_del_entry_t *mp;
14945   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14946   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14947   i32 priority = 0;
14948   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14949   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14950   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14951   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14952   int ret;
14953
14954   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14955   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14956   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14957   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14958   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14959   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14960
14961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (i, "del"))
14964         is_add = 0;
14965       if (unformat (i, "outbound"))
14966         is_outbound = 1;
14967       if (unformat (i, "inbound"))
14968         is_outbound = 0;
14969       else if (unformat (i, "spd_id %d", &spd_id))
14970         ;
14971       else if (unformat (i, "sa_id %d", &sa_id))
14972         ;
14973       else if (unformat (i, "priority %d", &priority))
14974         ;
14975       else if (unformat (i, "protocol %d", &protocol))
14976         ;
14977       else if (unformat (i, "lport_start %d", &lport_start))
14978         ;
14979       else if (unformat (i, "lport_stop %d", &lport_stop))
14980         ;
14981       else if (unformat (i, "rport_start %d", &rport_start))
14982         ;
14983       else if (unformat (i, "rport_stop %d", &rport_stop))
14984         ;
14985       else
14986         if (unformat
14987             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14988         {
14989           is_ipv6 = 0;
14990           is_ip_any = 0;
14991         }
14992       else
14993         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14994         {
14995           is_ipv6 = 0;
14996           is_ip_any = 0;
14997         }
14998       else
14999         if (unformat
15000             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15001         {
15002           is_ipv6 = 0;
15003           is_ip_any = 0;
15004         }
15005       else
15006         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15007         {
15008           is_ipv6 = 0;
15009           is_ip_any = 0;
15010         }
15011       else
15012         if (unformat
15013             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15014         {
15015           is_ipv6 = 1;
15016           is_ip_any = 0;
15017         }
15018       else
15019         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15020         {
15021           is_ipv6 = 1;
15022           is_ip_any = 0;
15023         }
15024       else
15025         if (unformat
15026             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15027         {
15028           is_ipv6 = 1;
15029           is_ip_any = 0;
15030         }
15031       else
15032         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15033         {
15034           is_ipv6 = 1;
15035           is_ip_any = 0;
15036         }
15037       else
15038         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15039         {
15040           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15041             {
15042               clib_warning ("unsupported action: 'resolve'");
15043               return -99;
15044             }
15045         }
15046       else
15047         {
15048           clib_warning ("parse error '%U'", format_unformat_error, i);
15049           return -99;
15050         }
15051
15052     }
15053
15054   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15055
15056   mp->spd_id = ntohl (spd_id);
15057   mp->priority = ntohl (priority);
15058   mp->is_outbound = is_outbound;
15059
15060   mp->is_ipv6 = is_ipv6;
15061   if (is_ipv6 || is_ip_any)
15062     {
15063       clib_memcpy (mp->remote_address_start, &raddr6_start,
15064                    sizeof (ip6_address_t));
15065       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15066                    sizeof (ip6_address_t));
15067       clib_memcpy (mp->local_address_start, &laddr6_start,
15068                    sizeof (ip6_address_t));
15069       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15070                    sizeof (ip6_address_t));
15071     }
15072   else
15073     {
15074       clib_memcpy (mp->remote_address_start, &raddr4_start,
15075                    sizeof (ip4_address_t));
15076       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15077                    sizeof (ip4_address_t));
15078       clib_memcpy (mp->local_address_start, &laddr4_start,
15079                    sizeof (ip4_address_t));
15080       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15081                    sizeof (ip4_address_t));
15082     }
15083   mp->protocol = (u8) protocol;
15084   mp->local_port_start = ntohs ((u16) lport_start);
15085   mp->local_port_stop = ntohs ((u16) lport_stop);
15086   mp->remote_port_start = ntohs ((u16) rport_start);
15087   mp->remote_port_stop = ntohs ((u16) rport_stop);
15088   mp->policy = (u8) policy;
15089   mp->sa_id = ntohl (sa_id);
15090   mp->is_add = is_add;
15091   mp->is_ip_any = is_ip_any;
15092   S (mp);
15093   W (ret);
15094   return ret;
15095 }
15096
15097 static int
15098 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15099 {
15100   unformat_input_t *i = vam->input;
15101   vl_api_ipsec_sad_add_del_entry_t *mp;
15102   u32 sad_id = 0, spi = 0;
15103   u8 *ck = 0, *ik = 0;
15104   u8 is_add = 1;
15105
15106   u8 protocol = IPSEC_PROTOCOL_AH;
15107   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15108   u32 crypto_alg = 0, integ_alg = 0;
15109   ip4_address_t tun_src4;
15110   ip4_address_t tun_dst4;
15111   ip6_address_t tun_src6;
15112   ip6_address_t tun_dst6;
15113   int ret;
15114
15115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15116     {
15117       if (unformat (i, "del"))
15118         is_add = 0;
15119       else if (unformat (i, "sad_id %d", &sad_id))
15120         ;
15121       else if (unformat (i, "spi %d", &spi))
15122         ;
15123       else if (unformat (i, "esp"))
15124         protocol = IPSEC_PROTOCOL_ESP;
15125       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15126         {
15127           is_tunnel = 1;
15128           is_tunnel_ipv6 = 0;
15129         }
15130       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15131         {
15132           is_tunnel = 1;
15133           is_tunnel_ipv6 = 0;
15134         }
15135       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15136         {
15137           is_tunnel = 1;
15138           is_tunnel_ipv6 = 1;
15139         }
15140       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15141         {
15142           is_tunnel = 1;
15143           is_tunnel_ipv6 = 1;
15144         }
15145       else
15146         if (unformat
15147             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15148         {
15149           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
15150               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15151             {
15152               clib_warning ("unsupported crypto-alg: '%U'",
15153                             format_ipsec_crypto_alg, crypto_alg);
15154               return -99;
15155             }
15156         }
15157       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15158         ;
15159       else
15160         if (unformat
15161             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15162         {
15163           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
15164               integ_alg >= IPSEC_INTEG_N_ALG)
15165             {
15166               clib_warning ("unsupported integ-alg: '%U'",
15167                             format_ipsec_integ_alg, integ_alg);
15168               return -99;
15169             }
15170         }
15171       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15172         ;
15173       else
15174         {
15175           clib_warning ("parse error '%U'", format_unformat_error, i);
15176           return -99;
15177         }
15178
15179     }
15180
15181   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15182
15183   mp->sad_id = ntohl (sad_id);
15184   mp->is_add = is_add;
15185   mp->protocol = protocol;
15186   mp->spi = ntohl (spi);
15187   mp->is_tunnel = is_tunnel;
15188   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15189   mp->crypto_algorithm = crypto_alg;
15190   mp->integrity_algorithm = integ_alg;
15191   mp->crypto_key_length = vec_len (ck);
15192   mp->integrity_key_length = vec_len (ik);
15193
15194   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15195     mp->crypto_key_length = sizeof (mp->crypto_key);
15196
15197   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15198     mp->integrity_key_length = sizeof (mp->integrity_key);
15199
15200   if (ck)
15201     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15202   if (ik)
15203     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15204
15205   if (is_tunnel)
15206     {
15207       if (is_tunnel_ipv6)
15208         {
15209           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15210                        sizeof (ip6_address_t));
15211           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15212                        sizeof (ip6_address_t));
15213         }
15214       else
15215         {
15216           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15217                        sizeof (ip4_address_t));
15218           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15219                        sizeof (ip4_address_t));
15220         }
15221     }
15222
15223   S (mp);
15224   W (ret);
15225   return ret;
15226 }
15227
15228 static int
15229 api_ipsec_sa_set_key (vat_main_t * vam)
15230 {
15231   unformat_input_t *i = vam->input;
15232   vl_api_ipsec_sa_set_key_t *mp;
15233   u32 sa_id;
15234   u8 *ck = 0, *ik = 0;
15235   int ret;
15236
15237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15238     {
15239       if (unformat (i, "sa_id %d", &sa_id))
15240         ;
15241       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15242         ;
15243       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15244         ;
15245       else
15246         {
15247           clib_warning ("parse error '%U'", format_unformat_error, i);
15248           return -99;
15249         }
15250     }
15251
15252   M (IPSEC_SA_SET_KEY, mp);
15253
15254   mp->sa_id = ntohl (sa_id);
15255   mp->crypto_key_length = vec_len (ck);
15256   mp->integrity_key_length = vec_len (ik);
15257
15258   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15259     mp->crypto_key_length = sizeof (mp->crypto_key);
15260
15261   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15262     mp->integrity_key_length = sizeof (mp->integrity_key);
15263
15264   if (ck)
15265     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15266   if (ik)
15267     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15268
15269   S (mp);
15270   W (ret);
15271   return ret;
15272 }
15273
15274 static int
15275 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15276 {
15277   unformat_input_t *i = vam->input;
15278   vl_api_ipsec_tunnel_if_add_del_t *mp;
15279   u32 local_spi = 0, remote_spi = 0;
15280   u32 crypto_alg = 0, integ_alg = 0;
15281   u8 *lck = NULL, *rck = NULL;
15282   u8 *lik = NULL, *rik = NULL;
15283   ip4_address_t local_ip = { {0} };
15284   ip4_address_t remote_ip = { {0} };
15285   u8 is_add = 1;
15286   u8 esn = 0;
15287   u8 anti_replay = 0;
15288   u8 renumber = 0;
15289   u32 instance = ~0;
15290   int ret;
15291
15292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15293     {
15294       if (unformat (i, "del"))
15295         is_add = 0;
15296       else if (unformat (i, "esn"))
15297         esn = 1;
15298       else if (unformat (i, "anti_replay"))
15299         anti_replay = 1;
15300       else if (unformat (i, "local_spi %d", &local_spi))
15301         ;
15302       else if (unformat (i, "remote_spi %d", &remote_spi))
15303         ;
15304       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15305         ;
15306       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15307         ;
15308       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15309         ;
15310       else
15311         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15312         ;
15313       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15314         ;
15315       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15316         ;
15317       else
15318         if (unformat
15319             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15320         {
15321           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
15322               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15323             {
15324               errmsg ("unsupported crypto-alg: '%U'\n",
15325                       format_ipsec_crypto_alg, crypto_alg);
15326               return -99;
15327             }
15328         }
15329       else
15330         if (unformat
15331             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15332         {
15333           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
15334               integ_alg >= IPSEC_INTEG_N_ALG)
15335             {
15336               errmsg ("unsupported integ-alg: '%U'\n",
15337                       format_ipsec_integ_alg, integ_alg);
15338               return -99;
15339             }
15340         }
15341       else if (unformat (i, "instance %u", &instance))
15342         renumber = 1;
15343       else
15344         {
15345           errmsg ("parse error '%U'\n", format_unformat_error, i);
15346           return -99;
15347         }
15348     }
15349
15350   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15351
15352   mp->is_add = is_add;
15353   mp->esn = esn;
15354   mp->anti_replay = anti_replay;
15355
15356   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15357   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15358
15359   mp->local_spi = htonl (local_spi);
15360   mp->remote_spi = htonl (remote_spi);
15361   mp->crypto_alg = (u8) crypto_alg;
15362
15363   mp->local_crypto_key_len = 0;
15364   if (lck)
15365     {
15366       mp->local_crypto_key_len = vec_len (lck);
15367       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15368         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15369       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15370     }
15371
15372   mp->remote_crypto_key_len = 0;
15373   if (rck)
15374     {
15375       mp->remote_crypto_key_len = vec_len (rck);
15376       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15377         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15378       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15379     }
15380
15381   mp->integ_alg = (u8) integ_alg;
15382
15383   mp->local_integ_key_len = 0;
15384   if (lik)
15385     {
15386       mp->local_integ_key_len = vec_len (lik);
15387       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15388         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15389       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15390     }
15391
15392   mp->remote_integ_key_len = 0;
15393   if (rik)
15394     {
15395       mp->remote_integ_key_len = vec_len (rik);
15396       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15397         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15398       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15399     }
15400
15401   if (renumber)
15402     {
15403       mp->renumber = renumber;
15404       mp->show_instance = ntohl (instance);
15405     }
15406
15407   S (mp);
15408   W (ret);
15409   return ret;
15410 }
15411
15412 static void
15413 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15414 {
15415   vat_main_t *vam = &vat_main;
15416
15417   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15418          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15419          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15420          "tunnel_src_addr %U tunnel_dst_addr %U "
15421          "salt %u seq_outbound %lu last_seq_inbound %lu "
15422          "replay_window %lu total_data_size %lu\n",
15423          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15424          mp->protocol,
15425          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15426          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15427          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15428          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15429          mp->tunnel_src_addr,
15430          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15431          mp->tunnel_dst_addr,
15432          ntohl (mp->salt),
15433          clib_net_to_host_u64 (mp->seq_outbound),
15434          clib_net_to_host_u64 (mp->last_seq_inbound),
15435          clib_net_to_host_u64 (mp->replay_window),
15436          clib_net_to_host_u64 (mp->total_data_size));
15437 }
15438
15439 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15440 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15441
15442 static void vl_api_ipsec_sa_details_t_handler_json
15443   (vl_api_ipsec_sa_details_t * mp)
15444 {
15445   vat_main_t *vam = &vat_main;
15446   vat_json_node_t *node = NULL;
15447   struct in_addr src_ip4, dst_ip4;
15448   struct in6_addr src_ip6, dst_ip6;
15449
15450   if (VAT_JSON_ARRAY != vam->json_tree.type)
15451     {
15452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15453       vat_json_init_array (&vam->json_tree);
15454     }
15455   node = vat_json_array_add (&vam->json_tree);
15456
15457   vat_json_init_object (node);
15458   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15459   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15460   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15461   vat_json_object_add_uint (node, "proto", mp->protocol);
15462   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15463   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15464   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15465   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15466   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15467   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15468   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15469                              mp->crypto_key_len);
15470   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15471                              mp->integ_key_len);
15472   if (mp->is_tunnel_ip6)
15473     {
15474       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15475       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15476       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15477       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15478     }
15479   else
15480     {
15481       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15482       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15483       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15484       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15485     }
15486   vat_json_object_add_uint (node, "replay_window",
15487                             clib_net_to_host_u64 (mp->replay_window));
15488   vat_json_object_add_uint (node, "total_data_size",
15489                             clib_net_to_host_u64 (mp->total_data_size));
15490
15491 }
15492
15493 static int
15494 api_ipsec_sa_dump (vat_main_t * vam)
15495 {
15496   unformat_input_t *i = vam->input;
15497   vl_api_ipsec_sa_dump_t *mp;
15498   vl_api_control_ping_t *mp_ping;
15499   u32 sa_id = ~0;
15500   int ret;
15501
15502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15503     {
15504       if (unformat (i, "sa_id %d", &sa_id))
15505         ;
15506       else
15507         {
15508           clib_warning ("parse error '%U'", format_unformat_error, i);
15509           return -99;
15510         }
15511     }
15512
15513   M (IPSEC_SA_DUMP, mp);
15514
15515   mp->sa_id = ntohl (sa_id);
15516
15517   S (mp);
15518
15519   /* Use a control ping for synchronization */
15520   M (CONTROL_PING, mp_ping);
15521   S (mp_ping);
15522
15523   W (ret);
15524   return ret;
15525 }
15526
15527 static int
15528 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15529 {
15530   unformat_input_t *i = vam->input;
15531   vl_api_ipsec_tunnel_if_set_key_t *mp;
15532   u32 sw_if_index = ~0;
15533   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15534   u8 *key = 0;
15535   u32 alg = ~0;
15536   int ret;
15537
15538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15539     {
15540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15541         ;
15542       else
15543         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15544         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15545       else
15546         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15547         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15548       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15549         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15550       else
15551         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15552         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15553       else if (unformat (i, "%U", unformat_hex_string, &key))
15554         ;
15555       else
15556         {
15557           clib_warning ("parse error '%U'", format_unformat_error, i);
15558           return -99;
15559         }
15560     }
15561
15562   if (sw_if_index == ~0)
15563     {
15564       errmsg ("interface must be specified");
15565       return -99;
15566     }
15567
15568   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15569     {
15570       errmsg ("key type must be specified");
15571       return -99;
15572     }
15573
15574   if (alg == ~0)
15575     {
15576       errmsg ("algorithm must be specified");
15577       return -99;
15578     }
15579
15580   if (vec_len (key) == 0)
15581     {
15582       errmsg ("key must be specified");
15583       return -99;
15584     }
15585
15586   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15587
15588   mp->sw_if_index = htonl (sw_if_index);
15589   mp->alg = alg;
15590   mp->key_type = key_type;
15591   mp->key_len = vec_len (key);
15592   clib_memcpy (mp->key, key, vec_len (key));
15593
15594   S (mp);
15595   W (ret);
15596
15597   return ret;
15598 }
15599
15600 static int
15601 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15602 {
15603   unformat_input_t *i = vam->input;
15604   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15605   u32 sw_if_index = ~0;
15606   u32 sa_id = ~0;
15607   u8 is_outbound = (u8) ~ 0;
15608   int ret;
15609
15610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15613         ;
15614       else if (unformat (i, "sa_id %d", &sa_id))
15615         ;
15616       else if (unformat (i, "outbound"))
15617         is_outbound = 1;
15618       else if (unformat (i, "inbound"))
15619         is_outbound = 0;
15620       else
15621         {
15622           clib_warning ("parse error '%U'", format_unformat_error, i);
15623           return -99;
15624         }
15625     }
15626
15627   if (sw_if_index == ~0)
15628     {
15629       errmsg ("interface must be specified");
15630       return -99;
15631     }
15632
15633   if (sa_id == ~0)
15634     {
15635       errmsg ("SA ID must be specified");
15636       return -99;
15637     }
15638
15639   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15640
15641   mp->sw_if_index = htonl (sw_if_index);
15642   mp->sa_id = htonl (sa_id);
15643   mp->is_outbound = is_outbound;
15644
15645   S (mp);
15646   W (ret);
15647
15648   return ret;
15649 }
15650
15651 static int
15652 api_ikev2_profile_add_del (vat_main_t * vam)
15653 {
15654   unformat_input_t *i = vam->input;
15655   vl_api_ikev2_profile_add_del_t *mp;
15656   u8 is_add = 1;
15657   u8 *name = 0;
15658   int ret;
15659
15660   const char *valid_chars = "a-zA-Z0-9_";
15661
15662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15663     {
15664       if (unformat (i, "del"))
15665         is_add = 0;
15666       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15667         vec_add1 (name, 0);
15668       else
15669         {
15670           errmsg ("parse error '%U'", format_unformat_error, i);
15671           return -99;
15672         }
15673     }
15674
15675   if (!vec_len (name))
15676     {
15677       errmsg ("profile name must be specified");
15678       return -99;
15679     }
15680
15681   if (vec_len (name) > 64)
15682     {
15683       errmsg ("profile name too long");
15684       return -99;
15685     }
15686
15687   M (IKEV2_PROFILE_ADD_DEL, mp);
15688
15689   clib_memcpy (mp->name, name, vec_len (name));
15690   mp->is_add = is_add;
15691   vec_free (name);
15692
15693   S (mp);
15694   W (ret);
15695   return ret;
15696 }
15697
15698 static int
15699 api_ikev2_profile_set_auth (vat_main_t * vam)
15700 {
15701   unformat_input_t *i = vam->input;
15702   vl_api_ikev2_profile_set_auth_t *mp;
15703   u8 *name = 0;
15704   u8 *data = 0;
15705   u32 auth_method = 0;
15706   u8 is_hex = 0;
15707   int ret;
15708
15709   const char *valid_chars = "a-zA-Z0-9_";
15710
15711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15712     {
15713       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15714         vec_add1 (name, 0);
15715       else if (unformat (i, "auth_method %U",
15716                          unformat_ikev2_auth_method, &auth_method))
15717         ;
15718       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15719         is_hex = 1;
15720       else if (unformat (i, "auth_data %v", &data))
15721         ;
15722       else
15723         {
15724           errmsg ("parse error '%U'", format_unformat_error, i);
15725           return -99;
15726         }
15727     }
15728
15729   if (!vec_len (name))
15730     {
15731       errmsg ("profile name must be specified");
15732       return -99;
15733     }
15734
15735   if (vec_len (name) > 64)
15736     {
15737       errmsg ("profile name too long");
15738       return -99;
15739     }
15740
15741   if (!vec_len (data))
15742     {
15743       errmsg ("auth_data must be specified");
15744       return -99;
15745     }
15746
15747   if (!auth_method)
15748     {
15749       errmsg ("auth_method must be specified");
15750       return -99;
15751     }
15752
15753   M (IKEV2_PROFILE_SET_AUTH, mp);
15754
15755   mp->is_hex = is_hex;
15756   mp->auth_method = (u8) auth_method;
15757   mp->data_len = vec_len (data);
15758   clib_memcpy (mp->name, name, vec_len (name));
15759   clib_memcpy (mp->data, data, vec_len (data));
15760   vec_free (name);
15761   vec_free (data);
15762
15763   S (mp);
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_ikev2_profile_set_id (vat_main_t * vam)
15770 {
15771   unformat_input_t *i = vam->input;
15772   vl_api_ikev2_profile_set_id_t *mp;
15773   u8 *name = 0;
15774   u8 *data = 0;
15775   u8 is_local = 0;
15776   u32 id_type = 0;
15777   ip4_address_t ip4;
15778   int ret;
15779
15780   const char *valid_chars = "a-zA-Z0-9_";
15781
15782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15783     {
15784       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15785         vec_add1 (name, 0);
15786       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15787         ;
15788       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15789         {
15790           data = vec_new (u8, 4);
15791           clib_memcpy (data, ip4.as_u8, 4);
15792         }
15793       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15794         ;
15795       else if (unformat (i, "id_data %v", &data))
15796         ;
15797       else if (unformat (i, "local"))
15798         is_local = 1;
15799       else if (unformat (i, "remote"))
15800         is_local = 0;
15801       else
15802         {
15803           errmsg ("parse error '%U'", format_unformat_error, i);
15804           return -99;
15805         }
15806     }
15807
15808   if (!vec_len (name))
15809     {
15810       errmsg ("profile name must be specified");
15811       return -99;
15812     }
15813
15814   if (vec_len (name) > 64)
15815     {
15816       errmsg ("profile name too long");
15817       return -99;
15818     }
15819
15820   if (!vec_len (data))
15821     {
15822       errmsg ("id_data must be specified");
15823       return -99;
15824     }
15825
15826   if (!id_type)
15827     {
15828       errmsg ("id_type must be specified");
15829       return -99;
15830     }
15831
15832   M (IKEV2_PROFILE_SET_ID, mp);
15833
15834   mp->is_local = is_local;
15835   mp->id_type = (u8) id_type;
15836   mp->data_len = vec_len (data);
15837   clib_memcpy (mp->name, name, vec_len (name));
15838   clib_memcpy (mp->data, data, vec_len (data));
15839   vec_free (name);
15840   vec_free (data);
15841
15842   S (mp);
15843   W (ret);
15844   return ret;
15845 }
15846
15847 static int
15848 api_ikev2_profile_set_ts (vat_main_t * vam)
15849 {
15850   unformat_input_t *i = vam->input;
15851   vl_api_ikev2_profile_set_ts_t *mp;
15852   u8 *name = 0;
15853   u8 is_local = 0;
15854   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15855   ip4_address_t start_addr, end_addr;
15856
15857   const char *valid_chars = "a-zA-Z0-9_";
15858   int ret;
15859
15860   start_addr.as_u32 = 0;
15861   end_addr.as_u32 = (u32) ~ 0;
15862
15863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15864     {
15865       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15866         vec_add1 (name, 0);
15867       else if (unformat (i, "protocol %d", &proto))
15868         ;
15869       else if (unformat (i, "start_port %d", &start_port))
15870         ;
15871       else if (unformat (i, "end_port %d", &end_port))
15872         ;
15873       else
15874         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15875         ;
15876       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15877         ;
15878       else if (unformat (i, "local"))
15879         is_local = 1;
15880       else if (unformat (i, "remote"))
15881         is_local = 0;
15882       else
15883         {
15884           errmsg ("parse error '%U'", format_unformat_error, i);
15885           return -99;
15886         }
15887     }
15888
15889   if (!vec_len (name))
15890     {
15891       errmsg ("profile name must be specified");
15892       return -99;
15893     }
15894
15895   if (vec_len (name) > 64)
15896     {
15897       errmsg ("profile name too long");
15898       return -99;
15899     }
15900
15901   M (IKEV2_PROFILE_SET_TS, mp);
15902
15903   mp->is_local = is_local;
15904   mp->proto = (u8) proto;
15905   mp->start_port = (u16) start_port;
15906   mp->end_port = (u16) end_port;
15907   mp->start_addr = start_addr.as_u32;
15908   mp->end_addr = end_addr.as_u32;
15909   clib_memcpy (mp->name, name, vec_len (name));
15910   vec_free (name);
15911
15912   S (mp);
15913   W (ret);
15914   return ret;
15915 }
15916
15917 static int
15918 api_ikev2_set_local_key (vat_main_t * vam)
15919 {
15920   unformat_input_t *i = vam->input;
15921   vl_api_ikev2_set_local_key_t *mp;
15922   u8 *file = 0;
15923   int ret;
15924
15925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15926     {
15927       if (unformat (i, "file %v", &file))
15928         vec_add1 (file, 0);
15929       else
15930         {
15931           errmsg ("parse error '%U'", format_unformat_error, i);
15932           return -99;
15933         }
15934     }
15935
15936   if (!vec_len (file))
15937     {
15938       errmsg ("RSA key file must be specified");
15939       return -99;
15940     }
15941
15942   if (vec_len (file) > 256)
15943     {
15944       errmsg ("file name too long");
15945       return -99;
15946     }
15947
15948   M (IKEV2_SET_LOCAL_KEY, mp);
15949
15950   clib_memcpy (mp->key_file, file, vec_len (file));
15951   vec_free (file);
15952
15953   S (mp);
15954   W (ret);
15955   return ret;
15956 }
15957
15958 static int
15959 api_ikev2_set_responder (vat_main_t * vam)
15960 {
15961   unformat_input_t *i = vam->input;
15962   vl_api_ikev2_set_responder_t *mp;
15963   int ret;
15964   u8 *name = 0;
15965   u32 sw_if_index = ~0;
15966   ip4_address_t address;
15967
15968   const char *valid_chars = "a-zA-Z0-9_";
15969
15970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15971     {
15972       if (unformat
15973           (i, "%U interface %d address %U", unformat_token, valid_chars,
15974            &name, &sw_if_index, unformat_ip4_address, &address))
15975         vec_add1 (name, 0);
15976       else
15977         {
15978           errmsg ("parse error '%U'", format_unformat_error, i);
15979           return -99;
15980         }
15981     }
15982
15983   if (!vec_len (name))
15984     {
15985       errmsg ("profile name must be specified");
15986       return -99;
15987     }
15988
15989   if (vec_len (name) > 64)
15990     {
15991       errmsg ("profile name too long");
15992       return -99;
15993     }
15994
15995   M (IKEV2_SET_RESPONDER, mp);
15996
15997   clib_memcpy (mp->name, name, vec_len (name));
15998   vec_free (name);
15999
16000   mp->sw_if_index = sw_if_index;
16001   clib_memcpy (mp->address, &address, sizeof (address));
16002
16003   S (mp);
16004   W (ret);
16005   return ret;
16006 }
16007
16008 static int
16009 api_ikev2_set_ike_transforms (vat_main_t * vam)
16010 {
16011   unformat_input_t *i = vam->input;
16012   vl_api_ikev2_set_ike_transforms_t *mp;
16013   int ret;
16014   u8 *name = 0;
16015   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16016
16017   const char *valid_chars = "a-zA-Z0-9_";
16018
16019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16020     {
16021       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16022                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16023         vec_add1 (name, 0);
16024       else
16025         {
16026           errmsg ("parse error '%U'", format_unformat_error, i);
16027           return -99;
16028         }
16029     }
16030
16031   if (!vec_len (name))
16032     {
16033       errmsg ("profile name must be specified");
16034       return -99;
16035     }
16036
16037   if (vec_len (name) > 64)
16038     {
16039       errmsg ("profile name too long");
16040       return -99;
16041     }
16042
16043   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16044
16045   clib_memcpy (mp->name, name, vec_len (name));
16046   vec_free (name);
16047   mp->crypto_alg = crypto_alg;
16048   mp->crypto_key_size = crypto_key_size;
16049   mp->integ_alg = integ_alg;
16050   mp->dh_group = dh_group;
16051
16052   S (mp);
16053   W (ret);
16054   return ret;
16055 }
16056
16057
16058 static int
16059 api_ikev2_set_esp_transforms (vat_main_t * vam)
16060 {
16061   unformat_input_t *i = vam->input;
16062   vl_api_ikev2_set_esp_transforms_t *mp;
16063   int ret;
16064   u8 *name = 0;
16065   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16066
16067   const char *valid_chars = "a-zA-Z0-9_";
16068
16069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16070     {
16071       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16072                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16073         vec_add1 (name, 0);
16074       else
16075         {
16076           errmsg ("parse error '%U'", format_unformat_error, i);
16077           return -99;
16078         }
16079     }
16080
16081   if (!vec_len (name))
16082     {
16083       errmsg ("profile name must be specified");
16084       return -99;
16085     }
16086
16087   if (vec_len (name) > 64)
16088     {
16089       errmsg ("profile name too long");
16090       return -99;
16091     }
16092
16093   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16094
16095   clib_memcpy (mp->name, name, vec_len (name));
16096   vec_free (name);
16097   mp->crypto_alg = crypto_alg;
16098   mp->crypto_key_size = crypto_key_size;
16099   mp->integ_alg = integ_alg;
16100   mp->dh_group = dh_group;
16101
16102   S (mp);
16103   W (ret);
16104   return ret;
16105 }
16106
16107 static int
16108 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16109 {
16110   unformat_input_t *i = vam->input;
16111   vl_api_ikev2_set_sa_lifetime_t *mp;
16112   int ret;
16113   u8 *name = 0;
16114   u64 lifetime, lifetime_maxdata;
16115   u32 lifetime_jitter, handover;
16116
16117   const char *valid_chars = "a-zA-Z0-9_";
16118
16119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16120     {
16121       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16122                     &lifetime, &lifetime_jitter, &handover,
16123                     &lifetime_maxdata))
16124         vec_add1 (name, 0);
16125       else
16126         {
16127           errmsg ("parse error '%U'", format_unformat_error, i);
16128           return -99;
16129         }
16130     }
16131
16132   if (!vec_len (name))
16133     {
16134       errmsg ("profile name must be specified");
16135       return -99;
16136     }
16137
16138   if (vec_len (name) > 64)
16139     {
16140       errmsg ("profile name too long");
16141       return -99;
16142     }
16143
16144   M (IKEV2_SET_SA_LIFETIME, mp);
16145
16146   clib_memcpy (mp->name, name, vec_len (name));
16147   vec_free (name);
16148   mp->lifetime = lifetime;
16149   mp->lifetime_jitter = lifetime_jitter;
16150   mp->handover = handover;
16151   mp->lifetime_maxdata = lifetime_maxdata;
16152
16153   S (mp);
16154   W (ret);
16155   return ret;
16156 }
16157
16158 static int
16159 api_ikev2_initiate_sa_init (vat_main_t * vam)
16160 {
16161   unformat_input_t *i = vam->input;
16162   vl_api_ikev2_initiate_sa_init_t *mp;
16163   int ret;
16164   u8 *name = 0;
16165
16166   const char *valid_chars = "a-zA-Z0-9_";
16167
16168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16169     {
16170       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16171         vec_add1 (name, 0);
16172       else
16173         {
16174           errmsg ("parse error '%U'", format_unformat_error, i);
16175           return -99;
16176         }
16177     }
16178
16179   if (!vec_len (name))
16180     {
16181       errmsg ("profile name must be specified");
16182       return -99;
16183     }
16184
16185   if (vec_len (name) > 64)
16186     {
16187       errmsg ("profile name too long");
16188       return -99;
16189     }
16190
16191   M (IKEV2_INITIATE_SA_INIT, mp);
16192
16193   clib_memcpy (mp->name, name, vec_len (name));
16194   vec_free (name);
16195
16196   S (mp);
16197   W (ret);
16198   return ret;
16199 }
16200
16201 static int
16202 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16203 {
16204   unformat_input_t *i = vam->input;
16205   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16206   int ret;
16207   u64 ispi;
16208
16209
16210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16211     {
16212       if (unformat (i, "%lx", &ispi))
16213         ;
16214       else
16215         {
16216           errmsg ("parse error '%U'", format_unformat_error, i);
16217           return -99;
16218         }
16219     }
16220
16221   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16222
16223   mp->ispi = ispi;
16224
16225   S (mp);
16226   W (ret);
16227   return ret;
16228 }
16229
16230 static int
16231 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16232 {
16233   unformat_input_t *i = vam->input;
16234   vl_api_ikev2_initiate_del_child_sa_t *mp;
16235   int ret;
16236   u32 ispi;
16237
16238
16239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16240     {
16241       if (unformat (i, "%x", &ispi))
16242         ;
16243       else
16244         {
16245           errmsg ("parse error '%U'", format_unformat_error, i);
16246           return -99;
16247         }
16248     }
16249
16250   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16251
16252   mp->ispi = ispi;
16253
16254   S (mp);
16255   W (ret);
16256   return ret;
16257 }
16258
16259 static int
16260 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16261 {
16262   unformat_input_t *i = vam->input;
16263   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16264   int ret;
16265   u32 ispi;
16266
16267
16268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16269     {
16270       if (unformat (i, "%x", &ispi))
16271         ;
16272       else
16273         {
16274           errmsg ("parse error '%U'", format_unformat_error, i);
16275           return -99;
16276         }
16277     }
16278
16279   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16280
16281   mp->ispi = ispi;
16282
16283   S (mp);
16284   W (ret);
16285   return ret;
16286 }
16287
16288 /*
16289  * MAP
16290  */
16291 static int
16292 api_map_add_domain (vat_main_t * vam)
16293 {
16294   unformat_input_t *i = vam->input;
16295   vl_api_map_add_domain_t *mp;
16296
16297   ip4_address_t ip4_prefix;
16298   ip6_address_t ip6_prefix;
16299   ip6_address_t ip6_src;
16300   u32 num_m_args = 0;
16301   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16302     0, psid_length = 0;
16303   u8 is_translation = 0;
16304   u32 mtu = 0;
16305   u32 ip6_src_len = 128;
16306   int ret;
16307
16308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16309     {
16310       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16311                     &ip4_prefix, &ip4_prefix_len))
16312         num_m_args++;
16313       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16314                          &ip6_prefix, &ip6_prefix_len))
16315         num_m_args++;
16316       else
16317         if (unformat
16318             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16319              &ip6_src_len))
16320         num_m_args++;
16321       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16322         num_m_args++;
16323       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16324         num_m_args++;
16325       else if (unformat (i, "psid-offset %d", &psid_offset))
16326         num_m_args++;
16327       else if (unformat (i, "psid-len %d", &psid_length))
16328         num_m_args++;
16329       else if (unformat (i, "mtu %d", &mtu))
16330         num_m_args++;
16331       else if (unformat (i, "map-t"))
16332         is_translation = 1;
16333       else
16334         {
16335           clib_warning ("parse error '%U'", format_unformat_error, i);
16336           return -99;
16337         }
16338     }
16339
16340   if (num_m_args < 3)
16341     {
16342       errmsg ("mandatory argument(s) missing");
16343       return -99;
16344     }
16345
16346   /* Construct the API message */
16347   M (MAP_ADD_DOMAIN, mp);
16348
16349   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16350   mp->ip4_prefix_len = ip4_prefix_len;
16351
16352   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16353   mp->ip6_prefix_len = ip6_prefix_len;
16354
16355   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16356   mp->ip6_src_prefix_len = ip6_src_len;
16357
16358   mp->ea_bits_len = ea_bits_len;
16359   mp->psid_offset = psid_offset;
16360   mp->psid_length = psid_length;
16361   mp->is_translation = is_translation;
16362   mp->mtu = htons (mtu);
16363
16364   /* send it... */
16365   S (mp);
16366
16367   /* Wait for a reply, return good/bad news  */
16368   W (ret);
16369   return ret;
16370 }
16371
16372 static int
16373 api_map_del_domain (vat_main_t * vam)
16374 {
16375   unformat_input_t *i = vam->input;
16376   vl_api_map_del_domain_t *mp;
16377
16378   u32 num_m_args = 0;
16379   u32 index;
16380   int ret;
16381
16382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16383     {
16384       if (unformat (i, "index %d", &index))
16385         num_m_args++;
16386       else
16387         {
16388           clib_warning ("parse error '%U'", format_unformat_error, i);
16389           return -99;
16390         }
16391     }
16392
16393   if (num_m_args != 1)
16394     {
16395       errmsg ("mandatory argument(s) missing");
16396       return -99;
16397     }
16398
16399   /* Construct the API message */
16400   M (MAP_DEL_DOMAIN, mp);
16401
16402   mp->index = ntohl (index);
16403
16404   /* send it... */
16405   S (mp);
16406
16407   /* Wait for a reply, return good/bad news  */
16408   W (ret);
16409   return ret;
16410 }
16411
16412 static int
16413 api_map_add_del_rule (vat_main_t * vam)
16414 {
16415   unformat_input_t *i = vam->input;
16416   vl_api_map_add_del_rule_t *mp;
16417   u8 is_add = 1;
16418   ip6_address_t ip6_dst;
16419   u32 num_m_args = 0, index, psid = 0;
16420   int ret;
16421
16422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16423     {
16424       if (unformat (i, "index %d", &index))
16425         num_m_args++;
16426       else if (unformat (i, "psid %d", &psid))
16427         num_m_args++;
16428       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16429         num_m_args++;
16430       else if (unformat (i, "del"))
16431         {
16432           is_add = 0;
16433         }
16434       else
16435         {
16436           clib_warning ("parse error '%U'", format_unformat_error, i);
16437           return -99;
16438         }
16439     }
16440
16441   /* Construct the API message */
16442   M (MAP_ADD_DEL_RULE, mp);
16443
16444   mp->index = ntohl (index);
16445   mp->is_add = is_add;
16446   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16447   mp->psid = ntohs (psid);
16448
16449   /* send it... */
16450   S (mp);
16451
16452   /* Wait for a reply, return good/bad news  */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 static int
16458 api_map_domain_dump (vat_main_t * vam)
16459 {
16460   vl_api_map_domain_dump_t *mp;
16461   vl_api_control_ping_t *mp_ping;
16462   int ret;
16463
16464   /* Construct the API message */
16465   M (MAP_DOMAIN_DUMP, mp);
16466
16467   /* send it... */
16468   S (mp);
16469
16470   /* Use a control ping for synchronization */
16471   MPING (CONTROL_PING, mp_ping);
16472   S (mp_ping);
16473
16474   W (ret);
16475   return ret;
16476 }
16477
16478 static int
16479 api_map_rule_dump (vat_main_t * vam)
16480 {
16481   unformat_input_t *i = vam->input;
16482   vl_api_map_rule_dump_t *mp;
16483   vl_api_control_ping_t *mp_ping;
16484   u32 domain_index = ~0;
16485   int ret;
16486
16487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16488     {
16489       if (unformat (i, "index %u", &domain_index))
16490         ;
16491       else
16492         break;
16493     }
16494
16495   if (domain_index == ~0)
16496     {
16497       clib_warning ("parse error: domain index expected");
16498       return -99;
16499     }
16500
16501   /* Construct the API message */
16502   M (MAP_RULE_DUMP, mp);
16503
16504   mp->domain_index = htonl (domain_index);
16505
16506   /* send it... */
16507   S (mp);
16508
16509   /* Use a control ping for synchronization */
16510   MPING (CONTROL_PING, mp_ping);
16511   S (mp_ping);
16512
16513   W (ret);
16514   return ret;
16515 }
16516
16517 static void vl_api_map_add_domain_reply_t_handler
16518   (vl_api_map_add_domain_reply_t * mp)
16519 {
16520   vat_main_t *vam = &vat_main;
16521   i32 retval = ntohl (mp->retval);
16522
16523   if (vam->async_mode)
16524     {
16525       vam->async_errors += (retval < 0);
16526     }
16527   else
16528     {
16529       vam->retval = retval;
16530       vam->result_ready = 1;
16531     }
16532 }
16533
16534 static void vl_api_map_add_domain_reply_t_handler_json
16535   (vl_api_map_add_domain_reply_t * mp)
16536 {
16537   vat_main_t *vam = &vat_main;
16538   vat_json_node_t node;
16539
16540   vat_json_init_object (&node);
16541   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16542   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16543
16544   vat_json_print (vam->ofp, &node);
16545   vat_json_free (&node);
16546
16547   vam->retval = ntohl (mp->retval);
16548   vam->result_ready = 1;
16549 }
16550
16551 static int
16552 api_get_first_msg_id (vat_main_t * vam)
16553 {
16554   vl_api_get_first_msg_id_t *mp;
16555   unformat_input_t *i = vam->input;
16556   u8 *name;
16557   u8 name_set = 0;
16558   int ret;
16559
16560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16561     {
16562       if (unformat (i, "client %s", &name))
16563         name_set = 1;
16564       else
16565         break;
16566     }
16567
16568   if (name_set == 0)
16569     {
16570       errmsg ("missing client name");
16571       return -99;
16572     }
16573   vec_add1 (name, 0);
16574
16575   if (vec_len (name) > 63)
16576     {
16577       errmsg ("client name too long");
16578       return -99;
16579     }
16580
16581   M (GET_FIRST_MSG_ID, mp);
16582   clib_memcpy (mp->name, name, vec_len (name));
16583   S (mp);
16584   W (ret);
16585   return ret;
16586 }
16587
16588 static int
16589 api_cop_interface_enable_disable (vat_main_t * vam)
16590 {
16591   unformat_input_t *line_input = vam->input;
16592   vl_api_cop_interface_enable_disable_t *mp;
16593   u32 sw_if_index = ~0;
16594   u8 enable_disable = 1;
16595   int ret;
16596
16597   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16598     {
16599       if (unformat (line_input, "disable"))
16600         enable_disable = 0;
16601       if (unformat (line_input, "enable"))
16602         enable_disable = 1;
16603       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16604                          vam, &sw_if_index))
16605         ;
16606       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16607         ;
16608       else
16609         break;
16610     }
16611
16612   if (sw_if_index == ~0)
16613     {
16614       errmsg ("missing interface name or sw_if_index");
16615       return -99;
16616     }
16617
16618   /* Construct the API message */
16619   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16620   mp->sw_if_index = ntohl (sw_if_index);
16621   mp->enable_disable = enable_disable;
16622
16623   /* send it... */
16624   S (mp);
16625   /* Wait for the reply */
16626   W (ret);
16627   return ret;
16628 }
16629
16630 static int
16631 api_cop_whitelist_enable_disable (vat_main_t * vam)
16632 {
16633   unformat_input_t *line_input = vam->input;
16634   vl_api_cop_whitelist_enable_disable_t *mp;
16635   u32 sw_if_index = ~0;
16636   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16637   u32 fib_id = 0;
16638   int ret;
16639
16640   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16641     {
16642       if (unformat (line_input, "ip4"))
16643         ip4 = 1;
16644       else if (unformat (line_input, "ip6"))
16645         ip6 = 1;
16646       else if (unformat (line_input, "default"))
16647         default_cop = 1;
16648       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16649                          vam, &sw_if_index))
16650         ;
16651       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16652         ;
16653       else if (unformat (line_input, "fib-id %d", &fib_id))
16654         ;
16655       else
16656         break;
16657     }
16658
16659   if (sw_if_index == ~0)
16660     {
16661       errmsg ("missing interface name or sw_if_index");
16662       return -99;
16663     }
16664
16665   /* Construct the API message */
16666   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16667   mp->sw_if_index = ntohl (sw_if_index);
16668   mp->fib_id = ntohl (fib_id);
16669   mp->ip4 = ip4;
16670   mp->ip6 = ip6;
16671   mp->default_cop = default_cop;
16672
16673   /* send it... */
16674   S (mp);
16675   /* Wait for the reply */
16676   W (ret);
16677   return ret;
16678 }
16679
16680 static int
16681 api_get_node_graph (vat_main_t * vam)
16682 {
16683   vl_api_get_node_graph_t *mp;
16684   int ret;
16685
16686   M (GET_NODE_GRAPH, mp);
16687
16688   /* send it... */
16689   S (mp);
16690   /* Wait for the reply */
16691   W (ret);
16692   return ret;
16693 }
16694
16695 /* *INDENT-OFF* */
16696 /** Used for parsing LISP eids */
16697 typedef CLIB_PACKED(struct{
16698   u8 addr[16];   /**< eid address */
16699   u32 len;       /**< prefix length if IP */
16700   u8 type;      /**< type of eid */
16701 }) lisp_eid_vat_t;
16702 /* *INDENT-ON* */
16703
16704 static uword
16705 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16706 {
16707   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16708
16709   memset (a, 0, sizeof (a[0]));
16710
16711   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16712     {
16713       a->type = 0;              /* ipv4 type */
16714     }
16715   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16716     {
16717       a->type = 1;              /* ipv6 type */
16718     }
16719   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16720     {
16721       a->type = 2;              /* mac type */
16722     }
16723   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16724     {
16725       a->type = 3;              /* NSH type */
16726       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16727       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16728     }
16729   else
16730     {
16731       return 0;
16732     }
16733
16734   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16735     {
16736       return 0;
16737     }
16738
16739   return 1;
16740 }
16741
16742 static int
16743 lisp_eid_size_vat (u8 type)
16744 {
16745   switch (type)
16746     {
16747     case 0:
16748       return 4;
16749     case 1:
16750       return 16;
16751     case 2:
16752       return 6;
16753     case 3:
16754       return 5;
16755     }
16756   return 0;
16757 }
16758
16759 static void
16760 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16761 {
16762   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16763 }
16764
16765 static int
16766 api_one_add_del_locator_set (vat_main_t * vam)
16767 {
16768   unformat_input_t *input = vam->input;
16769   vl_api_one_add_del_locator_set_t *mp;
16770   u8 is_add = 1;
16771   u8 *locator_set_name = NULL;
16772   u8 locator_set_name_set = 0;
16773   vl_api_local_locator_t locator, *locators = 0;
16774   u32 sw_if_index, priority, weight;
16775   u32 data_len = 0;
16776
16777   int ret;
16778   /* Parse args required to build the message */
16779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16780     {
16781       if (unformat (input, "del"))
16782         {
16783           is_add = 0;
16784         }
16785       else if (unformat (input, "locator-set %s", &locator_set_name))
16786         {
16787           locator_set_name_set = 1;
16788         }
16789       else if (unformat (input, "sw_if_index %u p %u w %u",
16790                          &sw_if_index, &priority, &weight))
16791         {
16792           locator.sw_if_index = htonl (sw_if_index);
16793           locator.priority = priority;
16794           locator.weight = weight;
16795           vec_add1 (locators, locator);
16796         }
16797       else
16798         if (unformat
16799             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16800              &sw_if_index, &priority, &weight))
16801         {
16802           locator.sw_if_index = htonl (sw_if_index);
16803           locator.priority = priority;
16804           locator.weight = weight;
16805           vec_add1 (locators, locator);
16806         }
16807       else
16808         break;
16809     }
16810
16811   if (locator_set_name_set == 0)
16812     {
16813       errmsg ("missing locator-set name");
16814       vec_free (locators);
16815       return -99;
16816     }
16817
16818   if (vec_len (locator_set_name) > 64)
16819     {
16820       errmsg ("locator-set name too long");
16821       vec_free (locator_set_name);
16822       vec_free (locators);
16823       return -99;
16824     }
16825   vec_add1 (locator_set_name, 0);
16826
16827   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16828
16829   /* Construct the API message */
16830   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16831
16832   mp->is_add = is_add;
16833   clib_memcpy (mp->locator_set_name, locator_set_name,
16834                vec_len (locator_set_name));
16835   vec_free (locator_set_name);
16836
16837   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16838   if (locators)
16839     clib_memcpy (mp->locators, locators, data_len);
16840   vec_free (locators);
16841
16842   /* send it... */
16843   S (mp);
16844
16845   /* Wait for a reply... */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16851
16852 static int
16853 api_one_add_del_locator (vat_main_t * vam)
16854 {
16855   unformat_input_t *input = vam->input;
16856   vl_api_one_add_del_locator_t *mp;
16857   u32 tmp_if_index = ~0;
16858   u32 sw_if_index = ~0;
16859   u8 sw_if_index_set = 0;
16860   u8 sw_if_index_if_name_set = 0;
16861   u32 priority = ~0;
16862   u8 priority_set = 0;
16863   u32 weight = ~0;
16864   u8 weight_set = 0;
16865   u8 is_add = 1;
16866   u8 *locator_set_name = NULL;
16867   u8 locator_set_name_set = 0;
16868   int ret;
16869
16870   /* Parse args required to build the message */
16871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16872     {
16873       if (unformat (input, "del"))
16874         {
16875           is_add = 0;
16876         }
16877       else if (unformat (input, "locator-set %s", &locator_set_name))
16878         {
16879           locator_set_name_set = 1;
16880         }
16881       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16882                          &tmp_if_index))
16883         {
16884           sw_if_index_if_name_set = 1;
16885           sw_if_index = tmp_if_index;
16886         }
16887       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16888         {
16889           sw_if_index_set = 1;
16890           sw_if_index = tmp_if_index;
16891         }
16892       else if (unformat (input, "p %d", &priority))
16893         {
16894           priority_set = 1;
16895         }
16896       else if (unformat (input, "w %d", &weight))
16897         {
16898           weight_set = 1;
16899         }
16900       else
16901         break;
16902     }
16903
16904   if (locator_set_name_set == 0)
16905     {
16906       errmsg ("missing locator-set name");
16907       return -99;
16908     }
16909
16910   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16911     {
16912       errmsg ("missing sw_if_index");
16913       vec_free (locator_set_name);
16914       return -99;
16915     }
16916
16917   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16918     {
16919       errmsg ("cannot use both params interface name and sw_if_index");
16920       vec_free (locator_set_name);
16921       return -99;
16922     }
16923
16924   if (priority_set == 0)
16925     {
16926       errmsg ("missing locator-set priority");
16927       vec_free (locator_set_name);
16928       return -99;
16929     }
16930
16931   if (weight_set == 0)
16932     {
16933       errmsg ("missing locator-set weight");
16934       vec_free (locator_set_name);
16935       return -99;
16936     }
16937
16938   if (vec_len (locator_set_name) > 64)
16939     {
16940       errmsg ("locator-set name too long");
16941       vec_free (locator_set_name);
16942       return -99;
16943     }
16944   vec_add1 (locator_set_name, 0);
16945
16946   /* Construct the API message */
16947   M (ONE_ADD_DEL_LOCATOR, mp);
16948
16949   mp->is_add = is_add;
16950   mp->sw_if_index = ntohl (sw_if_index);
16951   mp->priority = priority;
16952   mp->weight = weight;
16953   clib_memcpy (mp->locator_set_name, locator_set_name,
16954                vec_len (locator_set_name));
16955   vec_free (locator_set_name);
16956
16957   /* send it... */
16958   S (mp);
16959
16960   /* Wait for a reply... */
16961   W (ret);
16962   return ret;
16963 }
16964
16965 #define api_lisp_add_del_locator api_one_add_del_locator
16966
16967 uword
16968 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16969 {
16970   u32 *key_id = va_arg (*args, u32 *);
16971   u8 *s = 0;
16972
16973   if (unformat (input, "%s", &s))
16974     {
16975       if (!strcmp ((char *) s, "sha1"))
16976         key_id[0] = HMAC_SHA_1_96;
16977       else if (!strcmp ((char *) s, "sha256"))
16978         key_id[0] = HMAC_SHA_256_128;
16979       else
16980         {
16981           clib_warning ("invalid key_id: '%s'", s);
16982           key_id[0] = HMAC_NO_KEY;
16983         }
16984     }
16985   else
16986     return 0;
16987
16988   vec_free (s);
16989   return 1;
16990 }
16991
16992 static int
16993 api_one_add_del_local_eid (vat_main_t * vam)
16994 {
16995   unformat_input_t *input = vam->input;
16996   vl_api_one_add_del_local_eid_t *mp;
16997   u8 is_add = 1;
16998   u8 eid_set = 0;
16999   lisp_eid_vat_t _eid, *eid = &_eid;
17000   u8 *locator_set_name = 0;
17001   u8 locator_set_name_set = 0;
17002   u32 vni = 0;
17003   u16 key_id = 0;
17004   u8 *key = 0;
17005   int ret;
17006
17007   /* Parse args required to build the message */
17008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17009     {
17010       if (unformat (input, "del"))
17011         {
17012           is_add = 0;
17013         }
17014       else if (unformat (input, "vni %d", &vni))
17015         {
17016           ;
17017         }
17018       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17019         {
17020           eid_set = 1;
17021         }
17022       else if (unformat (input, "locator-set %s", &locator_set_name))
17023         {
17024           locator_set_name_set = 1;
17025         }
17026       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17027         ;
17028       else if (unformat (input, "secret-key %_%v%_", &key))
17029         ;
17030       else
17031         break;
17032     }
17033
17034   if (locator_set_name_set == 0)
17035     {
17036       errmsg ("missing locator-set name");
17037       return -99;
17038     }
17039
17040   if (0 == eid_set)
17041     {
17042       errmsg ("EID address not set!");
17043       vec_free (locator_set_name);
17044       return -99;
17045     }
17046
17047   if (key && (0 == key_id))
17048     {
17049       errmsg ("invalid key_id!");
17050       return -99;
17051     }
17052
17053   if (vec_len (key) > 64)
17054     {
17055       errmsg ("key too long");
17056       vec_free (key);
17057       return -99;
17058     }
17059
17060   if (vec_len (locator_set_name) > 64)
17061     {
17062       errmsg ("locator-set name too long");
17063       vec_free (locator_set_name);
17064       return -99;
17065     }
17066   vec_add1 (locator_set_name, 0);
17067
17068   /* Construct the API message */
17069   M (ONE_ADD_DEL_LOCAL_EID, mp);
17070
17071   mp->is_add = is_add;
17072   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17073   mp->eid_type = eid->type;
17074   mp->prefix_len = eid->len;
17075   mp->vni = clib_host_to_net_u32 (vni);
17076   mp->key_id = clib_host_to_net_u16 (key_id);
17077   clib_memcpy (mp->locator_set_name, locator_set_name,
17078                vec_len (locator_set_name));
17079   clib_memcpy (mp->key, key, vec_len (key));
17080
17081   vec_free (locator_set_name);
17082   vec_free (key);
17083
17084   /* send it... */
17085   S (mp);
17086
17087   /* Wait for a reply... */
17088   W (ret);
17089   return ret;
17090 }
17091
17092 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17093
17094 static int
17095 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17096 {
17097   u32 dp_table = 0, vni = 0;;
17098   unformat_input_t *input = vam->input;
17099   vl_api_gpe_add_del_fwd_entry_t *mp;
17100   u8 is_add = 1;
17101   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17102   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17103   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17104   u32 action = ~0, w;
17105   ip4_address_t rmt_rloc4, lcl_rloc4;
17106   ip6_address_t rmt_rloc6, lcl_rloc6;
17107   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17108   int ret;
17109
17110   memset (&rloc, 0, sizeof (rloc));
17111
17112   /* Parse args required to build the message */
17113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17114     {
17115       if (unformat (input, "del"))
17116         is_add = 0;
17117       else if (unformat (input, "add"))
17118         is_add = 1;
17119       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17120         {
17121           rmt_eid_set = 1;
17122         }
17123       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17124         {
17125           lcl_eid_set = 1;
17126         }
17127       else if (unformat (input, "vrf %d", &dp_table))
17128         ;
17129       else if (unformat (input, "bd %d", &dp_table))
17130         ;
17131       else if (unformat (input, "vni %d", &vni))
17132         ;
17133       else if (unformat (input, "w %d", &w))
17134         {
17135           if (!curr_rloc)
17136             {
17137               errmsg ("No RLOC configured for setting priority/weight!");
17138               return -99;
17139             }
17140           curr_rloc->weight = w;
17141         }
17142       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17143                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17144         {
17145           rloc.is_ip4 = 1;
17146
17147           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17148           rloc.weight = 0;
17149           vec_add1 (lcl_locs, rloc);
17150
17151           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17152           vec_add1 (rmt_locs, rloc);
17153           /* weight saved in rmt loc */
17154           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17155         }
17156       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17157                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17158         {
17159           rloc.is_ip4 = 0;
17160           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17161           rloc.weight = 0;
17162           vec_add1 (lcl_locs, rloc);
17163
17164           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17165           vec_add1 (rmt_locs, rloc);
17166           /* weight saved in rmt loc */
17167           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17168         }
17169       else if (unformat (input, "action %d", &action))
17170         {
17171           ;
17172         }
17173       else
17174         {
17175           clib_warning ("parse error '%U'", format_unformat_error, input);
17176           return -99;
17177         }
17178     }
17179
17180   if (!rmt_eid_set)
17181     {
17182       errmsg ("remote eid addresses not set");
17183       return -99;
17184     }
17185
17186   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17187     {
17188       errmsg ("eid types don't match");
17189       return -99;
17190     }
17191
17192   if (0 == rmt_locs && (u32) ~ 0 == action)
17193     {
17194       errmsg ("action not set for negative mapping");
17195       return -99;
17196     }
17197
17198   /* Construct the API message */
17199   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17200       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17201
17202   mp->is_add = is_add;
17203   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17204   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17205   mp->eid_type = rmt_eid->type;
17206   mp->dp_table = clib_host_to_net_u32 (dp_table);
17207   mp->vni = clib_host_to_net_u32 (vni);
17208   mp->rmt_len = rmt_eid->len;
17209   mp->lcl_len = lcl_eid->len;
17210   mp->action = action;
17211
17212   if (0 != rmt_locs && 0 != lcl_locs)
17213     {
17214       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17215       clib_memcpy (mp->locs, lcl_locs,
17216                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17217
17218       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17219       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17220                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17221     }
17222   vec_free (lcl_locs);
17223   vec_free (rmt_locs);
17224
17225   /* send it... */
17226   S (mp);
17227
17228   /* Wait for a reply... */
17229   W (ret);
17230   return ret;
17231 }
17232
17233 static int
17234 api_one_add_del_map_server (vat_main_t * vam)
17235 {
17236   unformat_input_t *input = vam->input;
17237   vl_api_one_add_del_map_server_t *mp;
17238   u8 is_add = 1;
17239   u8 ipv4_set = 0;
17240   u8 ipv6_set = 0;
17241   ip4_address_t ipv4;
17242   ip6_address_t ipv6;
17243   int ret;
17244
17245   /* Parse args required to build the message */
17246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17247     {
17248       if (unformat (input, "del"))
17249         {
17250           is_add = 0;
17251         }
17252       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17253         {
17254           ipv4_set = 1;
17255         }
17256       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17257         {
17258           ipv6_set = 1;
17259         }
17260       else
17261         break;
17262     }
17263
17264   if (ipv4_set && ipv6_set)
17265     {
17266       errmsg ("both eid v4 and v6 addresses set");
17267       return -99;
17268     }
17269
17270   if (!ipv4_set && !ipv6_set)
17271     {
17272       errmsg ("eid addresses not set");
17273       return -99;
17274     }
17275
17276   /* Construct the API message */
17277   M (ONE_ADD_DEL_MAP_SERVER, mp);
17278
17279   mp->is_add = is_add;
17280   if (ipv6_set)
17281     {
17282       mp->is_ipv6 = 1;
17283       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17284     }
17285   else
17286     {
17287       mp->is_ipv6 = 0;
17288       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17289     }
17290
17291   /* send it... */
17292   S (mp);
17293
17294   /* Wait for a reply... */
17295   W (ret);
17296   return ret;
17297 }
17298
17299 #define api_lisp_add_del_map_server api_one_add_del_map_server
17300
17301 static int
17302 api_one_add_del_map_resolver (vat_main_t * vam)
17303 {
17304   unformat_input_t *input = vam->input;
17305   vl_api_one_add_del_map_resolver_t *mp;
17306   u8 is_add = 1;
17307   u8 ipv4_set = 0;
17308   u8 ipv6_set = 0;
17309   ip4_address_t ipv4;
17310   ip6_address_t ipv6;
17311   int ret;
17312
17313   /* Parse args required to build the message */
17314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17315     {
17316       if (unformat (input, "del"))
17317         {
17318           is_add = 0;
17319         }
17320       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17321         {
17322           ipv4_set = 1;
17323         }
17324       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17325         {
17326           ipv6_set = 1;
17327         }
17328       else
17329         break;
17330     }
17331
17332   if (ipv4_set && ipv6_set)
17333     {
17334       errmsg ("both eid v4 and v6 addresses set");
17335       return -99;
17336     }
17337
17338   if (!ipv4_set && !ipv6_set)
17339     {
17340       errmsg ("eid addresses not set");
17341       return -99;
17342     }
17343
17344   /* Construct the API message */
17345   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17346
17347   mp->is_add = is_add;
17348   if (ipv6_set)
17349     {
17350       mp->is_ipv6 = 1;
17351       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17352     }
17353   else
17354     {
17355       mp->is_ipv6 = 0;
17356       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17357     }
17358
17359   /* send it... */
17360   S (mp);
17361
17362   /* Wait for a reply... */
17363   W (ret);
17364   return ret;
17365 }
17366
17367 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17368
17369 static int
17370 api_lisp_gpe_enable_disable (vat_main_t * vam)
17371 {
17372   unformat_input_t *input = vam->input;
17373   vl_api_gpe_enable_disable_t *mp;
17374   u8 is_set = 0;
17375   u8 is_en = 1;
17376   int ret;
17377
17378   /* Parse args required to build the message */
17379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17380     {
17381       if (unformat (input, "enable"))
17382         {
17383           is_set = 1;
17384           is_en = 1;
17385         }
17386       else if (unformat (input, "disable"))
17387         {
17388           is_set = 1;
17389           is_en = 0;
17390         }
17391       else
17392         break;
17393     }
17394
17395   if (is_set == 0)
17396     {
17397       errmsg ("Value not set");
17398       return -99;
17399     }
17400
17401   /* Construct the API message */
17402   M (GPE_ENABLE_DISABLE, mp);
17403
17404   mp->is_en = is_en;
17405
17406   /* send it... */
17407   S (mp);
17408
17409   /* Wait for a reply... */
17410   W (ret);
17411   return ret;
17412 }
17413
17414 static int
17415 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17416 {
17417   unformat_input_t *input = vam->input;
17418   vl_api_one_rloc_probe_enable_disable_t *mp;
17419   u8 is_set = 0;
17420   u8 is_en = 0;
17421   int ret;
17422
17423   /* Parse args required to build the message */
17424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17425     {
17426       if (unformat (input, "enable"))
17427         {
17428           is_set = 1;
17429           is_en = 1;
17430         }
17431       else if (unformat (input, "disable"))
17432         is_set = 1;
17433       else
17434         break;
17435     }
17436
17437   if (!is_set)
17438     {
17439       errmsg ("Value not set");
17440       return -99;
17441     }
17442
17443   /* Construct the API message */
17444   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17445
17446   mp->is_enabled = is_en;
17447
17448   /* send it... */
17449   S (mp);
17450
17451   /* Wait for a reply... */
17452   W (ret);
17453   return ret;
17454 }
17455
17456 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17457
17458 static int
17459 api_one_map_register_enable_disable (vat_main_t * vam)
17460 {
17461   unformat_input_t *input = vam->input;
17462   vl_api_one_map_register_enable_disable_t *mp;
17463   u8 is_set = 0;
17464   u8 is_en = 0;
17465   int ret;
17466
17467   /* Parse args required to build the message */
17468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17469     {
17470       if (unformat (input, "enable"))
17471         {
17472           is_set = 1;
17473           is_en = 1;
17474         }
17475       else if (unformat (input, "disable"))
17476         is_set = 1;
17477       else
17478         break;
17479     }
17480
17481   if (!is_set)
17482     {
17483       errmsg ("Value not set");
17484       return -99;
17485     }
17486
17487   /* Construct the API message */
17488   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17489
17490   mp->is_enabled = is_en;
17491
17492   /* send it... */
17493   S (mp);
17494
17495   /* Wait for a reply... */
17496   W (ret);
17497   return ret;
17498 }
17499
17500 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17501
17502 static int
17503 api_one_enable_disable (vat_main_t * vam)
17504 {
17505   unformat_input_t *input = vam->input;
17506   vl_api_one_enable_disable_t *mp;
17507   u8 is_set = 0;
17508   u8 is_en = 0;
17509   int ret;
17510
17511   /* Parse args required to build the message */
17512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17513     {
17514       if (unformat (input, "enable"))
17515         {
17516           is_set = 1;
17517           is_en = 1;
17518         }
17519       else if (unformat (input, "disable"))
17520         {
17521           is_set = 1;
17522         }
17523       else
17524         break;
17525     }
17526
17527   if (!is_set)
17528     {
17529       errmsg ("Value not set");
17530       return -99;
17531     }
17532
17533   /* Construct the API message */
17534   M (ONE_ENABLE_DISABLE, mp);
17535
17536   mp->is_en = is_en;
17537
17538   /* send it... */
17539   S (mp);
17540
17541   /* Wait for a reply... */
17542   W (ret);
17543   return ret;
17544 }
17545
17546 #define api_lisp_enable_disable api_one_enable_disable
17547
17548 static int
17549 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17550 {
17551   unformat_input_t *input = vam->input;
17552   vl_api_one_enable_disable_xtr_mode_t *mp;
17553   u8 is_set = 0;
17554   u8 is_en = 0;
17555   int ret;
17556
17557   /* Parse args required to build the message */
17558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17559     {
17560       if (unformat (input, "enable"))
17561         {
17562           is_set = 1;
17563           is_en = 1;
17564         }
17565       else if (unformat (input, "disable"))
17566         {
17567           is_set = 1;
17568         }
17569       else
17570         break;
17571     }
17572
17573   if (!is_set)
17574     {
17575       errmsg ("Value not set");
17576       return -99;
17577     }
17578
17579   /* Construct the API message */
17580   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17581
17582   mp->is_en = is_en;
17583
17584   /* send it... */
17585   S (mp);
17586
17587   /* Wait for a reply... */
17588   W (ret);
17589   return ret;
17590 }
17591
17592 static int
17593 api_one_show_xtr_mode (vat_main_t * vam)
17594 {
17595   vl_api_one_show_xtr_mode_t *mp;
17596   int ret;
17597
17598   /* Construct the API message */
17599   M (ONE_SHOW_XTR_MODE, mp);
17600
17601   /* send it... */
17602   S (mp);
17603
17604   /* Wait for a reply... */
17605   W (ret);
17606   return ret;
17607 }
17608
17609 static int
17610 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17611 {
17612   unformat_input_t *input = vam->input;
17613   vl_api_one_enable_disable_pitr_mode_t *mp;
17614   u8 is_set = 0;
17615   u8 is_en = 0;
17616   int ret;
17617
17618   /* Parse args required to build the message */
17619   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17620     {
17621       if (unformat (input, "enable"))
17622         {
17623           is_set = 1;
17624           is_en = 1;
17625         }
17626       else if (unformat (input, "disable"))
17627         {
17628           is_set = 1;
17629         }
17630       else
17631         break;
17632     }
17633
17634   if (!is_set)
17635     {
17636       errmsg ("Value not set");
17637       return -99;
17638     }
17639
17640   /* Construct the API message */
17641   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17642
17643   mp->is_en = is_en;
17644
17645   /* send it... */
17646   S (mp);
17647
17648   /* Wait for a reply... */
17649   W (ret);
17650   return ret;
17651 }
17652
17653 static int
17654 api_one_show_pitr_mode (vat_main_t * vam)
17655 {
17656   vl_api_one_show_pitr_mode_t *mp;
17657   int ret;
17658
17659   /* Construct the API message */
17660   M (ONE_SHOW_PITR_MODE, mp);
17661
17662   /* send it... */
17663   S (mp);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 static int
17671 api_one_enable_disable_petr_mode (vat_main_t * vam)
17672 {
17673   unformat_input_t *input = vam->input;
17674   vl_api_one_enable_disable_petr_mode_t *mp;
17675   u8 is_set = 0;
17676   u8 is_en = 0;
17677   int ret;
17678
17679   /* Parse args required to build the message */
17680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17681     {
17682       if (unformat (input, "enable"))
17683         {
17684           is_set = 1;
17685           is_en = 1;
17686         }
17687       else if (unformat (input, "disable"))
17688         {
17689           is_set = 1;
17690         }
17691       else
17692         break;
17693     }
17694
17695   if (!is_set)
17696     {
17697       errmsg ("Value not set");
17698       return -99;
17699     }
17700
17701   /* Construct the API message */
17702   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17703
17704   mp->is_en = is_en;
17705
17706   /* send it... */
17707   S (mp);
17708
17709   /* Wait for a reply... */
17710   W (ret);
17711   return ret;
17712 }
17713
17714 static int
17715 api_one_show_petr_mode (vat_main_t * vam)
17716 {
17717   vl_api_one_show_petr_mode_t *mp;
17718   int ret;
17719
17720   /* Construct the API message */
17721   M (ONE_SHOW_PETR_MODE, mp);
17722
17723   /* send it... */
17724   S (mp);
17725
17726   /* Wait for a reply... */
17727   W (ret);
17728   return ret;
17729 }
17730
17731 static int
17732 api_show_one_map_register_state (vat_main_t * vam)
17733 {
17734   vl_api_show_one_map_register_state_t *mp;
17735   int ret;
17736
17737   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17738
17739   /* send */
17740   S (mp);
17741
17742   /* wait for reply */
17743   W (ret);
17744   return ret;
17745 }
17746
17747 #define api_show_lisp_map_register_state api_show_one_map_register_state
17748
17749 static int
17750 api_show_one_rloc_probe_state (vat_main_t * vam)
17751 {
17752   vl_api_show_one_rloc_probe_state_t *mp;
17753   int ret;
17754
17755   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17756
17757   /* send */
17758   S (mp);
17759
17760   /* wait for reply */
17761   W (ret);
17762   return ret;
17763 }
17764
17765 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17766
17767 static int
17768 api_one_add_del_ndp_entry (vat_main_t * vam)
17769 {
17770   vl_api_one_add_del_ndp_entry_t *mp;
17771   unformat_input_t *input = vam->input;
17772   u8 is_add = 1;
17773   u8 mac_set = 0;
17774   u8 bd_set = 0;
17775   u8 ip_set = 0;
17776   u8 mac[6] = { 0, };
17777   u8 ip6[16] = { 0, };
17778   u32 bd = ~0;
17779   int ret;
17780
17781   /* Parse args required to build the message */
17782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17783     {
17784       if (unformat (input, "del"))
17785         is_add = 0;
17786       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17787         mac_set = 1;
17788       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17789         ip_set = 1;
17790       else if (unformat (input, "bd %d", &bd))
17791         bd_set = 1;
17792       else
17793         {
17794           errmsg ("parse error '%U'", format_unformat_error, input);
17795           return -99;
17796         }
17797     }
17798
17799   if (!bd_set || !ip_set || (!mac_set && is_add))
17800     {
17801       errmsg ("Missing BD, IP or MAC!");
17802       return -99;
17803     }
17804
17805   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17806   mp->is_add = is_add;
17807   clib_memcpy (mp->mac, mac, 6);
17808   mp->bd = clib_host_to_net_u32 (bd);
17809   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17810
17811   /* send */
17812   S (mp);
17813
17814   /* wait for reply */
17815   W (ret);
17816   return ret;
17817 }
17818
17819 static int
17820 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17821 {
17822   vl_api_one_add_del_l2_arp_entry_t *mp;
17823   unformat_input_t *input = vam->input;
17824   u8 is_add = 1;
17825   u8 mac_set = 0;
17826   u8 bd_set = 0;
17827   u8 ip_set = 0;
17828   u8 mac[6] = { 0, };
17829   u32 ip4 = 0, bd = ~0;
17830   int ret;
17831
17832   /* Parse args required to build the message */
17833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17834     {
17835       if (unformat (input, "del"))
17836         is_add = 0;
17837       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17838         mac_set = 1;
17839       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17840         ip_set = 1;
17841       else if (unformat (input, "bd %d", &bd))
17842         bd_set = 1;
17843       else
17844         {
17845           errmsg ("parse error '%U'", format_unformat_error, input);
17846           return -99;
17847         }
17848     }
17849
17850   if (!bd_set || !ip_set || (!mac_set && is_add))
17851     {
17852       errmsg ("Missing BD, IP or MAC!");
17853       return -99;
17854     }
17855
17856   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17857   mp->is_add = is_add;
17858   clib_memcpy (mp->mac, mac, 6);
17859   mp->bd = clib_host_to_net_u32 (bd);
17860   mp->ip4 = ip4;
17861
17862   /* send */
17863   S (mp);
17864
17865   /* wait for reply */
17866   W (ret);
17867   return ret;
17868 }
17869
17870 static int
17871 api_one_ndp_bd_get (vat_main_t * vam)
17872 {
17873   vl_api_one_ndp_bd_get_t *mp;
17874   int ret;
17875
17876   M (ONE_NDP_BD_GET, mp);
17877
17878   /* send */
17879   S (mp);
17880
17881   /* wait for reply */
17882   W (ret);
17883   return ret;
17884 }
17885
17886 static int
17887 api_one_ndp_entries_get (vat_main_t * vam)
17888 {
17889   vl_api_one_ndp_entries_get_t *mp;
17890   unformat_input_t *input = vam->input;
17891   u8 bd_set = 0;
17892   u32 bd = ~0;
17893   int ret;
17894
17895   /* Parse args required to build the message */
17896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (input, "bd %d", &bd))
17899         bd_set = 1;
17900       else
17901         {
17902           errmsg ("parse error '%U'", format_unformat_error, input);
17903           return -99;
17904         }
17905     }
17906
17907   if (!bd_set)
17908     {
17909       errmsg ("Expected bridge domain!");
17910       return -99;
17911     }
17912
17913   M (ONE_NDP_ENTRIES_GET, mp);
17914   mp->bd = clib_host_to_net_u32 (bd);
17915
17916   /* send */
17917   S (mp);
17918
17919   /* wait for reply */
17920   W (ret);
17921   return ret;
17922 }
17923
17924 static int
17925 api_one_l2_arp_bd_get (vat_main_t * vam)
17926 {
17927   vl_api_one_l2_arp_bd_get_t *mp;
17928   int ret;
17929
17930   M (ONE_L2_ARP_BD_GET, mp);
17931
17932   /* send */
17933   S (mp);
17934
17935   /* wait for reply */
17936   W (ret);
17937   return ret;
17938 }
17939
17940 static int
17941 api_one_l2_arp_entries_get (vat_main_t * vam)
17942 {
17943   vl_api_one_l2_arp_entries_get_t *mp;
17944   unformat_input_t *input = vam->input;
17945   u8 bd_set = 0;
17946   u32 bd = ~0;
17947   int ret;
17948
17949   /* Parse args required to build the message */
17950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17951     {
17952       if (unformat (input, "bd %d", &bd))
17953         bd_set = 1;
17954       else
17955         {
17956           errmsg ("parse error '%U'", format_unformat_error, input);
17957           return -99;
17958         }
17959     }
17960
17961   if (!bd_set)
17962     {
17963       errmsg ("Expected bridge domain!");
17964       return -99;
17965     }
17966
17967   M (ONE_L2_ARP_ENTRIES_GET, mp);
17968   mp->bd = clib_host_to_net_u32 (bd);
17969
17970   /* send */
17971   S (mp);
17972
17973   /* wait for reply */
17974   W (ret);
17975   return ret;
17976 }
17977
17978 static int
17979 api_one_stats_enable_disable (vat_main_t * vam)
17980 {
17981   vl_api_one_stats_enable_disable_t *mp;
17982   unformat_input_t *input = vam->input;
17983   u8 is_set = 0;
17984   u8 is_en = 0;
17985   int ret;
17986
17987   /* Parse args required to build the message */
17988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17989     {
17990       if (unformat (input, "enable"))
17991         {
17992           is_set = 1;
17993           is_en = 1;
17994         }
17995       else if (unformat (input, "disable"))
17996         {
17997           is_set = 1;
17998         }
17999       else
18000         break;
18001     }
18002
18003   if (!is_set)
18004     {
18005       errmsg ("Value not set");
18006       return -99;
18007     }
18008
18009   M (ONE_STATS_ENABLE_DISABLE, mp);
18010   mp->is_en = is_en;
18011
18012   /* send */
18013   S (mp);
18014
18015   /* wait for reply */
18016   W (ret);
18017   return ret;
18018 }
18019
18020 static int
18021 api_show_one_stats_enable_disable (vat_main_t * vam)
18022 {
18023   vl_api_show_one_stats_enable_disable_t *mp;
18024   int ret;
18025
18026   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18027
18028   /* send */
18029   S (mp);
18030
18031   /* wait for reply */
18032   W (ret);
18033   return ret;
18034 }
18035
18036 static int
18037 api_show_one_map_request_mode (vat_main_t * vam)
18038 {
18039   vl_api_show_one_map_request_mode_t *mp;
18040   int ret;
18041
18042   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18043
18044   /* send */
18045   S (mp);
18046
18047   /* wait for reply */
18048   W (ret);
18049   return ret;
18050 }
18051
18052 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18053
18054 static int
18055 api_one_map_request_mode (vat_main_t * vam)
18056 {
18057   unformat_input_t *input = vam->input;
18058   vl_api_one_map_request_mode_t *mp;
18059   u8 mode = 0;
18060   int ret;
18061
18062   /* Parse args required to build the message */
18063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18064     {
18065       if (unformat (input, "dst-only"))
18066         mode = 0;
18067       else if (unformat (input, "src-dst"))
18068         mode = 1;
18069       else
18070         {
18071           errmsg ("parse error '%U'", format_unformat_error, input);
18072           return -99;
18073         }
18074     }
18075
18076   M (ONE_MAP_REQUEST_MODE, mp);
18077
18078   mp->mode = mode;
18079
18080   /* send */
18081   S (mp);
18082
18083   /* wait for reply */
18084   W (ret);
18085   return ret;
18086 }
18087
18088 #define api_lisp_map_request_mode api_one_map_request_mode
18089
18090 /**
18091  * Enable/disable ONE proxy ITR.
18092  *
18093  * @param vam vpp API test context
18094  * @return return code
18095  */
18096 static int
18097 api_one_pitr_set_locator_set (vat_main_t * vam)
18098 {
18099   u8 ls_name_set = 0;
18100   unformat_input_t *input = vam->input;
18101   vl_api_one_pitr_set_locator_set_t *mp;
18102   u8 is_add = 1;
18103   u8 *ls_name = 0;
18104   int ret;
18105
18106   /* Parse args required to build the message */
18107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18108     {
18109       if (unformat (input, "del"))
18110         is_add = 0;
18111       else if (unformat (input, "locator-set %s", &ls_name))
18112         ls_name_set = 1;
18113       else
18114         {
18115           errmsg ("parse error '%U'", format_unformat_error, input);
18116           return -99;
18117         }
18118     }
18119
18120   if (!ls_name_set)
18121     {
18122       errmsg ("locator-set name not set!");
18123       return -99;
18124     }
18125
18126   M (ONE_PITR_SET_LOCATOR_SET, mp);
18127
18128   mp->is_add = is_add;
18129   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18130   vec_free (ls_name);
18131
18132   /* send */
18133   S (mp);
18134
18135   /* wait for reply */
18136   W (ret);
18137   return ret;
18138 }
18139
18140 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18141
18142 static int
18143 api_one_nsh_set_locator_set (vat_main_t * vam)
18144 {
18145   u8 ls_name_set = 0;
18146   unformat_input_t *input = vam->input;
18147   vl_api_one_nsh_set_locator_set_t *mp;
18148   u8 is_add = 1;
18149   u8 *ls_name = 0;
18150   int ret;
18151
18152   /* Parse args required to build the message */
18153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18154     {
18155       if (unformat (input, "del"))
18156         is_add = 0;
18157       else if (unformat (input, "ls %s", &ls_name))
18158         ls_name_set = 1;
18159       else
18160         {
18161           errmsg ("parse error '%U'", format_unformat_error, input);
18162           return -99;
18163         }
18164     }
18165
18166   if (!ls_name_set && is_add)
18167     {
18168       errmsg ("locator-set name not set!");
18169       return -99;
18170     }
18171
18172   M (ONE_NSH_SET_LOCATOR_SET, mp);
18173
18174   mp->is_add = is_add;
18175   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18176   vec_free (ls_name);
18177
18178   /* send */
18179   S (mp);
18180
18181   /* wait for reply */
18182   W (ret);
18183   return ret;
18184 }
18185
18186 static int
18187 api_show_one_pitr (vat_main_t * vam)
18188 {
18189   vl_api_show_one_pitr_t *mp;
18190   int ret;
18191
18192   if (!vam->json_output)
18193     {
18194       print (vam->ofp, "%=20s", "lisp status:");
18195     }
18196
18197   M (SHOW_ONE_PITR, mp);
18198   /* send it... */
18199   S (mp);
18200
18201   /* Wait for a reply... */
18202   W (ret);
18203   return ret;
18204 }
18205
18206 #define api_show_lisp_pitr api_show_one_pitr
18207
18208 static int
18209 api_one_use_petr (vat_main_t * vam)
18210 {
18211   unformat_input_t *input = vam->input;
18212   vl_api_one_use_petr_t *mp;
18213   u8 is_add = 0;
18214   ip_address_t ip;
18215   int ret;
18216
18217   memset (&ip, 0, sizeof (ip));
18218
18219   /* Parse args required to build the message */
18220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18221     {
18222       if (unformat (input, "disable"))
18223         is_add = 0;
18224       else
18225         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18226         {
18227           is_add = 1;
18228           ip_addr_version (&ip) = IP4;
18229         }
18230       else
18231         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18232         {
18233           is_add = 1;
18234           ip_addr_version (&ip) = IP6;
18235         }
18236       else
18237         {
18238           errmsg ("parse error '%U'", format_unformat_error, input);
18239           return -99;
18240         }
18241     }
18242
18243   M (ONE_USE_PETR, mp);
18244
18245   mp->is_add = is_add;
18246   if (is_add)
18247     {
18248       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18249       if (mp->is_ip4)
18250         clib_memcpy (mp->address, &ip, 4);
18251       else
18252         clib_memcpy (mp->address, &ip, 16);
18253     }
18254
18255   /* send */
18256   S (mp);
18257
18258   /* wait for reply */
18259   W (ret);
18260   return ret;
18261 }
18262
18263 #define api_lisp_use_petr api_one_use_petr
18264
18265 static int
18266 api_show_one_nsh_mapping (vat_main_t * vam)
18267 {
18268   vl_api_show_one_use_petr_t *mp;
18269   int ret;
18270
18271   if (!vam->json_output)
18272     {
18273       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18274     }
18275
18276   M (SHOW_ONE_NSH_MAPPING, mp);
18277   /* send it... */
18278   S (mp);
18279
18280   /* Wait for a reply... */
18281   W (ret);
18282   return ret;
18283 }
18284
18285 static int
18286 api_show_one_use_petr (vat_main_t * vam)
18287 {
18288   vl_api_show_one_use_petr_t *mp;
18289   int ret;
18290
18291   if (!vam->json_output)
18292     {
18293       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18294     }
18295
18296   M (SHOW_ONE_USE_PETR, mp);
18297   /* send it... */
18298   S (mp);
18299
18300   /* Wait for a reply... */
18301   W (ret);
18302   return ret;
18303 }
18304
18305 #define api_show_lisp_use_petr api_show_one_use_petr
18306
18307 /**
18308  * Add/delete mapping between vni and vrf
18309  */
18310 static int
18311 api_one_eid_table_add_del_map (vat_main_t * vam)
18312 {
18313   unformat_input_t *input = vam->input;
18314   vl_api_one_eid_table_add_del_map_t *mp;
18315   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18316   u32 vni, vrf, bd_index;
18317   int ret;
18318
18319   /* Parse args required to build the message */
18320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18321     {
18322       if (unformat (input, "del"))
18323         is_add = 0;
18324       else if (unformat (input, "vrf %d", &vrf))
18325         vrf_set = 1;
18326       else if (unformat (input, "bd_index %d", &bd_index))
18327         bd_index_set = 1;
18328       else if (unformat (input, "vni %d", &vni))
18329         vni_set = 1;
18330       else
18331         break;
18332     }
18333
18334   if (!vni_set || (!vrf_set && !bd_index_set))
18335     {
18336       errmsg ("missing arguments!");
18337       return -99;
18338     }
18339
18340   if (vrf_set && bd_index_set)
18341     {
18342       errmsg ("error: both vrf and bd entered!");
18343       return -99;
18344     }
18345
18346   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18347
18348   mp->is_add = is_add;
18349   mp->vni = htonl (vni);
18350   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18351   mp->is_l2 = bd_index_set;
18352
18353   /* send */
18354   S (mp);
18355
18356   /* wait for reply */
18357   W (ret);
18358   return ret;
18359 }
18360
18361 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18362
18363 uword
18364 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18365 {
18366   u32 *action = va_arg (*args, u32 *);
18367   u8 *s = 0;
18368
18369   if (unformat (input, "%s", &s))
18370     {
18371       if (!strcmp ((char *) s, "no-action"))
18372         action[0] = 0;
18373       else if (!strcmp ((char *) s, "natively-forward"))
18374         action[0] = 1;
18375       else if (!strcmp ((char *) s, "send-map-request"))
18376         action[0] = 2;
18377       else if (!strcmp ((char *) s, "drop"))
18378         action[0] = 3;
18379       else
18380         {
18381           clib_warning ("invalid action: '%s'", s);
18382           action[0] = 3;
18383         }
18384     }
18385   else
18386     return 0;
18387
18388   vec_free (s);
18389   return 1;
18390 }
18391
18392 /**
18393  * Add/del remote mapping to/from ONE control plane
18394  *
18395  * @param vam vpp API test context
18396  * @return return code
18397  */
18398 static int
18399 api_one_add_del_remote_mapping (vat_main_t * vam)
18400 {
18401   unformat_input_t *input = vam->input;
18402   vl_api_one_add_del_remote_mapping_t *mp;
18403   u32 vni = 0;
18404   lisp_eid_vat_t _eid, *eid = &_eid;
18405   lisp_eid_vat_t _seid, *seid = &_seid;
18406   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18407   u32 action = ~0, p, w, data_len;
18408   ip4_address_t rloc4;
18409   ip6_address_t rloc6;
18410   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18411   int ret;
18412
18413   memset (&rloc, 0, sizeof (rloc));
18414
18415   /* Parse args required to build the message */
18416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18417     {
18418       if (unformat (input, "del-all"))
18419         {
18420           del_all = 1;
18421         }
18422       else if (unformat (input, "del"))
18423         {
18424           is_add = 0;
18425         }
18426       else if (unformat (input, "add"))
18427         {
18428           is_add = 1;
18429         }
18430       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18431         {
18432           eid_set = 1;
18433         }
18434       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18435         {
18436           seid_set = 1;
18437         }
18438       else if (unformat (input, "vni %d", &vni))
18439         {
18440           ;
18441         }
18442       else if (unformat (input, "p %d w %d", &p, &w))
18443         {
18444           if (!curr_rloc)
18445             {
18446               errmsg ("No RLOC configured for setting priority/weight!");
18447               return -99;
18448             }
18449           curr_rloc->priority = p;
18450           curr_rloc->weight = w;
18451         }
18452       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18453         {
18454           rloc.is_ip4 = 1;
18455           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18456           vec_add1 (rlocs, rloc);
18457           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18458         }
18459       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18460         {
18461           rloc.is_ip4 = 0;
18462           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18463           vec_add1 (rlocs, rloc);
18464           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18465         }
18466       else if (unformat (input, "action %U",
18467                          unformat_negative_mapping_action, &action))
18468         {
18469           ;
18470         }
18471       else
18472         {
18473           clib_warning ("parse error '%U'", format_unformat_error, input);
18474           return -99;
18475         }
18476     }
18477
18478   if (0 == eid_set)
18479     {
18480       errmsg ("missing params!");
18481       return -99;
18482     }
18483
18484   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18485     {
18486       errmsg ("no action set for negative map-reply!");
18487       return -99;
18488     }
18489
18490   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18491
18492   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18493   mp->is_add = is_add;
18494   mp->vni = htonl (vni);
18495   mp->action = (u8) action;
18496   mp->is_src_dst = seid_set;
18497   mp->eid_len = eid->len;
18498   mp->seid_len = seid->len;
18499   mp->del_all = del_all;
18500   mp->eid_type = eid->type;
18501   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18502   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18503
18504   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18505   clib_memcpy (mp->rlocs, rlocs, data_len);
18506   vec_free (rlocs);
18507
18508   /* send it... */
18509   S (mp);
18510
18511   /* Wait for a reply... */
18512   W (ret);
18513   return ret;
18514 }
18515
18516 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18517
18518 /**
18519  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18520  * forwarding entries in data-plane accordingly.
18521  *
18522  * @param vam vpp API test context
18523  * @return return code
18524  */
18525 static int
18526 api_one_add_del_adjacency (vat_main_t * vam)
18527 {
18528   unformat_input_t *input = vam->input;
18529   vl_api_one_add_del_adjacency_t *mp;
18530   u32 vni = 0;
18531   ip4_address_t leid4, reid4;
18532   ip6_address_t leid6, reid6;
18533   u8 reid_mac[6] = { 0 };
18534   u8 leid_mac[6] = { 0 };
18535   u8 reid_type, leid_type;
18536   u32 leid_len = 0, reid_len = 0, len;
18537   u8 is_add = 1;
18538   int ret;
18539
18540   leid_type = reid_type = (u8) ~ 0;
18541
18542   /* Parse args required to build the message */
18543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18544     {
18545       if (unformat (input, "del"))
18546         {
18547           is_add = 0;
18548         }
18549       else if (unformat (input, "add"))
18550         {
18551           is_add = 1;
18552         }
18553       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18554                          &reid4, &len))
18555         {
18556           reid_type = 0;        /* ipv4 */
18557           reid_len = len;
18558         }
18559       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18560                          &reid6, &len))
18561         {
18562           reid_type = 1;        /* ipv6 */
18563           reid_len = len;
18564         }
18565       else if (unformat (input, "reid %U", unformat_ethernet_address,
18566                          reid_mac))
18567         {
18568           reid_type = 2;        /* mac */
18569         }
18570       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18571                          &leid4, &len))
18572         {
18573           leid_type = 0;        /* ipv4 */
18574           leid_len = len;
18575         }
18576       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18577                          &leid6, &len))
18578         {
18579           leid_type = 1;        /* ipv6 */
18580           leid_len = len;
18581         }
18582       else if (unformat (input, "leid %U", unformat_ethernet_address,
18583                          leid_mac))
18584         {
18585           leid_type = 2;        /* mac */
18586         }
18587       else if (unformat (input, "vni %d", &vni))
18588         {
18589           ;
18590         }
18591       else
18592         {
18593           errmsg ("parse error '%U'", format_unformat_error, input);
18594           return -99;
18595         }
18596     }
18597
18598   if ((u8) ~ 0 == reid_type)
18599     {
18600       errmsg ("missing params!");
18601       return -99;
18602     }
18603
18604   if (leid_type != reid_type)
18605     {
18606       errmsg ("remote and local EIDs are of different types!");
18607       return -99;
18608     }
18609
18610   M (ONE_ADD_DEL_ADJACENCY, mp);
18611   mp->is_add = is_add;
18612   mp->vni = htonl (vni);
18613   mp->leid_len = leid_len;
18614   mp->reid_len = reid_len;
18615   mp->eid_type = reid_type;
18616
18617   switch (mp->eid_type)
18618     {
18619     case 0:
18620       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18621       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18622       break;
18623     case 1:
18624       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18625       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18626       break;
18627     case 2:
18628       clib_memcpy (mp->leid, leid_mac, 6);
18629       clib_memcpy (mp->reid, reid_mac, 6);
18630       break;
18631     default:
18632       errmsg ("unknown EID type %d!", mp->eid_type);
18633       return 0;
18634     }
18635
18636   /* send it... */
18637   S (mp);
18638
18639   /* Wait for a reply... */
18640   W (ret);
18641   return ret;
18642 }
18643
18644 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18645
18646 uword
18647 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18648 {
18649   u32 *mode = va_arg (*args, u32 *);
18650
18651   if (unformat (input, "lisp"))
18652     *mode = 0;
18653   else if (unformat (input, "vxlan"))
18654     *mode = 1;
18655   else
18656     return 0;
18657
18658   return 1;
18659 }
18660
18661 static int
18662 api_gpe_get_encap_mode (vat_main_t * vam)
18663 {
18664   vl_api_gpe_get_encap_mode_t *mp;
18665   int ret;
18666
18667   /* Construct the API message */
18668   M (GPE_GET_ENCAP_MODE, mp);
18669
18670   /* send it... */
18671   S (mp);
18672
18673   /* Wait for a reply... */
18674   W (ret);
18675   return ret;
18676 }
18677
18678 static int
18679 api_gpe_set_encap_mode (vat_main_t * vam)
18680 {
18681   unformat_input_t *input = vam->input;
18682   vl_api_gpe_set_encap_mode_t *mp;
18683   int ret;
18684   u32 mode = 0;
18685
18686   /* Parse args required to build the message */
18687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18688     {
18689       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18690         ;
18691       else
18692         break;
18693     }
18694
18695   /* Construct the API message */
18696   M (GPE_SET_ENCAP_MODE, mp);
18697
18698   mp->mode = mode;
18699
18700   /* send it... */
18701   S (mp);
18702
18703   /* Wait for a reply... */
18704   W (ret);
18705   return ret;
18706 }
18707
18708 static int
18709 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18710 {
18711   unformat_input_t *input = vam->input;
18712   vl_api_gpe_add_del_iface_t *mp;
18713   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18714   u32 dp_table = 0, vni = 0;
18715   int ret;
18716
18717   /* Parse args required to build the message */
18718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18719     {
18720       if (unformat (input, "up"))
18721         {
18722           action_set = 1;
18723           is_add = 1;
18724         }
18725       else if (unformat (input, "down"))
18726         {
18727           action_set = 1;
18728           is_add = 0;
18729         }
18730       else if (unformat (input, "table_id %d", &dp_table))
18731         {
18732           dp_table_set = 1;
18733         }
18734       else if (unformat (input, "bd_id %d", &dp_table))
18735         {
18736           dp_table_set = 1;
18737           is_l2 = 1;
18738         }
18739       else if (unformat (input, "vni %d", &vni))
18740         {
18741           vni_set = 1;
18742         }
18743       else
18744         break;
18745     }
18746
18747   if (action_set == 0)
18748     {
18749       errmsg ("Action not set");
18750       return -99;
18751     }
18752   if (dp_table_set == 0 || vni_set == 0)
18753     {
18754       errmsg ("vni and dp_table must be set");
18755       return -99;
18756     }
18757
18758   /* Construct the API message */
18759   M (GPE_ADD_DEL_IFACE, mp);
18760
18761   mp->is_add = is_add;
18762   mp->dp_table = clib_host_to_net_u32 (dp_table);
18763   mp->is_l2 = is_l2;
18764   mp->vni = clib_host_to_net_u32 (vni);
18765
18766   /* send it... */
18767   S (mp);
18768
18769   /* Wait for a reply... */
18770   W (ret);
18771   return ret;
18772 }
18773
18774 static int
18775 api_one_map_register_fallback_threshold (vat_main_t * vam)
18776 {
18777   unformat_input_t *input = vam->input;
18778   vl_api_one_map_register_fallback_threshold_t *mp;
18779   u32 value = 0;
18780   u8 is_set = 0;
18781   int ret;
18782
18783   /* Parse args required to build the message */
18784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18785     {
18786       if (unformat (input, "%u", &value))
18787         is_set = 1;
18788       else
18789         {
18790           clib_warning ("parse error '%U'", format_unformat_error, input);
18791           return -99;
18792         }
18793     }
18794
18795   if (!is_set)
18796     {
18797       errmsg ("fallback threshold value is missing!");
18798       return -99;
18799     }
18800
18801   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18802   mp->value = clib_host_to_net_u32 (value);
18803
18804   /* send it... */
18805   S (mp);
18806
18807   /* Wait for a reply... */
18808   W (ret);
18809   return ret;
18810 }
18811
18812 static int
18813 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18814 {
18815   vl_api_show_one_map_register_fallback_threshold_t *mp;
18816   int ret;
18817
18818   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18819
18820   /* send it... */
18821   S (mp);
18822
18823   /* Wait for a reply... */
18824   W (ret);
18825   return ret;
18826 }
18827
18828 uword
18829 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18830 {
18831   u32 *proto = va_arg (*args, u32 *);
18832
18833   if (unformat (input, "udp"))
18834     *proto = 1;
18835   else if (unformat (input, "api"))
18836     *proto = 2;
18837   else
18838     return 0;
18839
18840   return 1;
18841 }
18842
18843 static int
18844 api_one_set_transport_protocol (vat_main_t * vam)
18845 {
18846   unformat_input_t *input = vam->input;
18847   vl_api_one_set_transport_protocol_t *mp;
18848   u8 is_set = 0;
18849   u32 protocol = 0;
18850   int ret;
18851
18852   /* Parse args required to build the message */
18853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18854     {
18855       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18856         is_set = 1;
18857       else
18858         {
18859           clib_warning ("parse error '%U'", format_unformat_error, input);
18860           return -99;
18861         }
18862     }
18863
18864   if (!is_set)
18865     {
18866       errmsg ("Transport protocol missing!");
18867       return -99;
18868     }
18869
18870   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18871   mp->protocol = (u8) protocol;
18872
18873   /* send it... */
18874   S (mp);
18875
18876   /* Wait for a reply... */
18877   W (ret);
18878   return ret;
18879 }
18880
18881 static int
18882 api_one_get_transport_protocol (vat_main_t * vam)
18883 {
18884   vl_api_one_get_transport_protocol_t *mp;
18885   int ret;
18886
18887   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18888
18889   /* send it... */
18890   S (mp);
18891
18892   /* Wait for a reply... */
18893   W (ret);
18894   return ret;
18895 }
18896
18897 static int
18898 api_one_map_register_set_ttl (vat_main_t * vam)
18899 {
18900   unformat_input_t *input = vam->input;
18901   vl_api_one_map_register_set_ttl_t *mp;
18902   u32 ttl = 0;
18903   u8 is_set = 0;
18904   int ret;
18905
18906   /* Parse args required to build the message */
18907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18908     {
18909       if (unformat (input, "%u", &ttl))
18910         is_set = 1;
18911       else
18912         {
18913           clib_warning ("parse error '%U'", format_unformat_error, input);
18914           return -99;
18915         }
18916     }
18917
18918   if (!is_set)
18919     {
18920       errmsg ("TTL value missing!");
18921       return -99;
18922     }
18923
18924   M (ONE_MAP_REGISTER_SET_TTL, mp);
18925   mp->ttl = clib_host_to_net_u32 (ttl);
18926
18927   /* send it... */
18928   S (mp);
18929
18930   /* Wait for a reply... */
18931   W (ret);
18932   return ret;
18933 }
18934
18935 static int
18936 api_show_one_map_register_ttl (vat_main_t * vam)
18937 {
18938   vl_api_show_one_map_register_ttl_t *mp;
18939   int ret;
18940
18941   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18942
18943   /* send it... */
18944   S (mp);
18945
18946   /* Wait for a reply... */
18947   W (ret);
18948   return ret;
18949 }
18950
18951 /**
18952  * Add/del map request itr rlocs from ONE control plane and updates
18953  *
18954  * @param vam vpp API test context
18955  * @return return code
18956  */
18957 static int
18958 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18959 {
18960   unformat_input_t *input = vam->input;
18961   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18962   u8 *locator_set_name = 0;
18963   u8 locator_set_name_set = 0;
18964   u8 is_add = 1;
18965   int ret;
18966
18967   /* Parse args required to build the message */
18968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18969     {
18970       if (unformat (input, "del"))
18971         {
18972           is_add = 0;
18973         }
18974       else if (unformat (input, "%_%v%_", &locator_set_name))
18975         {
18976           locator_set_name_set = 1;
18977         }
18978       else
18979         {
18980           clib_warning ("parse error '%U'", format_unformat_error, input);
18981           return -99;
18982         }
18983     }
18984
18985   if (is_add && !locator_set_name_set)
18986     {
18987       errmsg ("itr-rloc is not set!");
18988       return -99;
18989     }
18990
18991   if (is_add && vec_len (locator_set_name) > 64)
18992     {
18993       errmsg ("itr-rloc locator-set name too long");
18994       vec_free (locator_set_name);
18995       return -99;
18996     }
18997
18998   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18999   mp->is_add = is_add;
19000   if (is_add)
19001     {
19002       clib_memcpy (mp->locator_set_name, locator_set_name,
19003                    vec_len (locator_set_name));
19004     }
19005   else
19006     {
19007       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19008     }
19009   vec_free (locator_set_name);
19010
19011   /* send it... */
19012   S (mp);
19013
19014   /* Wait for a reply... */
19015   W (ret);
19016   return ret;
19017 }
19018
19019 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19020
19021 static int
19022 api_one_locator_dump (vat_main_t * vam)
19023 {
19024   unformat_input_t *input = vam->input;
19025   vl_api_one_locator_dump_t *mp;
19026   vl_api_control_ping_t *mp_ping;
19027   u8 is_index_set = 0, is_name_set = 0;
19028   u8 *ls_name = 0;
19029   u32 ls_index = ~0;
19030   int ret;
19031
19032   /* Parse args required to build the message */
19033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19034     {
19035       if (unformat (input, "ls_name %_%v%_", &ls_name))
19036         {
19037           is_name_set = 1;
19038         }
19039       else if (unformat (input, "ls_index %d", &ls_index))
19040         {
19041           is_index_set = 1;
19042         }
19043       else
19044         {
19045           errmsg ("parse error '%U'", format_unformat_error, input);
19046           return -99;
19047         }
19048     }
19049
19050   if (!is_index_set && !is_name_set)
19051     {
19052       errmsg ("error: expected one of index or name!");
19053       return -99;
19054     }
19055
19056   if (is_index_set && is_name_set)
19057     {
19058       errmsg ("error: only one param expected!");
19059       return -99;
19060     }
19061
19062   if (vec_len (ls_name) > 62)
19063     {
19064       errmsg ("error: locator set name too long!");
19065       return -99;
19066     }
19067
19068   if (!vam->json_output)
19069     {
19070       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19071     }
19072
19073   M (ONE_LOCATOR_DUMP, mp);
19074   mp->is_index_set = is_index_set;
19075
19076   if (is_index_set)
19077     mp->ls_index = clib_host_to_net_u32 (ls_index);
19078   else
19079     {
19080       vec_add1 (ls_name, 0);
19081       strncpy ((char *) mp->ls_name, (char *) ls_name,
19082                sizeof (mp->ls_name) - 1);
19083     }
19084
19085   /* send it... */
19086   S (mp);
19087
19088   /* Use a control ping for synchronization */
19089   MPING (CONTROL_PING, mp_ping);
19090   S (mp_ping);
19091
19092   /* Wait for a reply... */
19093   W (ret);
19094   return ret;
19095 }
19096
19097 #define api_lisp_locator_dump api_one_locator_dump
19098
19099 static int
19100 api_one_locator_set_dump (vat_main_t * vam)
19101 {
19102   vl_api_one_locator_set_dump_t *mp;
19103   vl_api_control_ping_t *mp_ping;
19104   unformat_input_t *input = vam->input;
19105   u8 filter = 0;
19106   int ret;
19107
19108   /* Parse args required to build the message */
19109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19110     {
19111       if (unformat (input, "local"))
19112         {
19113           filter = 1;
19114         }
19115       else if (unformat (input, "remote"))
19116         {
19117           filter = 2;
19118         }
19119       else
19120         {
19121           errmsg ("parse error '%U'", format_unformat_error, input);
19122           return -99;
19123         }
19124     }
19125
19126   if (!vam->json_output)
19127     {
19128       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19129     }
19130
19131   M (ONE_LOCATOR_SET_DUMP, mp);
19132
19133   mp->filter = filter;
19134
19135   /* send it... */
19136   S (mp);
19137
19138   /* Use a control ping for synchronization */
19139   MPING (CONTROL_PING, mp_ping);
19140   S (mp_ping);
19141
19142   /* Wait for a reply... */
19143   W (ret);
19144   return ret;
19145 }
19146
19147 #define api_lisp_locator_set_dump api_one_locator_set_dump
19148
19149 static int
19150 api_one_eid_table_map_dump (vat_main_t * vam)
19151 {
19152   u8 is_l2 = 0;
19153   u8 mode_set = 0;
19154   unformat_input_t *input = vam->input;
19155   vl_api_one_eid_table_map_dump_t *mp;
19156   vl_api_control_ping_t *mp_ping;
19157   int ret;
19158
19159   /* Parse args required to build the message */
19160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19161     {
19162       if (unformat (input, "l2"))
19163         {
19164           is_l2 = 1;
19165           mode_set = 1;
19166         }
19167       else if (unformat (input, "l3"))
19168         {
19169           is_l2 = 0;
19170           mode_set = 1;
19171         }
19172       else
19173         {
19174           errmsg ("parse error '%U'", format_unformat_error, input);
19175           return -99;
19176         }
19177     }
19178
19179   if (!mode_set)
19180     {
19181       errmsg ("expected one of 'l2' or 'l3' parameter!");
19182       return -99;
19183     }
19184
19185   if (!vam->json_output)
19186     {
19187       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19188     }
19189
19190   M (ONE_EID_TABLE_MAP_DUMP, mp);
19191   mp->is_l2 = is_l2;
19192
19193   /* send it... */
19194   S (mp);
19195
19196   /* Use a control ping for synchronization */
19197   MPING (CONTROL_PING, mp_ping);
19198   S (mp_ping);
19199
19200   /* Wait for a reply... */
19201   W (ret);
19202   return ret;
19203 }
19204
19205 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19206
19207 static int
19208 api_one_eid_table_vni_dump (vat_main_t * vam)
19209 {
19210   vl_api_one_eid_table_vni_dump_t *mp;
19211   vl_api_control_ping_t *mp_ping;
19212   int ret;
19213
19214   if (!vam->json_output)
19215     {
19216       print (vam->ofp, "VNI");
19217     }
19218
19219   M (ONE_EID_TABLE_VNI_DUMP, mp);
19220
19221   /* send it... */
19222   S (mp);
19223
19224   /* Use a control ping for synchronization */
19225   MPING (CONTROL_PING, mp_ping);
19226   S (mp_ping);
19227
19228   /* Wait for a reply... */
19229   W (ret);
19230   return ret;
19231 }
19232
19233 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19234
19235 static int
19236 api_one_eid_table_dump (vat_main_t * vam)
19237 {
19238   unformat_input_t *i = vam->input;
19239   vl_api_one_eid_table_dump_t *mp;
19240   vl_api_control_ping_t *mp_ping;
19241   struct in_addr ip4;
19242   struct in6_addr ip6;
19243   u8 mac[6];
19244   u8 eid_type = ~0, eid_set = 0;
19245   u32 prefix_length = ~0, t, vni = 0;
19246   u8 filter = 0;
19247   int ret;
19248   lisp_nsh_api_t nsh;
19249
19250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19253         {
19254           eid_set = 1;
19255           eid_type = 0;
19256           prefix_length = t;
19257         }
19258       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19259         {
19260           eid_set = 1;
19261           eid_type = 1;
19262           prefix_length = t;
19263         }
19264       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19265         {
19266           eid_set = 1;
19267           eid_type = 2;
19268         }
19269       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19270         {
19271           eid_set = 1;
19272           eid_type = 3;
19273         }
19274       else if (unformat (i, "vni %d", &t))
19275         {
19276           vni = t;
19277         }
19278       else if (unformat (i, "local"))
19279         {
19280           filter = 1;
19281         }
19282       else if (unformat (i, "remote"))
19283         {
19284           filter = 2;
19285         }
19286       else
19287         {
19288           errmsg ("parse error '%U'", format_unformat_error, i);
19289           return -99;
19290         }
19291     }
19292
19293   if (!vam->json_output)
19294     {
19295       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19296              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19297     }
19298
19299   M (ONE_EID_TABLE_DUMP, mp);
19300
19301   mp->filter = filter;
19302   if (eid_set)
19303     {
19304       mp->eid_set = 1;
19305       mp->vni = htonl (vni);
19306       mp->eid_type = eid_type;
19307       switch (eid_type)
19308         {
19309         case 0:
19310           mp->prefix_length = prefix_length;
19311           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19312           break;
19313         case 1:
19314           mp->prefix_length = prefix_length;
19315           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19316           break;
19317         case 2:
19318           clib_memcpy (mp->eid, mac, sizeof (mac));
19319           break;
19320         case 3:
19321           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19322           break;
19323         default:
19324           errmsg ("unknown EID type %d!", eid_type);
19325           return -99;
19326         }
19327     }
19328
19329   /* send it... */
19330   S (mp);
19331
19332   /* Use a control ping for synchronization */
19333   MPING (CONTROL_PING, mp_ping);
19334   S (mp_ping);
19335
19336   /* Wait for a reply... */
19337   W (ret);
19338   return ret;
19339 }
19340
19341 #define api_lisp_eid_table_dump api_one_eid_table_dump
19342
19343 static int
19344 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19345 {
19346   unformat_input_t *i = vam->input;
19347   vl_api_gpe_fwd_entries_get_t *mp;
19348   u8 vni_set = 0;
19349   u32 vni = ~0;
19350   int ret;
19351
19352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19353     {
19354       if (unformat (i, "vni %d", &vni))
19355         {
19356           vni_set = 1;
19357         }
19358       else
19359         {
19360           errmsg ("parse error '%U'", format_unformat_error, i);
19361           return -99;
19362         }
19363     }
19364
19365   if (!vni_set)
19366     {
19367       errmsg ("vni not set!");
19368       return -99;
19369     }
19370
19371   if (!vam->json_output)
19372     {
19373       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19374              "leid", "reid");
19375     }
19376
19377   M (GPE_FWD_ENTRIES_GET, mp);
19378   mp->vni = clib_host_to_net_u32 (vni);
19379
19380   /* send it... */
19381   S (mp);
19382
19383   /* Wait for a reply... */
19384   W (ret);
19385   return ret;
19386 }
19387
19388 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19389 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19390 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19391 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19392 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19393 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19394 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19395 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19396
19397 static int
19398 api_one_adjacencies_get (vat_main_t * vam)
19399 {
19400   unformat_input_t *i = vam->input;
19401   vl_api_one_adjacencies_get_t *mp;
19402   u8 vni_set = 0;
19403   u32 vni = ~0;
19404   int ret;
19405
19406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19407     {
19408       if (unformat (i, "vni %d", &vni))
19409         {
19410           vni_set = 1;
19411         }
19412       else
19413         {
19414           errmsg ("parse error '%U'", format_unformat_error, i);
19415           return -99;
19416         }
19417     }
19418
19419   if (!vni_set)
19420     {
19421       errmsg ("vni not set!");
19422       return -99;
19423     }
19424
19425   if (!vam->json_output)
19426     {
19427       print (vam->ofp, "%s %40s", "leid", "reid");
19428     }
19429
19430   M (ONE_ADJACENCIES_GET, mp);
19431   mp->vni = clib_host_to_net_u32 (vni);
19432
19433   /* send it... */
19434   S (mp);
19435
19436   /* Wait for a reply... */
19437   W (ret);
19438   return ret;
19439 }
19440
19441 #define api_lisp_adjacencies_get api_one_adjacencies_get
19442
19443 static int
19444 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19445 {
19446   unformat_input_t *i = vam->input;
19447   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19448   int ret;
19449   u8 ip_family_set = 0, is_ip4 = 1;
19450
19451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19452     {
19453       if (unformat (i, "ip4"))
19454         {
19455           ip_family_set = 1;
19456           is_ip4 = 1;
19457         }
19458       else if (unformat (i, "ip6"))
19459         {
19460           ip_family_set = 1;
19461           is_ip4 = 0;
19462         }
19463       else
19464         {
19465           errmsg ("parse error '%U'", format_unformat_error, i);
19466           return -99;
19467         }
19468     }
19469
19470   if (!ip_family_set)
19471     {
19472       errmsg ("ip family not set!");
19473       return -99;
19474     }
19475
19476   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19477   mp->is_ip4 = is_ip4;
19478
19479   /* send it... */
19480   S (mp);
19481
19482   /* Wait for a reply... */
19483   W (ret);
19484   return ret;
19485 }
19486
19487 static int
19488 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19489 {
19490   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19491   int ret;
19492
19493   if (!vam->json_output)
19494     {
19495       print (vam->ofp, "VNIs");
19496     }
19497
19498   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19499
19500   /* send it... */
19501   S (mp);
19502
19503   /* Wait for a reply... */
19504   W (ret);
19505   return ret;
19506 }
19507
19508 static int
19509 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19510 {
19511   unformat_input_t *i = vam->input;
19512   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19513   int ret = 0;
19514   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19515   struct in_addr ip4;
19516   struct in6_addr ip6;
19517   u32 table_id = 0, nh_sw_if_index = ~0;
19518
19519   memset (&ip4, 0, sizeof (ip4));
19520   memset (&ip6, 0, sizeof (ip6));
19521
19522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19523     {
19524       if (unformat (i, "del"))
19525         is_add = 0;
19526       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19527                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19528         {
19529           ip_set = 1;
19530           is_ip4 = 1;
19531         }
19532       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19533                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19534         {
19535           ip_set = 1;
19536           is_ip4 = 0;
19537         }
19538       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19539         {
19540           ip_set = 1;
19541           is_ip4 = 1;
19542           nh_sw_if_index = ~0;
19543         }
19544       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19545         {
19546           ip_set = 1;
19547           is_ip4 = 0;
19548           nh_sw_if_index = ~0;
19549         }
19550       else if (unformat (i, "table %d", &table_id))
19551         ;
19552       else
19553         {
19554           errmsg ("parse error '%U'", format_unformat_error, i);
19555           return -99;
19556         }
19557     }
19558
19559   if (!ip_set)
19560     {
19561       errmsg ("nh addr not set!");
19562       return -99;
19563     }
19564
19565   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19566   mp->is_add = is_add;
19567   mp->table_id = clib_host_to_net_u32 (table_id);
19568   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19569   mp->is_ip4 = is_ip4;
19570   if (is_ip4)
19571     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19572   else
19573     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19574
19575   /* send it... */
19576   S (mp);
19577
19578   /* Wait for a reply... */
19579   W (ret);
19580   return ret;
19581 }
19582
19583 static int
19584 api_one_map_server_dump (vat_main_t * vam)
19585 {
19586   vl_api_one_map_server_dump_t *mp;
19587   vl_api_control_ping_t *mp_ping;
19588   int ret;
19589
19590   if (!vam->json_output)
19591     {
19592       print (vam->ofp, "%=20s", "Map server");
19593     }
19594
19595   M (ONE_MAP_SERVER_DUMP, mp);
19596   /* send it... */
19597   S (mp);
19598
19599   /* Use a control ping for synchronization */
19600   MPING (CONTROL_PING, mp_ping);
19601   S (mp_ping);
19602
19603   /* Wait for a reply... */
19604   W (ret);
19605   return ret;
19606 }
19607
19608 #define api_lisp_map_server_dump api_one_map_server_dump
19609
19610 static int
19611 api_one_map_resolver_dump (vat_main_t * vam)
19612 {
19613   vl_api_one_map_resolver_dump_t *mp;
19614   vl_api_control_ping_t *mp_ping;
19615   int ret;
19616
19617   if (!vam->json_output)
19618     {
19619       print (vam->ofp, "%=20s", "Map resolver");
19620     }
19621
19622   M (ONE_MAP_RESOLVER_DUMP, mp);
19623   /* send it... */
19624   S (mp);
19625
19626   /* Use a control ping for synchronization */
19627   MPING (CONTROL_PING, mp_ping);
19628   S (mp_ping);
19629
19630   /* Wait for a reply... */
19631   W (ret);
19632   return ret;
19633 }
19634
19635 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19636
19637 static int
19638 api_one_stats_flush (vat_main_t * vam)
19639 {
19640   vl_api_one_stats_flush_t *mp;
19641   int ret = 0;
19642
19643   M (ONE_STATS_FLUSH, mp);
19644   S (mp);
19645   W (ret);
19646   return ret;
19647 }
19648
19649 static int
19650 api_one_stats_dump (vat_main_t * vam)
19651 {
19652   vl_api_one_stats_dump_t *mp;
19653   vl_api_control_ping_t *mp_ping;
19654   int ret;
19655
19656   M (ONE_STATS_DUMP, mp);
19657   /* send it... */
19658   S (mp);
19659
19660   /* Use a control ping for synchronization */
19661   MPING (CONTROL_PING, mp_ping);
19662   S (mp_ping);
19663
19664   /* Wait for a reply... */
19665   W (ret);
19666   return ret;
19667 }
19668
19669 static int
19670 api_show_one_status (vat_main_t * vam)
19671 {
19672   vl_api_show_one_status_t *mp;
19673   int ret;
19674
19675   if (!vam->json_output)
19676     {
19677       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19678     }
19679
19680   M (SHOW_ONE_STATUS, mp);
19681   /* send it... */
19682   S (mp);
19683   /* Wait for a reply... */
19684   W (ret);
19685   return ret;
19686 }
19687
19688 #define api_show_lisp_status api_show_one_status
19689
19690 static int
19691 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19692 {
19693   vl_api_gpe_fwd_entry_path_dump_t *mp;
19694   vl_api_control_ping_t *mp_ping;
19695   unformat_input_t *i = vam->input;
19696   u32 fwd_entry_index = ~0;
19697   int ret;
19698
19699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19700     {
19701       if (unformat (i, "index %d", &fwd_entry_index))
19702         ;
19703       else
19704         break;
19705     }
19706
19707   if (~0 == fwd_entry_index)
19708     {
19709       errmsg ("no index specified!");
19710       return -99;
19711     }
19712
19713   if (!vam->json_output)
19714     {
19715       print (vam->ofp, "first line");
19716     }
19717
19718   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19719
19720   /* send it... */
19721   S (mp);
19722   /* Use a control ping for synchronization */
19723   MPING (CONTROL_PING, mp_ping);
19724   S (mp_ping);
19725
19726   /* Wait for a reply... */
19727   W (ret);
19728   return ret;
19729 }
19730
19731 static int
19732 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19733 {
19734   vl_api_one_get_map_request_itr_rlocs_t *mp;
19735   int ret;
19736
19737   if (!vam->json_output)
19738     {
19739       print (vam->ofp, "%=20s", "itr-rlocs:");
19740     }
19741
19742   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19743   /* send it... */
19744   S (mp);
19745   /* Wait for a reply... */
19746   W (ret);
19747   return ret;
19748 }
19749
19750 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19751
19752 static int
19753 api_af_packet_create (vat_main_t * vam)
19754 {
19755   unformat_input_t *i = vam->input;
19756   vl_api_af_packet_create_t *mp;
19757   u8 *host_if_name = 0;
19758   u8 hw_addr[6];
19759   u8 random_hw_addr = 1;
19760   int ret;
19761
19762   memset (hw_addr, 0, sizeof (hw_addr));
19763
19764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19765     {
19766       if (unformat (i, "name %s", &host_if_name))
19767         vec_add1 (host_if_name, 0);
19768       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19769         random_hw_addr = 0;
19770       else
19771         break;
19772     }
19773
19774   if (!vec_len (host_if_name))
19775     {
19776       errmsg ("host-interface name must be specified");
19777       return -99;
19778     }
19779
19780   if (vec_len (host_if_name) > 64)
19781     {
19782       errmsg ("host-interface name too long");
19783       return -99;
19784     }
19785
19786   M (AF_PACKET_CREATE, mp);
19787
19788   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19789   clib_memcpy (mp->hw_addr, hw_addr, 6);
19790   mp->use_random_hw_addr = random_hw_addr;
19791   vec_free (host_if_name);
19792
19793   S (mp);
19794
19795   /* *INDENT-OFF* */
19796   W2 (ret,
19797       ({
19798         if (ret == 0)
19799           fprintf (vam->ofp ? vam->ofp : stderr,
19800                    " new sw_if_index = %d\n", vam->sw_if_index);
19801       }));
19802   /* *INDENT-ON* */
19803   return ret;
19804 }
19805
19806 static int
19807 api_af_packet_delete (vat_main_t * vam)
19808 {
19809   unformat_input_t *i = vam->input;
19810   vl_api_af_packet_delete_t *mp;
19811   u8 *host_if_name = 0;
19812   int ret;
19813
19814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19815     {
19816       if (unformat (i, "name %s", &host_if_name))
19817         vec_add1 (host_if_name, 0);
19818       else
19819         break;
19820     }
19821
19822   if (!vec_len (host_if_name))
19823     {
19824       errmsg ("host-interface name must be specified");
19825       return -99;
19826     }
19827
19828   if (vec_len (host_if_name) > 64)
19829     {
19830       errmsg ("host-interface name too long");
19831       return -99;
19832     }
19833
19834   M (AF_PACKET_DELETE, mp);
19835
19836   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19837   vec_free (host_if_name);
19838
19839   S (mp);
19840   W (ret);
19841   return ret;
19842 }
19843
19844 static int
19845 api_policer_add_del (vat_main_t * vam)
19846 {
19847   unformat_input_t *i = vam->input;
19848   vl_api_policer_add_del_t *mp;
19849   u8 is_add = 1;
19850   u8 *name = 0;
19851   u32 cir = 0;
19852   u32 eir = 0;
19853   u64 cb = 0;
19854   u64 eb = 0;
19855   u8 rate_type = 0;
19856   u8 round_type = 0;
19857   u8 type = 0;
19858   u8 color_aware = 0;
19859   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19860   int ret;
19861
19862   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19863   conform_action.dscp = 0;
19864   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19865   exceed_action.dscp = 0;
19866   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19867   violate_action.dscp = 0;
19868
19869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19870     {
19871       if (unformat (i, "del"))
19872         is_add = 0;
19873       else if (unformat (i, "name %s", &name))
19874         vec_add1 (name, 0);
19875       else if (unformat (i, "cir %u", &cir))
19876         ;
19877       else if (unformat (i, "eir %u", &eir))
19878         ;
19879       else if (unformat (i, "cb %u", &cb))
19880         ;
19881       else if (unformat (i, "eb %u", &eb))
19882         ;
19883       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19884                          &rate_type))
19885         ;
19886       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19887                          &round_type))
19888         ;
19889       else if (unformat (i, "type %U", unformat_policer_type, &type))
19890         ;
19891       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19892                          &conform_action))
19893         ;
19894       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19895                          &exceed_action))
19896         ;
19897       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19898                          &violate_action))
19899         ;
19900       else if (unformat (i, "color-aware"))
19901         color_aware = 1;
19902       else
19903         break;
19904     }
19905
19906   if (!vec_len (name))
19907     {
19908       errmsg ("policer name must be specified");
19909       return -99;
19910     }
19911
19912   if (vec_len (name) > 64)
19913     {
19914       errmsg ("policer name too long");
19915       return -99;
19916     }
19917
19918   M (POLICER_ADD_DEL, mp);
19919
19920   clib_memcpy (mp->name, name, vec_len (name));
19921   vec_free (name);
19922   mp->is_add = is_add;
19923   mp->cir = ntohl (cir);
19924   mp->eir = ntohl (eir);
19925   mp->cb = clib_net_to_host_u64 (cb);
19926   mp->eb = clib_net_to_host_u64 (eb);
19927   mp->rate_type = rate_type;
19928   mp->round_type = round_type;
19929   mp->type = type;
19930   mp->conform_action_type = conform_action.action_type;
19931   mp->conform_dscp = conform_action.dscp;
19932   mp->exceed_action_type = exceed_action.action_type;
19933   mp->exceed_dscp = exceed_action.dscp;
19934   mp->violate_action_type = violate_action.action_type;
19935   mp->violate_dscp = violate_action.dscp;
19936   mp->color_aware = color_aware;
19937
19938   S (mp);
19939   W (ret);
19940   return ret;
19941 }
19942
19943 static int
19944 api_policer_dump (vat_main_t * vam)
19945 {
19946   unformat_input_t *i = vam->input;
19947   vl_api_policer_dump_t *mp;
19948   vl_api_control_ping_t *mp_ping;
19949   u8 *match_name = 0;
19950   u8 match_name_valid = 0;
19951   int ret;
19952
19953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19954     {
19955       if (unformat (i, "name %s", &match_name))
19956         {
19957           vec_add1 (match_name, 0);
19958           match_name_valid = 1;
19959         }
19960       else
19961         break;
19962     }
19963
19964   M (POLICER_DUMP, mp);
19965   mp->match_name_valid = match_name_valid;
19966   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19967   vec_free (match_name);
19968   /* send it... */
19969   S (mp);
19970
19971   /* Use a control ping for synchronization */
19972   MPING (CONTROL_PING, mp_ping);
19973   S (mp_ping);
19974
19975   /* Wait for a reply... */
19976   W (ret);
19977   return ret;
19978 }
19979
19980 static int
19981 api_policer_classify_set_interface (vat_main_t * vam)
19982 {
19983   unformat_input_t *i = vam->input;
19984   vl_api_policer_classify_set_interface_t *mp;
19985   u32 sw_if_index;
19986   int sw_if_index_set;
19987   u32 ip4_table_index = ~0;
19988   u32 ip6_table_index = ~0;
19989   u32 l2_table_index = ~0;
19990   u8 is_add = 1;
19991   int ret;
19992
19993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19994     {
19995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19996         sw_if_index_set = 1;
19997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19998         sw_if_index_set = 1;
19999       else if (unformat (i, "del"))
20000         is_add = 0;
20001       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20002         ;
20003       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20004         ;
20005       else if (unformat (i, "l2-table %d", &l2_table_index))
20006         ;
20007       else
20008         {
20009           clib_warning ("parse error '%U'", format_unformat_error, i);
20010           return -99;
20011         }
20012     }
20013
20014   if (sw_if_index_set == 0)
20015     {
20016       errmsg ("missing interface name or sw_if_index");
20017       return -99;
20018     }
20019
20020   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20021
20022   mp->sw_if_index = ntohl (sw_if_index);
20023   mp->ip4_table_index = ntohl (ip4_table_index);
20024   mp->ip6_table_index = ntohl (ip6_table_index);
20025   mp->l2_table_index = ntohl (l2_table_index);
20026   mp->is_add = is_add;
20027
20028   S (mp);
20029   W (ret);
20030   return ret;
20031 }
20032
20033 static int
20034 api_policer_classify_dump (vat_main_t * vam)
20035 {
20036   unformat_input_t *i = vam->input;
20037   vl_api_policer_classify_dump_t *mp;
20038   vl_api_control_ping_t *mp_ping;
20039   u8 type = POLICER_CLASSIFY_N_TABLES;
20040   int ret;
20041
20042   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20043     ;
20044   else
20045     {
20046       errmsg ("classify table type must be specified");
20047       return -99;
20048     }
20049
20050   if (!vam->json_output)
20051     {
20052       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20053     }
20054
20055   M (POLICER_CLASSIFY_DUMP, mp);
20056   mp->type = type;
20057   /* send it... */
20058   S (mp);
20059
20060   /* Use a control ping for synchronization */
20061   MPING (CONTROL_PING, mp_ping);
20062   S (mp_ping);
20063
20064   /* Wait for a reply... */
20065   W (ret);
20066   return ret;
20067 }
20068
20069 static int
20070 api_netmap_create (vat_main_t * vam)
20071 {
20072   unformat_input_t *i = vam->input;
20073   vl_api_netmap_create_t *mp;
20074   u8 *if_name = 0;
20075   u8 hw_addr[6];
20076   u8 random_hw_addr = 1;
20077   u8 is_pipe = 0;
20078   u8 is_master = 0;
20079   int ret;
20080
20081   memset (hw_addr, 0, sizeof (hw_addr));
20082
20083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20084     {
20085       if (unformat (i, "name %s", &if_name))
20086         vec_add1 (if_name, 0);
20087       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20088         random_hw_addr = 0;
20089       else if (unformat (i, "pipe"))
20090         is_pipe = 1;
20091       else if (unformat (i, "master"))
20092         is_master = 1;
20093       else if (unformat (i, "slave"))
20094         is_master = 0;
20095       else
20096         break;
20097     }
20098
20099   if (!vec_len (if_name))
20100     {
20101       errmsg ("interface name must be specified");
20102       return -99;
20103     }
20104
20105   if (vec_len (if_name) > 64)
20106     {
20107       errmsg ("interface name too long");
20108       return -99;
20109     }
20110
20111   M (NETMAP_CREATE, mp);
20112
20113   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20114   clib_memcpy (mp->hw_addr, hw_addr, 6);
20115   mp->use_random_hw_addr = random_hw_addr;
20116   mp->is_pipe = is_pipe;
20117   mp->is_master = is_master;
20118   vec_free (if_name);
20119
20120   S (mp);
20121   W (ret);
20122   return ret;
20123 }
20124
20125 static int
20126 api_netmap_delete (vat_main_t * vam)
20127 {
20128   unformat_input_t *i = vam->input;
20129   vl_api_netmap_delete_t *mp;
20130   u8 *if_name = 0;
20131   int ret;
20132
20133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20134     {
20135       if (unformat (i, "name %s", &if_name))
20136         vec_add1 (if_name, 0);
20137       else
20138         break;
20139     }
20140
20141   if (!vec_len (if_name))
20142     {
20143       errmsg ("interface name must be specified");
20144       return -99;
20145     }
20146
20147   if (vec_len (if_name) > 64)
20148     {
20149       errmsg ("interface name too long");
20150       return -99;
20151     }
20152
20153   M (NETMAP_DELETE, mp);
20154
20155   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20156   vec_free (if_name);
20157
20158   S (mp);
20159   W (ret);
20160   return ret;
20161 }
20162
20163 static void
20164 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20165 {
20166   if (fp->afi == IP46_TYPE_IP6)
20167     print (vam->ofp,
20168            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20169            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20170            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20171            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20172            format_ip6_address, fp->next_hop);
20173   else if (fp->afi == IP46_TYPE_IP4)
20174     print (vam->ofp,
20175            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20176            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20177            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20178            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20179            format_ip4_address, fp->next_hop);
20180 }
20181
20182 static void
20183 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20184                                  vl_api_fib_path_t * fp)
20185 {
20186   struct in_addr ip4;
20187   struct in6_addr ip6;
20188
20189   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20190   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20191   vat_json_object_add_uint (node, "is_local", fp->is_local);
20192   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20193   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20194   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20195   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20196   if (fp->afi == IP46_TYPE_IP4)
20197     {
20198       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20199       vat_json_object_add_ip4 (node, "next_hop", ip4);
20200     }
20201   else if (fp->afi == IP46_TYPE_IP6)
20202     {
20203       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20204       vat_json_object_add_ip6 (node, "next_hop", ip6);
20205     }
20206 }
20207
20208 static void
20209 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20210 {
20211   vat_main_t *vam = &vat_main;
20212   int count = ntohl (mp->mt_count);
20213   vl_api_fib_path_t *fp;
20214   i32 i;
20215
20216   print (vam->ofp, "[%d]: sw_if_index %d via:",
20217          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20218   fp = mp->mt_paths;
20219   for (i = 0; i < count; i++)
20220     {
20221       vl_api_mpls_fib_path_print (vam, fp);
20222       fp++;
20223     }
20224
20225   print (vam->ofp, "");
20226 }
20227
20228 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20229 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20230
20231 static void
20232 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20233 {
20234   vat_main_t *vam = &vat_main;
20235   vat_json_node_t *node = NULL;
20236   int count = ntohl (mp->mt_count);
20237   vl_api_fib_path_t *fp;
20238   i32 i;
20239
20240   if (VAT_JSON_ARRAY != vam->json_tree.type)
20241     {
20242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20243       vat_json_init_array (&vam->json_tree);
20244     }
20245   node = vat_json_array_add (&vam->json_tree);
20246
20247   vat_json_init_object (node);
20248   vat_json_object_add_uint (node, "tunnel_index",
20249                             ntohl (mp->mt_tunnel_index));
20250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20251
20252   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20253
20254   fp = mp->mt_paths;
20255   for (i = 0; i < count; i++)
20256     {
20257       vl_api_mpls_fib_path_json_print (node, fp);
20258       fp++;
20259     }
20260 }
20261
20262 static int
20263 api_mpls_tunnel_dump (vat_main_t * vam)
20264 {
20265   vl_api_mpls_tunnel_dump_t *mp;
20266   vl_api_control_ping_t *mp_ping;
20267   i32 index = -1;
20268   int ret;
20269
20270   /* Parse args required to build the message */
20271   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20272     {
20273       if (!unformat (vam->input, "tunnel_index %d", &index))
20274         {
20275           index = -1;
20276           break;
20277         }
20278     }
20279
20280   print (vam->ofp, "  tunnel_index %d", index);
20281
20282   M (MPLS_TUNNEL_DUMP, mp);
20283   mp->tunnel_index = htonl (index);
20284   S (mp);
20285
20286   /* Use a control ping for synchronization */
20287   MPING (CONTROL_PING, mp_ping);
20288   S (mp_ping);
20289
20290   W (ret);
20291   return ret;
20292 }
20293
20294 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20295 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20296
20297
20298 static void
20299 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20300 {
20301   vat_main_t *vam = &vat_main;
20302   int count = ntohl (mp->count);
20303   vl_api_fib_path_t *fp;
20304   int i;
20305
20306   print (vam->ofp,
20307          "table-id %d, label %u, ess_bit %u",
20308          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20309   fp = mp->path;
20310   for (i = 0; i < count; i++)
20311     {
20312       vl_api_mpls_fib_path_print (vam, fp);
20313       fp++;
20314     }
20315 }
20316
20317 static void vl_api_mpls_fib_details_t_handler_json
20318   (vl_api_mpls_fib_details_t * mp)
20319 {
20320   vat_main_t *vam = &vat_main;
20321   int count = ntohl (mp->count);
20322   vat_json_node_t *node = NULL;
20323   vl_api_fib_path_t *fp;
20324   int i;
20325
20326   if (VAT_JSON_ARRAY != vam->json_tree.type)
20327     {
20328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20329       vat_json_init_array (&vam->json_tree);
20330     }
20331   node = vat_json_array_add (&vam->json_tree);
20332
20333   vat_json_init_object (node);
20334   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20335   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20336   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20337   vat_json_object_add_uint (node, "path_count", count);
20338   fp = mp->path;
20339   for (i = 0; i < count; i++)
20340     {
20341       vl_api_mpls_fib_path_json_print (node, fp);
20342       fp++;
20343     }
20344 }
20345
20346 static int
20347 api_mpls_fib_dump (vat_main_t * vam)
20348 {
20349   vl_api_mpls_fib_dump_t *mp;
20350   vl_api_control_ping_t *mp_ping;
20351   int ret;
20352
20353   M (MPLS_FIB_DUMP, mp);
20354   S (mp);
20355
20356   /* Use a control ping for synchronization */
20357   MPING (CONTROL_PING, mp_ping);
20358   S (mp_ping);
20359
20360   W (ret);
20361   return ret;
20362 }
20363
20364 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20365 #define vl_api_ip_fib_details_t_print vl_noop_handler
20366
20367 static void
20368 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20369 {
20370   vat_main_t *vam = &vat_main;
20371   int count = ntohl (mp->count);
20372   vl_api_fib_path_t *fp;
20373   int i;
20374
20375   print (vam->ofp,
20376          "table-id %d, prefix %U/%d",
20377          ntohl (mp->table_id), format_ip4_address, mp->address,
20378          mp->address_length);
20379   fp = mp->path;
20380   for (i = 0; i < count; i++)
20381     {
20382       if (fp->afi == IP46_TYPE_IP6)
20383         print (vam->ofp,
20384                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20385                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20386                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20387                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20388                format_ip6_address, fp->next_hop);
20389       else if (fp->afi == IP46_TYPE_IP4)
20390         print (vam->ofp,
20391                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20392                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20393                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20394                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20395                format_ip4_address, fp->next_hop);
20396       fp++;
20397     }
20398 }
20399
20400 static void vl_api_ip_fib_details_t_handler_json
20401   (vl_api_ip_fib_details_t * mp)
20402 {
20403   vat_main_t *vam = &vat_main;
20404   int count = ntohl (mp->count);
20405   vat_json_node_t *node = NULL;
20406   struct in_addr ip4;
20407   struct in6_addr ip6;
20408   vl_api_fib_path_t *fp;
20409   int i;
20410
20411   if (VAT_JSON_ARRAY != vam->json_tree.type)
20412     {
20413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20414       vat_json_init_array (&vam->json_tree);
20415     }
20416   node = vat_json_array_add (&vam->json_tree);
20417
20418   vat_json_init_object (node);
20419   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20420   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20421   vat_json_object_add_ip4 (node, "prefix", ip4);
20422   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20423   vat_json_object_add_uint (node, "path_count", count);
20424   fp = mp->path;
20425   for (i = 0; i < count; i++)
20426     {
20427       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20428       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20429       vat_json_object_add_uint (node, "is_local", fp->is_local);
20430       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20431       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20432       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20433       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20434       if (fp->afi == IP46_TYPE_IP4)
20435         {
20436           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20437           vat_json_object_add_ip4 (node, "next_hop", ip4);
20438         }
20439       else if (fp->afi == IP46_TYPE_IP6)
20440         {
20441           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20442           vat_json_object_add_ip6 (node, "next_hop", ip6);
20443         }
20444     }
20445 }
20446
20447 static int
20448 api_ip_fib_dump (vat_main_t * vam)
20449 {
20450   vl_api_ip_fib_dump_t *mp;
20451   vl_api_control_ping_t *mp_ping;
20452   int ret;
20453
20454   M (IP_FIB_DUMP, mp);
20455   S (mp);
20456
20457   /* Use a control ping for synchronization */
20458   MPING (CONTROL_PING, mp_ping);
20459   S (mp_ping);
20460
20461   W (ret);
20462   return ret;
20463 }
20464
20465 static int
20466 api_ip_mfib_dump (vat_main_t * vam)
20467 {
20468   vl_api_ip_mfib_dump_t *mp;
20469   vl_api_control_ping_t *mp_ping;
20470   int ret;
20471
20472   M (IP_MFIB_DUMP, mp);
20473   S (mp);
20474
20475   /* Use a control ping for synchronization */
20476   MPING (CONTROL_PING, mp_ping);
20477   S (mp_ping);
20478
20479   W (ret);
20480   return ret;
20481 }
20482
20483 static void vl_api_ip_neighbor_details_t_handler
20484   (vl_api_ip_neighbor_details_t * mp)
20485 {
20486   vat_main_t *vam = &vat_main;
20487
20488   print (vam->ofp, "%c %U %U",
20489          (mp->is_static) ? 'S' : 'D',
20490          format_ethernet_address, &mp->mac_address,
20491          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20492          &mp->ip_address);
20493 }
20494
20495 static void vl_api_ip_neighbor_details_t_handler_json
20496   (vl_api_ip_neighbor_details_t * mp)
20497 {
20498
20499   vat_main_t *vam = &vat_main;
20500   vat_json_node_t *node;
20501   struct in_addr ip4;
20502   struct in6_addr ip6;
20503
20504   if (VAT_JSON_ARRAY != vam->json_tree.type)
20505     {
20506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20507       vat_json_init_array (&vam->json_tree);
20508     }
20509   node = vat_json_array_add (&vam->json_tree);
20510
20511   vat_json_init_object (node);
20512   vat_json_object_add_string_copy (node, "flag",
20513                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20514                                    "dynamic");
20515
20516   vat_json_object_add_string_copy (node, "link_layer",
20517                                    format (0, "%U", format_ethernet_address,
20518                                            &mp->mac_address));
20519
20520   if (mp->is_ipv6)
20521     {
20522       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20523       vat_json_object_add_ip6 (node, "ip_address", ip6);
20524     }
20525   else
20526     {
20527       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20528       vat_json_object_add_ip4 (node, "ip_address", ip4);
20529     }
20530 }
20531
20532 static int
20533 api_ip_neighbor_dump (vat_main_t * vam)
20534 {
20535   unformat_input_t *i = vam->input;
20536   vl_api_ip_neighbor_dump_t *mp;
20537   vl_api_control_ping_t *mp_ping;
20538   u8 is_ipv6 = 0;
20539   u32 sw_if_index = ~0;
20540   int ret;
20541
20542   /* Parse args required to build the message */
20543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20546         ;
20547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20548         ;
20549       else if (unformat (i, "ip6"))
20550         is_ipv6 = 1;
20551       else
20552         break;
20553     }
20554
20555   if (sw_if_index == ~0)
20556     {
20557       errmsg ("missing interface name or sw_if_index");
20558       return -99;
20559     }
20560
20561   M (IP_NEIGHBOR_DUMP, mp);
20562   mp->is_ipv6 = (u8) is_ipv6;
20563   mp->sw_if_index = ntohl (sw_if_index);
20564   S (mp);
20565
20566   /* Use a control ping for synchronization */
20567   MPING (CONTROL_PING, mp_ping);
20568   S (mp_ping);
20569
20570   W (ret);
20571   return ret;
20572 }
20573
20574 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20575 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20576
20577 static void
20578 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20579 {
20580   vat_main_t *vam = &vat_main;
20581   int count = ntohl (mp->count);
20582   vl_api_fib_path_t *fp;
20583   int i;
20584
20585   print (vam->ofp,
20586          "table-id %d, prefix %U/%d",
20587          ntohl (mp->table_id), format_ip6_address, mp->address,
20588          mp->address_length);
20589   fp = mp->path;
20590   for (i = 0; i < count; i++)
20591     {
20592       if (fp->afi == IP46_TYPE_IP6)
20593         print (vam->ofp,
20594                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20595                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20596                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20597                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20598                format_ip6_address, fp->next_hop);
20599       else if (fp->afi == IP46_TYPE_IP4)
20600         print (vam->ofp,
20601                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20602                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20603                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20604                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20605                format_ip4_address, fp->next_hop);
20606       fp++;
20607     }
20608 }
20609
20610 static void vl_api_ip6_fib_details_t_handler_json
20611   (vl_api_ip6_fib_details_t * mp)
20612 {
20613   vat_main_t *vam = &vat_main;
20614   int count = ntohl (mp->count);
20615   vat_json_node_t *node = NULL;
20616   struct in_addr ip4;
20617   struct in6_addr ip6;
20618   vl_api_fib_path_t *fp;
20619   int i;
20620
20621   if (VAT_JSON_ARRAY != vam->json_tree.type)
20622     {
20623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20624       vat_json_init_array (&vam->json_tree);
20625     }
20626   node = vat_json_array_add (&vam->json_tree);
20627
20628   vat_json_init_object (node);
20629   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20630   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20631   vat_json_object_add_ip6 (node, "prefix", ip6);
20632   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20633   vat_json_object_add_uint (node, "path_count", count);
20634   fp = mp->path;
20635   for (i = 0; i < count; i++)
20636     {
20637       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20638       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20639       vat_json_object_add_uint (node, "is_local", fp->is_local);
20640       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20641       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20642       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20643       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20644       if (fp->afi == IP46_TYPE_IP4)
20645         {
20646           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20647           vat_json_object_add_ip4 (node, "next_hop", ip4);
20648         }
20649       else if (fp->afi == IP46_TYPE_IP6)
20650         {
20651           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20652           vat_json_object_add_ip6 (node, "next_hop", ip6);
20653         }
20654     }
20655 }
20656
20657 static int
20658 api_ip6_fib_dump (vat_main_t * vam)
20659 {
20660   vl_api_ip6_fib_dump_t *mp;
20661   vl_api_control_ping_t *mp_ping;
20662   int ret;
20663
20664   M (IP6_FIB_DUMP, mp);
20665   S (mp);
20666
20667   /* Use a control ping for synchronization */
20668   MPING (CONTROL_PING, mp_ping);
20669   S (mp_ping);
20670
20671   W (ret);
20672   return ret;
20673 }
20674
20675 static int
20676 api_ip6_mfib_dump (vat_main_t * vam)
20677 {
20678   vl_api_ip6_mfib_dump_t *mp;
20679   vl_api_control_ping_t *mp_ping;
20680   int ret;
20681
20682   M (IP6_MFIB_DUMP, mp);
20683   S (mp);
20684
20685   /* Use a control ping for synchronization */
20686   MPING (CONTROL_PING, mp_ping);
20687   S (mp_ping);
20688
20689   W (ret);
20690   return ret;
20691 }
20692
20693 int
20694 api_classify_table_ids (vat_main_t * vam)
20695 {
20696   vl_api_classify_table_ids_t *mp;
20697   int ret;
20698
20699   /* Construct the API message */
20700   M (CLASSIFY_TABLE_IDS, mp);
20701   mp->context = 0;
20702
20703   S (mp);
20704   W (ret);
20705   return ret;
20706 }
20707
20708 int
20709 api_classify_table_by_interface (vat_main_t * vam)
20710 {
20711   unformat_input_t *input = vam->input;
20712   vl_api_classify_table_by_interface_t *mp;
20713
20714   u32 sw_if_index = ~0;
20715   int ret;
20716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20717     {
20718       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20719         ;
20720       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20721         ;
20722       else
20723         break;
20724     }
20725   if (sw_if_index == ~0)
20726     {
20727       errmsg ("missing interface name or sw_if_index");
20728       return -99;
20729     }
20730
20731   /* Construct the API message */
20732   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20733   mp->context = 0;
20734   mp->sw_if_index = ntohl (sw_if_index);
20735
20736   S (mp);
20737   W (ret);
20738   return ret;
20739 }
20740
20741 int
20742 api_classify_table_info (vat_main_t * vam)
20743 {
20744   unformat_input_t *input = vam->input;
20745   vl_api_classify_table_info_t *mp;
20746
20747   u32 table_id = ~0;
20748   int ret;
20749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20750     {
20751       if (unformat (input, "table_id %d", &table_id))
20752         ;
20753       else
20754         break;
20755     }
20756   if (table_id == ~0)
20757     {
20758       errmsg ("missing table id");
20759       return -99;
20760     }
20761
20762   /* Construct the API message */
20763   M (CLASSIFY_TABLE_INFO, mp);
20764   mp->context = 0;
20765   mp->table_id = ntohl (table_id);
20766
20767   S (mp);
20768   W (ret);
20769   return ret;
20770 }
20771
20772 int
20773 api_classify_session_dump (vat_main_t * vam)
20774 {
20775   unformat_input_t *input = vam->input;
20776   vl_api_classify_session_dump_t *mp;
20777   vl_api_control_ping_t *mp_ping;
20778
20779   u32 table_id = ~0;
20780   int ret;
20781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20782     {
20783       if (unformat (input, "table_id %d", &table_id))
20784         ;
20785       else
20786         break;
20787     }
20788   if (table_id == ~0)
20789     {
20790       errmsg ("missing table id");
20791       return -99;
20792     }
20793
20794   /* Construct the API message */
20795   M (CLASSIFY_SESSION_DUMP, mp);
20796   mp->context = 0;
20797   mp->table_id = ntohl (table_id);
20798   S (mp);
20799
20800   /* Use a control ping for synchronization */
20801   MPING (CONTROL_PING, mp_ping);
20802   S (mp_ping);
20803
20804   W (ret);
20805   return ret;
20806 }
20807
20808 static void
20809 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20810 {
20811   vat_main_t *vam = &vat_main;
20812
20813   print (vam->ofp, "collector_address %U, collector_port %d, "
20814          "src_address %U, vrf_id %d, path_mtu %u, "
20815          "template_interval %u, udp_checksum %d",
20816          format_ip4_address, mp->collector_address,
20817          ntohs (mp->collector_port),
20818          format_ip4_address, mp->src_address,
20819          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20820          ntohl (mp->template_interval), mp->udp_checksum);
20821
20822   vam->retval = 0;
20823   vam->result_ready = 1;
20824 }
20825
20826 static void
20827   vl_api_ipfix_exporter_details_t_handler_json
20828   (vl_api_ipfix_exporter_details_t * mp)
20829 {
20830   vat_main_t *vam = &vat_main;
20831   vat_json_node_t node;
20832   struct in_addr collector_address;
20833   struct in_addr src_address;
20834
20835   vat_json_init_object (&node);
20836   clib_memcpy (&collector_address, &mp->collector_address,
20837                sizeof (collector_address));
20838   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20839   vat_json_object_add_uint (&node, "collector_port",
20840                             ntohs (mp->collector_port));
20841   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20842   vat_json_object_add_ip4 (&node, "src_address", src_address);
20843   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20844   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20845   vat_json_object_add_uint (&node, "template_interval",
20846                             ntohl (mp->template_interval));
20847   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20848
20849   vat_json_print (vam->ofp, &node);
20850   vat_json_free (&node);
20851   vam->retval = 0;
20852   vam->result_ready = 1;
20853 }
20854
20855 int
20856 api_ipfix_exporter_dump (vat_main_t * vam)
20857 {
20858   vl_api_ipfix_exporter_dump_t *mp;
20859   int ret;
20860
20861   /* Construct the API message */
20862   M (IPFIX_EXPORTER_DUMP, mp);
20863   mp->context = 0;
20864
20865   S (mp);
20866   W (ret);
20867   return ret;
20868 }
20869
20870 static int
20871 api_ipfix_classify_stream_dump (vat_main_t * vam)
20872 {
20873   vl_api_ipfix_classify_stream_dump_t *mp;
20874   int ret;
20875
20876   /* Construct the API message */
20877   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20878   mp->context = 0;
20879
20880   S (mp);
20881   W (ret);
20882   return ret;
20883   /* NOTREACHED */
20884   return 0;
20885 }
20886
20887 static void
20888   vl_api_ipfix_classify_stream_details_t_handler
20889   (vl_api_ipfix_classify_stream_details_t * mp)
20890 {
20891   vat_main_t *vam = &vat_main;
20892   print (vam->ofp, "domain_id %d, src_port %d",
20893          ntohl (mp->domain_id), ntohs (mp->src_port));
20894   vam->retval = 0;
20895   vam->result_ready = 1;
20896 }
20897
20898 static void
20899   vl_api_ipfix_classify_stream_details_t_handler_json
20900   (vl_api_ipfix_classify_stream_details_t * mp)
20901 {
20902   vat_main_t *vam = &vat_main;
20903   vat_json_node_t node;
20904
20905   vat_json_init_object (&node);
20906   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20907   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20908
20909   vat_json_print (vam->ofp, &node);
20910   vat_json_free (&node);
20911   vam->retval = 0;
20912   vam->result_ready = 1;
20913 }
20914
20915 static int
20916 api_ipfix_classify_table_dump (vat_main_t * vam)
20917 {
20918   vl_api_ipfix_classify_table_dump_t *mp;
20919   vl_api_control_ping_t *mp_ping;
20920   int ret;
20921
20922   if (!vam->json_output)
20923     {
20924       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20925              "transport_protocol");
20926     }
20927
20928   /* Construct the API message */
20929   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20930
20931   /* send it... */
20932   S (mp);
20933
20934   /* Use a control ping for synchronization */
20935   MPING (CONTROL_PING, mp_ping);
20936   S (mp_ping);
20937
20938   W (ret);
20939   return ret;
20940 }
20941
20942 static void
20943   vl_api_ipfix_classify_table_details_t_handler
20944   (vl_api_ipfix_classify_table_details_t * mp)
20945 {
20946   vat_main_t *vam = &vat_main;
20947   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20948          mp->transport_protocol);
20949 }
20950
20951 static void
20952   vl_api_ipfix_classify_table_details_t_handler_json
20953   (vl_api_ipfix_classify_table_details_t * mp)
20954 {
20955   vat_json_node_t *node = NULL;
20956   vat_main_t *vam = &vat_main;
20957
20958   if (VAT_JSON_ARRAY != vam->json_tree.type)
20959     {
20960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20961       vat_json_init_array (&vam->json_tree);
20962     }
20963
20964   node = vat_json_array_add (&vam->json_tree);
20965   vat_json_init_object (node);
20966
20967   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20968   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20969   vat_json_object_add_uint (node, "transport_protocol",
20970                             mp->transport_protocol);
20971 }
20972
20973 static int
20974 api_sw_interface_span_enable_disable (vat_main_t * vam)
20975 {
20976   unformat_input_t *i = vam->input;
20977   vl_api_sw_interface_span_enable_disable_t *mp;
20978   u32 src_sw_if_index = ~0;
20979   u32 dst_sw_if_index = ~0;
20980   u8 state = 3;
20981   int ret;
20982   u8 is_l2 = 0;
20983
20984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20985     {
20986       if (unformat
20987           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20988         ;
20989       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20990         ;
20991       else
20992         if (unformat
20993             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20994         ;
20995       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20996         ;
20997       else if (unformat (i, "disable"))
20998         state = 0;
20999       else if (unformat (i, "rx"))
21000         state = 1;
21001       else if (unformat (i, "tx"))
21002         state = 2;
21003       else if (unformat (i, "both"))
21004         state = 3;
21005       else if (unformat (i, "l2"))
21006         is_l2 = 1;
21007       else
21008         break;
21009     }
21010
21011   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21012
21013   mp->sw_if_index_from = htonl (src_sw_if_index);
21014   mp->sw_if_index_to = htonl (dst_sw_if_index);
21015   mp->state = state;
21016   mp->is_l2 = is_l2;
21017
21018   S (mp);
21019   W (ret);
21020   return ret;
21021 }
21022
21023 static void
21024 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21025                                             * mp)
21026 {
21027   vat_main_t *vam = &vat_main;
21028   u8 *sw_if_from_name = 0;
21029   u8 *sw_if_to_name = 0;
21030   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21031   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21032   char *states[] = { "none", "rx", "tx", "both" };
21033   hash_pair_t *p;
21034
21035   /* *INDENT-OFF* */
21036   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21037   ({
21038     if ((u32) p->value[0] == sw_if_index_from)
21039       {
21040         sw_if_from_name = (u8 *)(p->key);
21041         if (sw_if_to_name)
21042           break;
21043       }
21044     if ((u32) p->value[0] == sw_if_index_to)
21045       {
21046         sw_if_to_name = (u8 *)(p->key);
21047         if (sw_if_from_name)
21048           break;
21049       }
21050   }));
21051   /* *INDENT-ON* */
21052   print (vam->ofp, "%20s => %20s (%s) %s",
21053          sw_if_from_name, sw_if_to_name, states[mp->state],
21054          mp->is_l2 ? "l2" : "device");
21055 }
21056
21057 static void
21058   vl_api_sw_interface_span_details_t_handler_json
21059   (vl_api_sw_interface_span_details_t * mp)
21060 {
21061   vat_main_t *vam = &vat_main;
21062   vat_json_node_t *node = NULL;
21063   u8 *sw_if_from_name = 0;
21064   u8 *sw_if_to_name = 0;
21065   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21066   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21067   hash_pair_t *p;
21068
21069   /* *INDENT-OFF* */
21070   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21071   ({
21072     if ((u32) p->value[0] == sw_if_index_from)
21073       {
21074         sw_if_from_name = (u8 *)(p->key);
21075         if (sw_if_to_name)
21076           break;
21077       }
21078     if ((u32) p->value[0] == sw_if_index_to)
21079       {
21080         sw_if_to_name = (u8 *)(p->key);
21081         if (sw_if_from_name)
21082           break;
21083       }
21084   }));
21085   /* *INDENT-ON* */
21086
21087   if (VAT_JSON_ARRAY != vam->json_tree.type)
21088     {
21089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21090       vat_json_init_array (&vam->json_tree);
21091     }
21092   node = vat_json_array_add (&vam->json_tree);
21093
21094   vat_json_init_object (node);
21095   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21096   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21097   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21098   if (0 != sw_if_to_name)
21099     {
21100       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21101     }
21102   vat_json_object_add_uint (node, "state", mp->state);
21103   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21104 }
21105
21106 static int
21107 api_sw_interface_span_dump (vat_main_t * vam)
21108 {
21109   unformat_input_t *input = vam->input;
21110   vl_api_sw_interface_span_dump_t *mp;
21111   vl_api_control_ping_t *mp_ping;
21112   u8 is_l2 = 0;
21113   int ret;
21114
21115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21116     {
21117       if (unformat (input, "l2"))
21118         is_l2 = 1;
21119       else
21120         break;
21121     }
21122
21123   M (SW_INTERFACE_SPAN_DUMP, mp);
21124   mp->is_l2 = is_l2;
21125   S (mp);
21126
21127   /* Use a control ping for synchronization */
21128   MPING (CONTROL_PING, mp_ping);
21129   S (mp_ping);
21130
21131   W (ret);
21132   return ret;
21133 }
21134
21135 int
21136 api_pg_create_interface (vat_main_t * vam)
21137 {
21138   unformat_input_t *input = vam->input;
21139   vl_api_pg_create_interface_t *mp;
21140
21141   u32 if_id = ~0;
21142   int ret;
21143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21144     {
21145       if (unformat (input, "if_id %d", &if_id))
21146         ;
21147       else
21148         break;
21149     }
21150   if (if_id == ~0)
21151     {
21152       errmsg ("missing pg interface index");
21153       return -99;
21154     }
21155
21156   /* Construct the API message */
21157   M (PG_CREATE_INTERFACE, mp);
21158   mp->context = 0;
21159   mp->interface_id = ntohl (if_id);
21160
21161   S (mp);
21162   W (ret);
21163   return ret;
21164 }
21165
21166 int
21167 api_pg_capture (vat_main_t * vam)
21168 {
21169   unformat_input_t *input = vam->input;
21170   vl_api_pg_capture_t *mp;
21171
21172   u32 if_id = ~0;
21173   u8 enable = 1;
21174   u32 count = 1;
21175   u8 pcap_file_set = 0;
21176   u8 *pcap_file = 0;
21177   int ret;
21178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21179     {
21180       if (unformat (input, "if_id %d", &if_id))
21181         ;
21182       else if (unformat (input, "pcap %s", &pcap_file))
21183         pcap_file_set = 1;
21184       else if (unformat (input, "count %d", &count))
21185         ;
21186       else if (unformat (input, "disable"))
21187         enable = 0;
21188       else
21189         break;
21190     }
21191   if (if_id == ~0)
21192     {
21193       errmsg ("missing pg interface index");
21194       return -99;
21195     }
21196   if (pcap_file_set > 0)
21197     {
21198       if (vec_len (pcap_file) > 255)
21199         {
21200           errmsg ("pcap file name is too long");
21201           return -99;
21202         }
21203     }
21204
21205   u32 name_len = vec_len (pcap_file);
21206   /* Construct the API message */
21207   M (PG_CAPTURE, mp);
21208   mp->context = 0;
21209   mp->interface_id = ntohl (if_id);
21210   mp->is_enabled = enable;
21211   mp->count = ntohl (count);
21212   mp->pcap_name_length = ntohl (name_len);
21213   if (pcap_file_set != 0)
21214     {
21215       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21216     }
21217   vec_free (pcap_file);
21218
21219   S (mp);
21220   W (ret);
21221   return ret;
21222 }
21223
21224 int
21225 api_pg_enable_disable (vat_main_t * vam)
21226 {
21227   unformat_input_t *input = vam->input;
21228   vl_api_pg_enable_disable_t *mp;
21229
21230   u8 enable = 1;
21231   u8 stream_name_set = 0;
21232   u8 *stream_name = 0;
21233   int ret;
21234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21235     {
21236       if (unformat (input, "stream %s", &stream_name))
21237         stream_name_set = 1;
21238       else if (unformat (input, "disable"))
21239         enable = 0;
21240       else
21241         break;
21242     }
21243
21244   if (stream_name_set > 0)
21245     {
21246       if (vec_len (stream_name) > 255)
21247         {
21248           errmsg ("stream name too long");
21249           return -99;
21250         }
21251     }
21252
21253   u32 name_len = vec_len (stream_name);
21254   /* Construct the API message */
21255   M (PG_ENABLE_DISABLE, mp);
21256   mp->context = 0;
21257   mp->is_enabled = enable;
21258   if (stream_name_set != 0)
21259     {
21260       mp->stream_name_length = ntohl (name_len);
21261       clib_memcpy (mp->stream_name, stream_name, name_len);
21262     }
21263   vec_free (stream_name);
21264
21265   S (mp);
21266   W (ret);
21267   return ret;
21268 }
21269
21270 int
21271 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21272 {
21273   unformat_input_t *input = vam->input;
21274   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21275
21276   u16 *low_ports = 0;
21277   u16 *high_ports = 0;
21278   u16 this_low;
21279   u16 this_hi;
21280   ip4_address_t ip4_addr;
21281   ip6_address_t ip6_addr;
21282   u32 length;
21283   u32 tmp, tmp2;
21284   u8 prefix_set = 0;
21285   u32 vrf_id = ~0;
21286   u8 is_add = 1;
21287   u8 is_ipv6 = 0;
21288   int ret;
21289
21290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21291     {
21292       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21293         {
21294           prefix_set = 1;
21295         }
21296       else
21297         if (unformat
21298             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21299         {
21300           prefix_set = 1;
21301           is_ipv6 = 1;
21302         }
21303       else if (unformat (input, "vrf %d", &vrf_id))
21304         ;
21305       else if (unformat (input, "del"))
21306         is_add = 0;
21307       else if (unformat (input, "port %d", &tmp))
21308         {
21309           if (tmp == 0 || tmp > 65535)
21310             {
21311               errmsg ("port %d out of range", tmp);
21312               return -99;
21313             }
21314           this_low = tmp;
21315           this_hi = this_low + 1;
21316           vec_add1 (low_ports, this_low);
21317           vec_add1 (high_ports, this_hi);
21318         }
21319       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21320         {
21321           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21322             {
21323               errmsg ("incorrect range parameters");
21324               return -99;
21325             }
21326           this_low = tmp;
21327           /* Note: in debug CLI +1 is added to high before
21328              passing to real fn that does "the work"
21329              (ip_source_and_port_range_check_add_del).
21330              This fn is a wrapper around the binary API fn a
21331              control plane will call, which expects this increment
21332              to have occurred. Hence letting the binary API control
21333              plane fn do the increment for consistency between VAT
21334              and other control planes.
21335            */
21336           this_hi = tmp2;
21337           vec_add1 (low_ports, this_low);
21338           vec_add1 (high_ports, this_hi);
21339         }
21340       else
21341         break;
21342     }
21343
21344   if (prefix_set == 0)
21345     {
21346       errmsg ("<address>/<mask> not specified");
21347       return -99;
21348     }
21349
21350   if (vrf_id == ~0)
21351     {
21352       errmsg ("VRF ID required, not specified");
21353       return -99;
21354     }
21355
21356   if (vrf_id == 0)
21357     {
21358       errmsg
21359         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21360       return -99;
21361     }
21362
21363   if (vec_len (low_ports) == 0)
21364     {
21365       errmsg ("At least one port or port range required");
21366       return -99;
21367     }
21368
21369   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21370
21371   mp->is_add = is_add;
21372
21373   if (is_ipv6)
21374     {
21375       mp->is_ipv6 = 1;
21376       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21377     }
21378   else
21379     {
21380       mp->is_ipv6 = 0;
21381       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21382     }
21383
21384   mp->mask_length = length;
21385   mp->number_of_ranges = vec_len (low_ports);
21386
21387   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21388   vec_free (low_ports);
21389
21390   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21391   vec_free (high_ports);
21392
21393   mp->vrf_id = ntohl (vrf_id);
21394
21395   S (mp);
21396   W (ret);
21397   return ret;
21398 }
21399
21400 int
21401 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21402 {
21403   unformat_input_t *input = vam->input;
21404   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21405   u32 sw_if_index = ~0;
21406   int vrf_set = 0;
21407   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21408   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21409   u8 is_add = 1;
21410   int ret;
21411
21412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21413     {
21414       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21415         ;
21416       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21417         ;
21418       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21419         vrf_set = 1;
21420       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21421         vrf_set = 1;
21422       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21423         vrf_set = 1;
21424       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21425         vrf_set = 1;
21426       else if (unformat (input, "del"))
21427         is_add = 0;
21428       else
21429         break;
21430     }
21431
21432   if (sw_if_index == ~0)
21433     {
21434       errmsg ("Interface required but not specified");
21435       return -99;
21436     }
21437
21438   if (vrf_set == 0)
21439     {
21440       errmsg ("VRF ID required but not specified");
21441       return -99;
21442     }
21443
21444   if (tcp_out_vrf_id == 0
21445       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21446     {
21447       errmsg
21448         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21449       return -99;
21450     }
21451
21452   /* Construct the API message */
21453   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21454
21455   mp->sw_if_index = ntohl (sw_if_index);
21456   mp->is_add = is_add;
21457   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21458   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21459   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21460   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21461
21462   /* send it... */
21463   S (mp);
21464
21465   /* Wait for a reply... */
21466   W (ret);
21467   return ret;
21468 }
21469
21470 static int
21471 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21472 {
21473   unformat_input_t *i = vam->input;
21474   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21475   u32 local_sa_id = 0;
21476   u32 remote_sa_id = 0;
21477   ip4_address_t src_address;
21478   ip4_address_t dst_address;
21479   u8 is_add = 1;
21480   int ret;
21481
21482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21483     {
21484       if (unformat (i, "local_sa %d", &local_sa_id))
21485         ;
21486       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21487         ;
21488       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21489         ;
21490       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21491         ;
21492       else if (unformat (i, "del"))
21493         is_add = 0;
21494       else
21495         {
21496           clib_warning ("parse error '%U'", format_unformat_error, i);
21497           return -99;
21498         }
21499     }
21500
21501   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21502
21503   mp->local_sa_id = ntohl (local_sa_id);
21504   mp->remote_sa_id = ntohl (remote_sa_id);
21505   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21506   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21507   mp->is_add = is_add;
21508
21509   S (mp);
21510   W (ret);
21511   return ret;
21512 }
21513
21514 static int
21515 api_punt (vat_main_t * vam)
21516 {
21517   unformat_input_t *i = vam->input;
21518   vl_api_punt_t *mp;
21519   u32 ipv = ~0;
21520   u32 protocol = ~0;
21521   u32 port = ~0;
21522   int is_add = 1;
21523   int ret;
21524
21525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21526     {
21527       if (unformat (i, "ip %d", &ipv))
21528         ;
21529       else if (unformat (i, "protocol %d", &protocol))
21530         ;
21531       else if (unformat (i, "port %d", &port))
21532         ;
21533       else if (unformat (i, "del"))
21534         is_add = 0;
21535       else
21536         {
21537           clib_warning ("parse error '%U'", format_unformat_error, i);
21538           return -99;
21539         }
21540     }
21541
21542   M (PUNT, mp);
21543
21544   mp->is_add = (u8) is_add;
21545   mp->ipv = (u8) ipv;
21546   mp->l4_protocol = (u8) protocol;
21547   mp->l4_port = htons ((u16) port);
21548
21549   S (mp);
21550   W (ret);
21551   return ret;
21552 }
21553
21554 static void vl_api_ipsec_gre_tunnel_details_t_handler
21555   (vl_api_ipsec_gre_tunnel_details_t * mp)
21556 {
21557   vat_main_t *vam = &vat_main;
21558
21559   print (vam->ofp, "%11d%15U%15U%14d%14d",
21560          ntohl (mp->sw_if_index),
21561          format_ip4_address, &mp->src_address,
21562          format_ip4_address, &mp->dst_address,
21563          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21564 }
21565
21566 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21567   (vl_api_ipsec_gre_tunnel_details_t * mp)
21568 {
21569   vat_main_t *vam = &vat_main;
21570   vat_json_node_t *node = NULL;
21571   struct in_addr ip4;
21572
21573   if (VAT_JSON_ARRAY != vam->json_tree.type)
21574     {
21575       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21576       vat_json_init_array (&vam->json_tree);
21577     }
21578   node = vat_json_array_add (&vam->json_tree);
21579
21580   vat_json_init_object (node);
21581   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21582   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21583   vat_json_object_add_ip4 (node, "src_address", ip4);
21584   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21585   vat_json_object_add_ip4 (node, "dst_address", ip4);
21586   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21587   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21588 }
21589
21590 static int
21591 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21592 {
21593   unformat_input_t *i = vam->input;
21594   vl_api_ipsec_gre_tunnel_dump_t *mp;
21595   vl_api_control_ping_t *mp_ping;
21596   u32 sw_if_index;
21597   u8 sw_if_index_set = 0;
21598   int ret;
21599
21600   /* Parse args required to build the message */
21601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21602     {
21603       if (unformat (i, "sw_if_index %d", &sw_if_index))
21604         sw_if_index_set = 1;
21605       else
21606         break;
21607     }
21608
21609   if (sw_if_index_set == 0)
21610     {
21611       sw_if_index = ~0;
21612     }
21613
21614   if (!vam->json_output)
21615     {
21616       print (vam->ofp, "%11s%15s%15s%14s%14s",
21617              "sw_if_index", "src_address", "dst_address",
21618              "local_sa_id", "remote_sa_id");
21619     }
21620
21621   /* Get list of gre-tunnel interfaces */
21622   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21623
21624   mp->sw_if_index = htonl (sw_if_index);
21625
21626   S (mp);
21627
21628   /* Use a control ping for synchronization */
21629   MPING (CONTROL_PING, mp_ping);
21630   S (mp_ping);
21631
21632   W (ret);
21633   return ret;
21634 }
21635
21636 static int
21637 api_delete_subif (vat_main_t * vam)
21638 {
21639   unformat_input_t *i = vam->input;
21640   vl_api_delete_subif_t *mp;
21641   u32 sw_if_index = ~0;
21642   int ret;
21643
21644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21645     {
21646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21647         ;
21648       if (unformat (i, "sw_if_index %d", &sw_if_index))
21649         ;
21650       else
21651         break;
21652     }
21653
21654   if (sw_if_index == ~0)
21655     {
21656       errmsg ("missing sw_if_index");
21657       return -99;
21658     }
21659
21660   /* Construct the API message */
21661   M (DELETE_SUBIF, mp);
21662   mp->sw_if_index = ntohl (sw_if_index);
21663
21664   S (mp);
21665   W (ret);
21666   return ret;
21667 }
21668
21669 #define foreach_pbb_vtr_op      \
21670 _("disable",  L2_VTR_DISABLED)  \
21671 _("pop",  L2_VTR_POP_2)         \
21672 _("push",  L2_VTR_PUSH_2)
21673
21674 static int
21675 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21676 {
21677   unformat_input_t *i = vam->input;
21678   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21679   u32 sw_if_index = ~0, vtr_op = ~0;
21680   u16 outer_tag = ~0;
21681   u8 dmac[6], smac[6];
21682   u8 dmac_set = 0, smac_set = 0;
21683   u16 vlanid = 0;
21684   u32 sid = ~0;
21685   u32 tmp;
21686   int ret;
21687
21688   /* Shut up coverity */
21689   memset (dmac, 0, sizeof (dmac));
21690   memset (smac, 0, sizeof (smac));
21691
21692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21693     {
21694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21695         ;
21696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21697         ;
21698       else if (unformat (i, "vtr_op %d", &vtr_op))
21699         ;
21700 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21701       foreach_pbb_vtr_op
21702 #undef _
21703         else if (unformat (i, "translate_pbb_stag"))
21704         {
21705           if (unformat (i, "%d", &tmp))
21706             {
21707               vtr_op = L2_VTR_TRANSLATE_2_1;
21708               outer_tag = tmp;
21709             }
21710           else
21711             {
21712               errmsg
21713                 ("translate_pbb_stag operation requires outer tag definition");
21714               return -99;
21715             }
21716         }
21717       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21718         dmac_set++;
21719       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21720         smac_set++;
21721       else if (unformat (i, "sid %d", &sid))
21722         ;
21723       else if (unformat (i, "vlanid %d", &tmp))
21724         vlanid = tmp;
21725       else
21726         {
21727           clib_warning ("parse error '%U'", format_unformat_error, i);
21728           return -99;
21729         }
21730     }
21731
21732   if ((sw_if_index == ~0) || (vtr_op == ~0))
21733     {
21734       errmsg ("missing sw_if_index or vtr operation");
21735       return -99;
21736     }
21737   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21738       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21739     {
21740       errmsg
21741         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21742       return -99;
21743     }
21744
21745   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21746   mp->sw_if_index = ntohl (sw_if_index);
21747   mp->vtr_op = ntohl (vtr_op);
21748   mp->outer_tag = ntohs (outer_tag);
21749   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21750   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21751   mp->b_vlanid = ntohs (vlanid);
21752   mp->i_sid = ntohl (sid);
21753
21754   S (mp);
21755   W (ret);
21756   return ret;
21757 }
21758
21759 static int
21760 api_flow_classify_set_interface (vat_main_t * vam)
21761 {
21762   unformat_input_t *i = vam->input;
21763   vl_api_flow_classify_set_interface_t *mp;
21764   u32 sw_if_index;
21765   int sw_if_index_set;
21766   u32 ip4_table_index = ~0;
21767   u32 ip6_table_index = ~0;
21768   u8 is_add = 1;
21769   int ret;
21770
21771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21772     {
21773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21774         sw_if_index_set = 1;
21775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21776         sw_if_index_set = 1;
21777       else if (unformat (i, "del"))
21778         is_add = 0;
21779       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21780         ;
21781       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21782         ;
21783       else
21784         {
21785           clib_warning ("parse error '%U'", format_unformat_error, i);
21786           return -99;
21787         }
21788     }
21789
21790   if (sw_if_index_set == 0)
21791     {
21792       errmsg ("missing interface name or sw_if_index");
21793       return -99;
21794     }
21795
21796   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21797
21798   mp->sw_if_index = ntohl (sw_if_index);
21799   mp->ip4_table_index = ntohl (ip4_table_index);
21800   mp->ip6_table_index = ntohl (ip6_table_index);
21801   mp->is_add = is_add;
21802
21803   S (mp);
21804   W (ret);
21805   return ret;
21806 }
21807
21808 static int
21809 api_flow_classify_dump (vat_main_t * vam)
21810 {
21811   unformat_input_t *i = vam->input;
21812   vl_api_flow_classify_dump_t *mp;
21813   vl_api_control_ping_t *mp_ping;
21814   u8 type = FLOW_CLASSIFY_N_TABLES;
21815   int ret;
21816
21817   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21818     ;
21819   else
21820     {
21821       errmsg ("classify table type must be specified");
21822       return -99;
21823     }
21824
21825   if (!vam->json_output)
21826     {
21827       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21828     }
21829
21830   M (FLOW_CLASSIFY_DUMP, mp);
21831   mp->type = type;
21832   /* send it... */
21833   S (mp);
21834
21835   /* Use a control ping for synchronization */
21836   MPING (CONTROL_PING, mp_ping);
21837   S (mp_ping);
21838
21839   /* Wait for a reply... */
21840   W (ret);
21841   return ret;
21842 }
21843
21844 static int
21845 api_feature_enable_disable (vat_main_t * vam)
21846 {
21847   unformat_input_t *i = vam->input;
21848   vl_api_feature_enable_disable_t *mp;
21849   u8 *arc_name = 0;
21850   u8 *feature_name = 0;
21851   u32 sw_if_index = ~0;
21852   u8 enable = 1;
21853   int ret;
21854
21855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21856     {
21857       if (unformat (i, "arc_name %s", &arc_name))
21858         ;
21859       else if (unformat (i, "feature_name %s", &feature_name))
21860         ;
21861       else
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, "disable"))
21867         enable = 0;
21868       else
21869         break;
21870     }
21871
21872   if (arc_name == 0)
21873     {
21874       errmsg ("missing arc name");
21875       return -99;
21876     }
21877   if (vec_len (arc_name) > 63)
21878     {
21879       errmsg ("arc name too long");
21880     }
21881
21882   if (feature_name == 0)
21883     {
21884       errmsg ("missing feature name");
21885       return -99;
21886     }
21887   if (vec_len (feature_name) > 63)
21888     {
21889       errmsg ("feature name too long");
21890     }
21891
21892   if (sw_if_index == ~0)
21893     {
21894       errmsg ("missing interface name or sw_if_index");
21895       return -99;
21896     }
21897
21898   /* Construct the API message */
21899   M (FEATURE_ENABLE_DISABLE, mp);
21900   mp->sw_if_index = ntohl (sw_if_index);
21901   mp->enable = enable;
21902   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21903   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21904   vec_free (arc_name);
21905   vec_free (feature_name);
21906
21907   S (mp);
21908   W (ret);
21909   return ret;
21910 }
21911
21912 static int
21913 api_sw_interface_tag_add_del (vat_main_t * vam)
21914 {
21915   unformat_input_t *i = vam->input;
21916   vl_api_sw_interface_tag_add_del_t *mp;
21917   u32 sw_if_index = ~0;
21918   u8 *tag = 0;
21919   u8 enable = 1;
21920   int ret;
21921
21922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21923     {
21924       if (unformat (i, "tag %s", &tag))
21925         ;
21926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21927         ;
21928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21929         ;
21930       else if (unformat (i, "del"))
21931         enable = 0;
21932       else
21933         break;
21934     }
21935
21936   if (sw_if_index == ~0)
21937     {
21938       errmsg ("missing interface name or sw_if_index");
21939       return -99;
21940     }
21941
21942   if (enable && (tag == 0))
21943     {
21944       errmsg ("no tag specified");
21945       return -99;
21946     }
21947
21948   /* Construct the API message */
21949   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21950   mp->sw_if_index = ntohl (sw_if_index);
21951   mp->is_add = enable;
21952   if (enable)
21953     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21954   vec_free (tag);
21955
21956   S (mp);
21957   W (ret);
21958   return ret;
21959 }
21960
21961 static void vl_api_l2_xconnect_details_t_handler
21962   (vl_api_l2_xconnect_details_t * mp)
21963 {
21964   vat_main_t *vam = &vat_main;
21965
21966   print (vam->ofp, "%15d%15d",
21967          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21968 }
21969
21970 static void vl_api_l2_xconnect_details_t_handler_json
21971   (vl_api_l2_xconnect_details_t * mp)
21972 {
21973   vat_main_t *vam = &vat_main;
21974   vat_json_node_t *node = NULL;
21975
21976   if (VAT_JSON_ARRAY != vam->json_tree.type)
21977     {
21978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21979       vat_json_init_array (&vam->json_tree);
21980     }
21981   node = vat_json_array_add (&vam->json_tree);
21982
21983   vat_json_init_object (node);
21984   vat_json_object_add_uint (node, "rx_sw_if_index",
21985                             ntohl (mp->rx_sw_if_index));
21986   vat_json_object_add_uint (node, "tx_sw_if_index",
21987                             ntohl (mp->tx_sw_if_index));
21988 }
21989
21990 static int
21991 api_l2_xconnect_dump (vat_main_t * vam)
21992 {
21993   vl_api_l2_xconnect_dump_t *mp;
21994   vl_api_control_ping_t *mp_ping;
21995   int ret;
21996
21997   if (!vam->json_output)
21998     {
21999       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22000     }
22001
22002   M (L2_XCONNECT_DUMP, mp);
22003
22004   S (mp);
22005
22006   /* Use a control ping for synchronization */
22007   MPING (CONTROL_PING, mp_ping);
22008   S (mp_ping);
22009
22010   W (ret);
22011   return ret;
22012 }
22013
22014 static int
22015 api_sw_interface_set_mtu (vat_main_t * vam)
22016 {
22017   unformat_input_t *i = vam->input;
22018   vl_api_sw_interface_set_mtu_t *mp;
22019   u32 sw_if_index = ~0;
22020   u32 mtu = 0;
22021   int ret;
22022
22023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22024     {
22025       if (unformat (i, "mtu %d", &mtu))
22026         ;
22027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22028         ;
22029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22030         ;
22031       else
22032         break;
22033     }
22034
22035   if (sw_if_index == ~0)
22036     {
22037       errmsg ("missing interface name or sw_if_index");
22038       return -99;
22039     }
22040
22041   if (mtu == 0)
22042     {
22043       errmsg ("no mtu specified");
22044       return -99;
22045     }
22046
22047   /* Construct the API message */
22048   M (SW_INTERFACE_SET_MTU, mp);
22049   mp->sw_if_index = ntohl (sw_if_index);
22050   mp->mtu = ntohs ((u16) mtu);
22051
22052   S (mp);
22053   W (ret);
22054   return ret;
22055 }
22056
22057 static int
22058 api_p2p_ethernet_add (vat_main_t * vam)
22059 {
22060   unformat_input_t *i = vam->input;
22061   vl_api_p2p_ethernet_add_t *mp;
22062   u32 parent_if_index = ~0;
22063   u32 sub_id = ~0;
22064   u8 remote_mac[6];
22065   u8 mac_set = 0;
22066   int ret;
22067
22068   memset (remote_mac, 0, sizeof (remote_mac));
22069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22070     {
22071       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22072         ;
22073       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22074         ;
22075       else
22076         if (unformat
22077             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22078         mac_set++;
22079       else if (unformat (i, "sub_id %d", &sub_id))
22080         ;
22081       else
22082         {
22083           clib_warning ("parse error '%U'", format_unformat_error, i);
22084           return -99;
22085         }
22086     }
22087
22088   if (parent_if_index == ~0)
22089     {
22090       errmsg ("missing interface name or sw_if_index");
22091       return -99;
22092     }
22093   if (mac_set == 0)
22094     {
22095       errmsg ("missing remote mac address");
22096       return -99;
22097     }
22098   if (sub_id == ~0)
22099     {
22100       errmsg ("missing sub-interface id");
22101       return -99;
22102     }
22103
22104   M (P2P_ETHERNET_ADD, mp);
22105   mp->parent_if_index = ntohl (parent_if_index);
22106   mp->subif_id = ntohl (sub_id);
22107   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22108
22109   S (mp);
22110   W (ret);
22111   return ret;
22112 }
22113
22114 static int
22115 api_p2p_ethernet_del (vat_main_t * vam)
22116 {
22117   unformat_input_t *i = vam->input;
22118   vl_api_p2p_ethernet_del_t *mp;
22119   u32 parent_if_index = ~0;
22120   u8 remote_mac[6];
22121   u8 mac_set = 0;
22122   int ret;
22123
22124   memset (remote_mac, 0, sizeof (remote_mac));
22125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22126     {
22127       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22128         ;
22129       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22130         ;
22131       else
22132         if (unformat
22133             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22134         mac_set++;
22135       else
22136         {
22137           clib_warning ("parse error '%U'", format_unformat_error, i);
22138           return -99;
22139         }
22140     }
22141
22142   if (parent_if_index == ~0)
22143     {
22144       errmsg ("missing interface name or sw_if_index");
22145       return -99;
22146     }
22147   if (mac_set == 0)
22148     {
22149       errmsg ("missing remote mac address");
22150       return -99;
22151     }
22152
22153   M (P2P_ETHERNET_DEL, mp);
22154   mp->parent_if_index = ntohl (parent_if_index);
22155   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22156
22157   S (mp);
22158   W (ret);
22159   return ret;
22160 }
22161
22162 static int
22163 api_lldp_config (vat_main_t * vam)
22164 {
22165   unformat_input_t *i = vam->input;
22166   vl_api_lldp_config_t *mp;
22167   int tx_hold = 0;
22168   int tx_interval = 0;
22169   u8 *sys_name = NULL;
22170   int ret;
22171
22172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22173     {
22174       if (unformat (i, "system-name %s", &sys_name))
22175         ;
22176       else if (unformat (i, "tx-hold %d", &tx_hold))
22177         ;
22178       else if (unformat (i, "tx-interval %d", &tx_interval))
22179         ;
22180       else
22181         {
22182           clib_warning ("parse error '%U'", format_unformat_error, i);
22183           return -99;
22184         }
22185     }
22186
22187   vec_add1 (sys_name, 0);
22188
22189   M (LLDP_CONFIG, mp);
22190   mp->tx_hold = htonl (tx_hold);
22191   mp->tx_interval = htonl (tx_interval);
22192   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22193   vec_free (sys_name);
22194
22195   S (mp);
22196   W (ret);
22197   return ret;
22198 }
22199
22200 static int
22201 api_sw_interface_set_lldp (vat_main_t * vam)
22202 {
22203   unformat_input_t *i = vam->input;
22204   vl_api_sw_interface_set_lldp_t *mp;
22205   u32 sw_if_index = ~0;
22206   u32 enable = 1;
22207   u8 *port_desc = NULL, *mgmt_oid = NULL;
22208   ip4_address_t ip4_addr;
22209   ip6_address_t ip6_addr;
22210   int ret;
22211
22212   memset (&ip4_addr, 0, sizeof (ip4_addr));
22213   memset (&ip6_addr, 0, sizeof (ip6_addr));
22214
22215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22216     {
22217       if (unformat (i, "disable"))
22218         enable = 0;
22219       else
22220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22221         ;
22222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22223         ;
22224       else if (unformat (i, "port-desc %s", &port_desc))
22225         ;
22226       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22227         ;
22228       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22229         ;
22230       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22231         ;
22232       else
22233         break;
22234     }
22235
22236   if (sw_if_index == ~0)
22237     {
22238       errmsg ("missing interface name or sw_if_index");
22239       return -99;
22240     }
22241
22242   /* Construct the API message */
22243   vec_add1 (port_desc, 0);
22244   vec_add1 (mgmt_oid, 0);
22245   M (SW_INTERFACE_SET_LLDP, mp);
22246   mp->sw_if_index = ntohl (sw_if_index);
22247   mp->enable = enable;
22248   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22249   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22250   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22251   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22252   vec_free (port_desc);
22253   vec_free (mgmt_oid);
22254
22255   S (mp);
22256   W (ret);
22257   return ret;
22258 }
22259
22260 static int
22261 api_tcp_configure_src_addresses (vat_main_t * vam)
22262 {
22263   vl_api_tcp_configure_src_addresses_t *mp;
22264   unformat_input_t *i = vam->input;
22265   ip4_address_t v4first, v4last;
22266   ip6_address_t v6first, v6last;
22267   u8 range_set = 0;
22268   u32 vrf_id = 0;
22269   int ret;
22270
22271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22272     {
22273       if (unformat (i, "%U - %U",
22274                     unformat_ip4_address, &v4first,
22275                     unformat_ip4_address, &v4last))
22276         {
22277           if (range_set)
22278             {
22279               errmsg ("one range per message (range already set)");
22280               return -99;
22281             }
22282           range_set = 1;
22283         }
22284       else if (unformat (i, "%U - %U",
22285                          unformat_ip6_address, &v6first,
22286                          unformat_ip6_address, &v6last))
22287         {
22288           if (range_set)
22289             {
22290               errmsg ("one range per message (range already set)");
22291               return -99;
22292             }
22293           range_set = 2;
22294         }
22295       else if (unformat (i, "vrf %d", &vrf_id))
22296         ;
22297       else
22298         break;
22299     }
22300
22301   if (range_set == 0)
22302     {
22303       errmsg ("address range not set");
22304       return -99;
22305     }
22306
22307   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22308   mp->vrf_id = ntohl (vrf_id);
22309   /* ipv6? */
22310   if (range_set == 2)
22311     {
22312       mp->is_ipv6 = 1;
22313       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22314       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22315     }
22316   else
22317     {
22318       mp->is_ipv6 = 0;
22319       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22320       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22321     }
22322   S (mp);
22323   W (ret);
22324   return ret;
22325 }
22326
22327 static void vl_api_app_namespace_add_del_reply_t_handler
22328   (vl_api_app_namespace_add_del_reply_t * mp)
22329 {
22330   vat_main_t *vam = &vat_main;
22331   i32 retval = ntohl (mp->retval);
22332   if (vam->async_mode)
22333     {
22334       vam->async_errors += (retval < 0);
22335     }
22336   else
22337     {
22338       vam->retval = retval;
22339       if (retval == 0)
22340         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22341       vam->result_ready = 1;
22342     }
22343 }
22344
22345 static void vl_api_app_namespace_add_del_reply_t_handler_json
22346   (vl_api_app_namespace_add_del_reply_t * mp)
22347 {
22348   vat_main_t *vam = &vat_main;
22349   vat_json_node_t node;
22350
22351   vat_json_init_object (&node);
22352   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22353   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22354
22355   vat_json_print (vam->ofp, &node);
22356   vat_json_free (&node);
22357
22358   vam->retval = ntohl (mp->retval);
22359   vam->result_ready = 1;
22360 }
22361
22362 static int
22363 api_app_namespace_add_del (vat_main_t * vam)
22364 {
22365   vl_api_app_namespace_add_del_t *mp;
22366   unformat_input_t *i = vam->input;
22367   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22368   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22369   u64 secret;
22370   int ret;
22371
22372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22373     {
22374       if (unformat (i, "id %_%v%_", &ns_id))
22375         ;
22376       else if (unformat (i, "secret %lu", &secret))
22377         secret_set = 1;
22378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22379         sw_if_index_set = 1;
22380       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22381         ;
22382       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22383         ;
22384       else
22385         break;
22386     }
22387   if (!ns_id || !secret_set || !sw_if_index_set)
22388     {
22389       errmsg ("namespace id, secret and sw_if_index must be set");
22390       return -99;
22391     }
22392   if (vec_len (ns_id) > 64)
22393     {
22394       errmsg ("namespace id too long");
22395       return -99;
22396     }
22397   M (APP_NAMESPACE_ADD_DEL, mp);
22398
22399   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22400   mp->namespace_id_len = vec_len (ns_id);
22401   mp->secret = clib_host_to_net_u64 (secret);
22402   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22403   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22404   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22405   vec_free (ns_id);
22406   S (mp);
22407   W (ret);
22408   return ret;
22409 }
22410
22411 static int
22412 api_memfd_segment_create (vat_main_t * vam)
22413 {
22414 #if VPP_API_TEST_BUILTIN == 0
22415   unformat_input_t *i = vam->input;
22416   vl_api_memfd_segment_create_t *mp;
22417   u64 size = 64 << 20;
22418   int ret;
22419
22420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22421     {
22422       if (unformat (i, "size %U", unformat_memory_size, &size))
22423         ;
22424       else
22425         break;
22426     }
22427
22428   M (MEMFD_SEGMENT_CREATE, mp);
22429   mp->requested_size = size;
22430   S (mp);
22431   W (ret);
22432   return ret;
22433
22434 #else
22435   errmsg ("memfd_segment_create (builtin) not supported");
22436   return -99;
22437 #endif
22438 }
22439
22440 static int
22441 api_sock_init_shm (vat_main_t * vam)
22442 {
22443 #if VPP_API_TEST_BUILTIN == 0
22444   unformat_input_t *i = vam->input;
22445   vl_api_shm_elem_config_t *config = 0;
22446   u64 size = 64 << 20;
22447   int rv;
22448
22449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22450     {
22451       if (unformat (i, "size %U", unformat_memory_size, &size))
22452         ;
22453       else
22454         break;
22455     }
22456
22457   /* Try customized config to see if it works */
22458   vec_validate (config, 3);
22459   config[0].type = VL_API_VLIB_RING;
22460   config[0].count = 256;
22461   config[0].size = 256;
22462   config[1].type = VL_API_CLIENT_RING;
22463   config[1].count = 256;
22464   config[1].size = 1024;
22465   config[2].type = VL_API_CLIENT_RING;
22466   config[2].count = 8;
22467   config[2].size = 4096;
22468   config[3].type = VL_API_QUEUE;
22469   config[3].count = 256;
22470   config[3].size = sizeof (uword);
22471   rv = vl_socket_client_init_shm (config);
22472   if (!rv)
22473     vam->client_index_invalid = 1;
22474   return rv;
22475 #else
22476   return -99;
22477 #endif
22478 }
22479
22480 static int
22481 api_dns_enable_disable (vat_main_t * vam)
22482 {
22483   unformat_input_t *line_input = vam->input;
22484   vl_api_dns_enable_disable_t *mp;
22485   u8 enable_disable = 1;
22486   int ret;
22487
22488   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22489     {
22490       if (unformat (line_input, "disable"))
22491         enable_disable = 0;
22492       if (unformat (line_input, "enable"))
22493         enable_disable = 1;
22494       else
22495         break;
22496     }
22497
22498   /* Construct the API message */
22499   M (DNS_ENABLE_DISABLE, mp);
22500   mp->enable = enable_disable;
22501
22502   /* send it... */
22503   S (mp);
22504   /* Wait for the reply */
22505   W (ret);
22506   return ret;
22507 }
22508
22509 static int
22510 api_dns_resolve_name (vat_main_t * vam)
22511 {
22512   unformat_input_t *line_input = vam->input;
22513   vl_api_dns_resolve_name_t *mp;
22514   u8 *name = 0;
22515   int ret;
22516
22517   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22518     {
22519       if (unformat (line_input, "%s", &name))
22520         ;
22521       else
22522         break;
22523     }
22524
22525   if (vec_len (name) > 127)
22526     {
22527       errmsg ("name too long");
22528       return -99;
22529     }
22530
22531   /* Construct the API message */
22532   M (DNS_RESOLVE_NAME, mp);
22533   memcpy (mp->name, name, vec_len (name));
22534   vec_free (name);
22535
22536   /* send it... */
22537   S (mp);
22538   /* Wait for the reply */
22539   W (ret);
22540   return ret;
22541 }
22542
22543 static int
22544 api_dns_resolve_ip (vat_main_t * vam)
22545 {
22546   unformat_input_t *line_input = vam->input;
22547   vl_api_dns_resolve_ip_t *mp;
22548   int is_ip6 = -1;
22549   ip4_address_t addr4;
22550   ip6_address_t addr6;
22551   int ret;
22552
22553   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22554     {
22555       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22556         is_ip6 = 1;
22557       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22558         is_ip6 = 0;
22559       else
22560         break;
22561     }
22562
22563   if (is_ip6 == -1)
22564     {
22565       errmsg ("missing address");
22566       return -99;
22567     }
22568
22569   /* Construct the API message */
22570   M (DNS_RESOLVE_IP, mp);
22571   mp->is_ip6 = is_ip6;
22572   if (is_ip6)
22573     memcpy (mp->address, &addr6, sizeof (addr6));
22574   else
22575     memcpy (mp->address, &addr4, sizeof (addr4));
22576
22577   /* send it... */
22578   S (mp);
22579   /* Wait for the reply */
22580   W (ret);
22581   return ret;
22582 }
22583
22584 static int
22585 api_dns_name_server_add_del (vat_main_t * vam)
22586 {
22587   unformat_input_t *i = vam->input;
22588   vl_api_dns_name_server_add_del_t *mp;
22589   u8 is_add = 1;
22590   ip6_address_t ip6_server;
22591   ip4_address_t ip4_server;
22592   int ip6_set = 0;
22593   int ip4_set = 0;
22594   int ret = 0;
22595
22596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22597     {
22598       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22599         ip6_set = 1;
22600       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22601         ip4_set = 1;
22602       else if (unformat (i, "del"))
22603         is_add = 0;
22604       else
22605         {
22606           clib_warning ("parse error '%U'", format_unformat_error, i);
22607           return -99;
22608         }
22609     }
22610
22611   if (ip4_set && ip6_set)
22612     {
22613       errmsg ("Only one server address allowed per message");
22614       return -99;
22615     }
22616   if ((ip4_set + ip6_set) == 0)
22617     {
22618       errmsg ("Server address required");
22619       return -99;
22620     }
22621
22622   /* Construct the API message */
22623   M (DNS_NAME_SERVER_ADD_DEL, mp);
22624
22625   if (ip6_set)
22626     {
22627       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22628       mp->is_ip6 = 1;
22629     }
22630   else
22631     {
22632       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22633       mp->is_ip6 = 0;
22634     }
22635
22636   mp->is_add = is_add;
22637
22638   /* send it... */
22639   S (mp);
22640
22641   /* Wait for a reply, return good/bad news  */
22642   W (ret);
22643   return ret;
22644 }
22645
22646 static void
22647 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22648 {
22649   vat_main_t *vam = &vat_main;
22650
22651   if (mp->is_ip4)
22652     {
22653       print (vam->ofp,
22654              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22655              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22656              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22657              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22658              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22659              clib_net_to_host_u32 (mp->action_index), mp->tag);
22660     }
22661   else
22662     {
22663       print (vam->ofp,
22664              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22665              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22666              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22667              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22668              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22669              clib_net_to_host_u32 (mp->action_index), mp->tag);
22670     }
22671 }
22672
22673 static void
22674 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22675                                              mp)
22676 {
22677   vat_main_t *vam = &vat_main;
22678   vat_json_node_t *node = NULL;
22679   struct in6_addr ip6;
22680   struct in_addr ip4;
22681
22682   if (VAT_JSON_ARRAY != vam->json_tree.type)
22683     {
22684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22685       vat_json_init_array (&vam->json_tree);
22686     }
22687   node = vat_json_array_add (&vam->json_tree);
22688   vat_json_init_object (node);
22689
22690   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22691   vat_json_object_add_uint (node, "appns_index",
22692                             clib_net_to_host_u32 (mp->appns_index));
22693   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22694   vat_json_object_add_uint (node, "scope", mp->scope);
22695   vat_json_object_add_uint (node, "action_index",
22696                             clib_net_to_host_u32 (mp->action_index));
22697   vat_json_object_add_uint (node, "lcl_port",
22698                             clib_net_to_host_u16 (mp->lcl_port));
22699   vat_json_object_add_uint (node, "rmt_port",
22700                             clib_net_to_host_u16 (mp->rmt_port));
22701   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22702   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22703   vat_json_object_add_string_copy (node, "tag", mp->tag);
22704   if (mp->is_ip4)
22705     {
22706       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22707       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22708       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22709       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22710     }
22711   else
22712     {
22713       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22714       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22715       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22716       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22717     }
22718 }
22719
22720 static int
22721 api_session_rule_add_del (vat_main_t * vam)
22722 {
22723   vl_api_session_rule_add_del_t *mp;
22724   unformat_input_t *i = vam->input;
22725   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22726   u32 appns_index = 0, scope = 0;
22727   ip4_address_t lcl_ip4, rmt_ip4;
22728   ip6_address_t lcl_ip6, rmt_ip6;
22729   u8 is_ip4 = 1, conn_set = 0;
22730   u8 is_add = 1, *tag = 0;
22731   int ret;
22732
22733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22734     {
22735       if (unformat (i, "del"))
22736         is_add = 0;
22737       else if (unformat (i, "add"))
22738         ;
22739       else if (unformat (i, "proto tcp"))
22740         proto = 0;
22741       else if (unformat (i, "proto udp"))
22742         proto = 1;
22743       else if (unformat (i, "appns %d", &appns_index))
22744         ;
22745       else if (unformat (i, "scope %d", &scope))
22746         ;
22747       else if (unformat (i, "tag %_%v%_", &tag))
22748         ;
22749       else
22750         if (unformat
22751             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22752              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22753              &rmt_port))
22754         {
22755           is_ip4 = 1;
22756           conn_set = 1;
22757         }
22758       else
22759         if (unformat
22760             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22761              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22762              &rmt_port))
22763         {
22764           is_ip4 = 0;
22765           conn_set = 1;
22766         }
22767       else if (unformat (i, "action %d", &action))
22768         ;
22769       else
22770         break;
22771     }
22772   if (proto == ~0 || !conn_set || action == ~0)
22773     {
22774       errmsg ("transport proto, connection and action must be set");
22775       return -99;
22776     }
22777
22778   if (scope > 3)
22779     {
22780       errmsg ("scope should be 0-3");
22781       return -99;
22782     }
22783
22784   M (SESSION_RULE_ADD_DEL, mp);
22785
22786   mp->is_ip4 = is_ip4;
22787   mp->transport_proto = proto;
22788   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22789   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22790   mp->lcl_plen = lcl_plen;
22791   mp->rmt_plen = rmt_plen;
22792   mp->action_index = clib_host_to_net_u32 (action);
22793   mp->appns_index = clib_host_to_net_u32 (appns_index);
22794   mp->scope = scope;
22795   mp->is_add = is_add;
22796   if (is_ip4)
22797     {
22798       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22799       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22800     }
22801   else
22802     {
22803       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22804       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22805     }
22806   if (tag)
22807     {
22808       clib_memcpy (mp->tag, tag, vec_len (tag));
22809       vec_free (tag);
22810     }
22811
22812   S (mp);
22813   W (ret);
22814   return ret;
22815 }
22816
22817 static int
22818 api_session_rules_dump (vat_main_t * vam)
22819 {
22820   vl_api_session_rules_dump_t *mp;
22821   vl_api_control_ping_t *mp_ping;
22822   int ret;
22823
22824   if (!vam->json_output)
22825     {
22826       print (vam->ofp, "%=20s", "Session Rules");
22827     }
22828
22829   M (SESSION_RULES_DUMP, mp);
22830   /* send it... */
22831   S (mp);
22832
22833   /* Use a control ping for synchronization */
22834   MPING (CONTROL_PING, mp_ping);
22835   S (mp_ping);
22836
22837   /* Wait for a reply... */
22838   W (ret);
22839   return ret;
22840 }
22841
22842 static int
22843 api_ip_container_proxy_add_del (vat_main_t * vam)
22844 {
22845   vl_api_ip_container_proxy_add_del_t *mp;
22846   unformat_input_t *i = vam->input;
22847   u32 plen = ~0, sw_if_index = ~0;
22848   ip4_address_t ip4;
22849   ip6_address_t ip6;
22850   u8 is_ip4 = 1;
22851   u8 is_add = 1;
22852   int ret;
22853
22854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22855     {
22856       if (unformat (i, "del"))
22857         is_add = 0;
22858       else if (unformat (i, "add"))
22859         ;
22860       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22861         {
22862           is_ip4 = 1;
22863           plen = 32;
22864         }
22865       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22866         {
22867           is_ip4 = 0;
22868           plen = 128;
22869         }
22870       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22871         ;
22872       else
22873         break;
22874     }
22875   if (sw_if_index == ~0 || plen == ~0)
22876     {
22877       errmsg ("address and sw_if_index must be set");
22878       return -99;
22879     }
22880
22881   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22882
22883   mp->is_ip4 = is_ip4;
22884   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22885   mp->plen = plen;
22886   mp->is_add = is_add;
22887   if (is_ip4)
22888     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22889   else
22890     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22891
22892   S (mp);
22893   W (ret);
22894   return ret;
22895 }
22896
22897 static int
22898 q_or_quit (vat_main_t * vam)
22899 {
22900 #if VPP_API_TEST_BUILTIN == 0
22901   longjmp (vam->jump_buf, 1);
22902 #endif
22903   return 0;                     /* not so much */
22904 }
22905
22906 static int
22907 q (vat_main_t * vam)
22908 {
22909   return q_or_quit (vam);
22910 }
22911
22912 static int
22913 quit (vat_main_t * vam)
22914 {
22915   return q_or_quit (vam);
22916 }
22917
22918 static int
22919 comment (vat_main_t * vam)
22920 {
22921   return 0;
22922 }
22923
22924 static int
22925 cmd_cmp (void *a1, void *a2)
22926 {
22927   u8 **c1 = a1;
22928   u8 **c2 = a2;
22929
22930   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22931 }
22932
22933 static int
22934 help (vat_main_t * vam)
22935 {
22936   u8 **cmds = 0;
22937   u8 *name = 0;
22938   hash_pair_t *p;
22939   unformat_input_t *i = vam->input;
22940   int j;
22941
22942   if (unformat (i, "%s", &name))
22943     {
22944       uword *hs;
22945
22946       vec_add1 (name, 0);
22947
22948       hs = hash_get_mem (vam->help_by_name, name);
22949       if (hs)
22950         print (vam->ofp, "usage: %s %s", name, hs[0]);
22951       else
22952         print (vam->ofp, "No such msg / command '%s'", name);
22953       vec_free (name);
22954       return 0;
22955     }
22956
22957   print (vam->ofp, "Help is available for the following:");
22958
22959     /* *INDENT-OFF* */
22960     hash_foreach_pair (p, vam->function_by_name,
22961     ({
22962       vec_add1 (cmds, (u8 *)(p->key));
22963     }));
22964     /* *INDENT-ON* */
22965
22966   vec_sort_with_function (cmds, cmd_cmp);
22967
22968   for (j = 0; j < vec_len (cmds); j++)
22969     print (vam->ofp, "%s", cmds[j]);
22970
22971   vec_free (cmds);
22972   return 0;
22973 }
22974
22975 static int
22976 set (vat_main_t * vam)
22977 {
22978   u8 *name = 0, *value = 0;
22979   unformat_input_t *i = vam->input;
22980
22981   if (unformat (i, "%s", &name))
22982     {
22983       /* The input buffer is a vector, not a string. */
22984       value = vec_dup (i->buffer);
22985       vec_delete (value, i->index, 0);
22986       /* Almost certainly has a trailing newline */
22987       if (value[vec_len (value) - 1] == '\n')
22988         value[vec_len (value) - 1] = 0;
22989       /* Make sure it's a proper string, one way or the other */
22990       vec_add1 (value, 0);
22991       (void) clib_macro_set_value (&vam->macro_main,
22992                                    (char *) name, (char *) value);
22993     }
22994   else
22995     errmsg ("usage: set <name> <value>");
22996
22997   vec_free (name);
22998   vec_free (value);
22999   return 0;
23000 }
23001
23002 static int
23003 unset (vat_main_t * vam)
23004 {
23005   u8 *name = 0;
23006
23007   if (unformat (vam->input, "%s", &name))
23008     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23009       errmsg ("unset: %s wasn't set", name);
23010   vec_free (name);
23011   return 0;
23012 }
23013
23014 typedef struct
23015 {
23016   u8 *name;
23017   u8 *value;
23018 } macro_sort_t;
23019
23020
23021 static int
23022 macro_sort_cmp (void *a1, void *a2)
23023 {
23024   macro_sort_t *s1 = a1;
23025   macro_sort_t *s2 = a2;
23026
23027   return strcmp ((char *) (s1->name), (char *) (s2->name));
23028 }
23029
23030 static int
23031 dump_macro_table (vat_main_t * vam)
23032 {
23033   macro_sort_t *sort_me = 0, *sm;
23034   int i;
23035   hash_pair_t *p;
23036
23037     /* *INDENT-OFF* */
23038     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23039     ({
23040       vec_add2 (sort_me, sm, 1);
23041       sm->name = (u8 *)(p->key);
23042       sm->value = (u8 *) (p->value[0]);
23043     }));
23044     /* *INDENT-ON* */
23045
23046   vec_sort_with_function (sort_me, macro_sort_cmp);
23047
23048   if (vec_len (sort_me))
23049     print (vam->ofp, "%-15s%s", "Name", "Value");
23050   else
23051     print (vam->ofp, "The macro table is empty...");
23052
23053   for (i = 0; i < vec_len (sort_me); i++)
23054     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23055   return 0;
23056 }
23057
23058 static int
23059 dump_node_table (vat_main_t * vam)
23060 {
23061   int i, j;
23062   vlib_node_t *node, *next_node;
23063
23064   if (vec_len (vam->graph_nodes) == 0)
23065     {
23066       print (vam->ofp, "Node table empty, issue get_node_graph...");
23067       return 0;
23068     }
23069
23070   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23071     {
23072       node = vam->graph_nodes[i];
23073       print (vam->ofp, "[%d] %s", i, node->name);
23074       for (j = 0; j < vec_len (node->next_nodes); j++)
23075         {
23076           if (node->next_nodes[j] != ~0)
23077             {
23078               next_node = vam->graph_nodes[node->next_nodes[j]];
23079               print (vam->ofp, "  [%d] %s", j, next_node->name);
23080             }
23081         }
23082     }
23083   return 0;
23084 }
23085
23086 static int
23087 value_sort_cmp (void *a1, void *a2)
23088 {
23089   name_sort_t *n1 = a1;
23090   name_sort_t *n2 = a2;
23091
23092   if (n1->value < n2->value)
23093     return -1;
23094   if (n1->value > n2->value)
23095     return 1;
23096   return 0;
23097 }
23098
23099
23100 static int
23101 dump_msg_api_table (vat_main_t * vam)
23102 {
23103   api_main_t *am = &api_main;
23104   name_sort_t *nses = 0, *ns;
23105   hash_pair_t *hp;
23106   int i;
23107
23108   /* *INDENT-OFF* */
23109   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23110   ({
23111     vec_add2 (nses, ns, 1);
23112     ns->name = (u8 *)(hp->key);
23113     ns->value = (u32) hp->value[0];
23114   }));
23115   /* *INDENT-ON* */
23116
23117   vec_sort_with_function (nses, value_sort_cmp);
23118
23119   for (i = 0; i < vec_len (nses); i++)
23120     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23121   vec_free (nses);
23122   return 0;
23123 }
23124
23125 static int
23126 get_msg_id (vat_main_t * vam)
23127 {
23128   u8 *name_and_crc;
23129   u32 message_index;
23130
23131   if (unformat (vam->input, "%s", &name_and_crc))
23132     {
23133       message_index = vl_msg_api_get_msg_index (name_and_crc);
23134       if (message_index == ~0)
23135         {
23136           print (vam->ofp, " '%s' not found", name_and_crc);
23137           return 0;
23138         }
23139       print (vam->ofp, " '%s' has message index %d",
23140              name_and_crc, message_index);
23141       return 0;
23142     }
23143   errmsg ("name_and_crc required...");
23144   return 0;
23145 }
23146
23147 static int
23148 search_node_table (vat_main_t * vam)
23149 {
23150   unformat_input_t *line_input = vam->input;
23151   u8 *node_to_find;
23152   int j;
23153   vlib_node_t *node, *next_node;
23154   uword *p;
23155
23156   if (vam->graph_node_index_by_name == 0)
23157     {
23158       print (vam->ofp, "Node table empty, issue get_node_graph...");
23159       return 0;
23160     }
23161
23162   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23163     {
23164       if (unformat (line_input, "%s", &node_to_find))
23165         {
23166           vec_add1 (node_to_find, 0);
23167           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23168           if (p == 0)
23169             {
23170               print (vam->ofp, "%s not found...", node_to_find);
23171               goto out;
23172             }
23173           node = vam->graph_nodes[p[0]];
23174           print (vam->ofp, "[%d] %s", p[0], node->name);
23175           for (j = 0; j < vec_len (node->next_nodes); j++)
23176             {
23177               if (node->next_nodes[j] != ~0)
23178                 {
23179                   next_node = vam->graph_nodes[node->next_nodes[j]];
23180                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23181                 }
23182             }
23183         }
23184
23185       else
23186         {
23187           clib_warning ("parse error '%U'", format_unformat_error,
23188                         line_input);
23189           return -99;
23190         }
23191
23192     out:
23193       vec_free (node_to_find);
23194
23195     }
23196
23197   return 0;
23198 }
23199
23200
23201 static int
23202 script (vat_main_t * vam)
23203 {
23204 #if (VPP_API_TEST_BUILTIN==0)
23205   u8 *s = 0;
23206   char *save_current_file;
23207   unformat_input_t save_input;
23208   jmp_buf save_jump_buf;
23209   u32 save_line_number;
23210
23211   FILE *new_fp, *save_ifp;
23212
23213   if (unformat (vam->input, "%s", &s))
23214     {
23215       new_fp = fopen ((char *) s, "r");
23216       if (new_fp == 0)
23217         {
23218           errmsg ("Couldn't open script file %s", s);
23219           vec_free (s);
23220           return -99;
23221         }
23222     }
23223   else
23224     {
23225       errmsg ("Missing script name");
23226       return -99;
23227     }
23228
23229   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23230   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23231   save_ifp = vam->ifp;
23232   save_line_number = vam->input_line_number;
23233   save_current_file = (char *) vam->current_file;
23234
23235   vam->input_line_number = 0;
23236   vam->ifp = new_fp;
23237   vam->current_file = s;
23238   do_one_file (vam);
23239
23240   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23241   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23242   vam->ifp = save_ifp;
23243   vam->input_line_number = save_line_number;
23244   vam->current_file = (u8 *) save_current_file;
23245   vec_free (s);
23246
23247   return 0;
23248 #else
23249   clib_warning ("use the exec command...");
23250   return -99;
23251 #endif
23252 }
23253
23254 static int
23255 echo (vat_main_t * vam)
23256 {
23257   print (vam->ofp, "%v", vam->input->buffer);
23258   return 0;
23259 }
23260
23261 /* List of API message constructors, CLI names map to api_xxx */
23262 #define foreach_vpe_api_msg                                             \
23263 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23264 _(sw_interface_dump,"")                                                 \
23265 _(sw_interface_set_flags,                                               \
23266   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23267 _(sw_interface_add_del_address,                                         \
23268   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23269 _(sw_interface_set_rx_mode,                                             \
23270   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23271 _(sw_interface_set_table,                                               \
23272   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23273 _(sw_interface_set_mpls_enable,                                         \
23274   "<intfc> | sw_if_index [disable | dis]")                              \
23275 _(sw_interface_set_vpath,                                               \
23276   "<intfc> | sw_if_index <id> enable | disable")                        \
23277 _(sw_interface_set_vxlan_bypass,                                        \
23278   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23279 _(sw_interface_set_geneve_bypass,                                       \
23280   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23281 _(sw_interface_set_l2_xconnect,                                         \
23282   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23283   "enable | disable")                                                   \
23284 _(sw_interface_set_l2_bridge,                                           \
23285   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23286   "[shg <split-horizon-group>] [bvi]\n"                                 \
23287   "enable | disable")                                                   \
23288 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23289 _(bridge_domain_add_del,                                                \
23290   "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") \
23291 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23292 _(l2fib_add_del,                                                        \
23293   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23294 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23295 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23296 _(l2_flags,                                                             \
23297   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23298 _(bridge_flags,                                                         \
23299   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23300 _(tap_connect,                                                          \
23301   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23302 _(tap_modify,                                                           \
23303   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23304 _(tap_delete,                                                           \
23305   "<vpp-if-name> | sw_if_index <id>")                                   \
23306 _(sw_interface_tap_dump, "")                                            \
23307 _(tap_create_v2,                                                        \
23308   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23309 _(tap_delete_v2,                                                        \
23310   "<vpp-if-name> | sw_if_index <id>")                                   \
23311 _(sw_interface_tap_v2_dump, "")                                         \
23312 _(bond_create,                                                          \
23313   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23314   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23315 _(bond_delete,                                                          \
23316   "<vpp-if-name> | sw_if_index <id>")                                   \
23317 _(bond_enslave,                                                         \
23318   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23319 _(bond_detach_slave,                                                    \
23320   "sw_if_index <n>")                                                    \
23321 _(sw_interface_bond_dump, "")                                           \
23322 _(sw_interface_slave_dump,                                              \
23323   "<vpp-if-name> | sw_if_index <id>")                                   \
23324 _(ip_table_add_del,                                                     \
23325   "table-id <n> [ipv6]\n")                                              \
23326 _(ip_add_del_route,                                                     \
23327   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23328   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23329   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23330   "[multipath] [count <n>]")                                            \
23331 _(ip_mroute_add_del,                                                    \
23332   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23333   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23334 _(mpls_table_add_del,                                                   \
23335   "table-id <n>\n")                                                     \
23336 _(mpls_route_add_del,                                                   \
23337   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23338   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23339   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23340   "[multipath] [count <n>]")                                            \
23341 _(mpls_ip_bind_unbind,                                                  \
23342   "<label> <addr/len>")                                                 \
23343 _(mpls_tunnel_add_del,                                                  \
23344   " via <addr> [table-id <n>]\n"                                        \
23345   "sw_if_index <id>] [l2]  [del]")                                      \
23346 _(bier_table_add_del,                                                   \
23347   "<label> <sub-domain> <set> <bsl> [del]")                             \
23348 _(bier_route_add_del,                                                   \
23349   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23350   "[<intfc> | sw_if_index <id>]"                                        \
23351   "[weight <n>] [del] [multipath]")                                     \
23352 _(proxy_arp_add_del,                                                    \
23353   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23354 _(proxy_arp_intfc_enable_disable,                                       \
23355   "<intfc> | sw_if_index <id> enable | disable")                        \
23356 _(sw_interface_set_unnumbered,                                          \
23357   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23358 _(ip_neighbor_add_del,                                                  \
23359   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23360   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23361 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23362 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23363   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23364   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23365   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23366 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23367 _(reset_fib, "vrf <n> [ipv6]")                                          \
23368 _(dhcp_proxy_config,                                                    \
23369   "svr <v46-address> src <v46-address>\n"                               \
23370    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23371 _(dhcp_proxy_set_vss,                                                   \
23372   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23373 _(dhcp_proxy_dump, "ip6")                                               \
23374 _(dhcp_client_config,                                                   \
23375   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23376 _(set_ip_flow_hash,                                                     \
23377   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23378 _(sw_interface_ip6_enable_disable,                                      \
23379   "<intfc> | sw_if_index <id> enable | disable")                        \
23380 _(sw_interface_ip6_set_link_local_address,                              \
23381   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23382 _(ip6nd_proxy_add_del,                                                  \
23383   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23384 _(ip6nd_proxy_dump, "")                                                 \
23385 _(sw_interface_ip6nd_ra_prefix,                                         \
23386   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23387   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23388   "[nolink] [isno]")                                                    \
23389 _(sw_interface_ip6nd_ra_config,                                         \
23390   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23391   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23392   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23393 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23394 _(l2_patch_add_del,                                                     \
23395   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23396   "enable | disable")                                                   \
23397 _(sr_localsid_add_del,                                                  \
23398   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23399   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23400 _(classify_add_del_table,                                               \
23401   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23402   " [del] [del-chain] mask <mask-value>\n"                              \
23403   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23404   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23405 _(classify_add_del_session,                                             \
23406   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23407   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23408   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23409   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23410 _(classify_set_interface_ip_table,                                      \
23411   "<intfc> | sw_if_index <nn> table <nn>")                              \
23412 _(classify_set_interface_l2_tables,                                     \
23413   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23414   "  [other-table <nn>]")                                               \
23415 _(get_node_index, "node <node-name")                                    \
23416 _(add_node_next, "node <node-name> next <next-node-name>")              \
23417 _(l2tpv3_create_tunnel,                                                 \
23418   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23419   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23420   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23421 _(l2tpv3_set_tunnel_cookies,                                            \
23422   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23423   "[new_remote_cookie <nn>]\n")                                         \
23424 _(l2tpv3_interface_enable_disable,                                      \
23425   "<intfc> | sw_if_index <nn> enable | disable")                        \
23426 _(l2tpv3_set_lookup_key,                                                \
23427   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23428 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23429 _(vxlan_add_del_tunnel,                                                 \
23430   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23431   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23432   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23433 _(geneve_add_del_tunnel,                                                \
23434   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23435   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23436   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23437 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23438 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23439 _(gre_add_del_tunnel,                                                   \
23440   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23441   "[teb | erspan <session-id>] [del]")                                  \
23442 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23443 _(l2_fib_clear_table, "")                                               \
23444 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23445 _(l2_interface_vlan_tag_rewrite,                                        \
23446   "<intfc> | sw_if_index <nn> \n"                                       \
23447   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23448   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23449 _(create_vhost_user_if,                                                 \
23450         "socket <filename> [server] [renumber <dev_instance>] "         \
23451         "[mac <mac_address>]")                                          \
23452 _(modify_vhost_user_if,                                                 \
23453         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23454         "[server] [renumber <dev_instance>]")                           \
23455 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23456 _(sw_interface_vhost_user_dump, "")                                     \
23457 _(show_version, "")                                                     \
23458 _(vxlan_gpe_add_del_tunnel,                                             \
23459   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23460   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23461   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23462   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23463 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23464 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23465 _(interface_name_renumber,                                              \
23466   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23467 _(input_acl_set_interface,                                              \
23468   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23469   "  [l2-table <nn>] [del]")                                            \
23470 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23471 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23472 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23473 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23474 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23475 _(ip_dump, "ipv4 | ipv6")                                               \
23476 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23477 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23478   "  spid_id <n> ")                                                     \
23479 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23480   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23481   "  integ_alg <alg> integ_key <hex>")                                  \
23482 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23483   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23484   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23485   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23486 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23487 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23488   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23489   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23490   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23491   "  [instance <n>]")     \
23492 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23493 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23494   "  <alg> <hex>\n")                                                    \
23495 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23496 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23497 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23498   "(auth_data 0x<data> | auth_data <data>)")                            \
23499 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23500   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23501 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23502   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23503   "(local|remote)")                                                     \
23504 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23505 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23506 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23507 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23508 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23509 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23510 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23511 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23512 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23513 _(delete_loopback,"sw_if_index <nn>")                                   \
23514 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23515 _(map_add_domain,                                                       \
23516   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23517   "ip6-src <ip6addr> "                                                  \
23518   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23519 _(map_del_domain, "index <n>")                                          \
23520 _(map_add_del_rule,                                                     \
23521   "index <n> psid <n> dst <ip6addr> [del]")                             \
23522 _(map_domain_dump, "")                                                  \
23523 _(map_rule_dump, "index <map-domain>")                                  \
23524 _(want_interface_events,  "enable|disable")                             \
23525 _(want_stats,"enable|disable")                                          \
23526 _(get_first_msg_id, "client <name>")                                    \
23527 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23528 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23529   "fib-id <nn> [ip4][ip6][default]")                                    \
23530 _(get_node_graph, " ")                                                  \
23531 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23532 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23533 _(ioam_disable, "")                                                     \
23534 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23535                             " sw_if_index <sw_if_index> p <priority> "  \
23536                             "w <weight>] [del]")                        \
23537 _(one_add_del_locator, "locator-set <locator_name> "                    \
23538                         "iface <intf> | sw_if_index <sw_if_index> "     \
23539                         "p <priority> w <weight> [del]")                \
23540 _(one_add_del_local_eid,"vni <vni> eid "                                \
23541                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23542                          "locator-set <locator_name> [del]"             \
23543                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23544 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23545 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23546 _(one_enable_disable, "enable|disable")                                 \
23547 _(one_map_register_enable_disable, "enable|disable")                    \
23548 _(one_map_register_fallback_threshold, "<value>")                       \
23549 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23550 _(one_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 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23556                           "<local-eid>")                                \
23557 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23558 _(one_use_petr, "ip-address> | disable")                                \
23559 _(one_map_request_mode, "src-dst|dst-only")                             \
23560 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23561 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23562 _(one_locator_set_dump, "[local | remote]")                             \
23563 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23564 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23565                        "[local] | [remote]")                            \
23566 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23567 _(one_ndp_bd_get, "")                                                   \
23568 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23569 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23570 _(one_l2_arp_bd_get, "")                                                \
23571 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23572 _(one_stats_enable_disable, "enable|disalbe")                           \
23573 _(show_one_stats_enable_disable, "")                                    \
23574 _(one_eid_table_vni_dump, "")                                           \
23575 _(one_eid_table_map_dump, "l2|l3")                                      \
23576 _(one_map_resolver_dump, "")                                            \
23577 _(one_map_server_dump, "")                                              \
23578 _(one_adjacencies_get, "vni <vni>")                                     \
23579 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23580 _(show_one_rloc_probe_state, "")                                        \
23581 _(show_one_map_register_state, "")                                      \
23582 _(show_one_status, "")                                                  \
23583 _(one_stats_dump, "")                                                   \
23584 _(one_stats_flush, "")                                                  \
23585 _(one_get_map_request_itr_rlocs, "")                                    \
23586 _(one_map_register_set_ttl, "<ttl>")                                    \
23587 _(one_set_transport_protocol, "udp|api")                                \
23588 _(one_get_transport_protocol, "")                                       \
23589 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23590 _(one_show_xtr_mode, "")                                                \
23591 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23592 _(one_show_pitr_mode, "")                                               \
23593 _(one_enable_disable_petr_mode, "enable|disable")                       \
23594 _(one_show_petr_mode, "")                                               \
23595 _(show_one_nsh_mapping, "")                                             \
23596 _(show_one_pitr, "")                                                    \
23597 _(show_one_use_petr, "")                                                \
23598 _(show_one_map_request_mode, "")                                        \
23599 _(show_one_map_register_ttl, "")                                        \
23600 _(show_one_map_register_fallback_threshold, "")                         \
23601 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23602                             " sw_if_index <sw_if_index> p <priority> "  \
23603                             "w <weight>] [del]")                        \
23604 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23605                         "iface <intf> | sw_if_index <sw_if_index> "     \
23606                         "p <priority> w <weight> [del]")                \
23607 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23608                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23609                          "locator-set <locator_name> [del]"             \
23610                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23611 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23612 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23613 _(lisp_enable_disable, "enable|disable")                                \
23614 _(lisp_map_register_enable_disable, "enable|disable")                   \
23615 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23616 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23617                                "[seid <seid>] "                         \
23618                                "rloc <locator> p <prio> "               \
23619                                "w <weight> [rloc <loc> ... ] "          \
23620                                "action <action> [del-all]")             \
23621 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23622                           "<local-eid>")                                \
23623 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23624 _(lisp_use_petr, "<ip-address> | disable")                              \
23625 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23626 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23627 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23628 _(lisp_locator_set_dump, "[local | remote]")                            \
23629 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23630 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23631                        "[local] | [remote]")                            \
23632 _(lisp_eid_table_vni_dump, "")                                          \
23633 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23634 _(lisp_map_resolver_dump, "")                                           \
23635 _(lisp_map_server_dump, "")                                             \
23636 _(lisp_adjacencies_get, "vni <vni>")                                    \
23637 _(gpe_fwd_entry_vnis_get, "")                                           \
23638 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23639 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23640                                 "[table <table-id>]")                   \
23641 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23642 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23643 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23644 _(gpe_get_encap_mode, "")                                               \
23645 _(lisp_gpe_add_del_iface, "up|down")                                    \
23646 _(lisp_gpe_enable_disable, "enable|disable")                            \
23647 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23648   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23649 _(show_lisp_rloc_probe_state, "")                                       \
23650 _(show_lisp_map_register_state, "")                                     \
23651 _(show_lisp_status, "")                                                 \
23652 _(lisp_get_map_request_itr_rlocs, "")                                   \
23653 _(show_lisp_pitr, "")                                                   \
23654 _(show_lisp_use_petr, "")                                               \
23655 _(show_lisp_map_request_mode, "")                                       \
23656 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23657 _(af_packet_delete, "name <host interface name>")                       \
23658 _(policer_add_del, "name <policer name> <params> [del]")                \
23659 _(policer_dump, "[name <policer name>]")                                \
23660 _(policer_classify_set_interface,                                       \
23661   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23662   "  [l2-table <nn>] [del]")                                            \
23663 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23664 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23665     "[master|slave]")                                                   \
23666 _(netmap_delete, "name <interface name>")                               \
23667 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23668 _(mpls_fib_dump, "")                                                    \
23669 _(classify_table_ids, "")                                               \
23670 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23671 _(classify_table_info, "table_id <nn>")                                 \
23672 _(classify_session_dump, "table_id <nn>")                               \
23673 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23674     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23675     "[template_interval <nn>] [udp_checksum]")                          \
23676 _(ipfix_exporter_dump, "")                                              \
23677 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23678 _(ipfix_classify_stream_dump, "")                                       \
23679 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23680 _(ipfix_classify_table_dump, "")                                        \
23681 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23682 _(sw_interface_span_dump, "[l2]")                                           \
23683 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23684 _(pg_create_interface, "if_id <nn>")                                    \
23685 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23686 _(pg_enable_disable, "[stream <id>] disable")                           \
23687 _(ip_source_and_port_range_check_add_del,                               \
23688   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23689 _(ip_source_and_port_range_check_interface_add_del,                     \
23690   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23691   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23692 _(ipsec_gre_add_del_tunnel,                                             \
23693   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23694 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23695 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23696 _(l2_interface_pbb_tag_rewrite,                                         \
23697   "<intfc> | sw_if_index <nn> \n"                                       \
23698   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23699   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23700 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23701 _(flow_classify_set_interface,                                          \
23702   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23703 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23704 _(ip_fib_dump, "")                                                      \
23705 _(ip_mfib_dump, "")                                                     \
23706 _(ip6_fib_dump, "")                                                     \
23707 _(ip6_mfib_dump, "")                                                    \
23708 _(feature_enable_disable, "arc_name <arc_name> "                        \
23709   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23710 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23711 "[disable]")                                                            \
23712 _(l2_xconnect_dump, "")                                                 \
23713 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23714 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23715 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23716 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23717 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23718 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23719 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23720   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23721 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23722 _(memfd_segment_create,"size <nnn>")                                    \
23723 _(sock_init_shm, "size <nnn>")                                          \
23724 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23725 _(dns_enable_disable, "[enable][disable]")                              \
23726 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23727 _(dns_resolve_name, "<hostname>")                                       \
23728 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23729 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23730 _(dns_resolve_name, "<hostname>")                                       \
23731 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23732   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23733 _(session_rules_dump, "")                                               \
23734 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23735 _(output_acl_set_interface,                                             \
23736   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23737   "  [l2-table <nn>] [del]")                                            \
23738
23739 /* List of command functions, CLI names map directly to functions */
23740 #define foreach_cli_function                                    \
23741 _(comment, "usage: comment <ignore-rest-of-line>")              \
23742 _(dump_interface_table, "usage: dump_interface_table")          \
23743 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23744 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23745 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23746 _(dump_stats_table, "usage: dump_stats_table")                  \
23747 _(dump_macro_table, "usage: dump_macro_table ")                 \
23748 _(dump_node_table, "usage: dump_node_table")                    \
23749 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23750 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23751 _(echo, "usage: echo <message>")                                \
23752 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23753 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23754 _(help, "usage: help")                                          \
23755 _(q, "usage: quit")                                             \
23756 _(quit, "usage: quit")                                          \
23757 _(search_node_table, "usage: search_node_table <name>...")      \
23758 _(set, "usage: set <variable-name> <value>")                    \
23759 _(script, "usage: script <file-name>")                          \
23760 _(unset, "usage: unset <variable-name>")
23761 #define _(N,n)                                  \
23762     static void vl_api_##n##_t_handler_uni      \
23763     (vl_api_##n##_t * mp)                       \
23764     {                                           \
23765         vat_main_t * vam = &vat_main;           \
23766         if (vam->json_output) {                 \
23767             vl_api_##n##_t_handler_json(mp);    \
23768         } else {                                \
23769             vl_api_##n##_t_handler(mp);         \
23770         }                                       \
23771     }
23772 foreach_vpe_api_reply_msg;
23773 #if VPP_API_TEST_BUILTIN == 0
23774 foreach_standalone_reply_msg;
23775 #endif
23776 #undef _
23777
23778 void
23779 vat_api_hookup (vat_main_t * vam)
23780 {
23781 #define _(N,n)                                                  \
23782     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23783                            vl_api_##n##_t_handler_uni,          \
23784                            vl_noop_handler,                     \
23785                            vl_api_##n##_t_endian,               \
23786                            vl_api_##n##_t_print,                \
23787                            sizeof(vl_api_##n##_t), 1);
23788   foreach_vpe_api_reply_msg;
23789 #if VPP_API_TEST_BUILTIN == 0
23790   foreach_standalone_reply_msg;
23791 #endif
23792 #undef _
23793
23794 #if (VPP_API_TEST_BUILTIN==0)
23795   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23796
23797   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23798
23799   vam->function_by_name = hash_create_string (0, sizeof (uword));
23800
23801   vam->help_by_name = hash_create_string (0, sizeof (uword));
23802 #endif
23803
23804   /* API messages we can send */
23805 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23806   foreach_vpe_api_msg;
23807 #undef _
23808
23809   /* Help strings */
23810 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23811   foreach_vpe_api_msg;
23812 #undef _
23813
23814   /* CLI functions */
23815 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23816   foreach_cli_function;
23817 #undef _
23818
23819   /* Help strings */
23820 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23821   foreach_cli_function;
23822 #undef _
23823 }
23824
23825 #if VPP_API_TEST_BUILTIN
23826 static clib_error_t *
23827 vat_api_hookup_shim (vlib_main_t * vm)
23828 {
23829   vat_api_hookup (&vat_main);
23830   return 0;
23831 }
23832
23833 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23834 #endif
23835
23836 /*
23837  * fd.io coding-style-patch-verification: ON
23838  *
23839  * Local Variables:
23840  * eval: (c-set-style "gnu")
23841  * End:
23842  */