Fix the order of RFC2685 fields in the output.
[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
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  is_del %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->is_del);
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 vl_api_mpls_tunnel_add_del_reply_t_handler
1779   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   i32 retval = ntohl (mp->retval);
1783   if (vam->async_mode)
1784     {
1785       vam->async_errors += (retval < 0);
1786     }
1787   else
1788     {
1789       vam->retval = retval;
1790       vam->result_ready = 1;
1791     }
1792 }
1793
1794 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1795   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   vat_json_node_t node;
1799
1800   vat_json_init_object (&node);
1801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1802   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1803                             ntohl (mp->sw_if_index));
1804
1805   vat_json_print (vam->ofp, &node);
1806   vat_json_free (&node);
1807
1808   vam->retval = ntohl (mp->retval);
1809   vam->result_ready = 1;
1810 }
1811
1812 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1813   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   i32 retval = ntohl (mp->retval);
1817   if (vam->async_mode)
1818     {
1819       vam->async_errors += (retval < 0);
1820     }
1821   else
1822     {
1823       vam->retval = retval;
1824       vam->sw_if_index = ntohl (mp->sw_if_index);
1825       vam->result_ready = 1;
1826     }
1827 }
1828
1829 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1830   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   vat_json_node_t node;
1834
1835   vat_json_init_object (&node);
1836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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 vl_api_gpe_add_del_fwd_entry_reply_t_handler
1847   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1863   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870   vat_json_object_add_uint (&node, "fwd_entry_index",
1871                             clib_net_to_host_u32 (mp->fwd_entry_index));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 u8 *
1881 format_lisp_transport_protocol (u8 * s, va_list * args)
1882 {
1883   u32 proto = va_arg (*args, u32);
1884
1885   switch (proto)
1886     {
1887     case 1:
1888       return format (s, "udp");
1889     case 2:
1890       return format (s, "api");
1891     default:
1892       return 0;
1893     }
1894   return 0;
1895 }
1896
1897 static void vl_api_one_get_transport_protocol_reply_t_handler
1898   (vl_api_one_get_transport_protocol_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       u32 proto = mp->protocol;
1909       print (vam->ofp, "Transport protocol: %U",
1910              format_lisp_transport_protocol, proto);
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1917   (vl_api_one_get_transport_protocol_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921   u8 *s;
1922
1923   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1924   vec_add1 (s, 0);
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1929
1930   vec_free (s);
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void vl_api_one_add_del_locator_set_reply_t_handler
1939   (vl_api_one_add_del_locator_set_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1955   (vl_api_one_add_del_locator_set_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1972   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->sw_if_index = ntohl (mp->sw_if_index);
1984       vam->result_ready = 1;
1985     }
1986   vam->regenerate_interface_table = 1;
1987 }
1988
1989 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1990   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2007   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   i32 retval = ntohl (mp->retval);
2011   if (vam->async_mode)
2012     {
2013       vam->async_errors += (retval < 0);
2014     }
2015   else
2016     {
2017       vam->retval = retval;
2018       vam->sw_if_index = ntohl (mp->sw_if_index);
2019       vam->result_ready = 1;
2020     }
2021 }
2022
2023 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2024   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t node;
2028
2029   vat_json_init_object (&node);
2030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2031   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2032
2033   vat_json_print (vam->ofp, &node);
2034   vat_json_free (&node);
2035
2036   vam->retval = ntohl (mp->retval);
2037   vam->result_ready = 1;
2038 }
2039
2040 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2041   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044   i32 retval = ntohl (mp->retval);
2045   if (vam->async_mode)
2046     {
2047       vam->async_errors += (retval < 0);
2048     }
2049   else
2050     {
2051       vam->retval = retval;
2052       vam->sw_if_index = ntohl (mp->sw_if_index);
2053       vam->result_ready = 1;
2054     }
2055   vam->regenerate_interface_table = 1;
2056 }
2057
2058 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2059   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2060 {
2061   vat_main_t *vam = &vat_main;
2062   vat_json_node_t node;
2063
2064   vat_json_init_object (&node);
2065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2066   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2067
2068   vat_json_print (vam->ofp, &node);
2069   vat_json_free (&node);
2070
2071   vam->retval = ntohl (mp->retval);
2072   vam->result_ready = 1;
2073 }
2074
2075 static void vl_api_gre_add_del_tunnel_reply_t_handler
2076   (vl_api_gre_add_del_tunnel_reply_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   i32 retval = ntohl (mp->retval);
2080   if (vam->async_mode)
2081     {
2082       vam->async_errors += (retval < 0);
2083     }
2084   else
2085     {
2086       vam->retval = retval;
2087       vam->sw_if_index = ntohl (mp->sw_if_index);
2088       vam->result_ready = 1;
2089     }
2090 }
2091
2092 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2093   (vl_api_gre_add_del_tunnel_reply_t * mp)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   vat_json_node_t node;
2097
2098   vat_json_init_object (&node);
2099   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2100   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2101
2102   vat_json_print (vam->ofp, &node);
2103   vat_json_free (&node);
2104
2105   vam->retval = ntohl (mp->retval);
2106   vam->result_ready = 1;
2107 }
2108
2109 static void vl_api_create_vhost_user_if_reply_t_handler
2110   (vl_api_create_vhost_user_if_reply_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113   i32 retval = ntohl (mp->retval);
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->sw_if_index = ntohl (mp->sw_if_index);
2122       vam->result_ready = 1;
2123     }
2124   vam->regenerate_interface_table = 1;
2125 }
2126
2127 static void vl_api_create_vhost_user_if_reply_t_handler_json
2128   (vl_api_create_vhost_user_if_reply_t * mp)
2129 {
2130   vat_main_t *vam = &vat_main;
2131   vat_json_node_t node;
2132
2133   vat_json_init_object (&node);
2134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2135   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2136
2137   vat_json_print (vam->ofp, &node);
2138   vat_json_free (&node);
2139
2140   vam->retval = ntohl (mp->retval);
2141   vam->result_ready = 1;
2142 }
2143
2144 static clib_error_t *
2145 receive_fd_msg (int socket_fd, int *my_fd)
2146 {
2147   char msgbuf[16];
2148   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2149   struct msghdr mh = { 0 };
2150   struct iovec iov[1];
2151   ssize_t size;
2152   struct ucred *cr = 0;
2153   struct cmsghdr *cmsg;
2154   pid_t pid __attribute__ ((unused));
2155   uid_t uid __attribute__ ((unused));
2156   gid_t gid __attribute__ ((unused));
2157
2158   iov[0].iov_base = msgbuf;
2159   iov[0].iov_len = 5;
2160   mh.msg_iov = iov;
2161   mh.msg_iovlen = 1;
2162   mh.msg_control = ctl;
2163   mh.msg_controllen = sizeof (ctl);
2164
2165   memset (ctl, 0, sizeof (ctl));
2166
2167   /* receive the incoming message */
2168   size = recvmsg (socket_fd, &mh, 0);
2169   if (size != 5)
2170     {
2171       return (size == 0) ? clib_error_return (0, "disconnected") :
2172         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2173                                 socket_fd);
2174     }
2175
2176   cmsg = CMSG_FIRSTHDR (&mh);
2177   while (cmsg)
2178     {
2179       if (cmsg->cmsg_level == SOL_SOCKET)
2180         {
2181           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2182             {
2183               cr = (struct ucred *) CMSG_DATA (cmsg);
2184               uid = cr->uid;
2185               gid = cr->gid;
2186               pid = cr->pid;
2187             }
2188           else if (cmsg->cmsg_type == SCM_RIGHTS)
2189             {
2190               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2191             }
2192         }
2193       cmsg = CMSG_NXTHDR (&mh, cmsg);
2194     }
2195   return 0;
2196 }
2197
2198 static void vl_api_memfd_segment_create_reply_t_handler
2199   (vl_api_memfd_segment_create_reply_t * mp)
2200 {
2201   /* Dont bother in the builtin version */
2202 #if VPP_API_TEST_BUILTIN == 0
2203   vat_main_t *vam = &vat_main;
2204   api_main_t *am = &api_main;
2205   socket_client_main_t *scm = vam->socket_client_main;
2206   int my_fd = -1;
2207   clib_error_t *error;
2208   ssvm_private_t memfd;
2209   i32 retval = ntohl (mp->retval);
2210
2211   if (retval == 0)
2212     {
2213       error = receive_fd_msg (scm->socket_fd, &my_fd);
2214       if (error)
2215         {
2216           retval = -99;
2217           goto out;
2218         }
2219
2220       memset (&memfd, 0, sizeof (memfd));
2221       memfd.fd = my_fd;
2222
2223       vam->client_index_invalid = 1;
2224
2225       /* Note: this closes memfd.fd */
2226       retval = ssvm_slave_init_memfd (&memfd);
2227       if (retval)
2228         clib_warning ("WARNING: segment map returned %d", retval);
2229
2230       /* Pivot to the memory client segment that vpp just created */
2231
2232       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2233
2234       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2235
2236       vl_client_install_client_message_handlers ();
2237
2238       vl_client_connect_to_vlib_no_map ("pvt",
2239                                         "vpp_api_test(p)",
2240                                         32 /* input_queue_length */ );
2241       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2242
2243       vl_socket_client_enable_disable (0 /* disable socket */ );
2244     }
2245
2246 out:
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->result_ready = 1;
2255     }
2256 #endif
2257 }
2258
2259 static void vl_api_memfd_segment_create_reply_t_handler_json
2260   (vl_api_memfd_segment_create_reply_t * mp)
2261 {
2262   clib_warning ("no");
2263 }
2264
2265 static void vl_api_dns_resolve_name_reply_t_handler
2266   (vl_api_dns_resolve_name_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   i32 retval = ntohl (mp->retval);
2270   if (vam->async_mode)
2271     {
2272       vam->async_errors += (retval < 0);
2273     }
2274   else
2275     {
2276       vam->retval = retval;
2277       vam->result_ready = 1;
2278
2279       if (retval == 0)
2280         {
2281           if (mp->ip4_set)
2282             clib_warning ("ip4 address %U", format_ip4_address,
2283                           (ip4_address_t *) mp->ip4_address);
2284           if (mp->ip6_set)
2285             clib_warning ("ip6 address %U", format_ip6_address,
2286                           (ip6_address_t *) mp->ip6_address);
2287         }
2288       else
2289         clib_warning ("retval %d", retval);
2290     }
2291 }
2292
2293 static void vl_api_dns_resolve_name_reply_t_handler_json
2294   (vl_api_dns_resolve_name_reply_t * mp)
2295 {
2296   clib_warning ("not implemented");
2297 }
2298
2299 static void vl_api_dns_resolve_ip_reply_t_handler
2300   (vl_api_dns_resolve_ip_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312
2313       if (retval == 0)
2314         {
2315           clib_warning ("canonical name %s", mp->name);
2316         }
2317       else
2318         clib_warning ("retval %d", retval);
2319     }
2320 }
2321
2322 static void vl_api_dns_resolve_ip_reply_t_handler_json
2323   (vl_api_dns_resolve_ip_reply_t * mp)
2324 {
2325   clib_warning ("not implemented");
2326 }
2327
2328
2329 static void vl_api_ip_address_details_t_handler
2330   (vl_api_ip_address_details_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   static ip_address_details_t empty_ip_address_details = { {0} };
2334   ip_address_details_t *address = NULL;
2335   ip_details_t *current_ip_details = NULL;
2336   ip_details_t *details = NULL;
2337
2338   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2339
2340   if (!details || vam->current_sw_if_index >= vec_len (details)
2341       || !details[vam->current_sw_if_index].present)
2342     {
2343       errmsg ("ip address details arrived but not stored");
2344       errmsg ("ip_dump should be called first");
2345       return;
2346     }
2347
2348   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2349
2350 #define addresses (current_ip_details->addr)
2351
2352   vec_validate_init_empty (addresses, vec_len (addresses),
2353                            empty_ip_address_details);
2354
2355   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2356
2357   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2358   address->prefix_length = mp->prefix_length;
2359 #undef addresses
2360 }
2361
2362 static void vl_api_ip_address_details_t_handler_json
2363   (vl_api_ip_address_details_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t *node = NULL;
2367   struct in6_addr ip6;
2368   struct in_addr ip4;
2369
2370   if (VAT_JSON_ARRAY != vam->json_tree.type)
2371     {
2372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2373       vat_json_init_array (&vam->json_tree);
2374     }
2375   node = vat_json_array_add (&vam->json_tree);
2376
2377   vat_json_init_object (node);
2378   if (vam->is_ipv6)
2379     {
2380       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2381       vat_json_object_add_ip6 (node, "ip", ip6);
2382     }
2383   else
2384     {
2385       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2386       vat_json_object_add_ip4 (node, "ip", ip4);
2387     }
2388   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2389 }
2390
2391 static void
2392 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   static ip_details_t empty_ip_details = { 0 };
2396   ip_details_t *ip = NULL;
2397   u32 sw_if_index = ~0;
2398
2399   sw_if_index = ntohl (mp->sw_if_index);
2400
2401   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2402                            sw_if_index, empty_ip_details);
2403
2404   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2405                          sw_if_index);
2406
2407   ip->present = 1;
2408 }
2409
2410 static void
2411 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2412 {
2413   vat_main_t *vam = &vat_main;
2414
2415   if (VAT_JSON_ARRAY != vam->json_tree.type)
2416     {
2417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418       vat_json_init_array (&vam->json_tree);
2419     }
2420   vat_json_array_add_uint (&vam->json_tree,
2421                            clib_net_to_host_u32 (mp->sw_if_index));
2422 }
2423
2424 static void vl_api_map_domain_details_t_handler_json
2425   (vl_api_map_domain_details_t * mp)
2426 {
2427   vat_json_node_t *node = NULL;
2428   vat_main_t *vam = &vat_main;
2429   struct in6_addr ip6;
2430   struct in_addr ip4;
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437
2438   node = vat_json_array_add (&vam->json_tree);
2439   vat_json_init_object (node);
2440
2441   vat_json_object_add_uint (node, "domain_index",
2442                             clib_net_to_host_u32 (mp->domain_index));
2443   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2444   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2445   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2446   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2447   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2448   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2449   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2450   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2451   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2452   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2453   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2454   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2455   vat_json_object_add_uint (node, "flags", mp->flags);
2456   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2457   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2458 }
2459
2460 static void vl_api_map_domain_details_t_handler
2461   (vl_api_map_domain_details_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464
2465   if (mp->is_translation)
2466     {
2467       print (vam->ofp,
2468              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2469              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2470              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2471              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2472              clib_net_to_host_u32 (mp->domain_index));
2473     }
2474   else
2475     {
2476       print (vam->ofp,
2477              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2478              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2479              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2480              format_ip6_address, mp->ip6_src,
2481              clib_net_to_host_u32 (mp->domain_index));
2482     }
2483   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2484          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2485          mp->is_translation ? "map-t" : "");
2486 }
2487
2488 static void vl_api_map_rule_details_t_handler_json
2489   (vl_api_map_rule_details_t * mp)
2490 {
2491   struct in6_addr ip6;
2492   vat_json_node_t *node = NULL;
2493   vat_main_t *vam = &vat_main;
2494
2495   if (VAT_JSON_ARRAY != vam->json_tree.type)
2496     {
2497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2498       vat_json_init_array (&vam->json_tree);
2499     }
2500
2501   node = vat_json_array_add (&vam->json_tree);
2502   vat_json_init_object (node);
2503
2504   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2505   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2506   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2507 }
2508
2509 static void
2510 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2514          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2515 }
2516
2517 static void
2518 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2519 {
2520   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2521           "router_addr %U host_mac %U",
2522           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2523           format_ip4_address, &mp->host_address,
2524           format_ip4_address, &mp->router_address,
2525           format_ethernet_address, mp->host_mac);
2526 }
2527
2528 static void vl_api_dhcp_compl_event_t_handler_json
2529   (vl_api_dhcp_compl_event_t * mp)
2530 {
2531   /* JSON output not supported */
2532 }
2533
2534 static void
2535 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2536                               u32 counter)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   static u64 default_counter = 0;
2540
2541   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2542                            NULL);
2543   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2544                            sw_if_index, default_counter);
2545   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2546 }
2547
2548 static void
2549 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2550                                 interface_counter_t counter)
2551 {
2552   vat_main_t *vam = &vat_main;
2553   static interface_counter_t default_counter = { 0, };
2554
2555   vec_validate_init_empty (vam->combined_interface_counters,
2556                            vnet_counter_type, NULL);
2557   vec_validate_init_empty (vam->combined_interface_counters
2558                            [vnet_counter_type], sw_if_index, default_counter);
2559   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2560 }
2561
2562 static void vl_api_vnet_interface_simple_counters_t_handler
2563   (vl_api_vnet_interface_simple_counters_t * mp)
2564 {
2565   /* not supported */
2566 }
2567
2568 static void vl_api_vnet_interface_combined_counters_t_handler
2569   (vl_api_vnet_interface_combined_counters_t * mp)
2570 {
2571   /* not supported */
2572 }
2573
2574 static void vl_api_vnet_interface_simple_counters_t_handler_json
2575   (vl_api_vnet_interface_simple_counters_t * mp)
2576 {
2577   u64 *v_packets;
2578   u64 packets;
2579   u32 count;
2580   u32 first_sw_if_index;
2581   int i;
2582
2583   count = ntohl (mp->count);
2584   first_sw_if_index = ntohl (mp->first_sw_if_index);
2585
2586   v_packets = (u64 *) & mp->data;
2587   for (i = 0; i < count; i++)
2588     {
2589       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2590       set_simple_interface_counter (mp->vnet_counter_type,
2591                                     first_sw_if_index + i, packets);
2592       v_packets++;
2593     }
2594 }
2595
2596 static void vl_api_vnet_interface_combined_counters_t_handler_json
2597   (vl_api_vnet_interface_combined_counters_t * mp)
2598 {
2599   interface_counter_t counter;
2600   vlib_counter_t *v;
2601   u32 first_sw_if_index;
2602   int i;
2603   u32 count;
2604
2605   count = ntohl (mp->count);
2606   first_sw_if_index = ntohl (mp->first_sw_if_index);
2607
2608   v = (vlib_counter_t *) & mp->data;
2609   for (i = 0; i < count; i++)
2610     {
2611       counter.packets =
2612         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2613       counter.bytes =
2614         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2615       set_combined_interface_counter (mp->vnet_counter_type,
2616                                       first_sw_if_index + i, counter);
2617       v++;
2618     }
2619 }
2620
2621 static u32
2622 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2623 {
2624   vat_main_t *vam = &vat_main;
2625   u32 i;
2626
2627   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2628     {
2629       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2630         {
2631           return i;
2632         }
2633     }
2634   return ~0;
2635 }
2636
2637 static u32
2638 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   u32 i;
2642
2643   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2644     {
2645       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2646         {
2647           return i;
2648         }
2649     }
2650   return ~0;
2651 }
2652
2653 static void vl_api_vnet_ip4_fib_counters_t_handler
2654   (vl_api_vnet_ip4_fib_counters_t * mp)
2655 {
2656   /* not supported */
2657 }
2658
2659 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2660   (vl_api_vnet_ip4_fib_counters_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   vl_api_ip4_fib_counter_t *v;
2664   ip4_fib_counter_t *counter;
2665   struct in_addr ip4;
2666   u32 vrf_id;
2667   u32 vrf_index;
2668   u32 count;
2669   int i;
2670
2671   vrf_id = ntohl (mp->vrf_id);
2672   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2673   if (~0 == vrf_index)
2674     {
2675       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2676       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2677       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2678       vec_validate (vam->ip4_fib_counters, vrf_index);
2679       vam->ip4_fib_counters[vrf_index] = NULL;
2680     }
2681
2682   vec_free (vam->ip4_fib_counters[vrf_index]);
2683   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2684   count = ntohl (mp->count);
2685   for (i = 0; i < count; i++)
2686     {
2687       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2688       counter = &vam->ip4_fib_counters[vrf_index][i];
2689       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2690       counter->address = ip4;
2691       counter->address_length = v->address_length;
2692       counter->packets = clib_net_to_host_u64 (v->packets);
2693       counter->bytes = clib_net_to_host_u64 (v->bytes);
2694       v++;
2695     }
2696 }
2697
2698 static void vl_api_vnet_ip4_nbr_counters_t_handler
2699   (vl_api_vnet_ip4_nbr_counters_t * mp)
2700 {
2701   /* not supported */
2702 }
2703
2704 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2705   (vl_api_vnet_ip4_nbr_counters_t * mp)
2706 {
2707   vat_main_t *vam = &vat_main;
2708   vl_api_ip4_nbr_counter_t *v;
2709   ip4_nbr_counter_t *counter;
2710   u32 sw_if_index;
2711   u32 count;
2712   int i;
2713
2714   sw_if_index = ntohl (mp->sw_if_index);
2715   count = ntohl (mp->count);
2716   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2717
2718   if (mp->begin)
2719     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2720
2721   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2722   for (i = 0; i < count; i++)
2723     {
2724       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2725       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2726       counter->address.s_addr = v->address;
2727       counter->packets = clib_net_to_host_u64 (v->packets);
2728       counter->bytes = clib_net_to_host_u64 (v->bytes);
2729       counter->linkt = v->link_type;
2730       v++;
2731     }
2732 }
2733
2734 static void vl_api_vnet_ip6_fib_counters_t_handler
2735   (vl_api_vnet_ip6_fib_counters_t * mp)
2736 {
2737   /* not supported */
2738 }
2739
2740 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2741   (vl_api_vnet_ip6_fib_counters_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744   vl_api_ip6_fib_counter_t *v;
2745   ip6_fib_counter_t *counter;
2746   struct in6_addr ip6;
2747   u32 vrf_id;
2748   u32 vrf_index;
2749   u32 count;
2750   int i;
2751
2752   vrf_id = ntohl (mp->vrf_id);
2753   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2754   if (~0 == vrf_index)
2755     {
2756       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2757       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2758       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2759       vec_validate (vam->ip6_fib_counters, vrf_index);
2760       vam->ip6_fib_counters[vrf_index] = NULL;
2761     }
2762
2763   vec_free (vam->ip6_fib_counters[vrf_index]);
2764   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2765   count = ntohl (mp->count);
2766   for (i = 0; i < count; i++)
2767     {
2768       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2769       counter = &vam->ip6_fib_counters[vrf_index][i];
2770       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2771       counter->address = ip6;
2772       counter->address_length = v->address_length;
2773       counter->packets = clib_net_to_host_u64 (v->packets);
2774       counter->bytes = clib_net_to_host_u64 (v->bytes);
2775       v++;
2776     }
2777 }
2778
2779 static void vl_api_vnet_ip6_nbr_counters_t_handler
2780   (vl_api_vnet_ip6_nbr_counters_t * mp)
2781 {
2782   /* not supported */
2783 }
2784
2785 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2786   (vl_api_vnet_ip6_nbr_counters_t * mp)
2787 {
2788   vat_main_t *vam = &vat_main;
2789   vl_api_ip6_nbr_counter_t *v;
2790   ip6_nbr_counter_t *counter;
2791   struct in6_addr ip6;
2792   u32 sw_if_index;
2793   u32 count;
2794   int i;
2795
2796   sw_if_index = ntohl (mp->sw_if_index);
2797   count = ntohl (mp->count);
2798   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2799
2800   if (mp->begin)
2801     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2802
2803   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2804   for (i = 0; i < count; i++)
2805     {
2806       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2807       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2808       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2809       counter->address = ip6;
2810       counter->packets = clib_net_to_host_u64 (v->packets);
2811       counter->bytes = clib_net_to_host_u64 (v->bytes);
2812       v++;
2813     }
2814 }
2815
2816 static void vl_api_get_first_msg_id_reply_t_handler
2817   (vl_api_get_first_msg_id_reply_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   i32 retval = ntohl (mp->retval);
2821
2822   if (vam->async_mode)
2823     {
2824       vam->async_errors += (retval < 0);
2825     }
2826   else
2827     {
2828       vam->retval = retval;
2829       vam->result_ready = 1;
2830     }
2831   if (retval >= 0)
2832     {
2833       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2834     }
2835 }
2836
2837 static void vl_api_get_first_msg_id_reply_t_handler_json
2838   (vl_api_get_first_msg_id_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t node;
2842
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "first_msg_id",
2846                             (uint) ntohs (mp->first_msg_id));
2847
2848   vat_json_print (vam->ofp, &node);
2849   vat_json_free (&node);
2850
2851   vam->retval = ntohl (mp->retval);
2852   vam->result_ready = 1;
2853 }
2854
2855 static void vl_api_get_node_graph_reply_t_handler
2856   (vl_api_get_node_graph_reply_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   api_main_t *am = &api_main;
2860   i32 retval = ntohl (mp->retval);
2861   u8 *pvt_copy, *reply;
2862   void *oldheap;
2863   vlib_node_t *node;
2864   int i;
2865
2866   if (vam->async_mode)
2867     {
2868       vam->async_errors += (retval < 0);
2869     }
2870   else
2871     {
2872       vam->retval = retval;
2873       vam->result_ready = 1;
2874     }
2875
2876   /* "Should never happen..." */
2877   if (retval != 0)
2878     return;
2879
2880   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2881   pvt_copy = vec_dup (reply);
2882
2883   /* Toss the shared-memory original... */
2884   pthread_mutex_lock (&am->vlib_rp->mutex);
2885   oldheap = svm_push_data_heap (am->vlib_rp);
2886
2887   vec_free (reply);
2888
2889   svm_pop_heap (oldheap);
2890   pthread_mutex_unlock (&am->vlib_rp->mutex);
2891
2892   if (vam->graph_nodes)
2893     {
2894       hash_free (vam->graph_node_index_by_name);
2895
2896       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2897         {
2898           node = vam->graph_nodes[i];
2899           vec_free (node->name);
2900           vec_free (node->next_nodes);
2901           vec_free (node);
2902         }
2903       vec_free (vam->graph_nodes);
2904     }
2905
2906   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2907   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2908   vec_free (pvt_copy);
2909
2910   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2911     {
2912       node = vam->graph_nodes[i];
2913       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2914     }
2915 }
2916
2917 static void vl_api_get_node_graph_reply_t_handler_json
2918   (vl_api_get_node_graph_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   api_main_t *am = &api_main;
2922   void *oldheap;
2923   vat_json_node_t node;
2924   u8 *reply;
2925
2926   /* $$$$ make this real? */
2927   vat_json_init_object (&node);
2928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2929   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2930
2931   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2932
2933   /* Toss the shared-memory original... */
2934   pthread_mutex_lock (&am->vlib_rp->mutex);
2935   oldheap = svm_push_data_heap (am->vlib_rp);
2936
2937   vec_free (reply);
2938
2939   svm_pop_heap (oldheap);
2940   pthread_mutex_unlock (&am->vlib_rp->mutex);
2941
2942   vat_json_print (vam->ofp, &node);
2943   vat_json_free (&node);
2944
2945   vam->retval = ntohl (mp->retval);
2946   vam->result_ready = 1;
2947 }
2948
2949 static void
2950 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0;
2954
2955   if (mp->local)
2956     {
2957       s = format (s, "%=16d%=16d%=16d",
2958                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2959     }
2960   else
2961     {
2962       s = format (s, "%=16U%=16d%=16d",
2963                   mp->is_ipv6 ? format_ip6_address :
2964                   format_ip4_address,
2965                   mp->ip_address, mp->priority, mp->weight);
2966     }
2967
2968   print (vam->ofp, "%v", s);
2969   vec_free (s);
2970 }
2971
2972 static void
2973 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2974 {
2975   vat_main_t *vam = &vat_main;
2976   vat_json_node_t *node = NULL;
2977   struct in6_addr ip6;
2978   struct in_addr ip4;
2979
2980   if (VAT_JSON_ARRAY != vam->json_tree.type)
2981     {
2982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2983       vat_json_init_array (&vam->json_tree);
2984     }
2985   node = vat_json_array_add (&vam->json_tree);
2986   vat_json_init_object (node);
2987
2988   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2989   vat_json_object_add_uint (node, "priority", mp->priority);
2990   vat_json_object_add_uint (node, "weight", mp->weight);
2991
2992   if (mp->local)
2993     vat_json_object_add_uint (node, "sw_if_index",
2994                               clib_net_to_host_u32 (mp->sw_if_index));
2995   else
2996     {
2997       if (mp->is_ipv6)
2998         {
2999           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3000           vat_json_object_add_ip6 (node, "address", ip6);
3001         }
3002       else
3003         {
3004           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3005           vat_json_object_add_ip4 (node, "address", ip4);
3006         }
3007     }
3008 }
3009
3010 static void
3011 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3012                                           mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018
3019   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3020          ls_name);
3021   vec_free (ls_name);
3022 }
3023
3024 static void
3025   vl_api_one_locator_set_details_t_handler_json
3026   (vl_api_one_locator_set_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = 0;
3030   u8 *ls_name = 0;
3031
3032   ls_name = format (0, "%s", mp->ls_name);
3033   vec_add1 (ls_name, 0);
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3044   vat_json_object_add_uint (node, "ls_index",
3045                             clib_net_to_host_u32 (mp->ls_index));
3046   vec_free (ls_name);
3047 }
3048
3049 typedef struct
3050 {
3051   u32 spi;
3052   u8 si;
3053 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3054
3055 uword
3056 unformat_nsh_address (unformat_input_t * input, va_list * args)
3057 {
3058   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3059   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3060 }
3061
3062 u8 *
3063 format_nsh_address_vat (u8 * s, va_list * args)
3064 {
3065   nsh_t *a = va_arg (*args, nsh_t *);
3066   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3067 }
3068
3069 static u8 *
3070 format_lisp_flat_eid (u8 * s, va_list * args)
3071 {
3072   u32 type = va_arg (*args, u32);
3073   u8 *eid = va_arg (*args, u8 *);
3074   u32 eid_len = va_arg (*args, u32);
3075
3076   switch (type)
3077     {
3078     case 0:
3079       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3080     case 1:
3081       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3082     case 2:
3083       return format (s, "%U", format_ethernet_address, eid);
3084     case 3:
3085       return format (s, "%U", format_nsh_address_vat, eid);
3086     }
3087   return 0;
3088 }
3089
3090 static u8 *
3091 format_lisp_eid_vat (u8 * s, va_list * args)
3092 {
3093   u32 type = va_arg (*args, u32);
3094   u8 *eid = va_arg (*args, u8 *);
3095   u32 eid_len = va_arg (*args, u32);
3096   u8 *seid = va_arg (*args, u8 *);
3097   u32 seid_len = va_arg (*args, u32);
3098   u32 is_src_dst = va_arg (*args, u32);
3099
3100   if (is_src_dst)
3101     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3102
3103   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3104
3105   return s;
3106 }
3107
3108 static void
3109 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *s = 0, *eid = 0;
3113
3114   if (~0 == mp->locator_set_index)
3115     s = format (0, "action: %d", mp->action);
3116   else
3117     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3118
3119   eid = format (0, "%U", format_lisp_eid_vat,
3120                 mp->eid_type,
3121                 mp->eid,
3122                 mp->eid_prefix_len,
3123                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3124   vec_add1 (eid, 0);
3125
3126   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3127          clib_net_to_host_u32 (mp->vni),
3128          eid,
3129          mp->is_local ? "local" : "remote",
3130          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3131          clib_net_to_host_u16 (mp->key_id), mp->key);
3132
3133   vec_free (s);
3134   vec_free (eid);
3135 }
3136
3137 static void
3138 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3139                                              * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = 0;
3143   u8 *eid = 0;
3144
3145   if (VAT_JSON_ARRAY != vam->json_tree.type)
3146     {
3147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3148       vat_json_init_array (&vam->json_tree);
3149     }
3150   node = vat_json_array_add (&vam->json_tree);
3151
3152   vat_json_init_object (node);
3153   if (~0 == mp->locator_set_index)
3154     vat_json_object_add_uint (node, "action", mp->action);
3155   else
3156     vat_json_object_add_uint (node, "locator_set_index",
3157                               clib_net_to_host_u32 (mp->locator_set_index));
3158
3159   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3160   if (mp->eid_type == 3)
3161     {
3162       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3163       vat_json_init_object (nsh_json);
3164       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3165       vat_json_object_add_uint (nsh_json, "spi",
3166                                 clib_net_to_host_u32 (nsh->spi));
3167       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3168     }
3169   else
3170     {
3171       eid = format (0, "%U", format_lisp_eid_vat,
3172                     mp->eid_type,
3173                     mp->eid,
3174                     mp->eid_prefix_len,
3175                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3176       vec_add1 (eid, 0);
3177       vat_json_object_add_string_copy (node, "eid", eid);
3178       vec_free (eid);
3179     }
3180   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3181   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3182   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3183
3184   if (mp->key_id)
3185     {
3186       vat_json_object_add_uint (node, "key_id",
3187                                 clib_net_to_host_u16 (mp->key_id));
3188       vat_json_object_add_string_copy (node, "key", mp->key);
3189     }
3190 }
3191
3192 static void
3193 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   u8 *seid = 0, *deid = 0;
3197   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3198
3199   deid = format (0, "%U", format_lisp_eid_vat,
3200                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3201
3202   seid = format (0, "%U", format_lisp_eid_vat,
3203                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3204
3205   vec_add1 (deid, 0);
3206   vec_add1 (seid, 0);
3207
3208   if (mp->is_ip4)
3209     format_ip_address_fcn = format_ip4_address;
3210   else
3211     format_ip_address_fcn = format_ip6_address;
3212
3213
3214   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3215          clib_net_to_host_u32 (mp->vni),
3216          seid, deid,
3217          format_ip_address_fcn, mp->lloc,
3218          format_ip_address_fcn, mp->rloc,
3219          clib_net_to_host_u32 (mp->pkt_count),
3220          clib_net_to_host_u32 (mp->bytes));
3221
3222   vec_free (deid);
3223   vec_free (seid);
3224 }
3225
3226 static void
3227 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3228 {
3229   struct in6_addr ip6;
3230   struct in_addr ip4;
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t *node = 0;
3233   u8 *deid = 0, *seid = 0;
3234
3235   if (VAT_JSON_ARRAY != vam->json_tree.type)
3236     {
3237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3238       vat_json_init_array (&vam->json_tree);
3239     }
3240   node = vat_json_array_add (&vam->json_tree);
3241
3242   vat_json_init_object (node);
3243   deid = format (0, "%U", format_lisp_eid_vat,
3244                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3245
3246   seid = format (0, "%U", format_lisp_eid_vat,
3247                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3248
3249   vec_add1 (deid, 0);
3250   vec_add1 (seid, 0);
3251
3252   vat_json_object_add_string_copy (node, "seid", seid);
3253   vat_json_object_add_string_copy (node, "deid", deid);
3254   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3255
3256   if (mp->is_ip4)
3257     {
3258       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3259       vat_json_object_add_ip4 (node, "lloc", ip4);
3260       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3261       vat_json_object_add_ip4 (node, "rloc", ip4);
3262     }
3263   else
3264     {
3265       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3266       vat_json_object_add_ip6 (node, "lloc", ip6);
3267       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3268       vat_json_object_add_ip6 (node, "rloc", ip6);
3269     }
3270   vat_json_object_add_uint (node, "pkt_count",
3271                             clib_net_to_host_u32 (mp->pkt_count));
3272   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3273
3274   vec_free (deid);
3275   vec_free (seid);
3276 }
3277
3278 static void
3279   vl_api_one_eid_table_map_details_t_handler
3280   (vl_api_one_eid_table_map_details_t * mp)
3281 {
3282   vat_main_t *vam = &vat_main;
3283
3284   u8 *line = format (0, "%=10d%=10d",
3285                      clib_net_to_host_u32 (mp->vni),
3286                      clib_net_to_host_u32 (mp->dp_table));
3287   print (vam->ofp, "%v", line);
3288   vec_free (line);
3289 }
3290
3291 static void
3292   vl_api_one_eid_table_map_details_t_handler_json
3293   (vl_api_one_eid_table_map_details_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t *node = NULL;
3297
3298   if (VAT_JSON_ARRAY != vam->json_tree.type)
3299     {
3300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3301       vat_json_init_array (&vam->json_tree);
3302     }
3303   node = vat_json_array_add (&vam->json_tree);
3304   vat_json_init_object (node);
3305   vat_json_object_add_uint (node, "dp_table",
3306                             clib_net_to_host_u32 (mp->dp_table));
3307   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3308 }
3309
3310 static void
3311   vl_api_one_eid_table_vni_details_t_handler
3312   (vl_api_one_eid_table_vni_details_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315
3316   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3317   print (vam->ofp, "%v", line);
3318   vec_free (line);
3319 }
3320
3321 static void
3322   vl_api_one_eid_table_vni_details_t_handler_json
3323   (vl_api_one_eid_table_vni_details_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t *node = NULL;
3327
3328   if (VAT_JSON_ARRAY != vam->json_tree.type)
3329     {
3330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3331       vat_json_init_array (&vam->json_tree);
3332     }
3333   node = vat_json_array_add (&vam->json_tree);
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3336 }
3337
3338 static void
3339   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3340   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   print (vam->ofp, "fallback threshold value: %d", mp->value);
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3354   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t _node, *node = &_node;
3358   int retval = clib_net_to_host_u32 (mp->retval);
3359
3360   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "value", mp->value);
3363
3364   vat_json_print (vam->ofp, node);
3365   vat_json_free (node);
3366
3367   vam->retval = retval;
3368   vam->result_ready = 1;
3369 }
3370
3371 static void
3372   vl_api_show_one_map_register_state_reply_t_handler
3373   (vl_api_show_one_map_register_state_reply_t * mp)
3374 {
3375   vat_main_t *vam = &vat_main;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3379
3380   vam->retval = retval;
3381   vam->result_ready = 1;
3382 }
3383
3384 static void
3385   vl_api_show_one_map_register_state_reply_t_handler_json
3386   (vl_api_show_one_map_register_state_reply_t * mp)
3387 {
3388   vat_main_t *vam = &vat_main;
3389   vat_json_node_t _node, *node = &_node;
3390   int retval = clib_net_to_host_u32 (mp->retval);
3391
3392   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3393
3394   vat_json_init_object (node);
3395   vat_json_object_add_string_copy (node, "state", s);
3396
3397   vat_json_print (vam->ofp, node);
3398   vat_json_free (node);
3399
3400   vam->retval = retval;
3401   vam->result_ready = 1;
3402   vec_free (s);
3403 }
3404
3405 static void
3406   vl_api_show_one_rloc_probe_state_reply_t_handler
3407   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   int retval = clib_net_to_host_u32 (mp->retval);
3411
3412   if (retval)
3413     goto end;
3414
3415   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3416 end:
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3423   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   vat_json_node_t _node, *node = &_node;
3427   int retval = clib_net_to_host_u32 (mp->retval);
3428
3429   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3430   vat_json_init_object (node);
3431   vat_json_object_add_string_copy (node, "state", s);
3432
3433   vat_json_print (vam->ofp, node);
3434   vat_json_free (node);
3435
3436   vam->retval = retval;
3437   vam->result_ready = 1;
3438   vec_free (s);
3439 }
3440
3441 static void
3442   vl_api_show_one_stats_enable_disable_reply_t_handler
3443   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   int retval = clib_net_to_host_u32 (mp->retval);
3447
3448   if (retval)
3449     goto end;
3450
3451   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3452 end:
3453   vam->retval = retval;
3454   vam->result_ready = 1;
3455 }
3456
3457 static void
3458   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3459   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   vat_json_node_t _node, *node = &_node;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464
3465   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3466   vat_json_init_object (node);
3467   vat_json_object_add_string_copy (node, "state", s);
3468
3469   vat_json_print (vam->ofp, node);
3470   vat_json_free (node);
3471
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474   vec_free (s);
3475 }
3476
3477 static void
3478 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3479 {
3480   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3481   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3482   e->vni = clib_net_to_host_u32 (e->vni);
3483 }
3484
3485 static void
3486   gpe_fwd_entries_get_reply_t_net_to_host
3487   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3488 {
3489   u32 i;
3490
3491   mp->count = clib_net_to_host_u32 (mp->count);
3492   for (i = 0; i < mp->count; i++)
3493     {
3494       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3495     }
3496 }
3497
3498 static u8 *
3499 format_gpe_encap_mode (u8 * s, va_list * args)
3500 {
3501   u32 mode = va_arg (*args, u32);
3502
3503   switch (mode)
3504     {
3505     case 0:
3506       return format (s, "lisp");
3507     case 1:
3508       return format (s, "vxlan");
3509     }
3510   return 0;
3511 }
3512
3513 static void
3514   vl_api_gpe_get_encap_mode_reply_t_handler
3515   (vl_api_gpe_get_encap_mode_reply_t * mp)
3516 {
3517   vat_main_t *vam = &vat_main;
3518
3519   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3520   vam->retval = ntohl (mp->retval);
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_get_encap_mode_reply_t_handler_json
3526   (vl_api_gpe_get_encap_mode_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t node;
3530
3531   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3532   vec_add1 (encap_mode, 0);
3533
3534   vat_json_init_object (&node);
3535   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3536
3537   vec_free (encap_mode);
3538   vat_json_print (vam->ofp, &node);
3539   vat_json_free (&node);
3540
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_gpe_fwd_entry_path_details_t_handler
3547   (vl_api_gpe_fwd_entry_path_details_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3551
3552   if (mp->lcl_loc.is_ip4)
3553     format_ip_address_fcn = format_ip4_address;
3554   else
3555     format_ip_address_fcn = format_ip6_address;
3556
3557   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3558          format_ip_address_fcn, &mp->lcl_loc,
3559          format_ip_address_fcn, &mp->rmt_loc);
3560 }
3561
3562 static void
3563 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3564 {
3565   struct in6_addr ip6;
3566   struct in_addr ip4;
3567
3568   if (loc->is_ip4)
3569     {
3570       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3571       vat_json_object_add_ip4 (n, "address", ip4);
3572     }
3573   else
3574     {
3575       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3576       vat_json_object_add_ip6 (n, "address", ip6);
3577     }
3578   vat_json_object_add_uint (n, "weight", loc->weight);
3579 }
3580
3581 static void
3582   vl_api_gpe_fwd_entry_path_details_t_handler_json
3583   (vl_api_gpe_fwd_entry_path_details_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t *node = NULL;
3587   vat_json_node_t *loc_node;
3588
3589   if (VAT_JSON_ARRAY != vam->json_tree.type)
3590     {
3591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3592       vat_json_init_array (&vam->json_tree);
3593     }
3594   node = vat_json_array_add (&vam->json_tree);
3595   vat_json_init_object (node);
3596
3597   loc_node = vat_json_object_add (node, "local_locator");
3598   vat_json_init_object (loc_node);
3599   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3600
3601   loc_node = vat_json_object_add (node, "remote_locator");
3602   vat_json_init_object (loc_node);
3603   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3604 }
3605
3606 static void
3607   vl_api_gpe_fwd_entries_get_reply_t_handler
3608   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   u32 i;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613   vl_api_gpe_fwd_entry_t *e;
3614
3615   if (retval)
3616     goto end;
3617
3618   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3619
3620   for (i = 0; i < mp->count; i++)
3621     {
3622       e = &mp->entries[i];
3623       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3624              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3625              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3626     }
3627
3628 end:
3629   vam->retval = retval;
3630   vam->result_ready = 1;
3631 }
3632
3633 static void
3634   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3635   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3636 {
3637   u8 *s = 0;
3638   vat_main_t *vam = &vat_main;
3639   vat_json_node_t *e = 0, root;
3640   u32 i;
3641   int retval = clib_net_to_host_u32 (mp->retval);
3642   vl_api_gpe_fwd_entry_t *fwd;
3643
3644   if (retval)
3645     goto end;
3646
3647   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3648   vat_json_init_array (&root);
3649
3650   for (i = 0; i < mp->count; i++)
3651     {
3652       e = vat_json_array_add (&root);
3653       fwd = &mp->entries[i];
3654
3655       vat_json_init_object (e);
3656       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3657       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3658       vat_json_object_add_int (e, "vni", fwd->vni);
3659       vat_json_object_add_int (e, "action", fwd->action);
3660
3661       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3662                   fwd->leid_prefix_len);
3663       vec_add1 (s, 0);
3664       vat_json_object_add_string_copy (e, "leid", s);
3665       vec_free (s);
3666
3667       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3668                   fwd->reid_prefix_len);
3669       vec_add1 (s, 0);
3670       vat_json_object_add_string_copy (e, "reid", s);
3671       vec_free (s);
3672     }
3673
3674   vat_json_print (vam->ofp, &root);
3675   vat_json_free (&root);
3676
3677 end:
3678   vam->retval = retval;
3679   vam->result_ready = 1;
3680 }
3681
3682 static void
3683   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3684   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3685 {
3686   vat_main_t *vam = &vat_main;
3687   u32 i, n;
3688   int retval = clib_net_to_host_u32 (mp->retval);
3689   vl_api_gpe_native_fwd_rpath_t *r;
3690
3691   if (retval)
3692     goto end;
3693
3694   n = clib_net_to_host_u32 (mp->count);
3695
3696   for (i = 0; i < n; i++)
3697     {
3698       r = &mp->entries[i];
3699       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3700              clib_net_to_host_u32 (r->fib_index),
3701              clib_net_to_host_u32 (r->nh_sw_if_index),
3702              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3703     }
3704
3705 end:
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3712   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   vat_json_node_t root, *e;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718   vl_api_gpe_native_fwd_rpath_t *r;
3719   u8 *s;
3720
3721   if (retval)
3722     goto end;
3723
3724   n = clib_net_to_host_u32 (mp->count);
3725   vat_json_init_array (&root);
3726
3727   for (i = 0; i < n; i++)
3728     {
3729       e = vat_json_array_add (&root);
3730       vat_json_init_object (e);
3731       r = &mp->entries[i];
3732       s =
3733         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3734                 r->nh_addr);
3735       vec_add1 (s, 0);
3736       vat_json_object_add_string_copy (e, "ip4", s);
3737       vec_free (s);
3738
3739       vat_json_object_add_uint (e, "fib_index",
3740                                 clib_net_to_host_u32 (r->fib_index));
3741       vat_json_object_add_uint (e, "nh_sw_if_index",
3742                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3743     }
3744
3745   vat_json_print (vam->ofp, &root);
3746   vat_json_free (&root);
3747
3748 end:
3749   vam->retval = retval;
3750   vam->result_ready = 1;
3751 }
3752
3753 static void
3754   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3755   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3756 {
3757   vat_main_t *vam = &vat_main;
3758   u32 i, n;
3759   int retval = clib_net_to_host_u32 (mp->retval);
3760
3761   if (retval)
3762     goto end;
3763
3764   n = clib_net_to_host_u32 (mp->count);
3765
3766   for (i = 0; i < n; i++)
3767     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3776   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3777 {
3778   vat_main_t *vam = &vat_main;
3779   vat_json_node_t root;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787   vat_json_init_array (&root);
3788
3789   for (i = 0; i < n; i++)
3790     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_ndp_entries_get_reply_t_handler
3802   (vl_api_one_ndp_entries_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3815            format_ethernet_address, mp->entries[i].mac);
3816
3817 end:
3818   vam->retval = retval;
3819   vam->result_ready = 1;
3820 }
3821
3822 static void
3823   vl_api_one_ndp_entries_get_reply_t_handler_json
3824   (vl_api_one_ndp_entries_get_reply_t * mp)
3825 {
3826   u8 *s = 0;
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t *e = 0, root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831   vl_api_one_ndp_entry_t *arp_entry;
3832
3833   if (retval)
3834     goto end;
3835
3836   n = clib_net_to_host_u32 (mp->count);
3837   vat_json_init_array (&root);
3838
3839   for (i = 0; i < n; i++)
3840     {
3841       e = vat_json_array_add (&root);
3842       arp_entry = &mp->entries[i];
3843
3844       vat_json_init_object (e);
3845       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3846       vec_add1 (s, 0);
3847
3848       vat_json_object_add_string_copy (e, "mac", s);
3849       vec_free (s);
3850
3851       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3852       vec_add1 (s, 0);
3853       vat_json_object_add_string_copy (e, "ip6", s);
3854       vec_free (s);
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866   vl_api_one_l2_arp_entries_get_reply_t_handler
3867   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3868 {
3869   vat_main_t *vam = &vat_main;
3870   u32 i, n;
3871   int retval = clib_net_to_host_u32 (mp->retval);
3872
3873   if (retval)
3874     goto end;
3875
3876   n = clib_net_to_host_u32 (mp->count);
3877
3878   for (i = 0; i < n; i++)
3879     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3880            format_ethernet_address, mp->entries[i].mac);
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3889   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3890 {
3891   u8 *s = 0;
3892   vat_main_t *vam = &vat_main;
3893   vat_json_node_t *e = 0, root;
3894   u32 i, n;
3895   int retval = clib_net_to_host_u32 (mp->retval);
3896   vl_api_one_l2_arp_entry_t *arp_entry;
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       e = vat_json_array_add (&root);
3907       arp_entry = &mp->entries[i];
3908
3909       vat_json_init_object (e);
3910       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3911       vec_add1 (s, 0);
3912
3913       vat_json_object_add_string_copy (e, "mac", s);
3914       vec_free (s);
3915
3916       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3917       vec_add1 (s, 0);
3918       vat_json_object_add_string_copy (e, "ip4", s);
3919       vec_free (s);
3920     }
3921
3922   vat_json_print (vam->ofp, &root);
3923   vat_json_free (&root);
3924
3925 end:
3926   vam->retval = retval;
3927   vam->result_ready = 1;
3928 }
3929
3930 static void
3931 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3932 {
3933   vat_main_t *vam = &vat_main;
3934   u32 i, n;
3935   int retval = clib_net_to_host_u32 (mp->retval);
3936
3937   if (retval)
3938     goto end;
3939
3940   n = clib_net_to_host_u32 (mp->count);
3941
3942   for (i = 0; i < n; i++)
3943     {
3944       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3945     }
3946
3947 end:
3948   vam->retval = retval;
3949   vam->result_ready = 1;
3950 }
3951
3952 static void
3953   vl_api_one_ndp_bd_get_reply_t_handler_json
3954   (vl_api_one_ndp_bd_get_reply_t * mp)
3955 {
3956   vat_main_t *vam = &vat_main;
3957   vat_json_node_t root;
3958   u32 i, n;
3959   int retval = clib_net_to_host_u32 (mp->retval);
3960
3961   if (retval)
3962     goto end;
3963
3964   n = clib_net_to_host_u32 (mp->count);
3965   vat_json_init_array (&root);
3966
3967   for (i = 0; i < n; i++)
3968     {
3969       vat_json_array_add_uint (&root,
3970                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3971     }
3972
3973   vat_json_print (vam->ofp, &root);
3974   vat_json_free (&root);
3975
3976 end:
3977   vam->retval = retval;
3978   vam->result_ready = 1;
3979 }
3980
3981 static void
3982   vl_api_one_l2_arp_bd_get_reply_t_handler
3983   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3984 {
3985   vat_main_t *vam = &vat_main;
3986   u32 i, n;
3987   int retval = clib_net_to_host_u32 (mp->retval);
3988
3989   if (retval)
3990     goto end;
3991
3992   n = clib_net_to_host_u32 (mp->count);
3993
3994   for (i = 0; i < n; i++)
3995     {
3996       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3997     }
3998
3999 end:
4000   vam->retval = retval;
4001   vam->result_ready = 1;
4002 }
4003
4004 static void
4005   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4006   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4007 {
4008   vat_main_t *vam = &vat_main;
4009   vat_json_node_t root;
4010   u32 i, n;
4011   int retval = clib_net_to_host_u32 (mp->retval);
4012
4013   if (retval)
4014     goto end;
4015
4016   n = clib_net_to_host_u32 (mp->count);
4017   vat_json_init_array (&root);
4018
4019   for (i = 0; i < n; i++)
4020     {
4021       vat_json_array_add_uint (&root,
4022                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4023     }
4024
4025   vat_json_print (vam->ofp, &root);
4026   vat_json_free (&root);
4027
4028 end:
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_one_adjacencies_get_reply_t_handler
4035   (vl_api_one_adjacencies_get_reply_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   u32 i, n;
4039   int retval = clib_net_to_host_u32 (mp->retval);
4040   vl_api_one_adjacency_t *a;
4041
4042   if (retval)
4043     goto end;
4044
4045   n = clib_net_to_host_u32 (mp->count);
4046
4047   for (i = 0; i < n; i++)
4048     {
4049       a = &mp->adjacencies[i];
4050       print (vam->ofp, "%U %40U",
4051              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4052              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4053     }
4054
4055 end:
4056   vam->retval = retval;
4057   vam->result_ready = 1;
4058 }
4059
4060 static void
4061   vl_api_one_adjacencies_get_reply_t_handler_json
4062   (vl_api_one_adjacencies_get_reply_t * mp)
4063 {
4064   u8 *s = 0;
4065   vat_main_t *vam = &vat_main;
4066   vat_json_node_t *e = 0, root;
4067   u32 i, n;
4068   int retval = clib_net_to_host_u32 (mp->retval);
4069   vl_api_one_adjacency_t *a;
4070
4071   if (retval)
4072     goto end;
4073
4074   n = clib_net_to_host_u32 (mp->count);
4075   vat_json_init_array (&root);
4076
4077   for (i = 0; i < n; i++)
4078     {
4079       e = vat_json_array_add (&root);
4080       a = &mp->adjacencies[i];
4081
4082       vat_json_init_object (e);
4083       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4084                   a->leid_prefix_len);
4085       vec_add1 (s, 0);
4086       vat_json_object_add_string_copy (e, "leid", s);
4087       vec_free (s);
4088
4089       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4090                   a->reid_prefix_len);
4091       vec_add1 (s, 0);
4092       vat_json_object_add_string_copy (e, "reid", s);
4093       vec_free (s);
4094     }
4095
4096   vat_json_print (vam->ofp, &root);
4097   vat_json_free (&root);
4098
4099 end:
4100   vam->retval = retval;
4101   vam->result_ready = 1;
4102 }
4103
4104 static void
4105 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108
4109   print (vam->ofp, "%=20U",
4110          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4111          mp->ip_address);
4112 }
4113
4114 static void
4115   vl_api_one_map_server_details_t_handler_json
4116   (vl_api_one_map_server_details_t * mp)
4117 {
4118   vat_main_t *vam = &vat_main;
4119   vat_json_node_t *node = NULL;
4120   struct in6_addr ip6;
4121   struct in_addr ip4;
4122
4123   if (VAT_JSON_ARRAY != vam->json_tree.type)
4124     {
4125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4126       vat_json_init_array (&vam->json_tree);
4127     }
4128   node = vat_json_array_add (&vam->json_tree);
4129
4130   vat_json_init_object (node);
4131   if (mp->is_ipv6)
4132     {
4133       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4134       vat_json_object_add_ip6 (node, "map-server", ip6);
4135     }
4136   else
4137     {
4138       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4139       vat_json_object_add_ip4 (node, "map-server", ip4);
4140     }
4141 }
4142
4143 static void
4144 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4145                                            * mp)
4146 {
4147   vat_main_t *vam = &vat_main;
4148
4149   print (vam->ofp, "%=20U",
4150          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4151          mp->ip_address);
4152 }
4153
4154 static void
4155   vl_api_one_map_resolver_details_t_handler_json
4156   (vl_api_one_map_resolver_details_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t *node = NULL;
4160   struct in6_addr ip6;
4161   struct in_addr ip4;
4162
4163   if (VAT_JSON_ARRAY != vam->json_tree.type)
4164     {
4165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4166       vat_json_init_array (&vam->json_tree);
4167     }
4168   node = vat_json_array_add (&vam->json_tree);
4169
4170   vat_json_init_object (node);
4171   if (mp->is_ipv6)
4172     {
4173       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4174       vat_json_object_add_ip6 (node, "map resolver", ip6);
4175     }
4176   else
4177     {
4178       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4179       vat_json_object_add_ip4 (node, "map resolver", ip4);
4180     }
4181 }
4182
4183 static void
4184 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   i32 retval = ntohl (mp->retval);
4188
4189   if (0 <= retval)
4190     {
4191       print (vam->ofp, "feature: %s\ngpe: %s",
4192              mp->feature_status ? "enabled" : "disabled",
4193              mp->gpe_status ? "enabled" : "disabled");
4194     }
4195
4196   vam->retval = retval;
4197   vam->result_ready = 1;
4198 }
4199
4200 static void
4201   vl_api_show_one_status_reply_t_handler_json
4202   (vl_api_show_one_status_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   vat_json_node_t node;
4206   u8 *gpe_status = NULL;
4207   u8 *feature_status = NULL;
4208
4209   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4210   feature_status = format (0, "%s",
4211                            mp->feature_status ? "enabled" : "disabled");
4212   vec_add1 (gpe_status, 0);
4213   vec_add1 (feature_status, 0);
4214
4215   vat_json_init_object (&node);
4216   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4217   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4218
4219   vec_free (gpe_status);
4220   vec_free (feature_status);
4221
4222   vat_json_print (vam->ofp, &node);
4223   vat_json_free (&node);
4224
4225   vam->retval = ntohl (mp->retval);
4226   vam->result_ready = 1;
4227 }
4228
4229 static void
4230   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4231   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4232 {
4233   vat_main_t *vam = &vat_main;
4234   i32 retval = ntohl (mp->retval);
4235
4236   if (retval >= 0)
4237     {
4238       print (vam->ofp, "%=20s", mp->locator_set_name);
4239     }
4240
4241   vam->retval = retval;
4242   vam->result_ready = 1;
4243 }
4244
4245 static void
4246   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4247   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   vat_json_node_t *node = NULL;
4251
4252   if (VAT_JSON_ARRAY != vam->json_tree.type)
4253     {
4254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4255       vat_json_init_array (&vam->json_tree);
4256     }
4257   node = vat_json_array_add (&vam->json_tree);
4258
4259   vat_json_init_object (node);
4260   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4261
4262   vat_json_print (vam->ofp, node);
4263   vat_json_free (node);
4264
4265   vam->retval = ntohl (mp->retval);
4266   vam->result_ready = 1;
4267 }
4268
4269 static u8 *
4270 format_lisp_map_request_mode (u8 * s, va_list * args)
4271 {
4272   u32 mode = va_arg (*args, u32);
4273
4274   switch (mode)
4275     {
4276     case 0:
4277       return format (0, "dst-only");
4278     case 1:
4279       return format (0, "src-dst");
4280     }
4281   return 0;
4282 }
4283
4284 static void
4285   vl_api_show_one_map_request_mode_reply_t_handler
4286   (vl_api_show_one_map_request_mode_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       u32 mode = mp->mode;
4294       print (vam->ofp, "map_request_mode: %U",
4295              format_lisp_map_request_mode, mode);
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_map_request_mode_reply_t_handler_json
4304   (vl_api_show_one_map_request_mode_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *s = 0;
4309   u32 mode;
4310
4311   mode = mp->mode;
4312   s = format (0, "%U", format_lisp_map_request_mode, mode);
4313   vec_add1 (s, 0);
4314
4315   vat_json_init_object (&node);
4316   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vec_free (s);
4321   vam->retval = ntohl (mp->retval);
4322   vam->result_ready = 1;
4323 }
4324
4325 static void
4326   vl_api_one_show_xtr_mode_reply_t_handler
4327   (vl_api_one_show_xtr_mode_reply_t * mp)
4328 {
4329   vat_main_t *vam = &vat_main;
4330   i32 retval = ntohl (mp->retval);
4331
4332   if (0 <= retval)
4333     {
4334       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4335     }
4336
4337   vam->retval = retval;
4338   vam->result_ready = 1;
4339 }
4340
4341 static void
4342   vl_api_one_show_xtr_mode_reply_t_handler_json
4343   (vl_api_one_show_xtr_mode_reply_t * mp)
4344 {
4345   vat_main_t *vam = &vat_main;
4346   vat_json_node_t node;
4347   u8 *status = 0;
4348
4349   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4350   vec_add1 (status, 0);
4351
4352   vat_json_init_object (&node);
4353   vat_json_object_add_string_copy (&node, "status", status);
4354
4355   vec_free (status);
4356
4357   vat_json_print (vam->ofp, &node);
4358   vat_json_free (&node);
4359
4360   vam->retval = ntohl (mp->retval);
4361   vam->result_ready = 1;
4362 }
4363
4364 static void
4365   vl_api_one_show_pitr_mode_reply_t_handler
4366   (vl_api_one_show_pitr_mode_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369   i32 retval = ntohl (mp->retval);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_one_show_pitr_mode_reply_t_handler_json
4382   (vl_api_one_show_pitr_mode_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386   u8 *status = 0;
4387
4388   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4389   vec_add1 (status, 0);
4390
4391   vat_json_init_object (&node);
4392   vat_json_object_add_string_copy (&node, "status", status);
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_one_show_petr_mode_reply_t_handler
4405   (vl_api_one_show_petr_mode_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   if (0 <= retval)
4411     {
4412       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4413     }
4414
4415   vam->retval = retval;
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_one_show_petr_mode_reply_t_handler_json
4421   (vl_api_one_show_petr_mode_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   vat_json_node_t node;
4425   u8 *status = 0;
4426
4427   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4428   vec_add1 (status, 0);
4429
4430   vat_json_init_object (&node);
4431   vat_json_object_add_string_copy (&node, "status", status);
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static void
4443   vl_api_show_one_use_petr_reply_t_handler
4444   (vl_api_show_one_use_petr_reply_t * mp)
4445 {
4446   vat_main_t *vam = &vat_main;
4447   i32 retval = ntohl (mp->retval);
4448
4449   if (0 <= retval)
4450     {
4451       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4452       if (mp->status)
4453         {
4454           print (vam->ofp, "Proxy-ETR address; %U",
4455                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4456                  mp->address);
4457         }
4458     }
4459
4460   vam->retval = retval;
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465   vl_api_show_one_use_petr_reply_t_handler_json
4466   (vl_api_show_one_use_petr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   vat_json_node_t node;
4470   u8 *status = 0;
4471   struct in_addr ip4;
4472   struct in6_addr ip6;
4473
4474   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4475   vec_add1 (status, 0);
4476
4477   vat_json_init_object (&node);
4478   vat_json_object_add_string_copy (&node, "status", status);
4479   if (mp->status)
4480     {
4481       if (mp->is_ip4)
4482         {
4483           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4484           vat_json_object_add_ip6 (&node, "address", ip6);
4485         }
4486       else
4487         {
4488           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4489           vat_json_object_add_ip4 (&node, "address", ip4);
4490         }
4491     }
4492
4493   vec_free (status);
4494
4495   vat_json_print (vam->ofp, &node);
4496   vat_json_free (&node);
4497
4498   vam->retval = ntohl (mp->retval);
4499   vam->result_ready = 1;
4500 }
4501
4502 static void
4503   vl_api_show_one_nsh_mapping_reply_t_handler
4504   (vl_api_show_one_nsh_mapping_reply_t * mp)
4505 {
4506   vat_main_t *vam = &vat_main;
4507   i32 retval = ntohl (mp->retval);
4508
4509   if (0 <= retval)
4510     {
4511       print (vam->ofp, "%-20s%-16s",
4512              mp->is_set ? "set" : "not-set",
4513              mp->is_set ? (char *) mp->locator_set_name : "");
4514     }
4515
4516   vam->retval = retval;
4517   vam->result_ready = 1;
4518 }
4519
4520 static void
4521   vl_api_show_one_nsh_mapping_reply_t_handler_json
4522   (vl_api_show_one_nsh_mapping_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   vat_json_node_t node;
4526   u8 *status = 0;
4527
4528   status = format (0, "%s", mp->is_set ? "yes" : "no");
4529   vec_add1 (status, 0);
4530
4531   vat_json_init_object (&node);
4532   vat_json_object_add_string_copy (&node, "is_set", status);
4533   if (mp->is_set)
4534     {
4535       vat_json_object_add_string_copy (&node, "locator_set",
4536                                        mp->locator_set_name);
4537     }
4538
4539   vec_free (status);
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void
4549   vl_api_show_one_map_register_ttl_reply_t_handler
4550   (vl_api_show_one_map_register_ttl_reply_t * mp)
4551 {
4552   vat_main_t *vam = &vat_main;
4553   i32 retval = ntohl (mp->retval);
4554
4555   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4556
4557   if (0 <= retval)
4558     {
4559       print (vam->ofp, "ttl: %u", mp->ttl);
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_map_register_ttl_reply_t_handler_json
4568   (vl_api_show_one_map_register_ttl_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572
4573   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4574   vat_json_init_object (&node);
4575   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4576
4577   vat_json_print (vam->ofp, &node);
4578   vat_json_free (&node);
4579
4580   vam->retval = ntohl (mp->retval);
4581   vam->result_ready = 1;
4582 }
4583
4584 static void
4585 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4586 {
4587   vat_main_t *vam = &vat_main;
4588   i32 retval = ntohl (mp->retval);
4589
4590   if (0 <= retval)
4591     {
4592       print (vam->ofp, "%-20s%-16s",
4593              mp->status ? "enabled" : "disabled",
4594              mp->status ? (char *) mp->locator_set_name : "");
4595     }
4596
4597   vam->retval = retval;
4598   vam->result_ready = 1;
4599 }
4600
4601 static void
4602 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4603 {
4604   vat_main_t *vam = &vat_main;
4605   vat_json_node_t node;
4606   u8 *status = 0;
4607
4608   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4609   vec_add1 (status, 0);
4610
4611   vat_json_init_object (&node);
4612   vat_json_object_add_string_copy (&node, "status", status);
4613   if (mp->status)
4614     {
4615       vat_json_object_add_string_copy (&node, "locator_set",
4616                                        mp->locator_set_name);
4617     }
4618
4619   vec_free (status);
4620
4621   vat_json_print (vam->ofp, &node);
4622   vat_json_free (&node);
4623
4624   vam->retval = ntohl (mp->retval);
4625   vam->result_ready = 1;
4626 }
4627
4628 static u8 *
4629 format_policer_type (u8 * s, va_list * va)
4630 {
4631   u32 i = va_arg (*va, u32);
4632
4633   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4634     s = format (s, "1r2c");
4635   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4636     s = format (s, "1r3c");
4637   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4638     s = format (s, "2r3c-2698");
4639   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4640     s = format (s, "2r3c-4115");
4641   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4642     s = format (s, "2r3c-mef5cf1");
4643   else
4644     s = format (s, "ILLEGAL");
4645   return s;
4646 }
4647
4648 static u8 *
4649 format_policer_rate_type (u8 * s, va_list * va)
4650 {
4651   u32 i = va_arg (*va, u32);
4652
4653   if (i == SSE2_QOS_RATE_KBPS)
4654     s = format (s, "kbps");
4655   else if (i == SSE2_QOS_RATE_PPS)
4656     s = format (s, "pps");
4657   else
4658     s = format (s, "ILLEGAL");
4659   return s;
4660 }
4661
4662 static u8 *
4663 format_policer_round_type (u8 * s, va_list * va)
4664 {
4665   u32 i = va_arg (*va, u32);
4666
4667   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4668     s = format (s, "closest");
4669   else if (i == SSE2_QOS_ROUND_TO_UP)
4670     s = format (s, "up");
4671   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4672     s = format (s, "down");
4673   else
4674     s = format (s, "ILLEGAL");
4675   return s;
4676 }
4677
4678 static u8 *
4679 format_policer_action_type (u8 * s, va_list * va)
4680 {
4681   u32 i = va_arg (*va, u32);
4682
4683   if (i == SSE2_QOS_ACTION_DROP)
4684     s = format (s, "drop");
4685   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4686     s = format (s, "transmit");
4687   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4688     s = format (s, "mark-and-transmit");
4689   else
4690     s = format (s, "ILLEGAL");
4691   return s;
4692 }
4693
4694 static u8 *
4695 format_dscp (u8 * s, va_list * va)
4696 {
4697   u32 i = va_arg (*va, u32);
4698   char *t = 0;
4699
4700   switch (i)
4701     {
4702 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4703       foreach_vnet_dscp
4704 #undef _
4705     default:
4706       return format (s, "ILLEGAL");
4707     }
4708   s = format (s, "%s", t);
4709   return s;
4710 }
4711
4712 static void
4713 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4714 {
4715   vat_main_t *vam = &vat_main;
4716   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4717
4718   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4719     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4720   else
4721     conform_dscp_str = format (0, "");
4722
4723   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4724     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4725   else
4726     exceed_dscp_str = format (0, "");
4727
4728   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4729     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4730   else
4731     violate_dscp_str = format (0, "");
4732
4733   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4734          "rate type %U, round type %U, %s rate, %s color-aware, "
4735          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4736          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4737          "conform action %U%s, exceed action %U%s, violate action %U%s",
4738          mp->name,
4739          format_policer_type, mp->type,
4740          ntohl (mp->cir),
4741          ntohl (mp->eir),
4742          clib_net_to_host_u64 (mp->cb),
4743          clib_net_to_host_u64 (mp->eb),
4744          format_policer_rate_type, mp->rate_type,
4745          format_policer_round_type, mp->round_type,
4746          mp->single_rate ? "single" : "dual",
4747          mp->color_aware ? "is" : "not",
4748          ntohl (mp->cir_tokens_per_period),
4749          ntohl (mp->pir_tokens_per_period),
4750          ntohl (mp->scale),
4751          ntohl (mp->current_limit),
4752          ntohl (mp->current_bucket),
4753          ntohl (mp->extended_limit),
4754          ntohl (mp->extended_bucket),
4755          clib_net_to_host_u64 (mp->last_update_time),
4756          format_policer_action_type, mp->conform_action_type,
4757          conform_dscp_str,
4758          format_policer_action_type, mp->exceed_action_type,
4759          exceed_dscp_str,
4760          format_policer_action_type, mp->violate_action_type,
4761          violate_dscp_str);
4762
4763   vec_free (conform_dscp_str);
4764   vec_free (exceed_dscp_str);
4765   vec_free (violate_dscp_str);
4766 }
4767
4768 static void vl_api_policer_details_t_handler_json
4769   (vl_api_policer_details_t * mp)
4770 {
4771   vat_main_t *vam = &vat_main;
4772   vat_json_node_t *node;
4773   u8 *rate_type_str, *round_type_str, *type_str;
4774   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4775
4776   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4777   round_type_str =
4778     format (0, "%U", format_policer_round_type, mp->round_type);
4779   type_str = format (0, "%U", format_policer_type, mp->type);
4780   conform_action_str = format (0, "%U", format_policer_action_type,
4781                                mp->conform_action_type);
4782   exceed_action_str = format (0, "%U", format_policer_action_type,
4783                               mp->exceed_action_type);
4784   violate_action_str = format (0, "%U", format_policer_action_type,
4785                                mp->violate_action_type);
4786
4787   if (VAT_JSON_ARRAY != vam->json_tree.type)
4788     {
4789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4790       vat_json_init_array (&vam->json_tree);
4791     }
4792   node = vat_json_array_add (&vam->json_tree);
4793
4794   vat_json_init_object (node);
4795   vat_json_object_add_string_copy (node, "name", mp->name);
4796   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4797   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4798   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4799   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4800   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4801   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4802   vat_json_object_add_string_copy (node, "type", type_str);
4803   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4804   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4805   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4806   vat_json_object_add_uint (node, "cir_tokens_per_period",
4807                             ntohl (mp->cir_tokens_per_period));
4808   vat_json_object_add_uint (node, "eir_tokens_per_period",
4809                             ntohl (mp->pir_tokens_per_period));
4810   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4811   vat_json_object_add_uint (node, "current_bucket",
4812                             ntohl (mp->current_bucket));
4813   vat_json_object_add_uint (node, "extended_limit",
4814                             ntohl (mp->extended_limit));
4815   vat_json_object_add_uint (node, "extended_bucket",
4816                             ntohl (mp->extended_bucket));
4817   vat_json_object_add_uint (node, "last_update_time",
4818                             ntohl (mp->last_update_time));
4819   vat_json_object_add_string_copy (node, "conform_action",
4820                                    conform_action_str);
4821   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4824       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4828   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4829     {
4830       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4831       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4832       vec_free (dscp_str);
4833     }
4834   vat_json_object_add_string_copy (node, "violate_action",
4835                                    violate_action_str);
4836   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4837     {
4838       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4839       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4840       vec_free (dscp_str);
4841     }
4842
4843   vec_free (rate_type_str);
4844   vec_free (round_type_str);
4845   vec_free (type_str);
4846   vec_free (conform_action_str);
4847   vec_free (exceed_action_str);
4848   vec_free (violate_action_str);
4849 }
4850
4851 static void
4852 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4853                                            mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   int i, count = ntohl (mp->count);
4857
4858   if (count > 0)
4859     print (vam->ofp, "classify table ids (%d) : ", count);
4860   for (i = 0; i < count; i++)
4861     {
4862       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4863       print (vam->ofp, (i < count - 1) ? "," : "");
4864     }
4865   vam->retval = ntohl (mp->retval);
4866   vam->result_ready = 1;
4867 }
4868
4869 static void
4870   vl_api_classify_table_ids_reply_t_handler_json
4871   (vl_api_classify_table_ids_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   int i, count = ntohl (mp->count);
4875
4876   if (count > 0)
4877     {
4878       vat_json_node_t node;
4879
4880       vat_json_init_object (&node);
4881       for (i = 0; i < count; i++)
4882         {
4883           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4884         }
4885       vat_json_print (vam->ofp, &node);
4886       vat_json_free (&node);
4887     }
4888   vam->retval = ntohl (mp->retval);
4889   vam->result_ready = 1;
4890 }
4891
4892 static void
4893   vl_api_classify_table_by_interface_reply_t_handler
4894   (vl_api_classify_table_by_interface_reply_t * mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897   u32 table_id;
4898
4899   table_id = ntohl (mp->l2_table_id);
4900   if (table_id != ~0)
4901     print (vam->ofp, "l2 table id : %d", table_id);
4902   else
4903     print (vam->ofp, "l2 table id : No input ACL tables configured");
4904   table_id = ntohl (mp->ip4_table_id);
4905   if (table_id != ~0)
4906     print (vam->ofp, "ip4 table id : %d", table_id);
4907   else
4908     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4909   table_id = ntohl (mp->ip6_table_id);
4910   if (table_id != ~0)
4911     print (vam->ofp, "ip6 table id : %d", table_id);
4912   else
4913     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4914   vam->retval = ntohl (mp->retval);
4915   vam->result_ready = 1;
4916 }
4917
4918 static void
4919   vl_api_classify_table_by_interface_reply_t_handler_json
4920   (vl_api_classify_table_by_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   vat_json_init_object (&node);
4926
4927   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4928   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4929   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4930
4931   vat_json_print (vam->ofp, &node);
4932   vat_json_free (&node);
4933
4934   vam->retval = ntohl (mp->retval);
4935   vam->result_ready = 1;
4936 }
4937
4938 static void vl_api_policer_add_del_reply_t_handler
4939   (vl_api_policer_add_del_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   i32 retval = ntohl (mp->retval);
4943   if (vam->async_mode)
4944     {
4945       vam->async_errors += (retval < 0);
4946     }
4947   else
4948     {
4949       vam->retval = retval;
4950       vam->result_ready = 1;
4951       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4952         /*
4953          * Note: this is just barely thread-safe, depends on
4954          * the main thread spinning waiting for an answer...
4955          */
4956         errmsg ("policer index %d", ntohl (mp->policer_index));
4957     }
4958 }
4959
4960 static void vl_api_policer_add_del_reply_t_handler_json
4961   (vl_api_policer_add_del_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   vat_json_init_object (&node);
4967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4968   vat_json_object_add_uint (&node, "policer_index",
4969                             ntohl (mp->policer_index));
4970
4971   vat_json_print (vam->ofp, &node);
4972   vat_json_free (&node);
4973
4974   vam->retval = ntohl (mp->retval);
4975   vam->result_ready = 1;
4976 }
4977
4978 /* Format hex dump. */
4979 u8 *
4980 format_hex_bytes (u8 * s, va_list * va)
4981 {
4982   u8 *bytes = va_arg (*va, u8 *);
4983   int n_bytes = va_arg (*va, int);
4984   uword i;
4985
4986   /* Print short or long form depending on byte count. */
4987   uword short_form = n_bytes <= 32;
4988   u32 indent = format_get_indent (s);
4989
4990   if (n_bytes == 0)
4991     return s;
4992
4993   for (i = 0; i < n_bytes; i++)
4994     {
4995       if (!short_form && (i % 32) == 0)
4996         s = format (s, "%08x: ", i);
4997       s = format (s, "%02x", bytes[i]);
4998       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4999         s = format (s, "\n%U", format_white_space, indent);
5000     }
5001
5002   return s;
5003 }
5004
5005 static void
5006 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5007                                             * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010   i32 retval = ntohl (mp->retval);
5011   if (retval == 0)
5012     {
5013       print (vam->ofp, "classify table info :");
5014       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5015              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5016              ntohl (mp->miss_next_index));
5017       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5018              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5019              ntohl (mp->match_n_vectors));
5020       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5021              ntohl (mp->mask_length));
5022     }
5023   vam->retval = retval;
5024   vam->result_ready = 1;
5025 }
5026
5027 static void
5028   vl_api_classify_table_info_reply_t_handler_json
5029   (vl_api_classify_table_info_reply_t * mp)
5030 {
5031   vat_main_t *vam = &vat_main;
5032   vat_json_node_t node;
5033
5034   i32 retval = ntohl (mp->retval);
5035   if (retval == 0)
5036     {
5037       vat_json_init_object (&node);
5038
5039       vat_json_object_add_int (&node, "sessions",
5040                                ntohl (mp->active_sessions));
5041       vat_json_object_add_int (&node, "nexttbl",
5042                                ntohl (mp->next_table_index));
5043       vat_json_object_add_int (&node, "nextnode",
5044                                ntohl (mp->miss_next_index));
5045       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5046       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5047       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5048       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5049                       ntohl (mp->mask_length), 0);
5050       vat_json_object_add_string_copy (&node, "mask", s);
5051
5052       vat_json_print (vam->ofp, &node);
5053       vat_json_free (&node);
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void
5060 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5061                                            mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064
5065   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5066          ntohl (mp->hit_next_index), ntohl (mp->advance),
5067          ntohl (mp->opaque_index));
5068   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5069          ntohl (mp->match_length));
5070 }
5071
5072 static void
5073   vl_api_classify_session_details_t_handler_json
5074   (vl_api_classify_session_details_t * mp)
5075 {
5076   vat_main_t *vam = &vat_main;
5077   vat_json_node_t *node = NULL;
5078
5079   if (VAT_JSON_ARRAY != vam->json_tree.type)
5080     {
5081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5082       vat_json_init_array (&vam->json_tree);
5083     }
5084   node = vat_json_array_add (&vam->json_tree);
5085
5086   vat_json_init_object (node);
5087   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5088   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5089   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5090   u8 *s =
5091     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5092             0);
5093   vat_json_object_add_string_copy (node, "match", s);
5094 }
5095
5096 static void vl_api_pg_create_interface_reply_t_handler
5097   (vl_api_pg_create_interface_reply_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100
5101   vam->retval = ntohl (mp->retval);
5102   vam->result_ready = 1;
5103 }
5104
5105 static void vl_api_pg_create_interface_reply_t_handler_json
5106   (vl_api_pg_create_interface_reply_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t node;
5110
5111   i32 retval = ntohl (mp->retval);
5112   if (retval == 0)
5113     {
5114       vat_json_init_object (&node);
5115
5116       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5117
5118       vat_json_print (vam->ofp, &node);
5119       vat_json_free (&node);
5120     }
5121   vam->retval = ntohl (mp->retval);
5122   vam->result_ready = 1;
5123 }
5124
5125 static void vl_api_policer_classify_details_t_handler
5126   (vl_api_policer_classify_details_t * mp)
5127 {
5128   vat_main_t *vam = &vat_main;
5129
5130   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5131          ntohl (mp->table_index));
5132 }
5133
5134 static void vl_api_policer_classify_details_t_handler_json
5135   (vl_api_policer_classify_details_t * mp)
5136 {
5137   vat_main_t *vam = &vat_main;
5138   vat_json_node_t *node;
5139
5140   if (VAT_JSON_ARRAY != vam->json_tree.type)
5141     {
5142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5143       vat_json_init_array (&vam->json_tree);
5144     }
5145   node = vat_json_array_add (&vam->json_tree);
5146
5147   vat_json_init_object (node);
5148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5149   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5150 }
5151
5152 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5153   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5154 {
5155   vat_main_t *vam = &vat_main;
5156   i32 retval = ntohl (mp->retval);
5157   if (vam->async_mode)
5158     {
5159       vam->async_errors += (retval < 0);
5160     }
5161   else
5162     {
5163       vam->retval = retval;
5164       vam->sw_if_index = ntohl (mp->sw_if_index);
5165       vam->result_ready = 1;
5166     }
5167   vam->regenerate_interface_table = 1;
5168 }
5169
5170 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5171   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5172 {
5173   vat_main_t *vam = &vat_main;
5174   vat_json_node_t node;
5175
5176   vat_json_init_object (&node);
5177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5178   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5179
5180   vat_json_print (vam->ofp, &node);
5181   vat_json_free (&node);
5182
5183   vam->retval = ntohl (mp->retval);
5184   vam->result_ready = 1;
5185 }
5186
5187 static void vl_api_flow_classify_details_t_handler
5188   (vl_api_flow_classify_details_t * mp)
5189 {
5190   vat_main_t *vam = &vat_main;
5191
5192   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5193          ntohl (mp->table_index));
5194 }
5195
5196 static void vl_api_flow_classify_details_t_handler_json
5197   (vl_api_flow_classify_details_t * mp)
5198 {
5199   vat_main_t *vam = &vat_main;
5200   vat_json_node_t *node;
5201
5202   if (VAT_JSON_ARRAY != vam->json_tree.type)
5203     {
5204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5205       vat_json_init_array (&vam->json_tree);
5206     }
5207   node = vat_json_array_add (&vam->json_tree);
5208
5209   vat_json_init_object (node);
5210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5211   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5212 }
5213
5214 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5215 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5216 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5217 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5218 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5219 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5220 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5221 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5222 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5223 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5224 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5225 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5226 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5227 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5228 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5229 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5230 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5232 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5233 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5234 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5235 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5236
5237 /*
5238  * Generate boilerplate reply handlers, which
5239  * dig the return value out of the xxx_reply_t API message,
5240  * stick it into vam->retval, and set vam->result_ready
5241  *
5242  * Could also do this by pointing N message decode slots at
5243  * a single function, but that could break in subtle ways.
5244  */
5245
5246 #define foreach_standard_reply_retval_handler           \
5247 _(sw_interface_set_flags_reply)                         \
5248 _(sw_interface_add_del_address_reply)                   \
5249 _(sw_interface_set_rx_mode_reply)                       \
5250 _(sw_interface_set_table_reply)                         \
5251 _(sw_interface_set_mpls_enable_reply)                   \
5252 _(sw_interface_set_vpath_reply)                         \
5253 _(sw_interface_set_vxlan_bypass_reply)                  \
5254 _(sw_interface_set_geneve_bypass_reply)                 \
5255 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5256 _(sw_interface_set_l2_bridge_reply)                     \
5257 _(bridge_domain_add_del_reply)                          \
5258 _(sw_interface_set_l2_xconnect_reply)                   \
5259 _(l2fib_add_del_reply)                                  \
5260 _(l2fib_flush_int_reply)                                \
5261 _(l2fib_flush_bd_reply)                                 \
5262 _(ip_add_del_route_reply)                               \
5263 _(ip_table_add_del_reply)                               \
5264 _(ip_mroute_add_del_reply)                              \
5265 _(mpls_route_add_del_reply)                             \
5266 _(mpls_table_add_del_reply)                             \
5267 _(mpls_ip_bind_unbind_reply)                            \
5268 _(bier_route_add_del_reply)                             \
5269 _(bier_table_add_del_reply)                             \
5270 _(proxy_arp_add_del_reply)                              \
5271 _(proxy_arp_intfc_enable_disable_reply)                 \
5272 _(sw_interface_set_unnumbered_reply)                    \
5273 _(ip_neighbor_add_del_reply)                            \
5274 _(oam_add_del_reply)                                    \
5275 _(reset_fib_reply)                                      \
5276 _(dhcp_proxy_config_reply)                              \
5277 _(dhcp_proxy_set_vss_reply)                             \
5278 _(dhcp_client_config_reply)                             \
5279 _(set_ip_flow_hash_reply)                               \
5280 _(sw_interface_ip6_enable_disable_reply)                \
5281 _(sw_interface_ip6_set_link_local_address_reply)        \
5282 _(ip6nd_proxy_add_del_reply)                            \
5283 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5284 _(sw_interface_ip6nd_ra_config_reply)                   \
5285 _(set_arp_neighbor_limit_reply)                         \
5286 _(l2_patch_add_del_reply)                               \
5287 _(sr_policy_add_reply)                                  \
5288 _(sr_policy_mod_reply)                                  \
5289 _(sr_policy_del_reply)                                  \
5290 _(sr_localsid_add_del_reply)                            \
5291 _(sr_steering_add_del_reply)                            \
5292 _(classify_add_del_session_reply)                       \
5293 _(classify_set_interface_ip_table_reply)                \
5294 _(classify_set_interface_l2_tables_reply)               \
5295 _(l2tpv3_set_tunnel_cookies_reply)                      \
5296 _(l2tpv3_interface_enable_disable_reply)                \
5297 _(l2tpv3_set_lookup_key_reply)                          \
5298 _(l2_fib_clear_table_reply)                             \
5299 _(l2_interface_efp_filter_reply)                        \
5300 _(l2_interface_vlan_tag_rewrite_reply)                  \
5301 _(modify_vhost_user_if_reply)                           \
5302 _(delete_vhost_user_if_reply)                           \
5303 _(want_ip4_arp_events_reply)                            \
5304 _(want_ip6_nd_events_reply)                             \
5305 _(want_l2_macs_events_reply)                            \
5306 _(input_acl_set_interface_reply)                        \
5307 _(ipsec_spd_add_del_reply)                              \
5308 _(ipsec_interface_add_del_spd_reply)                    \
5309 _(ipsec_spd_add_del_entry_reply)                        \
5310 _(ipsec_sad_add_del_entry_reply)                        \
5311 _(ipsec_sa_set_key_reply)                               \
5312 _(ipsec_tunnel_if_add_del_reply)                        \
5313 _(ipsec_tunnel_if_set_key_reply)                        \
5314 _(ipsec_tunnel_if_set_sa_reply)                         \
5315 _(ikev2_profile_add_del_reply)                          \
5316 _(ikev2_profile_set_auth_reply)                         \
5317 _(ikev2_profile_set_id_reply)                           \
5318 _(ikev2_profile_set_ts_reply)                           \
5319 _(ikev2_set_local_key_reply)                            \
5320 _(ikev2_set_responder_reply)                            \
5321 _(ikev2_set_ike_transforms_reply)                       \
5322 _(ikev2_set_esp_transforms_reply)                       \
5323 _(ikev2_set_sa_lifetime_reply)                          \
5324 _(ikev2_initiate_sa_init_reply)                         \
5325 _(ikev2_initiate_del_ike_sa_reply)                      \
5326 _(ikev2_initiate_del_child_sa_reply)                    \
5327 _(ikev2_initiate_rekey_child_sa_reply)                  \
5328 _(delete_loopback_reply)                                \
5329 _(bd_ip_mac_add_del_reply)                              \
5330 _(map_del_domain_reply)                                 \
5331 _(map_add_del_rule_reply)                               \
5332 _(want_interface_events_reply)                          \
5333 _(want_stats_reply)                                     \
5334 _(cop_interface_enable_disable_reply)                   \
5335 _(cop_whitelist_enable_disable_reply)                   \
5336 _(sw_interface_clear_stats_reply)                       \
5337 _(ioam_enable_reply)                                    \
5338 _(ioam_disable_reply)                                   \
5339 _(one_add_del_locator_reply)                            \
5340 _(one_add_del_local_eid_reply)                          \
5341 _(one_add_del_remote_mapping_reply)                     \
5342 _(one_add_del_adjacency_reply)                          \
5343 _(one_add_del_map_resolver_reply)                       \
5344 _(one_add_del_map_server_reply)                         \
5345 _(one_enable_disable_reply)                             \
5346 _(one_rloc_probe_enable_disable_reply)                  \
5347 _(one_map_register_enable_disable_reply)                \
5348 _(one_map_register_set_ttl_reply)                       \
5349 _(one_set_transport_protocol_reply)                     \
5350 _(one_map_register_fallback_threshold_reply)            \
5351 _(one_pitr_set_locator_set_reply)                       \
5352 _(one_map_request_mode_reply)                           \
5353 _(one_add_del_map_request_itr_rlocs_reply)              \
5354 _(one_eid_table_add_del_map_reply)                      \
5355 _(one_use_petr_reply)                                   \
5356 _(one_stats_enable_disable_reply)                       \
5357 _(one_add_del_l2_arp_entry_reply)                       \
5358 _(one_add_del_ndp_entry_reply)                          \
5359 _(one_stats_flush_reply)                                \
5360 _(one_enable_disable_xtr_mode_reply)                    \
5361 _(one_enable_disable_pitr_mode_reply)                   \
5362 _(one_enable_disable_petr_mode_reply)                   \
5363 _(gpe_enable_disable_reply)                             \
5364 _(gpe_set_encap_mode_reply)                             \
5365 _(gpe_add_del_iface_reply)                              \
5366 _(gpe_add_del_native_fwd_rpath_reply)                   \
5367 _(af_packet_delete_reply)                               \
5368 _(policer_classify_set_interface_reply)                 \
5369 _(netmap_create_reply)                                  \
5370 _(netmap_delete_reply)                                  \
5371 _(set_ipfix_exporter_reply)                             \
5372 _(set_ipfix_classify_stream_reply)                      \
5373 _(ipfix_classify_table_add_del_reply)                   \
5374 _(flow_classify_set_interface_reply)                    \
5375 _(sw_interface_span_enable_disable_reply)               \
5376 _(pg_capture_reply)                                     \
5377 _(pg_enable_disable_reply)                              \
5378 _(ip_source_and_port_range_check_add_del_reply)         \
5379 _(ip_source_and_port_range_check_interface_add_del_reply)\
5380 _(delete_subif_reply)                                   \
5381 _(l2_interface_pbb_tag_rewrite_reply)                   \
5382 _(punt_reply)                                           \
5383 _(feature_enable_disable_reply)                         \
5384 _(sw_interface_tag_add_del_reply)                       \
5385 _(sw_interface_set_mtu_reply)                           \
5386 _(p2p_ethernet_add_reply)                               \
5387 _(p2p_ethernet_del_reply)                               \
5388 _(lldp_config_reply)                                    \
5389 _(sw_interface_set_lldp_reply)                          \
5390 _(tcp_configure_src_addresses_reply)                    \
5391 _(dns_enable_disable_reply)                             \
5392 _(dns_name_server_add_del_reply)                        \
5393 _(session_rule_add_del_reply)                           \
5394 _(ip_container_proxy_add_del_reply)                     \
5395 _(output_acl_set_interface_reply)
5396
5397 #define _(n)                                    \
5398     static void vl_api_##n##_t_handler          \
5399     (vl_api_##n##_t * mp)                       \
5400     {                                           \
5401         vat_main_t * vam = &vat_main;           \
5402         i32 retval = ntohl(mp->retval);         \
5403         if (vam->async_mode) {                  \
5404             vam->async_errors += (retval < 0);  \
5405         } else {                                \
5406             vam->retval = retval;               \
5407             vam->result_ready = 1;              \
5408         }                                       \
5409     }
5410 foreach_standard_reply_retval_handler;
5411 #undef _
5412
5413 #define _(n)                                    \
5414     static void vl_api_##n##_t_handler_json     \
5415     (vl_api_##n##_t * mp)                       \
5416     {                                           \
5417         vat_main_t * vam = &vat_main;           \
5418         vat_json_node_t node;                   \
5419         vat_json_init_object(&node);            \
5420         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5421         vat_json_print(vam->ofp, &node);        \
5422         vam->retval = ntohl(mp->retval);        \
5423         vam->result_ready = 1;                  \
5424     }
5425 foreach_standard_reply_retval_handler;
5426 #undef _
5427
5428 /*
5429  * Table of message reply handlers, must include boilerplate handlers
5430  * we just generated
5431  */
5432
5433 #define foreach_vpe_api_reply_msg                                       \
5434 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5435 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5436 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5437 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5438 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5439 _(CLI_REPLY, cli_reply)                                                 \
5440 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5441 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5442   sw_interface_add_del_address_reply)                                   \
5443 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5444 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5445 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5446 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5447 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5448 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5449 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5450 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5451   sw_interface_set_l2_xconnect_reply)                                   \
5452 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5453   sw_interface_set_l2_bridge_reply)                                     \
5454 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5455 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5456 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5457 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5458 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5459 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5460 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5461 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5462 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5463 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5464 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5465 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5466 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5467 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5468 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5469 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5470 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5471 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5472 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5473 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5474 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5475 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5476 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5477 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5478 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5479   proxy_arp_intfc_enable_disable_reply)                                 \
5480 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5481 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5482   sw_interface_set_unnumbered_reply)                                    \
5483 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5484 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5485 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5486 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5487 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5488 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5489 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5490 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5491 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5492 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5493 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5494   sw_interface_ip6_enable_disable_reply)                                \
5495 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5496   sw_interface_ip6_set_link_local_address_reply)                        \
5497 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5498 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5499 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5500   sw_interface_ip6nd_ra_prefix_reply)                                   \
5501 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5502   sw_interface_ip6nd_ra_config_reply)                                   \
5503 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5504 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5505 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5506 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5507 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5508 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5509 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5510 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5511 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5512 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5513 classify_set_interface_ip_table_reply)                                  \
5514 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5515   classify_set_interface_l2_tables_reply)                               \
5516 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5517 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5518 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5519 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5520 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5521   l2tpv3_interface_enable_disable_reply)                                \
5522 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5523 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5524 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5525 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5526 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5527 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5528 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5529 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5530 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5531 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5532 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5533 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5534 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5535 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5536 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5537 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5538 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5539 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5540 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5541 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5542 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5543 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5544 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5545 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5546 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5547 _(L2_MACS_EVENT, l2_macs_event)                                         \
5548 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5549 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5550 _(IP_DETAILS, ip_details)                                               \
5551 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5552 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5553 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5554 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5555 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5556 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5557 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5558 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5559 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5560 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5561 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5562 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5563 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5564 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5565 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5566 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5567 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5568 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5569 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5570 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5571 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5572 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5573 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5574 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5575 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5576 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5577 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5578 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5579 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5580 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5581 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5582 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5583 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5584 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5585 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5586 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5587 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5588 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5589 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5590 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5591 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5592 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5593 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5594 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5595 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5596 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5597 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5598 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5599   one_map_register_enable_disable_reply)                                \
5600 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5601 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5602 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5603 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5604   one_map_register_fallback_threshold_reply)                            \
5605 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5606   one_rloc_probe_enable_disable_reply)                                  \
5607 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5608 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5609 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5610 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5611 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5612 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5613 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5614 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5615 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5616 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5617 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5618 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5619 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5620 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5621 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5622 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5623   show_one_stats_enable_disable_reply)                                  \
5624 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5625 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5626 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5627 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5628 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5629 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5630 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5631 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5632   one_enable_disable_pitr_mode_reply)                                   \
5633 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5634   one_enable_disable_petr_mode_reply)                                   \
5635 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5636 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5637 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5638 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5639 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5640 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5641 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5642 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5643 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5644 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5645 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5646 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5647   gpe_add_del_native_fwd_rpath_reply)                                   \
5648 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5649   gpe_fwd_entry_path_details)                                           \
5650 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5651 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5652   one_add_del_map_request_itr_rlocs_reply)                              \
5653 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5654   one_get_map_request_itr_rlocs_reply)                                  \
5655 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5656 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5657 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5658 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5659 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5660 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5661   show_one_map_register_state_reply)                                    \
5662 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5663 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5664   show_one_map_register_fallback_threshold_reply)                       \
5665 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5666 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5667 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5668 _(POLICER_DETAILS, policer_details)                                     \
5669 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5670 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5671 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5672 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5673 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5674 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5675 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5676 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5677 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5678 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5679 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5680 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5681 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5682 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5683 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5684 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5685 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5686 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5687 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5688 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5689 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5690 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5691 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5692 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5693 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5694  ip_source_and_port_range_check_add_del_reply)                          \
5695 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5696  ip_source_and_port_range_check_interface_add_del_reply)                \
5697 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5698 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5699 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5700 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5701 _(PUNT_REPLY, punt_reply)                                               \
5702 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5703 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5704 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5705 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5706 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5707 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5708 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5709 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5710 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5711 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5712 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5713 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5714 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5715 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5716 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5717 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5718 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5719 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5720 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5721 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5722 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5723 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5724
5725 #define foreach_standalone_reply_msg                                    \
5726 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5727 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5728 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5729 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5730 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5731 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5732 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5733 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5734
5735 typedef struct
5736 {
5737   u8 *name;
5738   u32 value;
5739 } name_sort_t;
5740
5741
5742 #define STR_VTR_OP_CASE(op)     \
5743     case L2_VTR_ ## op:         \
5744         return "" # op;
5745
5746 static const char *
5747 str_vtr_op (u32 vtr_op)
5748 {
5749   switch (vtr_op)
5750     {
5751       STR_VTR_OP_CASE (DISABLED);
5752       STR_VTR_OP_CASE (PUSH_1);
5753       STR_VTR_OP_CASE (PUSH_2);
5754       STR_VTR_OP_CASE (POP_1);
5755       STR_VTR_OP_CASE (POP_2);
5756       STR_VTR_OP_CASE (TRANSLATE_1_1);
5757       STR_VTR_OP_CASE (TRANSLATE_1_2);
5758       STR_VTR_OP_CASE (TRANSLATE_2_1);
5759       STR_VTR_OP_CASE (TRANSLATE_2_2);
5760     }
5761
5762   return "UNKNOWN";
5763 }
5764
5765 static int
5766 dump_sub_interface_table (vat_main_t * vam)
5767 {
5768   const sw_interface_subif_t *sub = NULL;
5769
5770   if (vam->json_output)
5771     {
5772       clib_warning
5773         ("JSON output supported only for VPE API calls and dump_stats_table");
5774       return -99;
5775     }
5776
5777   print (vam->ofp,
5778          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5779          "Interface", "sw_if_index",
5780          "sub id", "dot1ad", "tags", "outer id",
5781          "inner id", "exact", "default", "outer any", "inner any");
5782
5783   vec_foreach (sub, vam->sw_if_subif_table)
5784   {
5785     print (vam->ofp,
5786            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5787            sub->interface_name,
5788            sub->sw_if_index,
5789            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5790            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5791            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5792            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5793     if (sub->vtr_op != L2_VTR_DISABLED)
5794       {
5795         print (vam->ofp,
5796                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5797                "tag1: %d tag2: %d ]",
5798                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5799                sub->vtr_tag1, sub->vtr_tag2);
5800       }
5801   }
5802
5803   return 0;
5804 }
5805
5806 static int
5807 name_sort_cmp (void *a1, void *a2)
5808 {
5809   name_sort_t *n1 = a1;
5810   name_sort_t *n2 = a2;
5811
5812   return strcmp ((char *) n1->name, (char *) n2->name);
5813 }
5814
5815 static int
5816 dump_interface_table (vat_main_t * vam)
5817 {
5818   hash_pair_t *p;
5819   name_sort_t *nses = 0, *ns;
5820
5821   if (vam->json_output)
5822     {
5823       clib_warning
5824         ("JSON output supported only for VPE API calls and dump_stats_table");
5825       return -99;
5826     }
5827
5828   /* *INDENT-OFF* */
5829   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5830   ({
5831     vec_add2 (nses, ns, 1);
5832     ns->name = (u8 *)(p->key);
5833     ns->value = (u32) p->value[0];
5834   }));
5835   /* *INDENT-ON* */
5836
5837   vec_sort_with_function (nses, name_sort_cmp);
5838
5839   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5840   vec_foreach (ns, nses)
5841   {
5842     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5843   }
5844   vec_free (nses);
5845   return 0;
5846 }
5847
5848 static int
5849 dump_ip_table (vat_main_t * vam, int is_ipv6)
5850 {
5851   const ip_details_t *det = NULL;
5852   const ip_address_details_t *address = NULL;
5853   u32 i = ~0;
5854
5855   print (vam->ofp, "%-12s", "sw_if_index");
5856
5857   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5858   {
5859     i++;
5860     if (!det->present)
5861       {
5862         continue;
5863       }
5864     print (vam->ofp, "%-12d", i);
5865     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5866     if (!det->addr)
5867       {
5868         continue;
5869       }
5870     vec_foreach (address, det->addr)
5871     {
5872       print (vam->ofp,
5873              "            %-30U%-13d",
5874              is_ipv6 ? format_ip6_address : format_ip4_address,
5875              address->ip, address->prefix_length);
5876     }
5877   }
5878
5879   return 0;
5880 }
5881
5882 static int
5883 dump_ipv4_table (vat_main_t * vam)
5884 {
5885   if (vam->json_output)
5886     {
5887       clib_warning
5888         ("JSON output supported only for VPE API calls and dump_stats_table");
5889       return -99;
5890     }
5891
5892   return dump_ip_table (vam, 0);
5893 }
5894
5895 static int
5896 dump_ipv6_table (vat_main_t * vam)
5897 {
5898   if (vam->json_output)
5899     {
5900       clib_warning
5901         ("JSON output supported only for VPE API calls and dump_stats_table");
5902       return -99;
5903     }
5904
5905   return dump_ip_table (vam, 1);
5906 }
5907
5908 static char *
5909 counter_type_to_str (u8 counter_type, u8 is_combined)
5910 {
5911   if (!is_combined)
5912     {
5913       switch (counter_type)
5914         {
5915         case VNET_INTERFACE_COUNTER_DROP:
5916           return "drop";
5917         case VNET_INTERFACE_COUNTER_PUNT:
5918           return "punt";
5919         case VNET_INTERFACE_COUNTER_IP4:
5920           return "ip4";
5921         case VNET_INTERFACE_COUNTER_IP6:
5922           return "ip6";
5923         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5924           return "rx-no-buf";
5925         case VNET_INTERFACE_COUNTER_RX_MISS:
5926           return "rx-miss";
5927         case VNET_INTERFACE_COUNTER_RX_ERROR:
5928           return "rx-error";
5929         case VNET_INTERFACE_COUNTER_TX_ERROR:
5930           return "tx-error";
5931         default:
5932           return "INVALID-COUNTER-TYPE";
5933         }
5934     }
5935   else
5936     {
5937       switch (counter_type)
5938         {
5939         case VNET_INTERFACE_COUNTER_RX:
5940           return "rx";
5941         case VNET_INTERFACE_COUNTER_TX:
5942           return "tx";
5943         default:
5944           return "INVALID-COUNTER-TYPE";
5945         }
5946     }
5947 }
5948
5949 static int
5950 dump_stats_table (vat_main_t * vam)
5951 {
5952   vat_json_node_t node;
5953   vat_json_node_t *msg_array;
5954   vat_json_node_t *msg;
5955   vat_json_node_t *counter_array;
5956   vat_json_node_t *counter;
5957   interface_counter_t c;
5958   u64 packets;
5959   ip4_fib_counter_t *c4;
5960   ip6_fib_counter_t *c6;
5961   ip4_nbr_counter_t *n4;
5962   ip6_nbr_counter_t *n6;
5963   int i, j;
5964
5965   if (!vam->json_output)
5966     {
5967       clib_warning ("dump_stats_table supported only in JSON format");
5968       return -99;
5969     }
5970
5971   vat_json_init_object (&node);
5972
5973   /* interface counters */
5974   msg_array = vat_json_object_add (&node, "interface_counters");
5975   vat_json_init_array (msg_array);
5976   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5977     {
5978       msg = vat_json_array_add (msg_array);
5979       vat_json_init_object (msg);
5980       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5981                                        (u8 *) counter_type_to_str (i, 0));
5982       vat_json_object_add_int (msg, "is_combined", 0);
5983       counter_array = vat_json_object_add (msg, "data");
5984       vat_json_init_array (counter_array);
5985       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5986         {
5987           packets = vam->simple_interface_counters[i][j];
5988           vat_json_array_add_uint (counter_array, packets);
5989         }
5990     }
5991   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5992     {
5993       msg = vat_json_array_add (msg_array);
5994       vat_json_init_object (msg);
5995       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5996                                        (u8 *) counter_type_to_str (i, 1));
5997       vat_json_object_add_int (msg, "is_combined", 1);
5998       counter_array = vat_json_object_add (msg, "data");
5999       vat_json_init_array (counter_array);
6000       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6001         {
6002           c = vam->combined_interface_counters[i][j];
6003           counter = vat_json_array_add (counter_array);
6004           vat_json_init_object (counter);
6005           vat_json_object_add_uint (counter, "packets", c.packets);
6006           vat_json_object_add_uint (counter, "bytes", c.bytes);
6007         }
6008     }
6009
6010   /* ip4 fib counters */
6011   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6012   vat_json_init_array (msg_array);
6013   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6014     {
6015       msg = vat_json_array_add (msg_array);
6016       vat_json_init_object (msg);
6017       vat_json_object_add_uint (msg, "vrf_id",
6018                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6019       counter_array = vat_json_object_add (msg, "c");
6020       vat_json_init_array (counter_array);
6021       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6022         {
6023           counter = vat_json_array_add (counter_array);
6024           vat_json_init_object (counter);
6025           c4 = &vam->ip4_fib_counters[i][j];
6026           vat_json_object_add_ip4 (counter, "address", c4->address);
6027           vat_json_object_add_uint (counter, "address_length",
6028                                     c4->address_length);
6029           vat_json_object_add_uint (counter, "packets", c4->packets);
6030           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6031         }
6032     }
6033
6034   /* ip6 fib counters */
6035   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6036   vat_json_init_array (msg_array);
6037   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6038     {
6039       msg = vat_json_array_add (msg_array);
6040       vat_json_init_object (msg);
6041       vat_json_object_add_uint (msg, "vrf_id",
6042                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6043       counter_array = vat_json_object_add (msg, "c");
6044       vat_json_init_array (counter_array);
6045       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6046         {
6047           counter = vat_json_array_add (counter_array);
6048           vat_json_init_object (counter);
6049           c6 = &vam->ip6_fib_counters[i][j];
6050           vat_json_object_add_ip6 (counter, "address", c6->address);
6051           vat_json_object_add_uint (counter, "address_length",
6052                                     c6->address_length);
6053           vat_json_object_add_uint (counter, "packets", c6->packets);
6054           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6055         }
6056     }
6057
6058   /* ip4 nbr counters */
6059   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6060   vat_json_init_array (msg_array);
6061   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6062     {
6063       msg = vat_json_array_add (msg_array);
6064       vat_json_init_object (msg);
6065       vat_json_object_add_uint (msg, "sw_if_index", i);
6066       counter_array = vat_json_object_add (msg, "c");
6067       vat_json_init_array (counter_array);
6068       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6069         {
6070           counter = vat_json_array_add (counter_array);
6071           vat_json_init_object (counter);
6072           n4 = &vam->ip4_nbr_counters[i][j];
6073           vat_json_object_add_ip4 (counter, "address", n4->address);
6074           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6075           vat_json_object_add_uint (counter, "packets", n4->packets);
6076           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6077         }
6078     }
6079
6080   /* ip6 nbr counters */
6081   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6082   vat_json_init_array (msg_array);
6083   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6084     {
6085       msg = vat_json_array_add (msg_array);
6086       vat_json_init_object (msg);
6087       vat_json_object_add_uint (msg, "sw_if_index", i);
6088       counter_array = vat_json_object_add (msg, "c");
6089       vat_json_init_array (counter_array);
6090       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6091         {
6092           counter = vat_json_array_add (counter_array);
6093           vat_json_init_object (counter);
6094           n6 = &vam->ip6_nbr_counters[i][j];
6095           vat_json_object_add_ip6 (counter, "address", n6->address);
6096           vat_json_object_add_uint (counter, "packets", n6->packets);
6097           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6098         }
6099     }
6100
6101   vat_json_print (vam->ofp, &node);
6102   vat_json_free (&node);
6103
6104   return 0;
6105 }
6106
6107 /*
6108  * Pass CLI buffers directly in the CLI_INBAND API message,
6109  * instead of an additional shared memory area.
6110  */
6111 static int
6112 exec_inband (vat_main_t * vam)
6113 {
6114   vl_api_cli_inband_t *mp;
6115   unformat_input_t *i = vam->input;
6116   int ret;
6117
6118   if (vec_len (i->buffer) == 0)
6119     return -1;
6120
6121   if (vam->exec_mode == 0 && unformat (i, "mode"))
6122     {
6123       vam->exec_mode = 1;
6124       return 0;
6125     }
6126   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6127     {
6128       vam->exec_mode = 0;
6129       return 0;
6130     }
6131
6132   /*
6133    * In order for the CLI command to work, it
6134    * must be a vector ending in \n, not a C-string ending
6135    * in \n\0.
6136    */
6137   u32 len = vec_len (vam->input->buffer);
6138   M2 (CLI_INBAND, mp, len);
6139   clib_memcpy (mp->cmd, vam->input->buffer, len);
6140   mp->length = htonl (len);
6141
6142   S (mp);
6143   W (ret);
6144   /* json responses may or may not include a useful reply... */
6145   if (vec_len (vam->cmd_reply))
6146     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6147   return ret;
6148 }
6149
6150 int
6151 exec (vat_main_t * vam)
6152 {
6153   return exec_inband (vam);
6154 }
6155
6156 static int
6157 api_create_loopback (vat_main_t * vam)
6158 {
6159   unformat_input_t *i = vam->input;
6160   vl_api_create_loopback_t *mp;
6161   vl_api_create_loopback_instance_t *mp_lbi;
6162   u8 mac_address[6];
6163   u8 mac_set = 0;
6164   u8 is_specified = 0;
6165   u32 user_instance = 0;
6166   int ret;
6167
6168   memset (mac_address, 0, sizeof (mac_address));
6169
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6173         mac_set = 1;
6174       if (unformat (i, "instance %d", &user_instance))
6175         is_specified = 1;
6176       else
6177         break;
6178     }
6179
6180   if (is_specified)
6181     {
6182       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6183       mp_lbi->is_specified = is_specified;
6184       if (is_specified)
6185         mp_lbi->user_instance = htonl (user_instance);
6186       if (mac_set)
6187         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6188       S (mp_lbi);
6189     }
6190   else
6191     {
6192       /* Construct the API message */
6193       M (CREATE_LOOPBACK, mp);
6194       if (mac_set)
6195         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6196       S (mp);
6197     }
6198
6199   W (ret);
6200   return ret;
6201 }
6202
6203 static int
6204 api_delete_loopback (vat_main_t * vam)
6205 {
6206   unformat_input_t *i = vam->input;
6207   vl_api_delete_loopback_t *mp;
6208   u32 sw_if_index = ~0;
6209   int ret;
6210
6211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6212     {
6213       if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         ;
6215       else
6216         break;
6217     }
6218
6219   if (sw_if_index == ~0)
6220     {
6221       errmsg ("missing sw_if_index");
6222       return -99;
6223     }
6224
6225   /* Construct the API message */
6226   M (DELETE_LOOPBACK, mp);
6227   mp->sw_if_index = ntohl (sw_if_index);
6228
6229   S (mp);
6230   W (ret);
6231   return ret;
6232 }
6233
6234 static int
6235 api_want_stats (vat_main_t * vam)
6236 {
6237   unformat_input_t *i = vam->input;
6238   vl_api_want_stats_t *mp;
6239   int enable = -1;
6240   int ret;
6241
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "enable"))
6245         enable = 1;
6246       else if (unformat (i, "disable"))
6247         enable = 0;
6248       else
6249         break;
6250     }
6251
6252   if (enable == -1)
6253     {
6254       errmsg ("missing enable|disable");
6255       return -99;
6256     }
6257
6258   M (WANT_STATS, mp);
6259   mp->enable_disable = enable;
6260
6261   S (mp);
6262   W (ret);
6263   return ret;
6264 }
6265
6266 static int
6267 api_want_interface_events (vat_main_t * vam)
6268 {
6269   unformat_input_t *i = vam->input;
6270   vl_api_want_interface_events_t *mp;
6271   int enable = -1;
6272   int ret;
6273
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "enable"))
6277         enable = 1;
6278       else if (unformat (i, "disable"))
6279         enable = 0;
6280       else
6281         break;
6282     }
6283
6284   if (enable == -1)
6285     {
6286       errmsg ("missing enable|disable");
6287       return -99;
6288     }
6289
6290   M (WANT_INTERFACE_EVENTS, mp);
6291   mp->enable_disable = enable;
6292
6293   vam->interface_event_display = enable;
6294
6295   S (mp);
6296   W (ret);
6297   return ret;
6298 }
6299
6300
6301 /* Note: non-static, called once to set up the initial intfc table */
6302 int
6303 api_sw_interface_dump (vat_main_t * vam)
6304 {
6305   vl_api_sw_interface_dump_t *mp;
6306   vl_api_control_ping_t *mp_ping;
6307   hash_pair_t *p;
6308   name_sort_t *nses = 0, *ns;
6309   sw_interface_subif_t *sub = NULL;
6310   int ret;
6311
6312   /* Toss the old name table */
6313   /* *INDENT-OFF* */
6314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6315   ({
6316     vec_add2 (nses, ns, 1);
6317     ns->name = (u8 *)(p->key);
6318     ns->value = (u32) p->value[0];
6319   }));
6320   /* *INDENT-ON* */
6321
6322   hash_free (vam->sw_if_index_by_interface_name);
6323
6324   vec_foreach (ns, nses) vec_free (ns->name);
6325
6326   vec_free (nses);
6327
6328   vec_foreach (sub, vam->sw_if_subif_table)
6329   {
6330     vec_free (sub->interface_name);
6331   }
6332   vec_free (vam->sw_if_subif_table);
6333
6334   /* recreate the interface name hash table */
6335   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6336
6337   /*
6338    * Ask for all interface names. Otherwise, the epic catalog of
6339    * name filters becomes ridiculously long, and vat ends up needing
6340    * to be taught about new interface types.
6341    */
6342   M (SW_INTERFACE_DUMP, mp);
6343   S (mp);
6344
6345   /* Use a control ping for synchronization */
6346   MPING (CONTROL_PING, mp_ping);
6347   S (mp_ping);
6348
6349   W (ret);
6350   return ret;
6351 }
6352
6353 static int
6354 api_sw_interface_set_flags (vat_main_t * vam)
6355 {
6356   unformat_input_t *i = vam->input;
6357   vl_api_sw_interface_set_flags_t *mp;
6358   u32 sw_if_index;
6359   u8 sw_if_index_set = 0;
6360   u8 admin_up = 0;
6361   int ret;
6362
6363   /* Parse args required to build the message */
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "admin-up"))
6367         admin_up = 1;
6368       else if (unformat (i, "admin-down"))
6369         admin_up = 0;
6370       else
6371         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   /* Construct the API message */
6386   M (SW_INTERFACE_SET_FLAGS, mp);
6387   mp->sw_if_index = ntohl (sw_if_index);
6388   mp->admin_up_down = admin_up;
6389
6390   /* send it... */
6391   S (mp);
6392
6393   /* Wait for a reply, return the good/bad news... */
6394   W (ret);
6395   return ret;
6396 }
6397
6398 static int
6399 api_sw_interface_set_rx_mode (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_sw_interface_set_rx_mode_t *mp;
6403   u32 sw_if_index;
6404   u8 sw_if_index_set = 0;
6405   int ret;
6406   u8 queue_id_valid = 0;
6407   u32 queue_id;
6408   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6409
6410   /* Parse args required to build the message */
6411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6412     {
6413       if (unformat (i, "queue %d", &queue_id))
6414         queue_id_valid = 1;
6415       else if (unformat (i, "polling"))
6416         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6417       else if (unformat (i, "interrupt"))
6418         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6419       else if (unformat (i, "adaptive"))
6420         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6421       else
6422         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6423         sw_if_index_set = 1;
6424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6425         sw_if_index_set = 1;
6426       else
6427         break;
6428     }
6429
6430   if (sw_if_index_set == 0)
6431     {
6432       errmsg ("missing interface name or sw_if_index");
6433       return -99;
6434     }
6435   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6436     {
6437       errmsg ("missing rx-mode");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (SW_INTERFACE_SET_RX_MODE, mp);
6443   mp->sw_if_index = ntohl (sw_if_index);
6444   mp->mode = mode;
6445   mp->queue_id_valid = queue_id_valid;
6446   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6447
6448   /* send it... */
6449   S (mp);
6450
6451   /* Wait for a reply, return the good/bad news... */
6452   W (ret);
6453   return ret;
6454 }
6455
6456 static int
6457 api_sw_interface_clear_stats (vat_main_t * vam)
6458 {
6459   unformat_input_t *i = vam->input;
6460   vl_api_sw_interface_clear_stats_t *mp;
6461   u32 sw_if_index;
6462   u8 sw_if_index_set = 0;
6463   int ret;
6464
6465   /* Parse args required to build the message */
6466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6467     {
6468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6471         sw_if_index_set = 1;
6472       else
6473         break;
6474     }
6475
6476   /* Construct the API message */
6477   M (SW_INTERFACE_CLEAR_STATS, mp);
6478
6479   if (sw_if_index_set == 1)
6480     mp->sw_if_index = ntohl (sw_if_index);
6481   else
6482     mp->sw_if_index = ~0;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply, return the good/bad news... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_add_del_address (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_add_del_address_t *mp;
6497   u32 sw_if_index;
6498   u8 sw_if_index_set = 0;
6499   u8 is_add = 1, del_all = 0;
6500   u32 address_length = 0;
6501   u8 v4_address_set = 0;
6502   u8 v6_address_set = 0;
6503   ip4_address_t v4address;
6504   ip6_address_t v6address;
6505   int ret;
6506
6507   /* Parse args required to build the message */
6508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6509     {
6510       if (unformat (i, "del-all"))
6511         del_all = 1;
6512       else if (unformat (i, "del"))
6513         is_add = 0;
6514       else
6515         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "%U/%d",
6520                          unformat_ip4_address, &v4address, &address_length))
6521         v4_address_set = 1;
6522       else if (unformat (i, "%U/%d",
6523                          unformat_ip6_address, &v6address, &address_length))
6524         v6_address_set = 1;
6525       else
6526         break;
6527     }
6528
6529   if (sw_if_index_set == 0)
6530     {
6531       errmsg ("missing interface name or sw_if_index");
6532       return -99;
6533     }
6534   if (v4_address_set && v6_address_set)
6535     {
6536       errmsg ("both v4 and v6 addresses set");
6537       return -99;
6538     }
6539   if (!v4_address_set && !v6_address_set && !del_all)
6540     {
6541       errmsg ("no addresses set");
6542       return -99;
6543     }
6544
6545   /* Construct the API message */
6546   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6547
6548   mp->sw_if_index = ntohl (sw_if_index);
6549   mp->is_add = is_add;
6550   mp->del_all = del_all;
6551   if (v6_address_set)
6552     {
6553       mp->is_ipv6 = 1;
6554       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6555     }
6556   else
6557     {
6558       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6559     }
6560   mp->address_length = address_length;
6561
6562   /* send it... */
6563   S (mp);
6564
6565   /* Wait for a reply, return good/bad news  */
6566   W (ret);
6567   return ret;
6568 }
6569
6570 static int
6571 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_mpls_enable_t *mp;
6575   u32 sw_if_index;
6576   u8 sw_if_index_set = 0;
6577   u8 enable = 1;
6578   int ret;
6579
6580   /* Parse args required to build the message */
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586         sw_if_index_set = 1;
6587       else if (unformat (i, "disable"))
6588         enable = 0;
6589       else if (unformat (i, "dis"))
6590         enable = 0;
6591       else
6592         break;
6593     }
6594
6595   if (sw_if_index_set == 0)
6596     {
6597       errmsg ("missing interface name or sw_if_index");
6598       return -99;
6599     }
6600
6601   /* Construct the API message */
6602   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6603
6604   mp->sw_if_index = ntohl (sw_if_index);
6605   mp->enable = enable;
6606
6607   /* send it... */
6608   S (mp);
6609
6610   /* Wait for a reply... */
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_sw_interface_set_table (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_sw_interface_set_table_t *mp;
6620   u32 sw_if_index, vrf_id = 0;
6621   u8 sw_if_index_set = 0;
6622   u8 is_ipv6 = 0;
6623   int ret;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6631         sw_if_index_set = 1;
6632       else if (unformat (i, "vrf %d", &vrf_id))
6633         ;
6634       else if (unformat (i, "ipv6"))
6635         is_ipv6 = 1;
6636       else
6637         break;
6638     }
6639
6640   if (sw_if_index_set == 0)
6641     {
6642       errmsg ("missing interface name or sw_if_index");
6643       return -99;
6644     }
6645
6646   /* Construct the API message */
6647   M (SW_INTERFACE_SET_TABLE, mp);
6648
6649   mp->sw_if_index = ntohl (sw_if_index);
6650   mp->is_ipv6 = is_ipv6;
6651   mp->vrf_id = ntohl (vrf_id);
6652
6653   /* send it... */
6654   S (mp);
6655
6656   /* Wait for a reply... */
6657   W (ret);
6658   return ret;
6659 }
6660
6661 static void vl_api_sw_interface_get_table_reply_t_handler
6662   (vl_api_sw_interface_get_table_reply_t * mp)
6663 {
6664   vat_main_t *vam = &vat_main;
6665
6666   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6667
6668   vam->retval = ntohl (mp->retval);
6669   vam->result_ready = 1;
6670
6671 }
6672
6673 static void vl_api_sw_interface_get_table_reply_t_handler_json
6674   (vl_api_sw_interface_get_table_reply_t * mp)
6675 {
6676   vat_main_t *vam = &vat_main;
6677   vat_json_node_t node;
6678
6679   vat_json_init_object (&node);
6680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6681   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6682
6683   vat_json_print (vam->ofp, &node);
6684   vat_json_free (&node);
6685
6686   vam->retval = ntohl (mp->retval);
6687   vam->result_ready = 1;
6688 }
6689
6690 static int
6691 api_sw_interface_get_table (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_sw_interface_get_table_t *mp;
6695   u32 sw_if_index;
6696   u8 sw_if_index_set = 0;
6697   u8 is_ipv6 = 0;
6698   int ret;
6699
6700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6701     {
6702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6705         sw_if_index_set = 1;
6706       else if (unformat (i, "ipv6"))
6707         is_ipv6 = 1;
6708       else
6709         break;
6710     }
6711
6712   if (sw_if_index_set == 0)
6713     {
6714       errmsg ("missing interface name or sw_if_index");
6715       return -99;
6716     }
6717
6718   M (SW_INTERFACE_GET_TABLE, mp);
6719   mp->sw_if_index = htonl (sw_if_index);
6720   mp->is_ipv6 = is_ipv6;
6721
6722   S (mp);
6723   W (ret);
6724   return ret;
6725 }
6726
6727 static int
6728 api_sw_interface_set_vpath (vat_main_t * vam)
6729 {
6730   unformat_input_t *i = vam->input;
6731   vl_api_sw_interface_set_vpath_t *mp;
6732   u32 sw_if_index = 0;
6733   u8 sw_if_index_set = 0;
6734   u8 is_enable = 0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6743         sw_if_index_set = 1;
6744       else if (unformat (i, "enable"))
6745         is_enable = 1;
6746       else if (unformat (i, "disable"))
6747         is_enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (sw_if_index_set == 0)
6753     {
6754       errmsg ("missing interface name or sw_if_index");
6755       return -99;
6756     }
6757
6758   /* Construct the API message */
6759   M (SW_INTERFACE_SET_VPATH, mp);
6760
6761   mp->sw_if_index = ntohl (sw_if_index);
6762   mp->enable = is_enable;
6763
6764   /* send it... */
6765   S (mp);
6766
6767   /* Wait for a reply... */
6768   W (ret);
6769   return ret;
6770 }
6771
6772 static int
6773 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6777   u32 sw_if_index = 0;
6778   u8 sw_if_index_set = 0;
6779   u8 is_enable = 1;
6780   u8 is_ipv6 = 0;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6787         sw_if_index_set = 1;
6788       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6789         sw_if_index_set = 1;
6790       else if (unformat (i, "enable"))
6791         is_enable = 1;
6792       else if (unformat (i, "disable"))
6793         is_enable = 0;
6794       else if (unformat (i, "ip4"))
6795         is_ipv6 = 0;
6796       else if (unformat (i, "ip6"))
6797         is_ipv6 = 1;
6798       else
6799         break;
6800     }
6801
6802   if (sw_if_index_set == 0)
6803     {
6804       errmsg ("missing interface name or sw_if_index");
6805       return -99;
6806     }
6807
6808   /* Construct the API message */
6809   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6810
6811   mp->sw_if_index = ntohl (sw_if_index);
6812   mp->enable = is_enable;
6813   mp->is_ipv6 = is_ipv6;
6814
6815   /* send it... */
6816   S (mp);
6817
6818   /* Wait for a reply... */
6819   W (ret);
6820   return ret;
6821 }
6822
6823 static int
6824 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_sw_interface_set_geneve_bypass_t *mp;
6828   u32 sw_if_index = 0;
6829   u8 sw_if_index_set = 0;
6830   u8 is_enable = 1;
6831   u8 is_ipv6 = 0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "enable"))
6842         is_enable = 1;
6843       else if (unformat (i, "disable"))
6844         is_enable = 0;
6845       else if (unformat (i, "ip4"))
6846         is_ipv6 = 0;
6847       else if (unformat (i, "ip6"))
6848         is_ipv6 = 1;
6849       else
6850         break;
6851     }
6852
6853   if (sw_if_index_set == 0)
6854     {
6855       errmsg ("missing interface name or sw_if_index");
6856       return -99;
6857     }
6858
6859   /* Construct the API message */
6860   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6861
6862   mp->sw_if_index = ntohl (sw_if_index);
6863   mp->enable = is_enable;
6864   mp->is_ipv6 = is_ipv6;
6865
6866   /* send it... */
6867   S (mp);
6868
6869   /* Wait for a reply... */
6870   W (ret);
6871   return ret;
6872 }
6873
6874 static int
6875 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6876 {
6877   unformat_input_t *i = vam->input;
6878   vl_api_sw_interface_set_l2_xconnect_t *mp;
6879   u32 rx_sw_if_index;
6880   u8 rx_sw_if_index_set = 0;
6881   u32 tx_sw_if_index;
6882   u8 tx_sw_if_index_set = 0;
6883   u8 enable = 1;
6884   int ret;
6885
6886   /* Parse args required to build the message */
6887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6888     {
6889       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6890         rx_sw_if_index_set = 1;
6891       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6892         tx_sw_if_index_set = 1;
6893       else if (unformat (i, "rx"))
6894         {
6895           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896             {
6897               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6898                             &rx_sw_if_index))
6899                 rx_sw_if_index_set = 1;
6900             }
6901           else
6902             break;
6903         }
6904       else if (unformat (i, "tx"))
6905         {
6906           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907             {
6908               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6909                             &tx_sw_if_index))
6910                 tx_sw_if_index_set = 1;
6911             }
6912           else
6913             break;
6914         }
6915       else if (unformat (i, "enable"))
6916         enable = 1;
6917       else if (unformat (i, "disable"))
6918         enable = 0;
6919       else
6920         break;
6921     }
6922
6923   if (rx_sw_if_index_set == 0)
6924     {
6925       errmsg ("missing rx interface name or rx_sw_if_index");
6926       return -99;
6927     }
6928
6929   if (enable && (tx_sw_if_index_set == 0))
6930     {
6931       errmsg ("missing tx interface name or tx_sw_if_index");
6932       return -99;
6933     }
6934
6935   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6936
6937   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6938   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6939   mp->enable = enable;
6940
6941   S (mp);
6942   W (ret);
6943   return ret;
6944 }
6945
6946 static int
6947 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6948 {
6949   unformat_input_t *i = vam->input;
6950   vl_api_sw_interface_set_l2_bridge_t *mp;
6951   u32 rx_sw_if_index;
6952   u8 rx_sw_if_index_set = 0;
6953   u32 bd_id;
6954   u8 bd_id_set = 0;
6955   u8 bvi = 0;
6956   u32 shg = 0;
6957   u8 enable = 1;
6958   int ret;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6964         rx_sw_if_index_set = 1;
6965       else if (unformat (i, "bd_id %d", &bd_id))
6966         bd_id_set = 1;
6967       else
6968         if (unformat
6969             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6970         rx_sw_if_index_set = 1;
6971       else if (unformat (i, "shg %d", &shg))
6972         ;
6973       else if (unformat (i, "bvi"))
6974         bvi = 1;
6975       else if (unformat (i, "enable"))
6976         enable = 1;
6977       else if (unformat (i, "disable"))
6978         enable = 0;
6979       else
6980         break;
6981     }
6982
6983   if (rx_sw_if_index_set == 0)
6984     {
6985       errmsg ("missing rx interface name or sw_if_index");
6986       return -99;
6987     }
6988
6989   if (enable && (bd_id_set == 0))
6990     {
6991       errmsg ("missing bridge domain");
6992       return -99;
6993     }
6994
6995   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6996
6997   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6998   mp->bd_id = ntohl (bd_id);
6999   mp->shg = (u8) shg;
7000   mp->bvi = bvi;
7001   mp->enable = enable;
7002
7003   S (mp);
7004   W (ret);
7005   return ret;
7006 }
7007
7008 static int
7009 api_bridge_domain_dump (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_bridge_domain_dump_t *mp;
7013   vl_api_control_ping_t *mp_ping;
7014   u32 bd_id = ~0;
7015   int ret;
7016
7017   /* Parse args required to build the message */
7018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7019     {
7020       if (unformat (i, "bd_id %d", &bd_id))
7021         ;
7022       else
7023         break;
7024     }
7025
7026   M (BRIDGE_DOMAIN_DUMP, mp);
7027   mp->bd_id = ntohl (bd_id);
7028   S (mp);
7029
7030   /* Use a control ping for synchronization */
7031   MPING (CONTROL_PING, mp_ping);
7032   S (mp_ping);
7033
7034   W (ret);
7035   return ret;
7036 }
7037
7038 static int
7039 api_bridge_domain_add_del (vat_main_t * vam)
7040 {
7041   unformat_input_t *i = vam->input;
7042   vl_api_bridge_domain_add_del_t *mp;
7043   u32 bd_id = ~0;
7044   u8 is_add = 1;
7045   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7046   u8 *bd_tag = NULL;
7047   u32 mac_age = 0;
7048   int ret;
7049
7050   /* Parse args required to build the message */
7051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7052     {
7053       if (unformat (i, "bd_id %d", &bd_id))
7054         ;
7055       else if (unformat (i, "flood %d", &flood))
7056         ;
7057       else if (unformat (i, "uu-flood %d", &uu_flood))
7058         ;
7059       else if (unformat (i, "forward %d", &forward))
7060         ;
7061       else if (unformat (i, "learn %d", &learn))
7062         ;
7063       else if (unformat (i, "arp-term %d", &arp_term))
7064         ;
7065       else if (unformat (i, "mac-age %d", &mac_age))
7066         ;
7067       else if (unformat (i, "bd-tag %s", &bd_tag))
7068         ;
7069       else if (unformat (i, "del"))
7070         {
7071           is_add = 0;
7072           flood = uu_flood = forward = learn = 0;
7073         }
7074       else
7075         break;
7076     }
7077
7078   if (bd_id == ~0)
7079     {
7080       errmsg ("missing bridge domain");
7081       ret = -99;
7082       goto done;
7083     }
7084
7085   if (mac_age > 255)
7086     {
7087       errmsg ("mac age must be less than 256 ");
7088       ret = -99;
7089       goto done;
7090     }
7091
7092   if ((bd_tag) && (vec_len (bd_tag) > 63))
7093     {
7094       errmsg ("bd-tag cannot be longer than 63");
7095       ret = -99;
7096       goto done;
7097     }
7098
7099   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7100
7101   mp->bd_id = ntohl (bd_id);
7102   mp->flood = flood;
7103   mp->uu_flood = uu_flood;
7104   mp->forward = forward;
7105   mp->learn = learn;
7106   mp->arp_term = arp_term;
7107   mp->is_add = is_add;
7108   mp->mac_age = (u8) mac_age;
7109   if (bd_tag)
7110     {
7111       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7112       mp->bd_tag[vec_len (bd_tag)] = 0;
7113     }
7114   S (mp);
7115   W (ret);
7116
7117 done:
7118   vec_free (bd_tag);
7119   return ret;
7120 }
7121
7122 static int
7123 api_l2fib_flush_bd (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_l2fib_flush_bd_t *mp;
7127   u32 bd_id = ~0;
7128   int ret;
7129
7130   /* Parse args required to build the message */
7131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7132     {
7133       if (unformat (i, "bd_id %d", &bd_id));
7134       else
7135         break;
7136     }
7137
7138   if (bd_id == ~0)
7139     {
7140       errmsg ("missing bridge domain");
7141       return -99;
7142     }
7143
7144   M (L2FIB_FLUSH_BD, mp);
7145
7146   mp->bd_id = htonl (bd_id);
7147
7148   S (mp);
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_l2fib_flush_int (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_l2fib_flush_int_t *mp;
7158   u32 sw_if_index = ~0;
7159   int ret;
7160
7161   /* Parse args required to build the message */
7162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7163     {
7164       if (unformat (i, "sw_if_index %d", &sw_if_index));
7165       else
7166         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7167       else
7168         break;
7169     }
7170
7171   if (sw_if_index == ~0)
7172     {
7173       errmsg ("missing interface name or sw_if_index");
7174       return -99;
7175     }
7176
7177   M (L2FIB_FLUSH_INT, mp);
7178
7179   mp->sw_if_index = ntohl (sw_if_index);
7180
7181   S (mp);
7182   W (ret);
7183   return ret;
7184 }
7185
7186 static int
7187 api_l2fib_add_del (vat_main_t * vam)
7188 {
7189   unformat_input_t *i = vam->input;
7190   vl_api_l2fib_add_del_t *mp;
7191   f64 timeout;
7192   u8 mac[6] = { 0 };
7193   u8 mac_set = 0;
7194   u32 bd_id;
7195   u8 bd_id_set = 0;
7196   u32 sw_if_index = ~0;
7197   u8 sw_if_index_set = 0;
7198   u8 is_add = 1;
7199   u8 static_mac = 0;
7200   u8 filter_mac = 0;
7201   u8 bvi_mac = 0;
7202   int count = 1;
7203   f64 before = 0;
7204   int j;
7205
7206   /* Parse args required to build the message */
7207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7208     {
7209       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7210         mac_set = 1;
7211       else if (unformat (i, "bd_id %d", &bd_id))
7212         bd_id_set = 1;
7213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7214         sw_if_index_set = 1;
7215       else if (unformat (i, "sw_if"))
7216         {
7217           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218             {
7219               if (unformat
7220                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7221                 sw_if_index_set = 1;
7222             }
7223           else
7224             break;
7225         }
7226       else if (unformat (i, "static"))
7227         static_mac = 1;
7228       else if (unformat (i, "filter"))
7229         {
7230           filter_mac = 1;
7231           static_mac = 1;
7232         }
7233       else if (unformat (i, "bvi"))
7234         {
7235           bvi_mac = 1;
7236           static_mac = 1;
7237         }
7238       else if (unformat (i, "del"))
7239         is_add = 0;
7240       else if (unformat (i, "count %d", &count))
7241         ;
7242       else
7243         break;
7244     }
7245
7246   if (mac_set == 0)
7247     {
7248       errmsg ("missing mac address");
7249       return -99;
7250     }
7251
7252   if (bd_id_set == 0)
7253     {
7254       errmsg ("missing bridge domain");
7255       return -99;
7256     }
7257
7258   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7259     {
7260       errmsg ("missing interface name or sw_if_index");
7261       return -99;
7262     }
7263
7264   if (count > 1)
7265     {
7266       /* Turn on async mode */
7267       vam->async_mode = 1;
7268       vam->async_errors = 0;
7269       before = vat_time_now (vam);
7270     }
7271
7272   for (j = 0; j < count; j++)
7273     {
7274       M (L2FIB_ADD_DEL, mp);
7275
7276       clib_memcpy (mp->mac, mac, 6);
7277       mp->bd_id = ntohl (bd_id);
7278       mp->is_add = is_add;
7279
7280       if (is_add)
7281         {
7282           mp->sw_if_index = ntohl (sw_if_index);
7283           mp->static_mac = static_mac;
7284           mp->filter_mac = filter_mac;
7285           mp->bvi_mac = bvi_mac;
7286         }
7287       increment_mac_address (mac);
7288       /* send it... */
7289       S (mp);
7290     }
7291
7292   if (count > 1)
7293     {
7294       vl_api_control_ping_t *mp_ping;
7295       f64 after;
7296
7297       /* Shut off async mode */
7298       vam->async_mode = 0;
7299
7300       MPING (CONTROL_PING, mp_ping);
7301       S (mp_ping);
7302
7303       timeout = vat_time_now (vam) + 1.0;
7304       while (vat_time_now (vam) < timeout)
7305         if (vam->result_ready == 1)
7306           goto out;
7307       vam->retval = -99;
7308
7309     out:
7310       if (vam->retval == -99)
7311         errmsg ("timeout");
7312
7313       if (vam->async_errors > 0)
7314         {
7315           errmsg ("%d asynchronous errors", vam->async_errors);
7316           vam->retval = -98;
7317         }
7318       vam->async_errors = 0;
7319       after = vat_time_now (vam);
7320
7321       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7322              count, after - before, count / (after - before));
7323     }
7324   else
7325     {
7326       int ret;
7327
7328       /* Wait for a reply... */
7329       W (ret);
7330       return ret;
7331     }
7332   /* Return the good/bad news */
7333   return (vam->retval);
7334 }
7335
7336 static int
7337 api_bridge_domain_set_mac_age (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_bridge_domain_set_mac_age_t *mp;
7341   u32 bd_id = ~0;
7342   u32 mac_age = 0;
7343   int ret;
7344
7345   /* Parse args required to build the message */
7346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7347     {
7348       if (unformat (i, "bd_id %d", &bd_id));
7349       else if (unformat (i, "mac-age %d", &mac_age));
7350       else
7351         break;
7352     }
7353
7354   if (bd_id == ~0)
7355     {
7356       errmsg ("missing bridge domain");
7357       return -99;
7358     }
7359
7360   if (mac_age > 255)
7361     {
7362       errmsg ("mac age must be less than 256 ");
7363       return -99;
7364     }
7365
7366   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7367
7368   mp->bd_id = htonl (bd_id);
7369   mp->mac_age = (u8) mac_age;
7370
7371   S (mp);
7372   W (ret);
7373   return ret;
7374 }
7375
7376 static int
7377 api_l2_flags (vat_main_t * vam)
7378 {
7379   unformat_input_t *i = vam->input;
7380   vl_api_l2_flags_t *mp;
7381   u32 sw_if_index;
7382   u32 flags = 0;
7383   u8 sw_if_index_set = 0;
7384   u8 is_set = 0;
7385   int ret;
7386
7387   /* Parse args required to build the message */
7388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389     {
7390       if (unformat (i, "sw_if_index %d", &sw_if_index))
7391         sw_if_index_set = 1;
7392       else if (unformat (i, "sw_if"))
7393         {
7394           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395             {
7396               if (unformat
7397                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7398                 sw_if_index_set = 1;
7399             }
7400           else
7401             break;
7402         }
7403       else if (unformat (i, "learn"))
7404         flags |= L2_LEARN;
7405       else if (unformat (i, "forward"))
7406         flags |= L2_FWD;
7407       else if (unformat (i, "flood"))
7408         flags |= L2_FLOOD;
7409       else if (unformat (i, "uu-flood"))
7410         flags |= L2_UU_FLOOD;
7411       else if (unformat (i, "arp-term"))
7412         flags |= L2_ARP_TERM;
7413       else if (unformat (i, "off"))
7414         is_set = 0;
7415       else if (unformat (i, "disable"))
7416         is_set = 0;
7417       else
7418         break;
7419     }
7420
7421   if (sw_if_index_set == 0)
7422     {
7423       errmsg ("missing interface name or sw_if_index");
7424       return -99;
7425     }
7426
7427   M (L2_FLAGS, mp);
7428
7429   mp->sw_if_index = ntohl (sw_if_index);
7430   mp->feature_bitmap = ntohl (flags);
7431   mp->is_set = is_set;
7432
7433   S (mp);
7434   W (ret);
7435   return ret;
7436 }
7437
7438 static int
7439 api_bridge_flags (vat_main_t * vam)
7440 {
7441   unformat_input_t *i = vam->input;
7442   vl_api_bridge_flags_t *mp;
7443   u32 bd_id;
7444   u8 bd_id_set = 0;
7445   u8 is_set = 1;
7446   u32 flags = 0;
7447   int ret;
7448
7449   /* Parse args required to build the message */
7450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7451     {
7452       if (unformat (i, "bd_id %d", &bd_id))
7453         bd_id_set = 1;
7454       else if (unformat (i, "learn"))
7455         flags |= L2_LEARN;
7456       else if (unformat (i, "forward"))
7457         flags |= L2_FWD;
7458       else if (unformat (i, "flood"))
7459         flags |= L2_FLOOD;
7460       else if (unformat (i, "uu-flood"))
7461         flags |= L2_UU_FLOOD;
7462       else if (unformat (i, "arp-term"))
7463         flags |= L2_ARP_TERM;
7464       else if (unformat (i, "off"))
7465         is_set = 0;
7466       else if (unformat (i, "disable"))
7467         is_set = 0;
7468       else
7469         break;
7470     }
7471
7472   if (bd_id_set == 0)
7473     {
7474       errmsg ("missing bridge domain");
7475       return -99;
7476     }
7477
7478   M (BRIDGE_FLAGS, mp);
7479
7480   mp->bd_id = ntohl (bd_id);
7481   mp->feature_bitmap = ntohl (flags);
7482   mp->is_set = is_set;
7483
7484   S (mp);
7485   W (ret);
7486   return ret;
7487 }
7488
7489 static int
7490 api_bd_ip_mac_add_del (vat_main_t * vam)
7491 {
7492   unformat_input_t *i = vam->input;
7493   vl_api_bd_ip_mac_add_del_t *mp;
7494   u32 bd_id;
7495   u8 is_ipv6 = 0;
7496   u8 is_add = 1;
7497   u8 bd_id_set = 0;
7498   u8 ip_set = 0;
7499   u8 mac_set = 0;
7500   ip4_address_t v4addr;
7501   ip6_address_t v6addr;
7502   u8 macaddr[6];
7503   int ret;
7504
7505
7506   /* Parse args required to build the message */
7507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7508     {
7509       if (unformat (i, "bd_id %d", &bd_id))
7510         {
7511           bd_id_set++;
7512         }
7513       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7514         {
7515           ip_set++;
7516         }
7517       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7518         {
7519           ip_set++;
7520           is_ipv6++;
7521         }
7522       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7523         {
7524           mac_set++;
7525         }
7526       else if (unformat (i, "del"))
7527         is_add = 0;
7528       else
7529         break;
7530     }
7531
7532   if (bd_id_set == 0)
7533     {
7534       errmsg ("missing bridge domain");
7535       return -99;
7536     }
7537   else if (ip_set == 0)
7538     {
7539       errmsg ("missing IP address");
7540       return -99;
7541     }
7542   else if (mac_set == 0)
7543     {
7544       errmsg ("missing MAC address");
7545       return -99;
7546     }
7547
7548   M (BD_IP_MAC_ADD_DEL, mp);
7549
7550   mp->bd_id = ntohl (bd_id);
7551   mp->is_ipv6 = is_ipv6;
7552   mp->is_add = is_add;
7553   if (is_ipv6)
7554     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7555   else
7556     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7557   clib_memcpy (mp->mac_address, macaddr, 6);
7558   S (mp);
7559   W (ret);
7560   return ret;
7561 }
7562
7563 static int
7564 api_tap_connect (vat_main_t * vam)
7565 {
7566   unformat_input_t *i = vam->input;
7567   vl_api_tap_connect_t *mp;
7568   u8 mac_address[6];
7569   u8 random_mac = 1;
7570   u8 name_set = 0;
7571   u8 *tap_name;
7572   u8 *tag = 0;
7573   ip4_address_t ip4_address;
7574   u32 ip4_mask_width;
7575   int ip4_address_set = 0;
7576   ip6_address_t ip6_address;
7577   u32 ip6_mask_width;
7578   int ip6_address_set = 0;
7579   int ret;
7580
7581   memset (mac_address, 0, sizeof (mac_address));
7582
7583   /* Parse args required to build the message */
7584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7585     {
7586       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7587         {
7588           random_mac = 0;
7589         }
7590       else if (unformat (i, "random-mac"))
7591         random_mac = 1;
7592       else if (unformat (i, "tapname %s", &tap_name))
7593         name_set = 1;
7594       else if (unformat (i, "tag %s", &tag))
7595         ;
7596       else if (unformat (i, "address %U/%d",
7597                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7598         ip4_address_set = 1;
7599       else if (unformat (i, "address %U/%d",
7600                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7601         ip6_address_set = 1;
7602       else
7603         break;
7604     }
7605
7606   if (name_set == 0)
7607     {
7608       errmsg ("missing tap name");
7609       return -99;
7610     }
7611   if (vec_len (tap_name) > 63)
7612     {
7613       errmsg ("tap name too long");
7614       return -99;
7615     }
7616   vec_add1 (tap_name, 0);
7617
7618   if (vec_len (tag) > 63)
7619     {
7620       errmsg ("tag too long");
7621       return -99;
7622     }
7623
7624   /* Construct the API message */
7625   M (TAP_CONNECT, mp);
7626
7627   mp->use_random_mac = random_mac;
7628   clib_memcpy (mp->mac_address, mac_address, 6);
7629   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7630   if (tag)
7631     clib_memcpy (mp->tag, tag, vec_len (tag));
7632
7633   if (ip4_address_set)
7634     {
7635       mp->ip4_address_set = 1;
7636       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7637       mp->ip4_mask_width = ip4_mask_width;
7638     }
7639   if (ip6_address_set)
7640     {
7641       mp->ip6_address_set = 1;
7642       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7643       mp->ip6_mask_width = ip6_mask_width;
7644     }
7645
7646   vec_free (tap_name);
7647   vec_free (tag);
7648
7649   /* send it... */
7650   S (mp);
7651
7652   /* Wait for a reply... */
7653   W (ret);
7654   return ret;
7655 }
7656
7657 static int
7658 api_tap_modify (vat_main_t * vam)
7659 {
7660   unformat_input_t *i = vam->input;
7661   vl_api_tap_modify_t *mp;
7662   u8 mac_address[6];
7663   u8 random_mac = 1;
7664   u8 name_set = 0;
7665   u8 *tap_name;
7666   u32 sw_if_index = ~0;
7667   u8 sw_if_index_set = 0;
7668   int ret;
7669
7670   memset (mac_address, 0, sizeof (mac_address));
7671
7672   /* Parse args required to build the message */
7673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7674     {
7675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7676         sw_if_index_set = 1;
7677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7678         sw_if_index_set = 1;
7679       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7680         {
7681           random_mac = 0;
7682         }
7683       else if (unformat (i, "random-mac"))
7684         random_mac = 1;
7685       else if (unformat (i, "tapname %s", &tap_name))
7686         name_set = 1;
7687       else
7688         break;
7689     }
7690
7691   if (sw_if_index_set == 0)
7692     {
7693       errmsg ("missing vpp interface name");
7694       return -99;
7695     }
7696   if (name_set == 0)
7697     {
7698       errmsg ("missing tap name");
7699       return -99;
7700     }
7701   if (vec_len (tap_name) > 63)
7702     {
7703       errmsg ("tap name too long");
7704     }
7705   vec_add1 (tap_name, 0);
7706
7707   /* Construct the API message */
7708   M (TAP_MODIFY, mp);
7709
7710   mp->use_random_mac = random_mac;
7711   mp->sw_if_index = ntohl (sw_if_index);
7712   clib_memcpy (mp->mac_address, mac_address, 6);
7713   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7714   vec_free (tap_name);
7715
7716   /* send it... */
7717   S (mp);
7718
7719   /* Wait for a reply... */
7720   W (ret);
7721   return ret;
7722 }
7723
7724 static int
7725 api_tap_delete (vat_main_t * vam)
7726 {
7727   unformat_input_t *i = vam->input;
7728   vl_api_tap_delete_t *mp;
7729   u32 sw_if_index = ~0;
7730   u8 sw_if_index_set = 0;
7731   int ret;
7732
7733   /* Parse args required to build the message */
7734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7735     {
7736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7737         sw_if_index_set = 1;
7738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7739         sw_if_index_set = 1;
7740       else
7741         break;
7742     }
7743
7744   if (sw_if_index_set == 0)
7745     {
7746       errmsg ("missing vpp interface name");
7747       return -99;
7748     }
7749
7750   /* Construct the API message */
7751   M (TAP_DELETE, mp);
7752
7753   mp->sw_if_index = ntohl (sw_if_index);
7754
7755   /* send it... */
7756   S (mp);
7757
7758   /* Wait for a reply... */
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_tap_create_v2 (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_tap_create_v2_t *mp;
7768   u8 mac_address[6];
7769   u8 random_mac = 1;
7770   u32 id = ~0;
7771   u8 *host_if_name = 0;
7772   u8 *host_ns = 0;
7773   u8 host_mac_addr[6];
7774   u8 host_mac_addr_set = 0;
7775   u8 *host_bridge = 0;
7776   ip4_address_t host_ip4_addr;
7777   ip4_address_t host_ip4_gw;
7778   u8 host_ip4_gw_set = 0;
7779   u32 host_ip4_prefix_len = 0;
7780   ip6_address_t host_ip6_addr;
7781   ip6_address_t host_ip6_gw;
7782   u8 host_ip6_gw_set = 0;
7783   u32 host_ip6_prefix_len = 0;
7784   int ret;
7785   int rx_ring_sz = 0, tx_ring_sz = 0;
7786
7787   memset (mac_address, 0, sizeof (mac_address));
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7793         {
7794           random_mac = 0;
7795         }
7796       else if (unformat (i, "id %s", &id))
7797         ;
7798       else if (unformat (i, "host-if-name %s", &host_if_name))
7799         ;
7800       else if (unformat (i, "host-ns %s", &host_ns))
7801         ;
7802       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7803                          host_mac_addr))
7804         host_mac_addr_set = 1;
7805       else if (unformat (i, "host-bridge %s", &host_bridge))
7806         ;
7807       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7808                          &host_ip4_addr, &host_ip4_prefix_len))
7809         ;
7810       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7811                          &host_ip6_addr, &host_ip6_prefix_len))
7812         ;
7813       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7814                          &host_ip4_gw))
7815         host_ip4_gw_set = 1;
7816       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7817                          &host_ip6_gw))
7818         host_ip6_gw_set = 1;
7819       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7820         ;
7821       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7822         ;
7823       else
7824         break;
7825     }
7826
7827   if (vec_len (host_if_name) > 63)
7828     {
7829       errmsg ("tap name too long. ");
7830       return -99;
7831     }
7832   if (vec_len (host_ns) > 63)
7833     {
7834       errmsg ("host name space too long. ");
7835       return -99;
7836     }
7837   if (vec_len (host_bridge) > 63)
7838     {
7839       errmsg ("host bridge name too long. ");
7840       return -99;
7841     }
7842   if (host_ip4_prefix_len > 32)
7843     {
7844       errmsg ("host ip4 prefix length not valid. ");
7845       return -99;
7846     }
7847   if (host_ip6_prefix_len > 128)
7848     {
7849       errmsg ("host ip6 prefix length not valid. ");
7850       return -99;
7851     }
7852   if (!is_pow2 (rx_ring_sz))
7853     {
7854       errmsg ("rx ring size must be power of 2. ");
7855       return -99;
7856     }
7857   if (rx_ring_sz > 32768)
7858     {
7859       errmsg ("rx ring size must be 32768 or lower. ");
7860       return -99;
7861     }
7862   if (!is_pow2 (tx_ring_sz))
7863     {
7864       errmsg ("tx ring size must be power of 2. ");
7865       return -99;
7866     }
7867   if (tx_ring_sz > 32768)
7868     {
7869       errmsg ("tx ring size must be 32768 or lower. ");
7870       return -99;
7871     }
7872
7873   /* Construct the API message */
7874   M (TAP_CREATE_V2, mp);
7875
7876   mp->use_random_mac = random_mac;
7877
7878   mp->id = id;
7879   mp->host_namespace_set = host_ns != 0;
7880   mp->host_bridge_set = host_bridge != 0;
7881   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7882   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7883   mp->rx_ring_sz = rx_ring_sz;
7884   mp->tx_ring_sz = tx_ring_sz;
7885
7886   if (random_mac)
7887     clib_memcpy (mp->mac_address, mac_address, 6);
7888   if (host_mac_addr_set)
7889     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7890   if (host_if_name)
7891     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7892   if (host_ns)
7893     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7894   if (host_bridge)
7895     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7896   if (host_ip4_prefix_len)
7897     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7898   if (host_ip4_prefix_len)
7899     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7900   if (host_ip4_gw_set)
7901     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7902   if (host_ip6_gw_set)
7903     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7904
7905   vec_free (host_ns);
7906   vec_free (host_if_name);
7907   vec_free (host_bridge);
7908
7909   /* send it... */
7910   S (mp);
7911
7912   /* Wait for a reply... */
7913   W (ret);
7914   return ret;
7915 }
7916
7917 static int
7918 api_tap_delete_v2 (vat_main_t * vam)
7919 {
7920   unformat_input_t *i = vam->input;
7921   vl_api_tap_delete_v2_t *mp;
7922   u32 sw_if_index = ~0;
7923   u8 sw_if_index_set = 0;
7924   int ret;
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7930         sw_if_index_set = 1;
7931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7932         sw_if_index_set = 1;
7933       else
7934         break;
7935     }
7936
7937   if (sw_if_index_set == 0)
7938     {
7939       errmsg ("missing vpp interface name. ");
7940       return -99;
7941     }
7942
7943   /* Construct the API message */
7944   M (TAP_DELETE_V2, mp);
7945
7946   mp->sw_if_index = ntohl (sw_if_index);
7947
7948   /* send it... */
7949   S (mp);
7950
7951   /* Wait for a reply... */
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_ip_table_add_del (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_ip_table_add_del_t *mp;
7961   u32 table_id = ~0;
7962   u8 is_ipv6 = 0;
7963   u8 is_add = 1;
7964   int ret = 0;
7965
7966   /* Parse args required to build the message */
7967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (i, "ipv6"))
7970         is_ipv6 = 1;
7971       else if (unformat (i, "del"))
7972         is_add = 0;
7973       else if (unformat (i, "add"))
7974         is_add = 1;
7975       else if (unformat (i, "table %d", &table_id))
7976         ;
7977       else
7978         {
7979           clib_warning ("parse error '%U'", format_unformat_error, i);
7980           return -99;
7981         }
7982     }
7983
7984   if (~0 == table_id)
7985     {
7986       errmsg ("missing table-ID");
7987       return -99;
7988     }
7989
7990   /* Construct the API message */
7991   M (IP_TABLE_ADD_DEL, mp);
7992
7993   mp->table_id = ntohl (table_id);
7994   mp->is_ipv6 = is_ipv6;
7995   mp->is_add = is_add;
7996
7997   /* send it... */
7998   S (mp);
7999
8000   /* Wait for a reply... */
8001   W (ret);
8002
8003   return ret;
8004 }
8005
8006 static int
8007 api_ip_add_del_route (vat_main_t * vam)
8008 {
8009   unformat_input_t *i = vam->input;
8010   vl_api_ip_add_del_route_t *mp;
8011   u32 sw_if_index = ~0, vrf_id = 0;
8012   u8 is_ipv6 = 0;
8013   u8 is_local = 0, is_drop = 0;
8014   u8 is_unreach = 0, is_prohibit = 0;
8015   u8 is_add = 1;
8016   u32 next_hop_weight = 1;
8017   u8 is_multipath = 0;
8018   u8 address_set = 0;
8019   u8 address_length_set = 0;
8020   u32 next_hop_table_id = 0;
8021   u32 resolve_attempts = 0;
8022   u32 dst_address_length = 0;
8023   u8 next_hop_set = 0;
8024   ip4_address_t v4_dst_address, v4_next_hop_address;
8025   ip6_address_t v6_dst_address, v6_next_hop_address;
8026   int count = 1;
8027   int j;
8028   f64 before = 0;
8029   u32 random_add_del = 0;
8030   u32 *random_vector = 0;
8031   uword *random_hash;
8032   u32 random_seed = 0xdeaddabe;
8033   u32 classify_table_index = ~0;
8034   u8 is_classify = 0;
8035   u8 resolve_host = 0, resolve_attached = 0;
8036   mpls_label_t *next_hop_out_label_stack = NULL;
8037   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8038   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8039
8040   /* Parse args required to build the message */
8041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8042     {
8043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8044         ;
8045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8046         ;
8047       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8048         {
8049           address_set = 1;
8050           is_ipv6 = 0;
8051         }
8052       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8053         {
8054           address_set = 1;
8055           is_ipv6 = 1;
8056         }
8057       else if (unformat (i, "/%d", &dst_address_length))
8058         {
8059           address_length_set = 1;
8060         }
8061
8062       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8063                                          &v4_next_hop_address))
8064         {
8065           next_hop_set = 1;
8066         }
8067       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8068                                          &v6_next_hop_address))
8069         {
8070           next_hop_set = 1;
8071         }
8072       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8073         ;
8074       else if (unformat (i, "weight %d", &next_hop_weight))
8075         ;
8076       else if (unformat (i, "drop"))
8077         {
8078           is_drop = 1;
8079         }
8080       else if (unformat (i, "null-send-unreach"))
8081         {
8082           is_unreach = 1;
8083         }
8084       else if (unformat (i, "null-send-prohibit"))
8085         {
8086           is_prohibit = 1;
8087         }
8088       else if (unformat (i, "local"))
8089         {
8090           is_local = 1;
8091         }
8092       else if (unformat (i, "classify %d", &classify_table_index))
8093         {
8094           is_classify = 1;
8095         }
8096       else if (unformat (i, "del"))
8097         is_add = 0;
8098       else if (unformat (i, "add"))
8099         is_add = 1;
8100       else if (unformat (i, "resolve-via-host"))
8101         resolve_host = 1;
8102       else if (unformat (i, "resolve-via-attached"))
8103         resolve_attached = 1;
8104       else if (unformat (i, "multipath"))
8105         is_multipath = 1;
8106       else if (unformat (i, "vrf %d", &vrf_id))
8107         ;
8108       else if (unformat (i, "count %d", &count))
8109         ;
8110       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8111         ;
8112       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8113         ;
8114       else if (unformat (i, "out-label %d", &next_hop_out_label))
8115         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8116       else if (unformat (i, "via-label %d", &next_hop_via_label))
8117         ;
8118       else if (unformat (i, "random"))
8119         random_add_del = 1;
8120       else if (unformat (i, "seed %d", &random_seed))
8121         ;
8122       else
8123         {
8124           clib_warning ("parse error '%U'", format_unformat_error, i);
8125           return -99;
8126         }
8127     }
8128
8129   if (!next_hop_set && !is_drop && !is_local &&
8130       !is_classify && !is_unreach && !is_prohibit &&
8131       MPLS_LABEL_INVALID == next_hop_via_label)
8132     {
8133       errmsg
8134         ("next hop / local / drop / unreach / prohibit / classify not set");
8135       return -99;
8136     }
8137
8138   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8139     {
8140       errmsg ("next hop and next-hop via label set");
8141       return -99;
8142     }
8143   if (address_set == 0)
8144     {
8145       errmsg ("missing addresses");
8146       return -99;
8147     }
8148
8149   if (address_length_set == 0)
8150     {
8151       errmsg ("missing address length");
8152       return -99;
8153     }
8154
8155   /* Generate a pile of unique, random routes */
8156   if (random_add_del)
8157     {
8158       u32 this_random_address;
8159       random_hash = hash_create (count, sizeof (uword));
8160
8161       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8162       for (j = 0; j <= count; j++)
8163         {
8164           do
8165             {
8166               this_random_address = random_u32 (&random_seed);
8167               this_random_address =
8168                 clib_host_to_net_u32 (this_random_address);
8169             }
8170           while (hash_get (random_hash, this_random_address));
8171           vec_add1 (random_vector, this_random_address);
8172           hash_set (random_hash, this_random_address, 1);
8173         }
8174       hash_free (random_hash);
8175       v4_dst_address.as_u32 = random_vector[0];
8176     }
8177
8178   if (count > 1)
8179     {
8180       /* Turn on async mode */
8181       vam->async_mode = 1;
8182       vam->async_errors = 0;
8183       before = vat_time_now (vam);
8184     }
8185
8186   for (j = 0; j < count; j++)
8187     {
8188       /* Construct the API message */
8189       M2 (IP_ADD_DEL_ROUTE, mp,
8190           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8191
8192       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8193       mp->table_id = ntohl (vrf_id);
8194
8195       mp->is_add = is_add;
8196       mp->is_drop = is_drop;
8197       mp->is_unreach = is_unreach;
8198       mp->is_prohibit = is_prohibit;
8199       mp->is_ipv6 = is_ipv6;
8200       mp->is_local = is_local;
8201       mp->is_classify = is_classify;
8202       mp->is_multipath = is_multipath;
8203       mp->is_resolve_host = resolve_host;
8204       mp->is_resolve_attached = resolve_attached;
8205       mp->next_hop_weight = next_hop_weight;
8206       mp->dst_address_length = dst_address_length;
8207       mp->next_hop_table_id = ntohl (next_hop_table_id);
8208       mp->classify_table_index = ntohl (classify_table_index);
8209       mp->next_hop_via_label = ntohl (next_hop_via_label);
8210       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8211       if (0 != mp->next_hop_n_out_labels)
8212         {
8213           memcpy (mp->next_hop_out_label_stack,
8214                   next_hop_out_label_stack,
8215                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8216           vec_free (next_hop_out_label_stack);
8217         }
8218
8219       if (is_ipv6)
8220         {
8221           clib_memcpy (mp->dst_address, &v6_dst_address,
8222                        sizeof (v6_dst_address));
8223           if (next_hop_set)
8224             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8225                          sizeof (v6_next_hop_address));
8226           increment_v6_address (&v6_dst_address);
8227         }
8228       else
8229         {
8230           clib_memcpy (mp->dst_address, &v4_dst_address,
8231                        sizeof (v4_dst_address));
8232           if (next_hop_set)
8233             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8234                          sizeof (v4_next_hop_address));
8235           if (random_add_del)
8236             v4_dst_address.as_u32 = random_vector[j + 1];
8237           else
8238             increment_v4_address (&v4_dst_address);
8239         }
8240       /* send it... */
8241       S (mp);
8242       /* If we receive SIGTERM, stop now... */
8243       if (vam->do_exit)
8244         break;
8245     }
8246
8247   /* When testing multiple add/del ops, use a control-ping to sync */
8248   if (count > 1)
8249     {
8250       vl_api_control_ping_t *mp_ping;
8251       f64 after;
8252       f64 timeout;
8253
8254       /* Shut off async mode */
8255       vam->async_mode = 0;
8256
8257       MPING (CONTROL_PING, mp_ping);
8258       S (mp_ping);
8259
8260       timeout = vat_time_now (vam) + 1.0;
8261       while (vat_time_now (vam) < timeout)
8262         if (vam->result_ready == 1)
8263           goto out;
8264       vam->retval = -99;
8265
8266     out:
8267       if (vam->retval == -99)
8268         errmsg ("timeout");
8269
8270       if (vam->async_errors > 0)
8271         {
8272           errmsg ("%d asynchronous errors", vam->async_errors);
8273           vam->retval = -98;
8274         }
8275       vam->async_errors = 0;
8276       after = vat_time_now (vam);
8277
8278       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8279       if (j > 0)
8280         count = j;
8281
8282       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8283              count, after - before, count / (after - before));
8284     }
8285   else
8286     {
8287       int ret;
8288
8289       /* Wait for a reply... */
8290       W (ret);
8291       return ret;
8292     }
8293
8294   /* Return the good/bad news */
8295   return (vam->retval);
8296 }
8297
8298 static int
8299 api_ip_mroute_add_del (vat_main_t * vam)
8300 {
8301   unformat_input_t *i = vam->input;
8302   vl_api_ip_mroute_add_del_t *mp;
8303   u32 sw_if_index = ~0, vrf_id = 0;
8304   u8 is_ipv6 = 0;
8305   u8 is_local = 0;
8306   u8 is_add = 1;
8307   u8 address_set = 0;
8308   u32 grp_address_length = 0;
8309   ip4_address_t v4_grp_address, v4_src_address;
8310   ip6_address_t v6_grp_address, v6_src_address;
8311   mfib_itf_flags_t iflags = 0;
8312   mfib_entry_flags_t eflags = 0;
8313   int ret;
8314
8315   /* Parse args required to build the message */
8316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8317     {
8318       if (unformat (i, "sw_if_index %d", &sw_if_index))
8319         ;
8320       else if (unformat (i, "%U %U",
8321                          unformat_ip4_address, &v4_src_address,
8322                          unformat_ip4_address, &v4_grp_address))
8323         {
8324           grp_address_length = 64;
8325           address_set = 1;
8326           is_ipv6 = 0;
8327         }
8328       else if (unformat (i, "%U %U",
8329                          unformat_ip6_address, &v6_src_address,
8330                          unformat_ip6_address, &v6_grp_address))
8331         {
8332           grp_address_length = 256;
8333           address_set = 1;
8334           is_ipv6 = 1;
8335         }
8336       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8337         {
8338           memset (&v4_src_address, 0, sizeof (v4_src_address));
8339           grp_address_length = 32;
8340           address_set = 1;
8341           is_ipv6 = 0;
8342         }
8343       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8344         {
8345           memset (&v6_src_address, 0, sizeof (v6_src_address));
8346           grp_address_length = 128;
8347           address_set = 1;
8348           is_ipv6 = 1;
8349         }
8350       else if (unformat (i, "/%d", &grp_address_length))
8351         ;
8352       else if (unformat (i, "local"))
8353         {
8354           is_local = 1;
8355         }
8356       else if (unformat (i, "del"))
8357         is_add = 0;
8358       else if (unformat (i, "add"))
8359         is_add = 1;
8360       else if (unformat (i, "vrf %d", &vrf_id))
8361         ;
8362       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8363         ;
8364       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8365         ;
8366       else
8367         {
8368           clib_warning ("parse error '%U'", format_unformat_error, i);
8369           return -99;
8370         }
8371     }
8372
8373   if (address_set == 0)
8374     {
8375       errmsg ("missing addresses\n");
8376       return -99;
8377     }
8378
8379   /* Construct the API message */
8380   M (IP_MROUTE_ADD_DEL, mp);
8381
8382   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8383   mp->table_id = ntohl (vrf_id);
8384
8385   mp->is_add = is_add;
8386   mp->is_ipv6 = is_ipv6;
8387   mp->is_local = is_local;
8388   mp->itf_flags = ntohl (iflags);
8389   mp->entry_flags = ntohl (eflags);
8390   mp->grp_address_length = grp_address_length;
8391   mp->grp_address_length = ntohs (mp->grp_address_length);
8392
8393   if (is_ipv6)
8394     {
8395       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8396       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8397     }
8398   else
8399     {
8400       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8401       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8402
8403     }
8404
8405   /* send it... */
8406   S (mp);
8407   /* Wait for a reply... */
8408   W (ret);
8409   return ret;
8410 }
8411
8412 static int
8413 api_mpls_table_add_del (vat_main_t * vam)
8414 {
8415   unformat_input_t *i = vam->input;
8416   vl_api_mpls_table_add_del_t *mp;
8417   u32 table_id = ~0;
8418   u8 is_add = 1;
8419   int ret = 0;
8420
8421   /* Parse args required to build the message */
8422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8423     {
8424       if (unformat (i, "table %d", &table_id))
8425         ;
8426       else if (unformat (i, "del"))
8427         is_add = 0;
8428       else if (unformat (i, "add"))
8429         is_add = 1;
8430       else
8431         {
8432           clib_warning ("parse error '%U'", format_unformat_error, i);
8433           return -99;
8434         }
8435     }
8436
8437   if (~0 == table_id)
8438     {
8439       errmsg ("missing table-ID");
8440       return -99;
8441     }
8442
8443   /* Construct the API message */
8444   M (MPLS_TABLE_ADD_DEL, mp);
8445
8446   mp->mt_table_id = ntohl (table_id);
8447   mp->mt_is_add = is_add;
8448
8449   /* send it... */
8450   S (mp);
8451
8452   /* Wait for a reply... */
8453   W (ret);
8454
8455   return ret;
8456 }
8457
8458 static int
8459 api_mpls_route_add_del (vat_main_t * vam)
8460 {
8461   unformat_input_t *i = vam->input;
8462   vl_api_mpls_route_add_del_t *mp;
8463   u32 sw_if_index = ~0, table_id = 0;
8464   u8 is_add = 1;
8465   u32 next_hop_weight = 1;
8466   u8 is_multipath = 0;
8467   u32 next_hop_table_id = 0;
8468   u8 next_hop_set = 0;
8469   ip4_address_t v4_next_hop_address = {
8470     .as_u32 = 0,
8471   };
8472   ip6_address_t v6_next_hop_address = { {0} };
8473   int count = 1;
8474   int j;
8475   f64 before = 0;
8476   u32 classify_table_index = ~0;
8477   u8 is_classify = 0;
8478   u8 resolve_host = 0, resolve_attached = 0;
8479   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8480   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8481   mpls_label_t *next_hop_out_label_stack = NULL;
8482   mpls_label_t local_label = MPLS_LABEL_INVALID;
8483   u8 is_eos = 0;
8484   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8485
8486   /* Parse args required to build the message */
8487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8490         ;
8491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8492         ;
8493       else if (unformat (i, "%d", &local_label))
8494         ;
8495       else if (unformat (i, "eos"))
8496         is_eos = 1;
8497       else if (unformat (i, "non-eos"))
8498         is_eos = 0;
8499       else if (unformat (i, "via %U", unformat_ip4_address,
8500                          &v4_next_hop_address))
8501         {
8502           next_hop_set = 1;
8503           next_hop_proto = DPO_PROTO_IP4;
8504         }
8505       else if (unformat (i, "via %U", unformat_ip6_address,
8506                          &v6_next_hop_address))
8507         {
8508           next_hop_set = 1;
8509           next_hop_proto = DPO_PROTO_IP6;
8510         }
8511       else if (unformat (i, "weight %d", &next_hop_weight))
8512         ;
8513       else if (unformat (i, "classify %d", &classify_table_index))
8514         {
8515           is_classify = 1;
8516         }
8517       else if (unformat (i, "del"))
8518         is_add = 0;
8519       else if (unformat (i, "add"))
8520         is_add = 1;
8521       else if (unformat (i, "resolve-via-host"))
8522         resolve_host = 1;
8523       else if (unformat (i, "resolve-via-attached"))
8524         resolve_attached = 1;
8525       else if (unformat (i, "multipath"))
8526         is_multipath = 1;
8527       else if (unformat (i, "count %d", &count))
8528         ;
8529       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8530         {
8531           next_hop_set = 1;
8532           next_hop_proto = DPO_PROTO_IP4;
8533         }
8534       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8535         {
8536           next_hop_set = 1;
8537           next_hop_proto = DPO_PROTO_IP6;
8538         }
8539       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8540         ;
8541       else if (unformat (i, "via-label %d", &next_hop_via_label))
8542         ;
8543       else if (unformat (i, "out-label %d", &next_hop_out_label))
8544         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8545       else
8546         {
8547           clib_warning ("parse error '%U'", format_unformat_error, i);
8548           return -99;
8549         }
8550     }
8551
8552   if (!next_hop_set && !is_classify)
8553     {
8554       errmsg ("next hop / classify not set");
8555       return -99;
8556     }
8557
8558   if (MPLS_LABEL_INVALID == local_label)
8559     {
8560       errmsg ("missing label");
8561       return -99;
8562     }
8563
8564   if (count > 1)
8565     {
8566       /* Turn on async mode */
8567       vam->async_mode = 1;
8568       vam->async_errors = 0;
8569       before = vat_time_now (vam);
8570     }
8571
8572   for (j = 0; j < count; j++)
8573     {
8574       /* Construct the API message */
8575       M2 (MPLS_ROUTE_ADD_DEL, mp,
8576           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8577
8578       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8579       mp->mr_table_id = ntohl (table_id);
8580
8581       mp->mr_is_add = is_add;
8582       mp->mr_next_hop_proto = next_hop_proto;
8583       mp->mr_is_classify = is_classify;
8584       mp->mr_is_multipath = is_multipath;
8585       mp->mr_is_resolve_host = resolve_host;
8586       mp->mr_is_resolve_attached = resolve_attached;
8587       mp->mr_next_hop_weight = next_hop_weight;
8588       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8589       mp->mr_classify_table_index = ntohl (classify_table_index);
8590       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8591       mp->mr_label = ntohl (local_label);
8592       mp->mr_eos = is_eos;
8593
8594       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8595       if (0 != mp->mr_next_hop_n_out_labels)
8596         {
8597           memcpy (mp->mr_next_hop_out_label_stack,
8598                   next_hop_out_label_stack,
8599                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8600           vec_free (next_hop_out_label_stack);
8601         }
8602
8603       if (next_hop_set)
8604         {
8605           if (DPO_PROTO_IP4 == next_hop_proto)
8606             {
8607               clib_memcpy (mp->mr_next_hop,
8608                            &v4_next_hop_address,
8609                            sizeof (v4_next_hop_address));
8610             }
8611           else if (DPO_PROTO_IP6 == next_hop_proto)
8612
8613             {
8614               clib_memcpy (mp->mr_next_hop,
8615                            &v6_next_hop_address,
8616                            sizeof (v6_next_hop_address));
8617             }
8618         }
8619       local_label++;
8620
8621       /* send it... */
8622       S (mp);
8623       /* If we receive SIGTERM, stop now... */
8624       if (vam->do_exit)
8625         break;
8626     }
8627
8628   /* When testing multiple add/del ops, use a control-ping to sync */
8629   if (count > 1)
8630     {
8631       vl_api_control_ping_t *mp_ping;
8632       f64 after;
8633       f64 timeout;
8634
8635       /* Shut off async mode */
8636       vam->async_mode = 0;
8637
8638       MPING (CONTROL_PING, mp_ping);
8639       S (mp_ping);
8640
8641       timeout = vat_time_now (vam) + 1.0;
8642       while (vat_time_now (vam) < timeout)
8643         if (vam->result_ready == 1)
8644           goto out;
8645       vam->retval = -99;
8646
8647     out:
8648       if (vam->retval == -99)
8649         errmsg ("timeout");
8650
8651       if (vam->async_errors > 0)
8652         {
8653           errmsg ("%d asynchronous errors", vam->async_errors);
8654           vam->retval = -98;
8655         }
8656       vam->async_errors = 0;
8657       after = vat_time_now (vam);
8658
8659       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8660       if (j > 0)
8661         count = j;
8662
8663       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8664              count, after - before, count / (after - before));
8665     }
8666   else
8667     {
8668       int ret;
8669
8670       /* Wait for a reply... */
8671       W (ret);
8672       return ret;
8673     }
8674
8675   /* Return the good/bad news */
8676   return (vam->retval);
8677 }
8678
8679 static int
8680 api_mpls_ip_bind_unbind (vat_main_t * vam)
8681 {
8682   unformat_input_t *i = vam->input;
8683   vl_api_mpls_ip_bind_unbind_t *mp;
8684   u32 ip_table_id = 0;
8685   u8 is_bind = 1;
8686   u8 is_ip4 = 1;
8687   ip4_address_t v4_address;
8688   ip6_address_t v6_address;
8689   u32 address_length;
8690   u8 address_set = 0;
8691   mpls_label_t local_label = MPLS_LABEL_INVALID;
8692   int ret;
8693
8694   /* Parse args required to build the message */
8695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8696     {
8697       if (unformat (i, "%U/%d", unformat_ip4_address,
8698                     &v4_address, &address_length))
8699         {
8700           is_ip4 = 1;
8701           address_set = 1;
8702         }
8703       else if (unformat (i, "%U/%d", unformat_ip6_address,
8704                          &v6_address, &address_length))
8705         {
8706           is_ip4 = 0;
8707           address_set = 1;
8708         }
8709       else if (unformat (i, "%d", &local_label))
8710         ;
8711       else if (unformat (i, "table-id %d", &ip_table_id))
8712         ;
8713       else if (unformat (i, "unbind"))
8714         is_bind = 0;
8715       else if (unformat (i, "bind"))
8716         is_bind = 1;
8717       else
8718         {
8719           clib_warning ("parse error '%U'", format_unformat_error, i);
8720           return -99;
8721         }
8722     }
8723
8724   if (!address_set)
8725     {
8726       errmsg ("IP addres not set");
8727       return -99;
8728     }
8729
8730   if (MPLS_LABEL_INVALID == local_label)
8731     {
8732       errmsg ("missing label");
8733       return -99;
8734     }
8735
8736   /* Construct the API message */
8737   M (MPLS_IP_BIND_UNBIND, mp);
8738
8739   mp->mb_is_bind = is_bind;
8740   mp->mb_is_ip4 = is_ip4;
8741   mp->mb_ip_table_id = ntohl (ip_table_id);
8742   mp->mb_mpls_table_id = 0;
8743   mp->mb_label = ntohl (local_label);
8744   mp->mb_address_length = address_length;
8745
8746   if (is_ip4)
8747     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8748   else
8749     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8750
8751   /* send it... */
8752   S (mp);
8753
8754   /* Wait for a reply... */
8755   W (ret);
8756   return ret;
8757 }
8758
8759 static int
8760 api_bier_table_add_del (vat_main_t * vam)
8761 {
8762   unformat_input_t *i = vam->input;
8763   vl_api_bier_table_add_del_t *mp;
8764   u8 is_add = 1;
8765   u32 set = 0, sub_domain = 0, hdr_len = 3;
8766   mpls_label_t local_label = MPLS_LABEL_INVALID;
8767   int ret;
8768
8769   /* Parse args required to build the message */
8770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8771     {
8772       if (unformat (i, "sub-domain %d", &sub_domain))
8773         ;
8774       else if (unformat (i, "set %d", &set))
8775         ;
8776       else if (unformat (i, "label %d", &local_label))
8777         ;
8778       else if (unformat (i, "hdr-len %d", &hdr_len))
8779         ;
8780       else if (unformat (i, "add"))
8781         is_add = 1;
8782       else if (unformat (i, "del"))
8783         is_add = 0;
8784       else
8785         {
8786           clib_warning ("parse error '%U'", format_unformat_error, i);
8787           return -99;
8788         }
8789     }
8790
8791   if (MPLS_LABEL_INVALID == local_label)
8792     {
8793       errmsg ("missing label\n");
8794       return -99;
8795     }
8796
8797   /* Construct the API message */
8798   M (BIER_TABLE_ADD_DEL, mp);
8799
8800   mp->bt_is_add = is_add;
8801   mp->bt_label = ntohl (local_label);
8802   mp->bt_tbl_id.bt_set = set;
8803   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8804   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8805
8806   /* send it... */
8807   S (mp);
8808
8809   /* Wait for a reply... */
8810   W (ret);
8811
8812   return (ret);
8813 }
8814
8815 static int
8816 api_bier_route_add_del (vat_main_t * vam)
8817 {
8818   unformat_input_t *i = vam->input;
8819   vl_api_bier_route_add_del_t *mp;
8820   u8 is_add = 1;
8821   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8822   ip4_address_t v4_next_hop_address;
8823   ip6_address_t v6_next_hop_address;
8824   u8 next_hop_set = 0;
8825   u8 next_hop_proto_is_ip4 = 1;
8826   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8827   int ret;
8828
8829   /* Parse args required to build the message */
8830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8833         {
8834           next_hop_proto_is_ip4 = 1;
8835           next_hop_set = 1;
8836         }
8837       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8838         {
8839           next_hop_proto_is_ip4 = 0;
8840           next_hop_set = 1;
8841         }
8842       if (unformat (i, "sub-domain %d", &sub_domain))
8843         ;
8844       else if (unformat (i, "set %d", &set))
8845         ;
8846       else if (unformat (i, "hdr-len %d", &hdr_len))
8847         ;
8848       else if (unformat (i, "bp %d", &bp))
8849         ;
8850       else if (unformat (i, "add"))
8851         is_add = 1;
8852       else if (unformat (i, "del"))
8853         is_add = 0;
8854       else if (unformat (i, "out-label %d", &next_hop_out_label))
8855         ;
8856       else
8857         {
8858           clib_warning ("parse error '%U'", format_unformat_error, i);
8859           return -99;
8860         }
8861     }
8862
8863   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8864     {
8865       errmsg ("next hop / label set\n");
8866       return -99;
8867     }
8868   if (0 == bp)
8869     {
8870       errmsg ("bit=position not set\n");
8871       return -99;
8872     }
8873
8874   /* Construct the API message */
8875   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8876
8877   mp->br_is_add = is_add;
8878   mp->br_tbl_id.bt_set = set;
8879   mp->br_tbl_id.bt_sub_domain = sub_domain;
8880   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8881   mp->br_bp = ntohs (bp);
8882   mp->br_n_paths = 1;
8883   mp->br_paths[0].n_labels = 1;
8884   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8885   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8886
8887   if (next_hop_proto_is_ip4)
8888     {
8889       clib_memcpy (mp->br_paths[0].next_hop,
8890                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8891     }
8892   else
8893     {
8894       clib_memcpy (mp->br_paths[0].next_hop,
8895                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8896     }
8897
8898   /* send it... */
8899   S (mp);
8900
8901   /* Wait for a reply... */
8902   W (ret);
8903
8904   return (ret);
8905 }
8906
8907 static int
8908 api_proxy_arp_add_del (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_proxy_arp_add_del_t *mp;
8912   u32 vrf_id = 0;
8913   u8 is_add = 1;
8914   ip4_address_t lo, hi;
8915   u8 range_set = 0;
8916   int ret;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "vrf %d", &vrf_id))
8921         ;
8922       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8923                          unformat_ip4_address, &hi))
8924         range_set = 1;
8925       else if (unformat (i, "del"))
8926         is_add = 0;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (range_set == 0)
8935     {
8936       errmsg ("address range not set");
8937       return -99;
8938     }
8939
8940   M (PROXY_ARP_ADD_DEL, mp);
8941
8942   mp->vrf_id = ntohl (vrf_id);
8943   mp->is_add = is_add;
8944   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8945   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8946
8947   S (mp);
8948   W (ret);
8949   return ret;
8950 }
8951
8952 static int
8953 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8957   u32 sw_if_index;
8958   u8 enable = 1;
8959   u8 sw_if_index_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "enable"))
8969         enable = 1;
8970       else if (unformat (i, "disable"))
8971         enable = 0;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index_set == 0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984
8985   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->enable_disable = enable;
8989
8990   S (mp);
8991   W (ret);
8992   return ret;
8993 }
8994
8995 static int
8996 api_mpls_tunnel_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_mpls_tunnel_add_del_t *mp;
9000
9001   u8 is_add = 1;
9002   u8 l2_only = 0;
9003   u32 sw_if_index = ~0;
9004   u32 next_hop_sw_if_index = ~0;
9005   u32 next_hop_proto_is_ip4 = 1;
9006
9007   u32 next_hop_table_id = 0;
9008   ip4_address_t v4_next_hop_address = {
9009     .as_u32 = 0,
9010   };
9011   ip6_address_t v6_next_hop_address = { {0} };
9012   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9013   int ret;
9014
9015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9016     {
9017       if (unformat (i, "add"))
9018         is_add = 1;
9019       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9020         is_add = 0;
9021       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9022         ;
9023       else if (unformat (i, "via %U",
9024                          unformat_ip4_address, &v4_next_hop_address))
9025         {
9026           next_hop_proto_is_ip4 = 1;
9027         }
9028       else if (unformat (i, "via %U",
9029                          unformat_ip6_address, &v6_next_hop_address))
9030         {
9031           next_hop_proto_is_ip4 = 0;
9032         }
9033       else if (unformat (i, "l2-only"))
9034         l2_only = 1;
9035       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9036         ;
9037       else if (unformat (i, "out-label %d", &next_hop_out_label))
9038         vec_add1 (labels, ntohl (next_hop_out_label));
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9047
9048   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9049   mp->mt_sw_if_index = ntohl (sw_if_index);
9050   mp->mt_is_add = is_add;
9051   mp->mt_l2_only = l2_only;
9052   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9053   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9054
9055   mp->mt_next_hop_n_out_labels = vec_len (labels);
9056
9057   if (0 != mp->mt_next_hop_n_out_labels)
9058     {
9059       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9060                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9061       vec_free (labels);
9062     }
9063
9064   if (next_hop_proto_is_ip4)
9065     {
9066       clib_memcpy (mp->mt_next_hop,
9067                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9068     }
9069   else
9070     {
9071       clib_memcpy (mp->mt_next_hop,
9072                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9073     }
9074
9075   S (mp);
9076   W (ret);
9077   return ret;
9078 }
9079
9080 static int
9081 api_sw_interface_set_unnumbered (vat_main_t * vam)
9082 {
9083   unformat_input_t *i = vam->input;
9084   vl_api_sw_interface_set_unnumbered_t *mp;
9085   u32 sw_if_index;
9086   u32 unnum_sw_index = ~0;
9087   u8 is_add = 1;
9088   u8 sw_if_index_set = 0;
9089   int ret;
9090
9091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9094         sw_if_index_set = 1;
9095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9098         ;
9099       else if (unformat (i, "del"))
9100         is_add = 0;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (sw_if_index_set == 0)
9109     {
9110       errmsg ("missing interface name or sw_if_index");
9111       return -99;
9112     }
9113
9114   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9115
9116   mp->sw_if_index = ntohl (sw_if_index);
9117   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9118   mp->is_add = is_add;
9119
9120   S (mp);
9121   W (ret);
9122   return ret;
9123 }
9124
9125 static int
9126 api_ip_neighbor_add_del (vat_main_t * vam)
9127 {
9128   unformat_input_t *i = vam->input;
9129   vl_api_ip_neighbor_add_del_t *mp;
9130   u32 sw_if_index;
9131   u8 sw_if_index_set = 0;
9132   u8 is_add = 1;
9133   u8 is_static = 0;
9134   u8 is_no_fib_entry = 0;
9135   u8 mac_address[6];
9136   u8 mac_set = 0;
9137   u8 v4_address_set = 0;
9138   u8 v6_address_set = 0;
9139   ip4_address_t v4address;
9140   ip6_address_t v6address;
9141   int ret;
9142
9143   memset (mac_address, 0, sizeof (mac_address));
9144
9145   /* Parse args required to build the message */
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9149         {
9150           mac_set = 1;
9151         }
9152       else if (unformat (i, "del"))
9153         is_add = 0;
9154       else
9155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "is_static"))
9160         is_static = 1;
9161       else if (unformat (i, "no-fib-entry"))
9162         is_no_fib_entry = 1;
9163       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9164         v4_address_set = 1;
9165       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9166         v6_address_set = 1;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179   if (v4_address_set && v6_address_set)
9180     {
9181       errmsg ("both v4 and v6 addresses set");
9182       return -99;
9183     }
9184   if (!v4_address_set && !v6_address_set)
9185     {
9186       errmsg ("no address set");
9187       return -99;
9188     }
9189
9190   /* Construct the API message */
9191   M (IP_NEIGHBOR_ADD_DEL, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->is_add = is_add;
9195   mp->is_static = is_static;
9196   mp->is_no_adj_fib = is_no_fib_entry;
9197   if (mac_set)
9198     clib_memcpy (mp->mac_address, mac_address, 6);
9199   if (v6_address_set)
9200     {
9201       mp->is_ipv6 = 1;
9202       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9203     }
9204   else
9205     {
9206       /* mp->is_ipv6 = 0; via memset in M macro above */
9207       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9208     }
9209
9210   /* send it... */
9211   S (mp);
9212
9213   /* Wait for a reply, return good/bad news  */
9214   W (ret);
9215   return ret;
9216 }
9217
9218 static int
9219 api_create_vlan_subif (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_create_vlan_subif_t *mp;
9223   u32 sw_if_index;
9224   u8 sw_if_index_set = 0;
9225   u32 vlan_id;
9226   u8 vlan_id_set = 0;
9227   int ret;
9228
9229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9230     {
9231       if (unformat (i, "sw_if_index %d", &sw_if_index))
9232         sw_if_index_set = 1;
9233       else
9234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9235         sw_if_index_set = 1;
9236       else if (unformat (i, "vlan %d", &vlan_id))
9237         vlan_id_set = 1;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (sw_if_index_set == 0)
9246     {
9247       errmsg ("missing interface name or sw_if_index");
9248       return -99;
9249     }
9250
9251   if (vlan_id_set == 0)
9252     {
9253       errmsg ("missing vlan_id");
9254       return -99;
9255     }
9256   M (CREATE_VLAN_SUBIF, mp);
9257
9258   mp->sw_if_index = ntohl (sw_if_index);
9259   mp->vlan_id = ntohl (vlan_id);
9260
9261   S (mp);
9262   W (ret);
9263   return ret;
9264 }
9265
9266 #define foreach_create_subif_bit                \
9267 _(no_tags)                                      \
9268 _(one_tag)                                      \
9269 _(two_tags)                                     \
9270 _(dot1ad)                                       \
9271 _(exact_match)                                  \
9272 _(default_sub)                                  \
9273 _(outer_vlan_id_any)                            \
9274 _(inner_vlan_id_any)
9275
9276 static int
9277 api_create_subif (vat_main_t * vam)
9278 {
9279   unformat_input_t *i = vam->input;
9280   vl_api_create_subif_t *mp;
9281   u32 sw_if_index;
9282   u8 sw_if_index_set = 0;
9283   u32 sub_id;
9284   u8 sub_id_set = 0;
9285   u32 no_tags = 0;
9286   u32 one_tag = 0;
9287   u32 two_tags = 0;
9288   u32 dot1ad = 0;
9289   u32 exact_match = 0;
9290   u32 default_sub = 0;
9291   u32 outer_vlan_id_any = 0;
9292   u32 inner_vlan_id_any = 0;
9293   u32 tmp;
9294   u16 outer_vlan_id = 0;
9295   u16 inner_vlan_id = 0;
9296   int ret;
9297
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "sw_if_index %d", &sw_if_index))
9301         sw_if_index_set = 1;
9302       else
9303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "sub_id %d", &sub_id))
9306         sub_id_set = 1;
9307       else if (unformat (i, "outer_vlan_id %d", &tmp))
9308         outer_vlan_id = tmp;
9309       else if (unformat (i, "inner_vlan_id %d", &tmp))
9310         inner_vlan_id = tmp;
9311
9312 #define _(a) else if (unformat (i, #a)) a = 1 ;
9313       foreach_create_subif_bit
9314 #undef _
9315         else
9316         {
9317           clib_warning ("parse error '%U'", format_unformat_error, i);
9318           return -99;
9319         }
9320     }
9321
9322   if (sw_if_index_set == 0)
9323     {
9324       errmsg ("missing interface name or sw_if_index");
9325       return -99;
9326     }
9327
9328   if (sub_id_set == 0)
9329     {
9330       errmsg ("missing sub_id");
9331       return -99;
9332     }
9333   M (CREATE_SUBIF, mp);
9334
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->sub_id = ntohl (sub_id);
9337
9338 #define _(a) mp->a = a;
9339   foreach_create_subif_bit;
9340 #undef _
9341
9342   mp->outer_vlan_id = ntohs (outer_vlan_id);
9343   mp->inner_vlan_id = ntohs (inner_vlan_id);
9344
9345   S (mp);
9346   W (ret);
9347   return ret;
9348 }
9349
9350 static int
9351 api_oam_add_del (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_oam_add_del_t *mp;
9355   u32 vrf_id = 0;
9356   u8 is_add = 1;
9357   ip4_address_t src, dst;
9358   u8 src_set = 0;
9359   u8 dst_set = 0;
9360   int ret;
9361
9362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (i, "vrf %d", &vrf_id))
9365         ;
9366       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9367         src_set = 1;
9368       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9369         dst_set = 1;
9370       else if (unformat (i, "del"))
9371         is_add = 0;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (src_set == 0)
9380     {
9381       errmsg ("missing src addr");
9382       return -99;
9383     }
9384
9385   if (dst_set == 0)
9386     {
9387       errmsg ("missing dst addr");
9388       return -99;
9389     }
9390
9391   M (OAM_ADD_DEL, mp);
9392
9393   mp->vrf_id = ntohl (vrf_id);
9394   mp->is_add = is_add;
9395   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9396   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_reset_fib (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_reset_fib_t *mp;
9408   u32 vrf_id = 0;
9409   u8 is_ipv6 = 0;
9410   u8 vrf_id_set = 0;
9411
9412   int ret;
9413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (i, "vrf %d", &vrf_id))
9416         vrf_id_set = 1;
9417       else if (unformat (i, "ipv6"))
9418         is_ipv6 = 1;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (vrf_id_set == 0)
9427     {
9428       errmsg ("missing vrf id");
9429       return -99;
9430     }
9431
9432   M (RESET_FIB, mp);
9433
9434   mp->vrf_id = ntohl (vrf_id);
9435   mp->is_ipv6 = is_ipv6;
9436
9437   S (mp);
9438   W (ret);
9439   return ret;
9440 }
9441
9442 static int
9443 api_dhcp_proxy_config (vat_main_t * vam)
9444 {
9445   unformat_input_t *i = vam->input;
9446   vl_api_dhcp_proxy_config_t *mp;
9447   u32 rx_vrf_id = 0;
9448   u32 server_vrf_id = 0;
9449   u8 is_add = 1;
9450   u8 v4_address_set = 0;
9451   u8 v6_address_set = 0;
9452   ip4_address_t v4address;
9453   ip6_address_t v6address;
9454   u8 v4_src_address_set = 0;
9455   u8 v6_src_address_set = 0;
9456   ip4_address_t v4srcaddress;
9457   ip6_address_t v6srcaddress;
9458   int ret;
9459
9460   /* Parse args required to build the message */
9461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (i, "del"))
9464         is_add = 0;
9465       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9466         ;
9467       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9468         ;
9469       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9470         v4_address_set = 1;
9471       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9472         v6_address_set = 1;
9473       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9474         v4_src_address_set = 1;
9475       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9476         v6_src_address_set = 1;
9477       else
9478         break;
9479     }
9480
9481   if (v4_address_set && v6_address_set)
9482     {
9483       errmsg ("both v4 and v6 server addresses set");
9484       return -99;
9485     }
9486   if (!v4_address_set && !v6_address_set)
9487     {
9488       errmsg ("no server addresses set");
9489       return -99;
9490     }
9491
9492   if (v4_src_address_set && v6_src_address_set)
9493     {
9494       errmsg ("both v4 and v6  src addresses set");
9495       return -99;
9496     }
9497   if (!v4_src_address_set && !v6_src_address_set)
9498     {
9499       errmsg ("no src addresses set");
9500       return -99;
9501     }
9502
9503   if (!(v4_src_address_set && v4_address_set) &&
9504       !(v6_src_address_set && v6_address_set))
9505     {
9506       errmsg ("no matching server and src addresses set");
9507       return -99;
9508     }
9509
9510   /* Construct the API message */
9511   M (DHCP_PROXY_CONFIG, mp);
9512
9513   mp->is_add = is_add;
9514   mp->rx_vrf_id = ntohl (rx_vrf_id);
9515   mp->server_vrf_id = ntohl (server_vrf_id);
9516   if (v6_address_set)
9517     {
9518       mp->is_ipv6 = 1;
9519       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9520       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9521     }
9522   else
9523     {
9524       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9525       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9526     }
9527
9528   /* send it... */
9529   S (mp);
9530
9531   /* Wait for a reply, return good/bad news  */
9532   W (ret);
9533   return ret;
9534 }
9535
9536 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9537 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9538
9539 static void
9540 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9541 {
9542   vat_main_t *vam = &vat_main;
9543   u32 i, count = mp->count;
9544   vl_api_dhcp_server_t *s;
9545
9546   if (mp->is_ipv6)
9547     print (vam->ofp,
9548            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9549            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9550            ntohl (mp->rx_vrf_id),
9551            format_ip6_address, mp->dhcp_src_address,
9552            mp->vss_type, mp->vss_vpn_ascii_id,
9553            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9554   else
9555     print (vam->ofp,
9556            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9557            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9558            ntohl (mp->rx_vrf_id),
9559            format_ip4_address, mp->dhcp_src_address,
9560            mp->vss_type, mp->vss_vpn_ascii_id,
9561            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9562
9563   for (i = 0; i < count; i++)
9564     {
9565       s = &mp->servers[i];
9566
9567       if (mp->is_ipv6)
9568         print (vam->ofp,
9569                " Server Table-ID %d, Server Address %U",
9570                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9571       else
9572         print (vam->ofp,
9573                " Server Table-ID %d, Server Address %U",
9574                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9575     }
9576 }
9577
9578 static void vl_api_dhcp_proxy_details_t_handler_json
9579   (vl_api_dhcp_proxy_details_t * mp)
9580 {
9581   vat_main_t *vam = &vat_main;
9582   vat_json_node_t *node = NULL;
9583   u32 i, count = mp->count;
9584   struct in_addr ip4;
9585   struct in6_addr ip6;
9586   vl_api_dhcp_server_t *s;
9587
9588   if (VAT_JSON_ARRAY != vam->json_tree.type)
9589     {
9590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9591       vat_json_init_array (&vam->json_tree);
9592     }
9593   node = vat_json_array_add (&vam->json_tree);
9594
9595   vat_json_init_object (node);
9596   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9597   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9598                              sizeof (mp->vss_type));
9599   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9600                                    mp->vss_vpn_ascii_id);
9601   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9602   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9603
9604   if (mp->is_ipv6)
9605     {
9606       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9607       vat_json_object_add_ip6 (node, "src_address", ip6);
9608     }
9609   else
9610     {
9611       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9612       vat_json_object_add_ip4 (node, "src_address", ip4);
9613     }
9614
9615   for (i = 0; i < count; i++)
9616     {
9617       s = &mp->servers[i];
9618
9619       vat_json_object_add_uint (node, "server-table-id",
9620                                 ntohl (s->server_vrf_id));
9621
9622       if (mp->is_ipv6)
9623         {
9624           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9625           vat_json_object_add_ip4 (node, "src_address", ip4);
9626         }
9627       else
9628         {
9629           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9630           vat_json_object_add_ip6 (node, "server_address", ip6);
9631         }
9632     }
9633 }
9634
9635 static int
9636 api_dhcp_proxy_dump (vat_main_t * vam)
9637 {
9638   unformat_input_t *i = vam->input;
9639   vl_api_control_ping_t *mp_ping;
9640   vl_api_dhcp_proxy_dump_t *mp;
9641   u8 is_ipv6 = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "ipv6"))
9647         is_ipv6 = 1;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   M (DHCP_PROXY_DUMP, mp);
9656
9657   mp->is_ip6 = is_ipv6;
9658   S (mp);
9659
9660   /* Use a control ping for synchronization */
9661   MPING (CONTROL_PING, mp_ping);
9662   S (mp_ping);
9663
9664   W (ret);
9665   return ret;
9666 }
9667
9668 static int
9669 api_dhcp_proxy_set_vss (vat_main_t * vam)
9670 {
9671   unformat_input_t *i = vam->input;
9672   vl_api_dhcp_proxy_set_vss_t *mp;
9673   u8 is_ipv6 = 0;
9674   u8 is_add = 1;
9675   u32 tbl_id = ~0;
9676   u8 vss_type = VSS_TYPE_DEFAULT;
9677   u8 *vpn_ascii_id = 0;
9678   u32 oui = 0;
9679   u32 fib_id = 0;
9680   int ret;
9681
9682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (i, "tbl_id %d", &tbl_id))
9685         ;
9686       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9687         vss_type = VSS_TYPE_ASCII;
9688       else if (unformat (i, "fib_id %d", &fib_id))
9689         vss_type = VSS_TYPE_VPN_ID;
9690       else if (unformat (i, "oui %d", &oui))
9691         vss_type = VSS_TYPE_VPN_ID;
9692       else if (unformat (i, "ipv6"))
9693         is_ipv6 = 1;
9694       else if (unformat (i, "del"))
9695         is_add = 0;
9696       else
9697         break;
9698     }
9699
9700   if (tbl_id == ~0)
9701     {
9702       errmsg ("missing tbl_id ");
9703       vec_free (vpn_ascii_id);
9704       return -99;
9705     }
9706
9707   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9708     {
9709       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9710       vec_free (vpn_ascii_id);
9711       return -99;
9712     }
9713
9714   M (DHCP_PROXY_SET_VSS, mp);
9715   mp->tbl_id = ntohl (tbl_id);
9716   mp->vss_type = vss_type;
9717   if (vpn_ascii_id)
9718     {
9719       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9720       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9721     }
9722   mp->vpn_index = ntohl (fib_id);
9723   mp->oui = ntohl (oui);
9724   mp->is_ipv6 = is_ipv6;
9725   mp->is_add = is_add;
9726
9727   S (mp);
9728   W (ret);
9729
9730   vec_free (vpn_ascii_id);
9731   return ret;
9732 }
9733
9734 static int
9735 api_dhcp_client_config (vat_main_t * vam)
9736 {
9737   unformat_input_t *i = vam->input;
9738   vl_api_dhcp_client_config_t *mp;
9739   u32 sw_if_index;
9740   u8 sw_if_index_set = 0;
9741   u8 is_add = 1;
9742   u8 *hostname = 0;
9743   u8 disable_event = 0;
9744   int ret;
9745
9746   /* Parse args required to build the message */
9747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (i, "del"))
9750         is_add = 0;
9751       else
9752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9753         sw_if_index_set = 1;
9754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9755         sw_if_index_set = 1;
9756       else if (unformat (i, "hostname %s", &hostname))
9757         ;
9758       else if (unformat (i, "disable_event"))
9759         disable_event = 1;
9760       else
9761         break;
9762     }
9763
9764   if (sw_if_index_set == 0)
9765     {
9766       errmsg ("missing interface name or sw_if_index");
9767       return -99;
9768     }
9769
9770   if (vec_len (hostname) > 63)
9771     {
9772       errmsg ("hostname too long");
9773     }
9774   vec_add1 (hostname, 0);
9775
9776   /* Construct the API message */
9777   M (DHCP_CLIENT_CONFIG, mp);
9778
9779   mp->sw_if_index = htonl (sw_if_index);
9780   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9781   vec_free (hostname);
9782   mp->is_add = is_add;
9783   mp->want_dhcp_event = disable_event ? 0 : 1;
9784   mp->pid = htonl (getpid ());
9785
9786   /* send it... */
9787   S (mp);
9788
9789   /* Wait for a reply, return good/bad news  */
9790   W (ret);
9791   return ret;
9792 }
9793
9794 static int
9795 api_set_ip_flow_hash (vat_main_t * vam)
9796 {
9797   unformat_input_t *i = vam->input;
9798   vl_api_set_ip_flow_hash_t *mp;
9799   u32 vrf_id = 0;
9800   u8 is_ipv6 = 0;
9801   u8 vrf_id_set = 0;
9802   u8 src = 0;
9803   u8 dst = 0;
9804   u8 sport = 0;
9805   u8 dport = 0;
9806   u8 proto = 0;
9807   u8 reverse = 0;
9808   int ret;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "vrf %d", &vrf_id))
9813         vrf_id_set = 1;
9814       else if (unformat (i, "ipv6"))
9815         is_ipv6 = 1;
9816       else if (unformat (i, "src"))
9817         src = 1;
9818       else if (unformat (i, "dst"))
9819         dst = 1;
9820       else if (unformat (i, "sport"))
9821         sport = 1;
9822       else if (unformat (i, "dport"))
9823         dport = 1;
9824       else if (unformat (i, "proto"))
9825         proto = 1;
9826       else if (unformat (i, "reverse"))
9827         reverse = 1;
9828
9829       else
9830         {
9831           clib_warning ("parse error '%U'", format_unformat_error, i);
9832           return -99;
9833         }
9834     }
9835
9836   if (vrf_id_set == 0)
9837     {
9838       errmsg ("missing vrf id");
9839       return -99;
9840     }
9841
9842   M (SET_IP_FLOW_HASH, mp);
9843   mp->src = src;
9844   mp->dst = dst;
9845   mp->sport = sport;
9846   mp->dport = dport;
9847   mp->proto = proto;
9848   mp->reverse = reverse;
9849   mp->vrf_id = ntohl (vrf_id);
9850   mp->is_ipv6 = is_ipv6;
9851
9852   S (mp);
9853   W (ret);
9854   return ret;
9855 }
9856
9857 static int
9858 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_sw_interface_ip6_enable_disable_t *mp;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable = 0;
9865   int ret;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable = 1;
9875       else if (unformat (i, "disable"))
9876         enable = 0;
9877       else
9878         {
9879           clib_warning ("parse error '%U'", format_unformat_error, i);
9880           return -99;
9881         }
9882     }
9883
9884   if (sw_if_index_set == 0)
9885     {
9886       errmsg ("missing interface name or sw_if_index");
9887       return -99;
9888     }
9889
9890   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9891
9892   mp->sw_if_index = ntohl (sw_if_index);
9893   mp->enable = enable;
9894
9895   S (mp);
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u8 v6_address_set = 0;
9908   ip6_address_t v6address;
9909   int ret;
9910
9911   /* Parse args required to build the message */
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9919         v6_address_set = 1;
9920       else
9921         break;
9922     }
9923
9924   if (sw_if_index_set == 0)
9925     {
9926       errmsg ("missing interface name or sw_if_index");
9927       return -99;
9928     }
9929   if (!v6_address_set)
9930     {
9931       errmsg ("no address set");
9932       return -99;
9933     }
9934
9935   /* Construct the API message */
9936   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9937
9938   mp->sw_if_index = ntohl (sw_if_index);
9939   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9940
9941   /* send it... */
9942   S (mp);
9943
9944   /* Wait for a reply, return good/bad news  */
9945   W (ret);
9946   return ret;
9947 }
9948
9949 static int
9950 api_ip6nd_proxy_add_del (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_ip6nd_proxy_add_del_t *mp;
9954   u32 sw_if_index = ~0;
9955   u8 v6_address_set = 0;
9956   ip6_address_t v6address;
9957   u8 is_del = 0;
9958   int ret;
9959
9960   /* Parse args required to build the message */
9961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9962     {
9963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9964         ;
9965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9966         ;
9967       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9968         v6_address_set = 1;
9969       if (unformat (i, "del"))
9970         is_del = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index == ~0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983   if (!v6_address_set)
9984     {
9985       errmsg ("no address set");
9986       return -99;
9987     }
9988
9989   /* Construct the API message */
9990   M (IP6ND_PROXY_ADD_DEL, mp);
9991
9992   mp->is_del = is_del;
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9995
9996   /* send it... */
9997   S (mp);
9998
9999   /* Wait for a reply, return good/bad news  */
10000   W (ret);
10001   return ret;
10002 }
10003
10004 static int
10005 api_ip6nd_proxy_dump (vat_main_t * vam)
10006 {
10007   vl_api_ip6nd_proxy_dump_t *mp;
10008   vl_api_control_ping_t *mp_ping;
10009   int ret;
10010
10011   M (IP6ND_PROXY_DUMP, mp);
10012
10013   S (mp);
10014
10015   /* Use a control ping for synchronization */
10016   MPING (CONTROL_PING, mp_ping);
10017   S (mp_ping);
10018
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static void vl_api_ip6nd_proxy_details_t_handler
10024   (vl_api_ip6nd_proxy_details_t * mp)
10025 {
10026   vat_main_t *vam = &vat_main;
10027
10028   print (vam->ofp, "host %U sw_if_index %d",
10029          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10030 }
10031
10032 static void vl_api_ip6nd_proxy_details_t_handler_json
10033   (vl_api_ip6nd_proxy_details_t * mp)
10034 {
10035   vat_main_t *vam = &vat_main;
10036   struct in6_addr ip6;
10037   vat_json_node_t *node = NULL;
10038
10039   if (VAT_JSON_ARRAY != vam->json_tree.type)
10040     {
10041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10042       vat_json_init_array (&vam->json_tree);
10043     }
10044   node = vat_json_array_add (&vam->json_tree);
10045
10046   vat_json_init_object (node);
10047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10048
10049   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10050   vat_json_object_add_ip6 (node, "host", ip6);
10051 }
10052
10053 static int
10054 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10058   u32 sw_if_index;
10059   u8 sw_if_index_set = 0;
10060   u32 address_length = 0;
10061   u8 v6_address_set = 0;
10062   ip6_address_t v6address;
10063   u8 use_default = 0;
10064   u8 no_advertise = 0;
10065   u8 off_link = 0;
10066   u8 no_autoconfig = 0;
10067   u8 no_onlink = 0;
10068   u8 is_no = 0;
10069   u32 val_lifetime = 0;
10070   u32 pref_lifetime = 0;
10071   int ret;
10072
10073   /* Parse args required to build the message */
10074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10075     {
10076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10079         sw_if_index_set = 1;
10080       else if (unformat (i, "%U/%d",
10081                          unformat_ip6_address, &v6address, &address_length))
10082         v6_address_set = 1;
10083       else if (unformat (i, "val_life %d", &val_lifetime))
10084         ;
10085       else if (unformat (i, "pref_life %d", &pref_lifetime))
10086         ;
10087       else if (unformat (i, "def"))
10088         use_default = 1;
10089       else if (unformat (i, "noadv"))
10090         no_advertise = 1;
10091       else if (unformat (i, "offl"))
10092         off_link = 1;
10093       else if (unformat (i, "noauto"))
10094         no_autoconfig = 1;
10095       else if (unformat (i, "nolink"))
10096         no_onlink = 1;
10097       else if (unformat (i, "isno"))
10098         is_no = 1;
10099       else
10100         {
10101           clib_warning ("parse error '%U'", format_unformat_error, i);
10102           return -99;
10103         }
10104     }
10105
10106   if (sw_if_index_set == 0)
10107     {
10108       errmsg ("missing interface name or sw_if_index");
10109       return -99;
10110     }
10111   if (!v6_address_set)
10112     {
10113       errmsg ("no address set");
10114       return -99;
10115     }
10116
10117   /* Construct the API message */
10118   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10122   mp->address_length = address_length;
10123   mp->use_default = use_default;
10124   mp->no_advertise = no_advertise;
10125   mp->off_link = off_link;
10126   mp->no_autoconfig = no_autoconfig;
10127   mp->no_onlink = no_onlink;
10128   mp->is_no = is_no;
10129   mp->val_lifetime = ntohl (val_lifetime);
10130   mp->pref_lifetime = ntohl (pref_lifetime);
10131
10132   /* send it... */
10133   S (mp);
10134
10135   /* Wait for a reply, return good/bad news  */
10136   W (ret);
10137   return ret;
10138 }
10139
10140 static int
10141 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10145   u32 sw_if_index;
10146   u8 sw_if_index_set = 0;
10147   u8 suppress = 0;
10148   u8 managed = 0;
10149   u8 other = 0;
10150   u8 ll_option = 0;
10151   u8 send_unicast = 0;
10152   u8 cease = 0;
10153   u8 is_no = 0;
10154   u8 default_router = 0;
10155   u32 max_interval = 0;
10156   u32 min_interval = 0;
10157   u32 lifetime = 0;
10158   u32 initial_count = 0;
10159   u32 initial_interval = 0;
10160   int ret;
10161
10162
10163   /* Parse args required to build the message */
10164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169         sw_if_index_set = 1;
10170       else if (unformat (i, "maxint %d", &max_interval))
10171         ;
10172       else if (unformat (i, "minint %d", &min_interval))
10173         ;
10174       else if (unformat (i, "life %d", &lifetime))
10175         ;
10176       else if (unformat (i, "count %d", &initial_count))
10177         ;
10178       else if (unformat (i, "interval %d", &initial_interval))
10179         ;
10180       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10181         suppress = 1;
10182       else if (unformat (i, "managed"))
10183         managed = 1;
10184       else if (unformat (i, "other"))
10185         other = 1;
10186       else if (unformat (i, "ll"))
10187         ll_option = 1;
10188       else if (unformat (i, "send"))
10189         send_unicast = 1;
10190       else if (unformat (i, "cease"))
10191         cease = 1;
10192       else if (unformat (i, "isno"))
10193         is_no = 1;
10194       else if (unformat (i, "def"))
10195         default_router = 1;
10196       else
10197         {
10198           clib_warning ("parse error '%U'", format_unformat_error, i);
10199           return -99;
10200         }
10201     }
10202
10203   if (sw_if_index_set == 0)
10204     {
10205       errmsg ("missing interface name or sw_if_index");
10206       return -99;
10207     }
10208
10209   /* Construct the API message */
10210   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10211
10212   mp->sw_if_index = ntohl (sw_if_index);
10213   mp->max_interval = ntohl (max_interval);
10214   mp->min_interval = ntohl (min_interval);
10215   mp->lifetime = ntohl (lifetime);
10216   mp->initial_count = ntohl (initial_count);
10217   mp->initial_interval = ntohl (initial_interval);
10218   mp->suppress = suppress;
10219   mp->managed = managed;
10220   mp->other = other;
10221   mp->ll_option = ll_option;
10222   mp->send_unicast = send_unicast;
10223   mp->cease = cease;
10224   mp->is_no = is_no;
10225   mp->default_router = default_router;
10226
10227   /* send it... */
10228   S (mp);
10229
10230   /* Wait for a reply, return good/bad news  */
10231   W (ret);
10232   return ret;
10233 }
10234
10235 static int
10236 api_set_arp_neighbor_limit (vat_main_t * vam)
10237 {
10238   unformat_input_t *i = vam->input;
10239   vl_api_set_arp_neighbor_limit_t *mp;
10240   u32 arp_nbr_limit;
10241   u8 limit_set = 0;
10242   u8 is_ipv6 = 0;
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10248         limit_set = 1;
10249       else if (unformat (i, "ipv6"))
10250         is_ipv6 = 1;
10251       else
10252         {
10253           clib_warning ("parse error '%U'", format_unformat_error, i);
10254           return -99;
10255         }
10256     }
10257
10258   if (limit_set == 0)
10259     {
10260       errmsg ("missing limit value");
10261       return -99;
10262     }
10263
10264   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10265
10266   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10267   mp->is_ipv6 = is_ipv6;
10268
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_l2_patch_add_del (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_l2_patch_add_del_t *mp;
10279   u32 rx_sw_if_index;
10280   u8 rx_sw_if_index_set = 0;
10281   u32 tx_sw_if_index;
10282   u8 tx_sw_if_index_set = 0;
10283   u8 is_add = 1;
10284   int ret;
10285
10286   /* Parse args required to build the message */
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10290         rx_sw_if_index_set = 1;
10291       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10292         tx_sw_if_index_set = 1;
10293       else if (unformat (i, "rx"))
10294         {
10295           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10296             {
10297               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10298                             &rx_sw_if_index))
10299                 rx_sw_if_index_set = 1;
10300             }
10301           else
10302             break;
10303         }
10304       else if (unformat (i, "tx"))
10305         {
10306           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307             {
10308               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10309                             &tx_sw_if_index))
10310                 tx_sw_if_index_set = 1;
10311             }
10312           else
10313             break;
10314         }
10315       else if (unformat (i, "del"))
10316         is_add = 0;
10317       else
10318         break;
10319     }
10320
10321   if (rx_sw_if_index_set == 0)
10322     {
10323       errmsg ("missing rx interface name or rx_sw_if_index");
10324       return -99;
10325     }
10326
10327   if (tx_sw_if_index_set == 0)
10328     {
10329       errmsg ("missing tx interface name or tx_sw_if_index");
10330       return -99;
10331     }
10332
10333   M (L2_PATCH_ADD_DEL, mp);
10334
10335   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10336   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10337   mp->is_add = is_add;
10338
10339   S (mp);
10340   W (ret);
10341   return ret;
10342 }
10343
10344 u8 is_del;
10345 u8 localsid_addr[16];
10346 u8 end_psp;
10347 u8 behavior;
10348 u32 sw_if_index;
10349 u32 vlan_index;
10350 u32 fib_table;
10351 u8 nh_addr[16];
10352
10353 static int
10354 api_sr_localsid_add_del (vat_main_t * vam)
10355 {
10356   unformat_input_t *i = vam->input;
10357   vl_api_sr_localsid_add_del_t *mp;
10358
10359   u8 is_del;
10360   ip6_address_t localsid;
10361   u8 end_psp = 0;
10362   u8 behavior = ~0;
10363   u32 sw_if_index;
10364   u32 fib_table = ~(u32) 0;
10365   ip6_address_t next_hop;
10366
10367   bool nexthop_set = 0;
10368
10369   int ret;
10370
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "del"))
10374         is_del = 1;
10375       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10376       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10377         nexthop_set = 1;
10378       else if (unformat (i, "behavior %u", &behavior));
10379       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10380       else if (unformat (i, "fib-table %u", &fib_table));
10381       else if (unformat (i, "end.psp %u", &behavior));
10382       else
10383         break;
10384     }
10385
10386   M (SR_LOCALSID_ADD_DEL, mp);
10387
10388   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10389   if (nexthop_set)
10390     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10391   mp->behavior = behavior;
10392   mp->sw_if_index = ntohl (sw_if_index);
10393   mp->fib_table = ntohl (fib_table);
10394   mp->end_psp = end_psp;
10395   mp->is_del = is_del;
10396
10397   S (mp);
10398   W (ret);
10399   return ret;
10400 }
10401
10402 static int
10403 api_ioam_enable (vat_main_t * vam)
10404 {
10405   unformat_input_t *input = vam->input;
10406   vl_api_ioam_enable_t *mp;
10407   u32 id = 0;
10408   int has_trace_option = 0;
10409   int has_pot_option = 0;
10410   int has_seqno_option = 0;
10411   int has_analyse_option = 0;
10412   int ret;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "trace"))
10417         has_trace_option = 1;
10418       else if (unformat (input, "pot"))
10419         has_pot_option = 1;
10420       else if (unformat (input, "seqno"))
10421         has_seqno_option = 1;
10422       else if (unformat (input, "analyse"))
10423         has_analyse_option = 1;
10424       else
10425         break;
10426     }
10427   M (IOAM_ENABLE, mp);
10428   mp->id = htons (id);
10429   mp->seqno = has_seqno_option;
10430   mp->analyse = has_analyse_option;
10431   mp->pot_enable = has_pot_option;
10432   mp->trace_enable = has_trace_option;
10433
10434   S (mp);
10435   W (ret);
10436   return ret;
10437 }
10438
10439
10440 static int
10441 api_ioam_disable (vat_main_t * vam)
10442 {
10443   vl_api_ioam_disable_t *mp;
10444   int ret;
10445
10446   M (IOAM_DISABLE, mp);
10447   S (mp);
10448   W (ret);
10449   return ret;
10450 }
10451
10452 #define foreach_tcp_proto_field                 \
10453 _(src_port)                                     \
10454 _(dst_port)
10455
10456 #define foreach_udp_proto_field                 \
10457 _(src_port)                                     \
10458 _(dst_port)
10459
10460 #define foreach_ip4_proto_field                 \
10461 _(src_address)                                  \
10462 _(dst_address)                                  \
10463 _(tos)                                          \
10464 _(length)                                       \
10465 _(fragment_id)                                  \
10466 _(ttl)                                          \
10467 _(protocol)                                     \
10468 _(checksum)
10469
10470 typedef struct
10471 {
10472   u16 src_port, dst_port;
10473 } tcpudp_header_t;
10474
10475 #if VPP_API_TEST_BUILTIN == 0
10476 uword
10477 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10478 {
10479   u8 **maskp = va_arg (*args, u8 **);
10480   u8 *mask = 0;
10481   u8 found_something = 0;
10482   tcp_header_t *tcp;
10483
10484 #define _(a) u8 a=0;
10485   foreach_tcp_proto_field;
10486 #undef _
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (0);
10491 #define _(a) else if (unformat (input, #a)) a=1;
10492       foreach_tcp_proto_field
10493 #undef _
10494         else
10495         break;
10496     }
10497
10498 #define _(a) found_something += a;
10499   foreach_tcp_proto_field;
10500 #undef _
10501
10502   if (found_something == 0)
10503     return 0;
10504
10505   vec_validate (mask, sizeof (*tcp) - 1);
10506
10507   tcp = (tcp_header_t *) mask;
10508
10509 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10510   foreach_tcp_proto_field;
10511 #undef _
10512
10513   *maskp = mask;
10514   return 1;
10515 }
10516
10517 uword
10518 unformat_udp_mask (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **maskp = va_arg (*args, u8 **);
10521   u8 *mask = 0;
10522   u8 found_something = 0;
10523   udp_header_t *udp;
10524
10525 #define _(a) u8 a=0;
10526   foreach_udp_proto_field;
10527 #undef _
10528
10529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10530     {
10531       if (0);
10532 #define _(a) else if (unformat (input, #a)) a=1;
10533       foreach_udp_proto_field
10534 #undef _
10535         else
10536         break;
10537     }
10538
10539 #define _(a) found_something += a;
10540   foreach_udp_proto_field;
10541 #undef _
10542
10543   if (found_something == 0)
10544     return 0;
10545
10546   vec_validate (mask, sizeof (*udp) - 1);
10547
10548   udp = (udp_header_t *) mask;
10549
10550 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10551   foreach_udp_proto_field;
10552 #undef _
10553
10554   *maskp = mask;
10555   return 1;
10556 }
10557
10558 uword
10559 unformat_l4_mask (unformat_input_t * input, va_list * args)
10560 {
10561   u8 **maskp = va_arg (*args, u8 **);
10562   u16 src_port = 0, dst_port = 0;
10563   tcpudp_header_t *tcpudp;
10564
10565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10568         return 1;
10569       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10570         return 1;
10571       else if (unformat (input, "src_port"))
10572         src_port = 0xFFFF;
10573       else if (unformat (input, "dst_port"))
10574         dst_port = 0xFFFF;
10575       else
10576         return 0;
10577     }
10578
10579   if (!src_port && !dst_port)
10580     return 0;
10581
10582   u8 *mask = 0;
10583   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10584
10585   tcpudp = (tcpudp_header_t *) mask;
10586   tcpudp->src_port = src_port;
10587   tcpudp->dst_port = dst_port;
10588
10589   *maskp = mask;
10590
10591   return 1;
10592 }
10593
10594 uword
10595 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10596 {
10597   u8 **maskp = va_arg (*args, u8 **);
10598   u8 *mask = 0;
10599   u8 found_something = 0;
10600   ip4_header_t *ip;
10601
10602 #define _(a) u8 a=0;
10603   foreach_ip4_proto_field;
10604 #undef _
10605   u8 version = 0;
10606   u8 hdr_length = 0;
10607
10608
10609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (input, "version"))
10612         version = 1;
10613       else if (unformat (input, "hdr_length"))
10614         hdr_length = 1;
10615       else if (unformat (input, "src"))
10616         src_address = 1;
10617       else if (unformat (input, "dst"))
10618         dst_address = 1;
10619       else if (unformat (input, "proto"))
10620         protocol = 1;
10621
10622 #define _(a) else if (unformat (input, #a)) a=1;
10623       foreach_ip4_proto_field
10624 #undef _
10625         else
10626         break;
10627     }
10628
10629 #define _(a) found_something += a;
10630   foreach_ip4_proto_field;
10631 #undef _
10632
10633   if (found_something == 0)
10634     return 0;
10635
10636   vec_validate (mask, sizeof (*ip) - 1);
10637
10638   ip = (ip4_header_t *) mask;
10639
10640 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10641   foreach_ip4_proto_field;
10642 #undef _
10643
10644   ip->ip_version_and_header_length = 0;
10645
10646   if (version)
10647     ip->ip_version_and_header_length |= 0xF0;
10648
10649   if (hdr_length)
10650     ip->ip_version_and_header_length |= 0x0F;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 #define foreach_ip6_proto_field                 \
10657 _(src_address)                                  \
10658 _(dst_address)                                  \
10659 _(payload_length)                               \
10660 _(hop_limit)                                    \
10661 _(protocol)
10662
10663 uword
10664 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10665 {
10666   u8 **maskp = va_arg (*args, u8 **);
10667   u8 *mask = 0;
10668   u8 found_something = 0;
10669   ip6_header_t *ip;
10670   u32 ip_version_traffic_class_and_flow_label;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip6_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 traffic_class = 0;
10677   u8 flow_label = 0;
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "traffic-class"))
10684         traffic_class = 1;
10685       else if (unformat (input, "flow-label"))
10686         flow_label = 1;
10687       else if (unformat (input, "src"))
10688         src_address = 1;
10689       else if (unformat (input, "dst"))
10690         dst_address = 1;
10691       else if (unformat (input, "proto"))
10692         protocol = 1;
10693
10694 #define _(a) else if (unformat (input, #a)) a=1;
10695       foreach_ip6_proto_field
10696 #undef _
10697         else
10698         break;
10699     }
10700
10701 #define _(a) found_something += a;
10702   foreach_ip6_proto_field;
10703 #undef _
10704
10705   if (found_something == 0)
10706     return 0;
10707
10708   vec_validate (mask, sizeof (*ip) - 1);
10709
10710   ip = (ip6_header_t *) mask;
10711
10712 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10713   foreach_ip6_proto_field;
10714 #undef _
10715
10716   ip_version_traffic_class_and_flow_label = 0;
10717
10718   if (version)
10719     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10720
10721   if (traffic_class)
10722     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10723
10724   if (flow_label)
10725     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10726
10727   ip->ip_version_traffic_class_and_flow_label =
10728     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10729
10730   *maskp = mask;
10731   return 1;
10732 }
10733
10734 uword
10735 unformat_l3_mask (unformat_input_t * input, va_list * args)
10736 {
10737   u8 **maskp = va_arg (*args, u8 **);
10738
10739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10742         return 1;
10743       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10744         return 1;
10745       else
10746         break;
10747     }
10748   return 0;
10749 }
10750
10751 uword
10752 unformat_l2_mask (unformat_input_t * input, va_list * args)
10753 {
10754   u8 **maskp = va_arg (*args, u8 **);
10755   u8 *mask = 0;
10756   u8 src = 0;
10757   u8 dst = 0;
10758   u8 proto = 0;
10759   u8 tag1 = 0;
10760   u8 tag2 = 0;
10761   u8 ignore_tag1 = 0;
10762   u8 ignore_tag2 = 0;
10763   u8 cos1 = 0;
10764   u8 cos2 = 0;
10765   u8 dot1q = 0;
10766   u8 dot1ad = 0;
10767   int len = 14;
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "src"))
10772         src = 1;
10773       else if (unformat (input, "dst"))
10774         dst = 1;
10775       else if (unformat (input, "proto"))
10776         proto = 1;
10777       else if (unformat (input, "tag1"))
10778         tag1 = 1;
10779       else if (unformat (input, "tag2"))
10780         tag2 = 1;
10781       else if (unformat (input, "ignore-tag1"))
10782         ignore_tag1 = 1;
10783       else if (unformat (input, "ignore-tag2"))
10784         ignore_tag2 = 1;
10785       else if (unformat (input, "cos1"))
10786         cos1 = 1;
10787       else if (unformat (input, "cos2"))
10788         cos2 = 1;
10789       else if (unformat (input, "dot1q"))
10790         dot1q = 1;
10791       else if (unformat (input, "dot1ad"))
10792         dot1ad = 1;
10793       else
10794         break;
10795     }
10796   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10797        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10798     return 0;
10799
10800   if (tag1 || ignore_tag1 || cos1 || dot1q)
10801     len = 18;
10802   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10803     len = 22;
10804
10805   vec_validate (mask, len - 1);
10806
10807   if (dst)
10808     memset (mask, 0xff, 6);
10809
10810   if (src)
10811     memset (mask + 6, 0xff, 6);
10812
10813   if (tag2 || dot1ad)
10814     {
10815       /* inner vlan tag */
10816       if (tag2)
10817         {
10818           mask[19] = 0xff;
10819           mask[18] = 0x0f;
10820         }
10821       if (cos2)
10822         mask[18] |= 0xe0;
10823       if (proto)
10824         mask[21] = mask[20] = 0xff;
10825       if (tag1)
10826         {
10827           mask[15] = 0xff;
10828           mask[14] = 0x0f;
10829         }
10830       if (cos1)
10831         mask[14] |= 0xe0;
10832       *maskp = mask;
10833       return 1;
10834     }
10835   if (tag1 | dot1q)
10836     {
10837       if (tag1)
10838         {
10839           mask[15] = 0xff;
10840           mask[14] = 0x0f;
10841         }
10842       if (cos1)
10843         mask[14] |= 0xe0;
10844       if (proto)
10845         mask[16] = mask[17] = 0xff;
10846
10847       *maskp = mask;
10848       return 1;
10849     }
10850   if (cos2)
10851     mask[18] |= 0xe0;
10852   if (cos1)
10853     mask[14] |= 0xe0;
10854   if (proto)
10855     mask[12] = mask[13] = 0xff;
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_classify_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u32 *skipp = va_arg (*args, u32 *);
10866   u32 *matchp = va_arg (*args, u32 *);
10867   u32 match;
10868   u8 *mask = 0;
10869   u8 *l2 = 0;
10870   u8 *l3 = 0;
10871   u8 *l4 = 0;
10872   int i;
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10877         ;
10878       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10879         ;
10880       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10881         ;
10882       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10883         ;
10884       else
10885         break;
10886     }
10887
10888   if (l4 && !l3)
10889     {
10890       vec_free (mask);
10891       vec_free (l2);
10892       vec_free (l4);
10893       return 0;
10894     }
10895
10896   if (mask || l2 || l3 || l4)
10897     {
10898       if (l2 || l3 || l4)
10899         {
10900           /* "With a free Ethernet header in every package" */
10901           if (l2 == 0)
10902             vec_validate (l2, 13);
10903           mask = l2;
10904           if (vec_len (l3))
10905             {
10906               vec_append (mask, l3);
10907               vec_free (l3);
10908             }
10909           if (vec_len (l4))
10910             {
10911               vec_append (mask, l4);
10912               vec_free (l4);
10913             }
10914         }
10915
10916       /* Scan forward looking for the first significant mask octet */
10917       for (i = 0; i < vec_len (mask); i++)
10918         if (mask[i])
10919           break;
10920
10921       /* compute (skip, match) params */
10922       *skipp = i / sizeof (u32x4);
10923       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10924
10925       /* Pad mask to an even multiple of the vector size */
10926       while (vec_len (mask) % sizeof (u32x4))
10927         vec_add1 (mask, 0);
10928
10929       match = vec_len (mask) / sizeof (u32x4);
10930
10931       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10932         {
10933           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10934           if (*tmp || *(tmp + 1))
10935             break;
10936           match--;
10937         }
10938       if (match == 0)
10939         clib_warning ("BUG: match 0");
10940
10941       _vec_len (mask) = match * sizeof (u32x4);
10942
10943       *matchp = match;
10944       *maskp = mask;
10945
10946       return 1;
10947     }
10948
10949   return 0;
10950 }
10951 #endif /* VPP_API_TEST_BUILTIN */
10952
10953 #define foreach_l2_next                         \
10954 _(drop, DROP)                                   \
10955 _(ethernet, ETHERNET_INPUT)                     \
10956 _(ip4, IP4_INPUT)                               \
10957 _(ip6, IP6_INPUT)
10958
10959 uword
10960 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10961 {
10962   u32 *miss_next_indexp = va_arg (*args, u32 *);
10963   u32 next_index = 0;
10964   u32 tmp;
10965
10966 #define _(n,N) \
10967   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10968   foreach_l2_next;
10969 #undef _
10970
10971   if (unformat (input, "%d", &tmp))
10972     {
10973       next_index = tmp;
10974       goto out;
10975     }
10976
10977   return 0;
10978
10979 out:
10980   *miss_next_indexp = next_index;
10981   return 1;
10982 }
10983
10984 #define foreach_ip_next                         \
10985 _(drop, DROP)                                   \
10986 _(local, LOCAL)                                 \
10987 _(rewrite, REWRITE)
10988
10989 uword
10990 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10991 {
10992   u32 *miss_next_indexp = va_arg (*args, u32 *);
10993   u32 next_index = 0;
10994   u32 tmp;
10995
10996 #define _(n,N) \
10997   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10998   foreach_ip_next;
10999 #undef _
11000
11001   if (unformat (input, "%d", &tmp))
11002     {
11003       next_index = tmp;
11004       goto out;
11005     }
11006
11007   return 0;
11008
11009 out:
11010   *miss_next_indexp = next_index;
11011   return 1;
11012 }
11013
11014 #define foreach_acl_next                        \
11015 _(deny, DENY)
11016
11017 uword
11018 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11019 {
11020   u32 *miss_next_indexp = va_arg (*args, u32 *);
11021   u32 next_index = 0;
11022   u32 tmp;
11023
11024 #define _(n,N) \
11025   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11026   foreach_acl_next;
11027 #undef _
11028
11029   if (unformat (input, "permit"))
11030     {
11031       next_index = ~0;
11032       goto out;
11033     }
11034   else if (unformat (input, "%d", &tmp))
11035     {
11036       next_index = tmp;
11037       goto out;
11038     }
11039
11040   return 0;
11041
11042 out:
11043   *miss_next_indexp = next_index;
11044   return 1;
11045 }
11046
11047 uword
11048 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *r = va_arg (*args, u32 *);
11051
11052   if (unformat (input, "conform-color"))
11053     *r = POLICE_CONFORM;
11054   else if (unformat (input, "exceed-color"))
11055     *r = POLICE_EXCEED;
11056   else
11057     return 0;
11058
11059   return 1;
11060 }
11061
11062 static int
11063 api_classify_add_del_table (vat_main_t * vam)
11064 {
11065   unformat_input_t *i = vam->input;
11066   vl_api_classify_add_del_table_t *mp;
11067
11068   u32 nbuckets = 2;
11069   u32 skip = ~0;
11070   u32 match = ~0;
11071   int is_add = 1;
11072   int del_chain = 0;
11073   u32 table_index = ~0;
11074   u32 next_table_index = ~0;
11075   u32 miss_next_index = ~0;
11076   u32 memory_size = 32 << 20;
11077   u8 *mask = 0;
11078   u32 current_data_flag = 0;
11079   int current_data_offset = 0;
11080   int ret;
11081
11082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11083     {
11084       if (unformat (i, "del"))
11085         is_add = 0;
11086       else if (unformat (i, "del-chain"))
11087         {
11088           is_add = 0;
11089           del_chain = 1;
11090         }
11091       else if (unformat (i, "buckets %d", &nbuckets))
11092         ;
11093       else if (unformat (i, "memory_size %d", &memory_size))
11094         ;
11095       else if (unformat (i, "skip %d", &skip))
11096         ;
11097       else if (unformat (i, "match %d", &match))
11098         ;
11099       else if (unformat (i, "table %d", &table_index))
11100         ;
11101       else if (unformat (i, "mask %U", unformat_classify_mask,
11102                          &mask, &skip, &match))
11103         ;
11104       else if (unformat (i, "next-table %d", &next_table_index))
11105         ;
11106       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11107                          &miss_next_index))
11108         ;
11109       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11110                          &miss_next_index))
11111         ;
11112       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11113                          &miss_next_index))
11114         ;
11115       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11116         ;
11117       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11118         ;
11119       else
11120         break;
11121     }
11122
11123   if (is_add && mask == 0)
11124     {
11125       errmsg ("Mask required");
11126       return -99;
11127     }
11128
11129   if (is_add && skip == ~0)
11130     {
11131       errmsg ("skip count required");
11132       return -99;
11133     }
11134
11135   if (is_add && match == ~0)
11136     {
11137       errmsg ("match count required");
11138       return -99;
11139     }
11140
11141   if (!is_add && table_index == ~0)
11142     {
11143       errmsg ("table index required for delete");
11144       return -99;
11145     }
11146
11147   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11148
11149   mp->is_add = is_add;
11150   mp->del_chain = del_chain;
11151   mp->table_index = ntohl (table_index);
11152   mp->nbuckets = ntohl (nbuckets);
11153   mp->memory_size = ntohl (memory_size);
11154   mp->skip_n_vectors = ntohl (skip);
11155   mp->match_n_vectors = ntohl (match);
11156   mp->next_table_index = ntohl (next_table_index);
11157   mp->miss_next_index = ntohl (miss_next_index);
11158   mp->current_data_flag = ntohl (current_data_flag);
11159   mp->current_data_offset = ntohl (current_data_offset);
11160   clib_memcpy (mp->mask, mask, vec_len (mask));
11161
11162   vec_free (mask);
11163
11164   S (mp);
11165   W (ret);
11166   return ret;
11167 }
11168
11169 #if VPP_API_TEST_BUILTIN == 0
11170 uword
11171 unformat_l4_match (unformat_input_t * input, va_list * args)
11172 {
11173   u8 **matchp = va_arg (*args, u8 **);
11174
11175   u8 *proto_header = 0;
11176   int src_port = 0;
11177   int dst_port = 0;
11178
11179   tcpudp_header_t h;
11180
11181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (input, "src_port %d", &src_port))
11184         ;
11185       else if (unformat (input, "dst_port %d", &dst_port))
11186         ;
11187       else
11188         return 0;
11189     }
11190
11191   h.src_port = clib_host_to_net_u16 (src_port);
11192   h.dst_port = clib_host_to_net_u16 (dst_port);
11193   vec_validate (proto_header, sizeof (h) - 1);
11194   memcpy (proto_header, &h, sizeof (h));
11195
11196   *matchp = proto_header;
11197
11198   return 1;
11199 }
11200
11201 uword
11202 unformat_ip4_match (unformat_input_t * input, va_list * args)
11203 {
11204   u8 **matchp = va_arg (*args, u8 **);
11205   u8 *match = 0;
11206   ip4_header_t *ip;
11207   int version = 0;
11208   u32 version_val;
11209   int hdr_length = 0;
11210   u32 hdr_length_val;
11211   int src = 0, dst = 0;
11212   ip4_address_t src_val, dst_val;
11213   int proto = 0;
11214   u32 proto_val;
11215   int tos = 0;
11216   u32 tos_val;
11217   int length = 0;
11218   u32 length_val;
11219   int fragment_id = 0;
11220   u32 fragment_id_val;
11221   int ttl = 0;
11222   int ttl_val;
11223   int checksum = 0;
11224   u32 checksum_val;
11225
11226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11227     {
11228       if (unformat (input, "version %d", &version_val))
11229         version = 1;
11230       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11231         hdr_length = 1;
11232       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11233         src = 1;
11234       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11235         dst = 1;
11236       else if (unformat (input, "proto %d", &proto_val))
11237         proto = 1;
11238       else if (unformat (input, "tos %d", &tos_val))
11239         tos = 1;
11240       else if (unformat (input, "length %d", &length_val))
11241         length = 1;
11242       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11243         fragment_id = 1;
11244       else if (unformat (input, "ttl %d", &ttl_val))
11245         ttl = 1;
11246       else if (unformat (input, "checksum %d", &checksum_val))
11247         checksum = 1;
11248       else
11249         break;
11250     }
11251
11252   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11253       + ttl + checksum == 0)
11254     return 0;
11255
11256   /*
11257    * Aligned because we use the real comparison functions
11258    */
11259   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11260
11261   ip = (ip4_header_t *) match;
11262
11263   /* These are realistically matched in practice */
11264   if (src)
11265     ip->src_address.as_u32 = src_val.as_u32;
11266
11267   if (dst)
11268     ip->dst_address.as_u32 = dst_val.as_u32;
11269
11270   if (proto)
11271     ip->protocol = proto_val;
11272
11273
11274   /* These are not, but they're included for completeness */
11275   if (version)
11276     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11277
11278   if (hdr_length)
11279     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11280
11281   if (tos)
11282     ip->tos = tos_val;
11283
11284   if (length)
11285     ip->length = clib_host_to_net_u16 (length_val);
11286
11287   if (ttl)
11288     ip->ttl = ttl_val;
11289
11290   if (checksum)
11291     ip->checksum = clib_host_to_net_u16 (checksum_val);
11292
11293   *matchp = match;
11294   return 1;
11295 }
11296
11297 uword
11298 unformat_ip6_match (unformat_input_t * input, va_list * args)
11299 {
11300   u8 **matchp = va_arg (*args, u8 **);
11301   u8 *match = 0;
11302   ip6_header_t *ip;
11303   int version = 0;
11304   u32 version_val;
11305   u8 traffic_class = 0;
11306   u32 traffic_class_val = 0;
11307   u8 flow_label = 0;
11308   u8 flow_label_val;
11309   int src = 0, dst = 0;
11310   ip6_address_t src_val, dst_val;
11311   int proto = 0;
11312   u32 proto_val;
11313   int payload_length = 0;
11314   u32 payload_length_val;
11315   int hop_limit = 0;
11316   int hop_limit_val;
11317   u32 ip_version_traffic_class_and_flow_label;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "version %d", &version_val))
11322         version = 1;
11323       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11324         traffic_class = 1;
11325       else if (unformat (input, "flow_label %d", &flow_label_val))
11326         flow_label = 1;
11327       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11328         src = 1;
11329       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11330         dst = 1;
11331       else if (unformat (input, "proto %d", &proto_val))
11332         proto = 1;
11333       else if (unformat (input, "payload_length %d", &payload_length_val))
11334         payload_length = 1;
11335       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11336         hop_limit = 1;
11337       else
11338         break;
11339     }
11340
11341   if (version + traffic_class + flow_label + src + dst + proto +
11342       payload_length + hop_limit == 0)
11343     return 0;
11344
11345   /*
11346    * Aligned because we use the real comparison functions
11347    */
11348   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11349
11350   ip = (ip6_header_t *) match;
11351
11352   if (src)
11353     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11354
11355   if (dst)
11356     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11357
11358   if (proto)
11359     ip->protocol = proto_val;
11360
11361   ip_version_traffic_class_and_flow_label = 0;
11362
11363   if (version)
11364     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11365
11366   if (traffic_class)
11367     ip_version_traffic_class_and_flow_label |=
11368       (traffic_class_val & 0xFF) << 20;
11369
11370   if (flow_label)
11371     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11372
11373   ip->ip_version_traffic_class_and_flow_label =
11374     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11375
11376   if (payload_length)
11377     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11378
11379   if (hop_limit)
11380     ip->hop_limit = hop_limit_val;
11381
11382   *matchp = match;
11383   return 1;
11384 }
11385
11386 uword
11387 unformat_l3_match (unformat_input_t * input, va_list * args)
11388 {
11389   u8 **matchp = va_arg (*args, u8 **);
11390
11391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11394         return 1;
11395       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11396         return 1;
11397       else
11398         break;
11399     }
11400   return 0;
11401 }
11402
11403 uword
11404 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11405 {
11406   u8 *tagp = va_arg (*args, u8 *);
11407   u32 tag;
11408
11409   if (unformat (input, "%d", &tag))
11410     {
11411       tagp[0] = (tag >> 8) & 0x0F;
11412       tagp[1] = tag & 0xFF;
11413       return 1;
11414     }
11415
11416   return 0;
11417 }
11418
11419 uword
11420 unformat_l2_match (unformat_input_t * input, va_list * args)
11421 {
11422   u8 **matchp = va_arg (*args, u8 **);
11423   u8 *match = 0;
11424   u8 src = 0;
11425   u8 src_val[6];
11426   u8 dst = 0;
11427   u8 dst_val[6];
11428   u8 proto = 0;
11429   u16 proto_val;
11430   u8 tag1 = 0;
11431   u8 tag1_val[2];
11432   u8 tag2 = 0;
11433   u8 tag2_val[2];
11434   int len = 14;
11435   u8 ignore_tag1 = 0;
11436   u8 ignore_tag2 = 0;
11437   u8 cos1 = 0;
11438   u8 cos2 = 0;
11439   u32 cos1_val = 0;
11440   u32 cos2_val = 0;
11441
11442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11445         src = 1;
11446       else
11447         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11448         dst = 1;
11449       else if (unformat (input, "proto %U",
11450                          unformat_ethernet_type_host_byte_order, &proto_val))
11451         proto = 1;
11452       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11453         tag1 = 1;
11454       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11455         tag2 = 1;
11456       else if (unformat (input, "ignore-tag1"))
11457         ignore_tag1 = 1;
11458       else if (unformat (input, "ignore-tag2"))
11459         ignore_tag2 = 1;
11460       else if (unformat (input, "cos1 %d", &cos1_val))
11461         cos1 = 1;
11462       else if (unformat (input, "cos2 %d", &cos2_val))
11463         cos2 = 1;
11464       else
11465         break;
11466     }
11467   if ((src + dst + proto + tag1 + tag2 +
11468        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11469     return 0;
11470
11471   if (tag1 || ignore_tag1 || cos1)
11472     len = 18;
11473   if (tag2 || ignore_tag2 || cos2)
11474     len = 22;
11475
11476   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11477
11478   if (dst)
11479     clib_memcpy (match, dst_val, 6);
11480
11481   if (src)
11482     clib_memcpy (match + 6, src_val, 6);
11483
11484   if (tag2)
11485     {
11486       /* inner vlan tag */
11487       match[19] = tag2_val[1];
11488       match[18] = tag2_val[0];
11489       if (cos2)
11490         match[18] |= (cos2_val & 0x7) << 5;
11491       if (proto)
11492         {
11493           match[21] = proto_val & 0xff;
11494           match[20] = proto_val >> 8;
11495         }
11496       if (tag1)
11497         {
11498           match[15] = tag1_val[1];
11499           match[14] = tag1_val[0];
11500         }
11501       if (cos1)
11502         match[14] |= (cos1_val & 0x7) << 5;
11503       *matchp = match;
11504       return 1;
11505     }
11506   if (tag1)
11507     {
11508       match[15] = tag1_val[1];
11509       match[14] = tag1_val[0];
11510       if (proto)
11511         {
11512           match[17] = proto_val & 0xff;
11513           match[16] = proto_val >> 8;
11514         }
11515       if (cos1)
11516         match[14] |= (cos1_val & 0x7) << 5;
11517
11518       *matchp = match;
11519       return 1;
11520     }
11521   if (cos2)
11522     match[18] |= (cos2_val & 0x7) << 5;
11523   if (cos1)
11524     match[14] |= (cos1_val & 0x7) << 5;
11525   if (proto)
11526     {
11527       match[13] = proto_val & 0xff;
11528       match[12] = proto_val >> 8;
11529     }
11530
11531   *matchp = match;
11532   return 1;
11533 }
11534 #endif
11535
11536 uword
11537 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11538 {
11539   u8 **matchp = va_arg (*args, u8 **);
11540   u32 skip_n_vectors = va_arg (*args, u32);
11541   u32 match_n_vectors = va_arg (*args, u32);
11542
11543   u8 *match = 0;
11544   u8 *l2 = 0;
11545   u8 *l3 = 0;
11546   u8 *l4 = 0;
11547
11548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (input, "hex %U", unformat_hex_string, &match))
11551         ;
11552       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11553         ;
11554       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11555         ;
11556       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11557         ;
11558       else
11559         break;
11560     }
11561
11562   if (l4 && !l3)
11563     {
11564       vec_free (match);
11565       vec_free (l2);
11566       vec_free (l4);
11567       return 0;
11568     }
11569
11570   if (match || l2 || l3 || l4)
11571     {
11572       if (l2 || l3 || l4)
11573         {
11574           /* "Win a free Ethernet header in every packet" */
11575           if (l2 == 0)
11576             vec_validate_aligned (l2, 13, sizeof (u32x4));
11577           match = l2;
11578           if (vec_len (l3))
11579             {
11580               vec_append_aligned (match, l3, sizeof (u32x4));
11581               vec_free (l3);
11582             }
11583           if (vec_len (l4))
11584             {
11585               vec_append_aligned (match, l4, sizeof (u32x4));
11586               vec_free (l4);
11587             }
11588         }
11589
11590       /* Make sure the vector is big enough even if key is all 0's */
11591       vec_validate_aligned
11592         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11593          sizeof (u32x4));
11594
11595       /* Set size, include skipped vectors */
11596       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11597
11598       *matchp = match;
11599
11600       return 1;
11601     }
11602
11603   return 0;
11604 }
11605
11606 static int
11607 api_classify_add_del_session (vat_main_t * vam)
11608 {
11609   unformat_input_t *i = vam->input;
11610   vl_api_classify_add_del_session_t *mp;
11611   int is_add = 1;
11612   u32 table_index = ~0;
11613   u32 hit_next_index = ~0;
11614   u32 opaque_index = ~0;
11615   u8 *match = 0;
11616   i32 advance = 0;
11617   u32 skip_n_vectors = 0;
11618   u32 match_n_vectors = 0;
11619   u32 action = 0;
11620   u32 metadata = 0;
11621   int ret;
11622
11623   /*
11624    * Warning: you have to supply skip_n and match_n
11625    * because the API client cant simply look at the classify
11626    * table object.
11627    */
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "del"))
11632         is_add = 0;
11633       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11634                          &hit_next_index))
11635         ;
11636       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11637                          &hit_next_index))
11638         ;
11639       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11640                          &hit_next_index))
11641         ;
11642       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11643         ;
11644       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11645         ;
11646       else if (unformat (i, "opaque-index %d", &opaque_index))
11647         ;
11648       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11649         ;
11650       else if (unformat (i, "match_n %d", &match_n_vectors))
11651         ;
11652       else if (unformat (i, "match %U", api_unformat_classify_match,
11653                          &match, skip_n_vectors, match_n_vectors))
11654         ;
11655       else if (unformat (i, "advance %d", &advance))
11656         ;
11657       else if (unformat (i, "table-index %d", &table_index))
11658         ;
11659       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11660         action = 1;
11661       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11662         action = 2;
11663       else if (unformat (i, "action %d", &action))
11664         ;
11665       else if (unformat (i, "metadata %d", &metadata))
11666         ;
11667       else
11668         break;
11669     }
11670
11671   if (table_index == ~0)
11672     {
11673       errmsg ("Table index required");
11674       return -99;
11675     }
11676
11677   if (is_add && match == 0)
11678     {
11679       errmsg ("Match value required");
11680       return -99;
11681     }
11682
11683   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11684
11685   mp->is_add = is_add;
11686   mp->table_index = ntohl (table_index);
11687   mp->hit_next_index = ntohl (hit_next_index);
11688   mp->opaque_index = ntohl (opaque_index);
11689   mp->advance = ntohl (advance);
11690   mp->action = action;
11691   mp->metadata = ntohl (metadata);
11692   clib_memcpy (mp->match, match, vec_len (match));
11693   vec_free (match);
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_classify_set_interface_ip_table (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_classify_set_interface_ip_table_t *mp;
11705   u32 sw_if_index;
11706   int sw_if_index_set;
11707   u32 table_index = ~0;
11708   u8 is_ipv6 = 0;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "table %d", &table_index))
11718         ;
11719       else
11720         {
11721           clib_warning ("parse error '%U'", format_unformat_error, i);
11722           return -99;
11723         }
11724     }
11725
11726   if (sw_if_index_set == 0)
11727     {
11728       errmsg ("missing interface name or sw_if_index");
11729       return -99;
11730     }
11731
11732
11733   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11734
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->table_index = ntohl (table_index);
11737   mp->is_ipv6 = is_ipv6;
11738
11739   S (mp);
11740   W (ret);
11741   return ret;
11742 }
11743
11744 static int
11745 api_classify_set_interface_l2_tables (vat_main_t * vam)
11746 {
11747   unformat_input_t *i = vam->input;
11748   vl_api_classify_set_interface_l2_tables_t *mp;
11749   u32 sw_if_index;
11750   int sw_if_index_set;
11751   u32 ip4_table_index = ~0;
11752   u32 ip6_table_index = ~0;
11753   u32 other_table_index = ~0;
11754   u32 is_input = 1;
11755   int ret;
11756
11757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11758     {
11759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11762         sw_if_index_set = 1;
11763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11764         ;
11765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11766         ;
11767       else if (unformat (i, "other-table %d", &other_table_index))
11768         ;
11769       else if (unformat (i, "is-input %d", &is_input))
11770         ;
11771       else
11772         {
11773           clib_warning ("parse error '%U'", format_unformat_error, i);
11774           return -99;
11775         }
11776     }
11777
11778   if (sw_if_index_set == 0)
11779     {
11780       errmsg ("missing interface name or sw_if_index");
11781       return -99;
11782     }
11783
11784
11785   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11786
11787   mp->sw_if_index = ntohl (sw_if_index);
11788   mp->ip4_table_index = ntohl (ip4_table_index);
11789   mp->ip6_table_index = ntohl (ip6_table_index);
11790   mp->other_table_index = ntohl (other_table_index);
11791   mp->is_input = (u8) is_input;
11792
11793   S (mp);
11794   W (ret);
11795   return ret;
11796 }
11797
11798 static int
11799 api_set_ipfix_exporter (vat_main_t * vam)
11800 {
11801   unformat_input_t *i = vam->input;
11802   vl_api_set_ipfix_exporter_t *mp;
11803   ip4_address_t collector_address;
11804   u8 collector_address_set = 0;
11805   u32 collector_port = ~0;
11806   ip4_address_t src_address;
11807   u8 src_address_set = 0;
11808   u32 vrf_id = ~0;
11809   u32 path_mtu = ~0;
11810   u32 template_interval = ~0;
11811   u8 udp_checksum = 0;
11812   int ret;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "collector_address %U", unformat_ip4_address,
11817                     &collector_address))
11818         collector_address_set = 1;
11819       else if (unformat (i, "collector_port %d", &collector_port))
11820         ;
11821       else if (unformat (i, "src_address %U", unformat_ip4_address,
11822                          &src_address))
11823         src_address_set = 1;
11824       else if (unformat (i, "vrf_id %d", &vrf_id))
11825         ;
11826       else if (unformat (i, "path_mtu %d", &path_mtu))
11827         ;
11828       else if (unformat (i, "template_interval %d", &template_interval))
11829         ;
11830       else if (unformat (i, "udp_checksum"))
11831         udp_checksum = 1;
11832       else
11833         break;
11834     }
11835
11836   if (collector_address_set == 0)
11837     {
11838       errmsg ("collector_address required");
11839       return -99;
11840     }
11841
11842   if (src_address_set == 0)
11843     {
11844       errmsg ("src_address required");
11845       return -99;
11846     }
11847
11848   M (SET_IPFIX_EXPORTER, mp);
11849
11850   memcpy (mp->collector_address, collector_address.data,
11851           sizeof (collector_address.data));
11852   mp->collector_port = htons ((u16) collector_port);
11853   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11854   mp->vrf_id = htonl (vrf_id);
11855   mp->path_mtu = htonl (path_mtu);
11856   mp->template_interval = htonl (template_interval);
11857   mp->udp_checksum = udp_checksum;
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_set_ipfix_classify_stream (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_set_ipfix_classify_stream_t *mp;
11869   u32 domain_id = 0;
11870   u32 src_port = UDP_DST_PORT_ipfix;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "domain %d", &domain_id))
11876         ;
11877       else if (unformat (i, "src_port %d", &src_port))
11878         ;
11879       else
11880         {
11881           errmsg ("unknown input `%U'", format_unformat_error, i);
11882           return -99;
11883         }
11884     }
11885
11886   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11887
11888   mp->domain_id = htonl (domain_id);
11889   mp->src_port = htons ((u16) src_port);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_ipfix_classify_table_add_del (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_ipfix_classify_table_add_del_t *mp;
11901   int is_add = -1;
11902   u32 classify_table_index = ~0;
11903   u8 ip_version = 0;
11904   u8 transport_protocol = 255;
11905   int ret;
11906
11907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11908     {
11909       if (unformat (i, "add"))
11910         is_add = 1;
11911       else if (unformat (i, "del"))
11912         is_add = 0;
11913       else if (unformat (i, "table %d", &classify_table_index))
11914         ;
11915       else if (unformat (i, "ip4"))
11916         ip_version = 4;
11917       else if (unformat (i, "ip6"))
11918         ip_version = 6;
11919       else if (unformat (i, "tcp"))
11920         transport_protocol = 6;
11921       else if (unformat (i, "udp"))
11922         transport_protocol = 17;
11923       else
11924         {
11925           errmsg ("unknown input `%U'", format_unformat_error, i);
11926           return -99;
11927         }
11928     }
11929
11930   if (is_add == -1)
11931     {
11932       errmsg ("expecting: add|del");
11933       return -99;
11934     }
11935   if (classify_table_index == ~0)
11936     {
11937       errmsg ("classifier table not specified");
11938       return -99;
11939     }
11940   if (ip_version == 0)
11941     {
11942       errmsg ("IP version not specified");
11943       return -99;
11944     }
11945
11946   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11947
11948   mp->is_add = is_add;
11949   mp->table_id = htonl (classify_table_index);
11950   mp->ip_version = ip_version;
11951   mp->transport_protocol = transport_protocol;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_get_node_index (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_get_node_index_t *mp;
11963   u8 *name = 0;
11964   int ret;
11965
11966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (i, "node %s", &name))
11969         ;
11970       else
11971         break;
11972     }
11973   if (name == 0)
11974     {
11975       errmsg ("node name required");
11976       return -99;
11977     }
11978   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11979     {
11980       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11981       return -99;
11982     }
11983
11984   M (GET_NODE_INDEX, mp);
11985   clib_memcpy (mp->node_name, name, vec_len (name));
11986   vec_free (name);
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993 static int
11994 api_get_next_index (vat_main_t * vam)
11995 {
11996   unformat_input_t *i = vam->input;
11997   vl_api_get_next_index_t *mp;
11998   u8 *node_name = 0, *next_node_name = 0;
11999   int ret;
12000
12001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (i, "node-name %s", &node_name))
12004         ;
12005       else if (unformat (i, "next-node-name %s", &next_node_name))
12006         break;
12007     }
12008
12009   if (node_name == 0)
12010     {
12011       errmsg ("node name required");
12012       return -99;
12013     }
12014   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12015     {
12016       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12017       return -99;
12018     }
12019
12020   if (next_node_name == 0)
12021     {
12022       errmsg ("next node name required");
12023       return -99;
12024     }
12025   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12026     {
12027       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12028       return -99;
12029     }
12030
12031   M (GET_NEXT_INDEX, mp);
12032   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12033   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12034   vec_free (node_name);
12035   vec_free (next_node_name);
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_add_node_next (vat_main_t * vam)
12044 {
12045   unformat_input_t *i = vam->input;
12046   vl_api_add_node_next_t *mp;
12047   u8 *name = 0;
12048   u8 *next = 0;
12049   int ret;
12050
12051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (i, "node %s", &name))
12054         ;
12055       else if (unformat (i, "next %s", &next))
12056         ;
12057       else
12058         break;
12059     }
12060   if (name == 0)
12061     {
12062       errmsg ("node name required");
12063       return -99;
12064     }
12065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12066     {
12067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12068       return -99;
12069     }
12070   if (next == 0)
12071     {
12072       errmsg ("next node required");
12073       return -99;
12074     }
12075   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12076     {
12077       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12078       return -99;
12079     }
12080
12081   M (ADD_NODE_NEXT, mp);
12082   clib_memcpy (mp->node_name, name, vec_len (name));
12083   clib_memcpy (mp->next_name, next, vec_len (next));
12084   vec_free (name);
12085   vec_free (next);
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_l2tpv3_create_tunnel (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   ip6_address_t client_address, our_address;
12097   int client_address_set = 0;
12098   int our_address_set = 0;
12099   u32 local_session_id = 0;
12100   u32 remote_session_id = 0;
12101   u64 local_cookie = 0;
12102   u64 remote_cookie = 0;
12103   u8 l2_sublayer_present = 0;
12104   vl_api_l2tpv3_create_tunnel_t *mp;
12105   int ret;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "client_address %U", unformat_ip6_address,
12110                     &client_address))
12111         client_address_set = 1;
12112       else if (unformat (i, "our_address %U", unformat_ip6_address,
12113                          &our_address))
12114         our_address_set = 1;
12115       else if (unformat (i, "local_session_id %d", &local_session_id))
12116         ;
12117       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12118         ;
12119       else if (unformat (i, "local_cookie %lld", &local_cookie))
12120         ;
12121       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12122         ;
12123       else if (unformat (i, "l2-sublayer-present"))
12124         l2_sublayer_present = 1;
12125       else
12126         break;
12127     }
12128
12129   if (client_address_set == 0)
12130     {
12131       errmsg ("client_address required");
12132       return -99;
12133     }
12134
12135   if (our_address_set == 0)
12136     {
12137       errmsg ("our_address required");
12138       return -99;
12139     }
12140
12141   M (L2TPV3_CREATE_TUNNEL, mp);
12142
12143   clib_memcpy (mp->client_address, client_address.as_u8,
12144                sizeof (mp->client_address));
12145
12146   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12147
12148   mp->local_session_id = ntohl (local_session_id);
12149   mp->remote_session_id = ntohl (remote_session_id);
12150   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12151   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12152   mp->l2_sublayer_present = l2_sublayer_present;
12153   mp->is_ipv6 = 1;
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   u32 sw_if_index;
12165   u8 sw_if_index_set = 0;
12166   u64 new_local_cookie = 0;
12167   u64 new_remote_cookie = 0;
12168   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12174         sw_if_index_set = 1;
12175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12178         ;
12179       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12180         ;
12181       else
12182         break;
12183     }
12184
12185   if (sw_if_index_set == 0)
12186     {
12187       errmsg ("missing interface name or sw_if_index");
12188       return -99;
12189     }
12190
12191   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12192
12193   mp->sw_if_index = ntohl (sw_if_index);
12194   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12195   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_l2tpv3_interface_enable_disable_t *mp;
12207   u32 sw_if_index;
12208   u8 sw_if_index_set = 0;
12209   u8 enable_disable = 1;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "enable"))
12219         enable_disable = 1;
12220       else if (unformat (i, "disable"))
12221         enable_disable = 0;
12222       else
12223         break;
12224     }
12225
12226   if (sw_if_index_set == 0)
12227     {
12228       errmsg ("missing interface name or sw_if_index");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12233
12234   mp->sw_if_index = ntohl (sw_if_index);
12235   mp->enable_disable = enable_disable;
12236
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 static int
12243 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12244 {
12245   unformat_input_t *i = vam->input;
12246   vl_api_l2tpv3_set_lookup_key_t *mp;
12247   u8 key = ~0;
12248   int ret;
12249
12250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12251     {
12252       if (unformat (i, "lookup_v6_src"))
12253         key = L2T_LOOKUP_SRC_ADDRESS;
12254       else if (unformat (i, "lookup_v6_dst"))
12255         key = L2T_LOOKUP_DST_ADDRESS;
12256       else if (unformat (i, "lookup_session_id"))
12257         key = L2T_LOOKUP_SESSION_ID;
12258       else
12259         break;
12260     }
12261
12262   if (key == (u8) ~ 0)
12263     {
12264       errmsg ("l2tp session lookup key unset");
12265       return -99;
12266     }
12267
12268   M (L2TPV3_SET_LOOKUP_KEY, mp);
12269
12270   mp->key = key;
12271
12272   S (mp);
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12278   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281
12282   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12283          format_ip6_address, mp->our_address,
12284          format_ip6_address, mp->client_address,
12285          clib_net_to_host_u32 (mp->sw_if_index));
12286
12287   print (vam->ofp,
12288          "   local cookies %016llx %016llx remote cookie %016llx",
12289          clib_net_to_host_u64 (mp->local_cookie[0]),
12290          clib_net_to_host_u64 (mp->local_cookie[1]),
12291          clib_net_to_host_u64 (mp->remote_cookie));
12292
12293   print (vam->ofp, "   local session-id %d remote session-id %d",
12294          clib_net_to_host_u32 (mp->local_session_id),
12295          clib_net_to_host_u32 (mp->remote_session_id));
12296
12297   print (vam->ofp, "   l2 specific sublayer %s\n",
12298          mp->l2_sublayer_present ? "preset" : "absent");
12299
12300 }
12301
12302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12304 {
12305   vat_main_t *vam = &vat_main;
12306   vat_json_node_t *node = NULL;
12307   struct in6_addr addr;
12308
12309   if (VAT_JSON_ARRAY != vam->json_tree.type)
12310     {
12311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12312       vat_json_init_array (&vam->json_tree);
12313     }
12314   node = vat_json_array_add (&vam->json_tree);
12315
12316   vat_json_init_object (node);
12317
12318   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12319   vat_json_object_add_ip6 (node, "our_address", addr);
12320   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12321   vat_json_object_add_ip6 (node, "client_address", addr);
12322
12323   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12324   vat_json_init_array (lc);
12325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12327   vat_json_object_add_uint (node, "remote_cookie",
12328                             clib_net_to_host_u64 (mp->remote_cookie));
12329
12330   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12331   vat_json_object_add_uint (node, "local_session_id",
12332                             clib_net_to_host_u32 (mp->local_session_id));
12333   vat_json_object_add_uint (node, "remote_session_id",
12334                             clib_net_to_host_u32 (mp->remote_session_id));
12335   vat_json_object_add_string_copy (node, "l2_sublayer",
12336                                    mp->l2_sublayer_present ? (u8 *) "present"
12337                                    : (u8 *) "absent");
12338 }
12339
12340 static int
12341 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12342 {
12343   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12344   vl_api_control_ping_t *mp_ping;
12345   int ret;
12346
12347   /* Get list of l2tpv3-tunnel interfaces */
12348   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12349   S (mp);
12350
12351   /* Use a control ping for synchronization */
12352   MPING (CONTROL_PING, mp_ping);
12353   S (mp_ping);
12354
12355   W (ret);
12356   return ret;
12357 }
12358
12359
12360 static void vl_api_sw_interface_tap_details_t_handler
12361   (vl_api_sw_interface_tap_details_t * mp)
12362 {
12363   vat_main_t *vam = &vat_main;
12364
12365   print (vam->ofp, "%-16s %d",
12366          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12367 }
12368
12369 static void vl_api_sw_interface_tap_details_t_handler_json
12370   (vl_api_sw_interface_tap_details_t * mp)
12371 {
12372   vat_main_t *vam = &vat_main;
12373   vat_json_node_t *node = NULL;
12374
12375   if (VAT_JSON_ARRAY != vam->json_tree.type)
12376     {
12377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12378       vat_json_init_array (&vam->json_tree);
12379     }
12380   node = vat_json_array_add (&vam->json_tree);
12381
12382   vat_json_init_object (node);
12383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12384   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12385 }
12386
12387 static int
12388 api_sw_interface_tap_dump (vat_main_t * vam)
12389 {
12390   vl_api_sw_interface_tap_dump_t *mp;
12391   vl_api_control_ping_t *mp_ping;
12392   int ret;
12393
12394   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12395   /* Get list of tap interfaces */
12396   M (SW_INTERFACE_TAP_DUMP, mp);
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   MPING (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static void vl_api_sw_interface_tap_v2_details_t_handler
12408   (vl_api_sw_interface_tap_v2_details_t * mp)
12409 {
12410   vat_main_t *vam = &vat_main;
12411
12412   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12413                     mp->host_ip4_prefix_len);
12414   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12415                     mp->host_ip6_prefix_len);
12416
12417   print (vam->ofp,
12418          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12419          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12420          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12421          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12422          mp->host_bridge, ip4, ip6);
12423
12424   vec_free (ip4);
12425   vec_free (ip6);
12426 }
12427
12428 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12429   (vl_api_sw_interface_tap_v2_details_t * mp)
12430 {
12431   vat_main_t *vam = &vat_main;
12432   vat_json_node_t *node = NULL;
12433
12434   if (VAT_JSON_ARRAY != vam->json_tree.type)
12435     {
12436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12437       vat_json_init_array (&vam->json_tree);
12438     }
12439   node = vat_json_array_add (&vam->json_tree);
12440
12441   vat_json_init_object (node);
12442   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12444   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12445   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12446   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12447   vat_json_object_add_string_copy (node, "host_mac_addr",
12448                                    format (0, "%U", format_ethernet_address,
12449                                            &mp->host_mac_addr));
12450   vat_json_object_add_string_copy (node, "host_namespace",
12451                                    mp->host_namespace);
12452   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12453   vat_json_object_add_string_copy (node, "host_ip4_addr",
12454                                    format (0, "%U/%d", format_ip4_address,
12455                                            mp->host_ip4_addr,
12456                                            mp->host_ip4_prefix_len));
12457   vat_json_object_add_string_copy (node, "host_ip6_addr",
12458                                    format (0, "%U/%d", format_ip6_address,
12459                                            mp->host_ip6_addr,
12460                                            mp->host_ip6_prefix_len));
12461
12462 }
12463
12464 static int
12465 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12466 {
12467   vl_api_sw_interface_tap_v2_dump_t *mp;
12468   vl_api_control_ping_t *mp_ping;
12469   int ret;
12470
12471   print (vam->ofp,
12472          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12473          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12474          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12475          "host_ip6_addr");
12476
12477   /* Get list of tap interfaces */
12478   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12479   S (mp);
12480
12481   /* Use a control ping for synchronization */
12482   MPING (CONTROL_PING, mp_ping);
12483   S (mp_ping);
12484
12485   W (ret);
12486   return ret;
12487 }
12488
12489 static uword unformat_vxlan_decap_next
12490   (unformat_input_t * input, va_list * args)
12491 {
12492   u32 *result = va_arg (*args, u32 *);
12493   u32 tmp;
12494
12495   if (unformat (input, "l2"))
12496     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12497   else if (unformat (input, "%d", &tmp))
12498     *result = tmp;
12499   else
12500     return 0;
12501   return 1;
12502 }
12503
12504 static int
12505 api_vxlan_add_del_tunnel (vat_main_t * vam)
12506 {
12507   unformat_input_t *line_input = vam->input;
12508   vl_api_vxlan_add_del_tunnel_t *mp;
12509   ip46_address_t src, dst;
12510   u8 is_add = 1;
12511   u8 ipv4_set = 0, ipv6_set = 0;
12512   u8 src_set = 0;
12513   u8 dst_set = 0;
12514   u8 grp_set = 0;
12515   u32 instance = ~0;
12516   u32 mcast_sw_if_index = ~0;
12517   u32 encap_vrf_id = 0;
12518   u32 decap_next_index = ~0;
12519   u32 vni = 0;
12520   int ret;
12521
12522   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12523   memset (&src, 0, sizeof src);
12524   memset (&dst, 0, sizeof dst);
12525
12526   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12527     {
12528       if (unformat (line_input, "del"))
12529         is_add = 0;
12530       else if (unformat (line_input, "instance %d", &instance))
12531         ;
12532       else
12533         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12534         {
12535           ipv4_set = 1;
12536           src_set = 1;
12537         }
12538       else
12539         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12540         {
12541           ipv4_set = 1;
12542           dst_set = 1;
12543         }
12544       else
12545         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12546         {
12547           ipv6_set = 1;
12548           src_set = 1;
12549         }
12550       else
12551         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12552         {
12553           ipv6_set = 1;
12554           dst_set = 1;
12555         }
12556       else if (unformat (line_input, "group %U %U",
12557                          unformat_ip4_address, &dst.ip4,
12558                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12559         {
12560           grp_set = dst_set = 1;
12561           ipv4_set = 1;
12562         }
12563       else if (unformat (line_input, "group %U",
12564                          unformat_ip4_address, &dst.ip4))
12565         {
12566           grp_set = dst_set = 1;
12567           ipv4_set = 1;
12568         }
12569       else if (unformat (line_input, "group %U %U",
12570                          unformat_ip6_address, &dst.ip6,
12571                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12572         {
12573           grp_set = dst_set = 1;
12574           ipv6_set = 1;
12575         }
12576       else if (unformat (line_input, "group %U",
12577                          unformat_ip6_address, &dst.ip6))
12578         {
12579           grp_set = dst_set = 1;
12580           ipv6_set = 1;
12581         }
12582       else
12583         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12584         ;
12585       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12586         ;
12587       else if (unformat (line_input, "decap-next %U",
12588                          unformat_vxlan_decap_next, &decap_next_index))
12589         ;
12590       else if (unformat (line_input, "vni %d", &vni))
12591         ;
12592       else
12593         {
12594           errmsg ("parse error '%U'", format_unformat_error, line_input);
12595           return -99;
12596         }
12597     }
12598
12599   if (src_set == 0)
12600     {
12601       errmsg ("tunnel src address not specified");
12602       return -99;
12603     }
12604   if (dst_set == 0)
12605     {
12606       errmsg ("tunnel dst address not specified");
12607       return -99;
12608     }
12609
12610   if (grp_set && !ip46_address_is_multicast (&dst))
12611     {
12612       errmsg ("tunnel group address not multicast");
12613       return -99;
12614     }
12615   if (grp_set && mcast_sw_if_index == ~0)
12616     {
12617       errmsg ("tunnel nonexistent multicast device");
12618       return -99;
12619     }
12620   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12621     {
12622       errmsg ("tunnel dst address must be unicast");
12623       return -99;
12624     }
12625
12626
12627   if (ipv4_set && ipv6_set)
12628     {
12629       errmsg ("both IPv4 and IPv6 addresses specified");
12630       return -99;
12631     }
12632
12633   if ((vni == 0) || (vni >> 24))
12634     {
12635       errmsg ("vni not specified or out of range");
12636       return -99;
12637     }
12638
12639   M (VXLAN_ADD_DEL_TUNNEL, mp);
12640
12641   if (ipv6_set)
12642     {
12643       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12644       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12645     }
12646   else
12647     {
12648       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12649       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12650     }
12651
12652   mp->instance = htonl (instance);
12653   mp->encap_vrf_id = ntohl (encap_vrf_id);
12654   mp->decap_next_index = ntohl (decap_next_index);
12655   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12656   mp->vni = ntohl (vni);
12657   mp->is_add = is_add;
12658   mp->is_ipv6 = ipv6_set;
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static void vl_api_vxlan_tunnel_details_t_handler
12666   (vl_api_vxlan_tunnel_details_t * mp)
12667 {
12668   vat_main_t *vam = &vat_main;
12669   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12670   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12671
12672   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12673          ntohl (mp->sw_if_index),
12674          ntohl (mp->instance),
12675          format_ip46_address, &src, IP46_TYPE_ANY,
12676          format_ip46_address, &dst, IP46_TYPE_ANY,
12677          ntohl (mp->encap_vrf_id),
12678          ntohl (mp->decap_next_index), ntohl (mp->vni),
12679          ntohl (mp->mcast_sw_if_index));
12680 }
12681
12682 static void vl_api_vxlan_tunnel_details_t_handler_json
12683   (vl_api_vxlan_tunnel_details_t * mp)
12684 {
12685   vat_main_t *vam = &vat_main;
12686   vat_json_node_t *node = NULL;
12687
12688   if (VAT_JSON_ARRAY != vam->json_tree.type)
12689     {
12690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12691       vat_json_init_array (&vam->json_tree);
12692     }
12693   node = vat_json_array_add (&vam->json_tree);
12694
12695   vat_json_init_object (node);
12696   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12697
12698   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12699
12700   if (mp->is_ipv6)
12701     {
12702       struct in6_addr ip6;
12703
12704       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12705       vat_json_object_add_ip6 (node, "src_address", ip6);
12706       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12707       vat_json_object_add_ip6 (node, "dst_address", ip6);
12708     }
12709   else
12710     {
12711       struct in_addr ip4;
12712
12713       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12714       vat_json_object_add_ip4 (node, "src_address", ip4);
12715       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12716       vat_json_object_add_ip4 (node, "dst_address", ip4);
12717     }
12718   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12719   vat_json_object_add_uint (node, "decap_next_index",
12720                             ntohl (mp->decap_next_index));
12721   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12722   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12723   vat_json_object_add_uint (node, "mcast_sw_if_index",
12724                             ntohl (mp->mcast_sw_if_index));
12725 }
12726
12727 static int
12728 api_vxlan_tunnel_dump (vat_main_t * vam)
12729 {
12730   unformat_input_t *i = vam->input;
12731   vl_api_vxlan_tunnel_dump_t *mp;
12732   vl_api_control_ping_t *mp_ping;
12733   u32 sw_if_index;
12734   u8 sw_if_index_set = 0;
12735   int ret;
12736
12737   /* Parse args required to build the message */
12738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat (i, "sw_if_index %d", &sw_if_index))
12741         sw_if_index_set = 1;
12742       else
12743         break;
12744     }
12745
12746   if (sw_if_index_set == 0)
12747     {
12748       sw_if_index = ~0;
12749     }
12750
12751   if (!vam->json_output)
12752     {
12753       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12754              "sw_if_index", "instance", "src_address", "dst_address",
12755              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12756     }
12757
12758   /* Get list of vxlan-tunnel interfaces */
12759   M (VXLAN_TUNNEL_DUMP, mp);
12760
12761   mp->sw_if_index = htonl (sw_if_index);
12762
12763   S (mp);
12764
12765   /* Use a control ping for synchronization */
12766   MPING (CONTROL_PING, mp_ping);
12767   S (mp_ping);
12768
12769   W (ret);
12770   return ret;
12771 }
12772
12773 static uword unformat_geneve_decap_next
12774   (unformat_input_t * input, va_list * args)
12775 {
12776   u32 *result = va_arg (*args, u32 *);
12777   u32 tmp;
12778
12779   if (unformat (input, "l2"))
12780     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12781   else if (unformat (input, "%d", &tmp))
12782     *result = tmp;
12783   else
12784     return 0;
12785   return 1;
12786 }
12787
12788 static int
12789 api_geneve_add_del_tunnel (vat_main_t * vam)
12790 {
12791   unformat_input_t *line_input = vam->input;
12792   vl_api_geneve_add_del_tunnel_t *mp;
12793   ip46_address_t src, dst;
12794   u8 is_add = 1;
12795   u8 ipv4_set = 0, ipv6_set = 0;
12796   u8 src_set = 0;
12797   u8 dst_set = 0;
12798   u8 grp_set = 0;
12799   u32 mcast_sw_if_index = ~0;
12800   u32 encap_vrf_id = 0;
12801   u32 decap_next_index = ~0;
12802   u32 vni = 0;
12803   int ret;
12804
12805   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12806   memset (&src, 0, sizeof src);
12807   memset (&dst, 0, sizeof dst);
12808
12809   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (line_input, "del"))
12812         is_add = 0;
12813       else
12814         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12815         {
12816           ipv4_set = 1;
12817           src_set = 1;
12818         }
12819       else
12820         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12821         {
12822           ipv4_set = 1;
12823           dst_set = 1;
12824         }
12825       else
12826         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12827         {
12828           ipv6_set = 1;
12829           src_set = 1;
12830         }
12831       else
12832         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12833         {
12834           ipv6_set = 1;
12835           dst_set = 1;
12836         }
12837       else if (unformat (line_input, "group %U %U",
12838                          unformat_ip4_address, &dst.ip4,
12839                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12840         {
12841           grp_set = dst_set = 1;
12842           ipv4_set = 1;
12843         }
12844       else if (unformat (line_input, "group %U",
12845                          unformat_ip4_address, &dst.ip4))
12846         {
12847           grp_set = dst_set = 1;
12848           ipv4_set = 1;
12849         }
12850       else if (unformat (line_input, "group %U %U",
12851                          unformat_ip6_address, &dst.ip6,
12852                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12853         {
12854           grp_set = dst_set = 1;
12855           ipv6_set = 1;
12856         }
12857       else if (unformat (line_input, "group %U",
12858                          unformat_ip6_address, &dst.ip6))
12859         {
12860           grp_set = dst_set = 1;
12861           ipv6_set = 1;
12862         }
12863       else
12864         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12865         ;
12866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12867         ;
12868       else if (unformat (line_input, "decap-next %U",
12869                          unformat_geneve_decap_next, &decap_next_index))
12870         ;
12871       else if (unformat (line_input, "vni %d", &vni))
12872         ;
12873       else
12874         {
12875           errmsg ("parse error '%U'", format_unformat_error, line_input);
12876           return -99;
12877         }
12878     }
12879
12880   if (src_set == 0)
12881     {
12882       errmsg ("tunnel src address not specified");
12883       return -99;
12884     }
12885   if (dst_set == 0)
12886     {
12887       errmsg ("tunnel dst address not specified");
12888       return -99;
12889     }
12890
12891   if (grp_set && !ip46_address_is_multicast (&dst))
12892     {
12893       errmsg ("tunnel group address not multicast");
12894       return -99;
12895     }
12896   if (grp_set && mcast_sw_if_index == ~0)
12897     {
12898       errmsg ("tunnel nonexistent multicast device");
12899       return -99;
12900     }
12901   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12902     {
12903       errmsg ("tunnel dst address must be unicast");
12904       return -99;
12905     }
12906
12907
12908   if (ipv4_set && ipv6_set)
12909     {
12910       errmsg ("both IPv4 and IPv6 addresses specified");
12911       return -99;
12912     }
12913
12914   if ((vni == 0) || (vni >> 24))
12915     {
12916       errmsg ("vni not specified or out of range");
12917       return -99;
12918     }
12919
12920   M (GENEVE_ADD_DEL_TUNNEL, mp);
12921
12922   if (ipv6_set)
12923     {
12924       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12925       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12926     }
12927   else
12928     {
12929       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12930       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12931     }
12932   mp->encap_vrf_id = ntohl (encap_vrf_id);
12933   mp->decap_next_index = ntohl (decap_next_index);
12934   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12935   mp->vni = ntohl (vni);
12936   mp->is_add = is_add;
12937   mp->is_ipv6 = ipv6_set;
12938
12939   S (mp);
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static void vl_api_geneve_tunnel_details_t_handler
12945   (vl_api_geneve_tunnel_details_t * mp)
12946 {
12947   vat_main_t *vam = &vat_main;
12948   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12949   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12950
12951   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12952          ntohl (mp->sw_if_index),
12953          format_ip46_address, &src, IP46_TYPE_ANY,
12954          format_ip46_address, &dst, IP46_TYPE_ANY,
12955          ntohl (mp->encap_vrf_id),
12956          ntohl (mp->decap_next_index), ntohl (mp->vni),
12957          ntohl (mp->mcast_sw_if_index));
12958 }
12959
12960 static void vl_api_geneve_tunnel_details_t_handler_json
12961   (vl_api_geneve_tunnel_details_t * mp)
12962 {
12963   vat_main_t *vam = &vat_main;
12964   vat_json_node_t *node = NULL;
12965
12966   if (VAT_JSON_ARRAY != vam->json_tree.type)
12967     {
12968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12969       vat_json_init_array (&vam->json_tree);
12970     }
12971   node = vat_json_array_add (&vam->json_tree);
12972
12973   vat_json_init_object (node);
12974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12975   if (mp->is_ipv6)
12976     {
12977       struct in6_addr ip6;
12978
12979       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12980       vat_json_object_add_ip6 (node, "src_address", ip6);
12981       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12982       vat_json_object_add_ip6 (node, "dst_address", ip6);
12983     }
12984   else
12985     {
12986       struct in_addr ip4;
12987
12988       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12989       vat_json_object_add_ip4 (node, "src_address", ip4);
12990       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12991       vat_json_object_add_ip4 (node, "dst_address", ip4);
12992     }
12993   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12994   vat_json_object_add_uint (node, "decap_next_index",
12995                             ntohl (mp->decap_next_index));
12996   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12997   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12998   vat_json_object_add_uint (node, "mcast_sw_if_index",
12999                             ntohl (mp->mcast_sw_if_index));
13000 }
13001
13002 static int
13003 api_geneve_tunnel_dump (vat_main_t * vam)
13004 {
13005   unformat_input_t *i = vam->input;
13006   vl_api_geneve_tunnel_dump_t *mp;
13007   vl_api_control_ping_t *mp_ping;
13008   u32 sw_if_index;
13009   u8 sw_if_index_set = 0;
13010   int ret;
13011
13012   /* Parse args required to build the message */
13013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13014     {
13015       if (unformat (i, "sw_if_index %d", &sw_if_index))
13016         sw_if_index_set = 1;
13017       else
13018         break;
13019     }
13020
13021   if (sw_if_index_set == 0)
13022     {
13023       sw_if_index = ~0;
13024     }
13025
13026   if (!vam->json_output)
13027     {
13028       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13029              "sw_if_index", "local_address", "remote_address",
13030              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13031     }
13032
13033   /* Get list of geneve-tunnel interfaces */
13034   M (GENEVE_TUNNEL_DUMP, mp);
13035
13036   mp->sw_if_index = htonl (sw_if_index);
13037
13038   S (mp);
13039
13040   /* Use a control ping for synchronization */
13041   M (CONTROL_PING, mp_ping);
13042   S (mp_ping);
13043
13044   W (ret);
13045   return ret;
13046 }
13047
13048 static int
13049 api_gre_add_del_tunnel (vat_main_t * vam)
13050 {
13051   unformat_input_t *line_input = vam->input;
13052   vl_api_gre_add_del_tunnel_t *mp;
13053   ip4_address_t src4, dst4;
13054   ip6_address_t src6, dst6;
13055   u8 is_add = 1;
13056   u8 ipv4_set = 0;
13057   u8 ipv6_set = 0;
13058   u8 teb = 0;
13059   u8 src_set = 0;
13060   u8 dst_set = 0;
13061   u32 outer_fib_id = 0;
13062   int ret;
13063
13064   memset (&src4, 0, sizeof src4);
13065   memset (&dst4, 0, sizeof dst4);
13066   memset (&src6, 0, sizeof src6);
13067   memset (&dst6, 0, sizeof dst6);
13068
13069   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13070     {
13071       if (unformat (line_input, "del"))
13072         is_add = 0;
13073       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13074         {
13075           src_set = 1;
13076           ipv4_set = 1;
13077         }
13078       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13079         {
13080           dst_set = 1;
13081           ipv4_set = 1;
13082         }
13083       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13084         {
13085           src_set = 1;
13086           ipv6_set = 1;
13087         }
13088       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13089         {
13090           dst_set = 1;
13091           ipv6_set = 1;
13092         }
13093       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13094         ;
13095       else if (unformat (line_input, "teb"))
13096         teb = 1;
13097       else
13098         {
13099           errmsg ("parse error '%U'", format_unformat_error, line_input);
13100           return -99;
13101         }
13102     }
13103
13104   if (src_set == 0)
13105     {
13106       errmsg ("tunnel src address not specified");
13107       return -99;
13108     }
13109   if (dst_set == 0)
13110     {
13111       errmsg ("tunnel dst address not specified");
13112       return -99;
13113     }
13114   if (ipv4_set && ipv6_set)
13115     {
13116       errmsg ("both IPv4 and IPv6 addresses specified");
13117       return -99;
13118     }
13119
13120
13121   M (GRE_ADD_DEL_TUNNEL, mp);
13122
13123   if (ipv4_set)
13124     {
13125       clib_memcpy (&mp->src_address, &src4, 4);
13126       clib_memcpy (&mp->dst_address, &dst4, 4);
13127     }
13128   else
13129     {
13130       clib_memcpy (&mp->src_address, &src6, 16);
13131       clib_memcpy (&mp->dst_address, &dst6, 16);
13132     }
13133   mp->outer_fib_id = ntohl (outer_fib_id);
13134   mp->is_add = is_add;
13135   mp->teb = teb;
13136   mp->is_ipv6 = ipv6_set;
13137
13138   S (mp);
13139   W (ret);
13140   return ret;
13141 }
13142
13143 static void vl_api_gre_tunnel_details_t_handler
13144   (vl_api_gre_tunnel_details_t * mp)
13145 {
13146   vat_main_t *vam = &vat_main;
13147   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13148   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13149
13150   print (vam->ofp, "%11d%24U%24U%6d%14d",
13151          ntohl (mp->sw_if_index),
13152          format_ip46_address, &src, IP46_TYPE_ANY,
13153          format_ip46_address, &dst, IP46_TYPE_ANY,
13154          mp->teb, ntohl (mp->outer_fib_id));
13155 }
13156
13157 static void vl_api_gre_tunnel_details_t_handler_json
13158   (vl_api_gre_tunnel_details_t * mp)
13159 {
13160   vat_main_t *vam = &vat_main;
13161   vat_json_node_t *node = NULL;
13162   struct in_addr ip4;
13163   struct in6_addr ip6;
13164
13165   if (VAT_JSON_ARRAY != vam->json_tree.type)
13166     {
13167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13168       vat_json_init_array (&vam->json_tree);
13169     }
13170   node = vat_json_array_add (&vam->json_tree);
13171
13172   vat_json_init_object (node);
13173   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13174   if (!mp->is_ipv6)
13175     {
13176       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13177       vat_json_object_add_ip4 (node, "src_address", ip4);
13178       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13179       vat_json_object_add_ip4 (node, "dst_address", ip4);
13180     }
13181   else
13182     {
13183       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13184       vat_json_object_add_ip6 (node, "src_address", ip6);
13185       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13186       vat_json_object_add_ip6 (node, "dst_address", ip6);
13187     }
13188   vat_json_object_add_uint (node, "teb", mp->teb);
13189   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13190   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13191 }
13192
13193 static int
13194 api_gre_tunnel_dump (vat_main_t * vam)
13195 {
13196   unformat_input_t *i = vam->input;
13197   vl_api_gre_tunnel_dump_t *mp;
13198   vl_api_control_ping_t *mp_ping;
13199   u32 sw_if_index;
13200   u8 sw_if_index_set = 0;
13201   int ret;
13202
13203   /* Parse args required to build the message */
13204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13205     {
13206       if (unformat (i, "sw_if_index %d", &sw_if_index))
13207         sw_if_index_set = 1;
13208       else
13209         break;
13210     }
13211
13212   if (sw_if_index_set == 0)
13213     {
13214       sw_if_index = ~0;
13215     }
13216
13217   if (!vam->json_output)
13218     {
13219       print (vam->ofp, "%11s%24s%24s%6s%14s",
13220              "sw_if_index", "src_address", "dst_address", "teb",
13221              "outer_fib_id");
13222     }
13223
13224   /* Get list of gre-tunnel interfaces */
13225   M (GRE_TUNNEL_DUMP, mp);
13226
13227   mp->sw_if_index = htonl (sw_if_index);
13228
13229   S (mp);
13230
13231   /* Use a control ping for synchronization */
13232   MPING (CONTROL_PING, mp_ping);
13233   S (mp_ping);
13234
13235   W (ret);
13236   return ret;
13237 }
13238
13239 static int
13240 api_l2_fib_clear_table (vat_main_t * vam)
13241 {
13242 //  unformat_input_t * i = vam->input;
13243   vl_api_l2_fib_clear_table_t *mp;
13244   int ret;
13245
13246   M (L2_FIB_CLEAR_TABLE, mp);
13247
13248   S (mp);
13249   W (ret);
13250   return ret;
13251 }
13252
13253 static int
13254 api_l2_interface_efp_filter (vat_main_t * vam)
13255 {
13256   unformat_input_t *i = vam->input;
13257   vl_api_l2_interface_efp_filter_t *mp;
13258   u32 sw_if_index;
13259   u8 enable = 1;
13260   u8 sw_if_index_set = 0;
13261   int ret;
13262
13263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13264     {
13265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13266         sw_if_index_set = 1;
13267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13268         sw_if_index_set = 1;
13269       else if (unformat (i, "enable"))
13270         enable = 1;
13271       else if (unformat (i, "disable"))
13272         enable = 0;
13273       else
13274         {
13275           clib_warning ("parse error '%U'", format_unformat_error, i);
13276           return -99;
13277         }
13278     }
13279
13280   if (sw_if_index_set == 0)
13281     {
13282       errmsg ("missing sw_if_index");
13283       return -99;
13284     }
13285
13286   M (L2_INTERFACE_EFP_FILTER, mp);
13287
13288   mp->sw_if_index = ntohl (sw_if_index);
13289   mp->enable_disable = enable;
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 #define foreach_vtr_op                          \
13297 _("disable",  L2_VTR_DISABLED)                  \
13298 _("push-1",  L2_VTR_PUSH_1)                     \
13299 _("push-2",  L2_VTR_PUSH_2)                     \
13300 _("pop-1",  L2_VTR_POP_1)                       \
13301 _("pop-2",  L2_VTR_POP_2)                       \
13302 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13303 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13304 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13305 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13306
13307 static int
13308 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13309 {
13310   unformat_input_t *i = vam->input;
13311   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13312   u32 sw_if_index;
13313   u8 sw_if_index_set = 0;
13314   u8 vtr_op_set = 0;
13315   u32 vtr_op = 0;
13316   u32 push_dot1q = 1;
13317   u32 tag1 = ~0;
13318   u32 tag2 = ~0;
13319   int ret;
13320
13321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13324         sw_if_index_set = 1;
13325       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13326         sw_if_index_set = 1;
13327       else if (unformat (i, "vtr_op %d", &vtr_op))
13328         vtr_op_set = 1;
13329 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13330       foreach_vtr_op
13331 #undef _
13332         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13333         ;
13334       else if (unformat (i, "tag1 %d", &tag1))
13335         ;
13336       else if (unformat (i, "tag2 %d", &tag2))
13337         ;
13338       else
13339         {
13340           clib_warning ("parse error '%U'", format_unformat_error, i);
13341           return -99;
13342         }
13343     }
13344
13345   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13346     {
13347       errmsg ("missing vtr operation or sw_if_index");
13348       return -99;
13349     }
13350
13351   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13352   mp->sw_if_index = ntohl (sw_if_index);
13353   mp->vtr_op = ntohl (vtr_op);
13354   mp->push_dot1q = ntohl (push_dot1q);
13355   mp->tag1 = ntohl (tag1);
13356   mp->tag2 = ntohl (tag2);
13357
13358   S (mp);
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_create_vhost_user_if (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_create_vhost_user_if_t *mp;
13368   u8 *file_name;
13369   u8 is_server = 0;
13370   u8 file_name_set = 0;
13371   u32 custom_dev_instance = ~0;
13372   u8 hwaddr[6];
13373   u8 use_custom_mac = 0;
13374   u8 *tag = 0;
13375   int ret;
13376
13377   /* Shut up coverity */
13378   memset (hwaddr, 0, sizeof (hwaddr));
13379
13380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13381     {
13382       if (unformat (i, "socket %s", &file_name))
13383         {
13384           file_name_set = 1;
13385         }
13386       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13387         ;
13388       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13389         use_custom_mac = 1;
13390       else if (unformat (i, "server"))
13391         is_server = 1;
13392       else if (unformat (i, "tag %s", &tag))
13393         ;
13394       else
13395         break;
13396     }
13397
13398   if (file_name_set == 0)
13399     {
13400       errmsg ("missing socket file name");
13401       return -99;
13402     }
13403
13404   if (vec_len (file_name) > 255)
13405     {
13406       errmsg ("socket file name too long");
13407       return -99;
13408     }
13409   vec_add1 (file_name, 0);
13410
13411   M (CREATE_VHOST_USER_IF, mp);
13412
13413   mp->is_server = is_server;
13414   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13415   vec_free (file_name);
13416   if (custom_dev_instance != ~0)
13417     {
13418       mp->renumber = 1;
13419       mp->custom_dev_instance = ntohl (custom_dev_instance);
13420     }
13421   mp->use_custom_mac = use_custom_mac;
13422   clib_memcpy (mp->mac_address, hwaddr, 6);
13423   if (tag)
13424     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13425   vec_free (tag);
13426
13427   S (mp);
13428   W (ret);
13429   return ret;
13430 }
13431
13432 static int
13433 api_modify_vhost_user_if (vat_main_t * vam)
13434 {
13435   unformat_input_t *i = vam->input;
13436   vl_api_modify_vhost_user_if_t *mp;
13437   u8 *file_name;
13438   u8 is_server = 0;
13439   u8 file_name_set = 0;
13440   u32 custom_dev_instance = ~0;
13441   u8 sw_if_index_set = 0;
13442   u32 sw_if_index = (u32) ~ 0;
13443   int ret;
13444
13445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13446     {
13447       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13448         sw_if_index_set = 1;
13449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13450         sw_if_index_set = 1;
13451       else if (unformat (i, "socket %s", &file_name))
13452         {
13453           file_name_set = 1;
13454         }
13455       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13456         ;
13457       else if (unformat (i, "server"))
13458         is_server = 1;
13459       else
13460         break;
13461     }
13462
13463   if (sw_if_index_set == 0)
13464     {
13465       errmsg ("missing sw_if_index or interface name");
13466       return -99;
13467     }
13468
13469   if (file_name_set == 0)
13470     {
13471       errmsg ("missing socket file name");
13472       return -99;
13473     }
13474
13475   if (vec_len (file_name) > 255)
13476     {
13477       errmsg ("socket file name too long");
13478       return -99;
13479     }
13480   vec_add1 (file_name, 0);
13481
13482   M (MODIFY_VHOST_USER_IF, mp);
13483
13484   mp->sw_if_index = ntohl (sw_if_index);
13485   mp->is_server = is_server;
13486   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13487   vec_free (file_name);
13488   if (custom_dev_instance != ~0)
13489     {
13490       mp->renumber = 1;
13491       mp->custom_dev_instance = ntohl (custom_dev_instance);
13492     }
13493
13494   S (mp);
13495   W (ret);
13496   return ret;
13497 }
13498
13499 static int
13500 api_delete_vhost_user_if (vat_main_t * vam)
13501 {
13502   unformat_input_t *i = vam->input;
13503   vl_api_delete_vhost_user_if_t *mp;
13504   u32 sw_if_index = ~0;
13505   u8 sw_if_index_set = 0;
13506   int ret;
13507
13508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509     {
13510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13511         sw_if_index_set = 1;
13512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13513         sw_if_index_set = 1;
13514       else
13515         break;
13516     }
13517
13518   if (sw_if_index_set == 0)
13519     {
13520       errmsg ("missing sw_if_index or interface name");
13521       return -99;
13522     }
13523
13524
13525   M (DELETE_VHOST_USER_IF, mp);
13526
13527   mp->sw_if_index = ntohl (sw_if_index);
13528
13529   S (mp);
13530   W (ret);
13531   return ret;
13532 }
13533
13534 static void vl_api_sw_interface_vhost_user_details_t_handler
13535   (vl_api_sw_interface_vhost_user_details_t * mp)
13536 {
13537   vat_main_t *vam = &vat_main;
13538
13539   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13540          (char *) mp->interface_name,
13541          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13542          clib_net_to_host_u64 (mp->features), mp->is_server,
13543          ntohl (mp->num_regions), (char *) mp->sock_filename);
13544   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13545 }
13546
13547 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13548   (vl_api_sw_interface_vhost_user_details_t * mp)
13549 {
13550   vat_main_t *vam = &vat_main;
13551   vat_json_node_t *node = NULL;
13552
13553   if (VAT_JSON_ARRAY != vam->json_tree.type)
13554     {
13555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13556       vat_json_init_array (&vam->json_tree);
13557     }
13558   node = vat_json_array_add (&vam->json_tree);
13559
13560   vat_json_init_object (node);
13561   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13562   vat_json_object_add_string_copy (node, "interface_name",
13563                                    mp->interface_name);
13564   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13565                             ntohl (mp->virtio_net_hdr_sz));
13566   vat_json_object_add_uint (node, "features",
13567                             clib_net_to_host_u64 (mp->features));
13568   vat_json_object_add_uint (node, "is_server", mp->is_server);
13569   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13570   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13571   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13572 }
13573
13574 static int
13575 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13576 {
13577   vl_api_sw_interface_vhost_user_dump_t *mp;
13578   vl_api_control_ping_t *mp_ping;
13579   int ret;
13580   print (vam->ofp,
13581          "Interface name            idx hdr_sz features server regions filename");
13582
13583   /* Get list of vhost-user interfaces */
13584   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13585   S (mp);
13586
13587   /* Use a control ping for synchronization */
13588   MPING (CONTROL_PING, mp_ping);
13589   S (mp_ping);
13590
13591   W (ret);
13592   return ret;
13593 }
13594
13595 static int
13596 api_show_version (vat_main_t * vam)
13597 {
13598   vl_api_show_version_t *mp;
13599   int ret;
13600
13601   M (SHOW_VERSION, mp);
13602
13603   S (mp);
13604   W (ret);
13605   return ret;
13606 }
13607
13608
13609 static int
13610 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13611 {
13612   unformat_input_t *line_input = vam->input;
13613   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13614   ip4_address_t local4, remote4;
13615   ip6_address_t local6, remote6;
13616   u8 is_add = 1;
13617   u8 ipv4_set = 0, ipv6_set = 0;
13618   u8 local_set = 0;
13619   u8 remote_set = 0;
13620   u8 grp_set = 0;
13621   u32 mcast_sw_if_index = ~0;
13622   u32 encap_vrf_id = 0;
13623   u32 decap_vrf_id = 0;
13624   u8 protocol = ~0;
13625   u32 vni;
13626   u8 vni_set = 0;
13627   int ret;
13628
13629   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13630   memset (&local4, 0, sizeof local4);
13631   memset (&remote4, 0, sizeof remote4);
13632   memset (&local6, 0, sizeof local6);
13633   memset (&remote6, 0, sizeof remote6);
13634
13635   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13636     {
13637       if (unformat (line_input, "del"))
13638         is_add = 0;
13639       else if (unformat (line_input, "local %U",
13640                          unformat_ip4_address, &local4))
13641         {
13642           local_set = 1;
13643           ipv4_set = 1;
13644         }
13645       else if (unformat (line_input, "remote %U",
13646                          unformat_ip4_address, &remote4))
13647         {
13648           remote_set = 1;
13649           ipv4_set = 1;
13650         }
13651       else if (unformat (line_input, "local %U",
13652                          unformat_ip6_address, &local6))
13653         {
13654           local_set = 1;
13655           ipv6_set = 1;
13656         }
13657       else if (unformat (line_input, "remote %U",
13658                          unformat_ip6_address, &remote6))
13659         {
13660           remote_set = 1;
13661           ipv6_set = 1;
13662         }
13663       else if (unformat (line_input, "group %U %U",
13664                          unformat_ip4_address, &remote4,
13665                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13666         {
13667           grp_set = remote_set = 1;
13668           ipv4_set = 1;
13669         }
13670       else if (unformat (line_input, "group %U",
13671                          unformat_ip4_address, &remote4))
13672         {
13673           grp_set = remote_set = 1;
13674           ipv4_set = 1;
13675         }
13676       else if (unformat (line_input, "group %U %U",
13677                          unformat_ip6_address, &remote6,
13678                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13679         {
13680           grp_set = remote_set = 1;
13681           ipv6_set = 1;
13682         }
13683       else if (unformat (line_input, "group %U",
13684                          unformat_ip6_address, &remote6))
13685         {
13686           grp_set = remote_set = 1;
13687           ipv6_set = 1;
13688         }
13689       else
13690         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13691         ;
13692       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13693         ;
13694       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13695         ;
13696       else if (unformat (line_input, "vni %d", &vni))
13697         vni_set = 1;
13698       else if (unformat (line_input, "next-ip4"))
13699         protocol = 1;
13700       else if (unformat (line_input, "next-ip6"))
13701         protocol = 2;
13702       else if (unformat (line_input, "next-ethernet"))
13703         protocol = 3;
13704       else if (unformat (line_input, "next-nsh"))
13705         protocol = 4;
13706       else
13707         {
13708           errmsg ("parse error '%U'", format_unformat_error, line_input);
13709           return -99;
13710         }
13711     }
13712
13713   if (local_set == 0)
13714     {
13715       errmsg ("tunnel local address not specified");
13716       return -99;
13717     }
13718   if (remote_set == 0)
13719     {
13720       errmsg ("tunnel remote address not specified");
13721       return -99;
13722     }
13723   if (grp_set && mcast_sw_if_index == ~0)
13724     {
13725       errmsg ("tunnel nonexistent multicast device");
13726       return -99;
13727     }
13728   if (ipv4_set && ipv6_set)
13729     {
13730       errmsg ("both IPv4 and IPv6 addresses specified");
13731       return -99;
13732     }
13733
13734   if (vni_set == 0)
13735     {
13736       errmsg ("vni not specified");
13737       return -99;
13738     }
13739
13740   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13741
13742
13743   if (ipv6_set)
13744     {
13745       clib_memcpy (&mp->local, &local6, sizeof (local6));
13746       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13747     }
13748   else
13749     {
13750       clib_memcpy (&mp->local, &local4, sizeof (local4));
13751       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13752     }
13753
13754   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13755   mp->encap_vrf_id = ntohl (encap_vrf_id);
13756   mp->decap_vrf_id = ntohl (decap_vrf_id);
13757   mp->protocol = protocol;
13758   mp->vni = ntohl (vni);
13759   mp->is_add = is_add;
13760   mp->is_ipv6 = ipv6_set;
13761
13762   S (mp);
13763   W (ret);
13764   return ret;
13765 }
13766
13767 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13768   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13769 {
13770   vat_main_t *vam = &vat_main;
13771   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13772   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13773
13774   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13775          ntohl (mp->sw_if_index),
13776          format_ip46_address, &local, IP46_TYPE_ANY,
13777          format_ip46_address, &remote, IP46_TYPE_ANY,
13778          ntohl (mp->vni), mp->protocol,
13779          ntohl (mp->mcast_sw_if_index),
13780          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13781 }
13782
13783
13784 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13785   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13786 {
13787   vat_main_t *vam = &vat_main;
13788   vat_json_node_t *node = NULL;
13789   struct in_addr ip4;
13790   struct in6_addr ip6;
13791
13792   if (VAT_JSON_ARRAY != vam->json_tree.type)
13793     {
13794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13795       vat_json_init_array (&vam->json_tree);
13796     }
13797   node = vat_json_array_add (&vam->json_tree);
13798
13799   vat_json_init_object (node);
13800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13801   if (mp->is_ipv6)
13802     {
13803       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13804       vat_json_object_add_ip6 (node, "local", ip6);
13805       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13806       vat_json_object_add_ip6 (node, "remote", ip6);
13807     }
13808   else
13809     {
13810       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13811       vat_json_object_add_ip4 (node, "local", ip4);
13812       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13813       vat_json_object_add_ip4 (node, "remote", ip4);
13814     }
13815   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13816   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13817   vat_json_object_add_uint (node, "mcast_sw_if_index",
13818                             ntohl (mp->mcast_sw_if_index));
13819   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13820   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13821   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13822 }
13823
13824 static int
13825 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13826 {
13827   unformat_input_t *i = vam->input;
13828   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13829   vl_api_control_ping_t *mp_ping;
13830   u32 sw_if_index;
13831   u8 sw_if_index_set = 0;
13832   int ret;
13833
13834   /* Parse args required to build the message */
13835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13836     {
13837       if (unformat (i, "sw_if_index %d", &sw_if_index))
13838         sw_if_index_set = 1;
13839       else
13840         break;
13841     }
13842
13843   if (sw_if_index_set == 0)
13844     {
13845       sw_if_index = ~0;
13846     }
13847
13848   if (!vam->json_output)
13849     {
13850       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13851              "sw_if_index", "local", "remote", "vni",
13852              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13853     }
13854
13855   /* Get list of vxlan-tunnel interfaces */
13856   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13857
13858   mp->sw_if_index = htonl (sw_if_index);
13859
13860   S (mp);
13861
13862   /* Use a control ping for synchronization */
13863   MPING (CONTROL_PING, mp_ping);
13864   S (mp_ping);
13865
13866   W (ret);
13867   return ret;
13868 }
13869
13870 static void vl_api_l2_fib_table_details_t_handler
13871   (vl_api_l2_fib_table_details_t * mp)
13872 {
13873   vat_main_t *vam = &vat_main;
13874
13875   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13876          "       %d       %d     %d",
13877          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13878          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13879          mp->bvi_mac);
13880 }
13881
13882 static void vl_api_l2_fib_table_details_t_handler_json
13883   (vl_api_l2_fib_table_details_t * mp)
13884 {
13885   vat_main_t *vam = &vat_main;
13886   vat_json_node_t *node = NULL;
13887
13888   if (VAT_JSON_ARRAY != vam->json_tree.type)
13889     {
13890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13891       vat_json_init_array (&vam->json_tree);
13892     }
13893   node = vat_json_array_add (&vam->json_tree);
13894
13895   vat_json_init_object (node);
13896   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13897   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13898   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13899   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13900   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13901   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13902 }
13903
13904 static int
13905 api_l2_fib_table_dump (vat_main_t * vam)
13906 {
13907   unformat_input_t *i = vam->input;
13908   vl_api_l2_fib_table_dump_t *mp;
13909   vl_api_control_ping_t *mp_ping;
13910   u32 bd_id;
13911   u8 bd_id_set = 0;
13912   int ret;
13913
13914   /* Parse args required to build the message */
13915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (i, "bd_id %d", &bd_id))
13918         bd_id_set = 1;
13919       else
13920         break;
13921     }
13922
13923   if (bd_id_set == 0)
13924     {
13925       errmsg ("missing bridge domain");
13926       return -99;
13927     }
13928
13929   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13930
13931   /* Get list of l2 fib entries */
13932   M (L2_FIB_TABLE_DUMP, mp);
13933
13934   mp->bd_id = ntohl (bd_id);
13935   S (mp);
13936
13937   /* Use a control ping for synchronization */
13938   MPING (CONTROL_PING, mp_ping);
13939   S (mp_ping);
13940
13941   W (ret);
13942   return ret;
13943 }
13944
13945
13946 static int
13947 api_interface_name_renumber (vat_main_t * vam)
13948 {
13949   unformat_input_t *line_input = vam->input;
13950   vl_api_interface_name_renumber_t *mp;
13951   u32 sw_if_index = ~0;
13952   u32 new_show_dev_instance = ~0;
13953   int ret;
13954
13955   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13956     {
13957       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13958                     &sw_if_index))
13959         ;
13960       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13961         ;
13962       else if (unformat (line_input, "new_show_dev_instance %d",
13963                          &new_show_dev_instance))
13964         ;
13965       else
13966         break;
13967     }
13968
13969   if (sw_if_index == ~0)
13970     {
13971       errmsg ("missing interface name or sw_if_index");
13972       return -99;
13973     }
13974
13975   if (new_show_dev_instance == ~0)
13976     {
13977       errmsg ("missing new_show_dev_instance");
13978       return -99;
13979     }
13980
13981   M (INTERFACE_NAME_RENUMBER, mp);
13982
13983   mp->sw_if_index = ntohl (sw_if_index);
13984   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13985
13986   S (mp);
13987   W (ret);
13988   return ret;
13989 }
13990
13991 static int
13992 api_want_ip4_arp_events (vat_main_t * vam)
13993 {
13994   unformat_input_t *line_input = vam->input;
13995   vl_api_want_ip4_arp_events_t *mp;
13996   ip4_address_t address;
13997   int address_set = 0;
13998   u32 enable_disable = 1;
13999   int ret;
14000
14001   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14002     {
14003       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14004         address_set = 1;
14005       else if (unformat (line_input, "del"))
14006         enable_disable = 0;
14007       else
14008         break;
14009     }
14010
14011   if (address_set == 0)
14012     {
14013       errmsg ("missing addresses");
14014       return -99;
14015     }
14016
14017   M (WANT_IP4_ARP_EVENTS, mp);
14018   mp->enable_disable = enable_disable;
14019   mp->pid = htonl (getpid ());
14020   mp->address = address.as_u32;
14021
14022   S (mp);
14023   W (ret);
14024   return ret;
14025 }
14026
14027 static int
14028 api_want_ip6_nd_events (vat_main_t * vam)
14029 {
14030   unformat_input_t *line_input = vam->input;
14031   vl_api_want_ip6_nd_events_t *mp;
14032   ip6_address_t address;
14033   int address_set = 0;
14034   u32 enable_disable = 1;
14035   int ret;
14036
14037   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14038     {
14039       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14040         address_set = 1;
14041       else if (unformat (line_input, "del"))
14042         enable_disable = 0;
14043       else
14044         break;
14045     }
14046
14047   if (address_set == 0)
14048     {
14049       errmsg ("missing addresses");
14050       return -99;
14051     }
14052
14053   M (WANT_IP6_ND_EVENTS, mp);
14054   mp->enable_disable = enable_disable;
14055   mp->pid = htonl (getpid ());
14056   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14057
14058   S (mp);
14059   W (ret);
14060   return ret;
14061 }
14062
14063 static int
14064 api_want_l2_macs_events (vat_main_t * vam)
14065 {
14066   unformat_input_t *line_input = vam->input;
14067   vl_api_want_l2_macs_events_t *mp;
14068   u8 enable_disable = 1;
14069   u32 scan_delay = 0;
14070   u32 max_macs_in_event = 0;
14071   u32 learn_limit = 0;
14072   int ret;
14073
14074   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14075     {
14076       if (unformat (line_input, "learn-limit %d", &learn_limit))
14077         ;
14078       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14079         ;
14080       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14081         ;
14082       else if (unformat (line_input, "disable"))
14083         enable_disable = 0;
14084       else
14085         break;
14086     }
14087
14088   M (WANT_L2_MACS_EVENTS, mp);
14089   mp->enable_disable = enable_disable;
14090   mp->pid = htonl (getpid ());
14091   mp->learn_limit = htonl (learn_limit);
14092   mp->scan_delay = (u8) scan_delay;
14093   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14094   S (mp);
14095   W (ret);
14096   return ret;
14097 }
14098
14099 static int
14100 api_input_acl_set_interface (vat_main_t * vam)
14101 {
14102   unformat_input_t *i = vam->input;
14103   vl_api_input_acl_set_interface_t *mp;
14104   u32 sw_if_index;
14105   int sw_if_index_set;
14106   u32 ip4_table_index = ~0;
14107   u32 ip6_table_index = ~0;
14108   u32 l2_table_index = ~0;
14109   u8 is_add = 1;
14110   int ret;
14111
14112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14115         sw_if_index_set = 1;
14116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14117         sw_if_index_set = 1;
14118       else if (unformat (i, "del"))
14119         is_add = 0;
14120       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14121         ;
14122       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14123         ;
14124       else if (unformat (i, "l2-table %d", &l2_table_index))
14125         ;
14126       else
14127         {
14128           clib_warning ("parse error '%U'", format_unformat_error, i);
14129           return -99;
14130         }
14131     }
14132
14133   if (sw_if_index_set == 0)
14134     {
14135       errmsg ("missing interface name or sw_if_index");
14136       return -99;
14137     }
14138
14139   M (INPUT_ACL_SET_INTERFACE, mp);
14140
14141   mp->sw_if_index = ntohl (sw_if_index);
14142   mp->ip4_table_index = ntohl (ip4_table_index);
14143   mp->ip6_table_index = ntohl (ip6_table_index);
14144   mp->l2_table_index = ntohl (l2_table_index);
14145   mp->is_add = is_add;
14146
14147   S (mp);
14148   W (ret);
14149   return ret;
14150 }
14151
14152 static int
14153 api_output_acl_set_interface (vat_main_t * vam)
14154 {
14155   unformat_input_t *i = vam->input;
14156   vl_api_output_acl_set_interface_t *mp;
14157   u32 sw_if_index;
14158   int sw_if_index_set;
14159   u32 ip4_table_index = ~0;
14160   u32 ip6_table_index = ~0;
14161   u32 l2_table_index = ~0;
14162   u8 is_add = 1;
14163   int ret;
14164
14165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14166     {
14167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14168         sw_if_index_set = 1;
14169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14170         sw_if_index_set = 1;
14171       else if (unformat (i, "del"))
14172         is_add = 0;
14173       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14174         ;
14175       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14176         ;
14177       else if (unformat (i, "l2-table %d", &l2_table_index))
14178         ;
14179       else
14180         {
14181           clib_warning ("parse error '%U'", format_unformat_error, i);
14182           return -99;
14183         }
14184     }
14185
14186   if (sw_if_index_set == 0)
14187     {
14188       errmsg ("missing interface name or sw_if_index");
14189       return -99;
14190     }
14191
14192   M (OUTPUT_ACL_SET_INTERFACE, mp);
14193
14194   mp->sw_if_index = ntohl (sw_if_index);
14195   mp->ip4_table_index = ntohl (ip4_table_index);
14196   mp->ip6_table_index = ntohl (ip6_table_index);
14197   mp->l2_table_index = ntohl (l2_table_index);
14198   mp->is_add = is_add;
14199
14200   S (mp);
14201   W (ret);
14202   return ret;
14203 }
14204
14205 static int
14206 api_ip_address_dump (vat_main_t * vam)
14207 {
14208   unformat_input_t *i = vam->input;
14209   vl_api_ip_address_dump_t *mp;
14210   vl_api_control_ping_t *mp_ping;
14211   u32 sw_if_index = ~0;
14212   u8 sw_if_index_set = 0;
14213   u8 ipv4_set = 0;
14214   u8 ipv6_set = 0;
14215   int ret;
14216
14217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14218     {
14219       if (unformat (i, "sw_if_index %d", &sw_if_index))
14220         sw_if_index_set = 1;
14221       else
14222         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14223         sw_if_index_set = 1;
14224       else if (unformat (i, "ipv4"))
14225         ipv4_set = 1;
14226       else if (unformat (i, "ipv6"))
14227         ipv6_set = 1;
14228       else
14229         break;
14230     }
14231
14232   if (ipv4_set && ipv6_set)
14233     {
14234       errmsg ("ipv4 and ipv6 flags cannot be both set");
14235       return -99;
14236     }
14237
14238   if ((!ipv4_set) && (!ipv6_set))
14239     {
14240       errmsg ("no ipv4 nor ipv6 flag set");
14241       return -99;
14242     }
14243
14244   if (sw_if_index_set == 0)
14245     {
14246       errmsg ("missing interface name or sw_if_index");
14247       return -99;
14248     }
14249
14250   vam->current_sw_if_index = sw_if_index;
14251   vam->is_ipv6 = ipv6_set;
14252
14253   M (IP_ADDRESS_DUMP, mp);
14254   mp->sw_if_index = ntohl (sw_if_index);
14255   mp->is_ipv6 = ipv6_set;
14256   S (mp);
14257
14258   /* Use a control ping for synchronization */
14259   MPING (CONTROL_PING, mp_ping);
14260   S (mp_ping);
14261
14262   W (ret);
14263   return ret;
14264 }
14265
14266 static int
14267 api_ip_dump (vat_main_t * vam)
14268 {
14269   vl_api_ip_dump_t *mp;
14270   vl_api_control_ping_t *mp_ping;
14271   unformat_input_t *in = vam->input;
14272   int ipv4_set = 0;
14273   int ipv6_set = 0;
14274   int is_ipv6;
14275   int i;
14276   int ret;
14277
14278   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14279     {
14280       if (unformat (in, "ipv4"))
14281         ipv4_set = 1;
14282       else if (unformat (in, "ipv6"))
14283         ipv6_set = 1;
14284       else
14285         break;
14286     }
14287
14288   if (ipv4_set && ipv6_set)
14289     {
14290       errmsg ("ipv4 and ipv6 flags cannot be both set");
14291       return -99;
14292     }
14293
14294   if ((!ipv4_set) && (!ipv6_set))
14295     {
14296       errmsg ("no ipv4 nor ipv6 flag set");
14297       return -99;
14298     }
14299
14300   is_ipv6 = ipv6_set;
14301   vam->is_ipv6 = is_ipv6;
14302
14303   /* free old data */
14304   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14305     {
14306       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14307     }
14308   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14309
14310   M (IP_DUMP, mp);
14311   mp->is_ipv6 = ipv6_set;
14312   S (mp);
14313
14314   /* Use a control ping for synchronization */
14315   MPING (CONTROL_PING, mp_ping);
14316   S (mp_ping);
14317
14318   W (ret);
14319   return ret;
14320 }
14321
14322 static int
14323 api_ipsec_spd_add_del (vat_main_t * vam)
14324 {
14325   unformat_input_t *i = vam->input;
14326   vl_api_ipsec_spd_add_del_t *mp;
14327   u32 spd_id = ~0;
14328   u8 is_add = 1;
14329   int ret;
14330
14331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14332     {
14333       if (unformat (i, "spd_id %d", &spd_id))
14334         ;
14335       else if (unformat (i, "del"))
14336         is_add = 0;
14337       else
14338         {
14339           clib_warning ("parse error '%U'", format_unformat_error, i);
14340           return -99;
14341         }
14342     }
14343   if (spd_id == ~0)
14344     {
14345       errmsg ("spd_id must be set");
14346       return -99;
14347     }
14348
14349   M (IPSEC_SPD_ADD_DEL, mp);
14350
14351   mp->spd_id = ntohl (spd_id);
14352   mp->is_add = is_add;
14353
14354   S (mp);
14355   W (ret);
14356   return ret;
14357 }
14358
14359 static int
14360 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14361 {
14362   unformat_input_t *i = vam->input;
14363   vl_api_ipsec_interface_add_del_spd_t *mp;
14364   u32 sw_if_index;
14365   u8 sw_if_index_set = 0;
14366   u32 spd_id = (u32) ~ 0;
14367   u8 is_add = 1;
14368   int ret;
14369
14370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14371     {
14372       if (unformat (i, "del"))
14373         is_add = 0;
14374       else if (unformat (i, "spd_id %d", &spd_id))
14375         ;
14376       else
14377         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14378         sw_if_index_set = 1;
14379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14380         sw_if_index_set = 1;
14381       else
14382         {
14383           clib_warning ("parse error '%U'", format_unformat_error, i);
14384           return -99;
14385         }
14386
14387     }
14388
14389   if (spd_id == (u32) ~ 0)
14390     {
14391       errmsg ("spd_id must be set");
14392       return -99;
14393     }
14394
14395   if (sw_if_index_set == 0)
14396     {
14397       errmsg ("missing interface name or sw_if_index");
14398       return -99;
14399     }
14400
14401   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14402
14403   mp->spd_id = ntohl (spd_id);
14404   mp->sw_if_index = ntohl (sw_if_index);
14405   mp->is_add = is_add;
14406
14407   S (mp);
14408   W (ret);
14409   return ret;
14410 }
14411
14412 static int
14413 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14414 {
14415   unformat_input_t *i = vam->input;
14416   vl_api_ipsec_spd_add_del_entry_t *mp;
14417   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14418   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14419   i32 priority = 0;
14420   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14421   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14422   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14423   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14424   int ret;
14425
14426   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14427   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14428   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14429   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14430   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14431   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "del"))
14436         is_add = 0;
14437       if (unformat (i, "outbound"))
14438         is_outbound = 1;
14439       if (unformat (i, "inbound"))
14440         is_outbound = 0;
14441       else if (unformat (i, "spd_id %d", &spd_id))
14442         ;
14443       else if (unformat (i, "sa_id %d", &sa_id))
14444         ;
14445       else if (unformat (i, "priority %d", &priority))
14446         ;
14447       else if (unformat (i, "protocol %d", &protocol))
14448         ;
14449       else if (unformat (i, "lport_start %d", &lport_start))
14450         ;
14451       else if (unformat (i, "lport_stop %d", &lport_stop))
14452         ;
14453       else if (unformat (i, "rport_start %d", &rport_start))
14454         ;
14455       else if (unformat (i, "rport_stop %d", &rport_stop))
14456         ;
14457       else
14458         if (unformat
14459             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14460         {
14461           is_ipv6 = 0;
14462           is_ip_any = 0;
14463         }
14464       else
14465         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14466         {
14467           is_ipv6 = 0;
14468           is_ip_any = 0;
14469         }
14470       else
14471         if (unformat
14472             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14473         {
14474           is_ipv6 = 0;
14475           is_ip_any = 0;
14476         }
14477       else
14478         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14479         {
14480           is_ipv6 = 0;
14481           is_ip_any = 0;
14482         }
14483       else
14484         if (unformat
14485             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14486         {
14487           is_ipv6 = 1;
14488           is_ip_any = 0;
14489         }
14490       else
14491         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14492         {
14493           is_ipv6 = 1;
14494           is_ip_any = 0;
14495         }
14496       else
14497         if (unformat
14498             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14499         {
14500           is_ipv6 = 1;
14501           is_ip_any = 0;
14502         }
14503       else
14504         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14505         {
14506           is_ipv6 = 1;
14507           is_ip_any = 0;
14508         }
14509       else
14510         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14511         {
14512           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14513             {
14514               clib_warning ("unsupported action: 'resolve'");
14515               return -99;
14516             }
14517         }
14518       else
14519         {
14520           clib_warning ("parse error '%U'", format_unformat_error, i);
14521           return -99;
14522         }
14523
14524     }
14525
14526   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14527
14528   mp->spd_id = ntohl (spd_id);
14529   mp->priority = ntohl (priority);
14530   mp->is_outbound = is_outbound;
14531
14532   mp->is_ipv6 = is_ipv6;
14533   if (is_ipv6 || is_ip_any)
14534     {
14535       clib_memcpy (mp->remote_address_start, &raddr6_start,
14536                    sizeof (ip6_address_t));
14537       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14538                    sizeof (ip6_address_t));
14539       clib_memcpy (mp->local_address_start, &laddr6_start,
14540                    sizeof (ip6_address_t));
14541       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14542                    sizeof (ip6_address_t));
14543     }
14544   else
14545     {
14546       clib_memcpy (mp->remote_address_start, &raddr4_start,
14547                    sizeof (ip4_address_t));
14548       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14549                    sizeof (ip4_address_t));
14550       clib_memcpy (mp->local_address_start, &laddr4_start,
14551                    sizeof (ip4_address_t));
14552       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14553                    sizeof (ip4_address_t));
14554     }
14555   mp->protocol = (u8) protocol;
14556   mp->local_port_start = ntohs ((u16) lport_start);
14557   mp->local_port_stop = ntohs ((u16) lport_stop);
14558   mp->remote_port_start = ntohs ((u16) rport_start);
14559   mp->remote_port_stop = ntohs ((u16) rport_stop);
14560   mp->policy = (u8) policy;
14561   mp->sa_id = ntohl (sa_id);
14562   mp->is_add = is_add;
14563   mp->is_ip_any = is_ip_any;
14564   S (mp);
14565   W (ret);
14566   return ret;
14567 }
14568
14569 static int
14570 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14571 {
14572   unformat_input_t *i = vam->input;
14573   vl_api_ipsec_sad_add_del_entry_t *mp;
14574   u32 sad_id = 0, spi = 0;
14575   u8 *ck = 0, *ik = 0;
14576   u8 is_add = 1;
14577
14578   u8 protocol = IPSEC_PROTOCOL_AH;
14579   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14580   u32 crypto_alg = 0, integ_alg = 0;
14581   ip4_address_t tun_src4;
14582   ip4_address_t tun_dst4;
14583   ip6_address_t tun_src6;
14584   ip6_address_t tun_dst6;
14585   int ret;
14586
14587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14588     {
14589       if (unformat (i, "del"))
14590         is_add = 0;
14591       else if (unformat (i, "sad_id %d", &sad_id))
14592         ;
14593       else if (unformat (i, "spi %d", &spi))
14594         ;
14595       else if (unformat (i, "esp"))
14596         protocol = IPSEC_PROTOCOL_ESP;
14597       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14598         {
14599           is_tunnel = 1;
14600           is_tunnel_ipv6 = 0;
14601         }
14602       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14603         {
14604           is_tunnel = 1;
14605           is_tunnel_ipv6 = 0;
14606         }
14607       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14608         {
14609           is_tunnel = 1;
14610           is_tunnel_ipv6 = 1;
14611         }
14612       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14613         {
14614           is_tunnel = 1;
14615           is_tunnel_ipv6 = 1;
14616         }
14617       else
14618         if (unformat
14619             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14620         {
14621           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14622               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14623             {
14624               clib_warning ("unsupported crypto-alg: '%U'",
14625                             format_ipsec_crypto_alg, crypto_alg);
14626               return -99;
14627             }
14628         }
14629       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14630         ;
14631       else
14632         if (unformat
14633             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14634         {
14635           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14636               integ_alg >= IPSEC_INTEG_N_ALG)
14637             {
14638               clib_warning ("unsupported integ-alg: '%U'",
14639                             format_ipsec_integ_alg, integ_alg);
14640               return -99;
14641             }
14642         }
14643       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14644         ;
14645       else
14646         {
14647           clib_warning ("parse error '%U'", format_unformat_error, i);
14648           return -99;
14649         }
14650
14651     }
14652
14653   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14654
14655   mp->sad_id = ntohl (sad_id);
14656   mp->is_add = is_add;
14657   mp->protocol = protocol;
14658   mp->spi = ntohl (spi);
14659   mp->is_tunnel = is_tunnel;
14660   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14661   mp->crypto_algorithm = crypto_alg;
14662   mp->integrity_algorithm = integ_alg;
14663   mp->crypto_key_length = vec_len (ck);
14664   mp->integrity_key_length = vec_len (ik);
14665
14666   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14667     mp->crypto_key_length = sizeof (mp->crypto_key);
14668
14669   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14670     mp->integrity_key_length = sizeof (mp->integrity_key);
14671
14672   if (ck)
14673     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14674   if (ik)
14675     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14676
14677   if (is_tunnel)
14678     {
14679       if (is_tunnel_ipv6)
14680         {
14681           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14682                        sizeof (ip6_address_t));
14683           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14684                        sizeof (ip6_address_t));
14685         }
14686       else
14687         {
14688           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14689                        sizeof (ip4_address_t));
14690           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14691                        sizeof (ip4_address_t));
14692         }
14693     }
14694
14695   S (mp);
14696   W (ret);
14697   return ret;
14698 }
14699
14700 static int
14701 api_ipsec_sa_set_key (vat_main_t * vam)
14702 {
14703   unformat_input_t *i = vam->input;
14704   vl_api_ipsec_sa_set_key_t *mp;
14705   u32 sa_id;
14706   u8 *ck = 0, *ik = 0;
14707   int ret;
14708
14709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14710     {
14711       if (unformat (i, "sa_id %d", &sa_id))
14712         ;
14713       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14714         ;
14715       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14716         ;
14717       else
14718         {
14719           clib_warning ("parse error '%U'", format_unformat_error, i);
14720           return -99;
14721         }
14722     }
14723
14724   M (IPSEC_SA_SET_KEY, mp);
14725
14726   mp->sa_id = ntohl (sa_id);
14727   mp->crypto_key_length = vec_len (ck);
14728   mp->integrity_key_length = vec_len (ik);
14729
14730   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14731     mp->crypto_key_length = sizeof (mp->crypto_key);
14732
14733   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14734     mp->integrity_key_length = sizeof (mp->integrity_key);
14735
14736   if (ck)
14737     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14738   if (ik)
14739     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14740
14741   S (mp);
14742   W (ret);
14743   return ret;
14744 }
14745
14746 static int
14747 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14748 {
14749   unformat_input_t *i = vam->input;
14750   vl_api_ipsec_tunnel_if_add_del_t *mp;
14751   u32 local_spi = 0, remote_spi = 0;
14752   u32 crypto_alg = 0, integ_alg = 0;
14753   u8 *lck = NULL, *rck = NULL;
14754   u8 *lik = NULL, *rik = NULL;
14755   ip4_address_t local_ip = { {0} };
14756   ip4_address_t remote_ip = { {0} };
14757   u8 is_add = 1;
14758   u8 esn = 0;
14759   u8 anti_replay = 0;
14760   int ret;
14761
14762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14763     {
14764       if (unformat (i, "del"))
14765         is_add = 0;
14766       else if (unformat (i, "esn"))
14767         esn = 1;
14768       else if (unformat (i, "anti_replay"))
14769         anti_replay = 1;
14770       else if (unformat (i, "local_spi %d", &local_spi))
14771         ;
14772       else if (unformat (i, "remote_spi %d", &remote_spi))
14773         ;
14774       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14775         ;
14776       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14777         ;
14778       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14779         ;
14780       else
14781         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14782         ;
14783       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14784         ;
14785       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14786         ;
14787       else
14788         if (unformat
14789             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14790         {
14791           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14792               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14793             {
14794               errmsg ("unsupported crypto-alg: '%U'\n",
14795                       format_ipsec_crypto_alg, crypto_alg);
14796               return -99;
14797             }
14798         }
14799       else
14800         if (unformat
14801             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14802         {
14803           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14804               integ_alg >= IPSEC_INTEG_N_ALG)
14805             {
14806               errmsg ("unsupported integ-alg: '%U'\n",
14807                       format_ipsec_integ_alg, integ_alg);
14808               return -99;
14809             }
14810         }
14811       else
14812         {
14813           errmsg ("parse error '%U'\n", format_unformat_error, i);
14814           return -99;
14815         }
14816     }
14817
14818   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14819
14820   mp->is_add = is_add;
14821   mp->esn = esn;
14822   mp->anti_replay = anti_replay;
14823
14824   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14825   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14826
14827   mp->local_spi = htonl (local_spi);
14828   mp->remote_spi = htonl (remote_spi);
14829   mp->crypto_alg = (u8) crypto_alg;
14830
14831   mp->local_crypto_key_len = 0;
14832   if (lck)
14833     {
14834       mp->local_crypto_key_len = vec_len (lck);
14835       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14836         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14837       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14838     }
14839
14840   mp->remote_crypto_key_len = 0;
14841   if (rck)
14842     {
14843       mp->remote_crypto_key_len = vec_len (rck);
14844       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14845         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14846       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14847     }
14848
14849   mp->integ_alg = (u8) integ_alg;
14850
14851   mp->local_integ_key_len = 0;
14852   if (lik)
14853     {
14854       mp->local_integ_key_len = vec_len (lik);
14855       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14856         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14857       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14858     }
14859
14860   mp->remote_integ_key_len = 0;
14861   if (rik)
14862     {
14863       mp->remote_integ_key_len = vec_len (rik);
14864       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14865         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14866       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14867     }
14868
14869   S (mp);
14870   W (ret);
14871   return ret;
14872 }
14873
14874 static void
14875 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14876 {
14877   vat_main_t *vam = &vat_main;
14878
14879   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14880          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14881          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14882          "tunnel_src_addr %U tunnel_dst_addr %U "
14883          "salt %u seq_outbound %lu last_seq_inbound %lu "
14884          "replay_window %lu total_data_size %lu\n",
14885          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14886          mp->protocol,
14887          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14888          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14889          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14890          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14891          mp->tunnel_src_addr,
14892          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14893          mp->tunnel_dst_addr,
14894          ntohl (mp->salt),
14895          clib_net_to_host_u64 (mp->seq_outbound),
14896          clib_net_to_host_u64 (mp->last_seq_inbound),
14897          clib_net_to_host_u64 (mp->replay_window),
14898          clib_net_to_host_u64 (mp->total_data_size));
14899 }
14900
14901 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14902 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14903
14904 static void vl_api_ipsec_sa_details_t_handler_json
14905   (vl_api_ipsec_sa_details_t * mp)
14906 {
14907   vat_main_t *vam = &vat_main;
14908   vat_json_node_t *node = NULL;
14909   struct in_addr src_ip4, dst_ip4;
14910   struct in6_addr src_ip6, dst_ip6;
14911
14912   if (VAT_JSON_ARRAY != vam->json_tree.type)
14913     {
14914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14915       vat_json_init_array (&vam->json_tree);
14916     }
14917   node = vat_json_array_add (&vam->json_tree);
14918
14919   vat_json_init_object (node);
14920   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14922   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14923   vat_json_object_add_uint (node, "proto", mp->protocol);
14924   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14925   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14926   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14927   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14928   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14929   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14930   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14931                              mp->crypto_key_len);
14932   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14933                              mp->integ_key_len);
14934   if (mp->is_tunnel_ip6)
14935     {
14936       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14937       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14938       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14939       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14940     }
14941   else
14942     {
14943       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14944       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14945       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14946       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14947     }
14948   vat_json_object_add_uint (node, "replay_window",
14949                             clib_net_to_host_u64 (mp->replay_window));
14950   vat_json_object_add_uint (node, "total_data_size",
14951                             clib_net_to_host_u64 (mp->total_data_size));
14952
14953 }
14954
14955 static int
14956 api_ipsec_sa_dump (vat_main_t * vam)
14957 {
14958   unformat_input_t *i = vam->input;
14959   vl_api_ipsec_sa_dump_t *mp;
14960   vl_api_control_ping_t *mp_ping;
14961   u32 sa_id = ~0;
14962   int ret;
14963
14964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14965     {
14966       if (unformat (i, "sa_id %d", &sa_id))
14967         ;
14968       else
14969         {
14970           clib_warning ("parse error '%U'", format_unformat_error, i);
14971           return -99;
14972         }
14973     }
14974
14975   M (IPSEC_SA_DUMP, mp);
14976
14977   mp->sa_id = ntohl (sa_id);
14978
14979   S (mp);
14980
14981   /* Use a control ping for synchronization */
14982   M (CONTROL_PING, mp_ping);
14983   S (mp_ping);
14984
14985   W (ret);
14986   return ret;
14987 }
14988
14989 static int
14990 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14991 {
14992   unformat_input_t *i = vam->input;
14993   vl_api_ipsec_tunnel_if_set_key_t *mp;
14994   u32 sw_if_index = ~0;
14995   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14996   u8 *key = 0;
14997   u32 alg = ~0;
14998   int ret;
14999
15000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15001     {
15002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15003         ;
15004       else
15005         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15006         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15007       else
15008         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15009         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15010       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15011         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15012       else
15013         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15014         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15015       else if (unformat (i, "%U", unformat_hex_string, &key))
15016         ;
15017       else
15018         {
15019           clib_warning ("parse error '%U'", format_unformat_error, i);
15020           return -99;
15021         }
15022     }
15023
15024   if (sw_if_index == ~0)
15025     {
15026       errmsg ("interface must be specified");
15027       return -99;
15028     }
15029
15030   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15031     {
15032       errmsg ("key type must be specified");
15033       return -99;
15034     }
15035
15036   if (alg == ~0)
15037     {
15038       errmsg ("algorithm must be specified");
15039       return -99;
15040     }
15041
15042   if (vec_len (key) == 0)
15043     {
15044       errmsg ("key must be specified");
15045       return -99;
15046     }
15047
15048   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15049
15050   mp->sw_if_index = htonl (sw_if_index);
15051   mp->alg = alg;
15052   mp->key_type = key_type;
15053   mp->key_len = vec_len (key);
15054   clib_memcpy (mp->key, key, vec_len (key));
15055
15056   S (mp);
15057   W (ret);
15058
15059   return ret;
15060 }
15061
15062 static int
15063 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15064 {
15065   unformat_input_t *i = vam->input;
15066   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15067   u32 sw_if_index = ~0;
15068   u32 sa_id = ~0;
15069   u8 is_outbound = (u8) ~ 0;
15070   int ret;
15071
15072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15073     {
15074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15075         ;
15076       else if (unformat (i, "sa_id %d", &sa_id))
15077         ;
15078       else if (unformat (i, "outbound"))
15079         is_outbound = 1;
15080       else if (unformat (i, "inbound"))
15081         is_outbound = 0;
15082       else
15083         {
15084           clib_warning ("parse error '%U'", format_unformat_error, i);
15085           return -99;
15086         }
15087     }
15088
15089   if (sw_if_index == ~0)
15090     {
15091       errmsg ("interface must be specified");
15092       return -99;
15093     }
15094
15095   if (sa_id == ~0)
15096     {
15097       errmsg ("SA ID must be specified");
15098       return -99;
15099     }
15100
15101   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15102
15103   mp->sw_if_index = htonl (sw_if_index);
15104   mp->sa_id = htonl (sa_id);
15105   mp->is_outbound = is_outbound;
15106
15107   S (mp);
15108   W (ret);
15109
15110   return ret;
15111 }
15112
15113 static int
15114 api_ikev2_profile_add_del (vat_main_t * vam)
15115 {
15116   unformat_input_t *i = vam->input;
15117   vl_api_ikev2_profile_add_del_t *mp;
15118   u8 is_add = 1;
15119   u8 *name = 0;
15120   int ret;
15121
15122   const char *valid_chars = "a-zA-Z0-9_";
15123
15124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15125     {
15126       if (unformat (i, "del"))
15127         is_add = 0;
15128       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15129         vec_add1 (name, 0);
15130       else
15131         {
15132           errmsg ("parse error '%U'", format_unformat_error, i);
15133           return -99;
15134         }
15135     }
15136
15137   if (!vec_len (name))
15138     {
15139       errmsg ("profile name must be specified");
15140       return -99;
15141     }
15142
15143   if (vec_len (name) > 64)
15144     {
15145       errmsg ("profile name too long");
15146       return -99;
15147     }
15148
15149   M (IKEV2_PROFILE_ADD_DEL, mp);
15150
15151   clib_memcpy (mp->name, name, vec_len (name));
15152   mp->is_add = is_add;
15153   vec_free (name);
15154
15155   S (mp);
15156   W (ret);
15157   return ret;
15158 }
15159
15160 static int
15161 api_ikev2_profile_set_auth (vat_main_t * vam)
15162 {
15163   unformat_input_t *i = vam->input;
15164   vl_api_ikev2_profile_set_auth_t *mp;
15165   u8 *name = 0;
15166   u8 *data = 0;
15167   u32 auth_method = 0;
15168   u8 is_hex = 0;
15169   int ret;
15170
15171   const char *valid_chars = "a-zA-Z0-9_";
15172
15173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15174     {
15175       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15176         vec_add1 (name, 0);
15177       else if (unformat (i, "auth_method %U",
15178                          unformat_ikev2_auth_method, &auth_method))
15179         ;
15180       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15181         is_hex = 1;
15182       else if (unformat (i, "auth_data %v", &data))
15183         ;
15184       else
15185         {
15186           errmsg ("parse error '%U'", format_unformat_error, i);
15187           return -99;
15188         }
15189     }
15190
15191   if (!vec_len (name))
15192     {
15193       errmsg ("profile name must be specified");
15194       return -99;
15195     }
15196
15197   if (vec_len (name) > 64)
15198     {
15199       errmsg ("profile name too long");
15200       return -99;
15201     }
15202
15203   if (!vec_len (data))
15204     {
15205       errmsg ("auth_data must be specified");
15206       return -99;
15207     }
15208
15209   if (!auth_method)
15210     {
15211       errmsg ("auth_method must be specified");
15212       return -99;
15213     }
15214
15215   M (IKEV2_PROFILE_SET_AUTH, mp);
15216
15217   mp->is_hex = is_hex;
15218   mp->auth_method = (u8) auth_method;
15219   mp->data_len = vec_len (data);
15220   clib_memcpy (mp->name, name, vec_len (name));
15221   clib_memcpy (mp->data, data, vec_len (data));
15222   vec_free (name);
15223   vec_free (data);
15224
15225   S (mp);
15226   W (ret);
15227   return ret;
15228 }
15229
15230 static int
15231 api_ikev2_profile_set_id (vat_main_t * vam)
15232 {
15233   unformat_input_t *i = vam->input;
15234   vl_api_ikev2_profile_set_id_t *mp;
15235   u8 *name = 0;
15236   u8 *data = 0;
15237   u8 is_local = 0;
15238   u32 id_type = 0;
15239   ip4_address_t ip4;
15240   int ret;
15241
15242   const char *valid_chars = "a-zA-Z0-9_";
15243
15244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15245     {
15246       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15247         vec_add1 (name, 0);
15248       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15249         ;
15250       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15251         {
15252           data = vec_new (u8, 4);
15253           clib_memcpy (data, ip4.as_u8, 4);
15254         }
15255       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15256         ;
15257       else if (unformat (i, "id_data %v", &data))
15258         ;
15259       else if (unformat (i, "local"))
15260         is_local = 1;
15261       else if (unformat (i, "remote"))
15262         is_local = 0;
15263       else
15264         {
15265           errmsg ("parse error '%U'", format_unformat_error, i);
15266           return -99;
15267         }
15268     }
15269
15270   if (!vec_len (name))
15271     {
15272       errmsg ("profile name must be specified");
15273       return -99;
15274     }
15275
15276   if (vec_len (name) > 64)
15277     {
15278       errmsg ("profile name too long");
15279       return -99;
15280     }
15281
15282   if (!vec_len (data))
15283     {
15284       errmsg ("id_data must be specified");
15285       return -99;
15286     }
15287
15288   if (!id_type)
15289     {
15290       errmsg ("id_type must be specified");
15291       return -99;
15292     }
15293
15294   M (IKEV2_PROFILE_SET_ID, mp);
15295
15296   mp->is_local = is_local;
15297   mp->id_type = (u8) id_type;
15298   mp->data_len = vec_len (data);
15299   clib_memcpy (mp->name, name, vec_len (name));
15300   clib_memcpy (mp->data, data, vec_len (data));
15301   vec_free (name);
15302   vec_free (data);
15303
15304   S (mp);
15305   W (ret);
15306   return ret;
15307 }
15308
15309 static int
15310 api_ikev2_profile_set_ts (vat_main_t * vam)
15311 {
15312   unformat_input_t *i = vam->input;
15313   vl_api_ikev2_profile_set_ts_t *mp;
15314   u8 *name = 0;
15315   u8 is_local = 0;
15316   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15317   ip4_address_t start_addr, end_addr;
15318
15319   const char *valid_chars = "a-zA-Z0-9_";
15320   int ret;
15321
15322   start_addr.as_u32 = 0;
15323   end_addr.as_u32 = (u32) ~ 0;
15324
15325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15326     {
15327       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15328         vec_add1 (name, 0);
15329       else if (unformat (i, "protocol %d", &proto))
15330         ;
15331       else if (unformat (i, "start_port %d", &start_port))
15332         ;
15333       else if (unformat (i, "end_port %d", &end_port))
15334         ;
15335       else
15336         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15337         ;
15338       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15339         ;
15340       else if (unformat (i, "local"))
15341         is_local = 1;
15342       else if (unformat (i, "remote"))
15343         is_local = 0;
15344       else
15345         {
15346           errmsg ("parse error '%U'", format_unformat_error, i);
15347           return -99;
15348         }
15349     }
15350
15351   if (!vec_len (name))
15352     {
15353       errmsg ("profile name must be specified");
15354       return -99;
15355     }
15356
15357   if (vec_len (name) > 64)
15358     {
15359       errmsg ("profile name too long");
15360       return -99;
15361     }
15362
15363   M (IKEV2_PROFILE_SET_TS, mp);
15364
15365   mp->is_local = is_local;
15366   mp->proto = (u8) proto;
15367   mp->start_port = (u16) start_port;
15368   mp->end_port = (u16) end_port;
15369   mp->start_addr = start_addr.as_u32;
15370   mp->end_addr = end_addr.as_u32;
15371   clib_memcpy (mp->name, name, vec_len (name));
15372   vec_free (name);
15373
15374   S (mp);
15375   W (ret);
15376   return ret;
15377 }
15378
15379 static int
15380 api_ikev2_set_local_key (vat_main_t * vam)
15381 {
15382   unformat_input_t *i = vam->input;
15383   vl_api_ikev2_set_local_key_t *mp;
15384   u8 *file = 0;
15385   int ret;
15386
15387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15388     {
15389       if (unformat (i, "file %v", &file))
15390         vec_add1 (file, 0);
15391       else
15392         {
15393           errmsg ("parse error '%U'", format_unformat_error, i);
15394           return -99;
15395         }
15396     }
15397
15398   if (!vec_len (file))
15399     {
15400       errmsg ("RSA key file must be specified");
15401       return -99;
15402     }
15403
15404   if (vec_len (file) > 256)
15405     {
15406       errmsg ("file name too long");
15407       return -99;
15408     }
15409
15410   M (IKEV2_SET_LOCAL_KEY, mp);
15411
15412   clib_memcpy (mp->key_file, file, vec_len (file));
15413   vec_free (file);
15414
15415   S (mp);
15416   W (ret);
15417   return ret;
15418 }
15419
15420 static int
15421 api_ikev2_set_responder (vat_main_t * vam)
15422 {
15423   unformat_input_t *i = vam->input;
15424   vl_api_ikev2_set_responder_t *mp;
15425   int ret;
15426   u8 *name = 0;
15427   u32 sw_if_index = ~0;
15428   ip4_address_t address;
15429
15430   const char *valid_chars = "a-zA-Z0-9_";
15431
15432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15433     {
15434       if (unformat
15435           (i, "%U interface %d address %U", unformat_token, valid_chars,
15436            &name, &sw_if_index, unformat_ip4_address, &address))
15437         vec_add1 (name, 0);
15438       else
15439         {
15440           errmsg ("parse error '%U'", format_unformat_error, i);
15441           return -99;
15442         }
15443     }
15444
15445   if (!vec_len (name))
15446     {
15447       errmsg ("profile name must be specified");
15448       return -99;
15449     }
15450
15451   if (vec_len (name) > 64)
15452     {
15453       errmsg ("profile name too long");
15454       return -99;
15455     }
15456
15457   M (IKEV2_SET_RESPONDER, mp);
15458
15459   clib_memcpy (mp->name, name, vec_len (name));
15460   vec_free (name);
15461
15462   mp->sw_if_index = sw_if_index;
15463   clib_memcpy (mp->address, &address, sizeof (address));
15464
15465   S (mp);
15466   W (ret);
15467   return ret;
15468 }
15469
15470 static int
15471 api_ikev2_set_ike_transforms (vat_main_t * vam)
15472 {
15473   unformat_input_t *i = vam->input;
15474   vl_api_ikev2_set_ike_transforms_t *mp;
15475   int ret;
15476   u8 *name = 0;
15477   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15478
15479   const char *valid_chars = "a-zA-Z0-9_";
15480
15481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15482     {
15483       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15484                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15485         vec_add1 (name, 0);
15486       else
15487         {
15488           errmsg ("parse error '%U'", format_unformat_error, i);
15489           return -99;
15490         }
15491     }
15492
15493   if (!vec_len (name))
15494     {
15495       errmsg ("profile name must be specified");
15496       return -99;
15497     }
15498
15499   if (vec_len (name) > 64)
15500     {
15501       errmsg ("profile name too long");
15502       return -99;
15503     }
15504
15505   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15506
15507   clib_memcpy (mp->name, name, vec_len (name));
15508   vec_free (name);
15509   mp->crypto_alg = crypto_alg;
15510   mp->crypto_key_size = crypto_key_size;
15511   mp->integ_alg = integ_alg;
15512   mp->dh_group = dh_group;
15513
15514   S (mp);
15515   W (ret);
15516   return ret;
15517 }
15518
15519
15520 static int
15521 api_ikev2_set_esp_transforms (vat_main_t * vam)
15522 {
15523   unformat_input_t *i = vam->input;
15524   vl_api_ikev2_set_esp_transforms_t *mp;
15525   int ret;
15526   u8 *name = 0;
15527   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15528
15529   const char *valid_chars = "a-zA-Z0-9_";
15530
15531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15532     {
15533       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15534                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15535         vec_add1 (name, 0);
15536       else
15537         {
15538           errmsg ("parse error '%U'", format_unformat_error, i);
15539           return -99;
15540         }
15541     }
15542
15543   if (!vec_len (name))
15544     {
15545       errmsg ("profile name must be specified");
15546       return -99;
15547     }
15548
15549   if (vec_len (name) > 64)
15550     {
15551       errmsg ("profile name too long");
15552       return -99;
15553     }
15554
15555   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15556
15557   clib_memcpy (mp->name, name, vec_len (name));
15558   vec_free (name);
15559   mp->crypto_alg = crypto_alg;
15560   mp->crypto_key_size = crypto_key_size;
15561   mp->integ_alg = integ_alg;
15562   mp->dh_group = dh_group;
15563
15564   S (mp);
15565   W (ret);
15566   return ret;
15567 }
15568
15569 static int
15570 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15571 {
15572   unformat_input_t *i = vam->input;
15573   vl_api_ikev2_set_sa_lifetime_t *mp;
15574   int ret;
15575   u8 *name = 0;
15576   u64 lifetime, lifetime_maxdata;
15577   u32 lifetime_jitter, handover;
15578
15579   const char *valid_chars = "a-zA-Z0-9_";
15580
15581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15582     {
15583       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15584                     &lifetime, &lifetime_jitter, &handover,
15585                     &lifetime_maxdata))
15586         vec_add1 (name, 0);
15587       else
15588         {
15589           errmsg ("parse error '%U'", format_unformat_error, i);
15590           return -99;
15591         }
15592     }
15593
15594   if (!vec_len (name))
15595     {
15596       errmsg ("profile name must be specified");
15597       return -99;
15598     }
15599
15600   if (vec_len (name) > 64)
15601     {
15602       errmsg ("profile name too long");
15603       return -99;
15604     }
15605
15606   M (IKEV2_SET_SA_LIFETIME, mp);
15607
15608   clib_memcpy (mp->name, name, vec_len (name));
15609   vec_free (name);
15610   mp->lifetime = lifetime;
15611   mp->lifetime_jitter = lifetime_jitter;
15612   mp->handover = handover;
15613   mp->lifetime_maxdata = lifetime_maxdata;
15614
15615   S (mp);
15616   W (ret);
15617   return ret;
15618 }
15619
15620 static int
15621 api_ikev2_initiate_sa_init (vat_main_t * vam)
15622 {
15623   unformat_input_t *i = vam->input;
15624   vl_api_ikev2_initiate_sa_init_t *mp;
15625   int ret;
15626   u8 *name = 0;
15627
15628   const char *valid_chars = "a-zA-Z0-9_";
15629
15630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15631     {
15632       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15633         vec_add1 (name, 0);
15634       else
15635         {
15636           errmsg ("parse error '%U'", format_unformat_error, i);
15637           return -99;
15638         }
15639     }
15640
15641   if (!vec_len (name))
15642     {
15643       errmsg ("profile name must be specified");
15644       return -99;
15645     }
15646
15647   if (vec_len (name) > 64)
15648     {
15649       errmsg ("profile name too long");
15650       return -99;
15651     }
15652
15653   M (IKEV2_INITIATE_SA_INIT, mp);
15654
15655   clib_memcpy (mp->name, name, vec_len (name));
15656   vec_free (name);
15657
15658   S (mp);
15659   W (ret);
15660   return ret;
15661 }
15662
15663 static int
15664 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15665 {
15666   unformat_input_t *i = vam->input;
15667   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15668   int ret;
15669   u64 ispi;
15670
15671
15672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15673     {
15674       if (unformat (i, "%lx", &ispi))
15675         ;
15676       else
15677         {
15678           errmsg ("parse error '%U'", format_unformat_error, i);
15679           return -99;
15680         }
15681     }
15682
15683   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15684
15685   mp->ispi = ispi;
15686
15687   S (mp);
15688   W (ret);
15689   return ret;
15690 }
15691
15692 static int
15693 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15694 {
15695   unformat_input_t *i = vam->input;
15696   vl_api_ikev2_initiate_del_child_sa_t *mp;
15697   int ret;
15698   u32 ispi;
15699
15700
15701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (i, "%x", &ispi))
15704         ;
15705       else
15706         {
15707           errmsg ("parse error '%U'", format_unformat_error, i);
15708           return -99;
15709         }
15710     }
15711
15712   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15713
15714   mp->ispi = ispi;
15715
15716   S (mp);
15717   W (ret);
15718   return ret;
15719 }
15720
15721 static int
15722 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15723 {
15724   unformat_input_t *i = vam->input;
15725   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15726   int ret;
15727   u32 ispi;
15728
15729
15730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (i, "%x", &ispi))
15733         ;
15734       else
15735         {
15736           errmsg ("parse error '%U'", format_unformat_error, i);
15737           return -99;
15738         }
15739     }
15740
15741   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15742
15743   mp->ispi = ispi;
15744
15745   S (mp);
15746   W (ret);
15747   return ret;
15748 }
15749
15750 /*
15751  * MAP
15752  */
15753 static int
15754 api_map_add_domain (vat_main_t * vam)
15755 {
15756   unformat_input_t *i = vam->input;
15757   vl_api_map_add_domain_t *mp;
15758
15759   ip4_address_t ip4_prefix;
15760   ip6_address_t ip6_prefix;
15761   ip6_address_t ip6_src;
15762   u32 num_m_args = 0;
15763   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15764     0, psid_length = 0;
15765   u8 is_translation = 0;
15766   u32 mtu = 0;
15767   u32 ip6_src_len = 128;
15768   int ret;
15769
15770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15771     {
15772       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15773                     &ip4_prefix, &ip4_prefix_len))
15774         num_m_args++;
15775       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15776                          &ip6_prefix, &ip6_prefix_len))
15777         num_m_args++;
15778       else
15779         if (unformat
15780             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15781              &ip6_src_len))
15782         num_m_args++;
15783       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15784         num_m_args++;
15785       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15786         num_m_args++;
15787       else if (unformat (i, "psid-offset %d", &psid_offset))
15788         num_m_args++;
15789       else if (unformat (i, "psid-len %d", &psid_length))
15790         num_m_args++;
15791       else if (unformat (i, "mtu %d", &mtu))
15792         num_m_args++;
15793       else if (unformat (i, "map-t"))
15794         is_translation = 1;
15795       else
15796         {
15797           clib_warning ("parse error '%U'", format_unformat_error, i);
15798           return -99;
15799         }
15800     }
15801
15802   if (num_m_args < 3)
15803     {
15804       errmsg ("mandatory argument(s) missing");
15805       return -99;
15806     }
15807
15808   /* Construct the API message */
15809   M (MAP_ADD_DOMAIN, mp);
15810
15811   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15812   mp->ip4_prefix_len = ip4_prefix_len;
15813
15814   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15815   mp->ip6_prefix_len = ip6_prefix_len;
15816
15817   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15818   mp->ip6_src_prefix_len = ip6_src_len;
15819
15820   mp->ea_bits_len = ea_bits_len;
15821   mp->psid_offset = psid_offset;
15822   mp->psid_length = psid_length;
15823   mp->is_translation = is_translation;
15824   mp->mtu = htons (mtu);
15825
15826   /* send it... */
15827   S (mp);
15828
15829   /* Wait for a reply, return good/bad news  */
15830   W (ret);
15831   return ret;
15832 }
15833
15834 static int
15835 api_map_del_domain (vat_main_t * vam)
15836 {
15837   unformat_input_t *i = vam->input;
15838   vl_api_map_del_domain_t *mp;
15839
15840   u32 num_m_args = 0;
15841   u32 index;
15842   int ret;
15843
15844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15845     {
15846       if (unformat (i, "index %d", &index))
15847         num_m_args++;
15848       else
15849         {
15850           clib_warning ("parse error '%U'", format_unformat_error, i);
15851           return -99;
15852         }
15853     }
15854
15855   if (num_m_args != 1)
15856     {
15857       errmsg ("mandatory argument(s) missing");
15858       return -99;
15859     }
15860
15861   /* Construct the API message */
15862   M (MAP_DEL_DOMAIN, mp);
15863
15864   mp->index = ntohl (index);
15865
15866   /* send it... */
15867   S (mp);
15868
15869   /* Wait for a reply, return good/bad news  */
15870   W (ret);
15871   return ret;
15872 }
15873
15874 static int
15875 api_map_add_del_rule (vat_main_t * vam)
15876 {
15877   unformat_input_t *i = vam->input;
15878   vl_api_map_add_del_rule_t *mp;
15879   u8 is_add = 1;
15880   ip6_address_t ip6_dst;
15881   u32 num_m_args = 0, index, psid = 0;
15882   int ret;
15883
15884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15885     {
15886       if (unformat (i, "index %d", &index))
15887         num_m_args++;
15888       else if (unformat (i, "psid %d", &psid))
15889         num_m_args++;
15890       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15891         num_m_args++;
15892       else if (unformat (i, "del"))
15893         {
15894           is_add = 0;
15895         }
15896       else
15897         {
15898           clib_warning ("parse error '%U'", format_unformat_error, i);
15899           return -99;
15900         }
15901     }
15902
15903   /* Construct the API message */
15904   M (MAP_ADD_DEL_RULE, mp);
15905
15906   mp->index = ntohl (index);
15907   mp->is_add = is_add;
15908   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15909   mp->psid = ntohs (psid);
15910
15911   /* send it... */
15912   S (mp);
15913
15914   /* Wait for a reply, return good/bad news  */
15915   W (ret);
15916   return ret;
15917 }
15918
15919 static int
15920 api_map_domain_dump (vat_main_t * vam)
15921 {
15922   vl_api_map_domain_dump_t *mp;
15923   vl_api_control_ping_t *mp_ping;
15924   int ret;
15925
15926   /* Construct the API message */
15927   M (MAP_DOMAIN_DUMP, mp);
15928
15929   /* send it... */
15930   S (mp);
15931
15932   /* Use a control ping for synchronization */
15933   MPING (CONTROL_PING, mp_ping);
15934   S (mp_ping);
15935
15936   W (ret);
15937   return ret;
15938 }
15939
15940 static int
15941 api_map_rule_dump (vat_main_t * vam)
15942 {
15943   unformat_input_t *i = vam->input;
15944   vl_api_map_rule_dump_t *mp;
15945   vl_api_control_ping_t *mp_ping;
15946   u32 domain_index = ~0;
15947   int ret;
15948
15949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15950     {
15951       if (unformat (i, "index %u", &domain_index))
15952         ;
15953       else
15954         break;
15955     }
15956
15957   if (domain_index == ~0)
15958     {
15959       clib_warning ("parse error: domain index expected");
15960       return -99;
15961     }
15962
15963   /* Construct the API message */
15964   M (MAP_RULE_DUMP, mp);
15965
15966   mp->domain_index = htonl (domain_index);
15967
15968   /* send it... */
15969   S (mp);
15970
15971   /* Use a control ping for synchronization */
15972   MPING (CONTROL_PING, mp_ping);
15973   S (mp_ping);
15974
15975   W (ret);
15976   return ret;
15977 }
15978
15979 static void vl_api_map_add_domain_reply_t_handler
15980   (vl_api_map_add_domain_reply_t * mp)
15981 {
15982   vat_main_t *vam = &vat_main;
15983   i32 retval = ntohl (mp->retval);
15984
15985   if (vam->async_mode)
15986     {
15987       vam->async_errors += (retval < 0);
15988     }
15989   else
15990     {
15991       vam->retval = retval;
15992       vam->result_ready = 1;
15993     }
15994 }
15995
15996 static void vl_api_map_add_domain_reply_t_handler_json
15997   (vl_api_map_add_domain_reply_t * mp)
15998 {
15999   vat_main_t *vam = &vat_main;
16000   vat_json_node_t node;
16001
16002   vat_json_init_object (&node);
16003   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16004   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16005
16006   vat_json_print (vam->ofp, &node);
16007   vat_json_free (&node);
16008
16009   vam->retval = ntohl (mp->retval);
16010   vam->result_ready = 1;
16011 }
16012
16013 static int
16014 api_get_first_msg_id (vat_main_t * vam)
16015 {
16016   vl_api_get_first_msg_id_t *mp;
16017   unformat_input_t *i = vam->input;
16018   u8 *name;
16019   u8 name_set = 0;
16020   int ret;
16021
16022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16023     {
16024       if (unformat (i, "client %s", &name))
16025         name_set = 1;
16026       else
16027         break;
16028     }
16029
16030   if (name_set == 0)
16031     {
16032       errmsg ("missing client name");
16033       return -99;
16034     }
16035   vec_add1 (name, 0);
16036
16037   if (vec_len (name) > 63)
16038     {
16039       errmsg ("client name too long");
16040       return -99;
16041     }
16042
16043   M (GET_FIRST_MSG_ID, mp);
16044   clib_memcpy (mp->name, name, vec_len (name));
16045   S (mp);
16046   W (ret);
16047   return ret;
16048 }
16049
16050 static int
16051 api_cop_interface_enable_disable (vat_main_t * vam)
16052 {
16053   unformat_input_t *line_input = vam->input;
16054   vl_api_cop_interface_enable_disable_t *mp;
16055   u32 sw_if_index = ~0;
16056   u8 enable_disable = 1;
16057   int ret;
16058
16059   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (line_input, "disable"))
16062         enable_disable = 0;
16063       if (unformat (line_input, "enable"))
16064         enable_disable = 1;
16065       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16066                          vam, &sw_if_index))
16067         ;
16068       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16069         ;
16070       else
16071         break;
16072     }
16073
16074   if (sw_if_index == ~0)
16075     {
16076       errmsg ("missing interface name or sw_if_index");
16077       return -99;
16078     }
16079
16080   /* Construct the API message */
16081   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16082   mp->sw_if_index = ntohl (sw_if_index);
16083   mp->enable_disable = enable_disable;
16084
16085   /* send it... */
16086   S (mp);
16087   /* Wait for the reply */
16088   W (ret);
16089   return ret;
16090 }
16091
16092 static int
16093 api_cop_whitelist_enable_disable (vat_main_t * vam)
16094 {
16095   unformat_input_t *line_input = vam->input;
16096   vl_api_cop_whitelist_enable_disable_t *mp;
16097   u32 sw_if_index = ~0;
16098   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16099   u32 fib_id = 0;
16100   int ret;
16101
16102   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (line_input, "ip4"))
16105         ip4 = 1;
16106       else if (unformat (line_input, "ip6"))
16107         ip6 = 1;
16108       else if (unformat (line_input, "default"))
16109         default_cop = 1;
16110       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16111                          vam, &sw_if_index))
16112         ;
16113       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16114         ;
16115       else if (unformat (line_input, "fib-id %d", &fib_id))
16116         ;
16117       else
16118         break;
16119     }
16120
16121   if (sw_if_index == ~0)
16122     {
16123       errmsg ("missing interface name or sw_if_index");
16124       return -99;
16125     }
16126
16127   /* Construct the API message */
16128   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16129   mp->sw_if_index = ntohl (sw_if_index);
16130   mp->fib_id = ntohl (fib_id);
16131   mp->ip4 = ip4;
16132   mp->ip6 = ip6;
16133   mp->default_cop = default_cop;
16134
16135   /* send it... */
16136   S (mp);
16137   /* Wait for the reply */
16138   W (ret);
16139   return ret;
16140 }
16141
16142 static int
16143 api_get_node_graph (vat_main_t * vam)
16144 {
16145   vl_api_get_node_graph_t *mp;
16146   int ret;
16147
16148   M (GET_NODE_GRAPH, mp);
16149
16150   /* send it... */
16151   S (mp);
16152   /* Wait for the reply */
16153   W (ret);
16154   return ret;
16155 }
16156
16157 /* *INDENT-OFF* */
16158 /** Used for parsing LISP eids */
16159 typedef CLIB_PACKED(struct{
16160   u8 addr[16];   /**< eid address */
16161   u32 len;       /**< prefix length if IP */
16162   u8 type;      /**< type of eid */
16163 }) lisp_eid_vat_t;
16164 /* *INDENT-ON* */
16165
16166 static uword
16167 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16168 {
16169   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16170
16171   memset (a, 0, sizeof (a[0]));
16172
16173   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16174     {
16175       a->type = 0;              /* ipv4 type */
16176     }
16177   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16178     {
16179       a->type = 1;              /* ipv6 type */
16180     }
16181   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16182     {
16183       a->type = 2;              /* mac type */
16184     }
16185   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16186     {
16187       a->type = 3;              /* NSH type */
16188       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16189       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16190     }
16191   else
16192     {
16193       return 0;
16194     }
16195
16196   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16197     {
16198       return 0;
16199     }
16200
16201   return 1;
16202 }
16203
16204 static int
16205 lisp_eid_size_vat (u8 type)
16206 {
16207   switch (type)
16208     {
16209     case 0:
16210       return 4;
16211     case 1:
16212       return 16;
16213     case 2:
16214       return 6;
16215     case 3:
16216       return 5;
16217     }
16218   return 0;
16219 }
16220
16221 static void
16222 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16223 {
16224   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16225 }
16226
16227 static int
16228 api_one_add_del_locator_set (vat_main_t * vam)
16229 {
16230   unformat_input_t *input = vam->input;
16231   vl_api_one_add_del_locator_set_t *mp;
16232   u8 is_add = 1;
16233   u8 *locator_set_name = NULL;
16234   u8 locator_set_name_set = 0;
16235   vl_api_local_locator_t locator, *locators = 0;
16236   u32 sw_if_index, priority, weight;
16237   u32 data_len = 0;
16238
16239   int ret;
16240   /* Parse args required to build the message */
16241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16242     {
16243       if (unformat (input, "del"))
16244         {
16245           is_add = 0;
16246         }
16247       else if (unformat (input, "locator-set %s", &locator_set_name))
16248         {
16249           locator_set_name_set = 1;
16250         }
16251       else if (unformat (input, "sw_if_index %u p %u w %u",
16252                          &sw_if_index, &priority, &weight))
16253         {
16254           locator.sw_if_index = htonl (sw_if_index);
16255           locator.priority = priority;
16256           locator.weight = weight;
16257           vec_add1 (locators, locator);
16258         }
16259       else
16260         if (unformat
16261             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16262              &sw_if_index, &priority, &weight))
16263         {
16264           locator.sw_if_index = htonl (sw_if_index);
16265           locator.priority = priority;
16266           locator.weight = weight;
16267           vec_add1 (locators, locator);
16268         }
16269       else
16270         break;
16271     }
16272
16273   if (locator_set_name_set == 0)
16274     {
16275       errmsg ("missing locator-set name");
16276       vec_free (locators);
16277       return -99;
16278     }
16279
16280   if (vec_len (locator_set_name) > 64)
16281     {
16282       errmsg ("locator-set name too long");
16283       vec_free (locator_set_name);
16284       vec_free (locators);
16285       return -99;
16286     }
16287   vec_add1 (locator_set_name, 0);
16288
16289   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16290
16291   /* Construct the API message */
16292   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16293
16294   mp->is_add = is_add;
16295   clib_memcpy (mp->locator_set_name, locator_set_name,
16296                vec_len (locator_set_name));
16297   vec_free (locator_set_name);
16298
16299   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16300   if (locators)
16301     clib_memcpy (mp->locators, locators, data_len);
16302   vec_free (locators);
16303
16304   /* send it... */
16305   S (mp);
16306
16307   /* Wait for a reply... */
16308   W (ret);
16309   return ret;
16310 }
16311
16312 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16313
16314 static int
16315 api_one_add_del_locator (vat_main_t * vam)
16316 {
16317   unformat_input_t *input = vam->input;
16318   vl_api_one_add_del_locator_t *mp;
16319   u32 tmp_if_index = ~0;
16320   u32 sw_if_index = ~0;
16321   u8 sw_if_index_set = 0;
16322   u8 sw_if_index_if_name_set = 0;
16323   u32 priority = ~0;
16324   u8 priority_set = 0;
16325   u32 weight = ~0;
16326   u8 weight_set = 0;
16327   u8 is_add = 1;
16328   u8 *locator_set_name = NULL;
16329   u8 locator_set_name_set = 0;
16330   int ret;
16331
16332   /* Parse args required to build the message */
16333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16334     {
16335       if (unformat (input, "del"))
16336         {
16337           is_add = 0;
16338         }
16339       else if (unformat (input, "locator-set %s", &locator_set_name))
16340         {
16341           locator_set_name_set = 1;
16342         }
16343       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16344                          &tmp_if_index))
16345         {
16346           sw_if_index_if_name_set = 1;
16347           sw_if_index = tmp_if_index;
16348         }
16349       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16350         {
16351           sw_if_index_set = 1;
16352           sw_if_index = tmp_if_index;
16353         }
16354       else if (unformat (input, "p %d", &priority))
16355         {
16356           priority_set = 1;
16357         }
16358       else if (unformat (input, "w %d", &weight))
16359         {
16360           weight_set = 1;
16361         }
16362       else
16363         break;
16364     }
16365
16366   if (locator_set_name_set == 0)
16367     {
16368       errmsg ("missing locator-set name");
16369       return -99;
16370     }
16371
16372   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16373     {
16374       errmsg ("missing sw_if_index");
16375       vec_free (locator_set_name);
16376       return -99;
16377     }
16378
16379   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16380     {
16381       errmsg ("cannot use both params interface name and sw_if_index");
16382       vec_free (locator_set_name);
16383       return -99;
16384     }
16385
16386   if (priority_set == 0)
16387     {
16388       errmsg ("missing locator-set priority");
16389       vec_free (locator_set_name);
16390       return -99;
16391     }
16392
16393   if (weight_set == 0)
16394     {
16395       errmsg ("missing locator-set weight");
16396       vec_free (locator_set_name);
16397       return -99;
16398     }
16399
16400   if (vec_len (locator_set_name) > 64)
16401     {
16402       errmsg ("locator-set name too long");
16403       vec_free (locator_set_name);
16404       return -99;
16405     }
16406   vec_add1 (locator_set_name, 0);
16407
16408   /* Construct the API message */
16409   M (ONE_ADD_DEL_LOCATOR, mp);
16410
16411   mp->is_add = is_add;
16412   mp->sw_if_index = ntohl (sw_if_index);
16413   mp->priority = priority;
16414   mp->weight = weight;
16415   clib_memcpy (mp->locator_set_name, locator_set_name,
16416                vec_len (locator_set_name));
16417   vec_free (locator_set_name);
16418
16419   /* send it... */
16420   S (mp);
16421
16422   /* Wait for a reply... */
16423   W (ret);
16424   return ret;
16425 }
16426
16427 #define api_lisp_add_del_locator api_one_add_del_locator
16428
16429 uword
16430 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16431 {
16432   u32 *key_id = va_arg (*args, u32 *);
16433   u8 *s = 0;
16434
16435   if (unformat (input, "%s", &s))
16436     {
16437       if (!strcmp ((char *) s, "sha1"))
16438         key_id[0] = HMAC_SHA_1_96;
16439       else if (!strcmp ((char *) s, "sha256"))
16440         key_id[0] = HMAC_SHA_256_128;
16441       else
16442         {
16443           clib_warning ("invalid key_id: '%s'", s);
16444           key_id[0] = HMAC_NO_KEY;
16445         }
16446     }
16447   else
16448     return 0;
16449
16450   vec_free (s);
16451   return 1;
16452 }
16453
16454 static int
16455 api_one_add_del_local_eid (vat_main_t * vam)
16456 {
16457   unformat_input_t *input = vam->input;
16458   vl_api_one_add_del_local_eid_t *mp;
16459   u8 is_add = 1;
16460   u8 eid_set = 0;
16461   lisp_eid_vat_t _eid, *eid = &_eid;
16462   u8 *locator_set_name = 0;
16463   u8 locator_set_name_set = 0;
16464   u32 vni = 0;
16465   u16 key_id = 0;
16466   u8 *key = 0;
16467   int ret;
16468
16469   /* Parse args required to build the message */
16470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16471     {
16472       if (unformat (input, "del"))
16473         {
16474           is_add = 0;
16475         }
16476       else if (unformat (input, "vni %d", &vni))
16477         {
16478           ;
16479         }
16480       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16481         {
16482           eid_set = 1;
16483         }
16484       else if (unformat (input, "locator-set %s", &locator_set_name))
16485         {
16486           locator_set_name_set = 1;
16487         }
16488       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16489         ;
16490       else if (unformat (input, "secret-key %_%v%_", &key))
16491         ;
16492       else
16493         break;
16494     }
16495
16496   if (locator_set_name_set == 0)
16497     {
16498       errmsg ("missing locator-set name");
16499       return -99;
16500     }
16501
16502   if (0 == eid_set)
16503     {
16504       errmsg ("EID address not set!");
16505       vec_free (locator_set_name);
16506       return -99;
16507     }
16508
16509   if (key && (0 == key_id))
16510     {
16511       errmsg ("invalid key_id!");
16512       return -99;
16513     }
16514
16515   if (vec_len (key) > 64)
16516     {
16517       errmsg ("key too long");
16518       vec_free (key);
16519       return -99;
16520     }
16521
16522   if (vec_len (locator_set_name) > 64)
16523     {
16524       errmsg ("locator-set name too long");
16525       vec_free (locator_set_name);
16526       return -99;
16527     }
16528   vec_add1 (locator_set_name, 0);
16529
16530   /* Construct the API message */
16531   M (ONE_ADD_DEL_LOCAL_EID, mp);
16532
16533   mp->is_add = is_add;
16534   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16535   mp->eid_type = eid->type;
16536   mp->prefix_len = eid->len;
16537   mp->vni = clib_host_to_net_u32 (vni);
16538   mp->key_id = clib_host_to_net_u16 (key_id);
16539   clib_memcpy (mp->locator_set_name, locator_set_name,
16540                vec_len (locator_set_name));
16541   clib_memcpy (mp->key, key, vec_len (key));
16542
16543   vec_free (locator_set_name);
16544   vec_free (key);
16545
16546   /* send it... */
16547   S (mp);
16548
16549   /* Wait for a reply... */
16550   W (ret);
16551   return ret;
16552 }
16553
16554 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16555
16556 static int
16557 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16558 {
16559   u32 dp_table = 0, vni = 0;;
16560   unformat_input_t *input = vam->input;
16561   vl_api_gpe_add_del_fwd_entry_t *mp;
16562   u8 is_add = 1;
16563   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16564   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16565   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16566   u32 action = ~0, w;
16567   ip4_address_t rmt_rloc4, lcl_rloc4;
16568   ip6_address_t rmt_rloc6, lcl_rloc6;
16569   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16570   int ret;
16571
16572   memset (&rloc, 0, sizeof (rloc));
16573
16574   /* Parse args required to build the message */
16575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16576     {
16577       if (unformat (input, "del"))
16578         is_add = 0;
16579       else if (unformat (input, "add"))
16580         is_add = 1;
16581       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16582         {
16583           rmt_eid_set = 1;
16584         }
16585       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16586         {
16587           lcl_eid_set = 1;
16588         }
16589       else if (unformat (input, "vrf %d", &dp_table))
16590         ;
16591       else if (unformat (input, "bd %d", &dp_table))
16592         ;
16593       else if (unformat (input, "vni %d", &vni))
16594         ;
16595       else if (unformat (input, "w %d", &w))
16596         {
16597           if (!curr_rloc)
16598             {
16599               errmsg ("No RLOC configured for setting priority/weight!");
16600               return -99;
16601             }
16602           curr_rloc->weight = w;
16603         }
16604       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16605                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16606         {
16607           rloc.is_ip4 = 1;
16608
16609           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16610           rloc.weight = 0;
16611           vec_add1 (lcl_locs, rloc);
16612
16613           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16614           vec_add1 (rmt_locs, rloc);
16615           /* weight saved in rmt loc */
16616           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16617         }
16618       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16619                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16620         {
16621           rloc.is_ip4 = 0;
16622           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16623           rloc.weight = 0;
16624           vec_add1 (lcl_locs, rloc);
16625
16626           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16627           vec_add1 (rmt_locs, rloc);
16628           /* weight saved in rmt loc */
16629           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16630         }
16631       else if (unformat (input, "action %d", &action))
16632         {
16633           ;
16634         }
16635       else
16636         {
16637           clib_warning ("parse error '%U'", format_unformat_error, input);
16638           return -99;
16639         }
16640     }
16641
16642   if (!rmt_eid_set)
16643     {
16644       errmsg ("remote eid addresses not set");
16645       return -99;
16646     }
16647
16648   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16649     {
16650       errmsg ("eid types don't match");
16651       return -99;
16652     }
16653
16654   if (0 == rmt_locs && (u32) ~ 0 == action)
16655     {
16656       errmsg ("action not set for negative mapping");
16657       return -99;
16658     }
16659
16660   /* Construct the API message */
16661   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16662       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16663
16664   mp->is_add = is_add;
16665   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16666   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16667   mp->eid_type = rmt_eid->type;
16668   mp->dp_table = clib_host_to_net_u32 (dp_table);
16669   mp->vni = clib_host_to_net_u32 (vni);
16670   mp->rmt_len = rmt_eid->len;
16671   mp->lcl_len = lcl_eid->len;
16672   mp->action = action;
16673
16674   if (0 != rmt_locs && 0 != lcl_locs)
16675     {
16676       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16677       clib_memcpy (mp->locs, lcl_locs,
16678                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16679
16680       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16681       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16682                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16683     }
16684   vec_free (lcl_locs);
16685   vec_free (rmt_locs);
16686
16687   /* send it... */
16688   S (mp);
16689
16690   /* Wait for a reply... */
16691   W (ret);
16692   return ret;
16693 }
16694
16695 static int
16696 api_one_add_del_map_server (vat_main_t * vam)
16697 {
16698   unformat_input_t *input = vam->input;
16699   vl_api_one_add_del_map_server_t *mp;
16700   u8 is_add = 1;
16701   u8 ipv4_set = 0;
16702   u8 ipv6_set = 0;
16703   ip4_address_t ipv4;
16704   ip6_address_t ipv6;
16705   int ret;
16706
16707   /* Parse args required to build the message */
16708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16709     {
16710       if (unformat (input, "del"))
16711         {
16712           is_add = 0;
16713         }
16714       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16715         {
16716           ipv4_set = 1;
16717         }
16718       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16719         {
16720           ipv6_set = 1;
16721         }
16722       else
16723         break;
16724     }
16725
16726   if (ipv4_set && ipv6_set)
16727     {
16728       errmsg ("both eid v4 and v6 addresses set");
16729       return -99;
16730     }
16731
16732   if (!ipv4_set && !ipv6_set)
16733     {
16734       errmsg ("eid addresses not set");
16735       return -99;
16736     }
16737
16738   /* Construct the API message */
16739   M (ONE_ADD_DEL_MAP_SERVER, mp);
16740
16741   mp->is_add = is_add;
16742   if (ipv6_set)
16743     {
16744       mp->is_ipv6 = 1;
16745       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16746     }
16747   else
16748     {
16749       mp->is_ipv6 = 0;
16750       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16751     }
16752
16753   /* send it... */
16754   S (mp);
16755
16756   /* Wait for a reply... */
16757   W (ret);
16758   return ret;
16759 }
16760
16761 #define api_lisp_add_del_map_server api_one_add_del_map_server
16762
16763 static int
16764 api_one_add_del_map_resolver (vat_main_t * vam)
16765 {
16766   unformat_input_t *input = vam->input;
16767   vl_api_one_add_del_map_resolver_t *mp;
16768   u8 is_add = 1;
16769   u8 ipv4_set = 0;
16770   u8 ipv6_set = 0;
16771   ip4_address_t ipv4;
16772   ip6_address_t ipv6;
16773   int ret;
16774
16775   /* Parse args required to build the message */
16776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16777     {
16778       if (unformat (input, "del"))
16779         {
16780           is_add = 0;
16781         }
16782       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16783         {
16784           ipv4_set = 1;
16785         }
16786       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16787         {
16788           ipv6_set = 1;
16789         }
16790       else
16791         break;
16792     }
16793
16794   if (ipv4_set && ipv6_set)
16795     {
16796       errmsg ("both eid v4 and v6 addresses set");
16797       return -99;
16798     }
16799
16800   if (!ipv4_set && !ipv6_set)
16801     {
16802       errmsg ("eid addresses not set");
16803       return -99;
16804     }
16805
16806   /* Construct the API message */
16807   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16808
16809   mp->is_add = is_add;
16810   if (ipv6_set)
16811     {
16812       mp->is_ipv6 = 1;
16813       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16814     }
16815   else
16816     {
16817       mp->is_ipv6 = 0;
16818       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16819     }
16820
16821   /* send it... */
16822   S (mp);
16823
16824   /* Wait for a reply... */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16830
16831 static int
16832 api_lisp_gpe_enable_disable (vat_main_t * vam)
16833 {
16834   unformat_input_t *input = vam->input;
16835   vl_api_gpe_enable_disable_t *mp;
16836   u8 is_set = 0;
16837   u8 is_en = 1;
16838   int ret;
16839
16840   /* Parse args required to build the message */
16841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16842     {
16843       if (unformat (input, "enable"))
16844         {
16845           is_set = 1;
16846           is_en = 1;
16847         }
16848       else if (unformat (input, "disable"))
16849         {
16850           is_set = 1;
16851           is_en = 0;
16852         }
16853       else
16854         break;
16855     }
16856
16857   if (is_set == 0)
16858     {
16859       errmsg ("Value not set");
16860       return -99;
16861     }
16862
16863   /* Construct the API message */
16864   M (GPE_ENABLE_DISABLE, mp);
16865
16866   mp->is_en = is_en;
16867
16868   /* send it... */
16869   S (mp);
16870
16871   /* Wait for a reply... */
16872   W (ret);
16873   return ret;
16874 }
16875
16876 static int
16877 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16878 {
16879   unformat_input_t *input = vam->input;
16880   vl_api_one_rloc_probe_enable_disable_t *mp;
16881   u8 is_set = 0;
16882   u8 is_en = 0;
16883   int ret;
16884
16885   /* Parse args required to build the message */
16886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16887     {
16888       if (unformat (input, "enable"))
16889         {
16890           is_set = 1;
16891           is_en = 1;
16892         }
16893       else if (unformat (input, "disable"))
16894         is_set = 1;
16895       else
16896         break;
16897     }
16898
16899   if (!is_set)
16900     {
16901       errmsg ("Value not set");
16902       return -99;
16903     }
16904
16905   /* Construct the API message */
16906   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16907
16908   mp->is_enabled = is_en;
16909
16910   /* send it... */
16911   S (mp);
16912
16913   /* Wait for a reply... */
16914   W (ret);
16915   return ret;
16916 }
16917
16918 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16919
16920 static int
16921 api_one_map_register_enable_disable (vat_main_t * vam)
16922 {
16923   unformat_input_t *input = vam->input;
16924   vl_api_one_map_register_enable_disable_t *mp;
16925   u8 is_set = 0;
16926   u8 is_en = 0;
16927   int ret;
16928
16929   /* Parse args required to build the message */
16930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16931     {
16932       if (unformat (input, "enable"))
16933         {
16934           is_set = 1;
16935           is_en = 1;
16936         }
16937       else if (unformat (input, "disable"))
16938         is_set = 1;
16939       else
16940         break;
16941     }
16942
16943   if (!is_set)
16944     {
16945       errmsg ("Value not set");
16946       return -99;
16947     }
16948
16949   /* Construct the API message */
16950   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16951
16952   mp->is_enabled = is_en;
16953
16954   /* send it... */
16955   S (mp);
16956
16957   /* Wait for a reply... */
16958   W (ret);
16959   return ret;
16960 }
16961
16962 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16963
16964 static int
16965 api_one_enable_disable (vat_main_t * vam)
16966 {
16967   unformat_input_t *input = vam->input;
16968   vl_api_one_enable_disable_t *mp;
16969   u8 is_set = 0;
16970   u8 is_en = 0;
16971   int ret;
16972
16973   /* Parse args required to build the message */
16974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16975     {
16976       if (unformat (input, "enable"))
16977         {
16978           is_set = 1;
16979           is_en = 1;
16980         }
16981       else if (unformat (input, "disable"))
16982         {
16983           is_set = 1;
16984         }
16985       else
16986         break;
16987     }
16988
16989   if (!is_set)
16990     {
16991       errmsg ("Value not set");
16992       return -99;
16993     }
16994
16995   /* Construct the API message */
16996   M (ONE_ENABLE_DISABLE, mp);
16997
16998   mp->is_en = is_en;
16999
17000   /* send it... */
17001   S (mp);
17002
17003   /* Wait for a reply... */
17004   W (ret);
17005   return ret;
17006 }
17007
17008 #define api_lisp_enable_disable api_one_enable_disable
17009
17010 static int
17011 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17012 {
17013   unformat_input_t *input = vam->input;
17014   vl_api_one_enable_disable_xtr_mode_t *mp;
17015   u8 is_set = 0;
17016   u8 is_en = 0;
17017   int ret;
17018
17019   /* Parse args required to build the message */
17020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17021     {
17022       if (unformat (input, "enable"))
17023         {
17024           is_set = 1;
17025           is_en = 1;
17026         }
17027       else if (unformat (input, "disable"))
17028         {
17029           is_set = 1;
17030         }
17031       else
17032         break;
17033     }
17034
17035   if (!is_set)
17036     {
17037       errmsg ("Value not set");
17038       return -99;
17039     }
17040
17041   /* Construct the API message */
17042   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17043
17044   mp->is_en = is_en;
17045
17046   /* send it... */
17047   S (mp);
17048
17049   /* Wait for a reply... */
17050   W (ret);
17051   return ret;
17052 }
17053
17054 static int
17055 api_one_show_xtr_mode (vat_main_t * vam)
17056 {
17057   vl_api_one_show_xtr_mode_t *mp;
17058   int ret;
17059
17060   /* Construct the API message */
17061   M (ONE_SHOW_XTR_MODE, mp);
17062
17063   /* send it... */
17064   S (mp);
17065
17066   /* Wait for a reply... */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 static int
17072 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17073 {
17074   unformat_input_t *input = vam->input;
17075   vl_api_one_enable_disable_pitr_mode_t *mp;
17076   u8 is_set = 0;
17077   u8 is_en = 0;
17078   int ret;
17079
17080   /* Parse args required to build the message */
17081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17082     {
17083       if (unformat (input, "enable"))
17084         {
17085           is_set = 1;
17086           is_en = 1;
17087         }
17088       else if (unformat (input, "disable"))
17089         {
17090           is_set = 1;
17091         }
17092       else
17093         break;
17094     }
17095
17096   if (!is_set)
17097     {
17098       errmsg ("Value not set");
17099       return -99;
17100     }
17101
17102   /* Construct the API message */
17103   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17104
17105   mp->is_en = is_en;
17106
17107   /* send it... */
17108   S (mp);
17109
17110   /* Wait for a reply... */
17111   W (ret);
17112   return ret;
17113 }
17114
17115 static int
17116 api_one_show_pitr_mode (vat_main_t * vam)
17117 {
17118   vl_api_one_show_pitr_mode_t *mp;
17119   int ret;
17120
17121   /* Construct the API message */
17122   M (ONE_SHOW_PITR_MODE, mp);
17123
17124   /* send it... */
17125   S (mp);
17126
17127   /* Wait for a reply... */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 static int
17133 api_one_enable_disable_petr_mode (vat_main_t * vam)
17134 {
17135   unformat_input_t *input = vam->input;
17136   vl_api_one_enable_disable_petr_mode_t *mp;
17137   u8 is_set = 0;
17138   u8 is_en = 0;
17139   int ret;
17140
17141   /* Parse args required to build the message */
17142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17143     {
17144       if (unformat (input, "enable"))
17145         {
17146           is_set = 1;
17147           is_en = 1;
17148         }
17149       else if (unformat (input, "disable"))
17150         {
17151           is_set = 1;
17152         }
17153       else
17154         break;
17155     }
17156
17157   if (!is_set)
17158     {
17159       errmsg ("Value not set");
17160       return -99;
17161     }
17162
17163   /* Construct the API message */
17164   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17165
17166   mp->is_en = is_en;
17167
17168   /* send it... */
17169   S (mp);
17170
17171   /* Wait for a reply... */
17172   W (ret);
17173   return ret;
17174 }
17175
17176 static int
17177 api_one_show_petr_mode (vat_main_t * vam)
17178 {
17179   vl_api_one_show_petr_mode_t *mp;
17180   int ret;
17181
17182   /* Construct the API message */
17183   M (ONE_SHOW_PETR_MODE, mp);
17184
17185   /* send it... */
17186   S (mp);
17187
17188   /* Wait for a reply... */
17189   W (ret);
17190   return ret;
17191 }
17192
17193 static int
17194 api_show_one_map_register_state (vat_main_t * vam)
17195 {
17196   vl_api_show_one_map_register_state_t *mp;
17197   int ret;
17198
17199   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17200
17201   /* send */
17202   S (mp);
17203
17204   /* wait for reply */
17205   W (ret);
17206   return ret;
17207 }
17208
17209 #define api_show_lisp_map_register_state api_show_one_map_register_state
17210
17211 static int
17212 api_show_one_rloc_probe_state (vat_main_t * vam)
17213 {
17214   vl_api_show_one_rloc_probe_state_t *mp;
17215   int ret;
17216
17217   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17218
17219   /* send */
17220   S (mp);
17221
17222   /* wait for reply */
17223   W (ret);
17224   return ret;
17225 }
17226
17227 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17228
17229 static int
17230 api_one_add_del_ndp_entry (vat_main_t * vam)
17231 {
17232   vl_api_one_add_del_ndp_entry_t *mp;
17233   unformat_input_t *input = vam->input;
17234   u8 is_add = 1;
17235   u8 mac_set = 0;
17236   u8 bd_set = 0;
17237   u8 ip_set = 0;
17238   u8 mac[6] = { 0, };
17239   u8 ip6[16] = { 0, };
17240   u32 bd = ~0;
17241   int ret;
17242
17243   /* Parse args required to build the message */
17244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17245     {
17246       if (unformat (input, "del"))
17247         is_add = 0;
17248       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17249         mac_set = 1;
17250       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17251         ip_set = 1;
17252       else if (unformat (input, "bd %d", &bd))
17253         bd_set = 1;
17254       else
17255         {
17256           errmsg ("parse error '%U'", format_unformat_error, input);
17257           return -99;
17258         }
17259     }
17260
17261   if (!bd_set || !ip_set || (!mac_set && is_add))
17262     {
17263       errmsg ("Missing BD, IP or MAC!");
17264       return -99;
17265     }
17266
17267   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17268   mp->is_add = is_add;
17269   clib_memcpy (mp->mac, mac, 6);
17270   mp->bd = clib_host_to_net_u32 (bd);
17271   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17272
17273   /* send */
17274   S (mp);
17275
17276   /* wait for reply */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 static int
17282 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17283 {
17284   vl_api_one_add_del_l2_arp_entry_t *mp;
17285   unformat_input_t *input = vam->input;
17286   u8 is_add = 1;
17287   u8 mac_set = 0;
17288   u8 bd_set = 0;
17289   u8 ip_set = 0;
17290   u8 mac[6] = { 0, };
17291   u32 ip4 = 0, bd = ~0;
17292   int ret;
17293
17294   /* Parse args required to build the message */
17295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17296     {
17297       if (unformat (input, "del"))
17298         is_add = 0;
17299       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17300         mac_set = 1;
17301       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17302         ip_set = 1;
17303       else if (unformat (input, "bd %d", &bd))
17304         bd_set = 1;
17305       else
17306         {
17307           errmsg ("parse error '%U'", format_unformat_error, input);
17308           return -99;
17309         }
17310     }
17311
17312   if (!bd_set || !ip_set || (!mac_set && is_add))
17313     {
17314       errmsg ("Missing BD, IP or MAC!");
17315       return -99;
17316     }
17317
17318   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17319   mp->is_add = is_add;
17320   clib_memcpy (mp->mac, mac, 6);
17321   mp->bd = clib_host_to_net_u32 (bd);
17322   mp->ip4 = ip4;
17323
17324   /* send */
17325   S (mp);
17326
17327   /* wait for reply */
17328   W (ret);
17329   return ret;
17330 }
17331
17332 static int
17333 api_one_ndp_bd_get (vat_main_t * vam)
17334 {
17335   vl_api_one_ndp_bd_get_t *mp;
17336   int ret;
17337
17338   M (ONE_NDP_BD_GET, mp);
17339
17340   /* send */
17341   S (mp);
17342
17343   /* wait for reply */
17344   W (ret);
17345   return ret;
17346 }
17347
17348 static int
17349 api_one_ndp_entries_get (vat_main_t * vam)
17350 {
17351   vl_api_one_ndp_entries_get_t *mp;
17352   unformat_input_t *input = vam->input;
17353   u8 bd_set = 0;
17354   u32 bd = ~0;
17355   int ret;
17356
17357   /* Parse args required to build the message */
17358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17359     {
17360       if (unformat (input, "bd %d", &bd))
17361         bd_set = 1;
17362       else
17363         {
17364           errmsg ("parse error '%U'", format_unformat_error, input);
17365           return -99;
17366         }
17367     }
17368
17369   if (!bd_set)
17370     {
17371       errmsg ("Expected bridge domain!");
17372       return -99;
17373     }
17374
17375   M (ONE_NDP_ENTRIES_GET, mp);
17376   mp->bd = clib_host_to_net_u32 (bd);
17377
17378   /* send */
17379   S (mp);
17380
17381   /* wait for reply */
17382   W (ret);
17383   return ret;
17384 }
17385
17386 static int
17387 api_one_l2_arp_bd_get (vat_main_t * vam)
17388 {
17389   vl_api_one_l2_arp_bd_get_t *mp;
17390   int ret;
17391
17392   M (ONE_L2_ARP_BD_GET, mp);
17393
17394   /* send */
17395   S (mp);
17396
17397   /* wait for reply */
17398   W (ret);
17399   return ret;
17400 }
17401
17402 static int
17403 api_one_l2_arp_entries_get (vat_main_t * vam)
17404 {
17405   vl_api_one_l2_arp_entries_get_t *mp;
17406   unformat_input_t *input = vam->input;
17407   u8 bd_set = 0;
17408   u32 bd = ~0;
17409   int ret;
17410
17411   /* Parse args required to build the message */
17412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17413     {
17414       if (unformat (input, "bd %d", &bd))
17415         bd_set = 1;
17416       else
17417         {
17418           errmsg ("parse error '%U'", format_unformat_error, input);
17419           return -99;
17420         }
17421     }
17422
17423   if (!bd_set)
17424     {
17425       errmsg ("Expected bridge domain!");
17426       return -99;
17427     }
17428
17429   M (ONE_L2_ARP_ENTRIES_GET, mp);
17430   mp->bd = clib_host_to_net_u32 (bd);
17431
17432   /* send */
17433   S (mp);
17434
17435   /* wait for reply */
17436   W (ret);
17437   return ret;
17438 }
17439
17440 static int
17441 api_one_stats_enable_disable (vat_main_t * vam)
17442 {
17443   vl_api_one_stats_enable_disable_t *mp;
17444   unformat_input_t *input = vam->input;
17445   u8 is_set = 0;
17446   u8 is_en = 0;
17447   int ret;
17448
17449   /* Parse args required to build the message */
17450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17451     {
17452       if (unformat (input, "enable"))
17453         {
17454           is_set = 1;
17455           is_en = 1;
17456         }
17457       else if (unformat (input, "disable"))
17458         {
17459           is_set = 1;
17460         }
17461       else
17462         break;
17463     }
17464
17465   if (!is_set)
17466     {
17467       errmsg ("Value not set");
17468       return -99;
17469     }
17470
17471   M (ONE_STATS_ENABLE_DISABLE, mp);
17472   mp->is_en = is_en;
17473
17474   /* send */
17475   S (mp);
17476
17477   /* wait for reply */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 static int
17483 api_show_one_stats_enable_disable (vat_main_t * vam)
17484 {
17485   vl_api_show_one_stats_enable_disable_t *mp;
17486   int ret;
17487
17488   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17489
17490   /* send */
17491   S (mp);
17492
17493   /* wait for reply */
17494   W (ret);
17495   return ret;
17496 }
17497
17498 static int
17499 api_show_one_map_request_mode (vat_main_t * vam)
17500 {
17501   vl_api_show_one_map_request_mode_t *mp;
17502   int ret;
17503
17504   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17505
17506   /* send */
17507   S (mp);
17508
17509   /* wait for reply */
17510   W (ret);
17511   return ret;
17512 }
17513
17514 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17515
17516 static int
17517 api_one_map_request_mode (vat_main_t * vam)
17518 {
17519   unformat_input_t *input = vam->input;
17520   vl_api_one_map_request_mode_t *mp;
17521   u8 mode = 0;
17522   int ret;
17523
17524   /* Parse args required to build the message */
17525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17526     {
17527       if (unformat (input, "dst-only"))
17528         mode = 0;
17529       else if (unformat (input, "src-dst"))
17530         mode = 1;
17531       else
17532         {
17533           errmsg ("parse error '%U'", format_unformat_error, input);
17534           return -99;
17535         }
17536     }
17537
17538   M (ONE_MAP_REQUEST_MODE, mp);
17539
17540   mp->mode = mode;
17541
17542   /* send */
17543   S (mp);
17544
17545   /* wait for reply */
17546   W (ret);
17547   return ret;
17548 }
17549
17550 #define api_lisp_map_request_mode api_one_map_request_mode
17551
17552 /**
17553  * Enable/disable ONE proxy ITR.
17554  *
17555  * @param vam vpp API test context
17556  * @return return code
17557  */
17558 static int
17559 api_one_pitr_set_locator_set (vat_main_t * vam)
17560 {
17561   u8 ls_name_set = 0;
17562   unformat_input_t *input = vam->input;
17563   vl_api_one_pitr_set_locator_set_t *mp;
17564   u8 is_add = 1;
17565   u8 *ls_name = 0;
17566   int ret;
17567
17568   /* Parse args required to build the message */
17569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17570     {
17571       if (unformat (input, "del"))
17572         is_add = 0;
17573       else if (unformat (input, "locator-set %s", &ls_name))
17574         ls_name_set = 1;
17575       else
17576         {
17577           errmsg ("parse error '%U'", format_unformat_error, input);
17578           return -99;
17579         }
17580     }
17581
17582   if (!ls_name_set)
17583     {
17584       errmsg ("locator-set name not set!");
17585       return -99;
17586     }
17587
17588   M (ONE_PITR_SET_LOCATOR_SET, mp);
17589
17590   mp->is_add = is_add;
17591   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17592   vec_free (ls_name);
17593
17594   /* send */
17595   S (mp);
17596
17597   /* wait for reply */
17598   W (ret);
17599   return ret;
17600 }
17601
17602 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17603
17604 static int
17605 api_one_nsh_set_locator_set (vat_main_t * vam)
17606 {
17607   u8 ls_name_set = 0;
17608   unformat_input_t *input = vam->input;
17609   vl_api_one_nsh_set_locator_set_t *mp;
17610   u8 is_add = 1;
17611   u8 *ls_name = 0;
17612   int ret;
17613
17614   /* Parse args required to build the message */
17615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17616     {
17617       if (unformat (input, "del"))
17618         is_add = 0;
17619       else if (unformat (input, "ls %s", &ls_name))
17620         ls_name_set = 1;
17621       else
17622         {
17623           errmsg ("parse error '%U'", format_unformat_error, input);
17624           return -99;
17625         }
17626     }
17627
17628   if (!ls_name_set && is_add)
17629     {
17630       errmsg ("locator-set name not set!");
17631       return -99;
17632     }
17633
17634   M (ONE_NSH_SET_LOCATOR_SET, mp);
17635
17636   mp->is_add = is_add;
17637   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17638   vec_free (ls_name);
17639
17640   /* send */
17641   S (mp);
17642
17643   /* wait for reply */
17644   W (ret);
17645   return ret;
17646 }
17647
17648 static int
17649 api_show_one_pitr (vat_main_t * vam)
17650 {
17651   vl_api_show_one_pitr_t *mp;
17652   int ret;
17653
17654   if (!vam->json_output)
17655     {
17656       print (vam->ofp, "%=20s", "lisp status:");
17657     }
17658
17659   M (SHOW_ONE_PITR, mp);
17660   /* send it... */
17661   S (mp);
17662
17663   /* Wait for a reply... */
17664   W (ret);
17665   return ret;
17666 }
17667
17668 #define api_show_lisp_pitr api_show_one_pitr
17669
17670 static int
17671 api_one_use_petr (vat_main_t * vam)
17672 {
17673   unformat_input_t *input = vam->input;
17674   vl_api_one_use_petr_t *mp;
17675   u8 is_add = 0;
17676   ip_address_t ip;
17677   int ret;
17678
17679   memset (&ip, 0, sizeof (ip));
17680
17681   /* Parse args required to build the message */
17682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17683     {
17684       if (unformat (input, "disable"))
17685         is_add = 0;
17686       else
17687         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17688         {
17689           is_add = 1;
17690           ip_addr_version (&ip) = IP4;
17691         }
17692       else
17693         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17694         {
17695           is_add = 1;
17696           ip_addr_version (&ip) = IP6;
17697         }
17698       else
17699         {
17700           errmsg ("parse error '%U'", format_unformat_error, input);
17701           return -99;
17702         }
17703     }
17704
17705   M (ONE_USE_PETR, mp);
17706
17707   mp->is_add = is_add;
17708   if (is_add)
17709     {
17710       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17711       if (mp->is_ip4)
17712         clib_memcpy (mp->address, &ip, 4);
17713       else
17714         clib_memcpy (mp->address, &ip, 16);
17715     }
17716
17717   /* send */
17718   S (mp);
17719
17720   /* wait for reply */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 #define api_lisp_use_petr api_one_use_petr
17726
17727 static int
17728 api_show_one_nsh_mapping (vat_main_t * vam)
17729 {
17730   vl_api_show_one_use_petr_t *mp;
17731   int ret;
17732
17733   if (!vam->json_output)
17734     {
17735       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17736     }
17737
17738   M (SHOW_ONE_NSH_MAPPING, mp);
17739   /* send it... */
17740   S (mp);
17741
17742   /* Wait for a reply... */
17743   W (ret);
17744   return ret;
17745 }
17746
17747 static int
17748 api_show_one_use_petr (vat_main_t * vam)
17749 {
17750   vl_api_show_one_use_petr_t *mp;
17751   int ret;
17752
17753   if (!vam->json_output)
17754     {
17755       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17756     }
17757
17758   M (SHOW_ONE_USE_PETR, mp);
17759   /* send it... */
17760   S (mp);
17761
17762   /* Wait for a reply... */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 #define api_show_lisp_use_petr api_show_one_use_petr
17768
17769 /**
17770  * Add/delete mapping between vni and vrf
17771  */
17772 static int
17773 api_one_eid_table_add_del_map (vat_main_t * vam)
17774 {
17775   unformat_input_t *input = vam->input;
17776   vl_api_one_eid_table_add_del_map_t *mp;
17777   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17778   u32 vni, vrf, bd_index;
17779   int ret;
17780
17781   /* Parse args required to build the message */
17782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17783     {
17784       if (unformat (input, "del"))
17785         is_add = 0;
17786       else if (unformat (input, "vrf %d", &vrf))
17787         vrf_set = 1;
17788       else if (unformat (input, "bd_index %d", &bd_index))
17789         bd_index_set = 1;
17790       else if (unformat (input, "vni %d", &vni))
17791         vni_set = 1;
17792       else
17793         break;
17794     }
17795
17796   if (!vni_set || (!vrf_set && !bd_index_set))
17797     {
17798       errmsg ("missing arguments!");
17799       return -99;
17800     }
17801
17802   if (vrf_set && bd_index_set)
17803     {
17804       errmsg ("error: both vrf and bd entered!");
17805       return -99;
17806     }
17807
17808   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17809
17810   mp->is_add = is_add;
17811   mp->vni = htonl (vni);
17812   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17813   mp->is_l2 = bd_index_set;
17814
17815   /* send */
17816   S (mp);
17817
17818   /* wait for reply */
17819   W (ret);
17820   return ret;
17821 }
17822
17823 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17824
17825 uword
17826 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17827 {
17828   u32 *action = va_arg (*args, u32 *);
17829   u8 *s = 0;
17830
17831   if (unformat (input, "%s", &s))
17832     {
17833       if (!strcmp ((char *) s, "no-action"))
17834         action[0] = 0;
17835       else if (!strcmp ((char *) s, "natively-forward"))
17836         action[0] = 1;
17837       else if (!strcmp ((char *) s, "send-map-request"))
17838         action[0] = 2;
17839       else if (!strcmp ((char *) s, "drop"))
17840         action[0] = 3;
17841       else
17842         {
17843           clib_warning ("invalid action: '%s'", s);
17844           action[0] = 3;
17845         }
17846     }
17847   else
17848     return 0;
17849
17850   vec_free (s);
17851   return 1;
17852 }
17853
17854 /**
17855  * Add/del remote mapping to/from ONE control plane
17856  *
17857  * @param vam vpp API test context
17858  * @return return code
17859  */
17860 static int
17861 api_one_add_del_remote_mapping (vat_main_t * vam)
17862 {
17863   unformat_input_t *input = vam->input;
17864   vl_api_one_add_del_remote_mapping_t *mp;
17865   u32 vni = 0;
17866   lisp_eid_vat_t _eid, *eid = &_eid;
17867   lisp_eid_vat_t _seid, *seid = &_seid;
17868   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17869   u32 action = ~0, p, w, data_len;
17870   ip4_address_t rloc4;
17871   ip6_address_t rloc6;
17872   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17873   int ret;
17874
17875   memset (&rloc, 0, sizeof (rloc));
17876
17877   /* Parse args required to build the message */
17878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17879     {
17880       if (unformat (input, "del-all"))
17881         {
17882           del_all = 1;
17883         }
17884       else if (unformat (input, "del"))
17885         {
17886           is_add = 0;
17887         }
17888       else if (unformat (input, "add"))
17889         {
17890           is_add = 1;
17891         }
17892       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17893         {
17894           eid_set = 1;
17895         }
17896       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17897         {
17898           seid_set = 1;
17899         }
17900       else if (unformat (input, "vni %d", &vni))
17901         {
17902           ;
17903         }
17904       else if (unformat (input, "p %d w %d", &p, &w))
17905         {
17906           if (!curr_rloc)
17907             {
17908               errmsg ("No RLOC configured for setting priority/weight!");
17909               return -99;
17910             }
17911           curr_rloc->priority = p;
17912           curr_rloc->weight = w;
17913         }
17914       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17915         {
17916           rloc.is_ip4 = 1;
17917           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17918           vec_add1 (rlocs, rloc);
17919           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17920         }
17921       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17922         {
17923           rloc.is_ip4 = 0;
17924           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17925           vec_add1 (rlocs, rloc);
17926           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17927         }
17928       else if (unformat (input, "action %U",
17929                          unformat_negative_mapping_action, &action))
17930         {
17931           ;
17932         }
17933       else
17934         {
17935           clib_warning ("parse error '%U'", format_unformat_error, input);
17936           return -99;
17937         }
17938     }
17939
17940   if (0 == eid_set)
17941     {
17942       errmsg ("missing params!");
17943       return -99;
17944     }
17945
17946   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17947     {
17948       errmsg ("no action set for negative map-reply!");
17949       return -99;
17950     }
17951
17952   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17953
17954   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17955   mp->is_add = is_add;
17956   mp->vni = htonl (vni);
17957   mp->action = (u8) action;
17958   mp->is_src_dst = seid_set;
17959   mp->eid_len = eid->len;
17960   mp->seid_len = seid->len;
17961   mp->del_all = del_all;
17962   mp->eid_type = eid->type;
17963   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17964   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17965
17966   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17967   clib_memcpy (mp->rlocs, rlocs, data_len);
17968   vec_free (rlocs);
17969
17970   /* send it... */
17971   S (mp);
17972
17973   /* Wait for a reply... */
17974   W (ret);
17975   return ret;
17976 }
17977
17978 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17979
17980 /**
17981  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17982  * forwarding entries in data-plane accordingly.
17983  *
17984  * @param vam vpp API test context
17985  * @return return code
17986  */
17987 static int
17988 api_one_add_del_adjacency (vat_main_t * vam)
17989 {
17990   unformat_input_t *input = vam->input;
17991   vl_api_one_add_del_adjacency_t *mp;
17992   u32 vni = 0;
17993   ip4_address_t leid4, reid4;
17994   ip6_address_t leid6, reid6;
17995   u8 reid_mac[6] = { 0 };
17996   u8 leid_mac[6] = { 0 };
17997   u8 reid_type, leid_type;
17998   u32 leid_len = 0, reid_len = 0, len;
17999   u8 is_add = 1;
18000   int ret;
18001
18002   leid_type = reid_type = (u8) ~ 0;
18003
18004   /* Parse args required to build the message */
18005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18006     {
18007       if (unformat (input, "del"))
18008         {
18009           is_add = 0;
18010         }
18011       else if (unformat (input, "add"))
18012         {
18013           is_add = 1;
18014         }
18015       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18016                          &reid4, &len))
18017         {
18018           reid_type = 0;        /* ipv4 */
18019           reid_len = len;
18020         }
18021       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18022                          &reid6, &len))
18023         {
18024           reid_type = 1;        /* ipv6 */
18025           reid_len = len;
18026         }
18027       else if (unformat (input, "reid %U", unformat_ethernet_address,
18028                          reid_mac))
18029         {
18030           reid_type = 2;        /* mac */
18031         }
18032       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18033                          &leid4, &len))
18034         {
18035           leid_type = 0;        /* ipv4 */
18036           leid_len = len;
18037         }
18038       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18039                          &leid6, &len))
18040         {
18041           leid_type = 1;        /* ipv6 */
18042           leid_len = len;
18043         }
18044       else if (unformat (input, "leid %U", unformat_ethernet_address,
18045                          leid_mac))
18046         {
18047           leid_type = 2;        /* mac */
18048         }
18049       else if (unformat (input, "vni %d", &vni))
18050         {
18051           ;
18052         }
18053       else
18054         {
18055           errmsg ("parse error '%U'", format_unformat_error, input);
18056           return -99;
18057         }
18058     }
18059
18060   if ((u8) ~ 0 == reid_type)
18061     {
18062       errmsg ("missing params!");
18063       return -99;
18064     }
18065
18066   if (leid_type != reid_type)
18067     {
18068       errmsg ("remote and local EIDs are of different types!");
18069       return -99;
18070     }
18071
18072   M (ONE_ADD_DEL_ADJACENCY, mp);
18073   mp->is_add = is_add;
18074   mp->vni = htonl (vni);
18075   mp->leid_len = leid_len;
18076   mp->reid_len = reid_len;
18077   mp->eid_type = reid_type;
18078
18079   switch (mp->eid_type)
18080     {
18081     case 0:
18082       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18083       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18084       break;
18085     case 1:
18086       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18087       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18088       break;
18089     case 2:
18090       clib_memcpy (mp->leid, leid_mac, 6);
18091       clib_memcpy (mp->reid, reid_mac, 6);
18092       break;
18093     default:
18094       errmsg ("unknown EID type %d!", mp->eid_type);
18095       return 0;
18096     }
18097
18098   /* send it... */
18099   S (mp);
18100
18101   /* Wait for a reply... */
18102   W (ret);
18103   return ret;
18104 }
18105
18106 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18107
18108 uword
18109 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18110 {
18111   u32 *mode = va_arg (*args, u32 *);
18112
18113   if (unformat (input, "lisp"))
18114     *mode = 0;
18115   else if (unformat (input, "vxlan"))
18116     *mode = 1;
18117   else
18118     return 0;
18119
18120   return 1;
18121 }
18122
18123 static int
18124 api_gpe_get_encap_mode (vat_main_t * vam)
18125 {
18126   vl_api_gpe_get_encap_mode_t *mp;
18127   int ret;
18128
18129   /* Construct the API message */
18130   M (GPE_GET_ENCAP_MODE, mp);
18131
18132   /* send it... */
18133   S (mp);
18134
18135   /* Wait for a reply... */
18136   W (ret);
18137   return ret;
18138 }
18139
18140 static int
18141 api_gpe_set_encap_mode (vat_main_t * vam)
18142 {
18143   unformat_input_t *input = vam->input;
18144   vl_api_gpe_set_encap_mode_t *mp;
18145   int ret;
18146   u32 mode = 0;
18147
18148   /* Parse args required to build the message */
18149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18150     {
18151       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18152         ;
18153       else
18154         break;
18155     }
18156
18157   /* Construct the API message */
18158   M (GPE_SET_ENCAP_MODE, mp);
18159
18160   mp->mode = mode;
18161
18162   /* send it... */
18163   S (mp);
18164
18165   /* Wait for a reply... */
18166   W (ret);
18167   return ret;
18168 }
18169
18170 static int
18171 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18172 {
18173   unformat_input_t *input = vam->input;
18174   vl_api_gpe_add_del_iface_t *mp;
18175   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18176   u32 dp_table = 0, vni = 0;
18177   int ret;
18178
18179   /* Parse args required to build the message */
18180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18181     {
18182       if (unformat (input, "up"))
18183         {
18184           action_set = 1;
18185           is_add = 1;
18186         }
18187       else if (unformat (input, "down"))
18188         {
18189           action_set = 1;
18190           is_add = 0;
18191         }
18192       else if (unformat (input, "table_id %d", &dp_table))
18193         {
18194           dp_table_set = 1;
18195         }
18196       else if (unformat (input, "bd_id %d", &dp_table))
18197         {
18198           dp_table_set = 1;
18199           is_l2 = 1;
18200         }
18201       else if (unformat (input, "vni %d", &vni))
18202         {
18203           vni_set = 1;
18204         }
18205       else
18206         break;
18207     }
18208
18209   if (action_set == 0)
18210     {
18211       errmsg ("Action not set");
18212       return -99;
18213     }
18214   if (dp_table_set == 0 || vni_set == 0)
18215     {
18216       errmsg ("vni and dp_table must be set");
18217       return -99;
18218     }
18219
18220   /* Construct the API message */
18221   M (GPE_ADD_DEL_IFACE, mp);
18222
18223   mp->is_add = is_add;
18224   mp->dp_table = clib_host_to_net_u32 (dp_table);
18225   mp->is_l2 = is_l2;
18226   mp->vni = clib_host_to_net_u32 (vni);
18227
18228   /* send it... */
18229   S (mp);
18230
18231   /* Wait for a reply... */
18232   W (ret);
18233   return ret;
18234 }
18235
18236 static int
18237 api_one_map_register_fallback_threshold (vat_main_t * vam)
18238 {
18239   unformat_input_t *input = vam->input;
18240   vl_api_one_map_register_fallback_threshold_t *mp;
18241   u32 value = 0;
18242   u8 is_set = 0;
18243   int ret;
18244
18245   /* Parse args required to build the message */
18246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18247     {
18248       if (unformat (input, "%u", &value))
18249         is_set = 1;
18250       else
18251         {
18252           clib_warning ("parse error '%U'", format_unformat_error, input);
18253           return -99;
18254         }
18255     }
18256
18257   if (!is_set)
18258     {
18259       errmsg ("fallback threshold value is missing!");
18260       return -99;
18261     }
18262
18263   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18264   mp->value = clib_host_to_net_u32 (value);
18265
18266   /* send it... */
18267   S (mp);
18268
18269   /* Wait for a reply... */
18270   W (ret);
18271   return ret;
18272 }
18273
18274 static int
18275 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18276 {
18277   vl_api_show_one_map_register_fallback_threshold_t *mp;
18278   int ret;
18279
18280   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18281
18282   /* send it... */
18283   S (mp);
18284
18285   /* Wait for a reply... */
18286   W (ret);
18287   return ret;
18288 }
18289
18290 uword
18291 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18292 {
18293   u32 *proto = va_arg (*args, u32 *);
18294
18295   if (unformat (input, "udp"))
18296     *proto = 1;
18297   else if (unformat (input, "api"))
18298     *proto = 2;
18299   else
18300     return 0;
18301
18302   return 1;
18303 }
18304
18305 static int
18306 api_one_set_transport_protocol (vat_main_t * vam)
18307 {
18308   unformat_input_t *input = vam->input;
18309   vl_api_one_set_transport_protocol_t *mp;
18310   u8 is_set = 0;
18311   u32 protocol = 0;
18312   int ret;
18313
18314   /* Parse args required to build the message */
18315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18316     {
18317       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18318         is_set = 1;
18319       else
18320         {
18321           clib_warning ("parse error '%U'", format_unformat_error, input);
18322           return -99;
18323         }
18324     }
18325
18326   if (!is_set)
18327     {
18328       errmsg ("Transport protocol missing!");
18329       return -99;
18330     }
18331
18332   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18333   mp->protocol = (u8) protocol;
18334
18335   /* send it... */
18336   S (mp);
18337
18338   /* Wait for a reply... */
18339   W (ret);
18340   return ret;
18341 }
18342
18343 static int
18344 api_one_get_transport_protocol (vat_main_t * vam)
18345 {
18346   vl_api_one_get_transport_protocol_t *mp;
18347   int ret;
18348
18349   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18350
18351   /* send it... */
18352   S (mp);
18353
18354   /* Wait for a reply... */
18355   W (ret);
18356   return ret;
18357 }
18358
18359 static int
18360 api_one_map_register_set_ttl (vat_main_t * vam)
18361 {
18362   unformat_input_t *input = vam->input;
18363   vl_api_one_map_register_set_ttl_t *mp;
18364   u32 ttl = 0;
18365   u8 is_set = 0;
18366   int ret;
18367
18368   /* Parse args required to build the message */
18369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18370     {
18371       if (unformat (input, "%u", &ttl))
18372         is_set = 1;
18373       else
18374         {
18375           clib_warning ("parse error '%U'", format_unformat_error, input);
18376           return -99;
18377         }
18378     }
18379
18380   if (!is_set)
18381     {
18382       errmsg ("TTL value missing!");
18383       return -99;
18384     }
18385
18386   M (ONE_MAP_REGISTER_SET_TTL, mp);
18387   mp->ttl = clib_host_to_net_u32 (ttl);
18388
18389   /* send it... */
18390   S (mp);
18391
18392   /* Wait for a reply... */
18393   W (ret);
18394   return ret;
18395 }
18396
18397 static int
18398 api_show_one_map_register_ttl (vat_main_t * vam)
18399 {
18400   vl_api_show_one_map_register_ttl_t *mp;
18401   int ret;
18402
18403   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18404
18405   /* send it... */
18406   S (mp);
18407
18408   /* Wait for a reply... */
18409   W (ret);
18410   return ret;
18411 }
18412
18413 /**
18414  * Add/del map request itr rlocs from ONE control plane and updates
18415  *
18416  * @param vam vpp API test context
18417  * @return return code
18418  */
18419 static int
18420 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18421 {
18422   unformat_input_t *input = vam->input;
18423   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18424   u8 *locator_set_name = 0;
18425   u8 locator_set_name_set = 0;
18426   u8 is_add = 1;
18427   int ret;
18428
18429   /* Parse args required to build the message */
18430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18431     {
18432       if (unformat (input, "del"))
18433         {
18434           is_add = 0;
18435         }
18436       else if (unformat (input, "%_%v%_", &locator_set_name))
18437         {
18438           locator_set_name_set = 1;
18439         }
18440       else
18441         {
18442           clib_warning ("parse error '%U'", format_unformat_error, input);
18443           return -99;
18444         }
18445     }
18446
18447   if (is_add && !locator_set_name_set)
18448     {
18449       errmsg ("itr-rloc is not set!");
18450       return -99;
18451     }
18452
18453   if (is_add && vec_len (locator_set_name) > 64)
18454     {
18455       errmsg ("itr-rloc locator-set name too long");
18456       vec_free (locator_set_name);
18457       return -99;
18458     }
18459
18460   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18461   mp->is_add = is_add;
18462   if (is_add)
18463     {
18464       clib_memcpy (mp->locator_set_name, locator_set_name,
18465                    vec_len (locator_set_name));
18466     }
18467   else
18468     {
18469       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18470     }
18471   vec_free (locator_set_name);
18472
18473   /* send it... */
18474   S (mp);
18475
18476   /* Wait for a reply... */
18477   W (ret);
18478   return ret;
18479 }
18480
18481 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18482
18483 static int
18484 api_one_locator_dump (vat_main_t * vam)
18485 {
18486   unformat_input_t *input = vam->input;
18487   vl_api_one_locator_dump_t *mp;
18488   vl_api_control_ping_t *mp_ping;
18489   u8 is_index_set = 0, is_name_set = 0;
18490   u8 *ls_name = 0;
18491   u32 ls_index = ~0;
18492   int ret;
18493
18494   /* Parse args required to build the message */
18495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18496     {
18497       if (unformat (input, "ls_name %_%v%_", &ls_name))
18498         {
18499           is_name_set = 1;
18500         }
18501       else if (unformat (input, "ls_index %d", &ls_index))
18502         {
18503           is_index_set = 1;
18504         }
18505       else
18506         {
18507           errmsg ("parse error '%U'", format_unformat_error, input);
18508           return -99;
18509         }
18510     }
18511
18512   if (!is_index_set && !is_name_set)
18513     {
18514       errmsg ("error: expected one of index or name!");
18515       return -99;
18516     }
18517
18518   if (is_index_set && is_name_set)
18519     {
18520       errmsg ("error: only one param expected!");
18521       return -99;
18522     }
18523
18524   if (vec_len (ls_name) > 62)
18525     {
18526       errmsg ("error: locator set name too long!");
18527       return -99;
18528     }
18529
18530   if (!vam->json_output)
18531     {
18532       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18533     }
18534
18535   M (ONE_LOCATOR_DUMP, mp);
18536   mp->is_index_set = is_index_set;
18537
18538   if (is_index_set)
18539     mp->ls_index = clib_host_to_net_u32 (ls_index);
18540   else
18541     {
18542       vec_add1 (ls_name, 0);
18543       strncpy ((char *) mp->ls_name, (char *) ls_name,
18544                sizeof (mp->ls_name) - 1);
18545     }
18546
18547   /* send it... */
18548   S (mp);
18549
18550   /* Use a control ping for synchronization */
18551   MPING (CONTROL_PING, mp_ping);
18552   S (mp_ping);
18553
18554   /* Wait for a reply... */
18555   W (ret);
18556   return ret;
18557 }
18558
18559 #define api_lisp_locator_dump api_one_locator_dump
18560
18561 static int
18562 api_one_locator_set_dump (vat_main_t * vam)
18563 {
18564   vl_api_one_locator_set_dump_t *mp;
18565   vl_api_control_ping_t *mp_ping;
18566   unformat_input_t *input = vam->input;
18567   u8 filter = 0;
18568   int ret;
18569
18570   /* Parse args required to build the message */
18571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18572     {
18573       if (unformat (input, "local"))
18574         {
18575           filter = 1;
18576         }
18577       else if (unformat (input, "remote"))
18578         {
18579           filter = 2;
18580         }
18581       else
18582         {
18583           errmsg ("parse error '%U'", format_unformat_error, input);
18584           return -99;
18585         }
18586     }
18587
18588   if (!vam->json_output)
18589     {
18590       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18591     }
18592
18593   M (ONE_LOCATOR_SET_DUMP, mp);
18594
18595   mp->filter = filter;
18596
18597   /* send it... */
18598   S (mp);
18599
18600   /* Use a control ping for synchronization */
18601   MPING (CONTROL_PING, mp_ping);
18602   S (mp_ping);
18603
18604   /* Wait for a reply... */
18605   W (ret);
18606   return ret;
18607 }
18608
18609 #define api_lisp_locator_set_dump api_one_locator_set_dump
18610
18611 static int
18612 api_one_eid_table_map_dump (vat_main_t * vam)
18613 {
18614   u8 is_l2 = 0;
18615   u8 mode_set = 0;
18616   unformat_input_t *input = vam->input;
18617   vl_api_one_eid_table_map_dump_t *mp;
18618   vl_api_control_ping_t *mp_ping;
18619   int ret;
18620
18621   /* Parse args required to build the message */
18622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18623     {
18624       if (unformat (input, "l2"))
18625         {
18626           is_l2 = 1;
18627           mode_set = 1;
18628         }
18629       else if (unformat (input, "l3"))
18630         {
18631           is_l2 = 0;
18632           mode_set = 1;
18633         }
18634       else
18635         {
18636           errmsg ("parse error '%U'", format_unformat_error, input);
18637           return -99;
18638         }
18639     }
18640
18641   if (!mode_set)
18642     {
18643       errmsg ("expected one of 'l2' or 'l3' parameter!");
18644       return -99;
18645     }
18646
18647   if (!vam->json_output)
18648     {
18649       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18650     }
18651
18652   M (ONE_EID_TABLE_MAP_DUMP, mp);
18653   mp->is_l2 = is_l2;
18654
18655   /* send it... */
18656   S (mp);
18657
18658   /* Use a control ping for synchronization */
18659   MPING (CONTROL_PING, mp_ping);
18660   S (mp_ping);
18661
18662   /* Wait for a reply... */
18663   W (ret);
18664   return ret;
18665 }
18666
18667 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18668
18669 static int
18670 api_one_eid_table_vni_dump (vat_main_t * vam)
18671 {
18672   vl_api_one_eid_table_vni_dump_t *mp;
18673   vl_api_control_ping_t *mp_ping;
18674   int ret;
18675
18676   if (!vam->json_output)
18677     {
18678       print (vam->ofp, "VNI");
18679     }
18680
18681   M (ONE_EID_TABLE_VNI_DUMP, mp);
18682
18683   /* send it... */
18684   S (mp);
18685
18686   /* Use a control ping for synchronization */
18687   MPING (CONTROL_PING, mp_ping);
18688   S (mp_ping);
18689
18690   /* Wait for a reply... */
18691   W (ret);
18692   return ret;
18693 }
18694
18695 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18696
18697 static int
18698 api_one_eid_table_dump (vat_main_t * vam)
18699 {
18700   unformat_input_t *i = vam->input;
18701   vl_api_one_eid_table_dump_t *mp;
18702   vl_api_control_ping_t *mp_ping;
18703   struct in_addr ip4;
18704   struct in6_addr ip6;
18705   u8 mac[6];
18706   u8 eid_type = ~0, eid_set = 0;
18707   u32 prefix_length = ~0, t, vni = 0;
18708   u8 filter = 0;
18709   int ret;
18710   lisp_nsh_api_t nsh;
18711
18712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18713     {
18714       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18715         {
18716           eid_set = 1;
18717           eid_type = 0;
18718           prefix_length = t;
18719         }
18720       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18721         {
18722           eid_set = 1;
18723           eid_type = 1;
18724           prefix_length = t;
18725         }
18726       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18727         {
18728           eid_set = 1;
18729           eid_type = 2;
18730         }
18731       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18732         {
18733           eid_set = 1;
18734           eid_type = 3;
18735         }
18736       else if (unformat (i, "vni %d", &t))
18737         {
18738           vni = t;
18739         }
18740       else if (unformat (i, "local"))
18741         {
18742           filter = 1;
18743         }
18744       else if (unformat (i, "remote"))
18745         {
18746           filter = 2;
18747         }
18748       else
18749         {
18750           errmsg ("parse error '%U'", format_unformat_error, i);
18751           return -99;
18752         }
18753     }
18754
18755   if (!vam->json_output)
18756     {
18757       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18758              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18759     }
18760
18761   M (ONE_EID_TABLE_DUMP, mp);
18762
18763   mp->filter = filter;
18764   if (eid_set)
18765     {
18766       mp->eid_set = 1;
18767       mp->vni = htonl (vni);
18768       mp->eid_type = eid_type;
18769       switch (eid_type)
18770         {
18771         case 0:
18772           mp->prefix_length = prefix_length;
18773           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18774           break;
18775         case 1:
18776           mp->prefix_length = prefix_length;
18777           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18778           break;
18779         case 2:
18780           clib_memcpy (mp->eid, mac, sizeof (mac));
18781           break;
18782         case 3:
18783           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18784           break;
18785         default:
18786           errmsg ("unknown EID type %d!", eid_type);
18787           return -99;
18788         }
18789     }
18790
18791   /* send it... */
18792   S (mp);
18793
18794   /* Use a control ping for synchronization */
18795   MPING (CONTROL_PING, mp_ping);
18796   S (mp_ping);
18797
18798   /* Wait for a reply... */
18799   W (ret);
18800   return ret;
18801 }
18802
18803 #define api_lisp_eid_table_dump api_one_eid_table_dump
18804
18805 static int
18806 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18807 {
18808   unformat_input_t *i = vam->input;
18809   vl_api_gpe_fwd_entries_get_t *mp;
18810   u8 vni_set = 0;
18811   u32 vni = ~0;
18812   int ret;
18813
18814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18815     {
18816       if (unformat (i, "vni %d", &vni))
18817         {
18818           vni_set = 1;
18819         }
18820       else
18821         {
18822           errmsg ("parse error '%U'", format_unformat_error, i);
18823           return -99;
18824         }
18825     }
18826
18827   if (!vni_set)
18828     {
18829       errmsg ("vni not set!");
18830       return -99;
18831     }
18832
18833   if (!vam->json_output)
18834     {
18835       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18836              "leid", "reid");
18837     }
18838
18839   M (GPE_FWD_ENTRIES_GET, mp);
18840   mp->vni = clib_host_to_net_u32 (vni);
18841
18842   /* send it... */
18843   S (mp);
18844
18845   /* Wait for a reply... */
18846   W (ret);
18847   return ret;
18848 }
18849
18850 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18851 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18852 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18853 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18854 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18855 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18856 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18857 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18858
18859 static int
18860 api_one_adjacencies_get (vat_main_t * vam)
18861 {
18862   unformat_input_t *i = vam->input;
18863   vl_api_one_adjacencies_get_t *mp;
18864   u8 vni_set = 0;
18865   u32 vni = ~0;
18866   int ret;
18867
18868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18869     {
18870       if (unformat (i, "vni %d", &vni))
18871         {
18872           vni_set = 1;
18873         }
18874       else
18875         {
18876           errmsg ("parse error '%U'", format_unformat_error, i);
18877           return -99;
18878         }
18879     }
18880
18881   if (!vni_set)
18882     {
18883       errmsg ("vni not set!");
18884       return -99;
18885     }
18886
18887   if (!vam->json_output)
18888     {
18889       print (vam->ofp, "%s %40s", "leid", "reid");
18890     }
18891
18892   M (ONE_ADJACENCIES_GET, mp);
18893   mp->vni = clib_host_to_net_u32 (vni);
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 #define api_lisp_adjacencies_get api_one_adjacencies_get
18904
18905 static int
18906 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18907 {
18908   unformat_input_t *i = vam->input;
18909   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18910   int ret;
18911   u8 ip_family_set = 0, is_ip4 = 1;
18912
18913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18914     {
18915       if (unformat (i, "ip4"))
18916         {
18917           ip_family_set = 1;
18918           is_ip4 = 1;
18919         }
18920       else if (unformat (i, "ip6"))
18921         {
18922           ip_family_set = 1;
18923           is_ip4 = 0;
18924         }
18925       else
18926         {
18927           errmsg ("parse error '%U'", format_unformat_error, i);
18928           return -99;
18929         }
18930     }
18931
18932   if (!ip_family_set)
18933     {
18934       errmsg ("ip family not set!");
18935       return -99;
18936     }
18937
18938   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18939   mp->is_ip4 = is_ip4;
18940
18941   /* send it... */
18942   S (mp);
18943
18944   /* Wait for a reply... */
18945   W (ret);
18946   return ret;
18947 }
18948
18949 static int
18950 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18951 {
18952   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18953   int ret;
18954
18955   if (!vam->json_output)
18956     {
18957       print (vam->ofp, "VNIs");
18958     }
18959
18960   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18961
18962   /* send it... */
18963   S (mp);
18964
18965   /* Wait for a reply... */
18966   W (ret);
18967   return ret;
18968 }
18969
18970 static int
18971 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18972 {
18973   unformat_input_t *i = vam->input;
18974   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18975   int ret = 0;
18976   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18977   struct in_addr ip4;
18978   struct in6_addr ip6;
18979   u32 table_id = 0, nh_sw_if_index = ~0;
18980
18981   memset (&ip4, 0, sizeof (ip4));
18982   memset (&ip6, 0, sizeof (ip6));
18983
18984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18985     {
18986       if (unformat (i, "del"))
18987         is_add = 0;
18988       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18989                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18990         {
18991           ip_set = 1;
18992           is_ip4 = 1;
18993         }
18994       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18995                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18996         {
18997           ip_set = 1;
18998           is_ip4 = 0;
18999         }
19000       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19001         {
19002           ip_set = 1;
19003           is_ip4 = 1;
19004           nh_sw_if_index = ~0;
19005         }
19006       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19007         {
19008           ip_set = 1;
19009           is_ip4 = 0;
19010           nh_sw_if_index = ~0;
19011         }
19012       else if (unformat (i, "table %d", &table_id))
19013         ;
19014       else
19015         {
19016           errmsg ("parse error '%U'", format_unformat_error, i);
19017           return -99;
19018         }
19019     }
19020
19021   if (!ip_set)
19022     {
19023       errmsg ("nh addr not set!");
19024       return -99;
19025     }
19026
19027   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19028   mp->is_add = is_add;
19029   mp->table_id = clib_host_to_net_u32 (table_id);
19030   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19031   mp->is_ip4 = is_ip4;
19032   if (is_ip4)
19033     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19034   else
19035     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19036
19037   /* send it... */
19038   S (mp);
19039
19040   /* Wait for a reply... */
19041   W (ret);
19042   return ret;
19043 }
19044
19045 static int
19046 api_one_map_server_dump (vat_main_t * vam)
19047 {
19048   vl_api_one_map_server_dump_t *mp;
19049   vl_api_control_ping_t *mp_ping;
19050   int ret;
19051
19052   if (!vam->json_output)
19053     {
19054       print (vam->ofp, "%=20s", "Map server");
19055     }
19056
19057   M (ONE_MAP_SERVER_DUMP, mp);
19058   /* send it... */
19059   S (mp);
19060
19061   /* Use a control ping for synchronization */
19062   MPING (CONTROL_PING, mp_ping);
19063   S (mp_ping);
19064
19065   /* Wait for a reply... */
19066   W (ret);
19067   return ret;
19068 }
19069
19070 #define api_lisp_map_server_dump api_one_map_server_dump
19071
19072 static int
19073 api_one_map_resolver_dump (vat_main_t * vam)
19074 {
19075   vl_api_one_map_resolver_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   int ret;
19078
19079   if (!vam->json_output)
19080     {
19081       print (vam->ofp, "%=20s", "Map resolver");
19082     }
19083
19084   M (ONE_MAP_RESOLVER_DUMP, mp);
19085   /* send it... */
19086   S (mp);
19087
19088   /* Use a control ping for synchronization */
19089   MPING (CONTROL_PING, mp_ping);
19090   S (mp_ping);
19091
19092   /* Wait for a reply... */
19093   W (ret);
19094   return ret;
19095 }
19096
19097 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19098
19099 static int
19100 api_one_stats_flush (vat_main_t * vam)
19101 {
19102   vl_api_one_stats_flush_t *mp;
19103   int ret = 0;
19104
19105   M (ONE_STATS_FLUSH, mp);
19106   S (mp);
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static int
19112 api_one_stats_dump (vat_main_t * vam)
19113 {
19114   vl_api_one_stats_dump_t *mp;
19115   vl_api_control_ping_t *mp_ping;
19116   int ret;
19117
19118   M (ONE_STATS_DUMP, mp);
19119   /* send it... */
19120   S (mp);
19121
19122   /* Use a control ping for synchronization */
19123   MPING (CONTROL_PING, mp_ping);
19124   S (mp_ping);
19125
19126   /* Wait for a reply... */
19127   W (ret);
19128   return ret;
19129 }
19130
19131 static int
19132 api_show_one_status (vat_main_t * vam)
19133 {
19134   vl_api_show_one_status_t *mp;
19135   int ret;
19136
19137   if (!vam->json_output)
19138     {
19139       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19140     }
19141
19142   M (SHOW_ONE_STATUS, mp);
19143   /* send it... */
19144   S (mp);
19145   /* Wait for a reply... */
19146   W (ret);
19147   return ret;
19148 }
19149
19150 #define api_show_lisp_status api_show_one_status
19151
19152 static int
19153 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19154 {
19155   vl_api_gpe_fwd_entry_path_dump_t *mp;
19156   vl_api_control_ping_t *mp_ping;
19157   unformat_input_t *i = vam->input;
19158   u32 fwd_entry_index = ~0;
19159   int ret;
19160
19161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19162     {
19163       if (unformat (i, "index %d", &fwd_entry_index))
19164         ;
19165       else
19166         break;
19167     }
19168
19169   if (~0 == fwd_entry_index)
19170     {
19171       errmsg ("no index specified!");
19172       return -99;
19173     }
19174
19175   if (!vam->json_output)
19176     {
19177       print (vam->ofp, "first line");
19178     }
19179
19180   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19181
19182   /* send it... */
19183   S (mp);
19184   /* Use a control ping for synchronization */
19185   MPING (CONTROL_PING, mp_ping);
19186   S (mp_ping);
19187
19188   /* Wait for a reply... */
19189   W (ret);
19190   return ret;
19191 }
19192
19193 static int
19194 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19195 {
19196   vl_api_one_get_map_request_itr_rlocs_t *mp;
19197   int ret;
19198
19199   if (!vam->json_output)
19200     {
19201       print (vam->ofp, "%=20s", "itr-rlocs:");
19202     }
19203
19204   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19205   /* send it... */
19206   S (mp);
19207   /* Wait for a reply... */
19208   W (ret);
19209   return ret;
19210 }
19211
19212 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19213
19214 static int
19215 api_af_packet_create (vat_main_t * vam)
19216 {
19217   unformat_input_t *i = vam->input;
19218   vl_api_af_packet_create_t *mp;
19219   u8 *host_if_name = 0;
19220   u8 hw_addr[6];
19221   u8 random_hw_addr = 1;
19222   int ret;
19223
19224   memset (hw_addr, 0, sizeof (hw_addr));
19225
19226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19227     {
19228       if (unformat (i, "name %s", &host_if_name))
19229         vec_add1 (host_if_name, 0);
19230       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19231         random_hw_addr = 0;
19232       else
19233         break;
19234     }
19235
19236   if (!vec_len (host_if_name))
19237     {
19238       errmsg ("host-interface name must be specified");
19239       return -99;
19240     }
19241
19242   if (vec_len (host_if_name) > 64)
19243     {
19244       errmsg ("host-interface name too long");
19245       return -99;
19246     }
19247
19248   M (AF_PACKET_CREATE, mp);
19249
19250   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19251   clib_memcpy (mp->hw_addr, hw_addr, 6);
19252   mp->use_random_hw_addr = random_hw_addr;
19253   vec_free (host_if_name);
19254
19255   S (mp);
19256
19257   /* *INDENT-OFF* */
19258   W2 (ret,
19259       ({
19260         if (ret == 0)
19261           fprintf (vam->ofp ? vam->ofp : stderr,
19262                    " new sw_if_index = %d\n", vam->sw_if_index);
19263       }));
19264   /* *INDENT-ON* */
19265   return ret;
19266 }
19267
19268 static int
19269 api_af_packet_delete (vat_main_t * vam)
19270 {
19271   unformat_input_t *i = vam->input;
19272   vl_api_af_packet_delete_t *mp;
19273   u8 *host_if_name = 0;
19274   int ret;
19275
19276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19277     {
19278       if (unformat (i, "name %s", &host_if_name))
19279         vec_add1 (host_if_name, 0);
19280       else
19281         break;
19282     }
19283
19284   if (!vec_len (host_if_name))
19285     {
19286       errmsg ("host-interface name must be specified");
19287       return -99;
19288     }
19289
19290   if (vec_len (host_if_name) > 64)
19291     {
19292       errmsg ("host-interface name too long");
19293       return -99;
19294     }
19295
19296   M (AF_PACKET_DELETE, mp);
19297
19298   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19299   vec_free (host_if_name);
19300
19301   S (mp);
19302   W (ret);
19303   return ret;
19304 }
19305
19306 static int
19307 api_policer_add_del (vat_main_t * vam)
19308 {
19309   unformat_input_t *i = vam->input;
19310   vl_api_policer_add_del_t *mp;
19311   u8 is_add = 1;
19312   u8 *name = 0;
19313   u32 cir = 0;
19314   u32 eir = 0;
19315   u64 cb = 0;
19316   u64 eb = 0;
19317   u8 rate_type = 0;
19318   u8 round_type = 0;
19319   u8 type = 0;
19320   u8 color_aware = 0;
19321   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19322   int ret;
19323
19324   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19325   conform_action.dscp = 0;
19326   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19327   exceed_action.dscp = 0;
19328   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19329   violate_action.dscp = 0;
19330
19331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19332     {
19333       if (unformat (i, "del"))
19334         is_add = 0;
19335       else if (unformat (i, "name %s", &name))
19336         vec_add1 (name, 0);
19337       else if (unformat (i, "cir %u", &cir))
19338         ;
19339       else if (unformat (i, "eir %u", &eir))
19340         ;
19341       else if (unformat (i, "cb %u", &cb))
19342         ;
19343       else if (unformat (i, "eb %u", &eb))
19344         ;
19345       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19346                          &rate_type))
19347         ;
19348       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19349                          &round_type))
19350         ;
19351       else if (unformat (i, "type %U", unformat_policer_type, &type))
19352         ;
19353       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19354                          &conform_action))
19355         ;
19356       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19357                          &exceed_action))
19358         ;
19359       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19360                          &violate_action))
19361         ;
19362       else if (unformat (i, "color-aware"))
19363         color_aware = 1;
19364       else
19365         break;
19366     }
19367
19368   if (!vec_len (name))
19369     {
19370       errmsg ("policer name must be specified");
19371       return -99;
19372     }
19373
19374   if (vec_len (name) > 64)
19375     {
19376       errmsg ("policer name too long");
19377       return -99;
19378     }
19379
19380   M (POLICER_ADD_DEL, mp);
19381
19382   clib_memcpy (mp->name, name, vec_len (name));
19383   vec_free (name);
19384   mp->is_add = is_add;
19385   mp->cir = ntohl (cir);
19386   mp->eir = ntohl (eir);
19387   mp->cb = clib_net_to_host_u64 (cb);
19388   mp->eb = clib_net_to_host_u64 (eb);
19389   mp->rate_type = rate_type;
19390   mp->round_type = round_type;
19391   mp->type = type;
19392   mp->conform_action_type = conform_action.action_type;
19393   mp->conform_dscp = conform_action.dscp;
19394   mp->exceed_action_type = exceed_action.action_type;
19395   mp->exceed_dscp = exceed_action.dscp;
19396   mp->violate_action_type = violate_action.action_type;
19397   mp->violate_dscp = violate_action.dscp;
19398   mp->color_aware = color_aware;
19399
19400   S (mp);
19401   W (ret);
19402   return ret;
19403 }
19404
19405 static int
19406 api_policer_dump (vat_main_t * vam)
19407 {
19408   unformat_input_t *i = vam->input;
19409   vl_api_policer_dump_t *mp;
19410   vl_api_control_ping_t *mp_ping;
19411   u8 *match_name = 0;
19412   u8 match_name_valid = 0;
19413   int ret;
19414
19415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19416     {
19417       if (unformat (i, "name %s", &match_name))
19418         {
19419           vec_add1 (match_name, 0);
19420           match_name_valid = 1;
19421         }
19422       else
19423         break;
19424     }
19425
19426   M (POLICER_DUMP, mp);
19427   mp->match_name_valid = match_name_valid;
19428   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19429   vec_free (match_name);
19430   /* send it... */
19431   S (mp);
19432
19433   /* Use a control ping for synchronization */
19434   MPING (CONTROL_PING, mp_ping);
19435   S (mp_ping);
19436
19437   /* Wait for a reply... */
19438   W (ret);
19439   return ret;
19440 }
19441
19442 static int
19443 api_policer_classify_set_interface (vat_main_t * vam)
19444 {
19445   unformat_input_t *i = vam->input;
19446   vl_api_policer_classify_set_interface_t *mp;
19447   u32 sw_if_index;
19448   int sw_if_index_set;
19449   u32 ip4_table_index = ~0;
19450   u32 ip6_table_index = ~0;
19451   u32 l2_table_index = ~0;
19452   u8 is_add = 1;
19453   int ret;
19454
19455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19456     {
19457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19458         sw_if_index_set = 1;
19459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19460         sw_if_index_set = 1;
19461       else if (unformat (i, "del"))
19462         is_add = 0;
19463       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19464         ;
19465       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19466         ;
19467       else if (unformat (i, "l2-table %d", &l2_table_index))
19468         ;
19469       else
19470         {
19471           clib_warning ("parse error '%U'", format_unformat_error, i);
19472           return -99;
19473         }
19474     }
19475
19476   if (sw_if_index_set == 0)
19477     {
19478       errmsg ("missing interface name or sw_if_index");
19479       return -99;
19480     }
19481
19482   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19483
19484   mp->sw_if_index = ntohl (sw_if_index);
19485   mp->ip4_table_index = ntohl (ip4_table_index);
19486   mp->ip6_table_index = ntohl (ip6_table_index);
19487   mp->l2_table_index = ntohl (l2_table_index);
19488   mp->is_add = is_add;
19489
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static int
19496 api_policer_classify_dump (vat_main_t * vam)
19497 {
19498   unformat_input_t *i = vam->input;
19499   vl_api_policer_classify_dump_t *mp;
19500   vl_api_control_ping_t *mp_ping;
19501   u8 type = POLICER_CLASSIFY_N_TABLES;
19502   int ret;
19503
19504   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19505     ;
19506   else
19507     {
19508       errmsg ("classify table type must be specified");
19509       return -99;
19510     }
19511
19512   if (!vam->json_output)
19513     {
19514       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19515     }
19516
19517   M (POLICER_CLASSIFY_DUMP, mp);
19518   mp->type = type;
19519   /* send it... */
19520   S (mp);
19521
19522   /* Use a control ping for synchronization */
19523   MPING (CONTROL_PING, mp_ping);
19524   S (mp_ping);
19525
19526   /* Wait for a reply... */
19527   W (ret);
19528   return ret;
19529 }
19530
19531 static int
19532 api_netmap_create (vat_main_t * vam)
19533 {
19534   unformat_input_t *i = vam->input;
19535   vl_api_netmap_create_t *mp;
19536   u8 *if_name = 0;
19537   u8 hw_addr[6];
19538   u8 random_hw_addr = 1;
19539   u8 is_pipe = 0;
19540   u8 is_master = 0;
19541   int ret;
19542
19543   memset (hw_addr, 0, sizeof (hw_addr));
19544
19545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19546     {
19547       if (unformat (i, "name %s", &if_name))
19548         vec_add1 (if_name, 0);
19549       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19550         random_hw_addr = 0;
19551       else if (unformat (i, "pipe"))
19552         is_pipe = 1;
19553       else if (unformat (i, "master"))
19554         is_master = 1;
19555       else if (unformat (i, "slave"))
19556         is_master = 0;
19557       else
19558         break;
19559     }
19560
19561   if (!vec_len (if_name))
19562     {
19563       errmsg ("interface name must be specified");
19564       return -99;
19565     }
19566
19567   if (vec_len (if_name) > 64)
19568     {
19569       errmsg ("interface name too long");
19570       return -99;
19571     }
19572
19573   M (NETMAP_CREATE, mp);
19574
19575   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19576   clib_memcpy (mp->hw_addr, hw_addr, 6);
19577   mp->use_random_hw_addr = random_hw_addr;
19578   mp->is_pipe = is_pipe;
19579   mp->is_master = is_master;
19580   vec_free (if_name);
19581
19582   S (mp);
19583   W (ret);
19584   return ret;
19585 }
19586
19587 static int
19588 api_netmap_delete (vat_main_t * vam)
19589 {
19590   unformat_input_t *i = vam->input;
19591   vl_api_netmap_delete_t *mp;
19592   u8 *if_name = 0;
19593   int ret;
19594
19595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19596     {
19597       if (unformat (i, "name %s", &if_name))
19598         vec_add1 (if_name, 0);
19599       else
19600         break;
19601     }
19602
19603   if (!vec_len (if_name))
19604     {
19605       errmsg ("interface name must be specified");
19606       return -99;
19607     }
19608
19609   if (vec_len (if_name) > 64)
19610     {
19611       errmsg ("interface name too long");
19612       return -99;
19613     }
19614
19615   M (NETMAP_DELETE, mp);
19616
19617   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19618   vec_free (if_name);
19619
19620   S (mp);
19621   W (ret);
19622   return ret;
19623 }
19624
19625 static void
19626 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19627 {
19628   if (fp->afi == IP46_TYPE_IP6)
19629     print (vam->ofp,
19630            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19631            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19632            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19633            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19634            format_ip6_address, fp->next_hop);
19635   else if (fp->afi == IP46_TYPE_IP4)
19636     print (vam->ofp,
19637            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19638            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19639            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19640            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19641            format_ip4_address, fp->next_hop);
19642 }
19643
19644 static void
19645 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19646                                  vl_api_fib_path2_t * fp)
19647 {
19648   struct in_addr ip4;
19649   struct in6_addr ip6;
19650
19651   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19652   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19653   vat_json_object_add_uint (node, "is_local", fp->is_local);
19654   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19655   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19656   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19657   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19658   if (fp->afi == IP46_TYPE_IP4)
19659     {
19660       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19661       vat_json_object_add_ip4 (node, "next_hop", ip4);
19662     }
19663   else if (fp->afi == IP46_TYPE_IP6)
19664     {
19665       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19666       vat_json_object_add_ip6 (node, "next_hop", ip6);
19667     }
19668 }
19669
19670 static void
19671 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19672 {
19673   vat_main_t *vam = &vat_main;
19674   int count = ntohl (mp->mt_count);
19675   vl_api_fib_path2_t *fp;
19676   i32 i;
19677
19678   print (vam->ofp, "[%d]: sw_if_index %d via:",
19679          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19680   fp = mp->mt_paths;
19681   for (i = 0; i < count; i++)
19682     {
19683       vl_api_mpls_fib_path_print (vam, fp);
19684       fp++;
19685     }
19686
19687   print (vam->ofp, "");
19688 }
19689
19690 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19691 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19692
19693 static void
19694 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19695 {
19696   vat_main_t *vam = &vat_main;
19697   vat_json_node_t *node = NULL;
19698   int count = ntohl (mp->mt_count);
19699   vl_api_fib_path2_t *fp;
19700   i32 i;
19701
19702   if (VAT_JSON_ARRAY != vam->json_tree.type)
19703     {
19704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19705       vat_json_init_array (&vam->json_tree);
19706     }
19707   node = vat_json_array_add (&vam->json_tree);
19708
19709   vat_json_init_object (node);
19710   vat_json_object_add_uint (node, "tunnel_index",
19711                             ntohl (mp->mt_tunnel_index));
19712   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19713
19714   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19715
19716   fp = mp->mt_paths;
19717   for (i = 0; i < count; i++)
19718     {
19719       vl_api_mpls_fib_path_json_print (node, fp);
19720       fp++;
19721     }
19722 }
19723
19724 static int
19725 api_mpls_tunnel_dump (vat_main_t * vam)
19726 {
19727   vl_api_mpls_tunnel_dump_t *mp;
19728   vl_api_control_ping_t *mp_ping;
19729   i32 index = -1;
19730   int ret;
19731
19732   /* Parse args required to build the message */
19733   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19734     {
19735       if (!unformat (vam->input, "tunnel_index %d", &index))
19736         {
19737           index = -1;
19738           break;
19739         }
19740     }
19741
19742   print (vam->ofp, "  tunnel_index %d", index);
19743
19744   M (MPLS_TUNNEL_DUMP, mp);
19745   mp->tunnel_index = htonl (index);
19746   S (mp);
19747
19748   /* Use a control ping for synchronization */
19749   MPING (CONTROL_PING, mp_ping);
19750   S (mp_ping);
19751
19752   W (ret);
19753   return ret;
19754 }
19755
19756 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19757 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19758
19759
19760 static void
19761 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19762 {
19763   vat_main_t *vam = &vat_main;
19764   int count = ntohl (mp->count);
19765   vl_api_fib_path2_t *fp;
19766   int i;
19767
19768   print (vam->ofp,
19769          "table-id %d, label %u, ess_bit %u",
19770          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19771   fp = mp->path;
19772   for (i = 0; i < count; i++)
19773     {
19774       vl_api_mpls_fib_path_print (vam, fp);
19775       fp++;
19776     }
19777 }
19778
19779 static void vl_api_mpls_fib_details_t_handler_json
19780   (vl_api_mpls_fib_details_t * mp)
19781 {
19782   vat_main_t *vam = &vat_main;
19783   int count = ntohl (mp->count);
19784   vat_json_node_t *node = NULL;
19785   vl_api_fib_path2_t *fp;
19786   int i;
19787
19788   if (VAT_JSON_ARRAY != vam->json_tree.type)
19789     {
19790       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19791       vat_json_init_array (&vam->json_tree);
19792     }
19793   node = vat_json_array_add (&vam->json_tree);
19794
19795   vat_json_init_object (node);
19796   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19797   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19798   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19799   vat_json_object_add_uint (node, "path_count", count);
19800   fp = mp->path;
19801   for (i = 0; i < count; i++)
19802     {
19803       vl_api_mpls_fib_path_json_print (node, fp);
19804       fp++;
19805     }
19806 }
19807
19808 static int
19809 api_mpls_fib_dump (vat_main_t * vam)
19810 {
19811   vl_api_mpls_fib_dump_t *mp;
19812   vl_api_control_ping_t *mp_ping;
19813   int ret;
19814
19815   M (MPLS_FIB_DUMP, mp);
19816   S (mp);
19817
19818   /* Use a control ping for synchronization */
19819   MPING (CONTROL_PING, mp_ping);
19820   S (mp_ping);
19821
19822   W (ret);
19823   return ret;
19824 }
19825
19826 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19827 #define vl_api_ip_fib_details_t_print vl_noop_handler
19828
19829 static void
19830 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19831 {
19832   vat_main_t *vam = &vat_main;
19833   int count = ntohl (mp->count);
19834   vl_api_fib_path_t *fp;
19835   int i;
19836
19837   print (vam->ofp,
19838          "table-id %d, prefix %U/%d",
19839          ntohl (mp->table_id), format_ip4_address, mp->address,
19840          mp->address_length);
19841   fp = mp->path;
19842   for (i = 0; i < count; i++)
19843     {
19844       if (fp->afi == IP46_TYPE_IP6)
19845         print (vam->ofp,
19846                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19847                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19848                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19849                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19850                format_ip6_address, fp->next_hop);
19851       else if (fp->afi == IP46_TYPE_IP4)
19852         print (vam->ofp,
19853                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19854                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19855                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19856                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19857                format_ip4_address, fp->next_hop);
19858       fp++;
19859     }
19860 }
19861
19862 static void vl_api_ip_fib_details_t_handler_json
19863   (vl_api_ip_fib_details_t * mp)
19864 {
19865   vat_main_t *vam = &vat_main;
19866   int count = ntohl (mp->count);
19867   vat_json_node_t *node = NULL;
19868   struct in_addr ip4;
19869   struct in6_addr ip6;
19870   vl_api_fib_path_t *fp;
19871   int i;
19872
19873   if (VAT_JSON_ARRAY != vam->json_tree.type)
19874     {
19875       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19876       vat_json_init_array (&vam->json_tree);
19877     }
19878   node = vat_json_array_add (&vam->json_tree);
19879
19880   vat_json_init_object (node);
19881   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19882   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19883   vat_json_object_add_ip4 (node, "prefix", ip4);
19884   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19885   vat_json_object_add_uint (node, "path_count", count);
19886   fp = mp->path;
19887   for (i = 0; i < count; i++)
19888     {
19889       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19890       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19891       vat_json_object_add_uint (node, "is_local", fp->is_local);
19892       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19893       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19894       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19895       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19896       if (fp->afi == IP46_TYPE_IP4)
19897         {
19898           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19899           vat_json_object_add_ip4 (node, "next_hop", ip4);
19900         }
19901       else if (fp->afi == IP46_TYPE_IP6)
19902         {
19903           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19904           vat_json_object_add_ip6 (node, "next_hop", ip6);
19905         }
19906     }
19907 }
19908
19909 static int
19910 api_ip_fib_dump (vat_main_t * vam)
19911 {
19912   vl_api_ip_fib_dump_t *mp;
19913   vl_api_control_ping_t *mp_ping;
19914   int ret;
19915
19916   M (IP_FIB_DUMP, mp);
19917   S (mp);
19918
19919   /* Use a control ping for synchronization */
19920   MPING (CONTROL_PING, mp_ping);
19921   S (mp_ping);
19922
19923   W (ret);
19924   return ret;
19925 }
19926
19927 static int
19928 api_ip_mfib_dump (vat_main_t * vam)
19929 {
19930   vl_api_ip_mfib_dump_t *mp;
19931   vl_api_control_ping_t *mp_ping;
19932   int ret;
19933
19934   M (IP_MFIB_DUMP, mp);
19935   S (mp);
19936
19937   /* Use a control ping for synchronization */
19938   MPING (CONTROL_PING, mp_ping);
19939   S (mp_ping);
19940
19941   W (ret);
19942   return ret;
19943 }
19944
19945 static void vl_api_ip_neighbor_details_t_handler
19946   (vl_api_ip_neighbor_details_t * mp)
19947 {
19948   vat_main_t *vam = &vat_main;
19949
19950   print (vam->ofp, "%c %U %U",
19951          (mp->is_static) ? 'S' : 'D',
19952          format_ethernet_address, &mp->mac_address,
19953          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19954          &mp->ip_address);
19955 }
19956
19957 static void vl_api_ip_neighbor_details_t_handler_json
19958   (vl_api_ip_neighbor_details_t * mp)
19959 {
19960
19961   vat_main_t *vam = &vat_main;
19962   vat_json_node_t *node;
19963   struct in_addr ip4;
19964   struct in6_addr ip6;
19965
19966   if (VAT_JSON_ARRAY != vam->json_tree.type)
19967     {
19968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19969       vat_json_init_array (&vam->json_tree);
19970     }
19971   node = vat_json_array_add (&vam->json_tree);
19972
19973   vat_json_init_object (node);
19974   vat_json_object_add_string_copy (node, "flag",
19975                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19976                                    "dynamic");
19977
19978   vat_json_object_add_string_copy (node, "link_layer",
19979                                    format (0, "%U", format_ethernet_address,
19980                                            &mp->mac_address));
19981
19982   if (mp->is_ipv6)
19983     {
19984       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19985       vat_json_object_add_ip6 (node, "ip_address", ip6);
19986     }
19987   else
19988     {
19989       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19990       vat_json_object_add_ip4 (node, "ip_address", ip4);
19991     }
19992 }
19993
19994 static int
19995 api_ip_neighbor_dump (vat_main_t * vam)
19996 {
19997   unformat_input_t *i = vam->input;
19998   vl_api_ip_neighbor_dump_t *mp;
19999   vl_api_control_ping_t *mp_ping;
20000   u8 is_ipv6 = 0;
20001   u32 sw_if_index = ~0;
20002   int ret;
20003
20004   /* Parse args required to build the message */
20005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20006     {
20007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20008         ;
20009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20010         ;
20011       else if (unformat (i, "ip6"))
20012         is_ipv6 = 1;
20013       else
20014         break;
20015     }
20016
20017   if (sw_if_index == ~0)
20018     {
20019       errmsg ("missing interface name or sw_if_index");
20020       return -99;
20021     }
20022
20023   M (IP_NEIGHBOR_DUMP, mp);
20024   mp->is_ipv6 = (u8) is_ipv6;
20025   mp->sw_if_index = ntohl (sw_if_index);
20026   S (mp);
20027
20028   /* Use a control ping for synchronization */
20029   MPING (CONTROL_PING, mp_ping);
20030   S (mp_ping);
20031
20032   W (ret);
20033   return ret;
20034 }
20035
20036 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20037 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20038
20039 static void
20040 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20041 {
20042   vat_main_t *vam = &vat_main;
20043   int count = ntohl (mp->count);
20044   vl_api_fib_path_t *fp;
20045   int i;
20046
20047   print (vam->ofp,
20048          "table-id %d, prefix %U/%d",
20049          ntohl (mp->table_id), format_ip6_address, mp->address,
20050          mp->address_length);
20051   fp = mp->path;
20052   for (i = 0; i < count; i++)
20053     {
20054       if (fp->afi == IP46_TYPE_IP6)
20055         print (vam->ofp,
20056                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20057                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20058                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20059                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20060                format_ip6_address, fp->next_hop);
20061       else if (fp->afi == IP46_TYPE_IP4)
20062         print (vam->ofp,
20063                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20064                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20065                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20066                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20067                format_ip4_address, fp->next_hop);
20068       fp++;
20069     }
20070 }
20071
20072 static void vl_api_ip6_fib_details_t_handler_json
20073   (vl_api_ip6_fib_details_t * mp)
20074 {
20075   vat_main_t *vam = &vat_main;
20076   int count = ntohl (mp->count);
20077   vat_json_node_t *node = NULL;
20078   struct in_addr ip4;
20079   struct in6_addr ip6;
20080   vl_api_fib_path_t *fp;
20081   int i;
20082
20083   if (VAT_JSON_ARRAY != vam->json_tree.type)
20084     {
20085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20086       vat_json_init_array (&vam->json_tree);
20087     }
20088   node = vat_json_array_add (&vam->json_tree);
20089
20090   vat_json_init_object (node);
20091   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20092   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20093   vat_json_object_add_ip6 (node, "prefix", ip6);
20094   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20095   vat_json_object_add_uint (node, "path_count", count);
20096   fp = mp->path;
20097   for (i = 0; i < count; i++)
20098     {
20099       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20100       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20101       vat_json_object_add_uint (node, "is_local", fp->is_local);
20102       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20103       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20104       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20105       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20106       if (fp->afi == IP46_TYPE_IP4)
20107         {
20108           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20109           vat_json_object_add_ip4 (node, "next_hop", ip4);
20110         }
20111       else if (fp->afi == IP46_TYPE_IP6)
20112         {
20113           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20114           vat_json_object_add_ip6 (node, "next_hop", ip6);
20115         }
20116     }
20117 }
20118
20119 static int
20120 api_ip6_fib_dump (vat_main_t * vam)
20121 {
20122   vl_api_ip6_fib_dump_t *mp;
20123   vl_api_control_ping_t *mp_ping;
20124   int ret;
20125
20126   M (IP6_FIB_DUMP, mp);
20127   S (mp);
20128
20129   /* Use a control ping for synchronization */
20130   MPING (CONTROL_PING, mp_ping);
20131   S (mp_ping);
20132
20133   W (ret);
20134   return ret;
20135 }
20136
20137 static int
20138 api_ip6_mfib_dump (vat_main_t * vam)
20139 {
20140   vl_api_ip6_mfib_dump_t *mp;
20141   vl_api_control_ping_t *mp_ping;
20142   int ret;
20143
20144   M (IP6_MFIB_DUMP, mp);
20145   S (mp);
20146
20147   /* Use a control ping for synchronization */
20148   MPING (CONTROL_PING, mp_ping);
20149   S (mp_ping);
20150
20151   W (ret);
20152   return ret;
20153 }
20154
20155 int
20156 api_classify_table_ids (vat_main_t * vam)
20157 {
20158   vl_api_classify_table_ids_t *mp;
20159   int ret;
20160
20161   /* Construct the API message */
20162   M (CLASSIFY_TABLE_IDS, mp);
20163   mp->context = 0;
20164
20165   S (mp);
20166   W (ret);
20167   return ret;
20168 }
20169
20170 int
20171 api_classify_table_by_interface (vat_main_t * vam)
20172 {
20173   unformat_input_t *input = vam->input;
20174   vl_api_classify_table_by_interface_t *mp;
20175
20176   u32 sw_if_index = ~0;
20177   int ret;
20178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20179     {
20180       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20181         ;
20182       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20183         ;
20184       else
20185         break;
20186     }
20187   if (sw_if_index == ~0)
20188     {
20189       errmsg ("missing interface name or sw_if_index");
20190       return -99;
20191     }
20192
20193   /* Construct the API message */
20194   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20195   mp->context = 0;
20196   mp->sw_if_index = ntohl (sw_if_index);
20197
20198   S (mp);
20199   W (ret);
20200   return ret;
20201 }
20202
20203 int
20204 api_classify_table_info (vat_main_t * vam)
20205 {
20206   unformat_input_t *input = vam->input;
20207   vl_api_classify_table_info_t *mp;
20208
20209   u32 table_id = ~0;
20210   int ret;
20211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20212     {
20213       if (unformat (input, "table_id %d", &table_id))
20214         ;
20215       else
20216         break;
20217     }
20218   if (table_id == ~0)
20219     {
20220       errmsg ("missing table id");
20221       return -99;
20222     }
20223
20224   /* Construct the API message */
20225   M (CLASSIFY_TABLE_INFO, mp);
20226   mp->context = 0;
20227   mp->table_id = ntohl (table_id);
20228
20229   S (mp);
20230   W (ret);
20231   return ret;
20232 }
20233
20234 int
20235 api_classify_session_dump (vat_main_t * vam)
20236 {
20237   unformat_input_t *input = vam->input;
20238   vl_api_classify_session_dump_t *mp;
20239   vl_api_control_ping_t *mp_ping;
20240
20241   u32 table_id = ~0;
20242   int ret;
20243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20244     {
20245       if (unformat (input, "table_id %d", &table_id))
20246         ;
20247       else
20248         break;
20249     }
20250   if (table_id == ~0)
20251     {
20252       errmsg ("missing table id");
20253       return -99;
20254     }
20255
20256   /* Construct the API message */
20257   M (CLASSIFY_SESSION_DUMP, mp);
20258   mp->context = 0;
20259   mp->table_id = ntohl (table_id);
20260   S (mp);
20261
20262   /* Use a control ping for synchronization */
20263   MPING (CONTROL_PING, mp_ping);
20264   S (mp_ping);
20265
20266   W (ret);
20267   return ret;
20268 }
20269
20270 static void
20271 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20272 {
20273   vat_main_t *vam = &vat_main;
20274
20275   print (vam->ofp, "collector_address %U, collector_port %d, "
20276          "src_address %U, vrf_id %d, path_mtu %u, "
20277          "template_interval %u, udp_checksum %d",
20278          format_ip4_address, mp->collector_address,
20279          ntohs (mp->collector_port),
20280          format_ip4_address, mp->src_address,
20281          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20282          ntohl (mp->template_interval), mp->udp_checksum);
20283
20284   vam->retval = 0;
20285   vam->result_ready = 1;
20286 }
20287
20288 static void
20289   vl_api_ipfix_exporter_details_t_handler_json
20290   (vl_api_ipfix_exporter_details_t * mp)
20291 {
20292   vat_main_t *vam = &vat_main;
20293   vat_json_node_t node;
20294   struct in_addr collector_address;
20295   struct in_addr src_address;
20296
20297   vat_json_init_object (&node);
20298   clib_memcpy (&collector_address, &mp->collector_address,
20299                sizeof (collector_address));
20300   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20301   vat_json_object_add_uint (&node, "collector_port",
20302                             ntohs (mp->collector_port));
20303   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20304   vat_json_object_add_ip4 (&node, "src_address", src_address);
20305   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20306   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20307   vat_json_object_add_uint (&node, "template_interval",
20308                             ntohl (mp->template_interval));
20309   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20310
20311   vat_json_print (vam->ofp, &node);
20312   vat_json_free (&node);
20313   vam->retval = 0;
20314   vam->result_ready = 1;
20315 }
20316
20317 int
20318 api_ipfix_exporter_dump (vat_main_t * vam)
20319 {
20320   vl_api_ipfix_exporter_dump_t *mp;
20321   int ret;
20322
20323   /* Construct the API message */
20324   M (IPFIX_EXPORTER_DUMP, mp);
20325   mp->context = 0;
20326
20327   S (mp);
20328   W (ret);
20329   return ret;
20330 }
20331
20332 static int
20333 api_ipfix_classify_stream_dump (vat_main_t * vam)
20334 {
20335   vl_api_ipfix_classify_stream_dump_t *mp;
20336   int ret;
20337
20338   /* Construct the API message */
20339   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20340   mp->context = 0;
20341
20342   S (mp);
20343   W (ret);
20344   return ret;
20345   /* NOTREACHED */
20346   return 0;
20347 }
20348
20349 static void
20350   vl_api_ipfix_classify_stream_details_t_handler
20351   (vl_api_ipfix_classify_stream_details_t * mp)
20352 {
20353   vat_main_t *vam = &vat_main;
20354   print (vam->ofp, "domain_id %d, src_port %d",
20355          ntohl (mp->domain_id), ntohs (mp->src_port));
20356   vam->retval = 0;
20357   vam->result_ready = 1;
20358 }
20359
20360 static void
20361   vl_api_ipfix_classify_stream_details_t_handler_json
20362   (vl_api_ipfix_classify_stream_details_t * mp)
20363 {
20364   vat_main_t *vam = &vat_main;
20365   vat_json_node_t node;
20366
20367   vat_json_init_object (&node);
20368   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20369   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20370
20371   vat_json_print (vam->ofp, &node);
20372   vat_json_free (&node);
20373   vam->retval = 0;
20374   vam->result_ready = 1;
20375 }
20376
20377 static int
20378 api_ipfix_classify_table_dump (vat_main_t * vam)
20379 {
20380   vl_api_ipfix_classify_table_dump_t *mp;
20381   vl_api_control_ping_t *mp_ping;
20382   int ret;
20383
20384   if (!vam->json_output)
20385     {
20386       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20387              "transport_protocol");
20388     }
20389
20390   /* Construct the API message */
20391   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20392
20393   /* send it... */
20394   S (mp);
20395
20396   /* Use a control ping for synchronization */
20397   MPING (CONTROL_PING, mp_ping);
20398   S (mp_ping);
20399
20400   W (ret);
20401   return ret;
20402 }
20403
20404 static void
20405   vl_api_ipfix_classify_table_details_t_handler
20406   (vl_api_ipfix_classify_table_details_t * mp)
20407 {
20408   vat_main_t *vam = &vat_main;
20409   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20410          mp->transport_protocol);
20411 }
20412
20413 static void
20414   vl_api_ipfix_classify_table_details_t_handler_json
20415   (vl_api_ipfix_classify_table_details_t * mp)
20416 {
20417   vat_json_node_t *node = NULL;
20418   vat_main_t *vam = &vat_main;
20419
20420   if (VAT_JSON_ARRAY != vam->json_tree.type)
20421     {
20422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20423       vat_json_init_array (&vam->json_tree);
20424     }
20425
20426   node = vat_json_array_add (&vam->json_tree);
20427   vat_json_init_object (node);
20428
20429   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20430   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20431   vat_json_object_add_uint (node, "transport_protocol",
20432                             mp->transport_protocol);
20433 }
20434
20435 static int
20436 api_sw_interface_span_enable_disable (vat_main_t * vam)
20437 {
20438   unformat_input_t *i = vam->input;
20439   vl_api_sw_interface_span_enable_disable_t *mp;
20440   u32 src_sw_if_index = ~0;
20441   u32 dst_sw_if_index = ~0;
20442   u8 state = 3;
20443   int ret;
20444   u8 is_l2 = 0;
20445
20446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20447     {
20448       if (unformat
20449           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20450         ;
20451       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20452         ;
20453       else
20454         if (unformat
20455             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20456         ;
20457       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20458         ;
20459       else if (unformat (i, "disable"))
20460         state = 0;
20461       else if (unformat (i, "rx"))
20462         state = 1;
20463       else if (unformat (i, "tx"))
20464         state = 2;
20465       else if (unformat (i, "both"))
20466         state = 3;
20467       else if (unformat (i, "l2"))
20468         is_l2 = 1;
20469       else
20470         break;
20471     }
20472
20473   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20474
20475   mp->sw_if_index_from = htonl (src_sw_if_index);
20476   mp->sw_if_index_to = htonl (dst_sw_if_index);
20477   mp->state = state;
20478   mp->is_l2 = is_l2;
20479
20480   S (mp);
20481   W (ret);
20482   return ret;
20483 }
20484
20485 static void
20486 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20487                                             * mp)
20488 {
20489   vat_main_t *vam = &vat_main;
20490   u8 *sw_if_from_name = 0;
20491   u8 *sw_if_to_name = 0;
20492   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20493   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20494   char *states[] = { "none", "rx", "tx", "both" };
20495   hash_pair_t *p;
20496
20497   /* *INDENT-OFF* */
20498   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20499   ({
20500     if ((u32) p->value[0] == sw_if_index_from)
20501       {
20502         sw_if_from_name = (u8 *)(p->key);
20503         if (sw_if_to_name)
20504           break;
20505       }
20506     if ((u32) p->value[0] == sw_if_index_to)
20507       {
20508         sw_if_to_name = (u8 *)(p->key);
20509         if (sw_if_from_name)
20510           break;
20511       }
20512   }));
20513   /* *INDENT-ON* */
20514   print (vam->ofp, "%20s => %20s (%s)",
20515          sw_if_from_name, sw_if_to_name, states[mp->state]);
20516 }
20517
20518 static void
20519   vl_api_sw_interface_span_details_t_handler_json
20520   (vl_api_sw_interface_span_details_t * mp)
20521 {
20522   vat_main_t *vam = &vat_main;
20523   vat_json_node_t *node = NULL;
20524   u8 *sw_if_from_name = 0;
20525   u8 *sw_if_to_name = 0;
20526   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20527   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20528   hash_pair_t *p;
20529
20530   /* *INDENT-OFF* */
20531   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20532   ({
20533     if ((u32) p->value[0] == sw_if_index_from)
20534       {
20535         sw_if_from_name = (u8 *)(p->key);
20536         if (sw_if_to_name)
20537           break;
20538       }
20539     if ((u32) p->value[0] == sw_if_index_to)
20540       {
20541         sw_if_to_name = (u8 *)(p->key);
20542         if (sw_if_from_name)
20543           break;
20544       }
20545   }));
20546   /* *INDENT-ON* */
20547
20548   if (VAT_JSON_ARRAY != vam->json_tree.type)
20549     {
20550       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20551       vat_json_init_array (&vam->json_tree);
20552     }
20553   node = vat_json_array_add (&vam->json_tree);
20554
20555   vat_json_init_object (node);
20556   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20557   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20558   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20559   if (0 != sw_if_to_name)
20560     {
20561       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20562     }
20563   vat_json_object_add_uint (node, "state", mp->state);
20564 }
20565
20566 static int
20567 api_sw_interface_span_dump (vat_main_t * vam)
20568 {
20569   unformat_input_t *input = vam->input;
20570   vl_api_sw_interface_span_dump_t *mp;
20571   vl_api_control_ping_t *mp_ping;
20572   u8 is_l2 = 0;
20573   int ret;
20574
20575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20576     {
20577       if (unformat (input, "l2"))
20578         is_l2 = 1;
20579       else
20580         break;
20581     }
20582
20583   M (SW_INTERFACE_SPAN_DUMP, mp);
20584   mp->is_l2 = is_l2;
20585   S (mp);
20586
20587   /* Use a control ping for synchronization */
20588   MPING (CONTROL_PING, mp_ping);
20589   S (mp_ping);
20590
20591   W (ret);
20592   return ret;
20593 }
20594
20595 int
20596 api_pg_create_interface (vat_main_t * vam)
20597 {
20598   unformat_input_t *input = vam->input;
20599   vl_api_pg_create_interface_t *mp;
20600
20601   u32 if_id = ~0;
20602   int ret;
20603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20604     {
20605       if (unformat (input, "if_id %d", &if_id))
20606         ;
20607       else
20608         break;
20609     }
20610   if (if_id == ~0)
20611     {
20612       errmsg ("missing pg interface index");
20613       return -99;
20614     }
20615
20616   /* Construct the API message */
20617   M (PG_CREATE_INTERFACE, mp);
20618   mp->context = 0;
20619   mp->interface_id = ntohl (if_id);
20620
20621   S (mp);
20622   W (ret);
20623   return ret;
20624 }
20625
20626 int
20627 api_pg_capture (vat_main_t * vam)
20628 {
20629   unformat_input_t *input = vam->input;
20630   vl_api_pg_capture_t *mp;
20631
20632   u32 if_id = ~0;
20633   u8 enable = 1;
20634   u32 count = 1;
20635   u8 pcap_file_set = 0;
20636   u8 *pcap_file = 0;
20637   int ret;
20638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20639     {
20640       if (unformat (input, "if_id %d", &if_id))
20641         ;
20642       else if (unformat (input, "pcap %s", &pcap_file))
20643         pcap_file_set = 1;
20644       else if (unformat (input, "count %d", &count))
20645         ;
20646       else if (unformat (input, "disable"))
20647         enable = 0;
20648       else
20649         break;
20650     }
20651   if (if_id == ~0)
20652     {
20653       errmsg ("missing pg interface index");
20654       return -99;
20655     }
20656   if (pcap_file_set > 0)
20657     {
20658       if (vec_len (pcap_file) > 255)
20659         {
20660           errmsg ("pcap file name is too long");
20661           return -99;
20662         }
20663     }
20664
20665   u32 name_len = vec_len (pcap_file);
20666   /* Construct the API message */
20667   M (PG_CAPTURE, mp);
20668   mp->context = 0;
20669   mp->interface_id = ntohl (if_id);
20670   mp->is_enabled = enable;
20671   mp->count = ntohl (count);
20672   mp->pcap_name_length = ntohl (name_len);
20673   if (pcap_file_set != 0)
20674     {
20675       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20676     }
20677   vec_free (pcap_file);
20678
20679   S (mp);
20680   W (ret);
20681   return ret;
20682 }
20683
20684 int
20685 api_pg_enable_disable (vat_main_t * vam)
20686 {
20687   unformat_input_t *input = vam->input;
20688   vl_api_pg_enable_disable_t *mp;
20689
20690   u8 enable = 1;
20691   u8 stream_name_set = 0;
20692   u8 *stream_name = 0;
20693   int ret;
20694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20695     {
20696       if (unformat (input, "stream %s", &stream_name))
20697         stream_name_set = 1;
20698       else if (unformat (input, "disable"))
20699         enable = 0;
20700       else
20701         break;
20702     }
20703
20704   if (stream_name_set > 0)
20705     {
20706       if (vec_len (stream_name) > 255)
20707         {
20708           errmsg ("stream name too long");
20709           return -99;
20710         }
20711     }
20712
20713   u32 name_len = vec_len (stream_name);
20714   /* Construct the API message */
20715   M (PG_ENABLE_DISABLE, mp);
20716   mp->context = 0;
20717   mp->is_enabled = enable;
20718   if (stream_name_set != 0)
20719     {
20720       mp->stream_name_length = ntohl (name_len);
20721       clib_memcpy (mp->stream_name, stream_name, name_len);
20722     }
20723   vec_free (stream_name);
20724
20725   S (mp);
20726   W (ret);
20727   return ret;
20728 }
20729
20730 int
20731 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20732 {
20733   unformat_input_t *input = vam->input;
20734   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20735
20736   u16 *low_ports = 0;
20737   u16 *high_ports = 0;
20738   u16 this_low;
20739   u16 this_hi;
20740   ip4_address_t ip4_addr;
20741   ip6_address_t ip6_addr;
20742   u32 length;
20743   u32 tmp, tmp2;
20744   u8 prefix_set = 0;
20745   u32 vrf_id = ~0;
20746   u8 is_add = 1;
20747   u8 is_ipv6 = 0;
20748   int ret;
20749
20750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20751     {
20752       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20753         {
20754           prefix_set = 1;
20755         }
20756       else
20757         if (unformat
20758             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20759         {
20760           prefix_set = 1;
20761           is_ipv6 = 1;
20762         }
20763       else if (unformat (input, "vrf %d", &vrf_id))
20764         ;
20765       else if (unformat (input, "del"))
20766         is_add = 0;
20767       else if (unformat (input, "port %d", &tmp))
20768         {
20769           if (tmp == 0 || tmp > 65535)
20770             {
20771               errmsg ("port %d out of range", tmp);
20772               return -99;
20773             }
20774           this_low = tmp;
20775           this_hi = this_low + 1;
20776           vec_add1 (low_ports, this_low);
20777           vec_add1 (high_ports, this_hi);
20778         }
20779       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20780         {
20781           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20782             {
20783               errmsg ("incorrect range parameters");
20784               return -99;
20785             }
20786           this_low = tmp;
20787           /* Note: in debug CLI +1 is added to high before
20788              passing to real fn that does "the work"
20789              (ip_source_and_port_range_check_add_del).
20790              This fn is a wrapper around the binary API fn a
20791              control plane will call, which expects this increment
20792              to have occurred. Hence letting the binary API control
20793              plane fn do the increment for consistency between VAT
20794              and other control planes.
20795            */
20796           this_hi = tmp2;
20797           vec_add1 (low_ports, this_low);
20798           vec_add1 (high_ports, this_hi);
20799         }
20800       else
20801         break;
20802     }
20803
20804   if (prefix_set == 0)
20805     {
20806       errmsg ("<address>/<mask> not specified");
20807       return -99;
20808     }
20809
20810   if (vrf_id == ~0)
20811     {
20812       errmsg ("VRF ID required, not specified");
20813       return -99;
20814     }
20815
20816   if (vrf_id == 0)
20817     {
20818       errmsg
20819         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20820       return -99;
20821     }
20822
20823   if (vec_len (low_ports) == 0)
20824     {
20825       errmsg ("At least one port or port range required");
20826       return -99;
20827     }
20828
20829   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20830
20831   mp->is_add = is_add;
20832
20833   if (is_ipv6)
20834     {
20835       mp->is_ipv6 = 1;
20836       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20837     }
20838   else
20839     {
20840       mp->is_ipv6 = 0;
20841       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20842     }
20843
20844   mp->mask_length = length;
20845   mp->number_of_ranges = vec_len (low_ports);
20846
20847   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20848   vec_free (low_ports);
20849
20850   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20851   vec_free (high_ports);
20852
20853   mp->vrf_id = ntohl (vrf_id);
20854
20855   S (mp);
20856   W (ret);
20857   return ret;
20858 }
20859
20860 int
20861 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20862 {
20863   unformat_input_t *input = vam->input;
20864   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20865   u32 sw_if_index = ~0;
20866   int vrf_set = 0;
20867   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20868   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20869   u8 is_add = 1;
20870   int ret;
20871
20872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20873     {
20874       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20875         ;
20876       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20877         ;
20878       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20879         vrf_set = 1;
20880       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20881         vrf_set = 1;
20882       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20883         vrf_set = 1;
20884       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20885         vrf_set = 1;
20886       else if (unformat (input, "del"))
20887         is_add = 0;
20888       else
20889         break;
20890     }
20891
20892   if (sw_if_index == ~0)
20893     {
20894       errmsg ("Interface required but not specified");
20895       return -99;
20896     }
20897
20898   if (vrf_set == 0)
20899     {
20900       errmsg ("VRF ID required but not specified");
20901       return -99;
20902     }
20903
20904   if (tcp_out_vrf_id == 0
20905       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20906     {
20907       errmsg
20908         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20909       return -99;
20910     }
20911
20912   /* Construct the API message */
20913   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20914
20915   mp->sw_if_index = ntohl (sw_if_index);
20916   mp->is_add = is_add;
20917   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20918   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20919   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20920   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20921
20922   /* send it... */
20923   S (mp);
20924
20925   /* Wait for a reply... */
20926   W (ret);
20927   return ret;
20928 }
20929
20930 static int
20931 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20932 {
20933   unformat_input_t *i = vam->input;
20934   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20935   u32 local_sa_id = 0;
20936   u32 remote_sa_id = 0;
20937   ip4_address_t src_address;
20938   ip4_address_t dst_address;
20939   u8 is_add = 1;
20940   int ret;
20941
20942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20943     {
20944       if (unformat (i, "local_sa %d", &local_sa_id))
20945         ;
20946       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20947         ;
20948       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20949         ;
20950       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20951         ;
20952       else if (unformat (i, "del"))
20953         is_add = 0;
20954       else
20955         {
20956           clib_warning ("parse error '%U'", format_unformat_error, i);
20957           return -99;
20958         }
20959     }
20960
20961   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20962
20963   mp->local_sa_id = ntohl (local_sa_id);
20964   mp->remote_sa_id = ntohl (remote_sa_id);
20965   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20966   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20967   mp->is_add = is_add;
20968
20969   S (mp);
20970   W (ret);
20971   return ret;
20972 }
20973
20974 static int
20975 api_punt (vat_main_t * vam)
20976 {
20977   unformat_input_t *i = vam->input;
20978   vl_api_punt_t *mp;
20979   u32 ipv = ~0;
20980   u32 protocol = ~0;
20981   u32 port = ~0;
20982   int is_add = 1;
20983   int ret;
20984
20985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20986     {
20987       if (unformat (i, "ip %d", &ipv))
20988         ;
20989       else if (unformat (i, "protocol %d", &protocol))
20990         ;
20991       else if (unformat (i, "port %d", &port))
20992         ;
20993       else if (unformat (i, "del"))
20994         is_add = 0;
20995       else
20996         {
20997           clib_warning ("parse error '%U'", format_unformat_error, i);
20998           return -99;
20999         }
21000     }
21001
21002   M (PUNT, mp);
21003
21004   mp->is_add = (u8) is_add;
21005   mp->ipv = (u8) ipv;
21006   mp->l4_protocol = (u8) protocol;
21007   mp->l4_port = htons ((u16) port);
21008
21009   S (mp);
21010   W (ret);
21011   return ret;
21012 }
21013
21014 static void vl_api_ipsec_gre_tunnel_details_t_handler
21015   (vl_api_ipsec_gre_tunnel_details_t * mp)
21016 {
21017   vat_main_t *vam = &vat_main;
21018
21019   print (vam->ofp, "%11d%15U%15U%14d%14d",
21020          ntohl (mp->sw_if_index),
21021          format_ip4_address, &mp->src_address,
21022          format_ip4_address, &mp->dst_address,
21023          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21024 }
21025
21026 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21027   (vl_api_ipsec_gre_tunnel_details_t * mp)
21028 {
21029   vat_main_t *vam = &vat_main;
21030   vat_json_node_t *node = NULL;
21031   struct in_addr ip4;
21032
21033   if (VAT_JSON_ARRAY != vam->json_tree.type)
21034     {
21035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21036       vat_json_init_array (&vam->json_tree);
21037     }
21038   node = vat_json_array_add (&vam->json_tree);
21039
21040   vat_json_init_object (node);
21041   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21042   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21043   vat_json_object_add_ip4 (node, "src_address", ip4);
21044   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21045   vat_json_object_add_ip4 (node, "dst_address", ip4);
21046   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21047   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21048 }
21049
21050 static int
21051 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21052 {
21053   unformat_input_t *i = vam->input;
21054   vl_api_ipsec_gre_tunnel_dump_t *mp;
21055   vl_api_control_ping_t *mp_ping;
21056   u32 sw_if_index;
21057   u8 sw_if_index_set = 0;
21058   int ret;
21059
21060   /* Parse args required to build the message */
21061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21062     {
21063       if (unformat (i, "sw_if_index %d", &sw_if_index))
21064         sw_if_index_set = 1;
21065       else
21066         break;
21067     }
21068
21069   if (sw_if_index_set == 0)
21070     {
21071       sw_if_index = ~0;
21072     }
21073
21074   if (!vam->json_output)
21075     {
21076       print (vam->ofp, "%11s%15s%15s%14s%14s",
21077              "sw_if_index", "src_address", "dst_address",
21078              "local_sa_id", "remote_sa_id");
21079     }
21080
21081   /* Get list of gre-tunnel interfaces */
21082   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21083
21084   mp->sw_if_index = htonl (sw_if_index);
21085
21086   S (mp);
21087
21088   /* Use a control ping for synchronization */
21089   MPING (CONTROL_PING, mp_ping);
21090   S (mp_ping);
21091
21092   W (ret);
21093   return ret;
21094 }
21095
21096 static int
21097 api_delete_subif (vat_main_t * vam)
21098 {
21099   unformat_input_t *i = vam->input;
21100   vl_api_delete_subif_t *mp;
21101   u32 sw_if_index = ~0;
21102   int ret;
21103
21104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21105     {
21106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21107         ;
21108       if (unformat (i, "sw_if_index %d", &sw_if_index))
21109         ;
21110       else
21111         break;
21112     }
21113
21114   if (sw_if_index == ~0)
21115     {
21116       errmsg ("missing sw_if_index");
21117       return -99;
21118     }
21119
21120   /* Construct the API message */
21121   M (DELETE_SUBIF, mp);
21122   mp->sw_if_index = ntohl (sw_if_index);
21123
21124   S (mp);
21125   W (ret);
21126   return ret;
21127 }
21128
21129 #define foreach_pbb_vtr_op      \
21130 _("disable",  L2_VTR_DISABLED)  \
21131 _("pop",  L2_VTR_POP_2)         \
21132 _("push",  L2_VTR_PUSH_2)
21133
21134 static int
21135 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21136 {
21137   unformat_input_t *i = vam->input;
21138   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21139   u32 sw_if_index = ~0, vtr_op = ~0;
21140   u16 outer_tag = ~0;
21141   u8 dmac[6], smac[6];
21142   u8 dmac_set = 0, smac_set = 0;
21143   u16 vlanid = 0;
21144   u32 sid = ~0;
21145   u32 tmp;
21146   int ret;
21147
21148   /* Shut up coverity */
21149   memset (dmac, 0, sizeof (dmac));
21150   memset (smac, 0, sizeof (smac));
21151
21152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21153     {
21154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21155         ;
21156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21157         ;
21158       else if (unformat (i, "vtr_op %d", &vtr_op))
21159         ;
21160 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21161       foreach_pbb_vtr_op
21162 #undef _
21163         else if (unformat (i, "translate_pbb_stag"))
21164         {
21165           if (unformat (i, "%d", &tmp))
21166             {
21167               vtr_op = L2_VTR_TRANSLATE_2_1;
21168               outer_tag = tmp;
21169             }
21170           else
21171             {
21172               errmsg
21173                 ("translate_pbb_stag operation requires outer tag definition");
21174               return -99;
21175             }
21176         }
21177       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21178         dmac_set++;
21179       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21180         smac_set++;
21181       else if (unformat (i, "sid %d", &sid))
21182         ;
21183       else if (unformat (i, "vlanid %d", &tmp))
21184         vlanid = tmp;
21185       else
21186         {
21187           clib_warning ("parse error '%U'", format_unformat_error, i);
21188           return -99;
21189         }
21190     }
21191
21192   if ((sw_if_index == ~0) || (vtr_op == ~0))
21193     {
21194       errmsg ("missing sw_if_index or vtr operation");
21195       return -99;
21196     }
21197   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21198       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21199     {
21200       errmsg
21201         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21202       return -99;
21203     }
21204
21205   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21206   mp->sw_if_index = ntohl (sw_if_index);
21207   mp->vtr_op = ntohl (vtr_op);
21208   mp->outer_tag = ntohs (outer_tag);
21209   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21210   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21211   mp->b_vlanid = ntohs (vlanid);
21212   mp->i_sid = ntohl (sid);
21213
21214   S (mp);
21215   W (ret);
21216   return ret;
21217 }
21218
21219 static int
21220 api_flow_classify_set_interface (vat_main_t * vam)
21221 {
21222   unformat_input_t *i = vam->input;
21223   vl_api_flow_classify_set_interface_t *mp;
21224   u32 sw_if_index;
21225   int sw_if_index_set;
21226   u32 ip4_table_index = ~0;
21227   u32 ip6_table_index = ~0;
21228   u8 is_add = 1;
21229   int ret;
21230
21231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21232     {
21233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21234         sw_if_index_set = 1;
21235       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21236         sw_if_index_set = 1;
21237       else if (unformat (i, "del"))
21238         is_add = 0;
21239       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21240         ;
21241       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21242         ;
21243       else
21244         {
21245           clib_warning ("parse error '%U'", format_unformat_error, i);
21246           return -99;
21247         }
21248     }
21249
21250   if (sw_if_index_set == 0)
21251     {
21252       errmsg ("missing interface name or sw_if_index");
21253       return -99;
21254     }
21255
21256   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21257
21258   mp->sw_if_index = ntohl (sw_if_index);
21259   mp->ip4_table_index = ntohl (ip4_table_index);
21260   mp->ip6_table_index = ntohl (ip6_table_index);
21261   mp->is_add = is_add;
21262
21263   S (mp);
21264   W (ret);
21265   return ret;
21266 }
21267
21268 static int
21269 api_flow_classify_dump (vat_main_t * vam)
21270 {
21271   unformat_input_t *i = vam->input;
21272   vl_api_flow_classify_dump_t *mp;
21273   vl_api_control_ping_t *mp_ping;
21274   u8 type = FLOW_CLASSIFY_N_TABLES;
21275   int ret;
21276
21277   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21278     ;
21279   else
21280     {
21281       errmsg ("classify table type must be specified");
21282       return -99;
21283     }
21284
21285   if (!vam->json_output)
21286     {
21287       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21288     }
21289
21290   M (FLOW_CLASSIFY_DUMP, mp);
21291   mp->type = type;
21292   /* send it... */
21293   S (mp);
21294
21295   /* Use a control ping for synchronization */
21296   MPING (CONTROL_PING, mp_ping);
21297   S (mp_ping);
21298
21299   /* Wait for a reply... */
21300   W (ret);
21301   return ret;
21302 }
21303
21304 static int
21305 api_feature_enable_disable (vat_main_t * vam)
21306 {
21307   unformat_input_t *i = vam->input;
21308   vl_api_feature_enable_disable_t *mp;
21309   u8 *arc_name = 0;
21310   u8 *feature_name = 0;
21311   u32 sw_if_index = ~0;
21312   u8 enable = 1;
21313   int ret;
21314
21315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21316     {
21317       if (unformat (i, "arc_name %s", &arc_name))
21318         ;
21319       else if (unformat (i, "feature_name %s", &feature_name))
21320         ;
21321       else
21322         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21323         ;
21324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21325         ;
21326       else if (unformat (i, "disable"))
21327         enable = 0;
21328       else
21329         break;
21330     }
21331
21332   if (arc_name == 0)
21333     {
21334       errmsg ("missing arc name");
21335       return -99;
21336     }
21337   if (vec_len (arc_name) > 63)
21338     {
21339       errmsg ("arc name too long");
21340     }
21341
21342   if (feature_name == 0)
21343     {
21344       errmsg ("missing feature name");
21345       return -99;
21346     }
21347   if (vec_len (feature_name) > 63)
21348     {
21349       errmsg ("feature name too long");
21350     }
21351
21352   if (sw_if_index == ~0)
21353     {
21354       errmsg ("missing interface name or sw_if_index");
21355       return -99;
21356     }
21357
21358   /* Construct the API message */
21359   M (FEATURE_ENABLE_DISABLE, mp);
21360   mp->sw_if_index = ntohl (sw_if_index);
21361   mp->enable = enable;
21362   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21363   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21364   vec_free (arc_name);
21365   vec_free (feature_name);
21366
21367   S (mp);
21368   W (ret);
21369   return ret;
21370 }
21371
21372 static int
21373 api_sw_interface_tag_add_del (vat_main_t * vam)
21374 {
21375   unformat_input_t *i = vam->input;
21376   vl_api_sw_interface_tag_add_del_t *mp;
21377   u32 sw_if_index = ~0;
21378   u8 *tag = 0;
21379   u8 enable = 1;
21380   int ret;
21381
21382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21383     {
21384       if (unformat (i, "tag %s", &tag))
21385         ;
21386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21387         ;
21388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21389         ;
21390       else if (unformat (i, "del"))
21391         enable = 0;
21392       else
21393         break;
21394     }
21395
21396   if (sw_if_index == ~0)
21397     {
21398       errmsg ("missing interface name or sw_if_index");
21399       return -99;
21400     }
21401
21402   if (enable && (tag == 0))
21403     {
21404       errmsg ("no tag specified");
21405       return -99;
21406     }
21407
21408   /* Construct the API message */
21409   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21410   mp->sw_if_index = ntohl (sw_if_index);
21411   mp->is_add = enable;
21412   if (enable)
21413     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21414   vec_free (tag);
21415
21416   S (mp);
21417   W (ret);
21418   return ret;
21419 }
21420
21421 static void vl_api_l2_xconnect_details_t_handler
21422   (vl_api_l2_xconnect_details_t * mp)
21423 {
21424   vat_main_t *vam = &vat_main;
21425
21426   print (vam->ofp, "%15d%15d",
21427          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21428 }
21429
21430 static void vl_api_l2_xconnect_details_t_handler_json
21431   (vl_api_l2_xconnect_details_t * mp)
21432 {
21433   vat_main_t *vam = &vat_main;
21434   vat_json_node_t *node = NULL;
21435
21436   if (VAT_JSON_ARRAY != vam->json_tree.type)
21437     {
21438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21439       vat_json_init_array (&vam->json_tree);
21440     }
21441   node = vat_json_array_add (&vam->json_tree);
21442
21443   vat_json_init_object (node);
21444   vat_json_object_add_uint (node, "rx_sw_if_index",
21445                             ntohl (mp->rx_sw_if_index));
21446   vat_json_object_add_uint (node, "tx_sw_if_index",
21447                             ntohl (mp->tx_sw_if_index));
21448 }
21449
21450 static int
21451 api_l2_xconnect_dump (vat_main_t * vam)
21452 {
21453   vl_api_l2_xconnect_dump_t *mp;
21454   vl_api_control_ping_t *mp_ping;
21455   int ret;
21456
21457   if (!vam->json_output)
21458     {
21459       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21460     }
21461
21462   M (L2_XCONNECT_DUMP, mp);
21463
21464   S (mp);
21465
21466   /* Use a control ping for synchronization */
21467   MPING (CONTROL_PING, mp_ping);
21468   S (mp_ping);
21469
21470   W (ret);
21471   return ret;
21472 }
21473
21474 static int
21475 api_sw_interface_set_mtu (vat_main_t * vam)
21476 {
21477   unformat_input_t *i = vam->input;
21478   vl_api_sw_interface_set_mtu_t *mp;
21479   u32 sw_if_index = ~0;
21480   u32 mtu = 0;
21481   int ret;
21482
21483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21484     {
21485       if (unformat (i, "mtu %d", &mtu))
21486         ;
21487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21488         ;
21489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21490         ;
21491       else
21492         break;
21493     }
21494
21495   if (sw_if_index == ~0)
21496     {
21497       errmsg ("missing interface name or sw_if_index");
21498       return -99;
21499     }
21500
21501   if (mtu == 0)
21502     {
21503       errmsg ("no mtu specified");
21504       return -99;
21505     }
21506
21507   /* Construct the API message */
21508   M (SW_INTERFACE_SET_MTU, mp);
21509   mp->sw_if_index = ntohl (sw_if_index);
21510   mp->mtu = ntohs ((u16) mtu);
21511
21512   S (mp);
21513   W (ret);
21514   return ret;
21515 }
21516
21517 static int
21518 api_p2p_ethernet_add (vat_main_t * vam)
21519 {
21520   unformat_input_t *i = vam->input;
21521   vl_api_p2p_ethernet_add_t *mp;
21522   u32 parent_if_index = ~0;
21523   u32 sub_id = ~0;
21524   u8 remote_mac[6];
21525   u8 mac_set = 0;
21526   int ret;
21527
21528   memset (remote_mac, 0, sizeof (remote_mac));
21529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21530     {
21531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21532         ;
21533       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21534         ;
21535       else
21536         if (unformat
21537             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21538         mac_set++;
21539       else if (unformat (i, "sub_id %d", &sub_id))
21540         ;
21541       else
21542         {
21543           clib_warning ("parse error '%U'", format_unformat_error, i);
21544           return -99;
21545         }
21546     }
21547
21548   if (parent_if_index == ~0)
21549     {
21550       errmsg ("missing interface name or sw_if_index");
21551       return -99;
21552     }
21553   if (mac_set == 0)
21554     {
21555       errmsg ("missing remote mac address");
21556       return -99;
21557     }
21558   if (sub_id == ~0)
21559     {
21560       errmsg ("missing sub-interface id");
21561       return -99;
21562     }
21563
21564   M (P2P_ETHERNET_ADD, mp);
21565   mp->parent_if_index = ntohl (parent_if_index);
21566   mp->subif_id = ntohl (sub_id);
21567   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21568
21569   S (mp);
21570   W (ret);
21571   return ret;
21572 }
21573
21574 static int
21575 api_p2p_ethernet_del (vat_main_t * vam)
21576 {
21577   unformat_input_t *i = vam->input;
21578   vl_api_p2p_ethernet_del_t *mp;
21579   u32 parent_if_index = ~0;
21580   u8 remote_mac[6];
21581   u8 mac_set = 0;
21582   int ret;
21583
21584   memset (remote_mac, 0, sizeof (remote_mac));
21585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21586     {
21587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21588         ;
21589       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21590         ;
21591       else
21592         if (unformat
21593             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21594         mac_set++;
21595       else
21596         {
21597           clib_warning ("parse error '%U'", format_unformat_error, i);
21598           return -99;
21599         }
21600     }
21601
21602   if (parent_if_index == ~0)
21603     {
21604       errmsg ("missing interface name or sw_if_index");
21605       return -99;
21606     }
21607   if (mac_set == 0)
21608     {
21609       errmsg ("missing remote mac address");
21610       return -99;
21611     }
21612
21613   M (P2P_ETHERNET_DEL, mp);
21614   mp->parent_if_index = ntohl (parent_if_index);
21615   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21616
21617   S (mp);
21618   W (ret);
21619   return ret;
21620 }
21621
21622 static int
21623 api_lldp_config (vat_main_t * vam)
21624 {
21625   unformat_input_t *i = vam->input;
21626   vl_api_lldp_config_t *mp;
21627   int tx_hold = 0;
21628   int tx_interval = 0;
21629   u8 *sys_name = NULL;
21630   int ret;
21631
21632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21633     {
21634       if (unformat (i, "system-name %s", &sys_name))
21635         ;
21636       else if (unformat (i, "tx-hold %d", &tx_hold))
21637         ;
21638       else if (unformat (i, "tx-interval %d", &tx_interval))
21639         ;
21640       else
21641         {
21642           clib_warning ("parse error '%U'", format_unformat_error, i);
21643           return -99;
21644         }
21645     }
21646
21647   vec_add1 (sys_name, 0);
21648
21649   M (LLDP_CONFIG, mp);
21650   mp->tx_hold = htonl (tx_hold);
21651   mp->tx_interval = htonl (tx_interval);
21652   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21653   vec_free (sys_name);
21654
21655   S (mp);
21656   W (ret);
21657   return ret;
21658 }
21659
21660 static int
21661 api_sw_interface_set_lldp (vat_main_t * vam)
21662 {
21663   unformat_input_t *i = vam->input;
21664   vl_api_sw_interface_set_lldp_t *mp;
21665   u32 sw_if_index = ~0;
21666   u32 enable = 1;
21667   u8 *port_desc = NULL, *mgmt_oid = NULL;
21668   ip4_address_t ip4_addr;
21669   ip6_address_t ip6_addr;
21670   int ret;
21671
21672   memset (&ip4_addr, 0, sizeof (ip4_addr));
21673   memset (&ip6_addr, 0, sizeof (ip6_addr));
21674
21675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21676     {
21677       if (unformat (i, "disable"))
21678         enable = 0;
21679       else
21680         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21681         ;
21682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21683         ;
21684       else if (unformat (i, "port-desc %s", &port_desc))
21685         ;
21686       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21687         ;
21688       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21689         ;
21690       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21691         ;
21692       else
21693         break;
21694     }
21695
21696   if (sw_if_index == ~0)
21697     {
21698       errmsg ("missing interface name or sw_if_index");
21699       return -99;
21700     }
21701
21702   /* Construct the API message */
21703   vec_add1 (port_desc, 0);
21704   vec_add1 (mgmt_oid, 0);
21705   M (SW_INTERFACE_SET_LLDP, mp);
21706   mp->sw_if_index = ntohl (sw_if_index);
21707   mp->enable = enable;
21708   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21709   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21710   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21711   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21712   vec_free (port_desc);
21713   vec_free (mgmt_oid);
21714
21715   S (mp);
21716   W (ret);
21717   return ret;
21718 }
21719
21720 static int
21721 api_tcp_configure_src_addresses (vat_main_t * vam)
21722 {
21723   vl_api_tcp_configure_src_addresses_t *mp;
21724   unformat_input_t *i = vam->input;
21725   ip4_address_t v4first, v4last;
21726   ip6_address_t v6first, v6last;
21727   u8 range_set = 0;
21728   u32 vrf_id = 0;
21729   int ret;
21730
21731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21732     {
21733       if (unformat (i, "%U - %U",
21734                     unformat_ip4_address, &v4first,
21735                     unformat_ip4_address, &v4last))
21736         {
21737           if (range_set)
21738             {
21739               errmsg ("one range per message (range already set)");
21740               return -99;
21741             }
21742           range_set = 1;
21743         }
21744       else if (unformat (i, "%U - %U",
21745                          unformat_ip6_address, &v6first,
21746                          unformat_ip6_address, &v6last))
21747         {
21748           if (range_set)
21749             {
21750               errmsg ("one range per message (range already set)");
21751               return -99;
21752             }
21753           range_set = 2;
21754         }
21755       else if (unformat (i, "vrf %d", &vrf_id))
21756         ;
21757       else
21758         break;
21759     }
21760
21761   if (range_set == 0)
21762     {
21763       errmsg ("address range not set");
21764       return -99;
21765     }
21766
21767   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21768   mp->vrf_id = ntohl (vrf_id);
21769   /* ipv6? */
21770   if (range_set == 2)
21771     {
21772       mp->is_ipv6 = 1;
21773       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21774       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21775     }
21776   else
21777     {
21778       mp->is_ipv6 = 0;
21779       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21780       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21781     }
21782   S (mp);
21783   W (ret);
21784   return ret;
21785 }
21786
21787 static void vl_api_app_namespace_add_del_reply_t_handler
21788   (vl_api_app_namespace_add_del_reply_t * mp)
21789 {
21790   vat_main_t *vam = &vat_main;
21791   i32 retval = ntohl (mp->retval);
21792   if (vam->async_mode)
21793     {
21794       vam->async_errors += (retval < 0);
21795     }
21796   else
21797     {
21798       vam->retval = retval;
21799       if (retval == 0)
21800         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21801       vam->result_ready = 1;
21802     }
21803 }
21804
21805 static void vl_api_app_namespace_add_del_reply_t_handler_json
21806   (vl_api_app_namespace_add_del_reply_t * mp)
21807 {
21808   vat_main_t *vam = &vat_main;
21809   vat_json_node_t node;
21810
21811   vat_json_init_object (&node);
21812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21813   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21814
21815   vat_json_print (vam->ofp, &node);
21816   vat_json_free (&node);
21817
21818   vam->retval = ntohl (mp->retval);
21819   vam->result_ready = 1;
21820 }
21821
21822 static int
21823 api_app_namespace_add_del (vat_main_t * vam)
21824 {
21825   vl_api_app_namespace_add_del_t *mp;
21826   unformat_input_t *i = vam->input;
21827   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21828   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21829   u64 secret;
21830   int ret;
21831
21832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21833     {
21834       if (unformat (i, "id %_%v%_", &ns_id))
21835         ;
21836       else if (unformat (i, "secret %lu", &secret))
21837         secret_set = 1;
21838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21839         sw_if_index_set = 1;
21840       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21841         ;
21842       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21843         ;
21844       else
21845         break;
21846     }
21847   if (!ns_id || !secret_set || !sw_if_index_set)
21848     {
21849       errmsg ("namespace id, secret and sw_if_index must be set");
21850       return -99;
21851     }
21852   if (vec_len (ns_id) > 64)
21853     {
21854       errmsg ("namespace id too long");
21855       return -99;
21856     }
21857   M (APP_NAMESPACE_ADD_DEL, mp);
21858
21859   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21860   mp->namespace_id_len = vec_len (ns_id);
21861   mp->secret = clib_host_to_net_u64 (secret);
21862   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21863   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21864   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21865   vec_free (ns_id);
21866   S (mp);
21867   W (ret);
21868   return ret;
21869 }
21870
21871 static int
21872 api_memfd_segment_create (vat_main_t * vam)
21873 {
21874 #if VPP_API_TEST_BUILTIN == 0
21875   unformat_input_t *i = vam->input;
21876   vl_api_memfd_segment_create_t *mp;
21877   u64 size = 64 << 20;
21878   int ret;
21879
21880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21881     {
21882       if (unformat (i, "size %U", unformat_memory_size, &size))
21883         ;
21884       else
21885         break;
21886     }
21887
21888   M (MEMFD_SEGMENT_CREATE, mp);
21889   mp->requested_size = size;
21890   S (mp);
21891   W (ret);
21892   return ret;
21893
21894 #else
21895   errmsg ("memfd_segment_create (builtin) not supported");
21896   return -99;
21897 #endif
21898 }
21899
21900 static int
21901 api_sock_init_shm (vat_main_t * vam)
21902 {
21903 #if VPP_API_TEST_BUILTIN == 0
21904   unformat_input_t *i = vam->input;
21905   vl_api_shm_elem_config_t *config = 0;
21906   u64 size = 64 << 20;
21907   int rv;
21908
21909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21910     {
21911       if (unformat (i, "size %U", unformat_memory_size, &size))
21912         ;
21913       else
21914         break;
21915     }
21916
21917   /* Try customized config to see if it works */
21918   vec_validate (config, 3);
21919   config[0].type = VL_API_VLIB_RING;
21920   config[0].count = 256;
21921   config[0].size = 256;
21922   config[1].type = VL_API_CLIENT_RING;
21923   config[1].count = 256;
21924   config[1].size = 1024;
21925   config[2].type = VL_API_CLIENT_RING;
21926   config[2].count = 8;
21927   config[2].size = 4096;
21928   config[3].type = VL_API_QUEUE;
21929   config[3].count = 256;
21930   config[3].size = sizeof (uword);
21931   rv = vl_socket_client_init_shm (config);
21932   if (!rv)
21933     vam->client_index_invalid = 1;
21934   return rv;
21935 #else
21936   return -99;
21937 #endif
21938 }
21939
21940 static int
21941 api_dns_enable_disable (vat_main_t * vam)
21942 {
21943   unformat_input_t *line_input = vam->input;
21944   vl_api_dns_enable_disable_t *mp;
21945   u8 enable_disable = 1;
21946   int ret;
21947
21948   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21949     {
21950       if (unformat (line_input, "disable"))
21951         enable_disable = 0;
21952       if (unformat (line_input, "enable"))
21953         enable_disable = 1;
21954       else
21955         break;
21956     }
21957
21958   /* Construct the API message */
21959   M (DNS_ENABLE_DISABLE, mp);
21960   mp->enable = enable_disable;
21961
21962   /* send it... */
21963   S (mp);
21964   /* Wait for the reply */
21965   W (ret);
21966   return ret;
21967 }
21968
21969 static int
21970 api_dns_resolve_name (vat_main_t * vam)
21971 {
21972   unformat_input_t *line_input = vam->input;
21973   vl_api_dns_resolve_name_t *mp;
21974   u8 *name = 0;
21975   int ret;
21976
21977   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21978     {
21979       if (unformat (line_input, "%s", &name))
21980         ;
21981       else
21982         break;
21983     }
21984
21985   if (vec_len (name) > 127)
21986     {
21987       errmsg ("name too long");
21988       return -99;
21989     }
21990
21991   /* Construct the API message */
21992   M (DNS_RESOLVE_NAME, mp);
21993   memcpy (mp->name, name, vec_len (name));
21994   vec_free (name);
21995
21996   /* send it... */
21997   S (mp);
21998   /* Wait for the reply */
21999   W (ret);
22000   return ret;
22001 }
22002
22003 static int
22004 api_dns_resolve_ip (vat_main_t * vam)
22005 {
22006   unformat_input_t *line_input = vam->input;
22007   vl_api_dns_resolve_ip_t *mp;
22008   int is_ip6 = -1;
22009   ip4_address_t addr4;
22010   ip6_address_t addr6;
22011   int ret;
22012
22013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22014     {
22015       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22016         is_ip6 = 1;
22017       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22018         is_ip6 = 0;
22019       else
22020         break;
22021     }
22022
22023   if (is_ip6 == -1)
22024     {
22025       errmsg ("missing address");
22026       return -99;
22027     }
22028
22029   /* Construct the API message */
22030   M (DNS_RESOLVE_IP, mp);
22031   mp->is_ip6 = is_ip6;
22032   if (is_ip6)
22033     memcpy (mp->address, &addr6, sizeof (addr6));
22034   else
22035     memcpy (mp->address, &addr4, sizeof (addr4));
22036
22037   /* send it... */
22038   S (mp);
22039   /* Wait for the reply */
22040   W (ret);
22041   return ret;
22042 }
22043
22044 static int
22045 api_dns_name_server_add_del (vat_main_t * vam)
22046 {
22047   unformat_input_t *i = vam->input;
22048   vl_api_dns_name_server_add_del_t *mp;
22049   u8 is_add = 1;
22050   ip6_address_t ip6_server;
22051   ip4_address_t ip4_server;
22052   int ip6_set = 0;
22053   int ip4_set = 0;
22054   int ret = 0;
22055
22056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22057     {
22058       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22059         ip6_set = 1;
22060       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22061         ip4_set = 1;
22062       else if (unformat (i, "del"))
22063         is_add = 0;
22064       else
22065         {
22066           clib_warning ("parse error '%U'", format_unformat_error, i);
22067           return -99;
22068         }
22069     }
22070
22071   if (ip4_set && ip6_set)
22072     {
22073       errmsg ("Only one server address allowed per message");
22074       return -99;
22075     }
22076   if ((ip4_set + ip6_set) == 0)
22077     {
22078       errmsg ("Server address required");
22079       return -99;
22080     }
22081
22082   /* Construct the API message */
22083   M (DNS_NAME_SERVER_ADD_DEL, mp);
22084
22085   if (ip6_set)
22086     {
22087       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22088       mp->is_ip6 = 1;
22089     }
22090   else
22091     {
22092       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22093       mp->is_ip6 = 0;
22094     }
22095
22096   mp->is_add = is_add;
22097
22098   /* send it... */
22099   S (mp);
22100
22101   /* Wait for a reply, return good/bad news  */
22102   W (ret);
22103   return ret;
22104 }
22105
22106 static void
22107 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22108 {
22109   vat_main_t *vam = &vat_main;
22110
22111   if (mp->is_ip4)
22112     {
22113       print (vam->ofp,
22114              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22115              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22116              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22117              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22118              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22119              clib_net_to_host_u32 (mp->action_index), mp->tag);
22120     }
22121   else
22122     {
22123       print (vam->ofp,
22124              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22125              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22126              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22127              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22128              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22129              clib_net_to_host_u32 (mp->action_index), mp->tag);
22130     }
22131 }
22132
22133 static void
22134 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22135                                              mp)
22136 {
22137   vat_main_t *vam = &vat_main;
22138   vat_json_node_t *node = NULL;
22139   struct in6_addr ip6;
22140   struct in_addr ip4;
22141
22142   if (VAT_JSON_ARRAY != vam->json_tree.type)
22143     {
22144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22145       vat_json_init_array (&vam->json_tree);
22146     }
22147   node = vat_json_array_add (&vam->json_tree);
22148   vat_json_init_object (node);
22149
22150   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22151   vat_json_object_add_uint (node, "appns_index",
22152                             clib_net_to_host_u32 (mp->appns_index));
22153   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22154   vat_json_object_add_uint (node, "scope", mp->scope);
22155   vat_json_object_add_uint (node, "action_index",
22156                             clib_net_to_host_u32 (mp->action_index));
22157   vat_json_object_add_uint (node, "lcl_port",
22158                             clib_net_to_host_u16 (mp->lcl_port));
22159   vat_json_object_add_uint (node, "rmt_port",
22160                             clib_net_to_host_u16 (mp->rmt_port));
22161   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22162   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22163   vat_json_object_add_string_copy (node, "tag", mp->tag);
22164   if (mp->is_ip4)
22165     {
22166       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22167       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22168       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22169       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22170     }
22171   else
22172     {
22173       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22174       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22175       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22176       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22177     }
22178 }
22179
22180 static int
22181 api_session_rule_add_del (vat_main_t * vam)
22182 {
22183   vl_api_session_rule_add_del_t *mp;
22184   unformat_input_t *i = vam->input;
22185   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22186   u32 appns_index = 0, scope = 0;
22187   ip4_address_t lcl_ip4, rmt_ip4;
22188   ip6_address_t lcl_ip6, rmt_ip6;
22189   u8 is_ip4 = 1, conn_set = 0;
22190   u8 is_add = 1, *tag = 0;
22191   int ret;
22192
22193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22194     {
22195       if (unformat (i, "del"))
22196         is_add = 0;
22197       else if (unformat (i, "add"))
22198         ;
22199       else if (unformat (i, "proto tcp"))
22200         proto = 0;
22201       else if (unformat (i, "proto udp"))
22202         proto = 1;
22203       else if (unformat (i, "appns %d", &appns_index))
22204         ;
22205       else if (unformat (i, "scope %d", &scope))
22206         ;
22207       else if (unformat (i, "tag %_%v%_", &tag))
22208         ;
22209       else
22210         if (unformat
22211             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22212              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22213              &rmt_port))
22214         {
22215           is_ip4 = 1;
22216           conn_set = 1;
22217         }
22218       else
22219         if (unformat
22220             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22221              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22222              &rmt_port))
22223         {
22224           is_ip4 = 0;
22225           conn_set = 1;
22226         }
22227       else if (unformat (i, "action %d", &action))
22228         ;
22229       else
22230         break;
22231     }
22232   if (proto == ~0 || !conn_set || action == ~0)
22233     {
22234       errmsg ("transport proto, connection and action must be set");
22235       return -99;
22236     }
22237
22238   if (scope > 3)
22239     {
22240       errmsg ("scope should be 0-3");
22241       return -99;
22242     }
22243
22244   M (SESSION_RULE_ADD_DEL, mp);
22245
22246   mp->is_ip4 = is_ip4;
22247   mp->transport_proto = proto;
22248   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22249   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22250   mp->lcl_plen = lcl_plen;
22251   mp->rmt_plen = rmt_plen;
22252   mp->action_index = clib_host_to_net_u32 (action);
22253   mp->appns_index = clib_host_to_net_u32 (appns_index);
22254   mp->scope = scope;
22255   mp->is_add = is_add;
22256   if (is_ip4)
22257     {
22258       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22259       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22260     }
22261   else
22262     {
22263       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22264       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22265     }
22266   if (tag)
22267     {
22268       clib_memcpy (mp->tag, tag, vec_len (tag));
22269       vec_free (tag);
22270     }
22271
22272   S (mp);
22273   W (ret);
22274   return ret;
22275 }
22276
22277 static int
22278 api_session_rules_dump (vat_main_t * vam)
22279 {
22280   vl_api_session_rules_dump_t *mp;
22281   vl_api_control_ping_t *mp_ping;
22282   int ret;
22283
22284   if (!vam->json_output)
22285     {
22286       print (vam->ofp, "%=20s", "Session Rules");
22287     }
22288
22289   M (SESSION_RULES_DUMP, mp);
22290   /* send it... */
22291   S (mp);
22292
22293   /* Use a control ping for synchronization */
22294   MPING (CONTROL_PING, mp_ping);
22295   S (mp_ping);
22296
22297   /* Wait for a reply... */
22298   W (ret);
22299   return ret;
22300 }
22301
22302 static int
22303 api_ip_container_proxy_add_del (vat_main_t * vam)
22304 {
22305   vl_api_ip_container_proxy_add_del_t *mp;
22306   unformat_input_t *i = vam->input;
22307   u32 plen = ~0, sw_if_index = ~0;
22308   ip4_address_t ip4;
22309   ip6_address_t ip6;
22310   u8 is_ip4 = 1;
22311   u8 is_add = 1;
22312   int ret;
22313
22314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22315     {
22316       if (unformat (i, "del"))
22317         is_add = 0;
22318       else if (unformat (i, "add"))
22319         ;
22320       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22321         {
22322           is_ip4 = 1;
22323           plen = 32;
22324         }
22325       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22326         {
22327           is_ip4 = 0;
22328           plen = 128;
22329         }
22330       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22331         ;
22332       else
22333         break;
22334     }
22335   if (sw_if_index == ~0 || plen == ~0)
22336     {
22337       errmsg ("address and sw_if_index must be set");
22338       return -99;
22339     }
22340
22341   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22342
22343   mp->is_ip4 = is_ip4;
22344   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22345   mp->plen = plen;
22346   mp->is_add = is_add;
22347   if (is_ip4)
22348     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22349   else
22350     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22351
22352   S (mp);
22353   W (ret);
22354   return ret;
22355 }
22356
22357 static int
22358 q_or_quit (vat_main_t * vam)
22359 {
22360 #if VPP_API_TEST_BUILTIN == 0
22361   longjmp (vam->jump_buf, 1);
22362 #endif
22363   return 0;                     /* not so much */
22364 }
22365
22366 static int
22367 q (vat_main_t * vam)
22368 {
22369   return q_or_quit (vam);
22370 }
22371
22372 static int
22373 quit (vat_main_t * vam)
22374 {
22375   return q_or_quit (vam);
22376 }
22377
22378 static int
22379 comment (vat_main_t * vam)
22380 {
22381   return 0;
22382 }
22383
22384 static int
22385 cmd_cmp (void *a1, void *a2)
22386 {
22387   u8 **c1 = a1;
22388   u8 **c2 = a2;
22389
22390   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22391 }
22392
22393 static int
22394 help (vat_main_t * vam)
22395 {
22396   u8 **cmds = 0;
22397   u8 *name = 0;
22398   hash_pair_t *p;
22399   unformat_input_t *i = vam->input;
22400   int j;
22401
22402   if (unformat (i, "%s", &name))
22403     {
22404       uword *hs;
22405
22406       vec_add1 (name, 0);
22407
22408       hs = hash_get_mem (vam->help_by_name, name);
22409       if (hs)
22410         print (vam->ofp, "usage: %s %s", name, hs[0]);
22411       else
22412         print (vam->ofp, "No such msg / command '%s'", name);
22413       vec_free (name);
22414       return 0;
22415     }
22416
22417   print (vam->ofp, "Help is available for the following:");
22418
22419     /* *INDENT-OFF* */
22420     hash_foreach_pair (p, vam->function_by_name,
22421     ({
22422       vec_add1 (cmds, (u8 *)(p->key));
22423     }));
22424     /* *INDENT-ON* */
22425
22426   vec_sort_with_function (cmds, cmd_cmp);
22427
22428   for (j = 0; j < vec_len (cmds); j++)
22429     print (vam->ofp, "%s", cmds[j]);
22430
22431   vec_free (cmds);
22432   return 0;
22433 }
22434
22435 static int
22436 set (vat_main_t * vam)
22437 {
22438   u8 *name = 0, *value = 0;
22439   unformat_input_t *i = vam->input;
22440
22441   if (unformat (i, "%s", &name))
22442     {
22443       /* The input buffer is a vector, not a string. */
22444       value = vec_dup (i->buffer);
22445       vec_delete (value, i->index, 0);
22446       /* Almost certainly has a trailing newline */
22447       if (value[vec_len (value) - 1] == '\n')
22448         value[vec_len (value) - 1] = 0;
22449       /* Make sure it's a proper string, one way or the other */
22450       vec_add1 (value, 0);
22451       (void) clib_macro_set_value (&vam->macro_main,
22452                                    (char *) name, (char *) value);
22453     }
22454   else
22455     errmsg ("usage: set <name> <value>");
22456
22457   vec_free (name);
22458   vec_free (value);
22459   return 0;
22460 }
22461
22462 static int
22463 unset (vat_main_t * vam)
22464 {
22465   u8 *name = 0;
22466
22467   if (unformat (vam->input, "%s", &name))
22468     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22469       errmsg ("unset: %s wasn't set", name);
22470   vec_free (name);
22471   return 0;
22472 }
22473
22474 typedef struct
22475 {
22476   u8 *name;
22477   u8 *value;
22478 } macro_sort_t;
22479
22480
22481 static int
22482 macro_sort_cmp (void *a1, void *a2)
22483 {
22484   macro_sort_t *s1 = a1;
22485   macro_sort_t *s2 = a2;
22486
22487   return strcmp ((char *) (s1->name), (char *) (s2->name));
22488 }
22489
22490 static int
22491 dump_macro_table (vat_main_t * vam)
22492 {
22493   macro_sort_t *sort_me = 0, *sm;
22494   int i;
22495   hash_pair_t *p;
22496
22497     /* *INDENT-OFF* */
22498     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22499     ({
22500       vec_add2 (sort_me, sm, 1);
22501       sm->name = (u8 *)(p->key);
22502       sm->value = (u8 *) (p->value[0]);
22503     }));
22504     /* *INDENT-ON* */
22505
22506   vec_sort_with_function (sort_me, macro_sort_cmp);
22507
22508   if (vec_len (sort_me))
22509     print (vam->ofp, "%-15s%s", "Name", "Value");
22510   else
22511     print (vam->ofp, "The macro table is empty...");
22512
22513   for (i = 0; i < vec_len (sort_me); i++)
22514     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22515   return 0;
22516 }
22517
22518 static int
22519 dump_node_table (vat_main_t * vam)
22520 {
22521   int i, j;
22522   vlib_node_t *node, *next_node;
22523
22524   if (vec_len (vam->graph_nodes) == 0)
22525     {
22526       print (vam->ofp, "Node table empty, issue get_node_graph...");
22527       return 0;
22528     }
22529
22530   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22531     {
22532       node = vam->graph_nodes[i];
22533       print (vam->ofp, "[%d] %s", i, node->name);
22534       for (j = 0; j < vec_len (node->next_nodes); j++)
22535         {
22536           if (node->next_nodes[j] != ~0)
22537             {
22538               next_node = vam->graph_nodes[node->next_nodes[j]];
22539               print (vam->ofp, "  [%d] %s", j, next_node->name);
22540             }
22541         }
22542     }
22543   return 0;
22544 }
22545
22546 static int
22547 value_sort_cmp (void *a1, void *a2)
22548 {
22549   name_sort_t *n1 = a1;
22550   name_sort_t *n2 = a2;
22551
22552   if (n1->value < n2->value)
22553     return -1;
22554   if (n1->value > n2->value)
22555     return 1;
22556   return 0;
22557 }
22558
22559
22560 static int
22561 dump_msg_api_table (vat_main_t * vam)
22562 {
22563   api_main_t *am = &api_main;
22564   name_sort_t *nses = 0, *ns;
22565   hash_pair_t *hp;
22566   int i;
22567
22568   /* *INDENT-OFF* */
22569   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22570   ({
22571     vec_add2 (nses, ns, 1);
22572     ns->name = (u8 *)(hp->key);
22573     ns->value = (u32) hp->value[0];
22574   }));
22575   /* *INDENT-ON* */
22576
22577   vec_sort_with_function (nses, value_sort_cmp);
22578
22579   for (i = 0; i < vec_len (nses); i++)
22580     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22581   vec_free (nses);
22582   return 0;
22583 }
22584
22585 static int
22586 get_msg_id (vat_main_t * vam)
22587 {
22588   u8 *name_and_crc;
22589   u32 message_index;
22590
22591   if (unformat (vam->input, "%s", &name_and_crc))
22592     {
22593       message_index = vl_msg_api_get_msg_index (name_and_crc);
22594       if (message_index == ~0)
22595         {
22596           print (vam->ofp, " '%s' not found", name_and_crc);
22597           return 0;
22598         }
22599       print (vam->ofp, " '%s' has message index %d",
22600              name_and_crc, message_index);
22601       return 0;
22602     }
22603   errmsg ("name_and_crc required...");
22604   return 0;
22605 }
22606
22607 static int
22608 search_node_table (vat_main_t * vam)
22609 {
22610   unformat_input_t *line_input = vam->input;
22611   u8 *node_to_find;
22612   int j;
22613   vlib_node_t *node, *next_node;
22614   uword *p;
22615
22616   if (vam->graph_node_index_by_name == 0)
22617     {
22618       print (vam->ofp, "Node table empty, issue get_node_graph...");
22619       return 0;
22620     }
22621
22622   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22623     {
22624       if (unformat (line_input, "%s", &node_to_find))
22625         {
22626           vec_add1 (node_to_find, 0);
22627           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22628           if (p == 0)
22629             {
22630               print (vam->ofp, "%s not found...", node_to_find);
22631               goto out;
22632             }
22633           node = vam->graph_nodes[p[0]];
22634           print (vam->ofp, "[%d] %s", p[0], node->name);
22635           for (j = 0; j < vec_len (node->next_nodes); j++)
22636             {
22637               if (node->next_nodes[j] != ~0)
22638                 {
22639                   next_node = vam->graph_nodes[node->next_nodes[j]];
22640                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22641                 }
22642             }
22643         }
22644
22645       else
22646         {
22647           clib_warning ("parse error '%U'", format_unformat_error,
22648                         line_input);
22649           return -99;
22650         }
22651
22652     out:
22653       vec_free (node_to_find);
22654
22655     }
22656
22657   return 0;
22658 }
22659
22660
22661 static int
22662 script (vat_main_t * vam)
22663 {
22664 #if (VPP_API_TEST_BUILTIN==0)
22665   u8 *s = 0;
22666   char *save_current_file;
22667   unformat_input_t save_input;
22668   jmp_buf save_jump_buf;
22669   u32 save_line_number;
22670
22671   FILE *new_fp, *save_ifp;
22672
22673   if (unformat (vam->input, "%s", &s))
22674     {
22675       new_fp = fopen ((char *) s, "r");
22676       if (new_fp == 0)
22677         {
22678           errmsg ("Couldn't open script file %s", s);
22679           vec_free (s);
22680           return -99;
22681         }
22682     }
22683   else
22684     {
22685       errmsg ("Missing script name");
22686       return -99;
22687     }
22688
22689   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22690   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22691   save_ifp = vam->ifp;
22692   save_line_number = vam->input_line_number;
22693   save_current_file = (char *) vam->current_file;
22694
22695   vam->input_line_number = 0;
22696   vam->ifp = new_fp;
22697   vam->current_file = s;
22698   do_one_file (vam);
22699
22700   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22701   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22702   vam->ifp = save_ifp;
22703   vam->input_line_number = save_line_number;
22704   vam->current_file = (u8 *) save_current_file;
22705   vec_free (s);
22706
22707   return 0;
22708 #else
22709   clib_warning ("use the exec command...");
22710   return -99;
22711 #endif
22712 }
22713
22714 static int
22715 echo (vat_main_t * vam)
22716 {
22717   print (vam->ofp, "%v", vam->input->buffer);
22718   return 0;
22719 }
22720
22721 /* List of API message constructors, CLI names map to api_xxx */
22722 #define foreach_vpe_api_msg                                             \
22723 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22724 _(sw_interface_dump,"")                                                 \
22725 _(sw_interface_set_flags,                                               \
22726   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22727 _(sw_interface_add_del_address,                                         \
22728   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22729 _(sw_interface_set_rx_mode,                                             \
22730   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22731 _(sw_interface_set_table,                                               \
22732   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22733 _(sw_interface_set_mpls_enable,                                         \
22734   "<intfc> | sw_if_index [disable | dis]")                              \
22735 _(sw_interface_set_vpath,                                               \
22736   "<intfc> | sw_if_index <id> enable | disable")                        \
22737 _(sw_interface_set_vxlan_bypass,                                        \
22738   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22739 _(sw_interface_set_geneve_bypass,                                       \
22740   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22741 _(sw_interface_set_l2_xconnect,                                         \
22742   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22743   "enable | disable")                                                   \
22744 _(sw_interface_set_l2_bridge,                                           \
22745   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22746   "[shg <split-horizon-group>] [bvi]\n"                                 \
22747   "enable | disable")                                                   \
22748 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22749 _(bridge_domain_add_del,                                                \
22750   "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") \
22751 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22752 _(l2fib_add_del,                                                        \
22753   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22754 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22755 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22756 _(l2_flags,                                                             \
22757   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22758 _(bridge_flags,                                                         \
22759   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22760 _(tap_connect,                                                          \
22761   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22762 _(tap_modify,                                                           \
22763   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22764 _(tap_delete,                                                           \
22765   "<vpp-if-name> | sw_if_index <id>")                                   \
22766 _(sw_interface_tap_dump, "")                                            \
22767 _(tap_create_v2,                                                        \
22768   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22769 _(tap_delete_v2,                                                        \
22770   "<vpp-if-name> | sw_if_index <id>")                                   \
22771 _(sw_interface_tap_v2_dump, "")                                         \
22772 _(ip_table_add_del,                                                     \
22773   "table-id <n> [ipv6]\n")                                              \
22774 _(ip_add_del_route,                                                     \
22775   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22776   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22777   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22778   "[multipath] [count <n>]")                                            \
22779 _(ip_mroute_add_del,                                                    \
22780   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22781   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22782 _(mpls_table_add_del,                                                   \
22783   "table-id <n>\n")                                                     \
22784 _(mpls_route_add_del,                                                   \
22785   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22786   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22787   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22788   "[multipath] [count <n>]")                                            \
22789 _(mpls_ip_bind_unbind,                                                  \
22790   "<label> <addr/len>")                                                 \
22791 _(mpls_tunnel_add_del,                                                  \
22792   " via <addr> [table-id <n>]\n"                                        \
22793   "sw_if_index <id>] [l2]  [del]")                                      \
22794 _(bier_table_add_del,                                                   \
22795   "<label> <sub-domain> <set> <bsl> [del]")                             \
22796 _(bier_route_add_del,                                                   \
22797   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22798   "[<intfc> | sw_if_index <id>]"                                        \
22799   "[weight <n>] [del] [multipath]")                                     \
22800 _(proxy_arp_add_del,                                                    \
22801   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22802 _(proxy_arp_intfc_enable_disable,                                       \
22803   "<intfc> | sw_if_index <id> enable | disable")                        \
22804 _(sw_interface_set_unnumbered,                                          \
22805   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22806 _(ip_neighbor_add_del,                                                  \
22807   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22808   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22809 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22810 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22811   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22812   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22813   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22814 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22815 _(reset_fib, "vrf <n> [ipv6]")                                          \
22816 _(dhcp_proxy_config,                                                    \
22817   "svr <v46-address> src <v46-address>\n"                               \
22818    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22819 _(dhcp_proxy_set_vss,                                                   \
22820   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22821 _(dhcp_proxy_dump, "ip6")                                               \
22822 _(dhcp_client_config,                                                   \
22823   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22824 _(set_ip_flow_hash,                                                     \
22825   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22826 _(sw_interface_ip6_enable_disable,                                      \
22827   "<intfc> | sw_if_index <id> enable | disable")                        \
22828 _(sw_interface_ip6_set_link_local_address,                              \
22829   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22830 _(ip6nd_proxy_add_del,                                                  \
22831   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22832 _(ip6nd_proxy_dump, "")                                                 \
22833 _(sw_interface_ip6nd_ra_prefix,                                         \
22834   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22835   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22836   "[nolink] [isno]")                                                    \
22837 _(sw_interface_ip6nd_ra_config,                                         \
22838   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22839   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22840   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22841 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22842 _(l2_patch_add_del,                                                     \
22843   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22844   "enable | disable")                                                   \
22845 _(sr_localsid_add_del,                                                  \
22846   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22847   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22848 _(classify_add_del_table,                                               \
22849   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22850   " [del] [del-chain] mask <mask-value>\n"                              \
22851   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22852   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22853 _(classify_add_del_session,                                             \
22854   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22855   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22856   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22857   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22858 _(classify_set_interface_ip_table,                                      \
22859   "<intfc> | sw_if_index <nn> table <nn>")                              \
22860 _(classify_set_interface_l2_tables,                                     \
22861   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22862   "  [other-table <nn>]")                                               \
22863 _(get_node_index, "node <node-name")                                    \
22864 _(add_node_next, "node <node-name> next <next-node-name>")              \
22865 _(l2tpv3_create_tunnel,                                                 \
22866   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22867   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22868   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22869 _(l2tpv3_set_tunnel_cookies,                                            \
22870   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22871   "[new_remote_cookie <nn>]\n")                                         \
22872 _(l2tpv3_interface_enable_disable,                                      \
22873   "<intfc> | sw_if_index <nn> enable | disable")                        \
22874 _(l2tpv3_set_lookup_key,                                                \
22875   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22876 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22877 _(vxlan_add_del_tunnel,                                                 \
22878   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22879   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22880   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22881 _(geneve_add_del_tunnel,                                                \
22882   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22883   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22884   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22885 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22886 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22887 _(gre_add_del_tunnel,                                                   \
22888   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22889 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22890 _(l2_fib_clear_table, "")                                               \
22891 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22892 _(l2_interface_vlan_tag_rewrite,                                        \
22893   "<intfc> | sw_if_index <nn> \n"                                       \
22894   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22895   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22896 _(create_vhost_user_if,                                                 \
22897         "socket <filename> [server] [renumber <dev_instance>] "         \
22898         "[mac <mac_address>]")                                          \
22899 _(modify_vhost_user_if,                                                 \
22900         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22901         "[server] [renumber <dev_instance>]")                           \
22902 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22903 _(sw_interface_vhost_user_dump, "")                                     \
22904 _(show_version, "")                                                     \
22905 _(vxlan_gpe_add_del_tunnel,                                             \
22906   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22907   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22908   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22909   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22910 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22911 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22912 _(interface_name_renumber,                                              \
22913   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22914 _(input_acl_set_interface,                                              \
22915   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22916   "  [l2-table <nn>] [del]")                                            \
22917 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22918 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22919 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22920 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22921 _(ip_dump, "ipv4 | ipv6")                                               \
22922 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22923 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22924   "  spid_id <n> ")                                                     \
22925 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22926   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22927   "  integ_alg <alg> integ_key <hex>")                                  \
22928 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22929   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22930   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22931   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22932 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22933 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22934   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22935   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22936   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22937 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22938 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22939   "  <alg> <hex>\n")                                                    \
22940 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22941 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22942 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22943   "(auth_data 0x<data> | auth_data <data>)")                            \
22944 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22945   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22946 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22947   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22948   "(local|remote)")                                                     \
22949 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22950 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22951 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22952 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22953 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22954 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22955 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22956 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22957 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22958 _(delete_loopback,"sw_if_index <nn>")                                   \
22959 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22960 _(map_add_domain,                                                       \
22961   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22962   "ip6-src <ip6addr> "                                                  \
22963   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22964 _(map_del_domain, "index <n>")                                          \
22965 _(map_add_del_rule,                                                     \
22966   "index <n> psid <n> dst <ip6addr> [del]")                             \
22967 _(map_domain_dump, "")                                                  \
22968 _(map_rule_dump, "index <map-domain>")                                  \
22969 _(want_interface_events,  "enable|disable")                             \
22970 _(want_stats,"enable|disable")                                          \
22971 _(get_first_msg_id, "client <name>")                                    \
22972 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22973 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22974   "fib-id <nn> [ip4][ip6][default]")                                    \
22975 _(get_node_graph, " ")                                                  \
22976 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22977 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22978 _(ioam_disable, "")                                                     \
22979 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22980                             " sw_if_index <sw_if_index> p <priority> "  \
22981                             "w <weight>] [del]")                        \
22982 _(one_add_del_locator, "locator-set <locator_name> "                    \
22983                         "iface <intf> | sw_if_index <sw_if_index> "     \
22984                         "p <priority> w <weight> [del]")                \
22985 _(one_add_del_local_eid,"vni <vni> eid "                                \
22986                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22987                          "locator-set <locator_name> [del]"             \
22988                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22989 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22990 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22991 _(one_enable_disable, "enable|disable")                                 \
22992 _(one_map_register_enable_disable, "enable|disable")                    \
22993 _(one_map_register_fallback_threshold, "<value>")                       \
22994 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22995 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22996                                "[seid <seid>] "                         \
22997                                "rloc <locator> p <prio> "               \
22998                                "w <weight> [rloc <loc> ... ] "          \
22999                                "action <action> [del-all]")             \
23000 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23001                           "<local-eid>")                                \
23002 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23003 _(one_use_petr, "ip-address> | disable")                                \
23004 _(one_map_request_mode, "src-dst|dst-only")                             \
23005 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23006 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23007 _(one_locator_set_dump, "[local | remote]")                             \
23008 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23009 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23010                        "[local] | [remote]")                            \
23011 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23012 _(one_ndp_bd_get, "")                                                   \
23013 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23014 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23015 _(one_l2_arp_bd_get, "")                                                \
23016 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23017 _(one_stats_enable_disable, "enable|disalbe")                           \
23018 _(show_one_stats_enable_disable, "")                                    \
23019 _(one_eid_table_vni_dump, "")                                           \
23020 _(one_eid_table_map_dump, "l2|l3")                                      \
23021 _(one_map_resolver_dump, "")                                            \
23022 _(one_map_server_dump, "")                                              \
23023 _(one_adjacencies_get, "vni <vni>")                                     \
23024 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23025 _(show_one_rloc_probe_state, "")                                        \
23026 _(show_one_map_register_state, "")                                      \
23027 _(show_one_status, "")                                                  \
23028 _(one_stats_dump, "")                                                   \
23029 _(one_stats_flush, "")                                                  \
23030 _(one_get_map_request_itr_rlocs, "")                                    \
23031 _(one_map_register_set_ttl, "<ttl>")                                    \
23032 _(one_set_transport_protocol, "udp|api")                                \
23033 _(one_get_transport_protocol, "")                                       \
23034 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23035 _(one_show_xtr_mode, "")                                                \
23036 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23037 _(one_show_pitr_mode, "")                                               \
23038 _(one_enable_disable_petr_mode, "enable|disable")                       \
23039 _(one_show_petr_mode, "")                                               \
23040 _(show_one_nsh_mapping, "")                                             \
23041 _(show_one_pitr, "")                                                    \
23042 _(show_one_use_petr, "")                                                \
23043 _(show_one_map_request_mode, "")                                        \
23044 _(show_one_map_register_ttl, "")                                        \
23045 _(show_one_map_register_fallback_threshold, "")                         \
23046 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23047                             " sw_if_index <sw_if_index> p <priority> "  \
23048                             "w <weight>] [del]")                        \
23049 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23050                         "iface <intf> | sw_if_index <sw_if_index> "     \
23051                         "p <priority> w <weight> [del]")                \
23052 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23053                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23054                          "locator-set <locator_name> [del]"             \
23055                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23056 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23057 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23058 _(lisp_enable_disable, "enable|disable")                                \
23059 _(lisp_map_register_enable_disable, "enable|disable")                   \
23060 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23061 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23062                                "[seid <seid>] "                         \
23063                                "rloc <locator> p <prio> "               \
23064                                "w <weight> [rloc <loc> ... ] "          \
23065                                "action <action> [del-all]")             \
23066 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23067                           "<local-eid>")                                \
23068 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23069 _(lisp_use_petr, "<ip-address> | disable")                              \
23070 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23071 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23072 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23073 _(lisp_locator_set_dump, "[local | remote]")                            \
23074 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23075 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23076                        "[local] | [remote]")                            \
23077 _(lisp_eid_table_vni_dump, "")                                          \
23078 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23079 _(lisp_map_resolver_dump, "")                                           \
23080 _(lisp_map_server_dump, "")                                             \
23081 _(lisp_adjacencies_get, "vni <vni>")                                    \
23082 _(gpe_fwd_entry_vnis_get, "")                                           \
23083 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23084 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23085                                 "[table <table-id>]")                   \
23086 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23087 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23088 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23089 _(gpe_get_encap_mode, "")                                               \
23090 _(lisp_gpe_add_del_iface, "up|down")                                    \
23091 _(lisp_gpe_enable_disable, "enable|disable")                            \
23092 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23093   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23094 _(show_lisp_rloc_probe_state, "")                                       \
23095 _(show_lisp_map_register_state, "")                                     \
23096 _(show_lisp_status, "")                                                 \
23097 _(lisp_get_map_request_itr_rlocs, "")                                   \
23098 _(show_lisp_pitr, "")                                                   \
23099 _(show_lisp_use_petr, "")                                               \
23100 _(show_lisp_map_request_mode, "")                                       \
23101 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23102 _(af_packet_delete, "name <host interface name>")                       \
23103 _(policer_add_del, "name <policer name> <params> [del]")                \
23104 _(policer_dump, "[name <policer name>]")                                \
23105 _(policer_classify_set_interface,                                       \
23106   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23107   "  [l2-table <nn>] [del]")                                            \
23108 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23109 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23110     "[master|slave]")                                                   \
23111 _(netmap_delete, "name <interface name>")                               \
23112 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23113 _(mpls_fib_dump, "")                                                    \
23114 _(classify_table_ids, "")                                               \
23115 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23116 _(classify_table_info, "table_id <nn>")                                 \
23117 _(classify_session_dump, "table_id <nn>")                               \
23118 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23119     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23120     "[template_interval <nn>] [udp_checksum]")                          \
23121 _(ipfix_exporter_dump, "")                                              \
23122 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23123 _(ipfix_classify_stream_dump, "")                                       \
23124 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23125 _(ipfix_classify_table_dump, "")                                        \
23126 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23127 _(sw_interface_span_dump, "[l2]")                                           \
23128 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23129 _(pg_create_interface, "if_id <nn>")                                    \
23130 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23131 _(pg_enable_disable, "[stream <id>] disable")                           \
23132 _(ip_source_and_port_range_check_add_del,                               \
23133   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23134 _(ip_source_and_port_range_check_interface_add_del,                     \
23135   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23136   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23137 _(ipsec_gre_add_del_tunnel,                                             \
23138   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23139 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23140 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23141 _(l2_interface_pbb_tag_rewrite,                                         \
23142   "<intfc> | sw_if_index <nn> \n"                                       \
23143   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23144   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23145 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23146 _(flow_classify_set_interface,                                          \
23147   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23148 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23149 _(ip_fib_dump, "")                                                      \
23150 _(ip_mfib_dump, "")                                                     \
23151 _(ip6_fib_dump, "")                                                     \
23152 _(ip6_mfib_dump, "")                                                    \
23153 _(feature_enable_disable, "arc_name <arc_name> "                        \
23154   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23155 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23156 "[disable]")                                                            \
23157 _(l2_xconnect_dump, "")                                                 \
23158 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23159 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23160 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23161 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23162 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23163 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23164 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23165   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23166 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23167 _(memfd_segment_create,"size <nnn>")                                    \
23168 _(sock_init_shm, "size <nnn>")                                          \
23169 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23170 _(dns_enable_disable, "[enable][disable]")                              \
23171 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23172 _(dns_resolve_name, "<hostname>")                                       \
23173 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23174 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23175 _(dns_resolve_name, "<hostname>")                                       \
23176 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23177   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23178 _(session_rules_dump, "")                                               \
23179 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23180 _(output_acl_set_interface,                                             \
23181   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23182   "  [l2-table <nn>] [del]")                                            \
23183
23184 /* List of command functions, CLI names map directly to functions */
23185 #define foreach_cli_function                                    \
23186 _(comment, "usage: comment <ignore-rest-of-line>")              \
23187 _(dump_interface_table, "usage: dump_interface_table")          \
23188 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23189 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23190 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23191 _(dump_stats_table, "usage: dump_stats_table")                  \
23192 _(dump_macro_table, "usage: dump_macro_table ")                 \
23193 _(dump_node_table, "usage: dump_node_table")                    \
23194 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23195 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23196 _(echo, "usage: echo <message>")                                \
23197 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23198 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23199 _(help, "usage: help")                                          \
23200 _(q, "usage: quit")                                             \
23201 _(quit, "usage: quit")                                          \
23202 _(search_node_table, "usage: search_node_table <name>...")      \
23203 _(set, "usage: set <variable-name> <value>")                    \
23204 _(script, "usage: script <file-name>")                          \
23205 _(unset, "usage: unset <variable-name>")
23206 #define _(N,n)                                  \
23207     static void vl_api_##n##_t_handler_uni      \
23208     (vl_api_##n##_t * mp)                       \
23209     {                                           \
23210         vat_main_t * vam = &vat_main;           \
23211         if (vam->json_output) {                 \
23212             vl_api_##n##_t_handler_json(mp);    \
23213         } else {                                \
23214             vl_api_##n##_t_handler(mp);         \
23215         }                                       \
23216     }
23217 foreach_vpe_api_reply_msg;
23218 #if VPP_API_TEST_BUILTIN == 0
23219 foreach_standalone_reply_msg;
23220 #endif
23221 #undef _
23222
23223 void
23224 vat_api_hookup (vat_main_t * vam)
23225 {
23226 #define _(N,n)                                                  \
23227     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23228                            vl_api_##n##_t_handler_uni,          \
23229                            vl_noop_handler,                     \
23230                            vl_api_##n##_t_endian,               \
23231                            vl_api_##n##_t_print,                \
23232                            sizeof(vl_api_##n##_t), 1);
23233   foreach_vpe_api_reply_msg;
23234 #if VPP_API_TEST_BUILTIN == 0
23235   foreach_standalone_reply_msg;
23236 #endif
23237 #undef _
23238
23239 #if (VPP_API_TEST_BUILTIN==0)
23240   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23241
23242   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23243
23244   vam->function_by_name = hash_create_string (0, sizeof (uword));
23245
23246   vam->help_by_name = hash_create_string (0, sizeof (uword));
23247 #endif
23248
23249   /* API messages we can send */
23250 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23251   foreach_vpe_api_msg;
23252 #undef _
23253
23254   /* Help strings */
23255 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23256   foreach_vpe_api_msg;
23257 #undef _
23258
23259   /* CLI functions */
23260 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23261   foreach_cli_function;
23262 #undef _
23263
23264   /* Help strings */
23265 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23266   foreach_cli_function;
23267 #undef _
23268 }
23269
23270 #if VPP_API_TEST_BUILTIN
23271 static clib_error_t *
23272 vat_api_hookup_shim (vlib_main_t * vm)
23273 {
23274   vat_api_hookup (&vat_main);
23275   return 0;
23276 }
23277
23278 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23279 #endif
23280
23281 /*
23282  * fd.io coding-style-patch-verification: ON
23283  *
23284  * Local Variables:
23285  * eval: (c-set-style "gnu")
23286  * End:
23287  */