Implement ip_probe_neighbor API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <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   int ret;
15289
15290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15291     {
15292       if (unformat (i, "del"))
15293         is_add = 0;
15294       else if (unformat (i, "esn"))
15295         esn = 1;
15296       else if (unformat (i, "anti_replay"))
15297         anti_replay = 1;
15298       else if (unformat (i, "local_spi %d", &local_spi))
15299         ;
15300       else if (unformat (i, "remote_spi %d", &remote_spi))
15301         ;
15302       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15303         ;
15304       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15305         ;
15306       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15307         ;
15308       else
15309         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15310         ;
15311       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15312         ;
15313       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15314         ;
15315       else
15316         if (unformat
15317             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15318         {
15319           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
15320               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15321             {
15322               errmsg ("unsupported crypto-alg: '%U'\n",
15323                       format_ipsec_crypto_alg, crypto_alg);
15324               return -99;
15325             }
15326         }
15327       else
15328         if (unformat
15329             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15330         {
15331           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
15332               integ_alg >= IPSEC_INTEG_N_ALG)
15333             {
15334               errmsg ("unsupported integ-alg: '%U'\n",
15335                       format_ipsec_integ_alg, integ_alg);
15336               return -99;
15337             }
15338         }
15339       else
15340         {
15341           errmsg ("parse error '%U'\n", format_unformat_error, i);
15342           return -99;
15343         }
15344     }
15345
15346   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15347
15348   mp->is_add = is_add;
15349   mp->esn = esn;
15350   mp->anti_replay = anti_replay;
15351
15352   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15353   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15354
15355   mp->local_spi = htonl (local_spi);
15356   mp->remote_spi = htonl (remote_spi);
15357   mp->crypto_alg = (u8) crypto_alg;
15358
15359   mp->local_crypto_key_len = 0;
15360   if (lck)
15361     {
15362       mp->local_crypto_key_len = vec_len (lck);
15363       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15364         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15365       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15366     }
15367
15368   mp->remote_crypto_key_len = 0;
15369   if (rck)
15370     {
15371       mp->remote_crypto_key_len = vec_len (rck);
15372       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15373         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15374       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15375     }
15376
15377   mp->integ_alg = (u8) integ_alg;
15378
15379   mp->local_integ_key_len = 0;
15380   if (lik)
15381     {
15382       mp->local_integ_key_len = vec_len (lik);
15383       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15384         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15385       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15386     }
15387
15388   mp->remote_integ_key_len = 0;
15389   if (rik)
15390     {
15391       mp->remote_integ_key_len = vec_len (rik);
15392       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15393         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15394       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15395     }
15396
15397   S (mp);
15398   W (ret);
15399   return ret;
15400 }
15401
15402 static void
15403 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15404 {
15405   vat_main_t *vam = &vat_main;
15406
15407   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15408          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15409          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15410          "tunnel_src_addr %U tunnel_dst_addr %U "
15411          "salt %u seq_outbound %lu last_seq_inbound %lu "
15412          "replay_window %lu total_data_size %lu\n",
15413          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15414          mp->protocol,
15415          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15416          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15417          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15418          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15419          mp->tunnel_src_addr,
15420          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15421          mp->tunnel_dst_addr,
15422          ntohl (mp->salt),
15423          clib_net_to_host_u64 (mp->seq_outbound),
15424          clib_net_to_host_u64 (mp->last_seq_inbound),
15425          clib_net_to_host_u64 (mp->replay_window),
15426          clib_net_to_host_u64 (mp->total_data_size));
15427 }
15428
15429 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15430 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15431
15432 static void vl_api_ipsec_sa_details_t_handler_json
15433   (vl_api_ipsec_sa_details_t * mp)
15434 {
15435   vat_main_t *vam = &vat_main;
15436   vat_json_node_t *node = NULL;
15437   struct in_addr src_ip4, dst_ip4;
15438   struct in6_addr src_ip6, dst_ip6;
15439
15440   if (VAT_JSON_ARRAY != vam->json_tree.type)
15441     {
15442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15443       vat_json_init_array (&vam->json_tree);
15444     }
15445   node = vat_json_array_add (&vam->json_tree);
15446
15447   vat_json_init_object (node);
15448   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15449   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15450   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15451   vat_json_object_add_uint (node, "proto", mp->protocol);
15452   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15453   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15454   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15455   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15456   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15457   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15458   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15459                              mp->crypto_key_len);
15460   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15461                              mp->integ_key_len);
15462   if (mp->is_tunnel_ip6)
15463     {
15464       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15465       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15466       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15467       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15468     }
15469   else
15470     {
15471       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15472       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15473       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15474       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15475     }
15476   vat_json_object_add_uint (node, "replay_window",
15477                             clib_net_to_host_u64 (mp->replay_window));
15478   vat_json_object_add_uint (node, "total_data_size",
15479                             clib_net_to_host_u64 (mp->total_data_size));
15480
15481 }
15482
15483 static int
15484 api_ipsec_sa_dump (vat_main_t * vam)
15485 {
15486   unformat_input_t *i = vam->input;
15487   vl_api_ipsec_sa_dump_t *mp;
15488   vl_api_control_ping_t *mp_ping;
15489   u32 sa_id = ~0;
15490   int ret;
15491
15492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (i, "sa_id %d", &sa_id))
15495         ;
15496       else
15497         {
15498           clib_warning ("parse error '%U'", format_unformat_error, i);
15499           return -99;
15500         }
15501     }
15502
15503   M (IPSEC_SA_DUMP, mp);
15504
15505   mp->sa_id = ntohl (sa_id);
15506
15507   S (mp);
15508
15509   /* Use a control ping for synchronization */
15510   M (CONTROL_PING, mp_ping);
15511   S (mp_ping);
15512
15513   W (ret);
15514   return ret;
15515 }
15516
15517 static int
15518 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15519 {
15520   unformat_input_t *i = vam->input;
15521   vl_api_ipsec_tunnel_if_set_key_t *mp;
15522   u32 sw_if_index = ~0;
15523   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15524   u8 *key = 0;
15525   u32 alg = ~0;
15526   int ret;
15527
15528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15529     {
15530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15531         ;
15532       else
15533         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15534         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15535       else
15536         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15537         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15538       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15539         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15540       else
15541         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15542         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15543       else if (unformat (i, "%U", unformat_hex_string, &key))
15544         ;
15545       else
15546         {
15547           clib_warning ("parse error '%U'", format_unformat_error, i);
15548           return -99;
15549         }
15550     }
15551
15552   if (sw_if_index == ~0)
15553     {
15554       errmsg ("interface must be specified");
15555       return -99;
15556     }
15557
15558   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15559     {
15560       errmsg ("key type must be specified");
15561       return -99;
15562     }
15563
15564   if (alg == ~0)
15565     {
15566       errmsg ("algorithm must be specified");
15567       return -99;
15568     }
15569
15570   if (vec_len (key) == 0)
15571     {
15572       errmsg ("key must be specified");
15573       return -99;
15574     }
15575
15576   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15577
15578   mp->sw_if_index = htonl (sw_if_index);
15579   mp->alg = alg;
15580   mp->key_type = key_type;
15581   mp->key_len = vec_len (key);
15582   clib_memcpy (mp->key, key, vec_len (key));
15583
15584   S (mp);
15585   W (ret);
15586
15587   return ret;
15588 }
15589
15590 static int
15591 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15592 {
15593   unformat_input_t *i = vam->input;
15594   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15595   u32 sw_if_index = ~0;
15596   u32 sa_id = ~0;
15597   u8 is_outbound = (u8) ~ 0;
15598   int ret;
15599
15600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15601     {
15602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15603         ;
15604       else if (unformat (i, "sa_id %d", &sa_id))
15605         ;
15606       else if (unformat (i, "outbound"))
15607         is_outbound = 1;
15608       else if (unformat (i, "inbound"))
15609         is_outbound = 0;
15610       else
15611         {
15612           clib_warning ("parse error '%U'", format_unformat_error, i);
15613           return -99;
15614         }
15615     }
15616
15617   if (sw_if_index == ~0)
15618     {
15619       errmsg ("interface must be specified");
15620       return -99;
15621     }
15622
15623   if (sa_id == ~0)
15624     {
15625       errmsg ("SA ID must be specified");
15626       return -99;
15627     }
15628
15629   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15630
15631   mp->sw_if_index = htonl (sw_if_index);
15632   mp->sa_id = htonl (sa_id);
15633   mp->is_outbound = is_outbound;
15634
15635   S (mp);
15636   W (ret);
15637
15638   return ret;
15639 }
15640
15641 static int
15642 api_ikev2_profile_add_del (vat_main_t * vam)
15643 {
15644   unformat_input_t *i = vam->input;
15645   vl_api_ikev2_profile_add_del_t *mp;
15646   u8 is_add = 1;
15647   u8 *name = 0;
15648   int ret;
15649
15650   const char *valid_chars = "a-zA-Z0-9_";
15651
15652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15653     {
15654       if (unformat (i, "del"))
15655         is_add = 0;
15656       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15657         vec_add1 (name, 0);
15658       else
15659         {
15660           errmsg ("parse error '%U'", format_unformat_error, i);
15661           return -99;
15662         }
15663     }
15664
15665   if (!vec_len (name))
15666     {
15667       errmsg ("profile name must be specified");
15668       return -99;
15669     }
15670
15671   if (vec_len (name) > 64)
15672     {
15673       errmsg ("profile name too long");
15674       return -99;
15675     }
15676
15677   M (IKEV2_PROFILE_ADD_DEL, mp);
15678
15679   clib_memcpy (mp->name, name, vec_len (name));
15680   mp->is_add = is_add;
15681   vec_free (name);
15682
15683   S (mp);
15684   W (ret);
15685   return ret;
15686 }
15687
15688 static int
15689 api_ikev2_profile_set_auth (vat_main_t * vam)
15690 {
15691   unformat_input_t *i = vam->input;
15692   vl_api_ikev2_profile_set_auth_t *mp;
15693   u8 *name = 0;
15694   u8 *data = 0;
15695   u32 auth_method = 0;
15696   u8 is_hex = 0;
15697   int ret;
15698
15699   const char *valid_chars = "a-zA-Z0-9_";
15700
15701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15704         vec_add1 (name, 0);
15705       else if (unformat (i, "auth_method %U",
15706                          unformat_ikev2_auth_method, &auth_method))
15707         ;
15708       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15709         is_hex = 1;
15710       else if (unformat (i, "auth_data %v", &data))
15711         ;
15712       else
15713         {
15714           errmsg ("parse error '%U'", format_unformat_error, i);
15715           return -99;
15716         }
15717     }
15718
15719   if (!vec_len (name))
15720     {
15721       errmsg ("profile name must be specified");
15722       return -99;
15723     }
15724
15725   if (vec_len (name) > 64)
15726     {
15727       errmsg ("profile name too long");
15728       return -99;
15729     }
15730
15731   if (!vec_len (data))
15732     {
15733       errmsg ("auth_data must be specified");
15734       return -99;
15735     }
15736
15737   if (!auth_method)
15738     {
15739       errmsg ("auth_method must be specified");
15740       return -99;
15741     }
15742
15743   M (IKEV2_PROFILE_SET_AUTH, mp);
15744
15745   mp->is_hex = is_hex;
15746   mp->auth_method = (u8) auth_method;
15747   mp->data_len = vec_len (data);
15748   clib_memcpy (mp->name, name, vec_len (name));
15749   clib_memcpy (mp->data, data, vec_len (data));
15750   vec_free (name);
15751   vec_free (data);
15752
15753   S (mp);
15754   W (ret);
15755   return ret;
15756 }
15757
15758 static int
15759 api_ikev2_profile_set_id (vat_main_t * vam)
15760 {
15761   unformat_input_t *i = vam->input;
15762   vl_api_ikev2_profile_set_id_t *mp;
15763   u8 *name = 0;
15764   u8 *data = 0;
15765   u8 is_local = 0;
15766   u32 id_type = 0;
15767   ip4_address_t ip4;
15768   int ret;
15769
15770   const char *valid_chars = "a-zA-Z0-9_";
15771
15772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15773     {
15774       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15775         vec_add1 (name, 0);
15776       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15777         ;
15778       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15779         {
15780           data = vec_new (u8, 4);
15781           clib_memcpy (data, ip4.as_u8, 4);
15782         }
15783       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15784         ;
15785       else if (unformat (i, "id_data %v", &data))
15786         ;
15787       else if (unformat (i, "local"))
15788         is_local = 1;
15789       else if (unformat (i, "remote"))
15790         is_local = 0;
15791       else
15792         {
15793           errmsg ("parse error '%U'", format_unformat_error, i);
15794           return -99;
15795         }
15796     }
15797
15798   if (!vec_len (name))
15799     {
15800       errmsg ("profile name must be specified");
15801       return -99;
15802     }
15803
15804   if (vec_len (name) > 64)
15805     {
15806       errmsg ("profile name too long");
15807       return -99;
15808     }
15809
15810   if (!vec_len (data))
15811     {
15812       errmsg ("id_data must be specified");
15813       return -99;
15814     }
15815
15816   if (!id_type)
15817     {
15818       errmsg ("id_type must be specified");
15819       return -99;
15820     }
15821
15822   M (IKEV2_PROFILE_SET_ID, mp);
15823
15824   mp->is_local = is_local;
15825   mp->id_type = (u8) id_type;
15826   mp->data_len = vec_len (data);
15827   clib_memcpy (mp->name, name, vec_len (name));
15828   clib_memcpy (mp->data, data, vec_len (data));
15829   vec_free (name);
15830   vec_free (data);
15831
15832   S (mp);
15833   W (ret);
15834   return ret;
15835 }
15836
15837 static int
15838 api_ikev2_profile_set_ts (vat_main_t * vam)
15839 {
15840   unformat_input_t *i = vam->input;
15841   vl_api_ikev2_profile_set_ts_t *mp;
15842   u8 *name = 0;
15843   u8 is_local = 0;
15844   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15845   ip4_address_t start_addr, end_addr;
15846
15847   const char *valid_chars = "a-zA-Z0-9_";
15848   int ret;
15849
15850   start_addr.as_u32 = 0;
15851   end_addr.as_u32 = (u32) ~ 0;
15852
15853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15854     {
15855       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15856         vec_add1 (name, 0);
15857       else if (unformat (i, "protocol %d", &proto))
15858         ;
15859       else if (unformat (i, "start_port %d", &start_port))
15860         ;
15861       else if (unformat (i, "end_port %d", &end_port))
15862         ;
15863       else
15864         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15865         ;
15866       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15867         ;
15868       else if (unformat (i, "local"))
15869         is_local = 1;
15870       else if (unformat (i, "remote"))
15871         is_local = 0;
15872       else
15873         {
15874           errmsg ("parse error '%U'", format_unformat_error, i);
15875           return -99;
15876         }
15877     }
15878
15879   if (!vec_len (name))
15880     {
15881       errmsg ("profile name must be specified");
15882       return -99;
15883     }
15884
15885   if (vec_len (name) > 64)
15886     {
15887       errmsg ("profile name too long");
15888       return -99;
15889     }
15890
15891   M (IKEV2_PROFILE_SET_TS, mp);
15892
15893   mp->is_local = is_local;
15894   mp->proto = (u8) proto;
15895   mp->start_port = (u16) start_port;
15896   mp->end_port = (u16) end_port;
15897   mp->start_addr = start_addr.as_u32;
15898   mp->end_addr = end_addr.as_u32;
15899   clib_memcpy (mp->name, name, vec_len (name));
15900   vec_free (name);
15901
15902   S (mp);
15903   W (ret);
15904   return ret;
15905 }
15906
15907 static int
15908 api_ikev2_set_local_key (vat_main_t * vam)
15909 {
15910   unformat_input_t *i = vam->input;
15911   vl_api_ikev2_set_local_key_t *mp;
15912   u8 *file = 0;
15913   int ret;
15914
15915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15916     {
15917       if (unformat (i, "file %v", &file))
15918         vec_add1 (file, 0);
15919       else
15920         {
15921           errmsg ("parse error '%U'", format_unformat_error, i);
15922           return -99;
15923         }
15924     }
15925
15926   if (!vec_len (file))
15927     {
15928       errmsg ("RSA key file must be specified");
15929       return -99;
15930     }
15931
15932   if (vec_len (file) > 256)
15933     {
15934       errmsg ("file name too long");
15935       return -99;
15936     }
15937
15938   M (IKEV2_SET_LOCAL_KEY, mp);
15939
15940   clib_memcpy (mp->key_file, file, vec_len (file));
15941   vec_free (file);
15942
15943   S (mp);
15944   W (ret);
15945   return ret;
15946 }
15947
15948 static int
15949 api_ikev2_set_responder (vat_main_t * vam)
15950 {
15951   unformat_input_t *i = vam->input;
15952   vl_api_ikev2_set_responder_t *mp;
15953   int ret;
15954   u8 *name = 0;
15955   u32 sw_if_index = ~0;
15956   ip4_address_t address;
15957
15958   const char *valid_chars = "a-zA-Z0-9_";
15959
15960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15961     {
15962       if (unformat
15963           (i, "%U interface %d address %U", unformat_token, valid_chars,
15964            &name, &sw_if_index, unformat_ip4_address, &address))
15965         vec_add1 (name, 0);
15966       else
15967         {
15968           errmsg ("parse error '%U'", format_unformat_error, i);
15969           return -99;
15970         }
15971     }
15972
15973   if (!vec_len (name))
15974     {
15975       errmsg ("profile name must be specified");
15976       return -99;
15977     }
15978
15979   if (vec_len (name) > 64)
15980     {
15981       errmsg ("profile name too long");
15982       return -99;
15983     }
15984
15985   M (IKEV2_SET_RESPONDER, mp);
15986
15987   clib_memcpy (mp->name, name, vec_len (name));
15988   vec_free (name);
15989
15990   mp->sw_if_index = sw_if_index;
15991   clib_memcpy (mp->address, &address, sizeof (address));
15992
15993   S (mp);
15994   W (ret);
15995   return ret;
15996 }
15997
15998 static int
15999 api_ikev2_set_ike_transforms (vat_main_t * vam)
16000 {
16001   unformat_input_t *i = vam->input;
16002   vl_api_ikev2_set_ike_transforms_t *mp;
16003   int ret;
16004   u8 *name = 0;
16005   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16006
16007   const char *valid_chars = "a-zA-Z0-9_";
16008
16009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16010     {
16011       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16012                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16013         vec_add1 (name, 0);
16014       else
16015         {
16016           errmsg ("parse error '%U'", format_unformat_error, i);
16017           return -99;
16018         }
16019     }
16020
16021   if (!vec_len (name))
16022     {
16023       errmsg ("profile name must be specified");
16024       return -99;
16025     }
16026
16027   if (vec_len (name) > 64)
16028     {
16029       errmsg ("profile name too long");
16030       return -99;
16031     }
16032
16033   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16034
16035   clib_memcpy (mp->name, name, vec_len (name));
16036   vec_free (name);
16037   mp->crypto_alg = crypto_alg;
16038   mp->crypto_key_size = crypto_key_size;
16039   mp->integ_alg = integ_alg;
16040   mp->dh_group = dh_group;
16041
16042   S (mp);
16043   W (ret);
16044   return ret;
16045 }
16046
16047
16048 static int
16049 api_ikev2_set_esp_transforms (vat_main_t * vam)
16050 {
16051   unformat_input_t *i = vam->input;
16052   vl_api_ikev2_set_esp_transforms_t *mp;
16053   int ret;
16054   u8 *name = 0;
16055   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16056
16057   const char *valid_chars = "a-zA-Z0-9_";
16058
16059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16062                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16063         vec_add1 (name, 0);
16064       else
16065         {
16066           errmsg ("parse error '%U'", format_unformat_error, i);
16067           return -99;
16068         }
16069     }
16070
16071   if (!vec_len (name))
16072     {
16073       errmsg ("profile name must be specified");
16074       return -99;
16075     }
16076
16077   if (vec_len (name) > 64)
16078     {
16079       errmsg ("profile name too long");
16080       return -99;
16081     }
16082
16083   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16084
16085   clib_memcpy (mp->name, name, vec_len (name));
16086   vec_free (name);
16087   mp->crypto_alg = crypto_alg;
16088   mp->crypto_key_size = crypto_key_size;
16089   mp->integ_alg = integ_alg;
16090   mp->dh_group = dh_group;
16091
16092   S (mp);
16093   W (ret);
16094   return ret;
16095 }
16096
16097 static int
16098 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16099 {
16100   unformat_input_t *i = vam->input;
16101   vl_api_ikev2_set_sa_lifetime_t *mp;
16102   int ret;
16103   u8 *name = 0;
16104   u64 lifetime, lifetime_maxdata;
16105   u32 lifetime_jitter, handover;
16106
16107   const char *valid_chars = "a-zA-Z0-9_";
16108
16109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16110     {
16111       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16112                     &lifetime, &lifetime_jitter, &handover,
16113                     &lifetime_maxdata))
16114         vec_add1 (name, 0);
16115       else
16116         {
16117           errmsg ("parse error '%U'", format_unformat_error, i);
16118           return -99;
16119         }
16120     }
16121
16122   if (!vec_len (name))
16123     {
16124       errmsg ("profile name must be specified");
16125       return -99;
16126     }
16127
16128   if (vec_len (name) > 64)
16129     {
16130       errmsg ("profile name too long");
16131       return -99;
16132     }
16133
16134   M (IKEV2_SET_SA_LIFETIME, mp);
16135
16136   clib_memcpy (mp->name, name, vec_len (name));
16137   vec_free (name);
16138   mp->lifetime = lifetime;
16139   mp->lifetime_jitter = lifetime_jitter;
16140   mp->handover = handover;
16141   mp->lifetime_maxdata = lifetime_maxdata;
16142
16143   S (mp);
16144   W (ret);
16145   return ret;
16146 }
16147
16148 static int
16149 api_ikev2_initiate_sa_init (vat_main_t * vam)
16150 {
16151   unformat_input_t *i = vam->input;
16152   vl_api_ikev2_initiate_sa_init_t *mp;
16153   int ret;
16154   u8 *name = 0;
16155
16156   const char *valid_chars = "a-zA-Z0-9_";
16157
16158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16159     {
16160       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16161         vec_add1 (name, 0);
16162       else
16163         {
16164           errmsg ("parse error '%U'", format_unformat_error, i);
16165           return -99;
16166         }
16167     }
16168
16169   if (!vec_len (name))
16170     {
16171       errmsg ("profile name must be specified");
16172       return -99;
16173     }
16174
16175   if (vec_len (name) > 64)
16176     {
16177       errmsg ("profile name too long");
16178       return -99;
16179     }
16180
16181   M (IKEV2_INITIATE_SA_INIT, mp);
16182
16183   clib_memcpy (mp->name, name, vec_len (name));
16184   vec_free (name);
16185
16186   S (mp);
16187   W (ret);
16188   return ret;
16189 }
16190
16191 static int
16192 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16193 {
16194   unformat_input_t *i = vam->input;
16195   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16196   int ret;
16197   u64 ispi;
16198
16199
16200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16201     {
16202       if (unformat (i, "%lx", &ispi))
16203         ;
16204       else
16205         {
16206           errmsg ("parse error '%U'", format_unformat_error, i);
16207           return -99;
16208         }
16209     }
16210
16211   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16212
16213   mp->ispi = ispi;
16214
16215   S (mp);
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16222 {
16223   unformat_input_t *i = vam->input;
16224   vl_api_ikev2_initiate_del_child_sa_t *mp;
16225   int ret;
16226   u32 ispi;
16227
16228
16229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16230     {
16231       if (unformat (i, "%x", &ispi))
16232         ;
16233       else
16234         {
16235           errmsg ("parse error '%U'", format_unformat_error, i);
16236           return -99;
16237         }
16238     }
16239
16240   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16241
16242   mp->ispi = ispi;
16243
16244   S (mp);
16245   W (ret);
16246   return ret;
16247 }
16248
16249 static int
16250 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16251 {
16252   unformat_input_t *i = vam->input;
16253   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16254   int ret;
16255   u32 ispi;
16256
16257
16258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16259     {
16260       if (unformat (i, "%x", &ispi))
16261         ;
16262       else
16263         {
16264           errmsg ("parse error '%U'", format_unformat_error, i);
16265           return -99;
16266         }
16267     }
16268
16269   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16270
16271   mp->ispi = ispi;
16272
16273   S (mp);
16274   W (ret);
16275   return ret;
16276 }
16277
16278 /*
16279  * MAP
16280  */
16281 static int
16282 api_map_add_domain (vat_main_t * vam)
16283 {
16284   unformat_input_t *i = vam->input;
16285   vl_api_map_add_domain_t *mp;
16286
16287   ip4_address_t ip4_prefix;
16288   ip6_address_t ip6_prefix;
16289   ip6_address_t ip6_src;
16290   u32 num_m_args = 0;
16291   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16292     0, psid_length = 0;
16293   u8 is_translation = 0;
16294   u32 mtu = 0;
16295   u32 ip6_src_len = 128;
16296   int ret;
16297
16298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16299     {
16300       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16301                     &ip4_prefix, &ip4_prefix_len))
16302         num_m_args++;
16303       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16304                          &ip6_prefix, &ip6_prefix_len))
16305         num_m_args++;
16306       else
16307         if (unformat
16308             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16309              &ip6_src_len))
16310         num_m_args++;
16311       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16312         num_m_args++;
16313       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16314         num_m_args++;
16315       else if (unformat (i, "psid-offset %d", &psid_offset))
16316         num_m_args++;
16317       else if (unformat (i, "psid-len %d", &psid_length))
16318         num_m_args++;
16319       else if (unformat (i, "mtu %d", &mtu))
16320         num_m_args++;
16321       else if (unformat (i, "map-t"))
16322         is_translation = 1;
16323       else
16324         {
16325           clib_warning ("parse error '%U'", format_unformat_error, i);
16326           return -99;
16327         }
16328     }
16329
16330   if (num_m_args < 3)
16331     {
16332       errmsg ("mandatory argument(s) missing");
16333       return -99;
16334     }
16335
16336   /* Construct the API message */
16337   M (MAP_ADD_DOMAIN, mp);
16338
16339   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16340   mp->ip4_prefix_len = ip4_prefix_len;
16341
16342   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16343   mp->ip6_prefix_len = ip6_prefix_len;
16344
16345   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16346   mp->ip6_src_prefix_len = ip6_src_len;
16347
16348   mp->ea_bits_len = ea_bits_len;
16349   mp->psid_offset = psid_offset;
16350   mp->psid_length = psid_length;
16351   mp->is_translation = is_translation;
16352   mp->mtu = htons (mtu);
16353
16354   /* send it... */
16355   S (mp);
16356
16357   /* Wait for a reply, return good/bad news  */
16358   W (ret);
16359   return ret;
16360 }
16361
16362 static int
16363 api_map_del_domain (vat_main_t * vam)
16364 {
16365   unformat_input_t *i = vam->input;
16366   vl_api_map_del_domain_t *mp;
16367
16368   u32 num_m_args = 0;
16369   u32 index;
16370   int ret;
16371
16372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (i, "index %d", &index))
16375         num_m_args++;
16376       else
16377         {
16378           clib_warning ("parse error '%U'", format_unformat_error, i);
16379           return -99;
16380         }
16381     }
16382
16383   if (num_m_args != 1)
16384     {
16385       errmsg ("mandatory argument(s) missing");
16386       return -99;
16387     }
16388
16389   /* Construct the API message */
16390   M (MAP_DEL_DOMAIN, mp);
16391
16392   mp->index = ntohl (index);
16393
16394   /* send it... */
16395   S (mp);
16396
16397   /* Wait for a reply, return good/bad news  */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_map_add_del_rule (vat_main_t * vam)
16404 {
16405   unformat_input_t *i = vam->input;
16406   vl_api_map_add_del_rule_t *mp;
16407   u8 is_add = 1;
16408   ip6_address_t ip6_dst;
16409   u32 num_m_args = 0, index, psid = 0;
16410   int ret;
16411
16412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16413     {
16414       if (unformat (i, "index %d", &index))
16415         num_m_args++;
16416       else if (unformat (i, "psid %d", &psid))
16417         num_m_args++;
16418       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16419         num_m_args++;
16420       else if (unformat (i, "del"))
16421         {
16422           is_add = 0;
16423         }
16424       else
16425         {
16426           clib_warning ("parse error '%U'", format_unformat_error, i);
16427           return -99;
16428         }
16429     }
16430
16431   /* Construct the API message */
16432   M (MAP_ADD_DEL_RULE, mp);
16433
16434   mp->index = ntohl (index);
16435   mp->is_add = is_add;
16436   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16437   mp->psid = ntohs (psid);
16438
16439   /* send it... */
16440   S (mp);
16441
16442   /* Wait for a reply, return good/bad news  */
16443   W (ret);
16444   return ret;
16445 }
16446
16447 static int
16448 api_map_domain_dump (vat_main_t * vam)
16449 {
16450   vl_api_map_domain_dump_t *mp;
16451   vl_api_control_ping_t *mp_ping;
16452   int ret;
16453
16454   /* Construct the API message */
16455   M (MAP_DOMAIN_DUMP, mp);
16456
16457   /* send it... */
16458   S (mp);
16459
16460   /* Use a control ping for synchronization */
16461   MPING (CONTROL_PING, mp_ping);
16462   S (mp_ping);
16463
16464   W (ret);
16465   return ret;
16466 }
16467
16468 static int
16469 api_map_rule_dump (vat_main_t * vam)
16470 {
16471   unformat_input_t *i = vam->input;
16472   vl_api_map_rule_dump_t *mp;
16473   vl_api_control_ping_t *mp_ping;
16474   u32 domain_index = ~0;
16475   int ret;
16476
16477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16478     {
16479       if (unformat (i, "index %u", &domain_index))
16480         ;
16481       else
16482         break;
16483     }
16484
16485   if (domain_index == ~0)
16486     {
16487       clib_warning ("parse error: domain index expected");
16488       return -99;
16489     }
16490
16491   /* Construct the API message */
16492   M (MAP_RULE_DUMP, mp);
16493
16494   mp->domain_index = htonl (domain_index);
16495
16496   /* send it... */
16497   S (mp);
16498
16499   /* Use a control ping for synchronization */
16500   MPING (CONTROL_PING, mp_ping);
16501   S (mp_ping);
16502
16503   W (ret);
16504   return ret;
16505 }
16506
16507 static void vl_api_map_add_domain_reply_t_handler
16508   (vl_api_map_add_domain_reply_t * mp)
16509 {
16510   vat_main_t *vam = &vat_main;
16511   i32 retval = ntohl (mp->retval);
16512
16513   if (vam->async_mode)
16514     {
16515       vam->async_errors += (retval < 0);
16516     }
16517   else
16518     {
16519       vam->retval = retval;
16520       vam->result_ready = 1;
16521     }
16522 }
16523
16524 static void vl_api_map_add_domain_reply_t_handler_json
16525   (vl_api_map_add_domain_reply_t * mp)
16526 {
16527   vat_main_t *vam = &vat_main;
16528   vat_json_node_t node;
16529
16530   vat_json_init_object (&node);
16531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16532   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16533
16534   vat_json_print (vam->ofp, &node);
16535   vat_json_free (&node);
16536
16537   vam->retval = ntohl (mp->retval);
16538   vam->result_ready = 1;
16539 }
16540
16541 static int
16542 api_get_first_msg_id (vat_main_t * vam)
16543 {
16544   vl_api_get_first_msg_id_t *mp;
16545   unformat_input_t *i = vam->input;
16546   u8 *name;
16547   u8 name_set = 0;
16548   int ret;
16549
16550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16551     {
16552       if (unformat (i, "client %s", &name))
16553         name_set = 1;
16554       else
16555         break;
16556     }
16557
16558   if (name_set == 0)
16559     {
16560       errmsg ("missing client name");
16561       return -99;
16562     }
16563   vec_add1 (name, 0);
16564
16565   if (vec_len (name) > 63)
16566     {
16567       errmsg ("client name too long");
16568       return -99;
16569     }
16570
16571   M (GET_FIRST_MSG_ID, mp);
16572   clib_memcpy (mp->name, name, vec_len (name));
16573   S (mp);
16574   W (ret);
16575   return ret;
16576 }
16577
16578 static int
16579 api_cop_interface_enable_disable (vat_main_t * vam)
16580 {
16581   unformat_input_t *line_input = vam->input;
16582   vl_api_cop_interface_enable_disable_t *mp;
16583   u32 sw_if_index = ~0;
16584   u8 enable_disable = 1;
16585   int ret;
16586
16587   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16588     {
16589       if (unformat (line_input, "disable"))
16590         enable_disable = 0;
16591       if (unformat (line_input, "enable"))
16592         enable_disable = 1;
16593       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16594                          vam, &sw_if_index))
16595         ;
16596       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16597         ;
16598       else
16599         break;
16600     }
16601
16602   if (sw_if_index == ~0)
16603     {
16604       errmsg ("missing interface name or sw_if_index");
16605       return -99;
16606     }
16607
16608   /* Construct the API message */
16609   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16610   mp->sw_if_index = ntohl (sw_if_index);
16611   mp->enable_disable = enable_disable;
16612
16613   /* send it... */
16614   S (mp);
16615   /* Wait for the reply */
16616   W (ret);
16617   return ret;
16618 }
16619
16620 static int
16621 api_cop_whitelist_enable_disable (vat_main_t * vam)
16622 {
16623   unformat_input_t *line_input = vam->input;
16624   vl_api_cop_whitelist_enable_disable_t *mp;
16625   u32 sw_if_index = ~0;
16626   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16627   u32 fib_id = 0;
16628   int ret;
16629
16630   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16631     {
16632       if (unformat (line_input, "ip4"))
16633         ip4 = 1;
16634       else if (unformat (line_input, "ip6"))
16635         ip6 = 1;
16636       else if (unformat (line_input, "default"))
16637         default_cop = 1;
16638       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16639                          vam, &sw_if_index))
16640         ;
16641       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16642         ;
16643       else if (unformat (line_input, "fib-id %d", &fib_id))
16644         ;
16645       else
16646         break;
16647     }
16648
16649   if (sw_if_index == ~0)
16650     {
16651       errmsg ("missing interface name or sw_if_index");
16652       return -99;
16653     }
16654
16655   /* Construct the API message */
16656   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16657   mp->sw_if_index = ntohl (sw_if_index);
16658   mp->fib_id = ntohl (fib_id);
16659   mp->ip4 = ip4;
16660   mp->ip6 = ip6;
16661   mp->default_cop = default_cop;
16662
16663   /* send it... */
16664   S (mp);
16665   /* Wait for the reply */
16666   W (ret);
16667   return ret;
16668 }
16669
16670 static int
16671 api_get_node_graph (vat_main_t * vam)
16672 {
16673   vl_api_get_node_graph_t *mp;
16674   int ret;
16675
16676   M (GET_NODE_GRAPH, mp);
16677
16678   /* send it... */
16679   S (mp);
16680   /* Wait for the reply */
16681   W (ret);
16682   return ret;
16683 }
16684
16685 /* *INDENT-OFF* */
16686 /** Used for parsing LISP eids */
16687 typedef CLIB_PACKED(struct{
16688   u8 addr[16];   /**< eid address */
16689   u32 len;       /**< prefix length if IP */
16690   u8 type;      /**< type of eid */
16691 }) lisp_eid_vat_t;
16692 /* *INDENT-ON* */
16693
16694 static uword
16695 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16696 {
16697   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16698
16699   memset (a, 0, sizeof (a[0]));
16700
16701   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16702     {
16703       a->type = 0;              /* ipv4 type */
16704     }
16705   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16706     {
16707       a->type = 1;              /* ipv6 type */
16708     }
16709   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16710     {
16711       a->type = 2;              /* mac type */
16712     }
16713   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16714     {
16715       a->type = 3;              /* NSH type */
16716       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16717       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16718     }
16719   else
16720     {
16721       return 0;
16722     }
16723
16724   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16725     {
16726       return 0;
16727     }
16728
16729   return 1;
16730 }
16731
16732 static int
16733 lisp_eid_size_vat (u8 type)
16734 {
16735   switch (type)
16736     {
16737     case 0:
16738       return 4;
16739     case 1:
16740       return 16;
16741     case 2:
16742       return 6;
16743     case 3:
16744       return 5;
16745     }
16746   return 0;
16747 }
16748
16749 static void
16750 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16751 {
16752   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16753 }
16754
16755 static int
16756 api_one_add_del_locator_set (vat_main_t * vam)
16757 {
16758   unformat_input_t *input = vam->input;
16759   vl_api_one_add_del_locator_set_t *mp;
16760   u8 is_add = 1;
16761   u8 *locator_set_name = NULL;
16762   u8 locator_set_name_set = 0;
16763   vl_api_local_locator_t locator, *locators = 0;
16764   u32 sw_if_index, priority, weight;
16765   u32 data_len = 0;
16766
16767   int ret;
16768   /* Parse args required to build the message */
16769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16770     {
16771       if (unformat (input, "del"))
16772         {
16773           is_add = 0;
16774         }
16775       else if (unformat (input, "locator-set %s", &locator_set_name))
16776         {
16777           locator_set_name_set = 1;
16778         }
16779       else if (unformat (input, "sw_if_index %u p %u w %u",
16780                          &sw_if_index, &priority, &weight))
16781         {
16782           locator.sw_if_index = htonl (sw_if_index);
16783           locator.priority = priority;
16784           locator.weight = weight;
16785           vec_add1 (locators, locator);
16786         }
16787       else
16788         if (unformat
16789             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
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         break;
16799     }
16800
16801   if (locator_set_name_set == 0)
16802     {
16803       errmsg ("missing locator-set name");
16804       vec_free (locators);
16805       return -99;
16806     }
16807
16808   if (vec_len (locator_set_name) > 64)
16809     {
16810       errmsg ("locator-set name too long");
16811       vec_free (locator_set_name);
16812       vec_free (locators);
16813       return -99;
16814     }
16815   vec_add1 (locator_set_name, 0);
16816
16817   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16818
16819   /* Construct the API message */
16820   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16821
16822   mp->is_add = is_add;
16823   clib_memcpy (mp->locator_set_name, locator_set_name,
16824                vec_len (locator_set_name));
16825   vec_free (locator_set_name);
16826
16827   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16828   if (locators)
16829     clib_memcpy (mp->locators, locators, data_len);
16830   vec_free (locators);
16831
16832   /* send it... */
16833   S (mp);
16834
16835   /* Wait for a reply... */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16841
16842 static int
16843 api_one_add_del_locator (vat_main_t * vam)
16844 {
16845   unformat_input_t *input = vam->input;
16846   vl_api_one_add_del_locator_t *mp;
16847   u32 tmp_if_index = ~0;
16848   u32 sw_if_index = ~0;
16849   u8 sw_if_index_set = 0;
16850   u8 sw_if_index_if_name_set = 0;
16851   u32 priority = ~0;
16852   u8 priority_set = 0;
16853   u32 weight = ~0;
16854   u8 weight_set = 0;
16855   u8 is_add = 1;
16856   u8 *locator_set_name = NULL;
16857   u8 locator_set_name_set = 0;
16858   int ret;
16859
16860   /* Parse args required to build the message */
16861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16862     {
16863       if (unformat (input, "del"))
16864         {
16865           is_add = 0;
16866         }
16867       else if (unformat (input, "locator-set %s", &locator_set_name))
16868         {
16869           locator_set_name_set = 1;
16870         }
16871       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16872                          &tmp_if_index))
16873         {
16874           sw_if_index_if_name_set = 1;
16875           sw_if_index = tmp_if_index;
16876         }
16877       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16878         {
16879           sw_if_index_set = 1;
16880           sw_if_index = tmp_if_index;
16881         }
16882       else if (unformat (input, "p %d", &priority))
16883         {
16884           priority_set = 1;
16885         }
16886       else if (unformat (input, "w %d", &weight))
16887         {
16888           weight_set = 1;
16889         }
16890       else
16891         break;
16892     }
16893
16894   if (locator_set_name_set == 0)
16895     {
16896       errmsg ("missing locator-set name");
16897       return -99;
16898     }
16899
16900   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16901     {
16902       errmsg ("missing sw_if_index");
16903       vec_free (locator_set_name);
16904       return -99;
16905     }
16906
16907   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16908     {
16909       errmsg ("cannot use both params interface name and sw_if_index");
16910       vec_free (locator_set_name);
16911       return -99;
16912     }
16913
16914   if (priority_set == 0)
16915     {
16916       errmsg ("missing locator-set priority");
16917       vec_free (locator_set_name);
16918       return -99;
16919     }
16920
16921   if (weight_set == 0)
16922     {
16923       errmsg ("missing locator-set weight");
16924       vec_free (locator_set_name);
16925       return -99;
16926     }
16927
16928   if (vec_len (locator_set_name) > 64)
16929     {
16930       errmsg ("locator-set name too long");
16931       vec_free (locator_set_name);
16932       return -99;
16933     }
16934   vec_add1 (locator_set_name, 0);
16935
16936   /* Construct the API message */
16937   M (ONE_ADD_DEL_LOCATOR, mp);
16938
16939   mp->is_add = is_add;
16940   mp->sw_if_index = ntohl (sw_if_index);
16941   mp->priority = priority;
16942   mp->weight = weight;
16943   clib_memcpy (mp->locator_set_name, locator_set_name,
16944                vec_len (locator_set_name));
16945   vec_free (locator_set_name);
16946
16947   /* send it... */
16948   S (mp);
16949
16950   /* Wait for a reply... */
16951   W (ret);
16952   return ret;
16953 }
16954
16955 #define api_lisp_add_del_locator api_one_add_del_locator
16956
16957 uword
16958 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16959 {
16960   u32 *key_id = va_arg (*args, u32 *);
16961   u8 *s = 0;
16962
16963   if (unformat (input, "%s", &s))
16964     {
16965       if (!strcmp ((char *) s, "sha1"))
16966         key_id[0] = HMAC_SHA_1_96;
16967       else if (!strcmp ((char *) s, "sha256"))
16968         key_id[0] = HMAC_SHA_256_128;
16969       else
16970         {
16971           clib_warning ("invalid key_id: '%s'", s);
16972           key_id[0] = HMAC_NO_KEY;
16973         }
16974     }
16975   else
16976     return 0;
16977
16978   vec_free (s);
16979   return 1;
16980 }
16981
16982 static int
16983 api_one_add_del_local_eid (vat_main_t * vam)
16984 {
16985   unformat_input_t *input = vam->input;
16986   vl_api_one_add_del_local_eid_t *mp;
16987   u8 is_add = 1;
16988   u8 eid_set = 0;
16989   lisp_eid_vat_t _eid, *eid = &_eid;
16990   u8 *locator_set_name = 0;
16991   u8 locator_set_name_set = 0;
16992   u32 vni = 0;
16993   u16 key_id = 0;
16994   u8 *key = 0;
16995   int ret;
16996
16997   /* Parse args required to build the message */
16998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16999     {
17000       if (unformat (input, "del"))
17001         {
17002           is_add = 0;
17003         }
17004       else if (unformat (input, "vni %d", &vni))
17005         {
17006           ;
17007         }
17008       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17009         {
17010           eid_set = 1;
17011         }
17012       else if (unformat (input, "locator-set %s", &locator_set_name))
17013         {
17014           locator_set_name_set = 1;
17015         }
17016       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17017         ;
17018       else if (unformat (input, "secret-key %_%v%_", &key))
17019         ;
17020       else
17021         break;
17022     }
17023
17024   if (locator_set_name_set == 0)
17025     {
17026       errmsg ("missing locator-set name");
17027       return -99;
17028     }
17029
17030   if (0 == eid_set)
17031     {
17032       errmsg ("EID address not set!");
17033       vec_free (locator_set_name);
17034       return -99;
17035     }
17036
17037   if (key && (0 == key_id))
17038     {
17039       errmsg ("invalid key_id!");
17040       return -99;
17041     }
17042
17043   if (vec_len (key) > 64)
17044     {
17045       errmsg ("key too long");
17046       vec_free (key);
17047       return -99;
17048     }
17049
17050   if (vec_len (locator_set_name) > 64)
17051     {
17052       errmsg ("locator-set name too long");
17053       vec_free (locator_set_name);
17054       return -99;
17055     }
17056   vec_add1 (locator_set_name, 0);
17057
17058   /* Construct the API message */
17059   M (ONE_ADD_DEL_LOCAL_EID, mp);
17060
17061   mp->is_add = is_add;
17062   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17063   mp->eid_type = eid->type;
17064   mp->prefix_len = eid->len;
17065   mp->vni = clib_host_to_net_u32 (vni);
17066   mp->key_id = clib_host_to_net_u16 (key_id);
17067   clib_memcpy (mp->locator_set_name, locator_set_name,
17068                vec_len (locator_set_name));
17069   clib_memcpy (mp->key, key, vec_len (key));
17070
17071   vec_free (locator_set_name);
17072   vec_free (key);
17073
17074   /* send it... */
17075   S (mp);
17076
17077   /* Wait for a reply... */
17078   W (ret);
17079   return ret;
17080 }
17081
17082 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17083
17084 static int
17085 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17086 {
17087   u32 dp_table = 0, vni = 0;;
17088   unformat_input_t *input = vam->input;
17089   vl_api_gpe_add_del_fwd_entry_t *mp;
17090   u8 is_add = 1;
17091   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17092   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17093   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17094   u32 action = ~0, w;
17095   ip4_address_t rmt_rloc4, lcl_rloc4;
17096   ip6_address_t rmt_rloc6, lcl_rloc6;
17097   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17098   int ret;
17099
17100   memset (&rloc, 0, sizeof (rloc));
17101
17102   /* Parse args required to build the message */
17103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17104     {
17105       if (unformat (input, "del"))
17106         is_add = 0;
17107       else if (unformat (input, "add"))
17108         is_add = 1;
17109       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17110         {
17111           rmt_eid_set = 1;
17112         }
17113       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17114         {
17115           lcl_eid_set = 1;
17116         }
17117       else if (unformat (input, "vrf %d", &dp_table))
17118         ;
17119       else if (unformat (input, "bd %d", &dp_table))
17120         ;
17121       else if (unformat (input, "vni %d", &vni))
17122         ;
17123       else if (unformat (input, "w %d", &w))
17124         {
17125           if (!curr_rloc)
17126             {
17127               errmsg ("No RLOC configured for setting priority/weight!");
17128               return -99;
17129             }
17130           curr_rloc->weight = w;
17131         }
17132       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17133                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17134         {
17135           rloc.is_ip4 = 1;
17136
17137           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17138           rloc.weight = 0;
17139           vec_add1 (lcl_locs, rloc);
17140
17141           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17142           vec_add1 (rmt_locs, rloc);
17143           /* weight saved in rmt loc */
17144           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17145         }
17146       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17147                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17148         {
17149           rloc.is_ip4 = 0;
17150           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17151           rloc.weight = 0;
17152           vec_add1 (lcl_locs, rloc);
17153
17154           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17155           vec_add1 (rmt_locs, rloc);
17156           /* weight saved in rmt loc */
17157           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17158         }
17159       else if (unformat (input, "action %d", &action))
17160         {
17161           ;
17162         }
17163       else
17164         {
17165           clib_warning ("parse error '%U'", format_unformat_error, input);
17166           return -99;
17167         }
17168     }
17169
17170   if (!rmt_eid_set)
17171     {
17172       errmsg ("remote eid addresses not set");
17173       return -99;
17174     }
17175
17176   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17177     {
17178       errmsg ("eid types don't match");
17179       return -99;
17180     }
17181
17182   if (0 == rmt_locs && (u32) ~ 0 == action)
17183     {
17184       errmsg ("action not set for negative mapping");
17185       return -99;
17186     }
17187
17188   /* Construct the API message */
17189   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17190       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17191
17192   mp->is_add = is_add;
17193   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17194   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17195   mp->eid_type = rmt_eid->type;
17196   mp->dp_table = clib_host_to_net_u32 (dp_table);
17197   mp->vni = clib_host_to_net_u32 (vni);
17198   mp->rmt_len = rmt_eid->len;
17199   mp->lcl_len = lcl_eid->len;
17200   mp->action = action;
17201
17202   if (0 != rmt_locs && 0 != lcl_locs)
17203     {
17204       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17205       clib_memcpy (mp->locs, lcl_locs,
17206                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17207
17208       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17209       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17210                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17211     }
17212   vec_free (lcl_locs);
17213   vec_free (rmt_locs);
17214
17215   /* send it... */
17216   S (mp);
17217
17218   /* Wait for a reply... */
17219   W (ret);
17220   return ret;
17221 }
17222
17223 static int
17224 api_one_add_del_map_server (vat_main_t * vam)
17225 {
17226   unformat_input_t *input = vam->input;
17227   vl_api_one_add_del_map_server_t *mp;
17228   u8 is_add = 1;
17229   u8 ipv4_set = 0;
17230   u8 ipv6_set = 0;
17231   ip4_address_t ipv4;
17232   ip6_address_t ipv6;
17233   int ret;
17234
17235   /* Parse args required to build the message */
17236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17237     {
17238       if (unformat (input, "del"))
17239         {
17240           is_add = 0;
17241         }
17242       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17243         {
17244           ipv4_set = 1;
17245         }
17246       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17247         {
17248           ipv6_set = 1;
17249         }
17250       else
17251         break;
17252     }
17253
17254   if (ipv4_set && ipv6_set)
17255     {
17256       errmsg ("both eid v4 and v6 addresses set");
17257       return -99;
17258     }
17259
17260   if (!ipv4_set && !ipv6_set)
17261     {
17262       errmsg ("eid addresses not set");
17263       return -99;
17264     }
17265
17266   /* Construct the API message */
17267   M (ONE_ADD_DEL_MAP_SERVER, mp);
17268
17269   mp->is_add = is_add;
17270   if (ipv6_set)
17271     {
17272       mp->is_ipv6 = 1;
17273       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17274     }
17275   else
17276     {
17277       mp->is_ipv6 = 0;
17278       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17279     }
17280
17281   /* send it... */
17282   S (mp);
17283
17284   /* Wait for a reply... */
17285   W (ret);
17286   return ret;
17287 }
17288
17289 #define api_lisp_add_del_map_server api_one_add_del_map_server
17290
17291 static int
17292 api_one_add_del_map_resolver (vat_main_t * vam)
17293 {
17294   unformat_input_t *input = vam->input;
17295   vl_api_one_add_del_map_resolver_t *mp;
17296   u8 is_add = 1;
17297   u8 ipv4_set = 0;
17298   u8 ipv6_set = 0;
17299   ip4_address_t ipv4;
17300   ip6_address_t ipv6;
17301   int ret;
17302
17303   /* Parse args required to build the message */
17304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17305     {
17306       if (unformat (input, "del"))
17307         {
17308           is_add = 0;
17309         }
17310       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17311         {
17312           ipv4_set = 1;
17313         }
17314       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17315         {
17316           ipv6_set = 1;
17317         }
17318       else
17319         break;
17320     }
17321
17322   if (ipv4_set && ipv6_set)
17323     {
17324       errmsg ("both eid v4 and v6 addresses set");
17325       return -99;
17326     }
17327
17328   if (!ipv4_set && !ipv6_set)
17329     {
17330       errmsg ("eid addresses not set");
17331       return -99;
17332     }
17333
17334   /* Construct the API message */
17335   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17336
17337   mp->is_add = is_add;
17338   if (ipv6_set)
17339     {
17340       mp->is_ipv6 = 1;
17341       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17342     }
17343   else
17344     {
17345       mp->is_ipv6 = 0;
17346       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17347     }
17348
17349   /* send it... */
17350   S (mp);
17351
17352   /* Wait for a reply... */
17353   W (ret);
17354   return ret;
17355 }
17356
17357 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17358
17359 static int
17360 api_lisp_gpe_enable_disable (vat_main_t * vam)
17361 {
17362   unformat_input_t *input = vam->input;
17363   vl_api_gpe_enable_disable_t *mp;
17364   u8 is_set = 0;
17365   u8 is_en = 1;
17366   int ret;
17367
17368   /* Parse args required to build the message */
17369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17370     {
17371       if (unformat (input, "enable"))
17372         {
17373           is_set = 1;
17374           is_en = 1;
17375         }
17376       else if (unformat (input, "disable"))
17377         {
17378           is_set = 1;
17379           is_en = 0;
17380         }
17381       else
17382         break;
17383     }
17384
17385   if (is_set == 0)
17386     {
17387       errmsg ("Value not set");
17388       return -99;
17389     }
17390
17391   /* Construct the API message */
17392   M (GPE_ENABLE_DISABLE, mp);
17393
17394   mp->is_en = is_en;
17395
17396   /* send it... */
17397   S (mp);
17398
17399   /* Wait for a reply... */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 static int
17405 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17406 {
17407   unformat_input_t *input = vam->input;
17408   vl_api_one_rloc_probe_enable_disable_t *mp;
17409   u8 is_set = 0;
17410   u8 is_en = 0;
17411   int ret;
17412
17413   /* Parse args required to build the message */
17414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17415     {
17416       if (unformat (input, "enable"))
17417         {
17418           is_set = 1;
17419           is_en = 1;
17420         }
17421       else if (unformat (input, "disable"))
17422         is_set = 1;
17423       else
17424         break;
17425     }
17426
17427   if (!is_set)
17428     {
17429       errmsg ("Value not set");
17430       return -99;
17431     }
17432
17433   /* Construct the API message */
17434   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17435
17436   mp->is_enabled = is_en;
17437
17438   /* send it... */
17439   S (mp);
17440
17441   /* Wait for a reply... */
17442   W (ret);
17443   return ret;
17444 }
17445
17446 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17447
17448 static int
17449 api_one_map_register_enable_disable (vat_main_t * vam)
17450 {
17451   unformat_input_t *input = vam->input;
17452   vl_api_one_map_register_enable_disable_t *mp;
17453   u8 is_set = 0;
17454   u8 is_en = 0;
17455   int ret;
17456
17457   /* Parse args required to build the message */
17458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17459     {
17460       if (unformat (input, "enable"))
17461         {
17462           is_set = 1;
17463           is_en = 1;
17464         }
17465       else if (unformat (input, "disable"))
17466         is_set = 1;
17467       else
17468         break;
17469     }
17470
17471   if (!is_set)
17472     {
17473       errmsg ("Value not set");
17474       return -99;
17475     }
17476
17477   /* Construct the API message */
17478   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17479
17480   mp->is_enabled = is_en;
17481
17482   /* send it... */
17483   S (mp);
17484
17485   /* Wait for a reply... */
17486   W (ret);
17487   return ret;
17488 }
17489
17490 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17491
17492 static int
17493 api_one_enable_disable (vat_main_t * vam)
17494 {
17495   unformat_input_t *input = vam->input;
17496   vl_api_one_enable_disable_t *mp;
17497   u8 is_set = 0;
17498   u8 is_en = 0;
17499   int ret;
17500
17501   /* Parse args required to build the message */
17502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17503     {
17504       if (unformat (input, "enable"))
17505         {
17506           is_set = 1;
17507           is_en = 1;
17508         }
17509       else if (unformat (input, "disable"))
17510         {
17511           is_set = 1;
17512         }
17513       else
17514         break;
17515     }
17516
17517   if (!is_set)
17518     {
17519       errmsg ("Value not set");
17520       return -99;
17521     }
17522
17523   /* Construct the API message */
17524   M (ONE_ENABLE_DISABLE, mp);
17525
17526   mp->is_en = is_en;
17527
17528   /* send it... */
17529   S (mp);
17530
17531   /* Wait for a reply... */
17532   W (ret);
17533   return ret;
17534 }
17535
17536 #define api_lisp_enable_disable api_one_enable_disable
17537
17538 static int
17539 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17540 {
17541   unformat_input_t *input = vam->input;
17542   vl_api_one_enable_disable_xtr_mode_t *mp;
17543   u8 is_set = 0;
17544   u8 is_en = 0;
17545   int ret;
17546
17547   /* Parse args required to build the message */
17548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17549     {
17550       if (unformat (input, "enable"))
17551         {
17552           is_set = 1;
17553           is_en = 1;
17554         }
17555       else if (unformat (input, "disable"))
17556         {
17557           is_set = 1;
17558         }
17559       else
17560         break;
17561     }
17562
17563   if (!is_set)
17564     {
17565       errmsg ("Value not set");
17566       return -99;
17567     }
17568
17569   /* Construct the API message */
17570   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17571
17572   mp->is_en = is_en;
17573
17574   /* send it... */
17575   S (mp);
17576
17577   /* Wait for a reply... */
17578   W (ret);
17579   return ret;
17580 }
17581
17582 static int
17583 api_one_show_xtr_mode (vat_main_t * vam)
17584 {
17585   vl_api_one_show_xtr_mode_t *mp;
17586   int ret;
17587
17588   /* Construct the API message */
17589   M (ONE_SHOW_XTR_MODE, mp);
17590
17591   /* send it... */
17592   S (mp);
17593
17594   /* Wait for a reply... */
17595   W (ret);
17596   return ret;
17597 }
17598
17599 static int
17600 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17601 {
17602   unformat_input_t *input = vam->input;
17603   vl_api_one_enable_disable_pitr_mode_t *mp;
17604   u8 is_set = 0;
17605   u8 is_en = 0;
17606   int ret;
17607
17608   /* Parse args required to build the message */
17609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17610     {
17611       if (unformat (input, "enable"))
17612         {
17613           is_set = 1;
17614           is_en = 1;
17615         }
17616       else if (unformat (input, "disable"))
17617         {
17618           is_set = 1;
17619         }
17620       else
17621         break;
17622     }
17623
17624   if (!is_set)
17625     {
17626       errmsg ("Value not set");
17627       return -99;
17628     }
17629
17630   /* Construct the API message */
17631   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17632
17633   mp->is_en = is_en;
17634
17635   /* send it... */
17636   S (mp);
17637
17638   /* Wait for a reply... */
17639   W (ret);
17640   return ret;
17641 }
17642
17643 static int
17644 api_one_show_pitr_mode (vat_main_t * vam)
17645 {
17646   vl_api_one_show_pitr_mode_t *mp;
17647   int ret;
17648
17649   /* Construct the API message */
17650   M (ONE_SHOW_PITR_MODE, mp);
17651
17652   /* send it... */
17653   S (mp);
17654
17655   /* Wait for a reply... */
17656   W (ret);
17657   return ret;
17658 }
17659
17660 static int
17661 api_one_enable_disable_petr_mode (vat_main_t * vam)
17662 {
17663   unformat_input_t *input = vam->input;
17664   vl_api_one_enable_disable_petr_mode_t *mp;
17665   u8 is_set = 0;
17666   u8 is_en = 0;
17667   int ret;
17668
17669   /* Parse args required to build the message */
17670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17671     {
17672       if (unformat (input, "enable"))
17673         {
17674           is_set = 1;
17675           is_en = 1;
17676         }
17677       else if (unformat (input, "disable"))
17678         {
17679           is_set = 1;
17680         }
17681       else
17682         break;
17683     }
17684
17685   if (!is_set)
17686     {
17687       errmsg ("Value not set");
17688       return -99;
17689     }
17690
17691   /* Construct the API message */
17692   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17693
17694   mp->is_en = is_en;
17695
17696   /* send it... */
17697   S (mp);
17698
17699   /* Wait for a reply... */
17700   W (ret);
17701   return ret;
17702 }
17703
17704 static int
17705 api_one_show_petr_mode (vat_main_t * vam)
17706 {
17707   vl_api_one_show_petr_mode_t *mp;
17708   int ret;
17709
17710   /* Construct the API message */
17711   M (ONE_SHOW_PETR_MODE, mp);
17712
17713   /* send it... */
17714   S (mp);
17715
17716   /* Wait for a reply... */
17717   W (ret);
17718   return ret;
17719 }
17720
17721 static int
17722 api_show_one_map_register_state (vat_main_t * vam)
17723 {
17724   vl_api_show_one_map_register_state_t *mp;
17725   int ret;
17726
17727   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17728
17729   /* send */
17730   S (mp);
17731
17732   /* wait for reply */
17733   W (ret);
17734   return ret;
17735 }
17736
17737 #define api_show_lisp_map_register_state api_show_one_map_register_state
17738
17739 static int
17740 api_show_one_rloc_probe_state (vat_main_t * vam)
17741 {
17742   vl_api_show_one_rloc_probe_state_t *mp;
17743   int ret;
17744
17745   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17746
17747   /* send */
17748   S (mp);
17749
17750   /* wait for reply */
17751   W (ret);
17752   return ret;
17753 }
17754
17755 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17756
17757 static int
17758 api_one_add_del_ndp_entry (vat_main_t * vam)
17759 {
17760   vl_api_one_add_del_ndp_entry_t *mp;
17761   unformat_input_t *input = vam->input;
17762   u8 is_add = 1;
17763   u8 mac_set = 0;
17764   u8 bd_set = 0;
17765   u8 ip_set = 0;
17766   u8 mac[6] = { 0, };
17767   u8 ip6[16] = { 0, };
17768   u32 bd = ~0;
17769   int ret;
17770
17771   /* Parse args required to build the message */
17772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17773     {
17774       if (unformat (input, "del"))
17775         is_add = 0;
17776       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17777         mac_set = 1;
17778       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17779         ip_set = 1;
17780       else if (unformat (input, "bd %d", &bd))
17781         bd_set = 1;
17782       else
17783         {
17784           errmsg ("parse error '%U'", format_unformat_error, input);
17785           return -99;
17786         }
17787     }
17788
17789   if (!bd_set || !ip_set || (!mac_set && is_add))
17790     {
17791       errmsg ("Missing BD, IP or MAC!");
17792       return -99;
17793     }
17794
17795   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17796   mp->is_add = is_add;
17797   clib_memcpy (mp->mac, mac, 6);
17798   mp->bd = clib_host_to_net_u32 (bd);
17799   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17800
17801   /* send */
17802   S (mp);
17803
17804   /* wait for reply */
17805   W (ret);
17806   return ret;
17807 }
17808
17809 static int
17810 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17811 {
17812   vl_api_one_add_del_l2_arp_entry_t *mp;
17813   unformat_input_t *input = vam->input;
17814   u8 is_add = 1;
17815   u8 mac_set = 0;
17816   u8 bd_set = 0;
17817   u8 ip_set = 0;
17818   u8 mac[6] = { 0, };
17819   u32 ip4 = 0, bd = ~0;
17820   int ret;
17821
17822   /* Parse args required to build the message */
17823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17824     {
17825       if (unformat (input, "del"))
17826         is_add = 0;
17827       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17828         mac_set = 1;
17829       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17830         ip_set = 1;
17831       else if (unformat (input, "bd %d", &bd))
17832         bd_set = 1;
17833       else
17834         {
17835           errmsg ("parse error '%U'", format_unformat_error, input);
17836           return -99;
17837         }
17838     }
17839
17840   if (!bd_set || !ip_set || (!mac_set && is_add))
17841     {
17842       errmsg ("Missing BD, IP or MAC!");
17843       return -99;
17844     }
17845
17846   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17847   mp->is_add = is_add;
17848   clib_memcpy (mp->mac, mac, 6);
17849   mp->bd = clib_host_to_net_u32 (bd);
17850   mp->ip4 = ip4;
17851
17852   /* send */
17853   S (mp);
17854
17855   /* wait for reply */
17856   W (ret);
17857   return ret;
17858 }
17859
17860 static int
17861 api_one_ndp_bd_get (vat_main_t * vam)
17862 {
17863   vl_api_one_ndp_bd_get_t *mp;
17864   int ret;
17865
17866   M (ONE_NDP_BD_GET, mp);
17867
17868   /* send */
17869   S (mp);
17870
17871   /* wait for reply */
17872   W (ret);
17873   return ret;
17874 }
17875
17876 static int
17877 api_one_ndp_entries_get (vat_main_t * vam)
17878 {
17879   vl_api_one_ndp_entries_get_t *mp;
17880   unformat_input_t *input = vam->input;
17881   u8 bd_set = 0;
17882   u32 bd = ~0;
17883   int ret;
17884
17885   /* Parse args required to build the message */
17886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17887     {
17888       if (unformat (input, "bd %d", &bd))
17889         bd_set = 1;
17890       else
17891         {
17892           errmsg ("parse error '%U'", format_unformat_error, input);
17893           return -99;
17894         }
17895     }
17896
17897   if (!bd_set)
17898     {
17899       errmsg ("Expected bridge domain!");
17900       return -99;
17901     }
17902
17903   M (ONE_NDP_ENTRIES_GET, mp);
17904   mp->bd = clib_host_to_net_u32 (bd);
17905
17906   /* send */
17907   S (mp);
17908
17909   /* wait for reply */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 static int
17915 api_one_l2_arp_bd_get (vat_main_t * vam)
17916 {
17917   vl_api_one_l2_arp_bd_get_t *mp;
17918   int ret;
17919
17920   M (ONE_L2_ARP_BD_GET, mp);
17921
17922   /* send */
17923   S (mp);
17924
17925   /* wait for reply */
17926   W (ret);
17927   return ret;
17928 }
17929
17930 static int
17931 api_one_l2_arp_entries_get (vat_main_t * vam)
17932 {
17933   vl_api_one_l2_arp_entries_get_t *mp;
17934   unformat_input_t *input = vam->input;
17935   u8 bd_set = 0;
17936   u32 bd = ~0;
17937   int ret;
17938
17939   /* Parse args required to build the message */
17940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17941     {
17942       if (unformat (input, "bd %d", &bd))
17943         bd_set = 1;
17944       else
17945         {
17946           errmsg ("parse error '%U'", format_unformat_error, input);
17947           return -99;
17948         }
17949     }
17950
17951   if (!bd_set)
17952     {
17953       errmsg ("Expected bridge domain!");
17954       return -99;
17955     }
17956
17957   M (ONE_L2_ARP_ENTRIES_GET, mp);
17958   mp->bd = clib_host_to_net_u32 (bd);
17959
17960   /* send */
17961   S (mp);
17962
17963   /* wait for reply */
17964   W (ret);
17965   return ret;
17966 }
17967
17968 static int
17969 api_one_stats_enable_disable (vat_main_t * vam)
17970 {
17971   vl_api_one_stats_enable_disable_t *mp;
17972   unformat_input_t *input = vam->input;
17973   u8 is_set = 0;
17974   u8 is_en = 0;
17975   int ret;
17976
17977   /* Parse args required to build the message */
17978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17979     {
17980       if (unformat (input, "enable"))
17981         {
17982           is_set = 1;
17983           is_en = 1;
17984         }
17985       else if (unformat (input, "disable"))
17986         {
17987           is_set = 1;
17988         }
17989       else
17990         break;
17991     }
17992
17993   if (!is_set)
17994     {
17995       errmsg ("Value not set");
17996       return -99;
17997     }
17998
17999   M (ONE_STATS_ENABLE_DISABLE, mp);
18000   mp->is_en = is_en;
18001
18002   /* send */
18003   S (mp);
18004
18005   /* wait for reply */
18006   W (ret);
18007   return ret;
18008 }
18009
18010 static int
18011 api_show_one_stats_enable_disable (vat_main_t * vam)
18012 {
18013   vl_api_show_one_stats_enable_disable_t *mp;
18014   int ret;
18015
18016   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18017
18018   /* send */
18019   S (mp);
18020
18021   /* wait for reply */
18022   W (ret);
18023   return ret;
18024 }
18025
18026 static int
18027 api_show_one_map_request_mode (vat_main_t * vam)
18028 {
18029   vl_api_show_one_map_request_mode_t *mp;
18030   int ret;
18031
18032   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18033
18034   /* send */
18035   S (mp);
18036
18037   /* wait for reply */
18038   W (ret);
18039   return ret;
18040 }
18041
18042 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18043
18044 static int
18045 api_one_map_request_mode (vat_main_t * vam)
18046 {
18047   unformat_input_t *input = vam->input;
18048   vl_api_one_map_request_mode_t *mp;
18049   u8 mode = 0;
18050   int ret;
18051
18052   /* Parse args required to build the message */
18053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18054     {
18055       if (unformat (input, "dst-only"))
18056         mode = 0;
18057       else if (unformat (input, "src-dst"))
18058         mode = 1;
18059       else
18060         {
18061           errmsg ("parse error '%U'", format_unformat_error, input);
18062           return -99;
18063         }
18064     }
18065
18066   M (ONE_MAP_REQUEST_MODE, mp);
18067
18068   mp->mode = mode;
18069
18070   /* send */
18071   S (mp);
18072
18073   /* wait for reply */
18074   W (ret);
18075   return ret;
18076 }
18077
18078 #define api_lisp_map_request_mode api_one_map_request_mode
18079
18080 /**
18081  * Enable/disable ONE proxy ITR.
18082  *
18083  * @param vam vpp API test context
18084  * @return return code
18085  */
18086 static int
18087 api_one_pitr_set_locator_set (vat_main_t * vam)
18088 {
18089   u8 ls_name_set = 0;
18090   unformat_input_t *input = vam->input;
18091   vl_api_one_pitr_set_locator_set_t *mp;
18092   u8 is_add = 1;
18093   u8 *ls_name = 0;
18094   int ret;
18095
18096   /* Parse args required to build the message */
18097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18098     {
18099       if (unformat (input, "del"))
18100         is_add = 0;
18101       else if (unformat (input, "locator-set %s", &ls_name))
18102         ls_name_set = 1;
18103       else
18104         {
18105           errmsg ("parse error '%U'", format_unformat_error, input);
18106           return -99;
18107         }
18108     }
18109
18110   if (!ls_name_set)
18111     {
18112       errmsg ("locator-set name not set!");
18113       return -99;
18114     }
18115
18116   M (ONE_PITR_SET_LOCATOR_SET, mp);
18117
18118   mp->is_add = is_add;
18119   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18120   vec_free (ls_name);
18121
18122   /* send */
18123   S (mp);
18124
18125   /* wait for reply */
18126   W (ret);
18127   return ret;
18128 }
18129
18130 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18131
18132 static int
18133 api_one_nsh_set_locator_set (vat_main_t * vam)
18134 {
18135   u8 ls_name_set = 0;
18136   unformat_input_t *input = vam->input;
18137   vl_api_one_nsh_set_locator_set_t *mp;
18138   u8 is_add = 1;
18139   u8 *ls_name = 0;
18140   int ret;
18141
18142   /* Parse args required to build the message */
18143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18144     {
18145       if (unformat (input, "del"))
18146         is_add = 0;
18147       else if (unformat (input, "ls %s", &ls_name))
18148         ls_name_set = 1;
18149       else
18150         {
18151           errmsg ("parse error '%U'", format_unformat_error, input);
18152           return -99;
18153         }
18154     }
18155
18156   if (!ls_name_set && is_add)
18157     {
18158       errmsg ("locator-set name not set!");
18159       return -99;
18160     }
18161
18162   M (ONE_NSH_SET_LOCATOR_SET, mp);
18163
18164   mp->is_add = is_add;
18165   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18166   vec_free (ls_name);
18167
18168   /* send */
18169   S (mp);
18170
18171   /* wait for reply */
18172   W (ret);
18173   return ret;
18174 }
18175
18176 static int
18177 api_show_one_pitr (vat_main_t * vam)
18178 {
18179   vl_api_show_one_pitr_t *mp;
18180   int ret;
18181
18182   if (!vam->json_output)
18183     {
18184       print (vam->ofp, "%=20s", "lisp status:");
18185     }
18186
18187   M (SHOW_ONE_PITR, mp);
18188   /* send it... */
18189   S (mp);
18190
18191   /* Wait for a reply... */
18192   W (ret);
18193   return ret;
18194 }
18195
18196 #define api_show_lisp_pitr api_show_one_pitr
18197
18198 static int
18199 api_one_use_petr (vat_main_t * vam)
18200 {
18201   unformat_input_t *input = vam->input;
18202   vl_api_one_use_petr_t *mp;
18203   u8 is_add = 0;
18204   ip_address_t ip;
18205   int ret;
18206
18207   memset (&ip, 0, sizeof (ip));
18208
18209   /* Parse args required to build the message */
18210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18211     {
18212       if (unformat (input, "disable"))
18213         is_add = 0;
18214       else
18215         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18216         {
18217           is_add = 1;
18218           ip_addr_version (&ip) = IP4;
18219         }
18220       else
18221         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18222         {
18223           is_add = 1;
18224           ip_addr_version (&ip) = IP6;
18225         }
18226       else
18227         {
18228           errmsg ("parse error '%U'", format_unformat_error, input);
18229           return -99;
18230         }
18231     }
18232
18233   M (ONE_USE_PETR, mp);
18234
18235   mp->is_add = is_add;
18236   if (is_add)
18237     {
18238       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18239       if (mp->is_ip4)
18240         clib_memcpy (mp->address, &ip, 4);
18241       else
18242         clib_memcpy (mp->address, &ip, 16);
18243     }
18244
18245   /* send */
18246   S (mp);
18247
18248   /* wait for reply */
18249   W (ret);
18250   return ret;
18251 }
18252
18253 #define api_lisp_use_petr api_one_use_petr
18254
18255 static int
18256 api_show_one_nsh_mapping (vat_main_t * vam)
18257 {
18258   vl_api_show_one_use_petr_t *mp;
18259   int ret;
18260
18261   if (!vam->json_output)
18262     {
18263       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18264     }
18265
18266   M (SHOW_ONE_NSH_MAPPING, mp);
18267   /* send it... */
18268   S (mp);
18269
18270   /* Wait for a reply... */
18271   W (ret);
18272   return ret;
18273 }
18274
18275 static int
18276 api_show_one_use_petr (vat_main_t * vam)
18277 {
18278   vl_api_show_one_use_petr_t *mp;
18279   int ret;
18280
18281   if (!vam->json_output)
18282     {
18283       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18284     }
18285
18286   M (SHOW_ONE_USE_PETR, mp);
18287   /* send it... */
18288   S (mp);
18289
18290   /* Wait for a reply... */
18291   W (ret);
18292   return ret;
18293 }
18294
18295 #define api_show_lisp_use_petr api_show_one_use_petr
18296
18297 /**
18298  * Add/delete mapping between vni and vrf
18299  */
18300 static int
18301 api_one_eid_table_add_del_map (vat_main_t * vam)
18302 {
18303   unformat_input_t *input = vam->input;
18304   vl_api_one_eid_table_add_del_map_t *mp;
18305   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18306   u32 vni, vrf, bd_index;
18307   int ret;
18308
18309   /* Parse args required to build the message */
18310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18311     {
18312       if (unformat (input, "del"))
18313         is_add = 0;
18314       else if (unformat (input, "vrf %d", &vrf))
18315         vrf_set = 1;
18316       else if (unformat (input, "bd_index %d", &bd_index))
18317         bd_index_set = 1;
18318       else if (unformat (input, "vni %d", &vni))
18319         vni_set = 1;
18320       else
18321         break;
18322     }
18323
18324   if (!vni_set || (!vrf_set && !bd_index_set))
18325     {
18326       errmsg ("missing arguments!");
18327       return -99;
18328     }
18329
18330   if (vrf_set && bd_index_set)
18331     {
18332       errmsg ("error: both vrf and bd entered!");
18333       return -99;
18334     }
18335
18336   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18337
18338   mp->is_add = is_add;
18339   mp->vni = htonl (vni);
18340   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18341   mp->is_l2 = bd_index_set;
18342
18343   /* send */
18344   S (mp);
18345
18346   /* wait for reply */
18347   W (ret);
18348   return ret;
18349 }
18350
18351 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18352
18353 uword
18354 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18355 {
18356   u32 *action = va_arg (*args, u32 *);
18357   u8 *s = 0;
18358
18359   if (unformat (input, "%s", &s))
18360     {
18361       if (!strcmp ((char *) s, "no-action"))
18362         action[0] = 0;
18363       else if (!strcmp ((char *) s, "natively-forward"))
18364         action[0] = 1;
18365       else if (!strcmp ((char *) s, "send-map-request"))
18366         action[0] = 2;
18367       else if (!strcmp ((char *) s, "drop"))
18368         action[0] = 3;
18369       else
18370         {
18371           clib_warning ("invalid action: '%s'", s);
18372           action[0] = 3;
18373         }
18374     }
18375   else
18376     return 0;
18377
18378   vec_free (s);
18379   return 1;
18380 }
18381
18382 /**
18383  * Add/del remote mapping to/from ONE control plane
18384  *
18385  * @param vam vpp API test context
18386  * @return return code
18387  */
18388 static int
18389 api_one_add_del_remote_mapping (vat_main_t * vam)
18390 {
18391   unformat_input_t *input = vam->input;
18392   vl_api_one_add_del_remote_mapping_t *mp;
18393   u32 vni = 0;
18394   lisp_eid_vat_t _eid, *eid = &_eid;
18395   lisp_eid_vat_t _seid, *seid = &_seid;
18396   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18397   u32 action = ~0, p, w, data_len;
18398   ip4_address_t rloc4;
18399   ip6_address_t rloc6;
18400   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18401   int ret;
18402
18403   memset (&rloc, 0, sizeof (rloc));
18404
18405   /* Parse args required to build the message */
18406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18407     {
18408       if (unformat (input, "del-all"))
18409         {
18410           del_all = 1;
18411         }
18412       else if (unformat (input, "del"))
18413         {
18414           is_add = 0;
18415         }
18416       else if (unformat (input, "add"))
18417         {
18418           is_add = 1;
18419         }
18420       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18421         {
18422           eid_set = 1;
18423         }
18424       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18425         {
18426           seid_set = 1;
18427         }
18428       else if (unformat (input, "vni %d", &vni))
18429         {
18430           ;
18431         }
18432       else if (unformat (input, "p %d w %d", &p, &w))
18433         {
18434           if (!curr_rloc)
18435             {
18436               errmsg ("No RLOC configured for setting priority/weight!");
18437               return -99;
18438             }
18439           curr_rloc->priority = p;
18440           curr_rloc->weight = w;
18441         }
18442       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18443         {
18444           rloc.is_ip4 = 1;
18445           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18446           vec_add1 (rlocs, rloc);
18447           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18448         }
18449       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18450         {
18451           rloc.is_ip4 = 0;
18452           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18453           vec_add1 (rlocs, rloc);
18454           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18455         }
18456       else if (unformat (input, "action %U",
18457                          unformat_negative_mapping_action, &action))
18458         {
18459           ;
18460         }
18461       else
18462         {
18463           clib_warning ("parse error '%U'", format_unformat_error, input);
18464           return -99;
18465         }
18466     }
18467
18468   if (0 == eid_set)
18469     {
18470       errmsg ("missing params!");
18471       return -99;
18472     }
18473
18474   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18475     {
18476       errmsg ("no action set for negative map-reply!");
18477       return -99;
18478     }
18479
18480   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18481
18482   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18483   mp->is_add = is_add;
18484   mp->vni = htonl (vni);
18485   mp->action = (u8) action;
18486   mp->is_src_dst = seid_set;
18487   mp->eid_len = eid->len;
18488   mp->seid_len = seid->len;
18489   mp->del_all = del_all;
18490   mp->eid_type = eid->type;
18491   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18492   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18493
18494   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18495   clib_memcpy (mp->rlocs, rlocs, data_len);
18496   vec_free (rlocs);
18497
18498   /* send it... */
18499   S (mp);
18500
18501   /* Wait for a reply... */
18502   W (ret);
18503   return ret;
18504 }
18505
18506 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18507
18508 /**
18509  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18510  * forwarding entries in data-plane accordingly.
18511  *
18512  * @param vam vpp API test context
18513  * @return return code
18514  */
18515 static int
18516 api_one_add_del_adjacency (vat_main_t * vam)
18517 {
18518   unformat_input_t *input = vam->input;
18519   vl_api_one_add_del_adjacency_t *mp;
18520   u32 vni = 0;
18521   ip4_address_t leid4, reid4;
18522   ip6_address_t leid6, reid6;
18523   u8 reid_mac[6] = { 0 };
18524   u8 leid_mac[6] = { 0 };
18525   u8 reid_type, leid_type;
18526   u32 leid_len = 0, reid_len = 0, len;
18527   u8 is_add = 1;
18528   int ret;
18529
18530   leid_type = reid_type = (u8) ~ 0;
18531
18532   /* Parse args required to build the message */
18533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18534     {
18535       if (unformat (input, "del"))
18536         {
18537           is_add = 0;
18538         }
18539       else if (unformat (input, "add"))
18540         {
18541           is_add = 1;
18542         }
18543       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18544                          &reid4, &len))
18545         {
18546           reid_type = 0;        /* ipv4 */
18547           reid_len = len;
18548         }
18549       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18550                          &reid6, &len))
18551         {
18552           reid_type = 1;        /* ipv6 */
18553           reid_len = len;
18554         }
18555       else if (unformat (input, "reid %U", unformat_ethernet_address,
18556                          reid_mac))
18557         {
18558           reid_type = 2;        /* mac */
18559         }
18560       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18561                          &leid4, &len))
18562         {
18563           leid_type = 0;        /* ipv4 */
18564           leid_len = len;
18565         }
18566       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18567                          &leid6, &len))
18568         {
18569           leid_type = 1;        /* ipv6 */
18570           leid_len = len;
18571         }
18572       else if (unformat (input, "leid %U", unformat_ethernet_address,
18573                          leid_mac))
18574         {
18575           leid_type = 2;        /* mac */
18576         }
18577       else if (unformat (input, "vni %d", &vni))
18578         {
18579           ;
18580         }
18581       else
18582         {
18583           errmsg ("parse error '%U'", format_unformat_error, input);
18584           return -99;
18585         }
18586     }
18587
18588   if ((u8) ~ 0 == reid_type)
18589     {
18590       errmsg ("missing params!");
18591       return -99;
18592     }
18593
18594   if (leid_type != reid_type)
18595     {
18596       errmsg ("remote and local EIDs are of different types!");
18597       return -99;
18598     }
18599
18600   M (ONE_ADD_DEL_ADJACENCY, mp);
18601   mp->is_add = is_add;
18602   mp->vni = htonl (vni);
18603   mp->leid_len = leid_len;
18604   mp->reid_len = reid_len;
18605   mp->eid_type = reid_type;
18606
18607   switch (mp->eid_type)
18608     {
18609     case 0:
18610       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18611       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18612       break;
18613     case 1:
18614       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18615       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18616       break;
18617     case 2:
18618       clib_memcpy (mp->leid, leid_mac, 6);
18619       clib_memcpy (mp->reid, reid_mac, 6);
18620       break;
18621     default:
18622       errmsg ("unknown EID type %d!", mp->eid_type);
18623       return 0;
18624     }
18625
18626   /* send it... */
18627   S (mp);
18628
18629   /* Wait for a reply... */
18630   W (ret);
18631   return ret;
18632 }
18633
18634 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18635
18636 uword
18637 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18638 {
18639   u32 *mode = va_arg (*args, u32 *);
18640
18641   if (unformat (input, "lisp"))
18642     *mode = 0;
18643   else if (unformat (input, "vxlan"))
18644     *mode = 1;
18645   else
18646     return 0;
18647
18648   return 1;
18649 }
18650
18651 static int
18652 api_gpe_get_encap_mode (vat_main_t * vam)
18653 {
18654   vl_api_gpe_get_encap_mode_t *mp;
18655   int ret;
18656
18657   /* Construct the API message */
18658   M (GPE_GET_ENCAP_MODE, mp);
18659
18660   /* send it... */
18661   S (mp);
18662
18663   /* Wait for a reply... */
18664   W (ret);
18665   return ret;
18666 }
18667
18668 static int
18669 api_gpe_set_encap_mode (vat_main_t * vam)
18670 {
18671   unformat_input_t *input = vam->input;
18672   vl_api_gpe_set_encap_mode_t *mp;
18673   int ret;
18674   u32 mode = 0;
18675
18676   /* Parse args required to build the message */
18677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18678     {
18679       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18680         ;
18681       else
18682         break;
18683     }
18684
18685   /* Construct the API message */
18686   M (GPE_SET_ENCAP_MODE, mp);
18687
18688   mp->mode = mode;
18689
18690   /* send it... */
18691   S (mp);
18692
18693   /* Wait for a reply... */
18694   W (ret);
18695   return ret;
18696 }
18697
18698 static int
18699 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18700 {
18701   unformat_input_t *input = vam->input;
18702   vl_api_gpe_add_del_iface_t *mp;
18703   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18704   u32 dp_table = 0, vni = 0;
18705   int ret;
18706
18707   /* Parse args required to build the message */
18708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18709     {
18710       if (unformat (input, "up"))
18711         {
18712           action_set = 1;
18713           is_add = 1;
18714         }
18715       else if (unformat (input, "down"))
18716         {
18717           action_set = 1;
18718           is_add = 0;
18719         }
18720       else if (unformat (input, "table_id %d", &dp_table))
18721         {
18722           dp_table_set = 1;
18723         }
18724       else if (unformat (input, "bd_id %d", &dp_table))
18725         {
18726           dp_table_set = 1;
18727           is_l2 = 1;
18728         }
18729       else if (unformat (input, "vni %d", &vni))
18730         {
18731           vni_set = 1;
18732         }
18733       else
18734         break;
18735     }
18736
18737   if (action_set == 0)
18738     {
18739       errmsg ("Action not set");
18740       return -99;
18741     }
18742   if (dp_table_set == 0 || vni_set == 0)
18743     {
18744       errmsg ("vni and dp_table must be set");
18745       return -99;
18746     }
18747
18748   /* Construct the API message */
18749   M (GPE_ADD_DEL_IFACE, mp);
18750
18751   mp->is_add = is_add;
18752   mp->dp_table = clib_host_to_net_u32 (dp_table);
18753   mp->is_l2 = is_l2;
18754   mp->vni = clib_host_to_net_u32 (vni);
18755
18756   /* send it... */
18757   S (mp);
18758
18759   /* Wait for a reply... */
18760   W (ret);
18761   return ret;
18762 }
18763
18764 static int
18765 api_one_map_register_fallback_threshold (vat_main_t * vam)
18766 {
18767   unformat_input_t *input = vam->input;
18768   vl_api_one_map_register_fallback_threshold_t *mp;
18769   u32 value = 0;
18770   u8 is_set = 0;
18771   int ret;
18772
18773   /* Parse args required to build the message */
18774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18775     {
18776       if (unformat (input, "%u", &value))
18777         is_set = 1;
18778       else
18779         {
18780           clib_warning ("parse error '%U'", format_unformat_error, input);
18781           return -99;
18782         }
18783     }
18784
18785   if (!is_set)
18786     {
18787       errmsg ("fallback threshold value is missing!");
18788       return -99;
18789     }
18790
18791   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18792   mp->value = clib_host_to_net_u32 (value);
18793
18794   /* send it... */
18795   S (mp);
18796
18797   /* Wait for a reply... */
18798   W (ret);
18799   return ret;
18800 }
18801
18802 static int
18803 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18804 {
18805   vl_api_show_one_map_register_fallback_threshold_t *mp;
18806   int ret;
18807
18808   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18809
18810   /* send it... */
18811   S (mp);
18812
18813   /* Wait for a reply... */
18814   W (ret);
18815   return ret;
18816 }
18817
18818 uword
18819 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18820 {
18821   u32 *proto = va_arg (*args, u32 *);
18822
18823   if (unformat (input, "udp"))
18824     *proto = 1;
18825   else if (unformat (input, "api"))
18826     *proto = 2;
18827   else
18828     return 0;
18829
18830   return 1;
18831 }
18832
18833 static int
18834 api_one_set_transport_protocol (vat_main_t * vam)
18835 {
18836   unformat_input_t *input = vam->input;
18837   vl_api_one_set_transport_protocol_t *mp;
18838   u8 is_set = 0;
18839   u32 protocol = 0;
18840   int ret;
18841
18842   /* Parse args required to build the message */
18843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18844     {
18845       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18846         is_set = 1;
18847       else
18848         {
18849           clib_warning ("parse error '%U'", format_unformat_error, input);
18850           return -99;
18851         }
18852     }
18853
18854   if (!is_set)
18855     {
18856       errmsg ("Transport protocol missing!");
18857       return -99;
18858     }
18859
18860   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18861   mp->protocol = (u8) protocol;
18862
18863   /* send it... */
18864   S (mp);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 static int
18872 api_one_get_transport_protocol (vat_main_t * vam)
18873 {
18874   vl_api_one_get_transport_protocol_t *mp;
18875   int ret;
18876
18877   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 static int
18888 api_one_map_register_set_ttl (vat_main_t * vam)
18889 {
18890   unformat_input_t *input = vam->input;
18891   vl_api_one_map_register_set_ttl_t *mp;
18892   u32 ttl = 0;
18893   u8 is_set = 0;
18894   int ret;
18895
18896   /* Parse args required to build the message */
18897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18898     {
18899       if (unformat (input, "%u", &ttl))
18900         is_set = 1;
18901       else
18902         {
18903           clib_warning ("parse error '%U'", format_unformat_error, input);
18904           return -99;
18905         }
18906     }
18907
18908   if (!is_set)
18909     {
18910       errmsg ("TTL value missing!");
18911       return -99;
18912     }
18913
18914   M (ONE_MAP_REGISTER_SET_TTL, mp);
18915   mp->ttl = clib_host_to_net_u32 (ttl);
18916
18917   /* send it... */
18918   S (mp);
18919
18920   /* Wait for a reply... */
18921   W (ret);
18922   return ret;
18923 }
18924
18925 static int
18926 api_show_one_map_register_ttl (vat_main_t * vam)
18927 {
18928   vl_api_show_one_map_register_ttl_t *mp;
18929   int ret;
18930
18931   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18932
18933   /* send it... */
18934   S (mp);
18935
18936   /* Wait for a reply... */
18937   W (ret);
18938   return ret;
18939 }
18940
18941 /**
18942  * Add/del map request itr rlocs from ONE control plane and updates
18943  *
18944  * @param vam vpp API test context
18945  * @return return code
18946  */
18947 static int
18948 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18949 {
18950   unformat_input_t *input = vam->input;
18951   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18952   u8 *locator_set_name = 0;
18953   u8 locator_set_name_set = 0;
18954   u8 is_add = 1;
18955   int ret;
18956
18957   /* Parse args required to build the message */
18958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18959     {
18960       if (unformat (input, "del"))
18961         {
18962           is_add = 0;
18963         }
18964       else if (unformat (input, "%_%v%_", &locator_set_name))
18965         {
18966           locator_set_name_set = 1;
18967         }
18968       else
18969         {
18970           clib_warning ("parse error '%U'", format_unformat_error, input);
18971           return -99;
18972         }
18973     }
18974
18975   if (is_add && !locator_set_name_set)
18976     {
18977       errmsg ("itr-rloc is not set!");
18978       return -99;
18979     }
18980
18981   if (is_add && vec_len (locator_set_name) > 64)
18982     {
18983       errmsg ("itr-rloc locator-set name too long");
18984       vec_free (locator_set_name);
18985       return -99;
18986     }
18987
18988   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18989   mp->is_add = is_add;
18990   if (is_add)
18991     {
18992       clib_memcpy (mp->locator_set_name, locator_set_name,
18993                    vec_len (locator_set_name));
18994     }
18995   else
18996     {
18997       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18998     }
18999   vec_free (locator_set_name);
19000
19001   /* send it... */
19002   S (mp);
19003
19004   /* Wait for a reply... */
19005   W (ret);
19006   return ret;
19007 }
19008
19009 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19010
19011 static int
19012 api_one_locator_dump (vat_main_t * vam)
19013 {
19014   unformat_input_t *input = vam->input;
19015   vl_api_one_locator_dump_t *mp;
19016   vl_api_control_ping_t *mp_ping;
19017   u8 is_index_set = 0, is_name_set = 0;
19018   u8 *ls_name = 0;
19019   u32 ls_index = ~0;
19020   int ret;
19021
19022   /* Parse args required to build the message */
19023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19024     {
19025       if (unformat (input, "ls_name %_%v%_", &ls_name))
19026         {
19027           is_name_set = 1;
19028         }
19029       else if (unformat (input, "ls_index %d", &ls_index))
19030         {
19031           is_index_set = 1;
19032         }
19033       else
19034         {
19035           errmsg ("parse error '%U'", format_unformat_error, input);
19036           return -99;
19037         }
19038     }
19039
19040   if (!is_index_set && !is_name_set)
19041     {
19042       errmsg ("error: expected one of index or name!");
19043       return -99;
19044     }
19045
19046   if (is_index_set && is_name_set)
19047     {
19048       errmsg ("error: only one param expected!");
19049       return -99;
19050     }
19051
19052   if (vec_len (ls_name) > 62)
19053     {
19054       errmsg ("error: locator set name too long!");
19055       return -99;
19056     }
19057
19058   if (!vam->json_output)
19059     {
19060       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19061     }
19062
19063   M (ONE_LOCATOR_DUMP, mp);
19064   mp->is_index_set = is_index_set;
19065
19066   if (is_index_set)
19067     mp->ls_index = clib_host_to_net_u32 (ls_index);
19068   else
19069     {
19070       vec_add1 (ls_name, 0);
19071       strncpy ((char *) mp->ls_name, (char *) ls_name,
19072                sizeof (mp->ls_name) - 1);
19073     }
19074
19075   /* send it... */
19076   S (mp);
19077
19078   /* Use a control ping for synchronization */
19079   MPING (CONTROL_PING, mp_ping);
19080   S (mp_ping);
19081
19082   /* Wait for a reply... */
19083   W (ret);
19084   return ret;
19085 }
19086
19087 #define api_lisp_locator_dump api_one_locator_dump
19088
19089 static int
19090 api_one_locator_set_dump (vat_main_t * vam)
19091 {
19092   vl_api_one_locator_set_dump_t *mp;
19093   vl_api_control_ping_t *mp_ping;
19094   unformat_input_t *input = vam->input;
19095   u8 filter = 0;
19096   int ret;
19097
19098   /* Parse args required to build the message */
19099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19100     {
19101       if (unformat (input, "local"))
19102         {
19103           filter = 1;
19104         }
19105       else if (unformat (input, "remote"))
19106         {
19107           filter = 2;
19108         }
19109       else
19110         {
19111           errmsg ("parse error '%U'", format_unformat_error, input);
19112           return -99;
19113         }
19114     }
19115
19116   if (!vam->json_output)
19117     {
19118       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19119     }
19120
19121   M (ONE_LOCATOR_SET_DUMP, mp);
19122
19123   mp->filter = filter;
19124
19125   /* send it... */
19126   S (mp);
19127
19128   /* Use a control ping for synchronization */
19129   MPING (CONTROL_PING, mp_ping);
19130   S (mp_ping);
19131
19132   /* Wait for a reply... */
19133   W (ret);
19134   return ret;
19135 }
19136
19137 #define api_lisp_locator_set_dump api_one_locator_set_dump
19138
19139 static int
19140 api_one_eid_table_map_dump (vat_main_t * vam)
19141 {
19142   u8 is_l2 = 0;
19143   u8 mode_set = 0;
19144   unformat_input_t *input = vam->input;
19145   vl_api_one_eid_table_map_dump_t *mp;
19146   vl_api_control_ping_t *mp_ping;
19147   int ret;
19148
19149   /* Parse args required to build the message */
19150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19151     {
19152       if (unformat (input, "l2"))
19153         {
19154           is_l2 = 1;
19155           mode_set = 1;
19156         }
19157       else if (unformat (input, "l3"))
19158         {
19159           is_l2 = 0;
19160           mode_set = 1;
19161         }
19162       else
19163         {
19164           errmsg ("parse error '%U'", format_unformat_error, input);
19165           return -99;
19166         }
19167     }
19168
19169   if (!mode_set)
19170     {
19171       errmsg ("expected one of 'l2' or 'l3' parameter!");
19172       return -99;
19173     }
19174
19175   if (!vam->json_output)
19176     {
19177       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19178     }
19179
19180   M (ONE_EID_TABLE_MAP_DUMP, mp);
19181   mp->is_l2 = is_l2;
19182
19183   /* send it... */
19184   S (mp);
19185
19186   /* Use a control ping for synchronization */
19187   MPING (CONTROL_PING, mp_ping);
19188   S (mp_ping);
19189
19190   /* Wait for a reply... */
19191   W (ret);
19192   return ret;
19193 }
19194
19195 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19196
19197 static int
19198 api_one_eid_table_vni_dump (vat_main_t * vam)
19199 {
19200   vl_api_one_eid_table_vni_dump_t *mp;
19201   vl_api_control_ping_t *mp_ping;
19202   int ret;
19203
19204   if (!vam->json_output)
19205     {
19206       print (vam->ofp, "VNI");
19207     }
19208
19209   M (ONE_EID_TABLE_VNI_DUMP, mp);
19210
19211   /* send it... */
19212   S (mp);
19213
19214   /* Use a control ping for synchronization */
19215   MPING (CONTROL_PING, mp_ping);
19216   S (mp_ping);
19217
19218   /* Wait for a reply... */
19219   W (ret);
19220   return ret;
19221 }
19222
19223 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19224
19225 static int
19226 api_one_eid_table_dump (vat_main_t * vam)
19227 {
19228   unformat_input_t *i = vam->input;
19229   vl_api_one_eid_table_dump_t *mp;
19230   vl_api_control_ping_t *mp_ping;
19231   struct in_addr ip4;
19232   struct in6_addr ip6;
19233   u8 mac[6];
19234   u8 eid_type = ~0, eid_set = 0;
19235   u32 prefix_length = ~0, t, vni = 0;
19236   u8 filter = 0;
19237   int ret;
19238   lisp_nsh_api_t nsh;
19239
19240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19241     {
19242       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19243         {
19244           eid_set = 1;
19245           eid_type = 0;
19246           prefix_length = t;
19247         }
19248       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19249         {
19250           eid_set = 1;
19251           eid_type = 1;
19252           prefix_length = t;
19253         }
19254       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19255         {
19256           eid_set = 1;
19257           eid_type = 2;
19258         }
19259       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19260         {
19261           eid_set = 1;
19262           eid_type = 3;
19263         }
19264       else if (unformat (i, "vni %d", &t))
19265         {
19266           vni = t;
19267         }
19268       else if (unformat (i, "local"))
19269         {
19270           filter = 1;
19271         }
19272       else if (unformat (i, "remote"))
19273         {
19274           filter = 2;
19275         }
19276       else
19277         {
19278           errmsg ("parse error '%U'", format_unformat_error, i);
19279           return -99;
19280         }
19281     }
19282
19283   if (!vam->json_output)
19284     {
19285       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19286              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19287     }
19288
19289   M (ONE_EID_TABLE_DUMP, mp);
19290
19291   mp->filter = filter;
19292   if (eid_set)
19293     {
19294       mp->eid_set = 1;
19295       mp->vni = htonl (vni);
19296       mp->eid_type = eid_type;
19297       switch (eid_type)
19298         {
19299         case 0:
19300           mp->prefix_length = prefix_length;
19301           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19302           break;
19303         case 1:
19304           mp->prefix_length = prefix_length;
19305           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19306           break;
19307         case 2:
19308           clib_memcpy (mp->eid, mac, sizeof (mac));
19309           break;
19310         case 3:
19311           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19312           break;
19313         default:
19314           errmsg ("unknown EID type %d!", eid_type);
19315           return -99;
19316         }
19317     }
19318
19319   /* send it... */
19320   S (mp);
19321
19322   /* Use a control ping for synchronization */
19323   MPING (CONTROL_PING, mp_ping);
19324   S (mp_ping);
19325
19326   /* Wait for a reply... */
19327   W (ret);
19328   return ret;
19329 }
19330
19331 #define api_lisp_eid_table_dump api_one_eid_table_dump
19332
19333 static int
19334 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19335 {
19336   unformat_input_t *i = vam->input;
19337   vl_api_gpe_fwd_entries_get_t *mp;
19338   u8 vni_set = 0;
19339   u32 vni = ~0;
19340   int ret;
19341
19342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19343     {
19344       if (unformat (i, "vni %d", &vni))
19345         {
19346           vni_set = 1;
19347         }
19348       else
19349         {
19350           errmsg ("parse error '%U'", format_unformat_error, i);
19351           return -99;
19352         }
19353     }
19354
19355   if (!vni_set)
19356     {
19357       errmsg ("vni not set!");
19358       return -99;
19359     }
19360
19361   if (!vam->json_output)
19362     {
19363       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19364              "leid", "reid");
19365     }
19366
19367   M (GPE_FWD_ENTRIES_GET, mp);
19368   mp->vni = clib_host_to_net_u32 (vni);
19369
19370   /* send it... */
19371   S (mp);
19372
19373   /* Wait for a reply... */
19374   W (ret);
19375   return ret;
19376 }
19377
19378 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19379 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19380 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19381 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19382 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19383 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19384 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19385 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19386
19387 static int
19388 api_one_adjacencies_get (vat_main_t * vam)
19389 {
19390   unformat_input_t *i = vam->input;
19391   vl_api_one_adjacencies_get_t *mp;
19392   u8 vni_set = 0;
19393   u32 vni = ~0;
19394   int ret;
19395
19396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19397     {
19398       if (unformat (i, "vni %d", &vni))
19399         {
19400           vni_set = 1;
19401         }
19402       else
19403         {
19404           errmsg ("parse error '%U'", format_unformat_error, i);
19405           return -99;
19406         }
19407     }
19408
19409   if (!vni_set)
19410     {
19411       errmsg ("vni not set!");
19412       return -99;
19413     }
19414
19415   if (!vam->json_output)
19416     {
19417       print (vam->ofp, "%s %40s", "leid", "reid");
19418     }
19419
19420   M (ONE_ADJACENCIES_GET, mp);
19421   mp->vni = clib_host_to_net_u32 (vni);
19422
19423   /* send it... */
19424   S (mp);
19425
19426   /* Wait for a reply... */
19427   W (ret);
19428   return ret;
19429 }
19430
19431 #define api_lisp_adjacencies_get api_one_adjacencies_get
19432
19433 static int
19434 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19435 {
19436   unformat_input_t *i = vam->input;
19437   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19438   int ret;
19439   u8 ip_family_set = 0, is_ip4 = 1;
19440
19441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19442     {
19443       if (unformat (i, "ip4"))
19444         {
19445           ip_family_set = 1;
19446           is_ip4 = 1;
19447         }
19448       else if (unformat (i, "ip6"))
19449         {
19450           ip_family_set = 1;
19451           is_ip4 = 0;
19452         }
19453       else
19454         {
19455           errmsg ("parse error '%U'", format_unformat_error, i);
19456           return -99;
19457         }
19458     }
19459
19460   if (!ip_family_set)
19461     {
19462       errmsg ("ip family not set!");
19463       return -99;
19464     }
19465
19466   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19467   mp->is_ip4 = is_ip4;
19468
19469   /* send it... */
19470   S (mp);
19471
19472   /* Wait for a reply... */
19473   W (ret);
19474   return ret;
19475 }
19476
19477 static int
19478 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19479 {
19480   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19481   int ret;
19482
19483   if (!vam->json_output)
19484     {
19485       print (vam->ofp, "VNIs");
19486     }
19487
19488   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19489
19490   /* send it... */
19491   S (mp);
19492
19493   /* Wait for a reply... */
19494   W (ret);
19495   return ret;
19496 }
19497
19498 static int
19499 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19500 {
19501   unformat_input_t *i = vam->input;
19502   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19503   int ret = 0;
19504   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19505   struct in_addr ip4;
19506   struct in6_addr ip6;
19507   u32 table_id = 0, nh_sw_if_index = ~0;
19508
19509   memset (&ip4, 0, sizeof (ip4));
19510   memset (&ip6, 0, sizeof (ip6));
19511
19512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19513     {
19514       if (unformat (i, "del"))
19515         is_add = 0;
19516       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19517                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19518         {
19519           ip_set = 1;
19520           is_ip4 = 1;
19521         }
19522       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19523                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19524         {
19525           ip_set = 1;
19526           is_ip4 = 0;
19527         }
19528       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19529         {
19530           ip_set = 1;
19531           is_ip4 = 1;
19532           nh_sw_if_index = ~0;
19533         }
19534       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19535         {
19536           ip_set = 1;
19537           is_ip4 = 0;
19538           nh_sw_if_index = ~0;
19539         }
19540       else if (unformat (i, "table %d", &table_id))
19541         ;
19542       else
19543         {
19544           errmsg ("parse error '%U'", format_unformat_error, i);
19545           return -99;
19546         }
19547     }
19548
19549   if (!ip_set)
19550     {
19551       errmsg ("nh addr not set!");
19552       return -99;
19553     }
19554
19555   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19556   mp->is_add = is_add;
19557   mp->table_id = clib_host_to_net_u32 (table_id);
19558   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19559   mp->is_ip4 = is_ip4;
19560   if (is_ip4)
19561     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19562   else
19563     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19564
19565   /* send it... */
19566   S (mp);
19567
19568   /* Wait for a reply... */
19569   W (ret);
19570   return ret;
19571 }
19572
19573 static int
19574 api_one_map_server_dump (vat_main_t * vam)
19575 {
19576   vl_api_one_map_server_dump_t *mp;
19577   vl_api_control_ping_t *mp_ping;
19578   int ret;
19579
19580   if (!vam->json_output)
19581     {
19582       print (vam->ofp, "%=20s", "Map server");
19583     }
19584
19585   M (ONE_MAP_SERVER_DUMP, mp);
19586   /* send it... */
19587   S (mp);
19588
19589   /* Use a control ping for synchronization */
19590   MPING (CONTROL_PING, mp_ping);
19591   S (mp_ping);
19592
19593   /* Wait for a reply... */
19594   W (ret);
19595   return ret;
19596 }
19597
19598 #define api_lisp_map_server_dump api_one_map_server_dump
19599
19600 static int
19601 api_one_map_resolver_dump (vat_main_t * vam)
19602 {
19603   vl_api_one_map_resolver_dump_t *mp;
19604   vl_api_control_ping_t *mp_ping;
19605   int ret;
19606
19607   if (!vam->json_output)
19608     {
19609       print (vam->ofp, "%=20s", "Map resolver");
19610     }
19611
19612   M (ONE_MAP_RESOLVER_DUMP, mp);
19613   /* send it... */
19614   S (mp);
19615
19616   /* Use a control ping for synchronization */
19617   MPING (CONTROL_PING, mp_ping);
19618   S (mp_ping);
19619
19620   /* Wait for a reply... */
19621   W (ret);
19622   return ret;
19623 }
19624
19625 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19626
19627 static int
19628 api_one_stats_flush (vat_main_t * vam)
19629 {
19630   vl_api_one_stats_flush_t *mp;
19631   int ret = 0;
19632
19633   M (ONE_STATS_FLUSH, mp);
19634   S (mp);
19635   W (ret);
19636   return ret;
19637 }
19638
19639 static int
19640 api_one_stats_dump (vat_main_t * vam)
19641 {
19642   vl_api_one_stats_dump_t *mp;
19643   vl_api_control_ping_t *mp_ping;
19644   int ret;
19645
19646   M (ONE_STATS_DUMP, mp);
19647   /* send it... */
19648   S (mp);
19649
19650   /* Use a control ping for synchronization */
19651   MPING (CONTROL_PING, mp_ping);
19652   S (mp_ping);
19653
19654   /* Wait for a reply... */
19655   W (ret);
19656   return ret;
19657 }
19658
19659 static int
19660 api_show_one_status (vat_main_t * vam)
19661 {
19662   vl_api_show_one_status_t *mp;
19663   int ret;
19664
19665   if (!vam->json_output)
19666     {
19667       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19668     }
19669
19670   M (SHOW_ONE_STATUS, mp);
19671   /* send it... */
19672   S (mp);
19673   /* Wait for a reply... */
19674   W (ret);
19675   return ret;
19676 }
19677
19678 #define api_show_lisp_status api_show_one_status
19679
19680 static int
19681 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19682 {
19683   vl_api_gpe_fwd_entry_path_dump_t *mp;
19684   vl_api_control_ping_t *mp_ping;
19685   unformat_input_t *i = vam->input;
19686   u32 fwd_entry_index = ~0;
19687   int ret;
19688
19689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19690     {
19691       if (unformat (i, "index %d", &fwd_entry_index))
19692         ;
19693       else
19694         break;
19695     }
19696
19697   if (~0 == fwd_entry_index)
19698     {
19699       errmsg ("no index specified!");
19700       return -99;
19701     }
19702
19703   if (!vam->json_output)
19704     {
19705       print (vam->ofp, "first line");
19706     }
19707
19708   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19709
19710   /* send it... */
19711   S (mp);
19712   /* Use a control ping for synchronization */
19713   MPING (CONTROL_PING, mp_ping);
19714   S (mp_ping);
19715
19716   /* Wait for a reply... */
19717   W (ret);
19718   return ret;
19719 }
19720
19721 static int
19722 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19723 {
19724   vl_api_one_get_map_request_itr_rlocs_t *mp;
19725   int ret;
19726
19727   if (!vam->json_output)
19728     {
19729       print (vam->ofp, "%=20s", "itr-rlocs:");
19730     }
19731
19732   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19733   /* send it... */
19734   S (mp);
19735   /* Wait for a reply... */
19736   W (ret);
19737   return ret;
19738 }
19739
19740 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19741
19742 static int
19743 api_af_packet_create (vat_main_t * vam)
19744 {
19745   unformat_input_t *i = vam->input;
19746   vl_api_af_packet_create_t *mp;
19747   u8 *host_if_name = 0;
19748   u8 hw_addr[6];
19749   u8 random_hw_addr = 1;
19750   int ret;
19751
19752   memset (hw_addr, 0, sizeof (hw_addr));
19753
19754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19755     {
19756       if (unformat (i, "name %s", &host_if_name))
19757         vec_add1 (host_if_name, 0);
19758       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19759         random_hw_addr = 0;
19760       else
19761         break;
19762     }
19763
19764   if (!vec_len (host_if_name))
19765     {
19766       errmsg ("host-interface name must be specified");
19767       return -99;
19768     }
19769
19770   if (vec_len (host_if_name) > 64)
19771     {
19772       errmsg ("host-interface name too long");
19773       return -99;
19774     }
19775
19776   M (AF_PACKET_CREATE, mp);
19777
19778   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19779   clib_memcpy (mp->hw_addr, hw_addr, 6);
19780   mp->use_random_hw_addr = random_hw_addr;
19781   vec_free (host_if_name);
19782
19783   S (mp);
19784
19785   /* *INDENT-OFF* */
19786   W2 (ret,
19787       ({
19788         if (ret == 0)
19789           fprintf (vam->ofp ? vam->ofp : stderr,
19790                    " new sw_if_index = %d\n", vam->sw_if_index);
19791       }));
19792   /* *INDENT-ON* */
19793   return ret;
19794 }
19795
19796 static int
19797 api_af_packet_delete (vat_main_t * vam)
19798 {
19799   unformat_input_t *i = vam->input;
19800   vl_api_af_packet_delete_t *mp;
19801   u8 *host_if_name = 0;
19802   int ret;
19803
19804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19805     {
19806       if (unformat (i, "name %s", &host_if_name))
19807         vec_add1 (host_if_name, 0);
19808       else
19809         break;
19810     }
19811
19812   if (!vec_len (host_if_name))
19813     {
19814       errmsg ("host-interface name must be specified");
19815       return -99;
19816     }
19817
19818   if (vec_len (host_if_name) > 64)
19819     {
19820       errmsg ("host-interface name too long");
19821       return -99;
19822     }
19823
19824   M (AF_PACKET_DELETE, mp);
19825
19826   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19827   vec_free (host_if_name);
19828
19829   S (mp);
19830   W (ret);
19831   return ret;
19832 }
19833
19834 static int
19835 api_policer_add_del (vat_main_t * vam)
19836 {
19837   unformat_input_t *i = vam->input;
19838   vl_api_policer_add_del_t *mp;
19839   u8 is_add = 1;
19840   u8 *name = 0;
19841   u32 cir = 0;
19842   u32 eir = 0;
19843   u64 cb = 0;
19844   u64 eb = 0;
19845   u8 rate_type = 0;
19846   u8 round_type = 0;
19847   u8 type = 0;
19848   u8 color_aware = 0;
19849   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19850   int ret;
19851
19852   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19853   conform_action.dscp = 0;
19854   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19855   exceed_action.dscp = 0;
19856   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19857   violate_action.dscp = 0;
19858
19859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19860     {
19861       if (unformat (i, "del"))
19862         is_add = 0;
19863       else if (unformat (i, "name %s", &name))
19864         vec_add1 (name, 0);
19865       else if (unformat (i, "cir %u", &cir))
19866         ;
19867       else if (unformat (i, "eir %u", &eir))
19868         ;
19869       else if (unformat (i, "cb %u", &cb))
19870         ;
19871       else if (unformat (i, "eb %u", &eb))
19872         ;
19873       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19874                          &rate_type))
19875         ;
19876       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19877                          &round_type))
19878         ;
19879       else if (unformat (i, "type %U", unformat_policer_type, &type))
19880         ;
19881       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19882                          &conform_action))
19883         ;
19884       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19885                          &exceed_action))
19886         ;
19887       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19888                          &violate_action))
19889         ;
19890       else if (unformat (i, "color-aware"))
19891         color_aware = 1;
19892       else
19893         break;
19894     }
19895
19896   if (!vec_len (name))
19897     {
19898       errmsg ("policer name must be specified");
19899       return -99;
19900     }
19901
19902   if (vec_len (name) > 64)
19903     {
19904       errmsg ("policer name too long");
19905       return -99;
19906     }
19907
19908   M (POLICER_ADD_DEL, mp);
19909
19910   clib_memcpy (mp->name, name, vec_len (name));
19911   vec_free (name);
19912   mp->is_add = is_add;
19913   mp->cir = ntohl (cir);
19914   mp->eir = ntohl (eir);
19915   mp->cb = clib_net_to_host_u64 (cb);
19916   mp->eb = clib_net_to_host_u64 (eb);
19917   mp->rate_type = rate_type;
19918   mp->round_type = round_type;
19919   mp->type = type;
19920   mp->conform_action_type = conform_action.action_type;
19921   mp->conform_dscp = conform_action.dscp;
19922   mp->exceed_action_type = exceed_action.action_type;
19923   mp->exceed_dscp = exceed_action.dscp;
19924   mp->violate_action_type = violate_action.action_type;
19925   mp->violate_dscp = violate_action.dscp;
19926   mp->color_aware = color_aware;
19927
19928   S (mp);
19929   W (ret);
19930   return ret;
19931 }
19932
19933 static int
19934 api_policer_dump (vat_main_t * vam)
19935 {
19936   unformat_input_t *i = vam->input;
19937   vl_api_policer_dump_t *mp;
19938   vl_api_control_ping_t *mp_ping;
19939   u8 *match_name = 0;
19940   u8 match_name_valid = 0;
19941   int ret;
19942
19943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19944     {
19945       if (unformat (i, "name %s", &match_name))
19946         {
19947           vec_add1 (match_name, 0);
19948           match_name_valid = 1;
19949         }
19950       else
19951         break;
19952     }
19953
19954   M (POLICER_DUMP, mp);
19955   mp->match_name_valid = match_name_valid;
19956   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19957   vec_free (match_name);
19958   /* send it... */
19959   S (mp);
19960
19961   /* Use a control ping for synchronization */
19962   MPING (CONTROL_PING, mp_ping);
19963   S (mp_ping);
19964
19965   /* Wait for a reply... */
19966   W (ret);
19967   return ret;
19968 }
19969
19970 static int
19971 api_policer_classify_set_interface (vat_main_t * vam)
19972 {
19973   unformat_input_t *i = vam->input;
19974   vl_api_policer_classify_set_interface_t *mp;
19975   u32 sw_if_index;
19976   int sw_if_index_set;
19977   u32 ip4_table_index = ~0;
19978   u32 ip6_table_index = ~0;
19979   u32 l2_table_index = ~0;
19980   u8 is_add = 1;
19981   int ret;
19982
19983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19984     {
19985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19986         sw_if_index_set = 1;
19987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19988         sw_if_index_set = 1;
19989       else if (unformat (i, "del"))
19990         is_add = 0;
19991       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19992         ;
19993       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19994         ;
19995       else if (unformat (i, "l2-table %d", &l2_table_index))
19996         ;
19997       else
19998         {
19999           clib_warning ("parse error '%U'", format_unformat_error, i);
20000           return -99;
20001         }
20002     }
20003
20004   if (sw_if_index_set == 0)
20005     {
20006       errmsg ("missing interface name or sw_if_index");
20007       return -99;
20008     }
20009
20010   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20011
20012   mp->sw_if_index = ntohl (sw_if_index);
20013   mp->ip4_table_index = ntohl (ip4_table_index);
20014   mp->ip6_table_index = ntohl (ip6_table_index);
20015   mp->l2_table_index = ntohl (l2_table_index);
20016   mp->is_add = is_add;
20017
20018   S (mp);
20019   W (ret);
20020   return ret;
20021 }
20022
20023 static int
20024 api_policer_classify_dump (vat_main_t * vam)
20025 {
20026   unformat_input_t *i = vam->input;
20027   vl_api_policer_classify_dump_t *mp;
20028   vl_api_control_ping_t *mp_ping;
20029   u8 type = POLICER_CLASSIFY_N_TABLES;
20030   int ret;
20031
20032   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20033     ;
20034   else
20035     {
20036       errmsg ("classify table type must be specified");
20037       return -99;
20038     }
20039
20040   if (!vam->json_output)
20041     {
20042       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20043     }
20044
20045   M (POLICER_CLASSIFY_DUMP, mp);
20046   mp->type = type;
20047   /* send it... */
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   /* Wait for a reply... */
20055   W (ret);
20056   return ret;
20057 }
20058
20059 static int
20060 api_netmap_create (vat_main_t * vam)
20061 {
20062   unformat_input_t *i = vam->input;
20063   vl_api_netmap_create_t *mp;
20064   u8 *if_name = 0;
20065   u8 hw_addr[6];
20066   u8 random_hw_addr = 1;
20067   u8 is_pipe = 0;
20068   u8 is_master = 0;
20069   int ret;
20070
20071   memset (hw_addr, 0, sizeof (hw_addr));
20072
20073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20074     {
20075       if (unformat (i, "name %s", &if_name))
20076         vec_add1 (if_name, 0);
20077       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20078         random_hw_addr = 0;
20079       else if (unformat (i, "pipe"))
20080         is_pipe = 1;
20081       else if (unformat (i, "master"))
20082         is_master = 1;
20083       else if (unformat (i, "slave"))
20084         is_master = 0;
20085       else
20086         break;
20087     }
20088
20089   if (!vec_len (if_name))
20090     {
20091       errmsg ("interface name must be specified");
20092       return -99;
20093     }
20094
20095   if (vec_len (if_name) > 64)
20096     {
20097       errmsg ("interface name too long");
20098       return -99;
20099     }
20100
20101   M (NETMAP_CREATE, mp);
20102
20103   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20104   clib_memcpy (mp->hw_addr, hw_addr, 6);
20105   mp->use_random_hw_addr = random_hw_addr;
20106   mp->is_pipe = is_pipe;
20107   mp->is_master = is_master;
20108   vec_free (if_name);
20109
20110   S (mp);
20111   W (ret);
20112   return ret;
20113 }
20114
20115 static int
20116 api_netmap_delete (vat_main_t * vam)
20117 {
20118   unformat_input_t *i = vam->input;
20119   vl_api_netmap_delete_t *mp;
20120   u8 *if_name = 0;
20121   int ret;
20122
20123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20124     {
20125       if (unformat (i, "name %s", &if_name))
20126         vec_add1 (if_name, 0);
20127       else
20128         break;
20129     }
20130
20131   if (!vec_len (if_name))
20132     {
20133       errmsg ("interface name must be specified");
20134       return -99;
20135     }
20136
20137   if (vec_len (if_name) > 64)
20138     {
20139       errmsg ("interface name too long");
20140       return -99;
20141     }
20142
20143   M (NETMAP_DELETE, mp);
20144
20145   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20146   vec_free (if_name);
20147
20148   S (mp);
20149   W (ret);
20150   return ret;
20151 }
20152
20153 static void
20154 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20155 {
20156   if (fp->afi == IP46_TYPE_IP6)
20157     print (vam->ofp,
20158            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20159            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20160            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20161            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20162            format_ip6_address, fp->next_hop);
20163   else if (fp->afi == IP46_TYPE_IP4)
20164     print (vam->ofp,
20165            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20166            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20167            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20168            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20169            format_ip4_address, fp->next_hop);
20170 }
20171
20172 static void
20173 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20174                                  vl_api_fib_path_t * fp)
20175 {
20176   struct in_addr ip4;
20177   struct in6_addr ip6;
20178
20179   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20180   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20181   vat_json_object_add_uint (node, "is_local", fp->is_local);
20182   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20183   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20184   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20185   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20186   if (fp->afi == IP46_TYPE_IP4)
20187     {
20188       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20189       vat_json_object_add_ip4 (node, "next_hop", ip4);
20190     }
20191   else if (fp->afi == IP46_TYPE_IP6)
20192     {
20193       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20194       vat_json_object_add_ip6 (node, "next_hop", ip6);
20195     }
20196 }
20197
20198 static void
20199 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20200 {
20201   vat_main_t *vam = &vat_main;
20202   int count = ntohl (mp->mt_count);
20203   vl_api_fib_path_t *fp;
20204   i32 i;
20205
20206   print (vam->ofp, "[%d]: sw_if_index %d via:",
20207          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20208   fp = mp->mt_paths;
20209   for (i = 0; i < count; i++)
20210     {
20211       vl_api_mpls_fib_path_print (vam, fp);
20212       fp++;
20213     }
20214
20215   print (vam->ofp, "");
20216 }
20217
20218 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20219 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20220
20221 static void
20222 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20223 {
20224   vat_main_t *vam = &vat_main;
20225   vat_json_node_t *node = NULL;
20226   int count = ntohl (mp->mt_count);
20227   vl_api_fib_path_t *fp;
20228   i32 i;
20229
20230   if (VAT_JSON_ARRAY != vam->json_tree.type)
20231     {
20232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20233       vat_json_init_array (&vam->json_tree);
20234     }
20235   node = vat_json_array_add (&vam->json_tree);
20236
20237   vat_json_init_object (node);
20238   vat_json_object_add_uint (node, "tunnel_index",
20239                             ntohl (mp->mt_tunnel_index));
20240   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20241
20242   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20243
20244   fp = mp->mt_paths;
20245   for (i = 0; i < count; i++)
20246     {
20247       vl_api_mpls_fib_path_json_print (node, fp);
20248       fp++;
20249     }
20250 }
20251
20252 static int
20253 api_mpls_tunnel_dump (vat_main_t * vam)
20254 {
20255   vl_api_mpls_tunnel_dump_t *mp;
20256   vl_api_control_ping_t *mp_ping;
20257   i32 index = -1;
20258   int ret;
20259
20260   /* Parse args required to build the message */
20261   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20262     {
20263       if (!unformat (vam->input, "tunnel_index %d", &index))
20264         {
20265           index = -1;
20266           break;
20267         }
20268     }
20269
20270   print (vam->ofp, "  tunnel_index %d", index);
20271
20272   M (MPLS_TUNNEL_DUMP, mp);
20273   mp->tunnel_index = htonl (index);
20274   S (mp);
20275
20276   /* Use a control ping for synchronization */
20277   MPING (CONTROL_PING, mp_ping);
20278   S (mp_ping);
20279
20280   W (ret);
20281   return ret;
20282 }
20283
20284 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20285 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20286
20287
20288 static void
20289 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20290 {
20291   vat_main_t *vam = &vat_main;
20292   int count = ntohl (mp->count);
20293   vl_api_fib_path_t *fp;
20294   int i;
20295
20296   print (vam->ofp,
20297          "table-id %d, label %u, ess_bit %u",
20298          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20299   fp = mp->path;
20300   for (i = 0; i < count; i++)
20301     {
20302       vl_api_mpls_fib_path_print (vam, fp);
20303       fp++;
20304     }
20305 }
20306
20307 static void vl_api_mpls_fib_details_t_handler_json
20308   (vl_api_mpls_fib_details_t * mp)
20309 {
20310   vat_main_t *vam = &vat_main;
20311   int count = ntohl (mp->count);
20312   vat_json_node_t *node = NULL;
20313   vl_api_fib_path_t *fp;
20314   int i;
20315
20316   if (VAT_JSON_ARRAY != vam->json_tree.type)
20317     {
20318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20319       vat_json_init_array (&vam->json_tree);
20320     }
20321   node = vat_json_array_add (&vam->json_tree);
20322
20323   vat_json_init_object (node);
20324   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20325   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20326   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20327   vat_json_object_add_uint (node, "path_count", count);
20328   fp = mp->path;
20329   for (i = 0; i < count; i++)
20330     {
20331       vl_api_mpls_fib_path_json_print (node, fp);
20332       fp++;
20333     }
20334 }
20335
20336 static int
20337 api_mpls_fib_dump (vat_main_t * vam)
20338 {
20339   vl_api_mpls_fib_dump_t *mp;
20340   vl_api_control_ping_t *mp_ping;
20341   int ret;
20342
20343   M (MPLS_FIB_DUMP, mp);
20344   S (mp);
20345
20346   /* Use a control ping for synchronization */
20347   MPING (CONTROL_PING, mp_ping);
20348   S (mp_ping);
20349
20350   W (ret);
20351   return ret;
20352 }
20353
20354 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20355 #define vl_api_ip_fib_details_t_print vl_noop_handler
20356
20357 static void
20358 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20359 {
20360   vat_main_t *vam = &vat_main;
20361   int count = ntohl (mp->count);
20362   vl_api_fib_path_t *fp;
20363   int i;
20364
20365   print (vam->ofp,
20366          "table-id %d, prefix %U/%d",
20367          ntohl (mp->table_id), format_ip4_address, mp->address,
20368          mp->address_length);
20369   fp = mp->path;
20370   for (i = 0; i < count; i++)
20371     {
20372       if (fp->afi == IP46_TYPE_IP6)
20373         print (vam->ofp,
20374                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20375                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20376                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20377                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20378                format_ip6_address, fp->next_hop);
20379       else if (fp->afi == IP46_TYPE_IP4)
20380         print (vam->ofp,
20381                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20382                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20383                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20384                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20385                format_ip4_address, fp->next_hop);
20386       fp++;
20387     }
20388 }
20389
20390 static void vl_api_ip_fib_details_t_handler_json
20391   (vl_api_ip_fib_details_t * mp)
20392 {
20393   vat_main_t *vam = &vat_main;
20394   int count = ntohl (mp->count);
20395   vat_json_node_t *node = NULL;
20396   struct in_addr ip4;
20397   struct in6_addr ip6;
20398   vl_api_fib_path_t *fp;
20399   int i;
20400
20401   if (VAT_JSON_ARRAY != vam->json_tree.type)
20402     {
20403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20404       vat_json_init_array (&vam->json_tree);
20405     }
20406   node = vat_json_array_add (&vam->json_tree);
20407
20408   vat_json_init_object (node);
20409   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20410   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20411   vat_json_object_add_ip4 (node, "prefix", ip4);
20412   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20413   vat_json_object_add_uint (node, "path_count", count);
20414   fp = mp->path;
20415   for (i = 0; i < count; i++)
20416     {
20417       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20418       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20419       vat_json_object_add_uint (node, "is_local", fp->is_local);
20420       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20421       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20422       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20423       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20424       if (fp->afi == IP46_TYPE_IP4)
20425         {
20426           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20427           vat_json_object_add_ip4 (node, "next_hop", ip4);
20428         }
20429       else if (fp->afi == IP46_TYPE_IP6)
20430         {
20431           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20432           vat_json_object_add_ip6 (node, "next_hop", ip6);
20433         }
20434     }
20435 }
20436
20437 static int
20438 api_ip_fib_dump (vat_main_t * vam)
20439 {
20440   vl_api_ip_fib_dump_t *mp;
20441   vl_api_control_ping_t *mp_ping;
20442   int ret;
20443
20444   M (IP_FIB_DUMP, mp);
20445   S (mp);
20446
20447   /* Use a control ping for synchronization */
20448   MPING (CONTROL_PING, mp_ping);
20449   S (mp_ping);
20450
20451   W (ret);
20452   return ret;
20453 }
20454
20455 static int
20456 api_ip_mfib_dump (vat_main_t * vam)
20457 {
20458   vl_api_ip_mfib_dump_t *mp;
20459   vl_api_control_ping_t *mp_ping;
20460   int ret;
20461
20462   M (IP_MFIB_DUMP, mp);
20463   S (mp);
20464
20465   /* Use a control ping for synchronization */
20466   MPING (CONTROL_PING, mp_ping);
20467   S (mp_ping);
20468
20469   W (ret);
20470   return ret;
20471 }
20472
20473 static void vl_api_ip_neighbor_details_t_handler
20474   (vl_api_ip_neighbor_details_t * mp)
20475 {
20476   vat_main_t *vam = &vat_main;
20477
20478   print (vam->ofp, "%c %U %U",
20479          (mp->is_static) ? 'S' : 'D',
20480          format_ethernet_address, &mp->mac_address,
20481          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20482          &mp->ip_address);
20483 }
20484
20485 static void vl_api_ip_neighbor_details_t_handler_json
20486   (vl_api_ip_neighbor_details_t * mp)
20487 {
20488
20489   vat_main_t *vam = &vat_main;
20490   vat_json_node_t *node;
20491   struct in_addr ip4;
20492   struct in6_addr ip6;
20493
20494   if (VAT_JSON_ARRAY != vam->json_tree.type)
20495     {
20496       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20497       vat_json_init_array (&vam->json_tree);
20498     }
20499   node = vat_json_array_add (&vam->json_tree);
20500
20501   vat_json_init_object (node);
20502   vat_json_object_add_string_copy (node, "flag",
20503                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20504                                    "dynamic");
20505
20506   vat_json_object_add_string_copy (node, "link_layer",
20507                                    format (0, "%U", format_ethernet_address,
20508                                            &mp->mac_address));
20509
20510   if (mp->is_ipv6)
20511     {
20512       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20513       vat_json_object_add_ip6 (node, "ip_address", ip6);
20514     }
20515   else
20516     {
20517       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20518       vat_json_object_add_ip4 (node, "ip_address", ip4);
20519     }
20520 }
20521
20522 static int
20523 api_ip_neighbor_dump (vat_main_t * vam)
20524 {
20525   unformat_input_t *i = vam->input;
20526   vl_api_ip_neighbor_dump_t *mp;
20527   vl_api_control_ping_t *mp_ping;
20528   u8 is_ipv6 = 0;
20529   u32 sw_if_index = ~0;
20530   int ret;
20531
20532   /* Parse args required to build the message */
20533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20534     {
20535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20536         ;
20537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20538         ;
20539       else if (unformat (i, "ip6"))
20540         is_ipv6 = 1;
20541       else
20542         break;
20543     }
20544
20545   if (sw_if_index == ~0)
20546     {
20547       errmsg ("missing interface name or sw_if_index");
20548       return -99;
20549     }
20550
20551   M (IP_NEIGHBOR_DUMP, mp);
20552   mp->is_ipv6 = (u8) is_ipv6;
20553   mp->sw_if_index = ntohl (sw_if_index);
20554   S (mp);
20555
20556   /* Use a control ping for synchronization */
20557   MPING (CONTROL_PING, mp_ping);
20558   S (mp_ping);
20559
20560   W (ret);
20561   return ret;
20562 }
20563
20564 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20565 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20566
20567 static void
20568 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20569 {
20570   vat_main_t *vam = &vat_main;
20571   int count = ntohl (mp->count);
20572   vl_api_fib_path_t *fp;
20573   int i;
20574
20575   print (vam->ofp,
20576          "table-id %d, prefix %U/%d",
20577          ntohl (mp->table_id), format_ip6_address, mp->address,
20578          mp->address_length);
20579   fp = mp->path;
20580   for (i = 0; i < count; i++)
20581     {
20582       if (fp->afi == IP46_TYPE_IP6)
20583         print (vam->ofp,
20584                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20585                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20586                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20587                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20588                format_ip6_address, fp->next_hop);
20589       else if (fp->afi == IP46_TYPE_IP4)
20590         print (vam->ofp,
20591                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20592                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20593                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20594                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20595                format_ip4_address, fp->next_hop);
20596       fp++;
20597     }
20598 }
20599
20600 static void vl_api_ip6_fib_details_t_handler_json
20601   (vl_api_ip6_fib_details_t * mp)
20602 {
20603   vat_main_t *vam = &vat_main;
20604   int count = ntohl (mp->count);
20605   vat_json_node_t *node = NULL;
20606   struct in_addr ip4;
20607   struct in6_addr ip6;
20608   vl_api_fib_path_t *fp;
20609   int i;
20610
20611   if (VAT_JSON_ARRAY != vam->json_tree.type)
20612     {
20613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20614       vat_json_init_array (&vam->json_tree);
20615     }
20616   node = vat_json_array_add (&vam->json_tree);
20617
20618   vat_json_init_object (node);
20619   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20620   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20621   vat_json_object_add_ip6 (node, "prefix", ip6);
20622   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20623   vat_json_object_add_uint (node, "path_count", count);
20624   fp = mp->path;
20625   for (i = 0; i < count; i++)
20626     {
20627       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20628       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20629       vat_json_object_add_uint (node, "is_local", fp->is_local);
20630       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20631       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20632       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20633       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20634       if (fp->afi == IP46_TYPE_IP4)
20635         {
20636           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20637           vat_json_object_add_ip4 (node, "next_hop", ip4);
20638         }
20639       else if (fp->afi == IP46_TYPE_IP6)
20640         {
20641           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20642           vat_json_object_add_ip6 (node, "next_hop", ip6);
20643         }
20644     }
20645 }
20646
20647 static int
20648 api_ip6_fib_dump (vat_main_t * vam)
20649 {
20650   vl_api_ip6_fib_dump_t *mp;
20651   vl_api_control_ping_t *mp_ping;
20652   int ret;
20653
20654   M (IP6_FIB_DUMP, mp);
20655   S (mp);
20656
20657   /* Use a control ping for synchronization */
20658   MPING (CONTROL_PING, mp_ping);
20659   S (mp_ping);
20660
20661   W (ret);
20662   return ret;
20663 }
20664
20665 static int
20666 api_ip6_mfib_dump (vat_main_t * vam)
20667 {
20668   vl_api_ip6_mfib_dump_t *mp;
20669   vl_api_control_ping_t *mp_ping;
20670   int ret;
20671
20672   M (IP6_MFIB_DUMP, mp);
20673   S (mp);
20674
20675   /* Use a control ping for synchronization */
20676   MPING (CONTROL_PING, mp_ping);
20677   S (mp_ping);
20678
20679   W (ret);
20680   return ret;
20681 }
20682
20683 int
20684 api_classify_table_ids (vat_main_t * vam)
20685 {
20686   vl_api_classify_table_ids_t *mp;
20687   int ret;
20688
20689   /* Construct the API message */
20690   M (CLASSIFY_TABLE_IDS, mp);
20691   mp->context = 0;
20692
20693   S (mp);
20694   W (ret);
20695   return ret;
20696 }
20697
20698 int
20699 api_classify_table_by_interface (vat_main_t * vam)
20700 {
20701   unformat_input_t *input = vam->input;
20702   vl_api_classify_table_by_interface_t *mp;
20703
20704   u32 sw_if_index = ~0;
20705   int ret;
20706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20707     {
20708       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20709         ;
20710       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20711         ;
20712       else
20713         break;
20714     }
20715   if (sw_if_index == ~0)
20716     {
20717       errmsg ("missing interface name or sw_if_index");
20718       return -99;
20719     }
20720
20721   /* Construct the API message */
20722   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20723   mp->context = 0;
20724   mp->sw_if_index = ntohl (sw_if_index);
20725
20726   S (mp);
20727   W (ret);
20728   return ret;
20729 }
20730
20731 int
20732 api_classify_table_info (vat_main_t * vam)
20733 {
20734   unformat_input_t *input = vam->input;
20735   vl_api_classify_table_info_t *mp;
20736
20737   u32 table_id = ~0;
20738   int ret;
20739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20740     {
20741       if (unformat (input, "table_id %d", &table_id))
20742         ;
20743       else
20744         break;
20745     }
20746   if (table_id == ~0)
20747     {
20748       errmsg ("missing table id");
20749       return -99;
20750     }
20751
20752   /* Construct the API message */
20753   M (CLASSIFY_TABLE_INFO, mp);
20754   mp->context = 0;
20755   mp->table_id = ntohl (table_id);
20756
20757   S (mp);
20758   W (ret);
20759   return ret;
20760 }
20761
20762 int
20763 api_classify_session_dump (vat_main_t * vam)
20764 {
20765   unformat_input_t *input = vam->input;
20766   vl_api_classify_session_dump_t *mp;
20767   vl_api_control_ping_t *mp_ping;
20768
20769   u32 table_id = ~0;
20770   int ret;
20771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20772     {
20773       if (unformat (input, "table_id %d", &table_id))
20774         ;
20775       else
20776         break;
20777     }
20778   if (table_id == ~0)
20779     {
20780       errmsg ("missing table id");
20781       return -99;
20782     }
20783
20784   /* Construct the API message */
20785   M (CLASSIFY_SESSION_DUMP, mp);
20786   mp->context = 0;
20787   mp->table_id = ntohl (table_id);
20788   S (mp);
20789
20790   /* Use a control ping for synchronization */
20791   MPING (CONTROL_PING, mp_ping);
20792   S (mp_ping);
20793
20794   W (ret);
20795   return ret;
20796 }
20797
20798 static void
20799 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20800 {
20801   vat_main_t *vam = &vat_main;
20802
20803   print (vam->ofp, "collector_address %U, collector_port %d, "
20804          "src_address %U, vrf_id %d, path_mtu %u, "
20805          "template_interval %u, udp_checksum %d",
20806          format_ip4_address, mp->collector_address,
20807          ntohs (mp->collector_port),
20808          format_ip4_address, mp->src_address,
20809          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20810          ntohl (mp->template_interval), mp->udp_checksum);
20811
20812   vam->retval = 0;
20813   vam->result_ready = 1;
20814 }
20815
20816 static void
20817   vl_api_ipfix_exporter_details_t_handler_json
20818   (vl_api_ipfix_exporter_details_t * mp)
20819 {
20820   vat_main_t *vam = &vat_main;
20821   vat_json_node_t node;
20822   struct in_addr collector_address;
20823   struct in_addr src_address;
20824
20825   vat_json_init_object (&node);
20826   clib_memcpy (&collector_address, &mp->collector_address,
20827                sizeof (collector_address));
20828   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20829   vat_json_object_add_uint (&node, "collector_port",
20830                             ntohs (mp->collector_port));
20831   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20832   vat_json_object_add_ip4 (&node, "src_address", src_address);
20833   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20834   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20835   vat_json_object_add_uint (&node, "template_interval",
20836                             ntohl (mp->template_interval));
20837   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20838
20839   vat_json_print (vam->ofp, &node);
20840   vat_json_free (&node);
20841   vam->retval = 0;
20842   vam->result_ready = 1;
20843 }
20844
20845 int
20846 api_ipfix_exporter_dump (vat_main_t * vam)
20847 {
20848   vl_api_ipfix_exporter_dump_t *mp;
20849   int ret;
20850
20851   /* Construct the API message */
20852   M (IPFIX_EXPORTER_DUMP, mp);
20853   mp->context = 0;
20854
20855   S (mp);
20856   W (ret);
20857   return ret;
20858 }
20859
20860 static int
20861 api_ipfix_classify_stream_dump (vat_main_t * vam)
20862 {
20863   vl_api_ipfix_classify_stream_dump_t *mp;
20864   int ret;
20865
20866   /* Construct the API message */
20867   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20868   mp->context = 0;
20869
20870   S (mp);
20871   W (ret);
20872   return ret;
20873   /* NOTREACHED */
20874   return 0;
20875 }
20876
20877 static void
20878   vl_api_ipfix_classify_stream_details_t_handler
20879   (vl_api_ipfix_classify_stream_details_t * mp)
20880 {
20881   vat_main_t *vam = &vat_main;
20882   print (vam->ofp, "domain_id %d, src_port %d",
20883          ntohl (mp->domain_id), ntohs (mp->src_port));
20884   vam->retval = 0;
20885   vam->result_ready = 1;
20886 }
20887
20888 static void
20889   vl_api_ipfix_classify_stream_details_t_handler_json
20890   (vl_api_ipfix_classify_stream_details_t * mp)
20891 {
20892   vat_main_t *vam = &vat_main;
20893   vat_json_node_t node;
20894
20895   vat_json_init_object (&node);
20896   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20897   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20898
20899   vat_json_print (vam->ofp, &node);
20900   vat_json_free (&node);
20901   vam->retval = 0;
20902   vam->result_ready = 1;
20903 }
20904
20905 static int
20906 api_ipfix_classify_table_dump (vat_main_t * vam)
20907 {
20908   vl_api_ipfix_classify_table_dump_t *mp;
20909   vl_api_control_ping_t *mp_ping;
20910   int ret;
20911
20912   if (!vam->json_output)
20913     {
20914       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20915              "transport_protocol");
20916     }
20917
20918   /* Construct the API message */
20919   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20920
20921   /* send it... */
20922   S (mp);
20923
20924   /* Use a control ping for synchronization */
20925   MPING (CONTROL_PING, mp_ping);
20926   S (mp_ping);
20927
20928   W (ret);
20929   return ret;
20930 }
20931
20932 static void
20933   vl_api_ipfix_classify_table_details_t_handler
20934   (vl_api_ipfix_classify_table_details_t * mp)
20935 {
20936   vat_main_t *vam = &vat_main;
20937   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20938          mp->transport_protocol);
20939 }
20940
20941 static void
20942   vl_api_ipfix_classify_table_details_t_handler_json
20943   (vl_api_ipfix_classify_table_details_t * mp)
20944 {
20945   vat_json_node_t *node = NULL;
20946   vat_main_t *vam = &vat_main;
20947
20948   if (VAT_JSON_ARRAY != vam->json_tree.type)
20949     {
20950       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20951       vat_json_init_array (&vam->json_tree);
20952     }
20953
20954   node = vat_json_array_add (&vam->json_tree);
20955   vat_json_init_object (node);
20956
20957   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20958   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20959   vat_json_object_add_uint (node, "transport_protocol",
20960                             mp->transport_protocol);
20961 }
20962
20963 static int
20964 api_sw_interface_span_enable_disable (vat_main_t * vam)
20965 {
20966   unformat_input_t *i = vam->input;
20967   vl_api_sw_interface_span_enable_disable_t *mp;
20968   u32 src_sw_if_index = ~0;
20969   u32 dst_sw_if_index = ~0;
20970   u8 state = 3;
20971   int ret;
20972   u8 is_l2 = 0;
20973
20974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20975     {
20976       if (unformat
20977           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20978         ;
20979       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20980         ;
20981       else
20982         if (unformat
20983             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20984         ;
20985       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20986         ;
20987       else if (unformat (i, "disable"))
20988         state = 0;
20989       else if (unformat (i, "rx"))
20990         state = 1;
20991       else if (unformat (i, "tx"))
20992         state = 2;
20993       else if (unformat (i, "both"))
20994         state = 3;
20995       else if (unformat (i, "l2"))
20996         is_l2 = 1;
20997       else
20998         break;
20999     }
21000
21001   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21002
21003   mp->sw_if_index_from = htonl (src_sw_if_index);
21004   mp->sw_if_index_to = htonl (dst_sw_if_index);
21005   mp->state = state;
21006   mp->is_l2 = is_l2;
21007
21008   S (mp);
21009   W (ret);
21010   return ret;
21011 }
21012
21013 static void
21014 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21015                                             * mp)
21016 {
21017   vat_main_t *vam = &vat_main;
21018   u8 *sw_if_from_name = 0;
21019   u8 *sw_if_to_name = 0;
21020   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21021   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21022   char *states[] = { "none", "rx", "tx", "both" };
21023   hash_pair_t *p;
21024
21025   /* *INDENT-OFF* */
21026   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21027   ({
21028     if ((u32) p->value[0] == sw_if_index_from)
21029       {
21030         sw_if_from_name = (u8 *)(p->key);
21031         if (sw_if_to_name)
21032           break;
21033       }
21034     if ((u32) p->value[0] == sw_if_index_to)
21035       {
21036         sw_if_to_name = (u8 *)(p->key);
21037         if (sw_if_from_name)
21038           break;
21039       }
21040   }));
21041   /* *INDENT-ON* */
21042   print (vam->ofp, "%20s => %20s (%s) %s",
21043          sw_if_from_name, sw_if_to_name, states[mp->state],
21044          mp->is_l2 ? "l2" : "device");
21045 }
21046
21047 static void
21048   vl_api_sw_interface_span_details_t_handler_json
21049   (vl_api_sw_interface_span_details_t * mp)
21050 {
21051   vat_main_t *vam = &vat_main;
21052   vat_json_node_t *node = NULL;
21053   u8 *sw_if_from_name = 0;
21054   u8 *sw_if_to_name = 0;
21055   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21056   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21057   hash_pair_t *p;
21058
21059   /* *INDENT-OFF* */
21060   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21061   ({
21062     if ((u32) p->value[0] == sw_if_index_from)
21063       {
21064         sw_if_from_name = (u8 *)(p->key);
21065         if (sw_if_to_name)
21066           break;
21067       }
21068     if ((u32) p->value[0] == sw_if_index_to)
21069       {
21070         sw_if_to_name = (u8 *)(p->key);
21071         if (sw_if_from_name)
21072           break;
21073       }
21074   }));
21075   /* *INDENT-ON* */
21076
21077   if (VAT_JSON_ARRAY != vam->json_tree.type)
21078     {
21079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21080       vat_json_init_array (&vam->json_tree);
21081     }
21082   node = vat_json_array_add (&vam->json_tree);
21083
21084   vat_json_init_object (node);
21085   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21086   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21087   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21088   if (0 != sw_if_to_name)
21089     {
21090       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21091     }
21092   vat_json_object_add_uint (node, "state", mp->state);
21093   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21094 }
21095
21096 static int
21097 api_sw_interface_span_dump (vat_main_t * vam)
21098 {
21099   unformat_input_t *input = vam->input;
21100   vl_api_sw_interface_span_dump_t *mp;
21101   vl_api_control_ping_t *mp_ping;
21102   u8 is_l2 = 0;
21103   int ret;
21104
21105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21106     {
21107       if (unformat (input, "l2"))
21108         is_l2 = 1;
21109       else
21110         break;
21111     }
21112
21113   M (SW_INTERFACE_SPAN_DUMP, mp);
21114   mp->is_l2 = is_l2;
21115   S (mp);
21116
21117   /* Use a control ping for synchronization */
21118   MPING (CONTROL_PING, mp_ping);
21119   S (mp_ping);
21120
21121   W (ret);
21122   return ret;
21123 }
21124
21125 int
21126 api_pg_create_interface (vat_main_t * vam)
21127 {
21128   unformat_input_t *input = vam->input;
21129   vl_api_pg_create_interface_t *mp;
21130
21131   u32 if_id = ~0;
21132   int ret;
21133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21134     {
21135       if (unformat (input, "if_id %d", &if_id))
21136         ;
21137       else
21138         break;
21139     }
21140   if (if_id == ~0)
21141     {
21142       errmsg ("missing pg interface index");
21143       return -99;
21144     }
21145
21146   /* Construct the API message */
21147   M (PG_CREATE_INTERFACE, mp);
21148   mp->context = 0;
21149   mp->interface_id = ntohl (if_id);
21150
21151   S (mp);
21152   W (ret);
21153   return ret;
21154 }
21155
21156 int
21157 api_pg_capture (vat_main_t * vam)
21158 {
21159   unformat_input_t *input = vam->input;
21160   vl_api_pg_capture_t *mp;
21161
21162   u32 if_id = ~0;
21163   u8 enable = 1;
21164   u32 count = 1;
21165   u8 pcap_file_set = 0;
21166   u8 *pcap_file = 0;
21167   int ret;
21168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21169     {
21170       if (unformat (input, "if_id %d", &if_id))
21171         ;
21172       else if (unformat (input, "pcap %s", &pcap_file))
21173         pcap_file_set = 1;
21174       else if (unformat (input, "count %d", &count))
21175         ;
21176       else if (unformat (input, "disable"))
21177         enable = 0;
21178       else
21179         break;
21180     }
21181   if (if_id == ~0)
21182     {
21183       errmsg ("missing pg interface index");
21184       return -99;
21185     }
21186   if (pcap_file_set > 0)
21187     {
21188       if (vec_len (pcap_file) > 255)
21189         {
21190           errmsg ("pcap file name is too long");
21191           return -99;
21192         }
21193     }
21194
21195   u32 name_len = vec_len (pcap_file);
21196   /* Construct the API message */
21197   M (PG_CAPTURE, mp);
21198   mp->context = 0;
21199   mp->interface_id = ntohl (if_id);
21200   mp->is_enabled = enable;
21201   mp->count = ntohl (count);
21202   mp->pcap_name_length = ntohl (name_len);
21203   if (pcap_file_set != 0)
21204     {
21205       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21206     }
21207   vec_free (pcap_file);
21208
21209   S (mp);
21210   W (ret);
21211   return ret;
21212 }
21213
21214 int
21215 api_pg_enable_disable (vat_main_t * vam)
21216 {
21217   unformat_input_t *input = vam->input;
21218   vl_api_pg_enable_disable_t *mp;
21219
21220   u8 enable = 1;
21221   u8 stream_name_set = 0;
21222   u8 *stream_name = 0;
21223   int ret;
21224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21225     {
21226       if (unformat (input, "stream %s", &stream_name))
21227         stream_name_set = 1;
21228       else if (unformat (input, "disable"))
21229         enable = 0;
21230       else
21231         break;
21232     }
21233
21234   if (stream_name_set > 0)
21235     {
21236       if (vec_len (stream_name) > 255)
21237         {
21238           errmsg ("stream name too long");
21239           return -99;
21240         }
21241     }
21242
21243   u32 name_len = vec_len (stream_name);
21244   /* Construct the API message */
21245   M (PG_ENABLE_DISABLE, mp);
21246   mp->context = 0;
21247   mp->is_enabled = enable;
21248   if (stream_name_set != 0)
21249     {
21250       mp->stream_name_length = ntohl (name_len);
21251       clib_memcpy (mp->stream_name, stream_name, name_len);
21252     }
21253   vec_free (stream_name);
21254
21255   S (mp);
21256   W (ret);
21257   return ret;
21258 }
21259
21260 int
21261 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21262 {
21263   unformat_input_t *input = vam->input;
21264   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21265
21266   u16 *low_ports = 0;
21267   u16 *high_ports = 0;
21268   u16 this_low;
21269   u16 this_hi;
21270   ip4_address_t ip4_addr;
21271   ip6_address_t ip6_addr;
21272   u32 length;
21273   u32 tmp, tmp2;
21274   u8 prefix_set = 0;
21275   u32 vrf_id = ~0;
21276   u8 is_add = 1;
21277   u8 is_ipv6 = 0;
21278   int ret;
21279
21280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21281     {
21282       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21283         {
21284           prefix_set = 1;
21285         }
21286       else
21287         if (unformat
21288             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21289         {
21290           prefix_set = 1;
21291           is_ipv6 = 1;
21292         }
21293       else if (unformat (input, "vrf %d", &vrf_id))
21294         ;
21295       else if (unformat (input, "del"))
21296         is_add = 0;
21297       else if (unformat (input, "port %d", &tmp))
21298         {
21299           if (tmp == 0 || tmp > 65535)
21300             {
21301               errmsg ("port %d out of range", tmp);
21302               return -99;
21303             }
21304           this_low = tmp;
21305           this_hi = this_low + 1;
21306           vec_add1 (low_ports, this_low);
21307           vec_add1 (high_ports, this_hi);
21308         }
21309       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21310         {
21311           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21312             {
21313               errmsg ("incorrect range parameters");
21314               return -99;
21315             }
21316           this_low = tmp;
21317           /* Note: in debug CLI +1 is added to high before
21318              passing to real fn that does "the work"
21319              (ip_source_and_port_range_check_add_del).
21320              This fn is a wrapper around the binary API fn a
21321              control plane will call, which expects this increment
21322              to have occurred. Hence letting the binary API control
21323              plane fn do the increment for consistency between VAT
21324              and other control planes.
21325            */
21326           this_hi = tmp2;
21327           vec_add1 (low_ports, this_low);
21328           vec_add1 (high_ports, this_hi);
21329         }
21330       else
21331         break;
21332     }
21333
21334   if (prefix_set == 0)
21335     {
21336       errmsg ("<address>/<mask> not specified");
21337       return -99;
21338     }
21339
21340   if (vrf_id == ~0)
21341     {
21342       errmsg ("VRF ID required, not specified");
21343       return -99;
21344     }
21345
21346   if (vrf_id == 0)
21347     {
21348       errmsg
21349         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21350       return -99;
21351     }
21352
21353   if (vec_len (low_ports) == 0)
21354     {
21355       errmsg ("At least one port or port range required");
21356       return -99;
21357     }
21358
21359   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21360
21361   mp->is_add = is_add;
21362
21363   if (is_ipv6)
21364     {
21365       mp->is_ipv6 = 1;
21366       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21367     }
21368   else
21369     {
21370       mp->is_ipv6 = 0;
21371       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21372     }
21373
21374   mp->mask_length = length;
21375   mp->number_of_ranges = vec_len (low_ports);
21376
21377   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21378   vec_free (low_ports);
21379
21380   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21381   vec_free (high_ports);
21382
21383   mp->vrf_id = ntohl (vrf_id);
21384
21385   S (mp);
21386   W (ret);
21387   return ret;
21388 }
21389
21390 int
21391 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21392 {
21393   unformat_input_t *input = vam->input;
21394   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21395   u32 sw_if_index = ~0;
21396   int vrf_set = 0;
21397   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21398   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21399   u8 is_add = 1;
21400   int ret;
21401
21402   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21403     {
21404       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21405         ;
21406       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21407         ;
21408       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21409         vrf_set = 1;
21410       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21411         vrf_set = 1;
21412       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21413         vrf_set = 1;
21414       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21415         vrf_set = 1;
21416       else if (unformat (input, "del"))
21417         is_add = 0;
21418       else
21419         break;
21420     }
21421
21422   if (sw_if_index == ~0)
21423     {
21424       errmsg ("Interface required but not specified");
21425       return -99;
21426     }
21427
21428   if (vrf_set == 0)
21429     {
21430       errmsg ("VRF ID required but not specified");
21431       return -99;
21432     }
21433
21434   if (tcp_out_vrf_id == 0
21435       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21436     {
21437       errmsg
21438         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21439       return -99;
21440     }
21441
21442   /* Construct the API message */
21443   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21444
21445   mp->sw_if_index = ntohl (sw_if_index);
21446   mp->is_add = is_add;
21447   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21448   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21449   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21450   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21451
21452   /* send it... */
21453   S (mp);
21454
21455   /* Wait for a reply... */
21456   W (ret);
21457   return ret;
21458 }
21459
21460 static int
21461 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21462 {
21463   unformat_input_t *i = vam->input;
21464   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21465   u32 local_sa_id = 0;
21466   u32 remote_sa_id = 0;
21467   ip4_address_t src_address;
21468   ip4_address_t dst_address;
21469   u8 is_add = 1;
21470   int ret;
21471
21472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21473     {
21474       if (unformat (i, "local_sa %d", &local_sa_id))
21475         ;
21476       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21477         ;
21478       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21479         ;
21480       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21481         ;
21482       else if (unformat (i, "del"))
21483         is_add = 0;
21484       else
21485         {
21486           clib_warning ("parse error '%U'", format_unformat_error, i);
21487           return -99;
21488         }
21489     }
21490
21491   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21492
21493   mp->local_sa_id = ntohl (local_sa_id);
21494   mp->remote_sa_id = ntohl (remote_sa_id);
21495   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21496   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21497   mp->is_add = is_add;
21498
21499   S (mp);
21500   W (ret);
21501   return ret;
21502 }
21503
21504 static int
21505 api_punt (vat_main_t * vam)
21506 {
21507   unformat_input_t *i = vam->input;
21508   vl_api_punt_t *mp;
21509   u32 ipv = ~0;
21510   u32 protocol = ~0;
21511   u32 port = ~0;
21512   int is_add = 1;
21513   int ret;
21514
21515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21516     {
21517       if (unformat (i, "ip %d", &ipv))
21518         ;
21519       else if (unformat (i, "protocol %d", &protocol))
21520         ;
21521       else if (unformat (i, "port %d", &port))
21522         ;
21523       else if (unformat (i, "del"))
21524         is_add = 0;
21525       else
21526         {
21527           clib_warning ("parse error '%U'", format_unformat_error, i);
21528           return -99;
21529         }
21530     }
21531
21532   M (PUNT, mp);
21533
21534   mp->is_add = (u8) is_add;
21535   mp->ipv = (u8) ipv;
21536   mp->l4_protocol = (u8) protocol;
21537   mp->l4_port = htons ((u16) port);
21538
21539   S (mp);
21540   W (ret);
21541   return ret;
21542 }
21543
21544 static void vl_api_ipsec_gre_tunnel_details_t_handler
21545   (vl_api_ipsec_gre_tunnel_details_t * mp)
21546 {
21547   vat_main_t *vam = &vat_main;
21548
21549   print (vam->ofp, "%11d%15U%15U%14d%14d",
21550          ntohl (mp->sw_if_index),
21551          format_ip4_address, &mp->src_address,
21552          format_ip4_address, &mp->dst_address,
21553          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21554 }
21555
21556 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21557   (vl_api_ipsec_gre_tunnel_details_t * mp)
21558 {
21559   vat_main_t *vam = &vat_main;
21560   vat_json_node_t *node = NULL;
21561   struct in_addr ip4;
21562
21563   if (VAT_JSON_ARRAY != vam->json_tree.type)
21564     {
21565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21566       vat_json_init_array (&vam->json_tree);
21567     }
21568   node = vat_json_array_add (&vam->json_tree);
21569
21570   vat_json_init_object (node);
21571   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21572   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21573   vat_json_object_add_ip4 (node, "src_address", ip4);
21574   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21575   vat_json_object_add_ip4 (node, "dst_address", ip4);
21576   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21577   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21578 }
21579
21580 static int
21581 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21582 {
21583   unformat_input_t *i = vam->input;
21584   vl_api_ipsec_gre_tunnel_dump_t *mp;
21585   vl_api_control_ping_t *mp_ping;
21586   u32 sw_if_index;
21587   u8 sw_if_index_set = 0;
21588   int ret;
21589
21590   /* Parse args required to build the message */
21591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21592     {
21593       if (unformat (i, "sw_if_index %d", &sw_if_index))
21594         sw_if_index_set = 1;
21595       else
21596         break;
21597     }
21598
21599   if (sw_if_index_set == 0)
21600     {
21601       sw_if_index = ~0;
21602     }
21603
21604   if (!vam->json_output)
21605     {
21606       print (vam->ofp, "%11s%15s%15s%14s%14s",
21607              "sw_if_index", "src_address", "dst_address",
21608              "local_sa_id", "remote_sa_id");
21609     }
21610
21611   /* Get list of gre-tunnel interfaces */
21612   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21613
21614   mp->sw_if_index = htonl (sw_if_index);
21615
21616   S (mp);
21617
21618   /* Use a control ping for synchronization */
21619   MPING (CONTROL_PING, mp_ping);
21620   S (mp_ping);
21621
21622   W (ret);
21623   return ret;
21624 }
21625
21626 static int
21627 api_delete_subif (vat_main_t * vam)
21628 {
21629   unformat_input_t *i = vam->input;
21630   vl_api_delete_subif_t *mp;
21631   u32 sw_if_index = ~0;
21632   int ret;
21633
21634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21635     {
21636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21637         ;
21638       if (unformat (i, "sw_if_index %d", &sw_if_index))
21639         ;
21640       else
21641         break;
21642     }
21643
21644   if (sw_if_index == ~0)
21645     {
21646       errmsg ("missing sw_if_index");
21647       return -99;
21648     }
21649
21650   /* Construct the API message */
21651   M (DELETE_SUBIF, mp);
21652   mp->sw_if_index = ntohl (sw_if_index);
21653
21654   S (mp);
21655   W (ret);
21656   return ret;
21657 }
21658
21659 #define foreach_pbb_vtr_op      \
21660 _("disable",  L2_VTR_DISABLED)  \
21661 _("pop",  L2_VTR_POP_2)         \
21662 _("push",  L2_VTR_PUSH_2)
21663
21664 static int
21665 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21666 {
21667   unformat_input_t *i = vam->input;
21668   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21669   u32 sw_if_index = ~0, vtr_op = ~0;
21670   u16 outer_tag = ~0;
21671   u8 dmac[6], smac[6];
21672   u8 dmac_set = 0, smac_set = 0;
21673   u16 vlanid = 0;
21674   u32 sid = ~0;
21675   u32 tmp;
21676   int ret;
21677
21678   /* Shut up coverity */
21679   memset (dmac, 0, sizeof (dmac));
21680   memset (smac, 0, sizeof (smac));
21681
21682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21683     {
21684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21685         ;
21686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21687         ;
21688       else if (unformat (i, "vtr_op %d", &vtr_op))
21689         ;
21690 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21691       foreach_pbb_vtr_op
21692 #undef _
21693         else if (unformat (i, "translate_pbb_stag"))
21694         {
21695           if (unformat (i, "%d", &tmp))
21696             {
21697               vtr_op = L2_VTR_TRANSLATE_2_1;
21698               outer_tag = tmp;
21699             }
21700           else
21701             {
21702               errmsg
21703                 ("translate_pbb_stag operation requires outer tag definition");
21704               return -99;
21705             }
21706         }
21707       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21708         dmac_set++;
21709       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21710         smac_set++;
21711       else if (unformat (i, "sid %d", &sid))
21712         ;
21713       else if (unformat (i, "vlanid %d", &tmp))
21714         vlanid = tmp;
21715       else
21716         {
21717           clib_warning ("parse error '%U'", format_unformat_error, i);
21718           return -99;
21719         }
21720     }
21721
21722   if ((sw_if_index == ~0) || (vtr_op == ~0))
21723     {
21724       errmsg ("missing sw_if_index or vtr operation");
21725       return -99;
21726     }
21727   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21728       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21729     {
21730       errmsg
21731         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21732       return -99;
21733     }
21734
21735   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21736   mp->sw_if_index = ntohl (sw_if_index);
21737   mp->vtr_op = ntohl (vtr_op);
21738   mp->outer_tag = ntohs (outer_tag);
21739   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21740   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21741   mp->b_vlanid = ntohs (vlanid);
21742   mp->i_sid = ntohl (sid);
21743
21744   S (mp);
21745   W (ret);
21746   return ret;
21747 }
21748
21749 static int
21750 api_flow_classify_set_interface (vat_main_t * vam)
21751 {
21752   unformat_input_t *i = vam->input;
21753   vl_api_flow_classify_set_interface_t *mp;
21754   u32 sw_if_index;
21755   int sw_if_index_set;
21756   u32 ip4_table_index = ~0;
21757   u32 ip6_table_index = ~0;
21758   u8 is_add = 1;
21759   int ret;
21760
21761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21762     {
21763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21764         sw_if_index_set = 1;
21765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21766         sw_if_index_set = 1;
21767       else if (unformat (i, "del"))
21768         is_add = 0;
21769       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21770         ;
21771       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21772         ;
21773       else
21774         {
21775           clib_warning ("parse error '%U'", format_unformat_error, i);
21776           return -99;
21777         }
21778     }
21779
21780   if (sw_if_index_set == 0)
21781     {
21782       errmsg ("missing interface name or sw_if_index");
21783       return -99;
21784     }
21785
21786   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21787
21788   mp->sw_if_index = ntohl (sw_if_index);
21789   mp->ip4_table_index = ntohl (ip4_table_index);
21790   mp->ip6_table_index = ntohl (ip6_table_index);
21791   mp->is_add = is_add;
21792
21793   S (mp);
21794   W (ret);
21795   return ret;
21796 }
21797
21798 static int
21799 api_flow_classify_dump (vat_main_t * vam)
21800 {
21801   unformat_input_t *i = vam->input;
21802   vl_api_flow_classify_dump_t *mp;
21803   vl_api_control_ping_t *mp_ping;
21804   u8 type = FLOW_CLASSIFY_N_TABLES;
21805   int ret;
21806
21807   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21808     ;
21809   else
21810     {
21811       errmsg ("classify table type must be specified");
21812       return -99;
21813     }
21814
21815   if (!vam->json_output)
21816     {
21817       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21818     }
21819
21820   M (FLOW_CLASSIFY_DUMP, mp);
21821   mp->type = type;
21822   /* send it... */
21823   S (mp);
21824
21825   /* Use a control ping for synchronization */
21826   MPING (CONTROL_PING, mp_ping);
21827   S (mp_ping);
21828
21829   /* Wait for a reply... */
21830   W (ret);
21831   return ret;
21832 }
21833
21834 static int
21835 api_feature_enable_disable (vat_main_t * vam)
21836 {
21837   unformat_input_t *i = vam->input;
21838   vl_api_feature_enable_disable_t *mp;
21839   u8 *arc_name = 0;
21840   u8 *feature_name = 0;
21841   u32 sw_if_index = ~0;
21842   u8 enable = 1;
21843   int ret;
21844
21845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21846     {
21847       if (unformat (i, "arc_name %s", &arc_name))
21848         ;
21849       else if (unformat (i, "feature_name %s", &feature_name))
21850         ;
21851       else
21852         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21853         ;
21854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21855         ;
21856       else if (unformat (i, "disable"))
21857         enable = 0;
21858       else
21859         break;
21860     }
21861
21862   if (arc_name == 0)
21863     {
21864       errmsg ("missing arc name");
21865       return -99;
21866     }
21867   if (vec_len (arc_name) > 63)
21868     {
21869       errmsg ("arc name too long");
21870     }
21871
21872   if (feature_name == 0)
21873     {
21874       errmsg ("missing feature name");
21875       return -99;
21876     }
21877   if (vec_len (feature_name) > 63)
21878     {
21879       errmsg ("feature name too long");
21880     }
21881
21882   if (sw_if_index == ~0)
21883     {
21884       errmsg ("missing interface name or sw_if_index");
21885       return -99;
21886     }
21887
21888   /* Construct the API message */
21889   M (FEATURE_ENABLE_DISABLE, mp);
21890   mp->sw_if_index = ntohl (sw_if_index);
21891   mp->enable = enable;
21892   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21893   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21894   vec_free (arc_name);
21895   vec_free (feature_name);
21896
21897   S (mp);
21898   W (ret);
21899   return ret;
21900 }
21901
21902 static int
21903 api_sw_interface_tag_add_del (vat_main_t * vam)
21904 {
21905   unformat_input_t *i = vam->input;
21906   vl_api_sw_interface_tag_add_del_t *mp;
21907   u32 sw_if_index = ~0;
21908   u8 *tag = 0;
21909   u8 enable = 1;
21910   int ret;
21911
21912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21913     {
21914       if (unformat (i, "tag %s", &tag))
21915         ;
21916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21917         ;
21918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21919         ;
21920       else if (unformat (i, "del"))
21921         enable = 0;
21922       else
21923         break;
21924     }
21925
21926   if (sw_if_index == ~0)
21927     {
21928       errmsg ("missing interface name or sw_if_index");
21929       return -99;
21930     }
21931
21932   if (enable && (tag == 0))
21933     {
21934       errmsg ("no tag specified");
21935       return -99;
21936     }
21937
21938   /* Construct the API message */
21939   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21940   mp->sw_if_index = ntohl (sw_if_index);
21941   mp->is_add = enable;
21942   if (enable)
21943     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21944   vec_free (tag);
21945
21946   S (mp);
21947   W (ret);
21948   return ret;
21949 }
21950
21951 static void vl_api_l2_xconnect_details_t_handler
21952   (vl_api_l2_xconnect_details_t * mp)
21953 {
21954   vat_main_t *vam = &vat_main;
21955
21956   print (vam->ofp, "%15d%15d",
21957          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21958 }
21959
21960 static void vl_api_l2_xconnect_details_t_handler_json
21961   (vl_api_l2_xconnect_details_t * mp)
21962 {
21963   vat_main_t *vam = &vat_main;
21964   vat_json_node_t *node = NULL;
21965
21966   if (VAT_JSON_ARRAY != vam->json_tree.type)
21967     {
21968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21969       vat_json_init_array (&vam->json_tree);
21970     }
21971   node = vat_json_array_add (&vam->json_tree);
21972
21973   vat_json_init_object (node);
21974   vat_json_object_add_uint (node, "rx_sw_if_index",
21975                             ntohl (mp->rx_sw_if_index));
21976   vat_json_object_add_uint (node, "tx_sw_if_index",
21977                             ntohl (mp->tx_sw_if_index));
21978 }
21979
21980 static int
21981 api_l2_xconnect_dump (vat_main_t * vam)
21982 {
21983   vl_api_l2_xconnect_dump_t *mp;
21984   vl_api_control_ping_t *mp_ping;
21985   int ret;
21986
21987   if (!vam->json_output)
21988     {
21989       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21990     }
21991
21992   M (L2_XCONNECT_DUMP, mp);
21993
21994   S (mp);
21995
21996   /* Use a control ping for synchronization */
21997   MPING (CONTROL_PING, mp_ping);
21998   S (mp_ping);
21999
22000   W (ret);
22001   return ret;
22002 }
22003
22004 static int
22005 api_sw_interface_set_mtu (vat_main_t * vam)
22006 {
22007   unformat_input_t *i = vam->input;
22008   vl_api_sw_interface_set_mtu_t *mp;
22009   u32 sw_if_index = ~0;
22010   u32 mtu = 0;
22011   int ret;
22012
22013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22014     {
22015       if (unformat (i, "mtu %d", &mtu))
22016         ;
22017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22018         ;
22019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22020         ;
22021       else
22022         break;
22023     }
22024
22025   if (sw_if_index == ~0)
22026     {
22027       errmsg ("missing interface name or sw_if_index");
22028       return -99;
22029     }
22030
22031   if (mtu == 0)
22032     {
22033       errmsg ("no mtu specified");
22034       return -99;
22035     }
22036
22037   /* Construct the API message */
22038   M (SW_INTERFACE_SET_MTU, mp);
22039   mp->sw_if_index = ntohl (sw_if_index);
22040   mp->mtu = ntohs ((u16) mtu);
22041
22042   S (mp);
22043   W (ret);
22044   return ret;
22045 }
22046
22047 static int
22048 api_p2p_ethernet_add (vat_main_t * vam)
22049 {
22050   unformat_input_t *i = vam->input;
22051   vl_api_p2p_ethernet_add_t *mp;
22052   u32 parent_if_index = ~0;
22053   u32 sub_id = ~0;
22054   u8 remote_mac[6];
22055   u8 mac_set = 0;
22056   int ret;
22057
22058   memset (remote_mac, 0, sizeof (remote_mac));
22059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22060     {
22061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22062         ;
22063       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22064         ;
22065       else
22066         if (unformat
22067             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22068         mac_set++;
22069       else if (unformat (i, "sub_id %d", &sub_id))
22070         ;
22071       else
22072         {
22073           clib_warning ("parse error '%U'", format_unformat_error, i);
22074           return -99;
22075         }
22076     }
22077
22078   if (parent_if_index == ~0)
22079     {
22080       errmsg ("missing interface name or sw_if_index");
22081       return -99;
22082     }
22083   if (mac_set == 0)
22084     {
22085       errmsg ("missing remote mac address");
22086       return -99;
22087     }
22088   if (sub_id == ~0)
22089     {
22090       errmsg ("missing sub-interface id");
22091       return -99;
22092     }
22093
22094   M (P2P_ETHERNET_ADD, mp);
22095   mp->parent_if_index = ntohl (parent_if_index);
22096   mp->subif_id = ntohl (sub_id);
22097   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22098
22099   S (mp);
22100   W (ret);
22101   return ret;
22102 }
22103
22104 static int
22105 api_p2p_ethernet_del (vat_main_t * vam)
22106 {
22107   unformat_input_t *i = vam->input;
22108   vl_api_p2p_ethernet_del_t *mp;
22109   u32 parent_if_index = ~0;
22110   u8 remote_mac[6];
22111   u8 mac_set = 0;
22112   int ret;
22113
22114   memset (remote_mac, 0, sizeof (remote_mac));
22115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22116     {
22117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22118         ;
22119       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22120         ;
22121       else
22122         if (unformat
22123             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22124         mac_set++;
22125       else
22126         {
22127           clib_warning ("parse error '%U'", format_unformat_error, i);
22128           return -99;
22129         }
22130     }
22131
22132   if (parent_if_index == ~0)
22133     {
22134       errmsg ("missing interface name or sw_if_index");
22135       return -99;
22136     }
22137   if (mac_set == 0)
22138     {
22139       errmsg ("missing remote mac address");
22140       return -99;
22141     }
22142
22143   M (P2P_ETHERNET_DEL, mp);
22144   mp->parent_if_index = ntohl (parent_if_index);
22145   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22146
22147   S (mp);
22148   W (ret);
22149   return ret;
22150 }
22151
22152 static int
22153 api_lldp_config (vat_main_t * vam)
22154 {
22155   unformat_input_t *i = vam->input;
22156   vl_api_lldp_config_t *mp;
22157   int tx_hold = 0;
22158   int tx_interval = 0;
22159   u8 *sys_name = NULL;
22160   int ret;
22161
22162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22163     {
22164       if (unformat (i, "system-name %s", &sys_name))
22165         ;
22166       else if (unformat (i, "tx-hold %d", &tx_hold))
22167         ;
22168       else if (unformat (i, "tx-interval %d", &tx_interval))
22169         ;
22170       else
22171         {
22172           clib_warning ("parse error '%U'", format_unformat_error, i);
22173           return -99;
22174         }
22175     }
22176
22177   vec_add1 (sys_name, 0);
22178
22179   M (LLDP_CONFIG, mp);
22180   mp->tx_hold = htonl (tx_hold);
22181   mp->tx_interval = htonl (tx_interval);
22182   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22183   vec_free (sys_name);
22184
22185   S (mp);
22186   W (ret);
22187   return ret;
22188 }
22189
22190 static int
22191 api_sw_interface_set_lldp (vat_main_t * vam)
22192 {
22193   unformat_input_t *i = vam->input;
22194   vl_api_sw_interface_set_lldp_t *mp;
22195   u32 sw_if_index = ~0;
22196   u32 enable = 1;
22197   u8 *port_desc = NULL, *mgmt_oid = NULL;
22198   ip4_address_t ip4_addr;
22199   ip6_address_t ip6_addr;
22200   int ret;
22201
22202   memset (&ip4_addr, 0, sizeof (ip4_addr));
22203   memset (&ip6_addr, 0, sizeof (ip6_addr));
22204
22205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22206     {
22207       if (unformat (i, "disable"))
22208         enable = 0;
22209       else
22210         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22211         ;
22212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22213         ;
22214       else if (unformat (i, "port-desc %s", &port_desc))
22215         ;
22216       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22217         ;
22218       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22219         ;
22220       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22221         ;
22222       else
22223         break;
22224     }
22225
22226   if (sw_if_index == ~0)
22227     {
22228       errmsg ("missing interface name or sw_if_index");
22229       return -99;
22230     }
22231
22232   /* Construct the API message */
22233   vec_add1 (port_desc, 0);
22234   vec_add1 (mgmt_oid, 0);
22235   M (SW_INTERFACE_SET_LLDP, mp);
22236   mp->sw_if_index = ntohl (sw_if_index);
22237   mp->enable = enable;
22238   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22239   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22240   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22241   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22242   vec_free (port_desc);
22243   vec_free (mgmt_oid);
22244
22245   S (mp);
22246   W (ret);
22247   return ret;
22248 }
22249
22250 static int
22251 api_tcp_configure_src_addresses (vat_main_t * vam)
22252 {
22253   vl_api_tcp_configure_src_addresses_t *mp;
22254   unformat_input_t *i = vam->input;
22255   ip4_address_t v4first, v4last;
22256   ip6_address_t v6first, v6last;
22257   u8 range_set = 0;
22258   u32 vrf_id = 0;
22259   int ret;
22260
22261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22262     {
22263       if (unformat (i, "%U - %U",
22264                     unformat_ip4_address, &v4first,
22265                     unformat_ip4_address, &v4last))
22266         {
22267           if (range_set)
22268             {
22269               errmsg ("one range per message (range already set)");
22270               return -99;
22271             }
22272           range_set = 1;
22273         }
22274       else if (unformat (i, "%U - %U",
22275                          unformat_ip6_address, &v6first,
22276                          unformat_ip6_address, &v6last))
22277         {
22278           if (range_set)
22279             {
22280               errmsg ("one range per message (range already set)");
22281               return -99;
22282             }
22283           range_set = 2;
22284         }
22285       else if (unformat (i, "vrf %d", &vrf_id))
22286         ;
22287       else
22288         break;
22289     }
22290
22291   if (range_set == 0)
22292     {
22293       errmsg ("address range not set");
22294       return -99;
22295     }
22296
22297   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22298   mp->vrf_id = ntohl (vrf_id);
22299   /* ipv6? */
22300   if (range_set == 2)
22301     {
22302       mp->is_ipv6 = 1;
22303       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22304       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22305     }
22306   else
22307     {
22308       mp->is_ipv6 = 0;
22309       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22310       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22311     }
22312   S (mp);
22313   W (ret);
22314   return ret;
22315 }
22316
22317 static void vl_api_app_namespace_add_del_reply_t_handler
22318   (vl_api_app_namespace_add_del_reply_t * mp)
22319 {
22320   vat_main_t *vam = &vat_main;
22321   i32 retval = ntohl (mp->retval);
22322   if (vam->async_mode)
22323     {
22324       vam->async_errors += (retval < 0);
22325     }
22326   else
22327     {
22328       vam->retval = retval;
22329       if (retval == 0)
22330         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22331       vam->result_ready = 1;
22332     }
22333 }
22334
22335 static void vl_api_app_namespace_add_del_reply_t_handler_json
22336   (vl_api_app_namespace_add_del_reply_t * mp)
22337 {
22338   vat_main_t *vam = &vat_main;
22339   vat_json_node_t node;
22340
22341   vat_json_init_object (&node);
22342   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22343   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22344
22345   vat_json_print (vam->ofp, &node);
22346   vat_json_free (&node);
22347
22348   vam->retval = ntohl (mp->retval);
22349   vam->result_ready = 1;
22350 }
22351
22352 static int
22353 api_app_namespace_add_del (vat_main_t * vam)
22354 {
22355   vl_api_app_namespace_add_del_t *mp;
22356   unformat_input_t *i = vam->input;
22357   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22358   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22359   u64 secret;
22360   int ret;
22361
22362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22363     {
22364       if (unformat (i, "id %_%v%_", &ns_id))
22365         ;
22366       else if (unformat (i, "secret %lu", &secret))
22367         secret_set = 1;
22368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22369         sw_if_index_set = 1;
22370       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22371         ;
22372       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22373         ;
22374       else
22375         break;
22376     }
22377   if (!ns_id || !secret_set || !sw_if_index_set)
22378     {
22379       errmsg ("namespace id, secret and sw_if_index must be set");
22380       return -99;
22381     }
22382   if (vec_len (ns_id) > 64)
22383     {
22384       errmsg ("namespace id too long");
22385       return -99;
22386     }
22387   M (APP_NAMESPACE_ADD_DEL, mp);
22388
22389   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22390   mp->namespace_id_len = vec_len (ns_id);
22391   mp->secret = clib_host_to_net_u64 (secret);
22392   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22393   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22394   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22395   vec_free (ns_id);
22396   S (mp);
22397   W (ret);
22398   return ret;
22399 }
22400
22401 static int
22402 api_memfd_segment_create (vat_main_t * vam)
22403 {
22404 #if VPP_API_TEST_BUILTIN == 0
22405   unformat_input_t *i = vam->input;
22406   vl_api_memfd_segment_create_t *mp;
22407   u64 size = 64 << 20;
22408   int ret;
22409
22410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22411     {
22412       if (unformat (i, "size %U", unformat_memory_size, &size))
22413         ;
22414       else
22415         break;
22416     }
22417
22418   M (MEMFD_SEGMENT_CREATE, mp);
22419   mp->requested_size = size;
22420   S (mp);
22421   W (ret);
22422   return ret;
22423
22424 #else
22425   errmsg ("memfd_segment_create (builtin) not supported");
22426   return -99;
22427 #endif
22428 }
22429
22430 static int
22431 api_sock_init_shm (vat_main_t * vam)
22432 {
22433 #if VPP_API_TEST_BUILTIN == 0
22434   unformat_input_t *i = vam->input;
22435   vl_api_shm_elem_config_t *config = 0;
22436   u64 size = 64 << 20;
22437   int rv;
22438
22439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22440     {
22441       if (unformat (i, "size %U", unformat_memory_size, &size))
22442         ;
22443       else
22444         break;
22445     }
22446
22447   /* Try customized config to see if it works */
22448   vec_validate (config, 3);
22449   config[0].type = VL_API_VLIB_RING;
22450   config[0].count = 256;
22451   config[0].size = 256;
22452   config[1].type = VL_API_CLIENT_RING;
22453   config[1].count = 256;
22454   config[1].size = 1024;
22455   config[2].type = VL_API_CLIENT_RING;
22456   config[2].count = 8;
22457   config[2].size = 4096;
22458   config[3].type = VL_API_QUEUE;
22459   config[3].count = 256;
22460   config[3].size = sizeof (uword);
22461   rv = vl_socket_client_init_shm (config);
22462   if (!rv)
22463     vam->client_index_invalid = 1;
22464   return rv;
22465 #else
22466   return -99;
22467 #endif
22468 }
22469
22470 static int
22471 api_dns_enable_disable (vat_main_t * vam)
22472 {
22473   unformat_input_t *line_input = vam->input;
22474   vl_api_dns_enable_disable_t *mp;
22475   u8 enable_disable = 1;
22476   int ret;
22477
22478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22479     {
22480       if (unformat (line_input, "disable"))
22481         enable_disable = 0;
22482       if (unformat (line_input, "enable"))
22483         enable_disable = 1;
22484       else
22485         break;
22486     }
22487
22488   /* Construct the API message */
22489   M (DNS_ENABLE_DISABLE, mp);
22490   mp->enable = enable_disable;
22491
22492   /* send it... */
22493   S (mp);
22494   /* Wait for the reply */
22495   W (ret);
22496   return ret;
22497 }
22498
22499 static int
22500 api_dns_resolve_name (vat_main_t * vam)
22501 {
22502   unformat_input_t *line_input = vam->input;
22503   vl_api_dns_resolve_name_t *mp;
22504   u8 *name = 0;
22505   int ret;
22506
22507   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22508     {
22509       if (unformat (line_input, "%s", &name))
22510         ;
22511       else
22512         break;
22513     }
22514
22515   if (vec_len (name) > 127)
22516     {
22517       errmsg ("name too long");
22518       return -99;
22519     }
22520
22521   /* Construct the API message */
22522   M (DNS_RESOLVE_NAME, mp);
22523   memcpy (mp->name, name, vec_len (name));
22524   vec_free (name);
22525
22526   /* send it... */
22527   S (mp);
22528   /* Wait for the reply */
22529   W (ret);
22530   return ret;
22531 }
22532
22533 static int
22534 api_dns_resolve_ip (vat_main_t * vam)
22535 {
22536   unformat_input_t *line_input = vam->input;
22537   vl_api_dns_resolve_ip_t *mp;
22538   int is_ip6 = -1;
22539   ip4_address_t addr4;
22540   ip6_address_t addr6;
22541   int ret;
22542
22543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22544     {
22545       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22546         is_ip6 = 1;
22547       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22548         is_ip6 = 0;
22549       else
22550         break;
22551     }
22552
22553   if (is_ip6 == -1)
22554     {
22555       errmsg ("missing address");
22556       return -99;
22557     }
22558
22559   /* Construct the API message */
22560   M (DNS_RESOLVE_IP, mp);
22561   mp->is_ip6 = is_ip6;
22562   if (is_ip6)
22563     memcpy (mp->address, &addr6, sizeof (addr6));
22564   else
22565     memcpy (mp->address, &addr4, sizeof (addr4));
22566
22567   /* send it... */
22568   S (mp);
22569   /* Wait for the reply */
22570   W (ret);
22571   return ret;
22572 }
22573
22574 static int
22575 api_dns_name_server_add_del (vat_main_t * vam)
22576 {
22577   unformat_input_t *i = vam->input;
22578   vl_api_dns_name_server_add_del_t *mp;
22579   u8 is_add = 1;
22580   ip6_address_t ip6_server;
22581   ip4_address_t ip4_server;
22582   int ip6_set = 0;
22583   int ip4_set = 0;
22584   int ret = 0;
22585
22586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22587     {
22588       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22589         ip6_set = 1;
22590       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22591         ip4_set = 1;
22592       else if (unformat (i, "del"))
22593         is_add = 0;
22594       else
22595         {
22596           clib_warning ("parse error '%U'", format_unformat_error, i);
22597           return -99;
22598         }
22599     }
22600
22601   if (ip4_set && ip6_set)
22602     {
22603       errmsg ("Only one server address allowed per message");
22604       return -99;
22605     }
22606   if ((ip4_set + ip6_set) == 0)
22607     {
22608       errmsg ("Server address required");
22609       return -99;
22610     }
22611
22612   /* Construct the API message */
22613   M (DNS_NAME_SERVER_ADD_DEL, mp);
22614
22615   if (ip6_set)
22616     {
22617       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22618       mp->is_ip6 = 1;
22619     }
22620   else
22621     {
22622       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22623       mp->is_ip6 = 0;
22624     }
22625
22626   mp->is_add = is_add;
22627
22628   /* send it... */
22629   S (mp);
22630
22631   /* Wait for a reply, return good/bad news  */
22632   W (ret);
22633   return ret;
22634 }
22635
22636 static void
22637 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22638 {
22639   vat_main_t *vam = &vat_main;
22640
22641   if (mp->is_ip4)
22642     {
22643       print (vam->ofp,
22644              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22645              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22646              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22647              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22648              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22649              clib_net_to_host_u32 (mp->action_index), mp->tag);
22650     }
22651   else
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_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22657              clib_net_to_host_u16 (mp->lcl_port), format_ip6_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 }
22662
22663 static void
22664 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22665                                              mp)
22666 {
22667   vat_main_t *vam = &vat_main;
22668   vat_json_node_t *node = NULL;
22669   struct in6_addr ip6;
22670   struct in_addr ip4;
22671
22672   if (VAT_JSON_ARRAY != vam->json_tree.type)
22673     {
22674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22675       vat_json_init_array (&vam->json_tree);
22676     }
22677   node = vat_json_array_add (&vam->json_tree);
22678   vat_json_init_object (node);
22679
22680   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22681   vat_json_object_add_uint (node, "appns_index",
22682                             clib_net_to_host_u32 (mp->appns_index));
22683   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22684   vat_json_object_add_uint (node, "scope", mp->scope);
22685   vat_json_object_add_uint (node, "action_index",
22686                             clib_net_to_host_u32 (mp->action_index));
22687   vat_json_object_add_uint (node, "lcl_port",
22688                             clib_net_to_host_u16 (mp->lcl_port));
22689   vat_json_object_add_uint (node, "rmt_port",
22690                             clib_net_to_host_u16 (mp->rmt_port));
22691   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22692   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22693   vat_json_object_add_string_copy (node, "tag", mp->tag);
22694   if (mp->is_ip4)
22695     {
22696       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22697       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22698       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22699       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22700     }
22701   else
22702     {
22703       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22704       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22705       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22706       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22707     }
22708 }
22709
22710 static int
22711 api_session_rule_add_del (vat_main_t * vam)
22712 {
22713   vl_api_session_rule_add_del_t *mp;
22714   unformat_input_t *i = vam->input;
22715   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22716   u32 appns_index = 0, scope = 0;
22717   ip4_address_t lcl_ip4, rmt_ip4;
22718   ip6_address_t lcl_ip6, rmt_ip6;
22719   u8 is_ip4 = 1, conn_set = 0;
22720   u8 is_add = 1, *tag = 0;
22721   int ret;
22722
22723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22724     {
22725       if (unformat (i, "del"))
22726         is_add = 0;
22727       else if (unformat (i, "add"))
22728         ;
22729       else if (unformat (i, "proto tcp"))
22730         proto = 0;
22731       else if (unformat (i, "proto udp"))
22732         proto = 1;
22733       else if (unformat (i, "appns %d", &appns_index))
22734         ;
22735       else if (unformat (i, "scope %d", &scope))
22736         ;
22737       else if (unformat (i, "tag %_%v%_", &tag))
22738         ;
22739       else
22740         if (unformat
22741             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22742              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22743              &rmt_port))
22744         {
22745           is_ip4 = 1;
22746           conn_set = 1;
22747         }
22748       else
22749         if (unformat
22750             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22751              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22752              &rmt_port))
22753         {
22754           is_ip4 = 0;
22755           conn_set = 1;
22756         }
22757       else if (unformat (i, "action %d", &action))
22758         ;
22759       else
22760         break;
22761     }
22762   if (proto == ~0 || !conn_set || action == ~0)
22763     {
22764       errmsg ("transport proto, connection and action must be set");
22765       return -99;
22766     }
22767
22768   if (scope > 3)
22769     {
22770       errmsg ("scope should be 0-3");
22771       return -99;
22772     }
22773
22774   M (SESSION_RULE_ADD_DEL, mp);
22775
22776   mp->is_ip4 = is_ip4;
22777   mp->transport_proto = proto;
22778   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22779   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22780   mp->lcl_plen = lcl_plen;
22781   mp->rmt_plen = rmt_plen;
22782   mp->action_index = clib_host_to_net_u32 (action);
22783   mp->appns_index = clib_host_to_net_u32 (appns_index);
22784   mp->scope = scope;
22785   mp->is_add = is_add;
22786   if (is_ip4)
22787     {
22788       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22789       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22790     }
22791   else
22792     {
22793       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22794       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22795     }
22796   if (tag)
22797     {
22798       clib_memcpy (mp->tag, tag, vec_len (tag));
22799       vec_free (tag);
22800     }
22801
22802   S (mp);
22803   W (ret);
22804   return ret;
22805 }
22806
22807 static int
22808 api_session_rules_dump (vat_main_t * vam)
22809 {
22810   vl_api_session_rules_dump_t *mp;
22811   vl_api_control_ping_t *mp_ping;
22812   int ret;
22813
22814   if (!vam->json_output)
22815     {
22816       print (vam->ofp, "%=20s", "Session Rules");
22817     }
22818
22819   M (SESSION_RULES_DUMP, mp);
22820   /* send it... */
22821   S (mp);
22822
22823   /* Use a control ping for synchronization */
22824   MPING (CONTROL_PING, mp_ping);
22825   S (mp_ping);
22826
22827   /* Wait for a reply... */
22828   W (ret);
22829   return ret;
22830 }
22831
22832 static int
22833 api_ip_container_proxy_add_del (vat_main_t * vam)
22834 {
22835   vl_api_ip_container_proxy_add_del_t *mp;
22836   unformat_input_t *i = vam->input;
22837   u32 plen = ~0, sw_if_index = ~0;
22838   ip4_address_t ip4;
22839   ip6_address_t ip6;
22840   u8 is_ip4 = 1;
22841   u8 is_add = 1;
22842   int ret;
22843
22844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22845     {
22846       if (unformat (i, "del"))
22847         is_add = 0;
22848       else if (unformat (i, "add"))
22849         ;
22850       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22851         {
22852           is_ip4 = 1;
22853           plen = 32;
22854         }
22855       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22856         {
22857           is_ip4 = 0;
22858           plen = 128;
22859         }
22860       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22861         ;
22862       else
22863         break;
22864     }
22865   if (sw_if_index == ~0 || plen == ~0)
22866     {
22867       errmsg ("address and sw_if_index must be set");
22868       return -99;
22869     }
22870
22871   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22872
22873   mp->is_ip4 = is_ip4;
22874   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22875   mp->plen = plen;
22876   mp->is_add = is_add;
22877   if (is_ip4)
22878     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22879   else
22880     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22881
22882   S (mp);
22883   W (ret);
22884   return ret;
22885 }
22886
22887 static int
22888 q_or_quit (vat_main_t * vam)
22889 {
22890 #if VPP_API_TEST_BUILTIN == 0
22891   longjmp (vam->jump_buf, 1);
22892 #endif
22893   return 0;                     /* not so much */
22894 }
22895
22896 static int
22897 q (vat_main_t * vam)
22898 {
22899   return q_or_quit (vam);
22900 }
22901
22902 static int
22903 quit (vat_main_t * vam)
22904 {
22905   return q_or_quit (vam);
22906 }
22907
22908 static int
22909 comment (vat_main_t * vam)
22910 {
22911   return 0;
22912 }
22913
22914 static int
22915 cmd_cmp (void *a1, void *a2)
22916 {
22917   u8 **c1 = a1;
22918   u8 **c2 = a2;
22919
22920   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22921 }
22922
22923 static int
22924 help (vat_main_t * vam)
22925 {
22926   u8 **cmds = 0;
22927   u8 *name = 0;
22928   hash_pair_t *p;
22929   unformat_input_t *i = vam->input;
22930   int j;
22931
22932   if (unformat (i, "%s", &name))
22933     {
22934       uword *hs;
22935
22936       vec_add1 (name, 0);
22937
22938       hs = hash_get_mem (vam->help_by_name, name);
22939       if (hs)
22940         print (vam->ofp, "usage: %s %s", name, hs[0]);
22941       else
22942         print (vam->ofp, "No such msg / command '%s'", name);
22943       vec_free (name);
22944       return 0;
22945     }
22946
22947   print (vam->ofp, "Help is available for the following:");
22948
22949     /* *INDENT-OFF* */
22950     hash_foreach_pair (p, vam->function_by_name,
22951     ({
22952       vec_add1 (cmds, (u8 *)(p->key));
22953     }));
22954     /* *INDENT-ON* */
22955
22956   vec_sort_with_function (cmds, cmd_cmp);
22957
22958   for (j = 0; j < vec_len (cmds); j++)
22959     print (vam->ofp, "%s", cmds[j]);
22960
22961   vec_free (cmds);
22962   return 0;
22963 }
22964
22965 static int
22966 set (vat_main_t * vam)
22967 {
22968   u8 *name = 0, *value = 0;
22969   unformat_input_t *i = vam->input;
22970
22971   if (unformat (i, "%s", &name))
22972     {
22973       /* The input buffer is a vector, not a string. */
22974       value = vec_dup (i->buffer);
22975       vec_delete (value, i->index, 0);
22976       /* Almost certainly has a trailing newline */
22977       if (value[vec_len (value) - 1] == '\n')
22978         value[vec_len (value) - 1] = 0;
22979       /* Make sure it's a proper string, one way or the other */
22980       vec_add1 (value, 0);
22981       (void) clib_macro_set_value (&vam->macro_main,
22982                                    (char *) name, (char *) value);
22983     }
22984   else
22985     errmsg ("usage: set <name> <value>");
22986
22987   vec_free (name);
22988   vec_free (value);
22989   return 0;
22990 }
22991
22992 static int
22993 unset (vat_main_t * vam)
22994 {
22995   u8 *name = 0;
22996
22997   if (unformat (vam->input, "%s", &name))
22998     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22999       errmsg ("unset: %s wasn't set", name);
23000   vec_free (name);
23001   return 0;
23002 }
23003
23004 typedef struct
23005 {
23006   u8 *name;
23007   u8 *value;
23008 } macro_sort_t;
23009
23010
23011 static int
23012 macro_sort_cmp (void *a1, void *a2)
23013 {
23014   macro_sort_t *s1 = a1;
23015   macro_sort_t *s2 = a2;
23016
23017   return strcmp ((char *) (s1->name), (char *) (s2->name));
23018 }
23019
23020 static int
23021 dump_macro_table (vat_main_t * vam)
23022 {
23023   macro_sort_t *sort_me = 0, *sm;
23024   int i;
23025   hash_pair_t *p;
23026
23027     /* *INDENT-OFF* */
23028     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23029     ({
23030       vec_add2 (sort_me, sm, 1);
23031       sm->name = (u8 *)(p->key);
23032       sm->value = (u8 *) (p->value[0]);
23033     }));
23034     /* *INDENT-ON* */
23035
23036   vec_sort_with_function (sort_me, macro_sort_cmp);
23037
23038   if (vec_len (sort_me))
23039     print (vam->ofp, "%-15s%s", "Name", "Value");
23040   else
23041     print (vam->ofp, "The macro table is empty...");
23042
23043   for (i = 0; i < vec_len (sort_me); i++)
23044     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23045   return 0;
23046 }
23047
23048 static int
23049 dump_node_table (vat_main_t * vam)
23050 {
23051   int i, j;
23052   vlib_node_t *node, *next_node;
23053
23054   if (vec_len (vam->graph_nodes) == 0)
23055     {
23056       print (vam->ofp, "Node table empty, issue get_node_graph...");
23057       return 0;
23058     }
23059
23060   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23061     {
23062       node = vam->graph_nodes[i];
23063       print (vam->ofp, "[%d] %s", i, node->name);
23064       for (j = 0; j < vec_len (node->next_nodes); j++)
23065         {
23066           if (node->next_nodes[j] != ~0)
23067             {
23068               next_node = vam->graph_nodes[node->next_nodes[j]];
23069               print (vam->ofp, "  [%d] %s", j, next_node->name);
23070             }
23071         }
23072     }
23073   return 0;
23074 }
23075
23076 static int
23077 value_sort_cmp (void *a1, void *a2)
23078 {
23079   name_sort_t *n1 = a1;
23080   name_sort_t *n2 = a2;
23081
23082   if (n1->value < n2->value)
23083     return -1;
23084   if (n1->value > n2->value)
23085     return 1;
23086   return 0;
23087 }
23088
23089
23090 static int
23091 dump_msg_api_table (vat_main_t * vam)
23092 {
23093   api_main_t *am = &api_main;
23094   name_sort_t *nses = 0, *ns;
23095   hash_pair_t *hp;
23096   int i;
23097
23098   /* *INDENT-OFF* */
23099   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23100   ({
23101     vec_add2 (nses, ns, 1);
23102     ns->name = (u8 *)(hp->key);
23103     ns->value = (u32) hp->value[0];
23104   }));
23105   /* *INDENT-ON* */
23106
23107   vec_sort_with_function (nses, value_sort_cmp);
23108
23109   for (i = 0; i < vec_len (nses); i++)
23110     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23111   vec_free (nses);
23112   return 0;
23113 }
23114
23115 static int
23116 get_msg_id (vat_main_t * vam)
23117 {
23118   u8 *name_and_crc;
23119   u32 message_index;
23120
23121   if (unformat (vam->input, "%s", &name_and_crc))
23122     {
23123       message_index = vl_msg_api_get_msg_index (name_and_crc);
23124       if (message_index == ~0)
23125         {
23126           print (vam->ofp, " '%s' not found", name_and_crc);
23127           return 0;
23128         }
23129       print (vam->ofp, " '%s' has message index %d",
23130              name_and_crc, message_index);
23131       return 0;
23132     }
23133   errmsg ("name_and_crc required...");
23134   return 0;
23135 }
23136
23137 static int
23138 search_node_table (vat_main_t * vam)
23139 {
23140   unformat_input_t *line_input = vam->input;
23141   u8 *node_to_find;
23142   int j;
23143   vlib_node_t *node, *next_node;
23144   uword *p;
23145
23146   if (vam->graph_node_index_by_name == 0)
23147     {
23148       print (vam->ofp, "Node table empty, issue get_node_graph...");
23149       return 0;
23150     }
23151
23152   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23153     {
23154       if (unformat (line_input, "%s", &node_to_find))
23155         {
23156           vec_add1 (node_to_find, 0);
23157           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23158           if (p == 0)
23159             {
23160               print (vam->ofp, "%s not found...", node_to_find);
23161               goto out;
23162             }
23163           node = vam->graph_nodes[p[0]];
23164           print (vam->ofp, "[%d] %s", p[0], node->name);
23165           for (j = 0; j < vec_len (node->next_nodes); j++)
23166             {
23167               if (node->next_nodes[j] != ~0)
23168                 {
23169                   next_node = vam->graph_nodes[node->next_nodes[j]];
23170                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23171                 }
23172             }
23173         }
23174
23175       else
23176         {
23177           clib_warning ("parse error '%U'", format_unformat_error,
23178                         line_input);
23179           return -99;
23180         }
23181
23182     out:
23183       vec_free (node_to_find);
23184
23185     }
23186
23187   return 0;
23188 }
23189
23190
23191 static int
23192 script (vat_main_t * vam)
23193 {
23194 #if (VPP_API_TEST_BUILTIN==0)
23195   u8 *s = 0;
23196   char *save_current_file;
23197   unformat_input_t save_input;
23198   jmp_buf save_jump_buf;
23199   u32 save_line_number;
23200
23201   FILE *new_fp, *save_ifp;
23202
23203   if (unformat (vam->input, "%s", &s))
23204     {
23205       new_fp = fopen ((char *) s, "r");
23206       if (new_fp == 0)
23207         {
23208           errmsg ("Couldn't open script file %s", s);
23209           vec_free (s);
23210           return -99;
23211         }
23212     }
23213   else
23214     {
23215       errmsg ("Missing script name");
23216       return -99;
23217     }
23218
23219   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23220   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23221   save_ifp = vam->ifp;
23222   save_line_number = vam->input_line_number;
23223   save_current_file = (char *) vam->current_file;
23224
23225   vam->input_line_number = 0;
23226   vam->ifp = new_fp;
23227   vam->current_file = s;
23228   do_one_file (vam);
23229
23230   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23231   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23232   vam->ifp = save_ifp;
23233   vam->input_line_number = save_line_number;
23234   vam->current_file = (u8 *) save_current_file;
23235   vec_free (s);
23236
23237   return 0;
23238 #else
23239   clib_warning ("use the exec command...");
23240   return -99;
23241 #endif
23242 }
23243
23244 static int
23245 echo (vat_main_t * vam)
23246 {
23247   print (vam->ofp, "%v", vam->input->buffer);
23248   return 0;
23249 }
23250
23251 /* List of API message constructors, CLI names map to api_xxx */
23252 #define foreach_vpe_api_msg                                             \
23253 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23254 _(sw_interface_dump,"")                                                 \
23255 _(sw_interface_set_flags,                                               \
23256   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23257 _(sw_interface_add_del_address,                                         \
23258   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23259 _(sw_interface_set_rx_mode,                                             \
23260   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23261 _(sw_interface_set_table,                                               \
23262   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23263 _(sw_interface_set_mpls_enable,                                         \
23264   "<intfc> | sw_if_index [disable | dis]")                              \
23265 _(sw_interface_set_vpath,                                               \
23266   "<intfc> | sw_if_index <id> enable | disable")                        \
23267 _(sw_interface_set_vxlan_bypass,                                        \
23268   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23269 _(sw_interface_set_geneve_bypass,                                       \
23270   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23271 _(sw_interface_set_l2_xconnect,                                         \
23272   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23273   "enable | disable")                                                   \
23274 _(sw_interface_set_l2_bridge,                                           \
23275   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23276   "[shg <split-horizon-group>] [bvi]\n"                                 \
23277   "enable | disable")                                                   \
23278 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23279 _(bridge_domain_add_del,                                                \
23280   "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") \
23281 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23282 _(l2fib_add_del,                                                        \
23283   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23284 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23285 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23286 _(l2_flags,                                                             \
23287   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23288 _(bridge_flags,                                                         \
23289   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23290 _(tap_connect,                                                          \
23291   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23292 _(tap_modify,                                                           \
23293   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23294 _(tap_delete,                                                           \
23295   "<vpp-if-name> | sw_if_index <id>")                                   \
23296 _(sw_interface_tap_dump, "")                                            \
23297 _(tap_create_v2,                                                        \
23298   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23299 _(tap_delete_v2,                                                        \
23300   "<vpp-if-name> | sw_if_index <id>")                                   \
23301 _(sw_interface_tap_v2_dump, "")                                         \
23302 _(bond_create,                                                          \
23303   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23304   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23305 _(bond_delete,                                                          \
23306   "<vpp-if-name> | sw_if_index <id>")                                   \
23307 _(bond_enslave,                                                         \
23308   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23309 _(bond_detach_slave,                                                    \
23310   "sw_if_index <n>")                                                    \
23311 _(sw_interface_bond_dump, "")                                           \
23312 _(sw_interface_slave_dump,                                              \
23313   "<vpp-if-name> | sw_if_index <id>")                                   \
23314 _(ip_table_add_del,                                                     \
23315   "table-id <n> [ipv6]\n")                                              \
23316 _(ip_add_del_route,                                                     \
23317   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23318   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23319   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23320   "[multipath] [count <n>]")                                            \
23321 _(ip_mroute_add_del,                                                    \
23322   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23323   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23324 _(mpls_table_add_del,                                                   \
23325   "table-id <n>\n")                                                     \
23326 _(mpls_route_add_del,                                                   \
23327   "<label> <eos> 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 _(mpls_ip_bind_unbind,                                                  \
23332   "<label> <addr/len>")                                                 \
23333 _(mpls_tunnel_add_del,                                                  \
23334   " via <addr> [table-id <n>]\n"                                        \
23335   "sw_if_index <id>] [l2]  [del]")                                      \
23336 _(bier_table_add_del,                                                   \
23337   "<label> <sub-domain> <set> <bsl> [del]")                             \
23338 _(bier_route_add_del,                                                   \
23339   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23340   "[<intfc> | sw_if_index <id>]"                                        \
23341   "[weight <n>] [del] [multipath]")                                     \
23342 _(proxy_arp_add_del,                                                    \
23343   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23344 _(proxy_arp_intfc_enable_disable,                                       \
23345   "<intfc> | sw_if_index <id> enable | disable")                        \
23346 _(sw_interface_set_unnumbered,                                          \
23347   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23348 _(ip_neighbor_add_del,                                                  \
23349   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23350   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23351 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23352 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23353   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23354   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23355   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23356 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23357 _(reset_fib, "vrf <n> [ipv6]")                                          \
23358 _(dhcp_proxy_config,                                                    \
23359   "svr <v46-address> src <v46-address>\n"                               \
23360    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23361 _(dhcp_proxy_set_vss,                                                   \
23362   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23363 _(dhcp_proxy_dump, "ip6")                                               \
23364 _(dhcp_client_config,                                                   \
23365   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23366 _(set_ip_flow_hash,                                                     \
23367   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23368 _(sw_interface_ip6_enable_disable,                                      \
23369   "<intfc> | sw_if_index <id> enable | disable")                        \
23370 _(sw_interface_ip6_set_link_local_address,                              \
23371   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23372 _(ip6nd_proxy_add_del,                                                  \
23373   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23374 _(ip6nd_proxy_dump, "")                                                 \
23375 _(sw_interface_ip6nd_ra_prefix,                                         \
23376   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23377   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23378   "[nolink] [isno]")                                                    \
23379 _(sw_interface_ip6nd_ra_config,                                         \
23380   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23381   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23382   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23383 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23384 _(l2_patch_add_del,                                                     \
23385   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23386   "enable | disable")                                                   \
23387 _(sr_localsid_add_del,                                                  \
23388   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23389   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23390 _(classify_add_del_table,                                               \
23391   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23392   " [del] [del-chain] mask <mask-value>\n"                              \
23393   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23394   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23395 _(classify_add_del_session,                                             \
23396   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23397   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23398   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23399   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23400 _(classify_set_interface_ip_table,                                      \
23401   "<intfc> | sw_if_index <nn> table <nn>")                              \
23402 _(classify_set_interface_l2_tables,                                     \
23403   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23404   "  [other-table <nn>]")                                               \
23405 _(get_node_index, "node <node-name")                                    \
23406 _(add_node_next, "node <node-name> next <next-node-name>")              \
23407 _(l2tpv3_create_tunnel,                                                 \
23408   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23409   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23410   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23411 _(l2tpv3_set_tunnel_cookies,                                            \
23412   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23413   "[new_remote_cookie <nn>]\n")                                         \
23414 _(l2tpv3_interface_enable_disable,                                      \
23415   "<intfc> | sw_if_index <nn> enable | disable")                        \
23416 _(l2tpv3_set_lookup_key,                                                \
23417   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23418 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23419 _(vxlan_add_del_tunnel,                                                 \
23420   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23421   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23422   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23423 _(geneve_add_del_tunnel,                                                \
23424   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23425   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23426   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23427 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23428 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23429 _(gre_add_del_tunnel,                                                   \
23430   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23431   "[teb | erspan <session-id>] [del]")                                  \
23432 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23433 _(l2_fib_clear_table, "")                                               \
23434 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23435 _(l2_interface_vlan_tag_rewrite,                                        \
23436   "<intfc> | sw_if_index <nn> \n"                                       \
23437   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23438   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23439 _(create_vhost_user_if,                                                 \
23440         "socket <filename> [server] [renumber <dev_instance>] "         \
23441         "[mac <mac_address>]")                                          \
23442 _(modify_vhost_user_if,                                                 \
23443         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23444         "[server] [renumber <dev_instance>]")                           \
23445 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23446 _(sw_interface_vhost_user_dump, "")                                     \
23447 _(show_version, "")                                                     \
23448 _(vxlan_gpe_add_del_tunnel,                                             \
23449   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23450   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23451   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23452   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23453 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23454 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23455 _(interface_name_renumber,                                              \
23456   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23457 _(input_acl_set_interface,                                              \
23458   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23459   "  [l2-table <nn>] [del]")                                            \
23460 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23461 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23462 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23463 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23464 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23465 _(ip_dump, "ipv4 | ipv6")                                               \
23466 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23467 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23468   "  spid_id <n> ")                                                     \
23469 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23470   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23471   "  integ_alg <alg> integ_key <hex>")                                  \
23472 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23473   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23474   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23475   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23476 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23477 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23478   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23479   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23480   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
23481 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23482 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23483   "  <alg> <hex>\n")                                                    \
23484 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23485 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23486 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23487   "(auth_data 0x<data> | auth_data <data>)")                            \
23488 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23489   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23490 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23491   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23492   "(local|remote)")                                                     \
23493 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23494 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23495 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23496 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23497 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23498 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23499 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23500 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23501 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23502 _(delete_loopback,"sw_if_index <nn>")                                   \
23503 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23504 _(map_add_domain,                                                       \
23505   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23506   "ip6-src <ip6addr> "                                                  \
23507   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23508 _(map_del_domain, "index <n>")                                          \
23509 _(map_add_del_rule,                                                     \
23510   "index <n> psid <n> dst <ip6addr> [del]")                             \
23511 _(map_domain_dump, "")                                                  \
23512 _(map_rule_dump, "index <map-domain>")                                  \
23513 _(want_interface_events,  "enable|disable")                             \
23514 _(want_stats,"enable|disable")                                          \
23515 _(get_first_msg_id, "client <name>")                                    \
23516 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23517 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23518   "fib-id <nn> [ip4][ip6][default]")                                    \
23519 _(get_node_graph, " ")                                                  \
23520 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23521 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23522 _(ioam_disable, "")                                                     \
23523 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23524                             " sw_if_index <sw_if_index> p <priority> "  \
23525                             "w <weight>] [del]")                        \
23526 _(one_add_del_locator, "locator-set <locator_name> "                    \
23527                         "iface <intf> | sw_if_index <sw_if_index> "     \
23528                         "p <priority> w <weight> [del]")                \
23529 _(one_add_del_local_eid,"vni <vni> eid "                                \
23530                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23531                          "locator-set <locator_name> [del]"             \
23532                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23533 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23534 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23535 _(one_enable_disable, "enable|disable")                                 \
23536 _(one_map_register_enable_disable, "enable|disable")                    \
23537 _(one_map_register_fallback_threshold, "<value>")                       \
23538 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23539 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23540                                "[seid <seid>] "                         \
23541                                "rloc <locator> p <prio> "               \
23542                                "w <weight> [rloc <loc> ... ] "          \
23543                                "action <action> [del-all]")             \
23544 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23545                           "<local-eid>")                                \
23546 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23547 _(one_use_petr, "ip-address> | disable")                                \
23548 _(one_map_request_mode, "src-dst|dst-only")                             \
23549 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23550 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23551 _(one_locator_set_dump, "[local | remote]")                             \
23552 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23553 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23554                        "[local] | [remote]")                            \
23555 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23556 _(one_ndp_bd_get, "")                                                   \
23557 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23558 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23559 _(one_l2_arp_bd_get, "")                                                \
23560 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23561 _(one_stats_enable_disable, "enable|disalbe")                           \
23562 _(show_one_stats_enable_disable, "")                                    \
23563 _(one_eid_table_vni_dump, "")                                           \
23564 _(one_eid_table_map_dump, "l2|l3")                                      \
23565 _(one_map_resolver_dump, "")                                            \
23566 _(one_map_server_dump, "")                                              \
23567 _(one_adjacencies_get, "vni <vni>")                                     \
23568 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23569 _(show_one_rloc_probe_state, "")                                        \
23570 _(show_one_map_register_state, "")                                      \
23571 _(show_one_status, "")                                                  \
23572 _(one_stats_dump, "")                                                   \
23573 _(one_stats_flush, "")                                                  \
23574 _(one_get_map_request_itr_rlocs, "")                                    \
23575 _(one_map_register_set_ttl, "<ttl>")                                    \
23576 _(one_set_transport_protocol, "udp|api")                                \
23577 _(one_get_transport_protocol, "")                                       \
23578 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23579 _(one_show_xtr_mode, "")                                                \
23580 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23581 _(one_show_pitr_mode, "")                                               \
23582 _(one_enable_disable_petr_mode, "enable|disable")                       \
23583 _(one_show_petr_mode, "")                                               \
23584 _(show_one_nsh_mapping, "")                                             \
23585 _(show_one_pitr, "")                                                    \
23586 _(show_one_use_petr, "")                                                \
23587 _(show_one_map_request_mode, "")                                        \
23588 _(show_one_map_register_ttl, "")                                        \
23589 _(show_one_map_register_fallback_threshold, "")                         \
23590 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23591                             " sw_if_index <sw_if_index> p <priority> "  \
23592                             "w <weight>] [del]")                        \
23593 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23594                         "iface <intf> | sw_if_index <sw_if_index> "     \
23595                         "p <priority> w <weight> [del]")                \
23596 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23597                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23598                          "locator-set <locator_name> [del]"             \
23599                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23600 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23601 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23602 _(lisp_enable_disable, "enable|disable")                                \
23603 _(lisp_map_register_enable_disable, "enable|disable")                   \
23604 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23605 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23606                                "[seid <seid>] "                         \
23607                                "rloc <locator> p <prio> "               \
23608                                "w <weight> [rloc <loc> ... ] "          \
23609                                "action <action> [del-all]")             \
23610 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23611                           "<local-eid>")                                \
23612 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23613 _(lisp_use_petr, "<ip-address> | disable")                              \
23614 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23615 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23616 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23617 _(lisp_locator_set_dump, "[local | remote]")                            \
23618 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23619 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23620                        "[local] | [remote]")                            \
23621 _(lisp_eid_table_vni_dump, "")                                          \
23622 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23623 _(lisp_map_resolver_dump, "")                                           \
23624 _(lisp_map_server_dump, "")                                             \
23625 _(lisp_adjacencies_get, "vni <vni>")                                    \
23626 _(gpe_fwd_entry_vnis_get, "")                                           \
23627 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23628 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23629                                 "[table <table-id>]")                   \
23630 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23631 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23632 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23633 _(gpe_get_encap_mode, "")                                               \
23634 _(lisp_gpe_add_del_iface, "up|down")                                    \
23635 _(lisp_gpe_enable_disable, "enable|disable")                            \
23636 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23637   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23638 _(show_lisp_rloc_probe_state, "")                                       \
23639 _(show_lisp_map_register_state, "")                                     \
23640 _(show_lisp_status, "")                                                 \
23641 _(lisp_get_map_request_itr_rlocs, "")                                   \
23642 _(show_lisp_pitr, "")                                                   \
23643 _(show_lisp_use_petr, "")                                               \
23644 _(show_lisp_map_request_mode, "")                                       \
23645 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23646 _(af_packet_delete, "name <host interface name>")                       \
23647 _(policer_add_del, "name <policer name> <params> [del]")                \
23648 _(policer_dump, "[name <policer name>]")                                \
23649 _(policer_classify_set_interface,                                       \
23650   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23651   "  [l2-table <nn>] [del]")                                            \
23652 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23653 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23654     "[master|slave]")                                                   \
23655 _(netmap_delete, "name <interface name>")                               \
23656 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23657 _(mpls_fib_dump, "")                                                    \
23658 _(classify_table_ids, "")                                               \
23659 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23660 _(classify_table_info, "table_id <nn>")                                 \
23661 _(classify_session_dump, "table_id <nn>")                               \
23662 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23663     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23664     "[template_interval <nn>] [udp_checksum]")                          \
23665 _(ipfix_exporter_dump, "")                                              \
23666 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23667 _(ipfix_classify_stream_dump, "")                                       \
23668 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23669 _(ipfix_classify_table_dump, "")                                        \
23670 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23671 _(sw_interface_span_dump, "[l2]")                                           \
23672 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23673 _(pg_create_interface, "if_id <nn>")                                    \
23674 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23675 _(pg_enable_disable, "[stream <id>] disable")                           \
23676 _(ip_source_and_port_range_check_add_del,                               \
23677   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23678 _(ip_source_and_port_range_check_interface_add_del,                     \
23679   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23680   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23681 _(ipsec_gre_add_del_tunnel,                                             \
23682   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23683 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23684 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23685 _(l2_interface_pbb_tag_rewrite,                                         \
23686   "<intfc> | sw_if_index <nn> \n"                                       \
23687   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23688   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23689 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23690 _(flow_classify_set_interface,                                          \
23691   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23692 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23693 _(ip_fib_dump, "")                                                      \
23694 _(ip_mfib_dump, "")                                                     \
23695 _(ip6_fib_dump, "")                                                     \
23696 _(ip6_mfib_dump, "")                                                    \
23697 _(feature_enable_disable, "arc_name <arc_name> "                        \
23698   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23699 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23700 "[disable]")                                                            \
23701 _(l2_xconnect_dump, "")                                                 \
23702 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23703 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23704 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23705 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23706 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23707 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23708 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23709   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23710 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23711 _(memfd_segment_create,"size <nnn>")                                    \
23712 _(sock_init_shm, "size <nnn>")                                          \
23713 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23714 _(dns_enable_disable, "[enable][disable]")                              \
23715 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23716 _(dns_resolve_name, "<hostname>")                                       \
23717 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23718 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23719 _(dns_resolve_name, "<hostname>")                                       \
23720 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23721   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23722 _(session_rules_dump, "")                                               \
23723 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23724 _(output_acl_set_interface,                                             \
23725   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23726   "  [l2-table <nn>] [del]")                                            \
23727
23728 /* List of command functions, CLI names map directly to functions */
23729 #define foreach_cli_function                                    \
23730 _(comment, "usage: comment <ignore-rest-of-line>")              \
23731 _(dump_interface_table, "usage: dump_interface_table")          \
23732 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23733 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23734 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23735 _(dump_stats_table, "usage: dump_stats_table")                  \
23736 _(dump_macro_table, "usage: dump_macro_table ")                 \
23737 _(dump_node_table, "usage: dump_node_table")                    \
23738 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23739 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23740 _(echo, "usage: echo <message>")                                \
23741 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23742 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23743 _(help, "usage: help")                                          \
23744 _(q, "usage: quit")                                             \
23745 _(quit, "usage: quit")                                          \
23746 _(search_node_table, "usage: search_node_table <name>...")      \
23747 _(set, "usage: set <variable-name> <value>")                    \
23748 _(script, "usage: script <file-name>")                          \
23749 _(unset, "usage: unset <variable-name>")
23750 #define _(N,n)                                  \
23751     static void vl_api_##n##_t_handler_uni      \
23752     (vl_api_##n##_t * mp)                       \
23753     {                                           \
23754         vat_main_t * vam = &vat_main;           \
23755         if (vam->json_output) {                 \
23756             vl_api_##n##_t_handler_json(mp);    \
23757         } else {                                \
23758             vl_api_##n##_t_handler(mp);         \
23759         }                                       \
23760     }
23761 foreach_vpe_api_reply_msg;
23762 #if VPP_API_TEST_BUILTIN == 0
23763 foreach_standalone_reply_msg;
23764 #endif
23765 #undef _
23766
23767 void
23768 vat_api_hookup (vat_main_t * vam)
23769 {
23770 #define _(N,n)                                                  \
23771     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23772                            vl_api_##n##_t_handler_uni,          \
23773                            vl_noop_handler,                     \
23774                            vl_api_##n##_t_endian,               \
23775                            vl_api_##n##_t_print,                \
23776                            sizeof(vl_api_##n##_t), 1);
23777   foreach_vpe_api_reply_msg;
23778 #if VPP_API_TEST_BUILTIN == 0
23779   foreach_standalone_reply_msg;
23780 #endif
23781 #undef _
23782
23783 #if (VPP_API_TEST_BUILTIN==0)
23784   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23785
23786   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23787
23788   vam->function_by_name = hash_create_string (0, sizeof (uword));
23789
23790   vam->help_by_name = hash_create_string (0, sizeof (uword));
23791 #endif
23792
23793   /* API messages we can send */
23794 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23795   foreach_vpe_api_msg;
23796 #undef _
23797
23798   /* Help strings */
23799 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23800   foreach_vpe_api_msg;
23801 #undef _
23802
23803   /* CLI functions */
23804 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23805   foreach_cli_function;
23806 #undef _
23807
23808   /* Help strings */
23809 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23810   foreach_cli_function;
23811 #undef _
23812 }
23813
23814 #if VPP_API_TEST_BUILTIN
23815 static clib_error_t *
23816 vat_api_hookup_shim (vlib_main_t * vm)
23817 {
23818   vat_api_hookup (&vat_main);
23819   return 0;
23820 }
23821
23822 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23823 #endif
23824
23825 /*
23826  * fd.io coding-style-patch-verification: ON
23827  *
23828  * Local Variables:
23829  * eval: (c-set-style "gnu")
23830  * End:
23831  */