tapv2: add option to set host-side default gw
[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/input_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
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler          \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         i32 retval = ntohl(mp->retval);         \
5402         if (vam->async_mode) {                  \
5403             vam->async_errors += (retval < 0);  \
5404         } else {                                \
5405             vam->retval = retval;               \
5406             vam->result_ready = 1;              \
5407         }                                       \
5408     }
5409 foreach_standard_reply_retval_handler;
5410 #undef _
5411
5412 #define _(n)                                    \
5413     static void vl_api_##n##_t_handler_json     \
5414     (vl_api_##n##_t * mp)                       \
5415     {                                           \
5416         vat_main_t * vam = &vat_main;           \
5417         vat_json_node_t node;                   \
5418         vat_json_init_object(&node);            \
5419         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5420         vat_json_print(vam->ofp, &node);        \
5421         vam->retval = ntohl(mp->retval);        \
5422         vam->result_ready = 1;                  \
5423     }
5424 foreach_standard_reply_retval_handler;
5425 #undef _
5426
5427 /*
5428  * Table of message reply handlers, must include boilerplate handlers
5429  * we just generated
5430  */
5431
5432 #define foreach_vpe_api_reply_msg                                       \
5433 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5434 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5435 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5436 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5437 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5438 _(CLI_REPLY, cli_reply)                                                 \
5439 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5440 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5441   sw_interface_add_del_address_reply)                                   \
5442 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5443 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5444 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5445 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5446 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5447 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5448 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5449 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5450   sw_interface_set_l2_xconnect_reply)                                   \
5451 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5452   sw_interface_set_l2_bridge_reply)                                     \
5453 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5454 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5455 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5456 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5457 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5458 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5459 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5460 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5461 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5462 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5463 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5464 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5465 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5466 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5467 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5468 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5469 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5470 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5471 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5472 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5473 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5474 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5475 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5476 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5477 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5478   proxy_arp_intfc_enable_disable_reply)                                 \
5479 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5480 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5481   sw_interface_set_unnumbered_reply)                                    \
5482 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5483 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5484 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5485 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5486 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5487 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5488 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5489 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5490 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5491 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5492 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5493   sw_interface_ip6_enable_disable_reply)                                \
5494 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5495   sw_interface_ip6_set_link_local_address_reply)                        \
5496 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5497 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5498 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5499   sw_interface_ip6nd_ra_prefix_reply)                                   \
5500 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5501   sw_interface_ip6nd_ra_config_reply)                                   \
5502 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5503 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5504 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5505 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5506 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5507 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5508 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5509 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5510 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5511 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5512 classify_set_interface_ip_table_reply)                                  \
5513 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5514   classify_set_interface_l2_tables_reply)                               \
5515 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5516 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5517 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5518 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5519 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5520   l2tpv3_interface_enable_disable_reply)                                \
5521 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5522 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5523 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5524 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5525 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5526 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5527 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5528 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5529 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5530 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5531 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5532 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5533 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5534 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5535 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5536 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5537 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5538 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5539 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5540 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5541 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5542 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5543 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5544 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5545 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5546 _(L2_MACS_EVENT, l2_macs_event)                                         \
5547 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5548 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5549 _(IP_DETAILS, ip_details)                                               \
5550 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5551 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5552 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5553 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5554 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5555 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5556 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5557 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5558 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5559 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5560 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5561 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5562 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5563 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5564 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5565 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5566 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5567 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5568 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5569 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5570 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5571 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5572 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5573 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5574 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5575 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5576 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5577 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5578 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5579 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5580 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5581 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5582 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5583 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5584 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5585 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5586 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5587 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5588 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5589 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5590 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5591 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5592 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5593 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5594 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5595 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5596 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5597 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5598   one_map_register_enable_disable_reply)                                \
5599 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5600 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5601 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5602 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5603   one_map_register_fallback_threshold_reply)                            \
5604 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5605   one_rloc_probe_enable_disable_reply)                                  \
5606 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5607 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5608 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5609 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5610 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5611 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5612 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5613 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5614 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5615 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5616 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5617 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5618 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5619 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5620 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5621 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5622   show_one_stats_enable_disable_reply)                                  \
5623 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5624 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5625 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5626 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5627 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5628 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5629 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5630 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5631   one_enable_disable_pitr_mode_reply)                                   \
5632 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5633   one_enable_disable_petr_mode_reply)                                   \
5634 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5635 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5636 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5637 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5638 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5639 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5640 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5641 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5642 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5643 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5644 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5645 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5646   gpe_add_del_native_fwd_rpath_reply)                                   \
5647 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5648   gpe_fwd_entry_path_details)                                           \
5649 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5650 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5651   one_add_del_map_request_itr_rlocs_reply)                              \
5652 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5653   one_get_map_request_itr_rlocs_reply)                                  \
5654 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5655 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5656 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5657 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5658 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5659 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5660   show_one_map_register_state_reply)                                    \
5661 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5662 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5663   show_one_map_register_fallback_threshold_reply)                       \
5664 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5665 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5666 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5667 _(POLICER_DETAILS, policer_details)                                     \
5668 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5669 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5670 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5671 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5672 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5673 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5674 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5675 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5676 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5677 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5678 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5679 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5680 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5681 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5682 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5683 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5684 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5685 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5686 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5687 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5688 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5689 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5690 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5691 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5692 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5693  ip_source_and_port_range_check_add_del_reply)                          \
5694 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5695  ip_source_and_port_range_check_interface_add_del_reply)                \
5696 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5697 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5698 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5699 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5700 _(PUNT_REPLY, punt_reply)                                               \
5701 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5702 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5703 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5704 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5705 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5706 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5707 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5708 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5709 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5710 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5711 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5712 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5713 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5714 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5715 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5716 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5717 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5718 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5719 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5720 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5721 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5722
5723 #define foreach_standalone_reply_msg                                    \
5724 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5725 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5726 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5727 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5728 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5729 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5730 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5731 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5732
5733 typedef struct
5734 {
5735   u8 *name;
5736   u32 value;
5737 } name_sort_t;
5738
5739
5740 #define STR_VTR_OP_CASE(op)     \
5741     case L2_VTR_ ## op:         \
5742         return "" # op;
5743
5744 static const char *
5745 str_vtr_op (u32 vtr_op)
5746 {
5747   switch (vtr_op)
5748     {
5749       STR_VTR_OP_CASE (DISABLED);
5750       STR_VTR_OP_CASE (PUSH_1);
5751       STR_VTR_OP_CASE (PUSH_2);
5752       STR_VTR_OP_CASE (POP_1);
5753       STR_VTR_OP_CASE (POP_2);
5754       STR_VTR_OP_CASE (TRANSLATE_1_1);
5755       STR_VTR_OP_CASE (TRANSLATE_1_2);
5756       STR_VTR_OP_CASE (TRANSLATE_2_1);
5757       STR_VTR_OP_CASE (TRANSLATE_2_2);
5758     }
5759
5760   return "UNKNOWN";
5761 }
5762
5763 static int
5764 dump_sub_interface_table (vat_main_t * vam)
5765 {
5766   const sw_interface_subif_t *sub = NULL;
5767
5768   if (vam->json_output)
5769     {
5770       clib_warning
5771         ("JSON output supported only for VPE API calls and dump_stats_table");
5772       return -99;
5773     }
5774
5775   print (vam->ofp,
5776          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5777          "Interface", "sw_if_index",
5778          "sub id", "dot1ad", "tags", "outer id",
5779          "inner id", "exact", "default", "outer any", "inner any");
5780
5781   vec_foreach (sub, vam->sw_if_subif_table)
5782   {
5783     print (vam->ofp,
5784            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5785            sub->interface_name,
5786            sub->sw_if_index,
5787            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5788            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5789            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5790            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5791     if (sub->vtr_op != L2_VTR_DISABLED)
5792       {
5793         print (vam->ofp,
5794                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5795                "tag1: %d tag2: %d ]",
5796                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5797                sub->vtr_tag1, sub->vtr_tag2);
5798       }
5799   }
5800
5801   return 0;
5802 }
5803
5804 static int
5805 name_sort_cmp (void *a1, void *a2)
5806 {
5807   name_sort_t *n1 = a1;
5808   name_sort_t *n2 = a2;
5809
5810   return strcmp ((char *) n1->name, (char *) n2->name);
5811 }
5812
5813 static int
5814 dump_interface_table (vat_main_t * vam)
5815 {
5816   hash_pair_t *p;
5817   name_sort_t *nses = 0, *ns;
5818
5819   if (vam->json_output)
5820     {
5821       clib_warning
5822         ("JSON output supported only for VPE API calls and dump_stats_table");
5823       return -99;
5824     }
5825
5826   /* *INDENT-OFF* */
5827   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5828   ({
5829     vec_add2 (nses, ns, 1);
5830     ns->name = (u8 *)(p->key);
5831     ns->value = (u32) p->value[0];
5832   }));
5833   /* *INDENT-ON* */
5834
5835   vec_sort_with_function (nses, name_sort_cmp);
5836
5837   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5838   vec_foreach (ns, nses)
5839   {
5840     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5841   }
5842   vec_free (nses);
5843   return 0;
5844 }
5845
5846 static int
5847 dump_ip_table (vat_main_t * vam, int is_ipv6)
5848 {
5849   const ip_details_t *det = NULL;
5850   const ip_address_details_t *address = NULL;
5851   u32 i = ~0;
5852
5853   print (vam->ofp, "%-12s", "sw_if_index");
5854
5855   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5856   {
5857     i++;
5858     if (!det->present)
5859       {
5860         continue;
5861       }
5862     print (vam->ofp, "%-12d", i);
5863     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5864     if (!det->addr)
5865       {
5866         continue;
5867       }
5868     vec_foreach (address, det->addr)
5869     {
5870       print (vam->ofp,
5871              "            %-30U%-13d",
5872              is_ipv6 ? format_ip6_address : format_ip4_address,
5873              address->ip, address->prefix_length);
5874     }
5875   }
5876
5877   return 0;
5878 }
5879
5880 static int
5881 dump_ipv4_table (vat_main_t * vam)
5882 {
5883   if (vam->json_output)
5884     {
5885       clib_warning
5886         ("JSON output supported only for VPE API calls and dump_stats_table");
5887       return -99;
5888     }
5889
5890   return dump_ip_table (vam, 0);
5891 }
5892
5893 static int
5894 dump_ipv6_table (vat_main_t * vam)
5895 {
5896   if (vam->json_output)
5897     {
5898       clib_warning
5899         ("JSON output supported only for VPE API calls and dump_stats_table");
5900       return -99;
5901     }
5902
5903   return dump_ip_table (vam, 1);
5904 }
5905
5906 static char *
5907 counter_type_to_str (u8 counter_type, u8 is_combined)
5908 {
5909   if (!is_combined)
5910     {
5911       switch (counter_type)
5912         {
5913         case VNET_INTERFACE_COUNTER_DROP:
5914           return "drop";
5915         case VNET_INTERFACE_COUNTER_PUNT:
5916           return "punt";
5917         case VNET_INTERFACE_COUNTER_IP4:
5918           return "ip4";
5919         case VNET_INTERFACE_COUNTER_IP6:
5920           return "ip6";
5921         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5922           return "rx-no-buf";
5923         case VNET_INTERFACE_COUNTER_RX_MISS:
5924           return "rx-miss";
5925         case VNET_INTERFACE_COUNTER_RX_ERROR:
5926           return "rx-error";
5927         case VNET_INTERFACE_COUNTER_TX_ERROR:
5928           return "tx-error";
5929         default:
5930           return "INVALID-COUNTER-TYPE";
5931         }
5932     }
5933   else
5934     {
5935       switch (counter_type)
5936         {
5937         case VNET_INTERFACE_COUNTER_RX:
5938           return "rx";
5939         case VNET_INTERFACE_COUNTER_TX:
5940           return "tx";
5941         default:
5942           return "INVALID-COUNTER-TYPE";
5943         }
5944     }
5945 }
5946
5947 static int
5948 dump_stats_table (vat_main_t * vam)
5949 {
5950   vat_json_node_t node;
5951   vat_json_node_t *msg_array;
5952   vat_json_node_t *msg;
5953   vat_json_node_t *counter_array;
5954   vat_json_node_t *counter;
5955   interface_counter_t c;
5956   u64 packets;
5957   ip4_fib_counter_t *c4;
5958   ip6_fib_counter_t *c6;
5959   ip4_nbr_counter_t *n4;
5960   ip6_nbr_counter_t *n6;
5961   int i, j;
5962
5963   if (!vam->json_output)
5964     {
5965       clib_warning ("dump_stats_table supported only in JSON format");
5966       return -99;
5967     }
5968
5969   vat_json_init_object (&node);
5970
5971   /* interface counters */
5972   msg_array = vat_json_object_add (&node, "interface_counters");
5973   vat_json_init_array (msg_array);
5974   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5975     {
5976       msg = vat_json_array_add (msg_array);
5977       vat_json_init_object (msg);
5978       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5979                                        (u8 *) counter_type_to_str (i, 0));
5980       vat_json_object_add_int (msg, "is_combined", 0);
5981       counter_array = vat_json_object_add (msg, "data");
5982       vat_json_init_array (counter_array);
5983       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5984         {
5985           packets = vam->simple_interface_counters[i][j];
5986           vat_json_array_add_uint (counter_array, packets);
5987         }
5988     }
5989   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5990     {
5991       msg = vat_json_array_add (msg_array);
5992       vat_json_init_object (msg);
5993       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5994                                        (u8 *) counter_type_to_str (i, 1));
5995       vat_json_object_add_int (msg, "is_combined", 1);
5996       counter_array = vat_json_object_add (msg, "data");
5997       vat_json_init_array (counter_array);
5998       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5999         {
6000           c = vam->combined_interface_counters[i][j];
6001           counter = vat_json_array_add (counter_array);
6002           vat_json_init_object (counter);
6003           vat_json_object_add_uint (counter, "packets", c.packets);
6004           vat_json_object_add_uint (counter, "bytes", c.bytes);
6005         }
6006     }
6007
6008   /* ip4 fib counters */
6009   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6010   vat_json_init_array (msg_array);
6011   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6012     {
6013       msg = vat_json_array_add (msg_array);
6014       vat_json_init_object (msg);
6015       vat_json_object_add_uint (msg, "vrf_id",
6016                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6017       counter_array = vat_json_object_add (msg, "c");
6018       vat_json_init_array (counter_array);
6019       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6020         {
6021           counter = vat_json_array_add (counter_array);
6022           vat_json_init_object (counter);
6023           c4 = &vam->ip4_fib_counters[i][j];
6024           vat_json_object_add_ip4 (counter, "address", c4->address);
6025           vat_json_object_add_uint (counter, "address_length",
6026                                     c4->address_length);
6027           vat_json_object_add_uint (counter, "packets", c4->packets);
6028           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6029         }
6030     }
6031
6032   /* ip6 fib counters */
6033   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6034   vat_json_init_array (msg_array);
6035   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6036     {
6037       msg = vat_json_array_add (msg_array);
6038       vat_json_init_object (msg);
6039       vat_json_object_add_uint (msg, "vrf_id",
6040                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6041       counter_array = vat_json_object_add (msg, "c");
6042       vat_json_init_array (counter_array);
6043       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6044         {
6045           counter = vat_json_array_add (counter_array);
6046           vat_json_init_object (counter);
6047           c6 = &vam->ip6_fib_counters[i][j];
6048           vat_json_object_add_ip6 (counter, "address", c6->address);
6049           vat_json_object_add_uint (counter, "address_length",
6050                                     c6->address_length);
6051           vat_json_object_add_uint (counter, "packets", c6->packets);
6052           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6053         }
6054     }
6055
6056   /* ip4 nbr counters */
6057   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6058   vat_json_init_array (msg_array);
6059   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6060     {
6061       msg = vat_json_array_add (msg_array);
6062       vat_json_init_object (msg);
6063       vat_json_object_add_uint (msg, "sw_if_index", i);
6064       counter_array = vat_json_object_add (msg, "c");
6065       vat_json_init_array (counter_array);
6066       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6067         {
6068           counter = vat_json_array_add (counter_array);
6069           vat_json_init_object (counter);
6070           n4 = &vam->ip4_nbr_counters[i][j];
6071           vat_json_object_add_ip4 (counter, "address", n4->address);
6072           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6073           vat_json_object_add_uint (counter, "packets", n4->packets);
6074           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6075         }
6076     }
6077
6078   /* ip6 nbr counters */
6079   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6080   vat_json_init_array (msg_array);
6081   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6082     {
6083       msg = vat_json_array_add (msg_array);
6084       vat_json_init_object (msg);
6085       vat_json_object_add_uint (msg, "sw_if_index", i);
6086       counter_array = vat_json_object_add (msg, "c");
6087       vat_json_init_array (counter_array);
6088       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6089         {
6090           counter = vat_json_array_add (counter_array);
6091           vat_json_init_object (counter);
6092           n6 = &vam->ip6_nbr_counters[i][j];
6093           vat_json_object_add_ip6 (counter, "address", n6->address);
6094           vat_json_object_add_uint (counter, "packets", n6->packets);
6095           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6096         }
6097     }
6098
6099   vat_json_print (vam->ofp, &node);
6100   vat_json_free (&node);
6101
6102   return 0;
6103 }
6104
6105 /*
6106  * Pass CLI buffers directly in the CLI_INBAND API message,
6107  * instead of an additional shared memory area.
6108  */
6109 static int
6110 exec_inband (vat_main_t * vam)
6111 {
6112   vl_api_cli_inband_t *mp;
6113   unformat_input_t *i = vam->input;
6114   int ret;
6115
6116   if (vec_len (i->buffer) == 0)
6117     return -1;
6118
6119   if (vam->exec_mode == 0 && unformat (i, "mode"))
6120     {
6121       vam->exec_mode = 1;
6122       return 0;
6123     }
6124   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6125     {
6126       vam->exec_mode = 0;
6127       return 0;
6128     }
6129
6130   /*
6131    * In order for the CLI command to work, it
6132    * must be a vector ending in \n, not a C-string ending
6133    * in \n\0.
6134    */
6135   u32 len = vec_len (vam->input->buffer);
6136   M2 (CLI_INBAND, mp, len);
6137   clib_memcpy (mp->cmd, vam->input->buffer, len);
6138   mp->length = htonl (len);
6139
6140   S (mp);
6141   W (ret);
6142   /* json responses may or may not include a useful reply... */
6143   if (vec_len (vam->cmd_reply))
6144     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6145   return ret;
6146 }
6147
6148 int
6149 exec (vat_main_t * vam)
6150 {
6151   return exec_inband (vam);
6152 }
6153
6154 static int
6155 api_create_loopback (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_create_loopback_t *mp;
6159   vl_api_create_loopback_instance_t *mp_lbi;
6160   u8 mac_address[6];
6161   u8 mac_set = 0;
6162   u8 is_specified = 0;
6163   u32 user_instance = 0;
6164   int ret;
6165
6166   memset (mac_address, 0, sizeof (mac_address));
6167
6168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6169     {
6170       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6171         mac_set = 1;
6172       if (unformat (i, "instance %d", &user_instance))
6173         is_specified = 1;
6174       else
6175         break;
6176     }
6177
6178   if (is_specified)
6179     {
6180       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6181       mp_lbi->is_specified = is_specified;
6182       if (is_specified)
6183         mp_lbi->user_instance = htonl (user_instance);
6184       if (mac_set)
6185         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6186       S (mp_lbi);
6187     }
6188   else
6189     {
6190       /* Construct the API message */
6191       M (CREATE_LOOPBACK, mp);
6192       if (mac_set)
6193         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6194       S (mp);
6195     }
6196
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static int
6202 api_delete_loopback (vat_main_t * vam)
6203 {
6204   unformat_input_t *i = vam->input;
6205   vl_api_delete_loopback_t *mp;
6206   u32 sw_if_index = ~0;
6207   int ret;
6208
6209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6210     {
6211       if (unformat (i, "sw_if_index %d", &sw_if_index))
6212         ;
6213       else
6214         break;
6215     }
6216
6217   if (sw_if_index == ~0)
6218     {
6219       errmsg ("missing sw_if_index");
6220       return -99;
6221     }
6222
6223   /* Construct the API message */
6224   M (DELETE_LOOPBACK, mp);
6225   mp->sw_if_index = ntohl (sw_if_index);
6226
6227   S (mp);
6228   W (ret);
6229   return ret;
6230 }
6231
6232 static int
6233 api_want_stats (vat_main_t * vam)
6234 {
6235   unformat_input_t *i = vam->input;
6236   vl_api_want_stats_t *mp;
6237   int enable = -1;
6238   int ret;
6239
6240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6241     {
6242       if (unformat (i, "enable"))
6243         enable = 1;
6244       else if (unformat (i, "disable"))
6245         enable = 0;
6246       else
6247         break;
6248     }
6249
6250   if (enable == -1)
6251     {
6252       errmsg ("missing enable|disable");
6253       return -99;
6254     }
6255
6256   M (WANT_STATS, mp);
6257   mp->enable_disable = enable;
6258
6259   S (mp);
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static int
6265 api_want_interface_events (vat_main_t * vam)
6266 {
6267   unformat_input_t *i = vam->input;
6268   vl_api_want_interface_events_t *mp;
6269   int enable = -1;
6270   int ret;
6271
6272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6273     {
6274       if (unformat (i, "enable"))
6275         enable = 1;
6276       else if (unformat (i, "disable"))
6277         enable = 0;
6278       else
6279         break;
6280     }
6281
6282   if (enable == -1)
6283     {
6284       errmsg ("missing enable|disable");
6285       return -99;
6286     }
6287
6288   M (WANT_INTERFACE_EVENTS, mp);
6289   mp->enable_disable = enable;
6290
6291   vam->interface_event_display = enable;
6292
6293   S (mp);
6294   W (ret);
6295   return ret;
6296 }
6297
6298
6299 /* Note: non-static, called once to set up the initial intfc table */
6300 int
6301 api_sw_interface_dump (vat_main_t * vam)
6302 {
6303   vl_api_sw_interface_dump_t *mp;
6304   vl_api_control_ping_t *mp_ping;
6305   hash_pair_t *p;
6306   name_sort_t *nses = 0, *ns;
6307   sw_interface_subif_t *sub = NULL;
6308   int ret;
6309
6310   /* Toss the old name table */
6311   /* *INDENT-OFF* */
6312   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6313   ({
6314     vec_add2 (nses, ns, 1);
6315     ns->name = (u8 *)(p->key);
6316     ns->value = (u32) p->value[0];
6317   }));
6318   /* *INDENT-ON* */
6319
6320   hash_free (vam->sw_if_index_by_interface_name);
6321
6322   vec_foreach (ns, nses) vec_free (ns->name);
6323
6324   vec_free (nses);
6325
6326   vec_foreach (sub, vam->sw_if_subif_table)
6327   {
6328     vec_free (sub->interface_name);
6329   }
6330   vec_free (vam->sw_if_subif_table);
6331
6332   /* recreate the interface name hash table */
6333   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6334
6335   /*
6336    * Ask for all interface names. Otherwise, the epic catalog of
6337    * name filters becomes ridiculously long, and vat ends up needing
6338    * to be taught about new interface types.
6339    */
6340   M (SW_INTERFACE_DUMP, mp);
6341   S (mp);
6342
6343   /* Use a control ping for synchronization */
6344   MPING (CONTROL_PING, mp_ping);
6345   S (mp_ping);
6346
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_sw_interface_set_flags (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_sw_interface_set_flags_t *mp;
6356   u32 sw_if_index;
6357   u8 sw_if_index_set = 0;
6358   u8 admin_up = 0;
6359   int ret;
6360
6361   /* Parse args required to build the message */
6362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6363     {
6364       if (unformat (i, "admin-up"))
6365         admin_up = 1;
6366       else if (unformat (i, "admin-down"))
6367         admin_up = 0;
6368       else
6369         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6372         sw_if_index_set = 1;
6373       else
6374         break;
6375     }
6376
6377   if (sw_if_index_set == 0)
6378     {
6379       errmsg ("missing interface name or sw_if_index");
6380       return -99;
6381     }
6382
6383   /* Construct the API message */
6384   M (SW_INTERFACE_SET_FLAGS, mp);
6385   mp->sw_if_index = ntohl (sw_if_index);
6386   mp->admin_up_down = admin_up;
6387
6388   /* send it... */
6389   S (mp);
6390
6391   /* Wait for a reply, return the good/bad news... */
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_rx_mode (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_rx_mode_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   int ret;
6404   u8 queue_id_valid = 0;
6405   u32 queue_id;
6406   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6407
6408   /* Parse args required to build the message */
6409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410     {
6411       if (unformat (i, "queue %d", &queue_id))
6412         queue_id_valid = 1;
6413       else if (unformat (i, "polling"))
6414         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6415       else if (unformat (i, "interrupt"))
6416         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6417       else if (unformat (i, "adaptive"))
6418         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6419       else
6420         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6421         sw_if_index_set = 1;
6422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6423         sw_if_index_set = 1;
6424       else
6425         break;
6426     }
6427
6428   if (sw_if_index_set == 0)
6429     {
6430       errmsg ("missing interface name or sw_if_index");
6431       return -99;
6432     }
6433   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6434     {
6435       errmsg ("missing rx-mode");
6436       return -99;
6437     }
6438
6439   /* Construct the API message */
6440   M (SW_INTERFACE_SET_RX_MODE, mp);
6441   mp->sw_if_index = ntohl (sw_if_index);
6442   mp->mode = mode;
6443   mp->queue_id_valid = queue_id_valid;
6444   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply, return the good/bad news... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_clear_stats (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_clear_stats_t *mp;
6459   u32 sw_if_index;
6460   u8 sw_if_index_set = 0;
6461   int ret;
6462
6463   /* Parse args required to build the message */
6464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6465     {
6466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6469         sw_if_index_set = 1;
6470       else
6471         break;
6472     }
6473
6474   /* Construct the API message */
6475   M (SW_INTERFACE_CLEAR_STATS, mp);
6476
6477   if (sw_if_index_set == 1)
6478     mp->sw_if_index = ntohl (sw_if_index);
6479   else
6480     mp->sw_if_index = ~0;
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply, return the good/bad news... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static int
6491 api_sw_interface_add_del_address (vat_main_t * vam)
6492 {
6493   unformat_input_t *i = vam->input;
6494   vl_api_sw_interface_add_del_address_t *mp;
6495   u32 sw_if_index;
6496   u8 sw_if_index_set = 0;
6497   u8 is_add = 1, del_all = 0;
6498   u32 address_length = 0;
6499   u8 v4_address_set = 0;
6500   u8 v6_address_set = 0;
6501   ip4_address_t v4address;
6502   ip6_address_t v6address;
6503   int ret;
6504
6505   /* Parse args required to build the message */
6506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6507     {
6508       if (unformat (i, "del-all"))
6509         del_all = 1;
6510       else if (unformat (i, "del"))
6511         is_add = 0;
6512       else
6513         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6514         sw_if_index_set = 1;
6515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "%U/%d",
6518                          unformat_ip4_address, &v4address, &address_length))
6519         v4_address_set = 1;
6520       else if (unformat (i, "%U/%d",
6521                          unformat_ip6_address, &v6address, &address_length))
6522         v6_address_set = 1;
6523       else
6524         break;
6525     }
6526
6527   if (sw_if_index_set == 0)
6528     {
6529       errmsg ("missing interface name or sw_if_index");
6530       return -99;
6531     }
6532   if (v4_address_set && v6_address_set)
6533     {
6534       errmsg ("both v4 and v6 addresses set");
6535       return -99;
6536     }
6537   if (!v4_address_set && !v6_address_set && !del_all)
6538     {
6539       errmsg ("no addresses set");
6540       return -99;
6541     }
6542
6543   /* Construct the API message */
6544   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6545
6546   mp->sw_if_index = ntohl (sw_if_index);
6547   mp->is_add = is_add;
6548   mp->del_all = del_all;
6549   if (v6_address_set)
6550     {
6551       mp->is_ipv6 = 1;
6552       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6553     }
6554   else
6555     {
6556       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6557     }
6558   mp->address_length = address_length;
6559
6560   /* send it... */
6561   S (mp);
6562
6563   /* Wait for a reply, return good/bad news  */
6564   W (ret);
6565   return ret;
6566 }
6567
6568 static int
6569 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6570 {
6571   unformat_input_t *i = vam->input;
6572   vl_api_sw_interface_set_mpls_enable_t *mp;
6573   u32 sw_if_index;
6574   u8 sw_if_index_set = 0;
6575   u8 enable = 1;
6576   int ret;
6577
6578   /* Parse args required to build the message */
6579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580     {
6581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "disable"))
6586         enable = 0;
6587       else if (unformat (i, "dis"))
6588         enable = 0;
6589       else
6590         break;
6591     }
6592
6593   if (sw_if_index_set == 0)
6594     {
6595       errmsg ("missing interface name or sw_if_index");
6596       return -99;
6597     }
6598
6599   /* Construct the API message */
6600   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6601
6602   mp->sw_if_index = ntohl (sw_if_index);
6603   mp->enable = enable;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply... */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_table (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_table_t *mp;
6618   u32 sw_if_index, vrf_id = 0;
6619   u8 sw_if_index_set = 0;
6620   u8 is_ipv6 = 0;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "vrf %d", &vrf_id))
6631         ;
6632       else if (unformat (i, "ipv6"))
6633         is_ipv6 = 1;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_TABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->is_ipv6 = is_ipv6;
6649   mp->vrf_id = ntohl (vrf_id);
6650
6651   /* send it... */
6652   S (mp);
6653
6654   /* Wait for a reply... */
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static void vl_api_sw_interface_get_table_reply_t_handler
6660   (vl_api_sw_interface_get_table_reply_t * mp)
6661 {
6662   vat_main_t *vam = &vat_main;
6663
6664   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6665
6666   vam->retval = ntohl (mp->retval);
6667   vam->result_ready = 1;
6668
6669 }
6670
6671 static void vl_api_sw_interface_get_table_reply_t_handler_json
6672   (vl_api_sw_interface_get_table_reply_t * mp)
6673 {
6674   vat_main_t *vam = &vat_main;
6675   vat_json_node_t node;
6676
6677   vat_json_init_object (&node);
6678   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6679   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6680
6681   vat_json_print (vam->ofp, &node);
6682   vat_json_free (&node);
6683
6684   vam->retval = ntohl (mp->retval);
6685   vam->result_ready = 1;
6686 }
6687
6688 static int
6689 api_sw_interface_get_table (vat_main_t * vam)
6690 {
6691   unformat_input_t *i = vam->input;
6692   vl_api_sw_interface_get_table_t *mp;
6693   u32 sw_if_index;
6694   u8 sw_if_index_set = 0;
6695   u8 is_ipv6 = 0;
6696   int ret;
6697
6698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6699     {
6700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6701         sw_if_index_set = 1;
6702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "ipv6"))
6705         is_ipv6 = 1;
6706       else
6707         break;
6708     }
6709
6710   if (sw_if_index_set == 0)
6711     {
6712       errmsg ("missing interface name or sw_if_index");
6713       return -99;
6714     }
6715
6716   M (SW_INTERFACE_GET_TABLE, mp);
6717   mp->sw_if_index = htonl (sw_if_index);
6718   mp->is_ipv6 = is_ipv6;
6719
6720   S (mp);
6721   W (ret);
6722   return ret;
6723 }
6724
6725 static int
6726 api_sw_interface_set_vpath (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_sw_interface_set_vpath_t *mp;
6730   u32 sw_if_index = 0;
6731   u8 sw_if_index_set = 0;
6732   u8 is_enable = 0;
6733   int ret;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6739         sw_if_index_set = 1;
6740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "enable"))
6743         is_enable = 1;
6744       else if (unformat (i, "disable"))
6745         is_enable = 0;
6746       else
6747         break;
6748     }
6749
6750   if (sw_if_index_set == 0)
6751     {
6752       errmsg ("missing interface name or sw_if_index");
6753       return -99;
6754     }
6755
6756   /* Construct the API message */
6757   M (SW_INTERFACE_SET_VPATH, mp);
6758
6759   mp->sw_if_index = ntohl (sw_if_index);
6760   mp->enable = is_enable;
6761
6762   /* send it... */
6763   S (mp);
6764
6765   /* Wait for a reply... */
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 1;
6778   u8 is_ipv6 = 0;
6779   int ret;
6780
6781   /* Parse args required to build the message */
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6785         sw_if_index_set = 1;
6786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6787         sw_if_index_set = 1;
6788       else if (unformat (i, "enable"))
6789         is_enable = 1;
6790       else if (unformat (i, "disable"))
6791         is_enable = 0;
6792       else if (unformat (i, "ip4"))
6793         is_ipv6 = 0;
6794       else if (unformat (i, "ip6"))
6795         is_ipv6 = 1;
6796       else
6797         break;
6798     }
6799
6800   if (sw_if_index_set == 0)
6801     {
6802       errmsg ("missing interface name or sw_if_index");
6803       return -99;
6804     }
6805
6806   /* Construct the API message */
6807   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6808
6809   mp->sw_if_index = ntohl (sw_if_index);
6810   mp->enable = is_enable;
6811   mp->is_ipv6 = is_ipv6;
6812
6813   /* send it... */
6814   S (mp);
6815
6816   /* Wait for a reply... */
6817   W (ret);
6818   return ret;
6819 }
6820
6821 static int
6822 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_sw_interface_set_geneve_bypass_t *mp;
6826   u32 sw_if_index = 0;
6827   u8 sw_if_index_set = 0;
6828   u8 is_enable = 1;
6829   u8 is_ipv6 = 0;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "enable"))
6840         is_enable = 1;
6841       else if (unformat (i, "disable"))
6842         is_enable = 0;
6843       else if (unformat (i, "ip4"))
6844         is_ipv6 = 0;
6845       else if (unformat (i, "ip6"))
6846         is_ipv6 = 1;
6847       else
6848         break;
6849     }
6850
6851   if (sw_if_index_set == 0)
6852     {
6853       errmsg ("missing interface name or sw_if_index");
6854       return -99;
6855     }
6856
6857   /* Construct the API message */
6858   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6859
6860   mp->sw_if_index = ntohl (sw_if_index);
6861   mp->enable = is_enable;
6862   mp->is_ipv6 = is_ipv6;
6863
6864   /* send it... */
6865   S (mp);
6866
6867   /* Wait for a reply... */
6868   W (ret);
6869   return ret;
6870 }
6871
6872 static int
6873 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6874 {
6875   unformat_input_t *i = vam->input;
6876   vl_api_sw_interface_set_l2_xconnect_t *mp;
6877   u32 rx_sw_if_index;
6878   u8 rx_sw_if_index_set = 0;
6879   u32 tx_sw_if_index;
6880   u8 tx_sw_if_index_set = 0;
6881   u8 enable = 1;
6882   int ret;
6883
6884   /* Parse args required to build the message */
6885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886     {
6887       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6888         rx_sw_if_index_set = 1;
6889       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6890         tx_sw_if_index_set = 1;
6891       else if (unformat (i, "rx"))
6892         {
6893           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894             {
6895               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6896                             &rx_sw_if_index))
6897                 rx_sw_if_index_set = 1;
6898             }
6899           else
6900             break;
6901         }
6902       else if (unformat (i, "tx"))
6903         {
6904           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905             {
6906               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6907                             &tx_sw_if_index))
6908                 tx_sw_if_index_set = 1;
6909             }
6910           else
6911             break;
6912         }
6913       else if (unformat (i, "enable"))
6914         enable = 1;
6915       else if (unformat (i, "disable"))
6916         enable = 0;
6917       else
6918         break;
6919     }
6920
6921   if (rx_sw_if_index_set == 0)
6922     {
6923       errmsg ("missing rx interface name or rx_sw_if_index");
6924       return -99;
6925     }
6926
6927   if (enable && (tx_sw_if_index_set == 0))
6928     {
6929       errmsg ("missing tx interface name or tx_sw_if_index");
6930       return -99;
6931     }
6932
6933   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6934
6935   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6936   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6937   mp->enable = enable;
6938
6939   S (mp);
6940   W (ret);
6941   return ret;
6942 }
6943
6944 static int
6945 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_sw_interface_set_l2_bridge_t *mp;
6949   u32 rx_sw_if_index;
6950   u8 rx_sw_if_index_set = 0;
6951   u32 bd_id;
6952   u8 bd_id_set = 0;
6953   u8 bvi = 0;
6954   u32 shg = 0;
6955   u8 enable = 1;
6956   int ret;
6957
6958   /* Parse args required to build the message */
6959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960     {
6961       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6962         rx_sw_if_index_set = 1;
6963       else if (unformat (i, "bd_id %d", &bd_id))
6964         bd_id_set = 1;
6965       else
6966         if (unformat
6967             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6968         rx_sw_if_index_set = 1;
6969       else if (unformat (i, "shg %d", &shg))
6970         ;
6971       else if (unformat (i, "bvi"))
6972         bvi = 1;
6973       else if (unformat (i, "enable"))
6974         enable = 1;
6975       else if (unformat (i, "disable"))
6976         enable = 0;
6977       else
6978         break;
6979     }
6980
6981   if (rx_sw_if_index_set == 0)
6982     {
6983       errmsg ("missing rx interface name or sw_if_index");
6984       return -99;
6985     }
6986
6987   if (enable && (bd_id_set == 0))
6988     {
6989       errmsg ("missing bridge domain");
6990       return -99;
6991     }
6992
6993   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6994
6995   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6996   mp->bd_id = ntohl (bd_id);
6997   mp->shg = (u8) shg;
6998   mp->bvi = bvi;
6999   mp->enable = enable;
7000
7001   S (mp);
7002   W (ret);
7003   return ret;
7004 }
7005
7006 static int
7007 api_bridge_domain_dump (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_bridge_domain_dump_t *mp;
7011   vl_api_control_ping_t *mp_ping;
7012   u32 bd_id = ~0;
7013   int ret;
7014
7015   /* Parse args required to build the message */
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "bd_id %d", &bd_id))
7019         ;
7020       else
7021         break;
7022     }
7023
7024   M (BRIDGE_DOMAIN_DUMP, mp);
7025   mp->bd_id = ntohl (bd_id);
7026   S (mp);
7027
7028   /* Use a control ping for synchronization */
7029   MPING (CONTROL_PING, mp_ping);
7030   S (mp_ping);
7031
7032   W (ret);
7033   return ret;
7034 }
7035
7036 static int
7037 api_bridge_domain_add_del (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_bridge_domain_add_del_t *mp;
7041   u32 bd_id = ~0;
7042   u8 is_add = 1;
7043   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7044   u8 *bd_tag = NULL;
7045   u32 mac_age = 0;
7046   int ret;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "bd_id %d", &bd_id))
7052         ;
7053       else if (unformat (i, "flood %d", &flood))
7054         ;
7055       else if (unformat (i, "uu-flood %d", &uu_flood))
7056         ;
7057       else if (unformat (i, "forward %d", &forward))
7058         ;
7059       else if (unformat (i, "learn %d", &learn))
7060         ;
7061       else if (unformat (i, "arp-term %d", &arp_term))
7062         ;
7063       else if (unformat (i, "mac-age %d", &mac_age))
7064         ;
7065       else if (unformat (i, "bd-tag %s", &bd_tag))
7066         ;
7067       else if (unformat (i, "del"))
7068         {
7069           is_add = 0;
7070           flood = uu_flood = forward = learn = 0;
7071         }
7072       else
7073         break;
7074     }
7075
7076   if (bd_id == ~0)
7077     {
7078       errmsg ("missing bridge domain");
7079       ret = -99;
7080       goto done;
7081     }
7082
7083   if (mac_age > 255)
7084     {
7085       errmsg ("mac age must be less than 256 ");
7086       ret = -99;
7087       goto done;
7088     }
7089
7090   if ((bd_tag) && (vec_len (bd_tag) > 63))
7091     {
7092       errmsg ("bd-tag cannot be longer than 63");
7093       ret = -99;
7094       goto done;
7095     }
7096
7097   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7098
7099   mp->bd_id = ntohl (bd_id);
7100   mp->flood = flood;
7101   mp->uu_flood = uu_flood;
7102   mp->forward = forward;
7103   mp->learn = learn;
7104   mp->arp_term = arp_term;
7105   mp->is_add = is_add;
7106   mp->mac_age = (u8) mac_age;
7107   if (bd_tag)
7108     {
7109       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7110       mp->bd_tag[vec_len (bd_tag)] = 0;
7111     }
7112   S (mp);
7113   W (ret);
7114
7115 done:
7116   vec_free (bd_tag);
7117   return ret;
7118 }
7119
7120 static int
7121 api_l2fib_flush_bd (vat_main_t * vam)
7122 {
7123   unformat_input_t *i = vam->input;
7124   vl_api_l2fib_flush_bd_t *mp;
7125   u32 bd_id = ~0;
7126   int ret;
7127
7128   /* Parse args required to build the message */
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "bd_id %d", &bd_id));
7132       else
7133         break;
7134     }
7135
7136   if (bd_id == ~0)
7137     {
7138       errmsg ("missing bridge domain");
7139       return -99;
7140     }
7141
7142   M (L2FIB_FLUSH_BD, mp);
7143
7144   mp->bd_id = htonl (bd_id);
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2fib_flush_int (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2fib_flush_int_t *mp;
7156   u32 sw_if_index = ~0;
7157   int ret;
7158
7159   /* Parse args required to build the message */
7160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161     {
7162       if (unformat (i, "sw_if_index %d", &sw_if_index));
7163       else
7164         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7165       else
7166         break;
7167     }
7168
7169   if (sw_if_index == ~0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174
7175   M (L2FIB_FLUSH_INT, mp);
7176
7177   mp->sw_if_index = ntohl (sw_if_index);
7178
7179   S (mp);
7180   W (ret);
7181   return ret;
7182 }
7183
7184 static int
7185 api_l2fib_add_del (vat_main_t * vam)
7186 {
7187   unformat_input_t *i = vam->input;
7188   vl_api_l2fib_add_del_t *mp;
7189   f64 timeout;
7190   u8 mac[6] = { 0 };
7191   u8 mac_set = 0;
7192   u32 bd_id;
7193   u8 bd_id_set = 0;
7194   u32 sw_if_index = ~0;
7195   u8 sw_if_index_set = 0;
7196   u8 is_add = 1;
7197   u8 static_mac = 0;
7198   u8 filter_mac = 0;
7199   u8 bvi_mac = 0;
7200   int count = 1;
7201   f64 before = 0;
7202   int j;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7208         mac_set = 1;
7209       else if (unformat (i, "bd_id %d", &bd_id))
7210         bd_id_set = 1;
7211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7212         sw_if_index_set = 1;
7213       else if (unformat (i, "sw_if"))
7214         {
7215           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216             {
7217               if (unformat
7218                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7219                 sw_if_index_set = 1;
7220             }
7221           else
7222             break;
7223         }
7224       else if (unformat (i, "static"))
7225         static_mac = 1;
7226       else if (unformat (i, "filter"))
7227         {
7228           filter_mac = 1;
7229           static_mac = 1;
7230         }
7231       else if (unformat (i, "bvi"))
7232         {
7233           bvi_mac = 1;
7234           static_mac = 1;
7235         }
7236       else if (unformat (i, "del"))
7237         is_add = 0;
7238       else if (unformat (i, "count %d", &count))
7239         ;
7240       else
7241         break;
7242     }
7243
7244   if (mac_set == 0)
7245     {
7246       errmsg ("missing mac address");
7247       return -99;
7248     }
7249
7250   if (bd_id_set == 0)
7251     {
7252       errmsg ("missing bridge domain");
7253       return -99;
7254     }
7255
7256   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7257     {
7258       errmsg ("missing interface name or sw_if_index");
7259       return -99;
7260     }
7261
7262   if (count > 1)
7263     {
7264       /* Turn on async mode */
7265       vam->async_mode = 1;
7266       vam->async_errors = 0;
7267       before = vat_time_now (vam);
7268     }
7269
7270   for (j = 0; j < count; j++)
7271     {
7272       M (L2FIB_ADD_DEL, mp);
7273
7274       clib_memcpy (mp->mac, mac, 6);
7275       mp->bd_id = ntohl (bd_id);
7276       mp->is_add = is_add;
7277
7278       if (is_add)
7279         {
7280           mp->sw_if_index = ntohl (sw_if_index);
7281           mp->static_mac = static_mac;
7282           mp->filter_mac = filter_mac;
7283           mp->bvi_mac = bvi_mac;
7284         }
7285       increment_mac_address (mac);
7286       /* send it... */
7287       S (mp);
7288     }
7289
7290   if (count > 1)
7291     {
7292       vl_api_control_ping_t *mp_ping;
7293       f64 after;
7294
7295       /* Shut off async mode */
7296       vam->async_mode = 0;
7297
7298       MPING (CONTROL_PING, mp_ping);
7299       S (mp_ping);
7300
7301       timeout = vat_time_now (vam) + 1.0;
7302       while (vat_time_now (vam) < timeout)
7303         if (vam->result_ready == 1)
7304           goto out;
7305       vam->retval = -99;
7306
7307     out:
7308       if (vam->retval == -99)
7309         errmsg ("timeout");
7310
7311       if (vam->async_errors > 0)
7312         {
7313           errmsg ("%d asynchronous errors", vam->async_errors);
7314           vam->retval = -98;
7315         }
7316       vam->async_errors = 0;
7317       after = vat_time_now (vam);
7318
7319       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7320              count, after - before, count / (after - before));
7321     }
7322   else
7323     {
7324       int ret;
7325
7326       /* Wait for a reply... */
7327       W (ret);
7328       return ret;
7329     }
7330   /* Return the good/bad news */
7331   return (vam->retval);
7332 }
7333
7334 static int
7335 api_bridge_domain_set_mac_age (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_bridge_domain_set_mac_age_t *mp;
7339   u32 bd_id = ~0;
7340   u32 mac_age = 0;
7341   int ret;
7342
7343   /* Parse args required to build the message */
7344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7345     {
7346       if (unformat (i, "bd_id %d", &bd_id));
7347       else if (unformat (i, "mac-age %d", &mac_age));
7348       else
7349         break;
7350     }
7351
7352   if (bd_id == ~0)
7353     {
7354       errmsg ("missing bridge domain");
7355       return -99;
7356     }
7357
7358   if (mac_age > 255)
7359     {
7360       errmsg ("mac age must be less than 256 ");
7361       return -99;
7362     }
7363
7364   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7365
7366   mp->bd_id = htonl (bd_id);
7367   mp->mac_age = (u8) mac_age;
7368
7369   S (mp);
7370   W (ret);
7371   return ret;
7372 }
7373
7374 static int
7375 api_l2_flags (vat_main_t * vam)
7376 {
7377   unformat_input_t *i = vam->input;
7378   vl_api_l2_flags_t *mp;
7379   u32 sw_if_index;
7380   u32 flags = 0;
7381   u8 sw_if_index_set = 0;
7382   u8 is_set = 0;
7383   int ret;
7384
7385   /* Parse args required to build the message */
7386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7387     {
7388       if (unformat (i, "sw_if_index %d", &sw_if_index))
7389         sw_if_index_set = 1;
7390       else if (unformat (i, "sw_if"))
7391         {
7392           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393             {
7394               if (unformat
7395                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7396                 sw_if_index_set = 1;
7397             }
7398           else
7399             break;
7400         }
7401       else if (unformat (i, "learn"))
7402         flags |= L2_LEARN;
7403       else if (unformat (i, "forward"))
7404         flags |= L2_FWD;
7405       else if (unformat (i, "flood"))
7406         flags |= L2_FLOOD;
7407       else if (unformat (i, "uu-flood"))
7408         flags |= L2_UU_FLOOD;
7409       else if (unformat (i, "arp-term"))
7410         flags |= L2_ARP_TERM;
7411       else if (unformat (i, "off"))
7412         is_set = 0;
7413       else if (unformat (i, "disable"))
7414         is_set = 0;
7415       else
7416         break;
7417     }
7418
7419   if (sw_if_index_set == 0)
7420     {
7421       errmsg ("missing interface name or sw_if_index");
7422       return -99;
7423     }
7424
7425   M (L2_FLAGS, mp);
7426
7427   mp->sw_if_index = ntohl (sw_if_index);
7428   mp->feature_bitmap = ntohl (flags);
7429   mp->is_set = is_set;
7430
7431   S (mp);
7432   W (ret);
7433   return ret;
7434 }
7435
7436 static int
7437 api_bridge_flags (vat_main_t * vam)
7438 {
7439   unformat_input_t *i = vam->input;
7440   vl_api_bridge_flags_t *mp;
7441   u32 bd_id;
7442   u8 bd_id_set = 0;
7443   u8 is_set = 1;
7444   u32 flags = 0;
7445   int ret;
7446
7447   /* Parse args required to build the message */
7448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (unformat (i, "bd_id %d", &bd_id))
7451         bd_id_set = 1;
7452       else if (unformat (i, "learn"))
7453         flags |= L2_LEARN;
7454       else if (unformat (i, "forward"))
7455         flags |= L2_FWD;
7456       else if (unformat (i, "flood"))
7457         flags |= L2_FLOOD;
7458       else if (unformat (i, "uu-flood"))
7459         flags |= L2_UU_FLOOD;
7460       else if (unformat (i, "arp-term"))
7461         flags |= L2_ARP_TERM;
7462       else if (unformat (i, "off"))
7463         is_set = 0;
7464       else if (unformat (i, "disable"))
7465         is_set = 0;
7466       else
7467         break;
7468     }
7469
7470   if (bd_id_set == 0)
7471     {
7472       errmsg ("missing bridge domain");
7473       return -99;
7474     }
7475
7476   M (BRIDGE_FLAGS, mp);
7477
7478   mp->bd_id = ntohl (bd_id);
7479   mp->feature_bitmap = ntohl (flags);
7480   mp->is_set = is_set;
7481
7482   S (mp);
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_bd_ip_mac_add_del (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_bd_ip_mac_add_del_t *mp;
7492   u32 bd_id;
7493   u8 is_ipv6 = 0;
7494   u8 is_add = 1;
7495   u8 bd_id_set = 0;
7496   u8 ip_set = 0;
7497   u8 mac_set = 0;
7498   ip4_address_t v4addr;
7499   ip6_address_t v6addr;
7500   u8 macaddr[6];
7501   int ret;
7502
7503
7504   /* Parse args required to build the message */
7505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7506     {
7507       if (unformat (i, "bd_id %d", &bd_id))
7508         {
7509           bd_id_set++;
7510         }
7511       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7512         {
7513           ip_set++;
7514         }
7515       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7516         {
7517           ip_set++;
7518           is_ipv6++;
7519         }
7520       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7521         {
7522           mac_set++;
7523         }
7524       else if (unformat (i, "del"))
7525         is_add = 0;
7526       else
7527         break;
7528     }
7529
7530   if (bd_id_set == 0)
7531     {
7532       errmsg ("missing bridge domain");
7533       return -99;
7534     }
7535   else if (ip_set == 0)
7536     {
7537       errmsg ("missing IP address");
7538       return -99;
7539     }
7540   else if (mac_set == 0)
7541     {
7542       errmsg ("missing MAC address");
7543       return -99;
7544     }
7545
7546   M (BD_IP_MAC_ADD_DEL, mp);
7547
7548   mp->bd_id = ntohl (bd_id);
7549   mp->is_ipv6 = is_ipv6;
7550   mp->is_add = is_add;
7551   if (is_ipv6)
7552     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7553   else
7554     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7555   clib_memcpy (mp->mac_address, macaddr, 6);
7556   S (mp);
7557   W (ret);
7558   return ret;
7559 }
7560
7561 static int
7562 api_tap_connect (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_tap_connect_t *mp;
7566   u8 mac_address[6];
7567   u8 random_mac = 1;
7568   u8 name_set = 0;
7569   u8 *tap_name;
7570   u8 *tag = 0;
7571   ip4_address_t ip4_address;
7572   u32 ip4_mask_width;
7573   int ip4_address_set = 0;
7574   ip6_address_t ip6_address;
7575   u32 ip6_mask_width;
7576   int ip6_address_set = 0;
7577   int ret;
7578
7579   memset (mac_address, 0, sizeof (mac_address));
7580
7581   /* Parse args required to build the message */
7582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7583     {
7584       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7585         {
7586           random_mac = 0;
7587         }
7588       else if (unformat (i, "random-mac"))
7589         random_mac = 1;
7590       else if (unformat (i, "tapname %s", &tap_name))
7591         name_set = 1;
7592       else if (unformat (i, "tag %s", &tag))
7593         ;
7594       else if (unformat (i, "address %U/%d",
7595                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7596         ip4_address_set = 1;
7597       else if (unformat (i, "address %U/%d",
7598                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7599         ip6_address_set = 1;
7600       else
7601         break;
7602     }
7603
7604   if (name_set == 0)
7605     {
7606       errmsg ("missing tap name");
7607       return -99;
7608     }
7609   if (vec_len (tap_name) > 63)
7610     {
7611       errmsg ("tap name too long");
7612       return -99;
7613     }
7614   vec_add1 (tap_name, 0);
7615
7616   if (vec_len (tag) > 63)
7617     {
7618       errmsg ("tag too long");
7619       return -99;
7620     }
7621
7622   /* Construct the API message */
7623   M (TAP_CONNECT, mp);
7624
7625   mp->use_random_mac = random_mac;
7626   clib_memcpy (mp->mac_address, mac_address, 6);
7627   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7628   if (tag)
7629     clib_memcpy (mp->tag, tag, vec_len (tag));
7630
7631   if (ip4_address_set)
7632     {
7633       mp->ip4_address_set = 1;
7634       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7635       mp->ip4_mask_width = ip4_mask_width;
7636     }
7637   if (ip6_address_set)
7638     {
7639       mp->ip6_address_set = 1;
7640       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7641       mp->ip6_mask_width = ip6_mask_width;
7642     }
7643
7644   vec_free (tap_name);
7645   vec_free (tag);
7646
7647   /* send it... */
7648   S (mp);
7649
7650   /* Wait for a reply... */
7651   W (ret);
7652   return ret;
7653 }
7654
7655 static int
7656 api_tap_modify (vat_main_t * vam)
7657 {
7658   unformat_input_t *i = vam->input;
7659   vl_api_tap_modify_t *mp;
7660   u8 mac_address[6];
7661   u8 random_mac = 1;
7662   u8 name_set = 0;
7663   u8 *tap_name;
7664   u32 sw_if_index = ~0;
7665   u8 sw_if_index_set = 0;
7666   int ret;
7667
7668   memset (mac_address, 0, sizeof (mac_address));
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7674         sw_if_index_set = 1;
7675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7676         sw_if_index_set = 1;
7677       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7678         {
7679           random_mac = 0;
7680         }
7681       else if (unformat (i, "random-mac"))
7682         random_mac = 1;
7683       else if (unformat (i, "tapname %s", &tap_name))
7684         name_set = 1;
7685       else
7686         break;
7687     }
7688
7689   if (sw_if_index_set == 0)
7690     {
7691       errmsg ("missing vpp interface name");
7692       return -99;
7693     }
7694   if (name_set == 0)
7695     {
7696       errmsg ("missing tap name");
7697       return -99;
7698     }
7699   if (vec_len (tap_name) > 63)
7700     {
7701       errmsg ("tap name too long");
7702     }
7703   vec_add1 (tap_name, 0);
7704
7705   /* Construct the API message */
7706   M (TAP_MODIFY, mp);
7707
7708   mp->use_random_mac = random_mac;
7709   mp->sw_if_index = ntohl (sw_if_index);
7710   clib_memcpy (mp->mac_address, mac_address, 6);
7711   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7712   vec_free (tap_name);
7713
7714   /* send it... */
7715   S (mp);
7716
7717   /* Wait for a reply... */
7718   W (ret);
7719   return ret;
7720 }
7721
7722 static int
7723 api_tap_delete (vat_main_t * vam)
7724 {
7725   unformat_input_t *i = vam->input;
7726   vl_api_tap_delete_t *mp;
7727   u32 sw_if_index = ~0;
7728   u8 sw_if_index_set = 0;
7729   int ret;
7730
7731   /* Parse args required to build the message */
7732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7733     {
7734       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7735         sw_if_index_set = 1;
7736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7737         sw_if_index_set = 1;
7738       else
7739         break;
7740     }
7741
7742   if (sw_if_index_set == 0)
7743     {
7744       errmsg ("missing vpp interface name");
7745       return -99;
7746     }
7747
7748   /* Construct the API message */
7749   M (TAP_DELETE, mp);
7750
7751   mp->sw_if_index = ntohl (sw_if_index);
7752
7753   /* send it... */
7754   S (mp);
7755
7756   /* Wait for a reply... */
7757   W (ret);
7758   return ret;
7759 }
7760
7761 static int
7762 api_tap_create_v2 (vat_main_t * vam)
7763 {
7764   unformat_input_t *i = vam->input;
7765   vl_api_tap_create_v2_t *mp;
7766   u8 mac_address[6];
7767   u8 random_mac = 1;
7768   u32 id = ~0;
7769   u8 *host_if_name = 0;
7770   u8 *host_ns = 0;
7771   u8 host_mac_addr[6];
7772   u8 host_mac_addr_set = 0;
7773   u8 *host_bridge = 0;
7774   ip4_address_t host_ip4_addr;
7775   ip4_address_t host_ip4_gw;
7776   u8 host_ip4_gw_set = 0;
7777   u32 host_ip4_prefix_len = 0;
7778   ip6_address_t host_ip6_addr;
7779   ip6_address_t host_ip6_gw;
7780   u8 host_ip6_gw_set = 0;
7781   u32 host_ip6_prefix_len = 0;
7782   int ret;
7783   int rx_ring_sz = 0, tx_ring_sz = 0;
7784
7785   memset (mac_address, 0, sizeof (mac_address));
7786
7787   /* Parse args required to build the message */
7788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7789     {
7790       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7791         {
7792           random_mac = 0;
7793         }
7794       else if (unformat (i, "id %s", &id))
7795         ;
7796       else if (unformat (i, "host-if-name %s", &host_if_name))
7797         ;
7798       else if (unformat (i, "host-ns %s", &host_ns))
7799         ;
7800       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7801                          host_mac_addr))
7802         host_mac_addr_set = 1;
7803       else if (unformat (i, "host-bridge %s", &host_bridge))
7804         ;
7805       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7806                          &host_ip4_addr, &host_ip4_prefix_len))
7807         ;
7808       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7809                          &host_ip6_addr, &host_ip6_prefix_len))
7810         ;
7811       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7812                          &host_ip4_gw))
7813         host_ip4_gw_set = 1;
7814       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7815                          &host_ip6_gw))
7816         host_ip6_gw_set = 1;
7817       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7818         ;
7819       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7820         ;
7821       else
7822         break;
7823     }
7824
7825   if (vec_len (host_if_name) > 63)
7826     {
7827       errmsg ("tap name too long. ");
7828       return -99;
7829     }
7830   if (vec_len (host_ns) > 63)
7831     {
7832       errmsg ("host name space too long. ");
7833       return -99;
7834     }
7835   if (vec_len (host_bridge) > 63)
7836     {
7837       errmsg ("host bridge name too long. ");
7838       return -99;
7839     }
7840   if (host_ip4_prefix_len > 32)
7841     {
7842       errmsg ("host ip4 prefix length not valid. ");
7843       return -99;
7844     }
7845   if (host_ip6_prefix_len > 128)
7846     {
7847       errmsg ("host ip6 prefix length not valid. ");
7848       return -99;
7849     }
7850   if (!is_pow2 (rx_ring_sz))
7851     {
7852       errmsg ("rx ring size must be power of 2. ");
7853       return -99;
7854     }
7855   if (rx_ring_sz > 32768)
7856     {
7857       errmsg ("rx ring size must be 32768 or lower. ");
7858       return -99;
7859     }
7860   if (!is_pow2 (tx_ring_sz))
7861     {
7862       errmsg ("tx ring size must be power of 2. ");
7863       return -99;
7864     }
7865   if (tx_ring_sz > 32768)
7866     {
7867       errmsg ("tx ring size must be 32768 or lower. ");
7868       return -99;
7869     }
7870
7871   /* Construct the API message */
7872   M (TAP_CREATE_V2, mp);
7873
7874   mp->use_random_mac = random_mac;
7875
7876   mp->id = id;
7877   mp->host_namespace_set = host_ns != 0;
7878   mp->host_bridge_set = host_bridge != 0;
7879   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7880   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7881   mp->rx_ring_sz = rx_ring_sz;
7882   mp->tx_ring_sz = tx_ring_sz;
7883
7884   if (random_mac)
7885     clib_memcpy (mp->mac_address, mac_address, 6);
7886   if (host_mac_addr_set)
7887     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7888   if (host_if_name)
7889     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7890   if (host_ns)
7891     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7892   if (host_bridge)
7893     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7894   if (host_ip4_prefix_len)
7895     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7896   if (host_ip4_prefix_len)
7897     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7898   if (host_ip4_gw_set)
7899     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7900   if (host_ip6_gw_set)
7901     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7902
7903   vec_free (host_ns);
7904   vec_free (host_if_name);
7905   vec_free (host_bridge);
7906
7907   /* send it... */
7908   S (mp);
7909
7910   /* Wait for a reply... */
7911   W (ret);
7912   return ret;
7913 }
7914
7915 static int
7916 api_tap_delete_v2 (vat_main_t * vam)
7917 {
7918   unformat_input_t *i = vam->input;
7919   vl_api_tap_delete_v2_t *mp;
7920   u32 sw_if_index = ~0;
7921   u8 sw_if_index_set = 0;
7922   int ret;
7923
7924   /* Parse args required to build the message */
7925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7926     {
7927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7928         sw_if_index_set = 1;
7929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7930         sw_if_index_set = 1;
7931       else
7932         break;
7933     }
7934
7935   if (sw_if_index_set == 0)
7936     {
7937       errmsg ("missing vpp interface name. ");
7938       return -99;
7939     }
7940
7941   /* Construct the API message */
7942   M (TAP_DELETE_V2, mp);
7943
7944   mp->sw_if_index = ntohl (sw_if_index);
7945
7946   /* send it... */
7947   S (mp);
7948
7949   /* Wait for a reply... */
7950   W (ret);
7951   return ret;
7952 }
7953
7954 static int
7955 api_ip_table_add_del (vat_main_t * vam)
7956 {
7957   unformat_input_t *i = vam->input;
7958   vl_api_ip_table_add_del_t *mp;
7959   u32 table_id = ~0;
7960   u8 is_ipv6 = 0;
7961   u8 is_add = 1;
7962   int ret = 0;
7963
7964   /* Parse args required to build the message */
7965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7966     {
7967       if (unformat (i, "ipv6"))
7968         is_ipv6 = 1;
7969       else if (unformat (i, "del"))
7970         is_add = 0;
7971       else if (unformat (i, "add"))
7972         is_add = 1;
7973       else if (unformat (i, "table %d", &table_id))
7974         ;
7975       else
7976         {
7977           clib_warning ("parse error '%U'", format_unformat_error, i);
7978           return -99;
7979         }
7980     }
7981
7982   if (~0 == table_id)
7983     {
7984       errmsg ("missing table-ID");
7985       return -99;
7986     }
7987
7988   /* Construct the API message */
7989   M (IP_TABLE_ADD_DEL, mp);
7990
7991   mp->table_id = ntohl (table_id);
7992   mp->is_ipv6 = is_ipv6;
7993   mp->is_add = is_add;
7994
7995   /* send it... */
7996   S (mp);
7997
7998   /* Wait for a reply... */
7999   W (ret);
8000
8001   return ret;
8002 }
8003
8004 static int
8005 api_ip_add_del_route (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_ip_add_del_route_t *mp;
8009   u32 sw_if_index = ~0, vrf_id = 0;
8010   u8 is_ipv6 = 0;
8011   u8 is_local = 0, is_drop = 0;
8012   u8 is_unreach = 0, is_prohibit = 0;
8013   u8 is_add = 1;
8014   u32 next_hop_weight = 1;
8015   u8 is_multipath = 0;
8016   u8 address_set = 0;
8017   u8 address_length_set = 0;
8018   u32 next_hop_table_id = 0;
8019   u32 resolve_attempts = 0;
8020   u32 dst_address_length = 0;
8021   u8 next_hop_set = 0;
8022   ip4_address_t v4_dst_address, v4_next_hop_address;
8023   ip6_address_t v6_dst_address, v6_next_hop_address;
8024   int count = 1;
8025   int j;
8026   f64 before = 0;
8027   u32 random_add_del = 0;
8028   u32 *random_vector = 0;
8029   uword *random_hash;
8030   u32 random_seed = 0xdeaddabe;
8031   u32 classify_table_index = ~0;
8032   u8 is_classify = 0;
8033   u8 resolve_host = 0, resolve_attached = 0;
8034   mpls_label_t *next_hop_out_label_stack = NULL;
8035   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8036   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8037
8038   /* Parse args required to build the message */
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8042         ;
8043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8044         ;
8045       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8046         {
8047           address_set = 1;
8048           is_ipv6 = 0;
8049         }
8050       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8051         {
8052           address_set = 1;
8053           is_ipv6 = 1;
8054         }
8055       else if (unformat (i, "/%d", &dst_address_length))
8056         {
8057           address_length_set = 1;
8058         }
8059
8060       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8061                                          &v4_next_hop_address))
8062         {
8063           next_hop_set = 1;
8064         }
8065       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8066                                          &v6_next_hop_address))
8067         {
8068           next_hop_set = 1;
8069         }
8070       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8071         ;
8072       else if (unformat (i, "weight %d", &next_hop_weight))
8073         ;
8074       else if (unformat (i, "drop"))
8075         {
8076           is_drop = 1;
8077         }
8078       else if (unformat (i, "null-send-unreach"))
8079         {
8080           is_unreach = 1;
8081         }
8082       else if (unformat (i, "null-send-prohibit"))
8083         {
8084           is_prohibit = 1;
8085         }
8086       else if (unformat (i, "local"))
8087         {
8088           is_local = 1;
8089         }
8090       else if (unformat (i, "classify %d", &classify_table_index))
8091         {
8092           is_classify = 1;
8093         }
8094       else if (unformat (i, "del"))
8095         is_add = 0;
8096       else if (unformat (i, "add"))
8097         is_add = 1;
8098       else if (unformat (i, "resolve-via-host"))
8099         resolve_host = 1;
8100       else if (unformat (i, "resolve-via-attached"))
8101         resolve_attached = 1;
8102       else if (unformat (i, "multipath"))
8103         is_multipath = 1;
8104       else if (unformat (i, "vrf %d", &vrf_id))
8105         ;
8106       else if (unformat (i, "count %d", &count))
8107         ;
8108       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8109         ;
8110       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8111         ;
8112       else if (unformat (i, "out-label %d", &next_hop_out_label))
8113         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8114       else if (unformat (i, "via-label %d", &next_hop_via_label))
8115         ;
8116       else if (unformat (i, "random"))
8117         random_add_del = 1;
8118       else if (unformat (i, "seed %d", &random_seed))
8119         ;
8120       else
8121         {
8122           clib_warning ("parse error '%U'", format_unformat_error, i);
8123           return -99;
8124         }
8125     }
8126
8127   if (!next_hop_set && !is_drop && !is_local &&
8128       !is_classify && !is_unreach && !is_prohibit &&
8129       MPLS_LABEL_INVALID == next_hop_via_label)
8130     {
8131       errmsg
8132         ("next hop / local / drop / unreach / prohibit / classify not set");
8133       return -99;
8134     }
8135
8136   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8137     {
8138       errmsg ("next hop and next-hop via label set");
8139       return -99;
8140     }
8141   if (address_set == 0)
8142     {
8143       errmsg ("missing addresses");
8144       return -99;
8145     }
8146
8147   if (address_length_set == 0)
8148     {
8149       errmsg ("missing address length");
8150       return -99;
8151     }
8152
8153   /* Generate a pile of unique, random routes */
8154   if (random_add_del)
8155     {
8156       u32 this_random_address;
8157       random_hash = hash_create (count, sizeof (uword));
8158
8159       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8160       for (j = 0; j <= count; j++)
8161         {
8162           do
8163             {
8164               this_random_address = random_u32 (&random_seed);
8165               this_random_address =
8166                 clib_host_to_net_u32 (this_random_address);
8167             }
8168           while (hash_get (random_hash, this_random_address));
8169           vec_add1 (random_vector, this_random_address);
8170           hash_set (random_hash, this_random_address, 1);
8171         }
8172       hash_free (random_hash);
8173       v4_dst_address.as_u32 = random_vector[0];
8174     }
8175
8176   if (count > 1)
8177     {
8178       /* Turn on async mode */
8179       vam->async_mode = 1;
8180       vam->async_errors = 0;
8181       before = vat_time_now (vam);
8182     }
8183
8184   for (j = 0; j < count; j++)
8185     {
8186       /* Construct the API message */
8187       M2 (IP_ADD_DEL_ROUTE, mp,
8188           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8189
8190       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8191       mp->table_id = ntohl (vrf_id);
8192
8193       mp->is_add = is_add;
8194       mp->is_drop = is_drop;
8195       mp->is_unreach = is_unreach;
8196       mp->is_prohibit = is_prohibit;
8197       mp->is_ipv6 = is_ipv6;
8198       mp->is_local = is_local;
8199       mp->is_classify = is_classify;
8200       mp->is_multipath = is_multipath;
8201       mp->is_resolve_host = resolve_host;
8202       mp->is_resolve_attached = resolve_attached;
8203       mp->next_hop_weight = next_hop_weight;
8204       mp->dst_address_length = dst_address_length;
8205       mp->next_hop_table_id = ntohl (next_hop_table_id);
8206       mp->classify_table_index = ntohl (classify_table_index);
8207       mp->next_hop_via_label = ntohl (next_hop_via_label);
8208       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8209       if (0 != mp->next_hop_n_out_labels)
8210         {
8211           memcpy (mp->next_hop_out_label_stack,
8212                   next_hop_out_label_stack,
8213                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8214           vec_free (next_hop_out_label_stack);
8215         }
8216
8217       if (is_ipv6)
8218         {
8219           clib_memcpy (mp->dst_address, &v6_dst_address,
8220                        sizeof (v6_dst_address));
8221           if (next_hop_set)
8222             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8223                          sizeof (v6_next_hop_address));
8224           increment_v6_address (&v6_dst_address);
8225         }
8226       else
8227         {
8228           clib_memcpy (mp->dst_address, &v4_dst_address,
8229                        sizeof (v4_dst_address));
8230           if (next_hop_set)
8231             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8232                          sizeof (v4_next_hop_address));
8233           if (random_add_del)
8234             v4_dst_address.as_u32 = random_vector[j + 1];
8235           else
8236             increment_v4_address (&v4_dst_address);
8237         }
8238       /* send it... */
8239       S (mp);
8240       /* If we receive SIGTERM, stop now... */
8241       if (vam->do_exit)
8242         break;
8243     }
8244
8245   /* When testing multiple add/del ops, use a control-ping to sync */
8246   if (count > 1)
8247     {
8248       vl_api_control_ping_t *mp_ping;
8249       f64 after;
8250       f64 timeout;
8251
8252       /* Shut off async mode */
8253       vam->async_mode = 0;
8254
8255       MPING (CONTROL_PING, mp_ping);
8256       S (mp_ping);
8257
8258       timeout = vat_time_now (vam) + 1.0;
8259       while (vat_time_now (vam) < timeout)
8260         if (vam->result_ready == 1)
8261           goto out;
8262       vam->retval = -99;
8263
8264     out:
8265       if (vam->retval == -99)
8266         errmsg ("timeout");
8267
8268       if (vam->async_errors > 0)
8269         {
8270           errmsg ("%d asynchronous errors", vam->async_errors);
8271           vam->retval = -98;
8272         }
8273       vam->async_errors = 0;
8274       after = vat_time_now (vam);
8275
8276       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8277       if (j > 0)
8278         count = j;
8279
8280       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8281              count, after - before, count / (after - before));
8282     }
8283   else
8284     {
8285       int ret;
8286
8287       /* Wait for a reply... */
8288       W (ret);
8289       return ret;
8290     }
8291
8292   /* Return the good/bad news */
8293   return (vam->retval);
8294 }
8295
8296 static int
8297 api_ip_mroute_add_del (vat_main_t * vam)
8298 {
8299   unformat_input_t *i = vam->input;
8300   vl_api_ip_mroute_add_del_t *mp;
8301   u32 sw_if_index = ~0, vrf_id = 0;
8302   u8 is_ipv6 = 0;
8303   u8 is_local = 0;
8304   u8 is_add = 1;
8305   u8 address_set = 0;
8306   u32 grp_address_length = 0;
8307   ip4_address_t v4_grp_address, v4_src_address;
8308   ip6_address_t v6_grp_address, v6_src_address;
8309   mfib_itf_flags_t iflags = 0;
8310   mfib_entry_flags_t eflags = 0;
8311   int ret;
8312
8313   /* Parse args required to build the message */
8314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8315     {
8316       if (unformat (i, "sw_if_index %d", &sw_if_index))
8317         ;
8318       else if (unformat (i, "%U %U",
8319                          unformat_ip4_address, &v4_src_address,
8320                          unformat_ip4_address, &v4_grp_address))
8321         {
8322           grp_address_length = 64;
8323           address_set = 1;
8324           is_ipv6 = 0;
8325         }
8326       else if (unformat (i, "%U %U",
8327                          unformat_ip6_address, &v6_src_address,
8328                          unformat_ip6_address, &v6_grp_address))
8329         {
8330           grp_address_length = 256;
8331           address_set = 1;
8332           is_ipv6 = 1;
8333         }
8334       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8335         {
8336           memset (&v4_src_address, 0, sizeof (v4_src_address));
8337           grp_address_length = 32;
8338           address_set = 1;
8339           is_ipv6 = 0;
8340         }
8341       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8342         {
8343           memset (&v6_src_address, 0, sizeof (v6_src_address));
8344           grp_address_length = 128;
8345           address_set = 1;
8346           is_ipv6 = 1;
8347         }
8348       else if (unformat (i, "/%d", &grp_address_length))
8349         ;
8350       else if (unformat (i, "local"))
8351         {
8352           is_local = 1;
8353         }
8354       else if (unformat (i, "del"))
8355         is_add = 0;
8356       else if (unformat (i, "add"))
8357         is_add = 1;
8358       else if (unformat (i, "vrf %d", &vrf_id))
8359         ;
8360       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8361         ;
8362       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8363         ;
8364       else
8365         {
8366           clib_warning ("parse error '%U'", format_unformat_error, i);
8367           return -99;
8368         }
8369     }
8370
8371   if (address_set == 0)
8372     {
8373       errmsg ("missing addresses\n");
8374       return -99;
8375     }
8376
8377   /* Construct the API message */
8378   M (IP_MROUTE_ADD_DEL, mp);
8379
8380   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8381   mp->table_id = ntohl (vrf_id);
8382
8383   mp->is_add = is_add;
8384   mp->is_ipv6 = is_ipv6;
8385   mp->is_local = is_local;
8386   mp->itf_flags = ntohl (iflags);
8387   mp->entry_flags = ntohl (eflags);
8388   mp->grp_address_length = grp_address_length;
8389   mp->grp_address_length = ntohs (mp->grp_address_length);
8390
8391   if (is_ipv6)
8392     {
8393       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8394       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8395     }
8396   else
8397     {
8398       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8399       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8400
8401     }
8402
8403   /* send it... */
8404   S (mp);
8405   /* Wait for a reply... */
8406   W (ret);
8407   return ret;
8408 }
8409
8410 static int
8411 api_mpls_table_add_del (vat_main_t * vam)
8412 {
8413   unformat_input_t *i = vam->input;
8414   vl_api_mpls_table_add_del_t *mp;
8415   u32 table_id = ~0;
8416   u8 is_add = 1;
8417   int ret = 0;
8418
8419   /* Parse args required to build the message */
8420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8421     {
8422       if (unformat (i, "table %d", &table_id))
8423         ;
8424       else if (unformat (i, "del"))
8425         is_add = 0;
8426       else if (unformat (i, "add"))
8427         is_add = 1;
8428       else
8429         {
8430           clib_warning ("parse error '%U'", format_unformat_error, i);
8431           return -99;
8432         }
8433     }
8434
8435   if (~0 == table_id)
8436     {
8437       errmsg ("missing table-ID");
8438       return -99;
8439     }
8440
8441   /* Construct the API message */
8442   M (MPLS_TABLE_ADD_DEL, mp);
8443
8444   mp->mt_table_id = ntohl (table_id);
8445   mp->mt_is_add = is_add;
8446
8447   /* send it... */
8448   S (mp);
8449
8450   /* Wait for a reply... */
8451   W (ret);
8452
8453   return ret;
8454 }
8455
8456 static int
8457 api_mpls_route_add_del (vat_main_t * vam)
8458 {
8459   unformat_input_t *i = vam->input;
8460   vl_api_mpls_route_add_del_t *mp;
8461   u32 sw_if_index = ~0, table_id = 0;
8462   u8 is_add = 1;
8463   u32 next_hop_weight = 1;
8464   u8 is_multipath = 0;
8465   u32 next_hop_table_id = 0;
8466   u8 next_hop_set = 0;
8467   ip4_address_t v4_next_hop_address = {
8468     .as_u32 = 0,
8469   };
8470   ip6_address_t v6_next_hop_address = { {0} };
8471   int count = 1;
8472   int j;
8473   f64 before = 0;
8474   u32 classify_table_index = ~0;
8475   u8 is_classify = 0;
8476   u8 resolve_host = 0, resolve_attached = 0;
8477   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8478   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8479   mpls_label_t *next_hop_out_label_stack = NULL;
8480   mpls_label_t local_label = MPLS_LABEL_INVALID;
8481   u8 is_eos = 0;
8482   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8483
8484   /* Parse args required to build the message */
8485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8486     {
8487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8488         ;
8489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8490         ;
8491       else if (unformat (i, "%d", &local_label))
8492         ;
8493       else if (unformat (i, "eos"))
8494         is_eos = 1;
8495       else if (unformat (i, "non-eos"))
8496         is_eos = 0;
8497       else if (unformat (i, "via %U", unformat_ip4_address,
8498                          &v4_next_hop_address))
8499         {
8500           next_hop_set = 1;
8501           next_hop_proto = DPO_PROTO_IP4;
8502         }
8503       else if (unformat (i, "via %U", unformat_ip6_address,
8504                          &v6_next_hop_address))
8505         {
8506           next_hop_set = 1;
8507           next_hop_proto = DPO_PROTO_IP6;
8508         }
8509       else if (unformat (i, "weight %d", &next_hop_weight))
8510         ;
8511       else if (unformat (i, "classify %d", &classify_table_index))
8512         {
8513           is_classify = 1;
8514         }
8515       else if (unformat (i, "del"))
8516         is_add = 0;
8517       else if (unformat (i, "add"))
8518         is_add = 1;
8519       else if (unformat (i, "resolve-via-host"))
8520         resolve_host = 1;
8521       else if (unformat (i, "resolve-via-attached"))
8522         resolve_attached = 1;
8523       else if (unformat (i, "multipath"))
8524         is_multipath = 1;
8525       else if (unformat (i, "count %d", &count))
8526         ;
8527       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8528         {
8529           next_hop_set = 1;
8530           next_hop_proto = DPO_PROTO_IP4;
8531         }
8532       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8533         {
8534           next_hop_set = 1;
8535           next_hop_proto = DPO_PROTO_IP6;
8536         }
8537       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8538         ;
8539       else if (unformat (i, "via-label %d", &next_hop_via_label))
8540         ;
8541       else if (unformat (i, "out-label %d", &next_hop_out_label))
8542         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8543       else
8544         {
8545           clib_warning ("parse error '%U'", format_unformat_error, i);
8546           return -99;
8547         }
8548     }
8549
8550   if (!next_hop_set && !is_classify)
8551     {
8552       errmsg ("next hop / classify not set");
8553       return -99;
8554     }
8555
8556   if (MPLS_LABEL_INVALID == local_label)
8557     {
8558       errmsg ("missing label");
8559       return -99;
8560     }
8561
8562   if (count > 1)
8563     {
8564       /* Turn on async mode */
8565       vam->async_mode = 1;
8566       vam->async_errors = 0;
8567       before = vat_time_now (vam);
8568     }
8569
8570   for (j = 0; j < count; j++)
8571     {
8572       /* Construct the API message */
8573       M2 (MPLS_ROUTE_ADD_DEL, mp,
8574           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8575
8576       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8577       mp->mr_table_id = ntohl (table_id);
8578
8579       mp->mr_is_add = is_add;
8580       mp->mr_next_hop_proto = next_hop_proto;
8581       mp->mr_is_classify = is_classify;
8582       mp->mr_is_multipath = is_multipath;
8583       mp->mr_is_resolve_host = resolve_host;
8584       mp->mr_is_resolve_attached = resolve_attached;
8585       mp->mr_next_hop_weight = next_hop_weight;
8586       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8587       mp->mr_classify_table_index = ntohl (classify_table_index);
8588       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8589       mp->mr_label = ntohl (local_label);
8590       mp->mr_eos = is_eos;
8591
8592       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8593       if (0 != mp->mr_next_hop_n_out_labels)
8594         {
8595           memcpy (mp->mr_next_hop_out_label_stack,
8596                   next_hop_out_label_stack,
8597                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8598           vec_free (next_hop_out_label_stack);
8599         }
8600
8601       if (next_hop_set)
8602         {
8603           if (DPO_PROTO_IP4 == next_hop_proto)
8604             {
8605               clib_memcpy (mp->mr_next_hop,
8606                            &v4_next_hop_address,
8607                            sizeof (v4_next_hop_address));
8608             }
8609           else if (DPO_PROTO_IP6 == next_hop_proto)
8610
8611             {
8612               clib_memcpy (mp->mr_next_hop,
8613                            &v6_next_hop_address,
8614                            sizeof (v6_next_hop_address));
8615             }
8616         }
8617       local_label++;
8618
8619       /* send it... */
8620       S (mp);
8621       /* If we receive SIGTERM, stop now... */
8622       if (vam->do_exit)
8623         break;
8624     }
8625
8626   /* When testing multiple add/del ops, use a control-ping to sync */
8627   if (count > 1)
8628     {
8629       vl_api_control_ping_t *mp_ping;
8630       f64 after;
8631       f64 timeout;
8632
8633       /* Shut off async mode */
8634       vam->async_mode = 0;
8635
8636       MPING (CONTROL_PING, mp_ping);
8637       S (mp_ping);
8638
8639       timeout = vat_time_now (vam) + 1.0;
8640       while (vat_time_now (vam) < timeout)
8641         if (vam->result_ready == 1)
8642           goto out;
8643       vam->retval = -99;
8644
8645     out:
8646       if (vam->retval == -99)
8647         errmsg ("timeout");
8648
8649       if (vam->async_errors > 0)
8650         {
8651           errmsg ("%d asynchronous errors", vam->async_errors);
8652           vam->retval = -98;
8653         }
8654       vam->async_errors = 0;
8655       after = vat_time_now (vam);
8656
8657       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8658       if (j > 0)
8659         count = j;
8660
8661       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8662              count, after - before, count / (after - before));
8663     }
8664   else
8665     {
8666       int ret;
8667
8668       /* Wait for a reply... */
8669       W (ret);
8670       return ret;
8671     }
8672
8673   /* Return the good/bad news */
8674   return (vam->retval);
8675 }
8676
8677 static int
8678 api_mpls_ip_bind_unbind (vat_main_t * vam)
8679 {
8680   unformat_input_t *i = vam->input;
8681   vl_api_mpls_ip_bind_unbind_t *mp;
8682   u32 ip_table_id = 0;
8683   u8 is_bind = 1;
8684   u8 is_ip4 = 1;
8685   ip4_address_t v4_address;
8686   ip6_address_t v6_address;
8687   u32 address_length;
8688   u8 address_set = 0;
8689   mpls_label_t local_label = MPLS_LABEL_INVALID;
8690   int ret;
8691
8692   /* Parse args required to build the message */
8693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8694     {
8695       if (unformat (i, "%U/%d", unformat_ip4_address,
8696                     &v4_address, &address_length))
8697         {
8698           is_ip4 = 1;
8699           address_set = 1;
8700         }
8701       else if (unformat (i, "%U/%d", unformat_ip6_address,
8702                          &v6_address, &address_length))
8703         {
8704           is_ip4 = 0;
8705           address_set = 1;
8706         }
8707       else if (unformat (i, "%d", &local_label))
8708         ;
8709       else if (unformat (i, "table-id %d", &ip_table_id))
8710         ;
8711       else if (unformat (i, "unbind"))
8712         is_bind = 0;
8713       else if (unformat (i, "bind"))
8714         is_bind = 1;
8715       else
8716         {
8717           clib_warning ("parse error '%U'", format_unformat_error, i);
8718           return -99;
8719         }
8720     }
8721
8722   if (!address_set)
8723     {
8724       errmsg ("IP addres not set");
8725       return -99;
8726     }
8727
8728   if (MPLS_LABEL_INVALID == local_label)
8729     {
8730       errmsg ("missing label");
8731       return -99;
8732     }
8733
8734   /* Construct the API message */
8735   M (MPLS_IP_BIND_UNBIND, mp);
8736
8737   mp->mb_is_bind = is_bind;
8738   mp->mb_is_ip4 = is_ip4;
8739   mp->mb_ip_table_id = ntohl (ip_table_id);
8740   mp->mb_mpls_table_id = 0;
8741   mp->mb_label = ntohl (local_label);
8742   mp->mb_address_length = address_length;
8743
8744   if (is_ip4)
8745     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8746   else
8747     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8748
8749   /* send it... */
8750   S (mp);
8751
8752   /* Wait for a reply... */
8753   W (ret);
8754   return ret;
8755 }
8756
8757 static int
8758 api_bier_table_add_del (vat_main_t * vam)
8759 {
8760   unformat_input_t *i = vam->input;
8761   vl_api_bier_table_add_del_t *mp;
8762   u8 is_add = 1;
8763   u32 set = 0, sub_domain = 0, hdr_len = 3;
8764   mpls_label_t local_label = MPLS_LABEL_INVALID;
8765   int ret;
8766
8767   /* Parse args required to build the message */
8768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8769     {
8770       if (unformat (i, "sub-domain %d", &sub_domain))
8771         ;
8772       else if (unformat (i, "set %d", &set))
8773         ;
8774       else if (unformat (i, "label %d", &local_label))
8775         ;
8776       else if (unformat (i, "hdr-len %d", &hdr_len))
8777         ;
8778       else if (unformat (i, "add"))
8779         is_add = 1;
8780       else if (unformat (i, "del"))
8781         is_add = 0;
8782       else
8783         {
8784           clib_warning ("parse error '%U'", format_unformat_error, i);
8785           return -99;
8786         }
8787     }
8788
8789   if (MPLS_LABEL_INVALID == local_label)
8790     {
8791       errmsg ("missing label\n");
8792       return -99;
8793     }
8794
8795   /* Construct the API message */
8796   M (BIER_TABLE_ADD_DEL, mp);
8797
8798   mp->bt_is_add = is_add;
8799   mp->bt_label = ntohl (local_label);
8800   mp->bt_tbl_id.bt_set = set;
8801   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8802   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8803
8804   /* send it... */
8805   S (mp);
8806
8807   /* Wait for a reply... */
8808   W (ret);
8809
8810   return (ret);
8811 }
8812
8813 static int
8814 api_bier_route_add_del (vat_main_t * vam)
8815 {
8816   unformat_input_t *i = vam->input;
8817   vl_api_bier_route_add_del_t *mp;
8818   u8 is_add = 1;
8819   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8820   ip4_address_t v4_next_hop_address;
8821   ip6_address_t v6_next_hop_address;
8822   u8 next_hop_set = 0;
8823   u8 next_hop_proto_is_ip4 = 1;
8824   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8825   int ret;
8826
8827   /* Parse args required to build the message */
8828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8831         {
8832           next_hop_proto_is_ip4 = 1;
8833           next_hop_set = 1;
8834         }
8835       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8836         {
8837           next_hop_proto_is_ip4 = 0;
8838           next_hop_set = 1;
8839         }
8840       if (unformat (i, "sub-domain %d", &sub_domain))
8841         ;
8842       else if (unformat (i, "set %d", &set))
8843         ;
8844       else if (unformat (i, "hdr-len %d", &hdr_len))
8845         ;
8846       else if (unformat (i, "bp %d", &bp))
8847         ;
8848       else if (unformat (i, "add"))
8849         is_add = 1;
8850       else if (unformat (i, "del"))
8851         is_add = 0;
8852       else if (unformat (i, "out-label %d", &next_hop_out_label))
8853         ;
8854       else
8855         {
8856           clib_warning ("parse error '%U'", format_unformat_error, i);
8857           return -99;
8858         }
8859     }
8860
8861   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8862     {
8863       errmsg ("next hop / label set\n");
8864       return -99;
8865     }
8866   if (0 == bp)
8867     {
8868       errmsg ("bit=position not set\n");
8869       return -99;
8870     }
8871
8872   /* Construct the API message */
8873   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8874
8875   mp->br_is_add = is_add;
8876   mp->br_tbl_id.bt_set = set;
8877   mp->br_tbl_id.bt_sub_domain = sub_domain;
8878   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8879   mp->br_bp = ntohs (bp);
8880   mp->br_n_paths = 1;
8881   mp->br_paths[0].n_labels = 1;
8882   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8883   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8884
8885   if (next_hop_proto_is_ip4)
8886     {
8887       clib_memcpy (mp->br_paths[0].next_hop,
8888                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8889     }
8890   else
8891     {
8892       clib_memcpy (mp->br_paths[0].next_hop,
8893                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8894     }
8895
8896   /* send it... */
8897   S (mp);
8898
8899   /* Wait for a reply... */
8900   W (ret);
8901
8902   return (ret);
8903 }
8904
8905 static int
8906 api_proxy_arp_add_del (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_proxy_arp_add_del_t *mp;
8910   u32 vrf_id = 0;
8911   u8 is_add = 1;
8912   ip4_address_t lo, hi;
8913   u8 range_set = 0;
8914   int ret;
8915
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "vrf %d", &vrf_id))
8919         ;
8920       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8921                          unformat_ip4_address, &hi))
8922         range_set = 1;
8923       else if (unformat (i, "del"))
8924         is_add = 0;
8925       else
8926         {
8927           clib_warning ("parse error '%U'", format_unformat_error, i);
8928           return -99;
8929         }
8930     }
8931
8932   if (range_set == 0)
8933     {
8934       errmsg ("address range not set");
8935       return -99;
8936     }
8937
8938   M (PROXY_ARP_ADD_DEL, mp);
8939
8940   mp->vrf_id = ntohl (vrf_id);
8941   mp->is_add = is_add;
8942   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8943   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8944
8945   S (mp);
8946   W (ret);
8947   return ret;
8948 }
8949
8950 static int
8951 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8955   u32 sw_if_index;
8956   u8 enable = 1;
8957   u8 sw_if_index_set = 0;
8958   int ret;
8959
8960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8961     {
8962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8963         sw_if_index_set = 1;
8964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "enable"))
8967         enable = 1;
8968       else if (unformat (i, "disable"))
8969         enable = 0;
8970       else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (sw_if_index_set == 0)
8978     {
8979       errmsg ("missing interface name or sw_if_index");
8980       return -99;
8981     }
8982
8983   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8984
8985   mp->sw_if_index = ntohl (sw_if_index);
8986   mp->enable_disable = enable;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_mpls_tunnel_add_del (vat_main_t * vam)
8995 {
8996   unformat_input_t *i = vam->input;
8997   vl_api_mpls_tunnel_add_del_t *mp;
8998
8999   u8 is_add = 1;
9000   u8 l2_only = 0;
9001   u32 sw_if_index = ~0;
9002   u32 next_hop_sw_if_index = ~0;
9003   u32 next_hop_proto_is_ip4 = 1;
9004
9005   u32 next_hop_table_id = 0;
9006   ip4_address_t v4_next_hop_address = {
9007     .as_u32 = 0,
9008   };
9009   ip6_address_t v6_next_hop_address = { {0} };
9010   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9011   int ret;
9012
9013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9014     {
9015       if (unformat (i, "add"))
9016         is_add = 1;
9017       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9018         is_add = 0;
9019       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9020         ;
9021       else if (unformat (i, "via %U",
9022                          unformat_ip4_address, &v4_next_hop_address))
9023         {
9024           next_hop_proto_is_ip4 = 1;
9025         }
9026       else if (unformat (i, "via %U",
9027                          unformat_ip6_address, &v6_next_hop_address))
9028         {
9029           next_hop_proto_is_ip4 = 0;
9030         }
9031       else if (unformat (i, "l2-only"))
9032         l2_only = 1;
9033       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9034         ;
9035       else if (unformat (i, "out-label %d", &next_hop_out_label))
9036         vec_add1 (labels, ntohl (next_hop_out_label));
9037       else
9038         {
9039           clib_warning ("parse error '%U'", format_unformat_error, i);
9040           return -99;
9041         }
9042     }
9043
9044   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9045
9046   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9047   mp->mt_sw_if_index = ntohl (sw_if_index);
9048   mp->mt_is_add = is_add;
9049   mp->mt_l2_only = l2_only;
9050   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9051   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9052
9053   mp->mt_next_hop_n_out_labels = vec_len (labels);
9054
9055   if (0 != mp->mt_next_hop_n_out_labels)
9056     {
9057       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9058                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9059       vec_free (labels);
9060     }
9061
9062   if (next_hop_proto_is_ip4)
9063     {
9064       clib_memcpy (mp->mt_next_hop,
9065                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9066     }
9067   else
9068     {
9069       clib_memcpy (mp->mt_next_hop,
9070                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9071     }
9072
9073   S (mp);
9074   W (ret);
9075   return ret;
9076 }
9077
9078 static int
9079 api_sw_interface_set_unnumbered (vat_main_t * vam)
9080 {
9081   unformat_input_t *i = vam->input;
9082   vl_api_sw_interface_set_unnumbered_t *mp;
9083   u32 sw_if_index;
9084   u32 unnum_sw_index = ~0;
9085   u8 is_add = 1;
9086   u8 sw_if_index_set = 0;
9087   int ret;
9088
9089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9090     {
9091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9092         sw_if_index_set = 1;
9093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9094         sw_if_index_set = 1;
9095       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9096         ;
9097       else if (unformat (i, "del"))
9098         is_add = 0;
9099       else
9100         {
9101           clib_warning ("parse error '%U'", format_unformat_error, i);
9102           return -99;
9103         }
9104     }
9105
9106   if (sw_if_index_set == 0)
9107     {
9108       errmsg ("missing interface name or sw_if_index");
9109       return -99;
9110     }
9111
9112   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9113
9114   mp->sw_if_index = ntohl (sw_if_index);
9115   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9116   mp->is_add = is_add;
9117
9118   S (mp);
9119   W (ret);
9120   return ret;
9121 }
9122
9123 static int
9124 api_ip_neighbor_add_del (vat_main_t * vam)
9125 {
9126   unformat_input_t *i = vam->input;
9127   vl_api_ip_neighbor_add_del_t *mp;
9128   u32 sw_if_index;
9129   u8 sw_if_index_set = 0;
9130   u8 is_add = 1;
9131   u8 is_static = 0;
9132   u8 is_no_fib_entry = 0;
9133   u8 mac_address[6];
9134   u8 mac_set = 0;
9135   u8 v4_address_set = 0;
9136   u8 v6_address_set = 0;
9137   ip4_address_t v4address;
9138   ip6_address_t v6address;
9139   int ret;
9140
9141   memset (mac_address, 0, sizeof (mac_address));
9142
9143   /* Parse args required to build the message */
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9147         {
9148           mac_set = 1;
9149         }
9150       else if (unformat (i, "del"))
9151         is_add = 0;
9152       else
9153         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9154         sw_if_index_set = 1;
9155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "is_static"))
9158         is_static = 1;
9159       else if (unformat (i, "no-fib-entry"))
9160         is_no_fib_entry = 1;
9161       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9162         v4_address_set = 1;
9163       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9164         v6_address_set = 1;
9165       else
9166         {
9167           clib_warning ("parse error '%U'", format_unformat_error, i);
9168           return -99;
9169         }
9170     }
9171
9172   if (sw_if_index_set == 0)
9173     {
9174       errmsg ("missing interface name or sw_if_index");
9175       return -99;
9176     }
9177   if (v4_address_set && v6_address_set)
9178     {
9179       errmsg ("both v4 and v6 addresses set");
9180       return -99;
9181     }
9182   if (!v4_address_set && !v6_address_set)
9183     {
9184       errmsg ("no address set");
9185       return -99;
9186     }
9187
9188   /* Construct the API message */
9189   M (IP_NEIGHBOR_ADD_DEL, mp);
9190
9191   mp->sw_if_index = ntohl (sw_if_index);
9192   mp->is_add = is_add;
9193   mp->is_static = is_static;
9194   mp->is_no_adj_fib = is_no_fib_entry;
9195   if (mac_set)
9196     clib_memcpy (mp->mac_address, mac_address, 6);
9197   if (v6_address_set)
9198     {
9199       mp->is_ipv6 = 1;
9200       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9201     }
9202   else
9203     {
9204       /* mp->is_ipv6 = 0; via memset in M macro above */
9205       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9206     }
9207
9208   /* send it... */
9209   S (mp);
9210
9211   /* Wait for a reply, return good/bad news  */
9212   W (ret);
9213   return ret;
9214 }
9215
9216 static int
9217 api_create_vlan_subif (vat_main_t * vam)
9218 {
9219   unformat_input_t *i = vam->input;
9220   vl_api_create_vlan_subif_t *mp;
9221   u32 sw_if_index;
9222   u8 sw_if_index_set = 0;
9223   u32 vlan_id;
9224   u8 vlan_id_set = 0;
9225   int ret;
9226
9227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228     {
9229       if (unformat (i, "sw_if_index %d", &sw_if_index))
9230         sw_if_index_set = 1;
9231       else
9232         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9233         sw_if_index_set = 1;
9234       else if (unformat (i, "vlan %d", &vlan_id))
9235         vlan_id_set = 1;
9236       else
9237         {
9238           clib_warning ("parse error '%U'", format_unformat_error, i);
9239           return -99;
9240         }
9241     }
9242
9243   if (sw_if_index_set == 0)
9244     {
9245       errmsg ("missing interface name or sw_if_index");
9246       return -99;
9247     }
9248
9249   if (vlan_id_set == 0)
9250     {
9251       errmsg ("missing vlan_id");
9252       return -99;
9253     }
9254   M (CREATE_VLAN_SUBIF, mp);
9255
9256   mp->sw_if_index = ntohl (sw_if_index);
9257   mp->vlan_id = ntohl (vlan_id);
9258
9259   S (mp);
9260   W (ret);
9261   return ret;
9262 }
9263
9264 #define foreach_create_subif_bit                \
9265 _(no_tags)                                      \
9266 _(one_tag)                                      \
9267 _(two_tags)                                     \
9268 _(dot1ad)                                       \
9269 _(exact_match)                                  \
9270 _(default_sub)                                  \
9271 _(outer_vlan_id_any)                            \
9272 _(inner_vlan_id_any)
9273
9274 static int
9275 api_create_subif (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_create_subif_t *mp;
9279   u32 sw_if_index;
9280   u8 sw_if_index_set = 0;
9281   u32 sub_id;
9282   u8 sub_id_set = 0;
9283   u32 no_tags = 0;
9284   u32 one_tag = 0;
9285   u32 two_tags = 0;
9286   u32 dot1ad = 0;
9287   u32 exact_match = 0;
9288   u32 default_sub = 0;
9289   u32 outer_vlan_id_any = 0;
9290   u32 inner_vlan_id_any = 0;
9291   u32 tmp;
9292   u16 outer_vlan_id = 0;
9293   u16 inner_vlan_id = 0;
9294   int ret;
9295
9296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9297     {
9298       if (unformat (i, "sw_if_index %d", &sw_if_index))
9299         sw_if_index_set = 1;
9300       else
9301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9302         sw_if_index_set = 1;
9303       else if (unformat (i, "sub_id %d", &sub_id))
9304         sub_id_set = 1;
9305       else if (unformat (i, "outer_vlan_id %d", &tmp))
9306         outer_vlan_id = tmp;
9307       else if (unformat (i, "inner_vlan_id %d", &tmp))
9308         inner_vlan_id = tmp;
9309
9310 #define _(a) else if (unformat (i, #a)) a = 1 ;
9311       foreach_create_subif_bit
9312 #undef _
9313         else
9314         {
9315           clib_warning ("parse error '%U'", format_unformat_error, i);
9316           return -99;
9317         }
9318     }
9319
9320   if (sw_if_index_set == 0)
9321     {
9322       errmsg ("missing interface name or sw_if_index");
9323       return -99;
9324     }
9325
9326   if (sub_id_set == 0)
9327     {
9328       errmsg ("missing sub_id");
9329       return -99;
9330     }
9331   M (CREATE_SUBIF, mp);
9332
9333   mp->sw_if_index = ntohl (sw_if_index);
9334   mp->sub_id = ntohl (sub_id);
9335
9336 #define _(a) mp->a = a;
9337   foreach_create_subif_bit;
9338 #undef _
9339
9340   mp->outer_vlan_id = ntohs (outer_vlan_id);
9341   mp->inner_vlan_id = ntohs (inner_vlan_id);
9342
9343   S (mp);
9344   W (ret);
9345   return ret;
9346 }
9347
9348 static int
9349 api_oam_add_del (vat_main_t * vam)
9350 {
9351   unformat_input_t *i = vam->input;
9352   vl_api_oam_add_del_t *mp;
9353   u32 vrf_id = 0;
9354   u8 is_add = 1;
9355   ip4_address_t src, dst;
9356   u8 src_set = 0;
9357   u8 dst_set = 0;
9358   int ret;
9359
9360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (i, "vrf %d", &vrf_id))
9363         ;
9364       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9365         src_set = 1;
9366       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9367         dst_set = 1;
9368       else if (unformat (i, "del"))
9369         is_add = 0;
9370       else
9371         {
9372           clib_warning ("parse error '%U'", format_unformat_error, i);
9373           return -99;
9374         }
9375     }
9376
9377   if (src_set == 0)
9378     {
9379       errmsg ("missing src addr");
9380       return -99;
9381     }
9382
9383   if (dst_set == 0)
9384     {
9385       errmsg ("missing dst addr");
9386       return -99;
9387     }
9388
9389   M (OAM_ADD_DEL, mp);
9390
9391   mp->vrf_id = ntohl (vrf_id);
9392   mp->is_add = is_add;
9393   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9394   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9395
9396   S (mp);
9397   W (ret);
9398   return ret;
9399 }
9400
9401 static int
9402 api_reset_fib (vat_main_t * vam)
9403 {
9404   unformat_input_t *i = vam->input;
9405   vl_api_reset_fib_t *mp;
9406   u32 vrf_id = 0;
9407   u8 is_ipv6 = 0;
9408   u8 vrf_id_set = 0;
9409
9410   int ret;
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "vrf %d", &vrf_id))
9414         vrf_id_set = 1;
9415       else if (unformat (i, "ipv6"))
9416         is_ipv6 = 1;
9417       else
9418         {
9419           clib_warning ("parse error '%U'", format_unformat_error, i);
9420           return -99;
9421         }
9422     }
9423
9424   if (vrf_id_set == 0)
9425     {
9426       errmsg ("missing vrf id");
9427       return -99;
9428     }
9429
9430   M (RESET_FIB, mp);
9431
9432   mp->vrf_id = ntohl (vrf_id);
9433   mp->is_ipv6 = is_ipv6;
9434
9435   S (mp);
9436   W (ret);
9437   return ret;
9438 }
9439
9440 static int
9441 api_dhcp_proxy_config (vat_main_t * vam)
9442 {
9443   unformat_input_t *i = vam->input;
9444   vl_api_dhcp_proxy_config_t *mp;
9445   u32 rx_vrf_id = 0;
9446   u32 server_vrf_id = 0;
9447   u8 is_add = 1;
9448   u8 v4_address_set = 0;
9449   u8 v6_address_set = 0;
9450   ip4_address_t v4address;
9451   ip6_address_t v6address;
9452   u8 v4_src_address_set = 0;
9453   u8 v6_src_address_set = 0;
9454   ip4_address_t v4srcaddress;
9455   ip6_address_t v6srcaddress;
9456   int ret;
9457
9458   /* Parse args required to build the message */
9459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (unformat (i, "del"))
9462         is_add = 0;
9463       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9464         ;
9465       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9466         ;
9467       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9468         v4_address_set = 1;
9469       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9470         v6_address_set = 1;
9471       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9472         v4_src_address_set = 1;
9473       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9474         v6_src_address_set = 1;
9475       else
9476         break;
9477     }
9478
9479   if (v4_address_set && v6_address_set)
9480     {
9481       errmsg ("both v4 and v6 server addresses set");
9482       return -99;
9483     }
9484   if (!v4_address_set && !v6_address_set)
9485     {
9486       errmsg ("no server addresses set");
9487       return -99;
9488     }
9489
9490   if (v4_src_address_set && v6_src_address_set)
9491     {
9492       errmsg ("both v4 and v6  src addresses set");
9493       return -99;
9494     }
9495   if (!v4_src_address_set && !v6_src_address_set)
9496     {
9497       errmsg ("no src addresses set");
9498       return -99;
9499     }
9500
9501   if (!(v4_src_address_set && v4_address_set) &&
9502       !(v6_src_address_set && v6_address_set))
9503     {
9504       errmsg ("no matching server and src addresses set");
9505       return -99;
9506     }
9507
9508   /* Construct the API message */
9509   M (DHCP_PROXY_CONFIG, mp);
9510
9511   mp->is_add = is_add;
9512   mp->rx_vrf_id = ntohl (rx_vrf_id);
9513   mp->server_vrf_id = ntohl (server_vrf_id);
9514   if (v6_address_set)
9515     {
9516       mp->is_ipv6 = 1;
9517       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9518       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9519     }
9520   else
9521     {
9522       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9523       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9524     }
9525
9526   /* send it... */
9527   S (mp);
9528
9529   /* Wait for a reply, return good/bad news  */
9530   W (ret);
9531   return ret;
9532 }
9533
9534 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9535 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9536
9537 static void
9538 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9539 {
9540   vat_main_t *vam = &vat_main;
9541   u32 i, count = mp->count;
9542   vl_api_dhcp_server_t *s;
9543
9544   if (mp->is_ipv6)
9545     print (vam->ofp,
9546            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9547            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9548            ntohl (mp->rx_vrf_id),
9549            format_ip6_address, mp->dhcp_src_address,
9550            mp->vss_type, mp->vss_vpn_ascii_id,
9551            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9552   else
9553     print (vam->ofp,
9554            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9555            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9556            ntohl (mp->rx_vrf_id),
9557            format_ip4_address, mp->dhcp_src_address,
9558            mp->vss_type, mp->vss_vpn_ascii_id,
9559            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9560
9561   for (i = 0; i < count; i++)
9562     {
9563       s = &mp->servers[i];
9564
9565       if (mp->is_ipv6)
9566         print (vam->ofp,
9567                " Server Table-ID %d, Server Address %U",
9568                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9569       else
9570         print (vam->ofp,
9571                " Server Table-ID %d, Server Address %U",
9572                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9573     }
9574 }
9575
9576 static void vl_api_dhcp_proxy_details_t_handler_json
9577   (vl_api_dhcp_proxy_details_t * mp)
9578 {
9579   vat_main_t *vam = &vat_main;
9580   vat_json_node_t *node = NULL;
9581   u32 i, count = mp->count;
9582   struct in_addr ip4;
9583   struct in6_addr ip6;
9584   vl_api_dhcp_server_t *s;
9585
9586   if (VAT_JSON_ARRAY != vam->json_tree.type)
9587     {
9588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9589       vat_json_init_array (&vam->json_tree);
9590     }
9591   node = vat_json_array_add (&vam->json_tree);
9592
9593   vat_json_init_object (node);
9594   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9595   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9596                              sizeof (mp->vss_type));
9597   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9598                                    mp->vss_vpn_ascii_id);
9599   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9600   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9601
9602   if (mp->is_ipv6)
9603     {
9604       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9605       vat_json_object_add_ip6 (node, "src_address", ip6);
9606     }
9607   else
9608     {
9609       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9610       vat_json_object_add_ip4 (node, "src_address", ip4);
9611     }
9612
9613   for (i = 0; i < count; i++)
9614     {
9615       s = &mp->servers[i];
9616
9617       vat_json_object_add_uint (node, "server-table-id",
9618                                 ntohl (s->server_vrf_id));
9619
9620       if (mp->is_ipv6)
9621         {
9622           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9623           vat_json_object_add_ip4 (node, "src_address", ip4);
9624         }
9625       else
9626         {
9627           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9628           vat_json_object_add_ip6 (node, "server_address", ip6);
9629         }
9630     }
9631 }
9632
9633 static int
9634 api_dhcp_proxy_dump (vat_main_t * vam)
9635 {
9636   unformat_input_t *i = vam->input;
9637   vl_api_control_ping_t *mp_ping;
9638   vl_api_dhcp_proxy_dump_t *mp;
9639   u8 is_ipv6 = 0;
9640   int ret;
9641
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "ipv6"))
9645         is_ipv6 = 1;
9646       else
9647         {
9648           clib_warning ("parse error '%U'", format_unformat_error, i);
9649           return -99;
9650         }
9651     }
9652
9653   M (DHCP_PROXY_DUMP, mp);
9654
9655   mp->is_ip6 = is_ipv6;
9656   S (mp);
9657
9658   /* Use a control ping for synchronization */
9659   MPING (CONTROL_PING, mp_ping);
9660   S (mp_ping);
9661
9662   W (ret);
9663   return ret;
9664 }
9665
9666 static int
9667 api_dhcp_proxy_set_vss (vat_main_t * vam)
9668 {
9669   unformat_input_t *i = vam->input;
9670   vl_api_dhcp_proxy_set_vss_t *mp;
9671   u8 is_ipv6 = 0;
9672   u8 is_add = 1;
9673   u32 tbl_id = ~0;
9674   u8 vss_type = VSS_TYPE_DEFAULT;
9675   u8 *vpn_ascii_id = 0;
9676   u32 oui = 0;
9677   u32 fib_id = 0;
9678   int ret;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "tbl_id %d", &tbl_id))
9683         ;
9684       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9685         vss_type = VSS_TYPE_ASCII;
9686       else if (unformat (i, "fib_id %d", &fib_id))
9687         vss_type = VSS_TYPE_VPN_ID;
9688       else if (unformat (i, "oui %d", &oui))
9689         vss_type = VSS_TYPE_VPN_ID;
9690       else if (unformat (i, "ipv6"))
9691         is_ipv6 = 1;
9692       else if (unformat (i, "del"))
9693         is_add = 0;
9694       else
9695         break;
9696     }
9697
9698   if (tbl_id == ~0)
9699     {
9700       errmsg ("missing tbl_id ");
9701       vec_free (vpn_ascii_id);
9702       return -99;
9703     }
9704
9705   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9706     {
9707       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9708       vec_free (vpn_ascii_id);
9709       return -99;
9710     }
9711
9712   M (DHCP_PROXY_SET_VSS, mp);
9713   mp->tbl_id = ntohl (tbl_id);
9714   mp->vss_type = vss_type;
9715   if (vpn_ascii_id)
9716     {
9717       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9718       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9719     }
9720   mp->vpn_index = ntohl (fib_id);
9721   mp->oui = ntohl (oui);
9722   mp->is_ipv6 = is_ipv6;
9723   mp->is_add = is_add;
9724
9725   S (mp);
9726   W (ret);
9727
9728   vec_free (vpn_ascii_id);
9729   return ret;
9730 }
9731
9732 static int
9733 api_dhcp_client_config (vat_main_t * vam)
9734 {
9735   unformat_input_t *i = vam->input;
9736   vl_api_dhcp_client_config_t *mp;
9737   u32 sw_if_index;
9738   u8 sw_if_index_set = 0;
9739   u8 is_add = 1;
9740   u8 *hostname = 0;
9741   u8 disable_event = 0;
9742   int ret;
9743
9744   /* Parse args required to build the message */
9745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9746     {
9747       if (unformat (i, "del"))
9748         is_add = 0;
9749       else
9750         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9751         sw_if_index_set = 1;
9752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9753         sw_if_index_set = 1;
9754       else if (unformat (i, "hostname %s", &hostname))
9755         ;
9756       else if (unformat (i, "disable_event"))
9757         disable_event = 1;
9758       else
9759         break;
9760     }
9761
9762   if (sw_if_index_set == 0)
9763     {
9764       errmsg ("missing interface name or sw_if_index");
9765       return -99;
9766     }
9767
9768   if (vec_len (hostname) > 63)
9769     {
9770       errmsg ("hostname too long");
9771     }
9772   vec_add1 (hostname, 0);
9773
9774   /* Construct the API message */
9775   M (DHCP_CLIENT_CONFIG, mp);
9776
9777   mp->sw_if_index = htonl (sw_if_index);
9778   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9779   vec_free (hostname);
9780   mp->is_add = is_add;
9781   mp->want_dhcp_event = disable_event ? 0 : 1;
9782   mp->pid = htonl (getpid ());
9783
9784   /* send it... */
9785   S (mp);
9786
9787   /* Wait for a reply, return good/bad news  */
9788   W (ret);
9789   return ret;
9790 }
9791
9792 static int
9793 api_set_ip_flow_hash (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_set_ip_flow_hash_t *mp;
9797   u32 vrf_id = 0;
9798   u8 is_ipv6 = 0;
9799   u8 vrf_id_set = 0;
9800   u8 src = 0;
9801   u8 dst = 0;
9802   u8 sport = 0;
9803   u8 dport = 0;
9804   u8 proto = 0;
9805   u8 reverse = 0;
9806   int ret;
9807
9808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9809     {
9810       if (unformat (i, "vrf %d", &vrf_id))
9811         vrf_id_set = 1;
9812       else if (unformat (i, "ipv6"))
9813         is_ipv6 = 1;
9814       else if (unformat (i, "src"))
9815         src = 1;
9816       else if (unformat (i, "dst"))
9817         dst = 1;
9818       else if (unformat (i, "sport"))
9819         sport = 1;
9820       else if (unformat (i, "dport"))
9821         dport = 1;
9822       else if (unformat (i, "proto"))
9823         proto = 1;
9824       else if (unformat (i, "reverse"))
9825         reverse = 1;
9826
9827       else
9828         {
9829           clib_warning ("parse error '%U'", format_unformat_error, i);
9830           return -99;
9831         }
9832     }
9833
9834   if (vrf_id_set == 0)
9835     {
9836       errmsg ("missing vrf id");
9837       return -99;
9838     }
9839
9840   M (SET_IP_FLOW_HASH, mp);
9841   mp->src = src;
9842   mp->dst = dst;
9843   mp->sport = sport;
9844   mp->dport = dport;
9845   mp->proto = proto;
9846   mp->reverse = reverse;
9847   mp->vrf_id = ntohl (vrf_id);
9848   mp->is_ipv6 = is_ipv6;
9849
9850   S (mp);
9851   W (ret);
9852   return ret;
9853 }
9854
9855 static int
9856 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9857 {
9858   unformat_input_t *i = vam->input;
9859   vl_api_sw_interface_ip6_enable_disable_t *mp;
9860   u32 sw_if_index;
9861   u8 sw_if_index_set = 0;
9862   u8 enable = 0;
9863   int ret;
9864
9865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9866     {
9867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9868         sw_if_index_set = 1;
9869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "enable"))
9872         enable = 1;
9873       else if (unformat (i, "disable"))
9874         enable = 0;
9875       else
9876         {
9877           clib_warning ("parse error '%U'", format_unformat_error, i);
9878           return -99;
9879         }
9880     }
9881
9882   if (sw_if_index_set == 0)
9883     {
9884       errmsg ("missing interface name or sw_if_index");
9885       return -99;
9886     }
9887
9888   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9889
9890   mp->sw_if_index = ntohl (sw_if_index);
9891   mp->enable = enable;
9892
9893   S (mp);
9894   W (ret);
9895   return ret;
9896 }
9897
9898 static int
9899 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9903   u32 sw_if_index;
9904   u8 sw_if_index_set = 0;
9905   u8 v6_address_set = 0;
9906   ip6_address_t v6address;
9907   int ret;
9908
9909   /* Parse args required to build the message */
9910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9911     {
9912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9913         sw_if_index_set = 1;
9914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9917         v6_address_set = 1;
9918       else
9919         break;
9920     }
9921
9922   if (sw_if_index_set == 0)
9923     {
9924       errmsg ("missing interface name or sw_if_index");
9925       return -99;
9926     }
9927   if (!v6_address_set)
9928     {
9929       errmsg ("no address set");
9930       return -99;
9931     }
9932
9933   /* Construct the API message */
9934   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9935
9936   mp->sw_if_index = ntohl (sw_if_index);
9937   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9938
9939   /* send it... */
9940   S (mp);
9941
9942   /* Wait for a reply, return good/bad news  */
9943   W (ret);
9944   return ret;
9945 }
9946
9947 static int
9948 api_ip6nd_proxy_add_del (vat_main_t * vam)
9949 {
9950   unformat_input_t *i = vam->input;
9951   vl_api_ip6nd_proxy_add_del_t *mp;
9952   u32 sw_if_index = ~0;
9953   u8 v6_address_set = 0;
9954   ip6_address_t v6address;
9955   u8 is_del = 0;
9956   int ret;
9957
9958   /* Parse args required to build the message */
9959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9960     {
9961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9962         ;
9963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9964         ;
9965       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9966         v6_address_set = 1;
9967       if (unformat (i, "del"))
9968         is_del = 1;
9969       else
9970         {
9971           clib_warning ("parse error '%U'", format_unformat_error, i);
9972           return -99;
9973         }
9974     }
9975
9976   if (sw_if_index == ~0)
9977     {
9978       errmsg ("missing interface name or sw_if_index");
9979       return -99;
9980     }
9981   if (!v6_address_set)
9982     {
9983       errmsg ("no address set");
9984       return -99;
9985     }
9986
9987   /* Construct the API message */
9988   M (IP6ND_PROXY_ADD_DEL, mp);
9989
9990   mp->is_del = is_del;
9991   mp->sw_if_index = ntohl (sw_if_index);
9992   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9993
9994   /* send it... */
9995   S (mp);
9996
9997   /* Wait for a reply, return good/bad news  */
9998   W (ret);
9999   return ret;
10000 }
10001
10002 static int
10003 api_ip6nd_proxy_dump (vat_main_t * vam)
10004 {
10005   vl_api_ip6nd_proxy_dump_t *mp;
10006   vl_api_control_ping_t *mp_ping;
10007   int ret;
10008
10009   M (IP6ND_PROXY_DUMP, mp);
10010
10011   S (mp);
10012
10013   /* Use a control ping for synchronization */
10014   MPING (CONTROL_PING, mp_ping);
10015   S (mp_ping);
10016
10017   W (ret);
10018   return ret;
10019 }
10020
10021 static void vl_api_ip6nd_proxy_details_t_handler
10022   (vl_api_ip6nd_proxy_details_t * mp)
10023 {
10024   vat_main_t *vam = &vat_main;
10025
10026   print (vam->ofp, "host %U sw_if_index %d",
10027          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10028 }
10029
10030 static void vl_api_ip6nd_proxy_details_t_handler_json
10031   (vl_api_ip6nd_proxy_details_t * mp)
10032 {
10033   vat_main_t *vam = &vat_main;
10034   struct in6_addr ip6;
10035   vat_json_node_t *node = NULL;
10036
10037   if (VAT_JSON_ARRAY != vam->json_tree.type)
10038     {
10039       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10040       vat_json_init_array (&vam->json_tree);
10041     }
10042   node = vat_json_array_add (&vam->json_tree);
10043
10044   vat_json_init_object (node);
10045   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10046
10047   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10048   vat_json_object_add_ip6 (node, "host", ip6);
10049 }
10050
10051 static int
10052 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10053 {
10054   unformat_input_t *i = vam->input;
10055   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10056   u32 sw_if_index;
10057   u8 sw_if_index_set = 0;
10058   u32 address_length = 0;
10059   u8 v6_address_set = 0;
10060   ip6_address_t v6address;
10061   u8 use_default = 0;
10062   u8 no_advertise = 0;
10063   u8 off_link = 0;
10064   u8 no_autoconfig = 0;
10065   u8 no_onlink = 0;
10066   u8 is_no = 0;
10067   u32 val_lifetime = 0;
10068   u32 pref_lifetime = 0;
10069   int ret;
10070
10071   /* Parse args required to build the message */
10072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10073     {
10074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10075         sw_if_index_set = 1;
10076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "%U/%d",
10079                          unformat_ip6_address, &v6address, &address_length))
10080         v6_address_set = 1;
10081       else if (unformat (i, "val_life %d", &val_lifetime))
10082         ;
10083       else if (unformat (i, "pref_life %d", &pref_lifetime))
10084         ;
10085       else if (unformat (i, "def"))
10086         use_default = 1;
10087       else if (unformat (i, "noadv"))
10088         no_advertise = 1;
10089       else if (unformat (i, "offl"))
10090         off_link = 1;
10091       else if (unformat (i, "noauto"))
10092         no_autoconfig = 1;
10093       else if (unformat (i, "nolink"))
10094         no_onlink = 1;
10095       else if (unformat (i, "isno"))
10096         is_no = 1;
10097       else
10098         {
10099           clib_warning ("parse error '%U'", format_unformat_error, i);
10100           return -99;
10101         }
10102     }
10103
10104   if (sw_if_index_set == 0)
10105     {
10106       errmsg ("missing interface name or sw_if_index");
10107       return -99;
10108     }
10109   if (!v6_address_set)
10110     {
10111       errmsg ("no address set");
10112       return -99;
10113     }
10114
10115   /* Construct the API message */
10116   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10117
10118   mp->sw_if_index = ntohl (sw_if_index);
10119   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10120   mp->address_length = address_length;
10121   mp->use_default = use_default;
10122   mp->no_advertise = no_advertise;
10123   mp->off_link = off_link;
10124   mp->no_autoconfig = no_autoconfig;
10125   mp->no_onlink = no_onlink;
10126   mp->is_no = is_no;
10127   mp->val_lifetime = ntohl (val_lifetime);
10128   mp->pref_lifetime = ntohl (pref_lifetime);
10129
10130   /* send it... */
10131   S (mp);
10132
10133   /* Wait for a reply, return good/bad news  */
10134   W (ret);
10135   return ret;
10136 }
10137
10138 static int
10139 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10140 {
10141   unformat_input_t *i = vam->input;
10142   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10143   u32 sw_if_index;
10144   u8 sw_if_index_set = 0;
10145   u8 suppress = 0;
10146   u8 managed = 0;
10147   u8 other = 0;
10148   u8 ll_option = 0;
10149   u8 send_unicast = 0;
10150   u8 cease = 0;
10151   u8 is_no = 0;
10152   u8 default_router = 0;
10153   u32 max_interval = 0;
10154   u32 min_interval = 0;
10155   u32 lifetime = 0;
10156   u32 initial_count = 0;
10157   u32 initial_interval = 0;
10158   int ret;
10159
10160
10161   /* Parse args required to build the message */
10162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "maxint %d", &max_interval))
10169         ;
10170       else if (unformat (i, "minint %d", &min_interval))
10171         ;
10172       else if (unformat (i, "life %d", &lifetime))
10173         ;
10174       else if (unformat (i, "count %d", &initial_count))
10175         ;
10176       else if (unformat (i, "interval %d", &initial_interval))
10177         ;
10178       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10179         suppress = 1;
10180       else if (unformat (i, "managed"))
10181         managed = 1;
10182       else if (unformat (i, "other"))
10183         other = 1;
10184       else if (unformat (i, "ll"))
10185         ll_option = 1;
10186       else if (unformat (i, "send"))
10187         send_unicast = 1;
10188       else if (unformat (i, "cease"))
10189         cease = 1;
10190       else if (unformat (i, "isno"))
10191         is_no = 1;
10192       else if (unformat (i, "def"))
10193         default_router = 1;
10194       else
10195         {
10196           clib_warning ("parse error '%U'", format_unformat_error, i);
10197           return -99;
10198         }
10199     }
10200
10201   if (sw_if_index_set == 0)
10202     {
10203       errmsg ("missing interface name or sw_if_index");
10204       return -99;
10205     }
10206
10207   /* Construct the API message */
10208   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10209
10210   mp->sw_if_index = ntohl (sw_if_index);
10211   mp->max_interval = ntohl (max_interval);
10212   mp->min_interval = ntohl (min_interval);
10213   mp->lifetime = ntohl (lifetime);
10214   mp->initial_count = ntohl (initial_count);
10215   mp->initial_interval = ntohl (initial_interval);
10216   mp->suppress = suppress;
10217   mp->managed = managed;
10218   mp->other = other;
10219   mp->ll_option = ll_option;
10220   mp->send_unicast = send_unicast;
10221   mp->cease = cease;
10222   mp->is_no = is_no;
10223   mp->default_router = default_router;
10224
10225   /* send it... */
10226   S (mp);
10227
10228   /* Wait for a reply, return good/bad news  */
10229   W (ret);
10230   return ret;
10231 }
10232
10233 static int
10234 api_set_arp_neighbor_limit (vat_main_t * vam)
10235 {
10236   unformat_input_t *i = vam->input;
10237   vl_api_set_arp_neighbor_limit_t *mp;
10238   u32 arp_nbr_limit;
10239   u8 limit_set = 0;
10240   u8 is_ipv6 = 0;
10241   int ret;
10242
10243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10244     {
10245       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10246         limit_set = 1;
10247       else if (unformat (i, "ipv6"))
10248         is_ipv6 = 1;
10249       else
10250         {
10251           clib_warning ("parse error '%U'", format_unformat_error, i);
10252           return -99;
10253         }
10254     }
10255
10256   if (limit_set == 0)
10257     {
10258       errmsg ("missing limit value");
10259       return -99;
10260     }
10261
10262   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10263
10264   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10265   mp->is_ipv6 = is_ipv6;
10266
10267   S (mp);
10268   W (ret);
10269   return ret;
10270 }
10271
10272 static int
10273 api_l2_patch_add_del (vat_main_t * vam)
10274 {
10275   unformat_input_t *i = vam->input;
10276   vl_api_l2_patch_add_del_t *mp;
10277   u32 rx_sw_if_index;
10278   u8 rx_sw_if_index_set = 0;
10279   u32 tx_sw_if_index;
10280   u8 tx_sw_if_index_set = 0;
10281   u8 is_add = 1;
10282   int ret;
10283
10284   /* Parse args required to build the message */
10285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10288         rx_sw_if_index_set = 1;
10289       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10290         tx_sw_if_index_set = 1;
10291       else if (unformat (i, "rx"))
10292         {
10293           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10294             {
10295               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10296                             &rx_sw_if_index))
10297                 rx_sw_if_index_set = 1;
10298             }
10299           else
10300             break;
10301         }
10302       else if (unformat (i, "tx"))
10303         {
10304           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10305             {
10306               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10307                             &tx_sw_if_index))
10308                 tx_sw_if_index_set = 1;
10309             }
10310           else
10311             break;
10312         }
10313       else if (unformat (i, "del"))
10314         is_add = 0;
10315       else
10316         break;
10317     }
10318
10319   if (rx_sw_if_index_set == 0)
10320     {
10321       errmsg ("missing rx interface name or rx_sw_if_index");
10322       return -99;
10323     }
10324
10325   if (tx_sw_if_index_set == 0)
10326     {
10327       errmsg ("missing tx interface name or tx_sw_if_index");
10328       return -99;
10329     }
10330
10331   M (L2_PATCH_ADD_DEL, mp);
10332
10333   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10334   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10335   mp->is_add = is_add;
10336
10337   S (mp);
10338   W (ret);
10339   return ret;
10340 }
10341
10342 u8 is_del;
10343 u8 localsid_addr[16];
10344 u8 end_psp;
10345 u8 behavior;
10346 u32 sw_if_index;
10347 u32 vlan_index;
10348 u32 fib_table;
10349 u8 nh_addr[16];
10350
10351 static int
10352 api_sr_localsid_add_del (vat_main_t * vam)
10353 {
10354   unformat_input_t *i = vam->input;
10355   vl_api_sr_localsid_add_del_t *mp;
10356
10357   u8 is_del;
10358   ip6_address_t localsid;
10359   u8 end_psp = 0;
10360   u8 behavior = ~0;
10361   u32 sw_if_index;
10362   u32 fib_table = ~(u32) 0;
10363   ip6_address_t next_hop;
10364
10365   bool nexthop_set = 0;
10366
10367   int ret;
10368
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "del"))
10372         is_del = 1;
10373       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10374       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10375         nexthop_set = 1;
10376       else if (unformat (i, "behavior %u", &behavior));
10377       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10378       else if (unformat (i, "fib-table %u", &fib_table));
10379       else if (unformat (i, "end.psp %u", &behavior));
10380       else
10381         break;
10382     }
10383
10384   M (SR_LOCALSID_ADD_DEL, mp);
10385
10386   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10387   if (nexthop_set)
10388     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10389   mp->behavior = behavior;
10390   mp->sw_if_index = ntohl (sw_if_index);
10391   mp->fib_table = ntohl (fib_table);
10392   mp->end_psp = end_psp;
10393   mp->is_del = is_del;
10394
10395   S (mp);
10396   W (ret);
10397   return ret;
10398 }
10399
10400 static int
10401 api_ioam_enable (vat_main_t * vam)
10402 {
10403   unformat_input_t *input = vam->input;
10404   vl_api_ioam_enable_t *mp;
10405   u32 id = 0;
10406   int has_trace_option = 0;
10407   int has_pot_option = 0;
10408   int has_seqno_option = 0;
10409   int has_analyse_option = 0;
10410   int ret;
10411
10412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10413     {
10414       if (unformat (input, "trace"))
10415         has_trace_option = 1;
10416       else if (unformat (input, "pot"))
10417         has_pot_option = 1;
10418       else if (unformat (input, "seqno"))
10419         has_seqno_option = 1;
10420       else if (unformat (input, "analyse"))
10421         has_analyse_option = 1;
10422       else
10423         break;
10424     }
10425   M (IOAM_ENABLE, mp);
10426   mp->id = htons (id);
10427   mp->seqno = has_seqno_option;
10428   mp->analyse = has_analyse_option;
10429   mp->pot_enable = has_pot_option;
10430   mp->trace_enable = has_trace_option;
10431
10432   S (mp);
10433   W (ret);
10434   return ret;
10435 }
10436
10437
10438 static int
10439 api_ioam_disable (vat_main_t * vam)
10440 {
10441   vl_api_ioam_disable_t *mp;
10442   int ret;
10443
10444   M (IOAM_DISABLE, mp);
10445   S (mp);
10446   W (ret);
10447   return ret;
10448 }
10449
10450 #define foreach_tcp_proto_field                 \
10451 _(src_port)                                     \
10452 _(dst_port)
10453
10454 #define foreach_udp_proto_field                 \
10455 _(src_port)                                     \
10456 _(dst_port)
10457
10458 #define foreach_ip4_proto_field                 \
10459 _(src_address)                                  \
10460 _(dst_address)                                  \
10461 _(tos)                                          \
10462 _(length)                                       \
10463 _(fragment_id)                                  \
10464 _(ttl)                                          \
10465 _(protocol)                                     \
10466 _(checksum)
10467
10468 typedef struct
10469 {
10470   u16 src_port, dst_port;
10471 } tcpudp_header_t;
10472
10473 #if VPP_API_TEST_BUILTIN == 0
10474 uword
10475 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10476 {
10477   u8 **maskp = va_arg (*args, u8 **);
10478   u8 *mask = 0;
10479   u8 found_something = 0;
10480   tcp_header_t *tcp;
10481
10482 #define _(a) u8 a=0;
10483   foreach_tcp_proto_field;
10484 #undef _
10485
10486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10487     {
10488       if (0);
10489 #define _(a) else if (unformat (input, #a)) a=1;
10490       foreach_tcp_proto_field
10491 #undef _
10492         else
10493         break;
10494     }
10495
10496 #define _(a) found_something += a;
10497   foreach_tcp_proto_field;
10498 #undef _
10499
10500   if (found_something == 0)
10501     return 0;
10502
10503   vec_validate (mask, sizeof (*tcp) - 1);
10504
10505   tcp = (tcp_header_t *) mask;
10506
10507 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10508   foreach_tcp_proto_field;
10509 #undef _
10510
10511   *maskp = mask;
10512   return 1;
10513 }
10514
10515 uword
10516 unformat_udp_mask (unformat_input_t * input, va_list * args)
10517 {
10518   u8 **maskp = va_arg (*args, u8 **);
10519   u8 *mask = 0;
10520   u8 found_something = 0;
10521   udp_header_t *udp;
10522
10523 #define _(a) u8 a=0;
10524   foreach_udp_proto_field;
10525 #undef _
10526
10527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10528     {
10529       if (0);
10530 #define _(a) else if (unformat (input, #a)) a=1;
10531       foreach_udp_proto_field
10532 #undef _
10533         else
10534         break;
10535     }
10536
10537 #define _(a) found_something += a;
10538   foreach_udp_proto_field;
10539 #undef _
10540
10541   if (found_something == 0)
10542     return 0;
10543
10544   vec_validate (mask, sizeof (*udp) - 1);
10545
10546   udp = (udp_header_t *) mask;
10547
10548 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10549   foreach_udp_proto_field;
10550 #undef _
10551
10552   *maskp = mask;
10553   return 1;
10554 }
10555
10556 uword
10557 unformat_l4_mask (unformat_input_t * input, va_list * args)
10558 {
10559   u8 **maskp = va_arg (*args, u8 **);
10560   u16 src_port = 0, dst_port = 0;
10561   tcpudp_header_t *tcpudp;
10562
10563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10564     {
10565       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10566         return 1;
10567       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10568         return 1;
10569       else if (unformat (input, "src_port"))
10570         src_port = 0xFFFF;
10571       else if (unformat (input, "dst_port"))
10572         dst_port = 0xFFFF;
10573       else
10574         return 0;
10575     }
10576
10577   if (!src_port && !dst_port)
10578     return 0;
10579
10580   u8 *mask = 0;
10581   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10582
10583   tcpudp = (tcpudp_header_t *) mask;
10584   tcpudp->src_port = src_port;
10585   tcpudp->dst_port = dst_port;
10586
10587   *maskp = mask;
10588
10589   return 1;
10590 }
10591
10592 uword
10593 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10594 {
10595   u8 **maskp = va_arg (*args, u8 **);
10596   u8 *mask = 0;
10597   u8 found_something = 0;
10598   ip4_header_t *ip;
10599
10600 #define _(a) u8 a=0;
10601   foreach_ip4_proto_field;
10602 #undef _
10603   u8 version = 0;
10604   u8 hdr_length = 0;
10605
10606
10607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10608     {
10609       if (unformat (input, "version"))
10610         version = 1;
10611       else if (unformat (input, "hdr_length"))
10612         hdr_length = 1;
10613       else if (unformat (input, "src"))
10614         src_address = 1;
10615       else if (unformat (input, "dst"))
10616         dst_address = 1;
10617       else if (unformat (input, "proto"))
10618         protocol = 1;
10619
10620 #define _(a) else if (unformat (input, #a)) a=1;
10621       foreach_ip4_proto_field
10622 #undef _
10623         else
10624         break;
10625     }
10626
10627 #define _(a) found_something += a;
10628   foreach_ip4_proto_field;
10629 #undef _
10630
10631   if (found_something == 0)
10632     return 0;
10633
10634   vec_validate (mask, sizeof (*ip) - 1);
10635
10636   ip = (ip4_header_t *) mask;
10637
10638 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10639   foreach_ip4_proto_field;
10640 #undef _
10641
10642   ip->ip_version_and_header_length = 0;
10643
10644   if (version)
10645     ip->ip_version_and_header_length |= 0xF0;
10646
10647   if (hdr_length)
10648     ip->ip_version_and_header_length |= 0x0F;
10649
10650   *maskp = mask;
10651   return 1;
10652 }
10653
10654 #define foreach_ip6_proto_field                 \
10655 _(src_address)                                  \
10656 _(dst_address)                                  \
10657 _(payload_length)                               \
10658 _(hop_limit)                                    \
10659 _(protocol)
10660
10661 uword
10662 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10663 {
10664   u8 **maskp = va_arg (*args, u8 **);
10665   u8 *mask = 0;
10666   u8 found_something = 0;
10667   ip6_header_t *ip;
10668   u32 ip_version_traffic_class_and_flow_label;
10669
10670 #define _(a) u8 a=0;
10671   foreach_ip6_proto_field;
10672 #undef _
10673   u8 version = 0;
10674   u8 traffic_class = 0;
10675   u8 flow_label = 0;
10676
10677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (input, "version"))
10680         version = 1;
10681       else if (unformat (input, "traffic-class"))
10682         traffic_class = 1;
10683       else if (unformat (input, "flow-label"))
10684         flow_label = 1;
10685       else if (unformat (input, "src"))
10686         src_address = 1;
10687       else if (unformat (input, "dst"))
10688         dst_address = 1;
10689       else if (unformat (input, "proto"))
10690         protocol = 1;
10691
10692 #define _(a) else if (unformat (input, #a)) a=1;
10693       foreach_ip6_proto_field
10694 #undef _
10695         else
10696         break;
10697     }
10698
10699 #define _(a) found_something += a;
10700   foreach_ip6_proto_field;
10701 #undef _
10702
10703   if (found_something == 0)
10704     return 0;
10705
10706   vec_validate (mask, sizeof (*ip) - 1);
10707
10708   ip = (ip6_header_t *) mask;
10709
10710 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10711   foreach_ip6_proto_field;
10712 #undef _
10713
10714   ip_version_traffic_class_and_flow_label = 0;
10715
10716   if (version)
10717     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10718
10719   if (traffic_class)
10720     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10721
10722   if (flow_label)
10723     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10724
10725   ip->ip_version_traffic_class_and_flow_label =
10726     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10727
10728   *maskp = mask;
10729   return 1;
10730 }
10731
10732 uword
10733 unformat_l3_mask (unformat_input_t * input, va_list * args)
10734 {
10735   u8 **maskp = va_arg (*args, u8 **);
10736
10737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10738     {
10739       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10740         return 1;
10741       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10742         return 1;
10743       else
10744         break;
10745     }
10746   return 0;
10747 }
10748
10749 uword
10750 unformat_l2_mask (unformat_input_t * input, va_list * args)
10751 {
10752   u8 **maskp = va_arg (*args, u8 **);
10753   u8 *mask = 0;
10754   u8 src = 0;
10755   u8 dst = 0;
10756   u8 proto = 0;
10757   u8 tag1 = 0;
10758   u8 tag2 = 0;
10759   u8 ignore_tag1 = 0;
10760   u8 ignore_tag2 = 0;
10761   u8 cos1 = 0;
10762   u8 cos2 = 0;
10763   u8 dot1q = 0;
10764   u8 dot1ad = 0;
10765   int len = 14;
10766
10767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10768     {
10769       if (unformat (input, "src"))
10770         src = 1;
10771       else if (unformat (input, "dst"))
10772         dst = 1;
10773       else if (unformat (input, "proto"))
10774         proto = 1;
10775       else if (unformat (input, "tag1"))
10776         tag1 = 1;
10777       else if (unformat (input, "tag2"))
10778         tag2 = 1;
10779       else if (unformat (input, "ignore-tag1"))
10780         ignore_tag1 = 1;
10781       else if (unformat (input, "ignore-tag2"))
10782         ignore_tag2 = 1;
10783       else if (unformat (input, "cos1"))
10784         cos1 = 1;
10785       else if (unformat (input, "cos2"))
10786         cos2 = 1;
10787       else if (unformat (input, "dot1q"))
10788         dot1q = 1;
10789       else if (unformat (input, "dot1ad"))
10790         dot1ad = 1;
10791       else
10792         break;
10793     }
10794   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10795        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10796     return 0;
10797
10798   if (tag1 || ignore_tag1 || cos1 || dot1q)
10799     len = 18;
10800   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10801     len = 22;
10802
10803   vec_validate (mask, len - 1);
10804
10805   if (dst)
10806     memset (mask, 0xff, 6);
10807
10808   if (src)
10809     memset (mask + 6, 0xff, 6);
10810
10811   if (tag2 || dot1ad)
10812     {
10813       /* inner vlan tag */
10814       if (tag2)
10815         {
10816           mask[19] = 0xff;
10817           mask[18] = 0x0f;
10818         }
10819       if (cos2)
10820         mask[18] |= 0xe0;
10821       if (proto)
10822         mask[21] = mask[20] = 0xff;
10823       if (tag1)
10824         {
10825           mask[15] = 0xff;
10826           mask[14] = 0x0f;
10827         }
10828       if (cos1)
10829         mask[14] |= 0xe0;
10830       *maskp = mask;
10831       return 1;
10832     }
10833   if (tag1 | dot1q)
10834     {
10835       if (tag1)
10836         {
10837           mask[15] = 0xff;
10838           mask[14] = 0x0f;
10839         }
10840       if (cos1)
10841         mask[14] |= 0xe0;
10842       if (proto)
10843         mask[16] = mask[17] = 0xff;
10844
10845       *maskp = mask;
10846       return 1;
10847     }
10848   if (cos2)
10849     mask[18] |= 0xe0;
10850   if (cos1)
10851     mask[14] |= 0xe0;
10852   if (proto)
10853     mask[12] = mask[13] = 0xff;
10854
10855   *maskp = mask;
10856   return 1;
10857 }
10858
10859 uword
10860 unformat_classify_mask (unformat_input_t * input, va_list * args)
10861 {
10862   u8 **maskp = va_arg (*args, u8 **);
10863   u32 *skipp = va_arg (*args, u32 *);
10864   u32 *matchp = va_arg (*args, u32 *);
10865   u32 match;
10866   u8 *mask = 0;
10867   u8 *l2 = 0;
10868   u8 *l3 = 0;
10869   u8 *l4 = 0;
10870   int i;
10871
10872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10873     {
10874       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10875         ;
10876       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10877         ;
10878       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10879         ;
10880       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10881         ;
10882       else
10883         break;
10884     }
10885
10886   if (l4 && !l3)
10887     {
10888       vec_free (mask);
10889       vec_free (l2);
10890       vec_free (l4);
10891       return 0;
10892     }
10893
10894   if (mask || l2 || l3 || l4)
10895     {
10896       if (l2 || l3 || l4)
10897         {
10898           /* "With a free Ethernet header in every package" */
10899           if (l2 == 0)
10900             vec_validate (l2, 13);
10901           mask = l2;
10902           if (vec_len (l3))
10903             {
10904               vec_append (mask, l3);
10905               vec_free (l3);
10906             }
10907           if (vec_len (l4))
10908             {
10909               vec_append (mask, l4);
10910               vec_free (l4);
10911             }
10912         }
10913
10914       /* Scan forward looking for the first significant mask octet */
10915       for (i = 0; i < vec_len (mask); i++)
10916         if (mask[i])
10917           break;
10918
10919       /* compute (skip, match) params */
10920       *skipp = i / sizeof (u32x4);
10921       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10922
10923       /* Pad mask to an even multiple of the vector size */
10924       while (vec_len (mask) % sizeof (u32x4))
10925         vec_add1 (mask, 0);
10926
10927       match = vec_len (mask) / sizeof (u32x4);
10928
10929       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10930         {
10931           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10932           if (*tmp || *(tmp + 1))
10933             break;
10934           match--;
10935         }
10936       if (match == 0)
10937         clib_warning ("BUG: match 0");
10938
10939       _vec_len (mask) = match * sizeof (u32x4);
10940
10941       *matchp = match;
10942       *maskp = mask;
10943
10944       return 1;
10945     }
10946
10947   return 0;
10948 }
10949 #endif /* VPP_API_TEST_BUILTIN */
10950
10951 #define foreach_l2_next                         \
10952 _(drop, DROP)                                   \
10953 _(ethernet, ETHERNET_INPUT)                     \
10954 _(ip4, IP4_INPUT)                               \
10955 _(ip6, IP6_INPUT)
10956
10957 uword
10958 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10959 {
10960   u32 *miss_next_indexp = va_arg (*args, u32 *);
10961   u32 next_index = 0;
10962   u32 tmp;
10963
10964 #define _(n,N) \
10965   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10966   foreach_l2_next;
10967 #undef _
10968
10969   if (unformat (input, "%d", &tmp))
10970     {
10971       next_index = tmp;
10972       goto out;
10973     }
10974
10975   return 0;
10976
10977 out:
10978   *miss_next_indexp = next_index;
10979   return 1;
10980 }
10981
10982 #define foreach_ip_next                         \
10983 _(drop, DROP)                                   \
10984 _(local, LOCAL)                                 \
10985 _(rewrite, REWRITE)
10986
10987 uword
10988 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10989 {
10990   u32 *miss_next_indexp = va_arg (*args, u32 *);
10991   u32 next_index = 0;
10992   u32 tmp;
10993
10994 #define _(n,N) \
10995   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10996   foreach_ip_next;
10997 #undef _
10998
10999   if (unformat (input, "%d", &tmp))
11000     {
11001       next_index = tmp;
11002       goto out;
11003     }
11004
11005   return 0;
11006
11007 out:
11008   *miss_next_indexp = next_index;
11009   return 1;
11010 }
11011
11012 #define foreach_acl_next                        \
11013 _(deny, DENY)
11014
11015 uword
11016 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11017 {
11018   u32 *miss_next_indexp = va_arg (*args, u32 *);
11019   u32 next_index = 0;
11020   u32 tmp;
11021
11022 #define _(n,N) \
11023   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11024   foreach_acl_next;
11025 #undef _
11026
11027   if (unformat (input, "permit"))
11028     {
11029       next_index = ~0;
11030       goto out;
11031     }
11032   else if (unformat (input, "%d", &tmp))
11033     {
11034       next_index = tmp;
11035       goto out;
11036     }
11037
11038   return 0;
11039
11040 out:
11041   *miss_next_indexp = next_index;
11042   return 1;
11043 }
11044
11045 uword
11046 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11047 {
11048   u32 *r = va_arg (*args, u32 *);
11049
11050   if (unformat (input, "conform-color"))
11051     *r = POLICE_CONFORM;
11052   else if (unformat (input, "exceed-color"))
11053     *r = POLICE_EXCEED;
11054   else
11055     return 0;
11056
11057   return 1;
11058 }
11059
11060 static int
11061 api_classify_add_del_table (vat_main_t * vam)
11062 {
11063   unformat_input_t *i = vam->input;
11064   vl_api_classify_add_del_table_t *mp;
11065
11066   u32 nbuckets = 2;
11067   u32 skip = ~0;
11068   u32 match = ~0;
11069   int is_add = 1;
11070   int del_chain = 0;
11071   u32 table_index = ~0;
11072   u32 next_table_index = ~0;
11073   u32 miss_next_index = ~0;
11074   u32 memory_size = 32 << 20;
11075   u8 *mask = 0;
11076   u32 current_data_flag = 0;
11077   int current_data_offset = 0;
11078   int ret;
11079
11080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11081     {
11082       if (unformat (i, "del"))
11083         is_add = 0;
11084       else if (unformat (i, "del-chain"))
11085         {
11086           is_add = 0;
11087           del_chain = 1;
11088         }
11089       else if (unformat (i, "buckets %d", &nbuckets))
11090         ;
11091       else if (unformat (i, "memory_size %d", &memory_size))
11092         ;
11093       else if (unformat (i, "skip %d", &skip))
11094         ;
11095       else if (unformat (i, "match %d", &match))
11096         ;
11097       else if (unformat (i, "table %d", &table_index))
11098         ;
11099       else if (unformat (i, "mask %U", unformat_classify_mask,
11100                          &mask, &skip, &match))
11101         ;
11102       else if (unformat (i, "next-table %d", &next_table_index))
11103         ;
11104       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11105                          &miss_next_index))
11106         ;
11107       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11108                          &miss_next_index))
11109         ;
11110       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11111                          &miss_next_index))
11112         ;
11113       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11114         ;
11115       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11116         ;
11117       else
11118         break;
11119     }
11120
11121   if (is_add && mask == 0)
11122     {
11123       errmsg ("Mask required");
11124       return -99;
11125     }
11126
11127   if (is_add && skip == ~0)
11128     {
11129       errmsg ("skip count required");
11130       return -99;
11131     }
11132
11133   if (is_add && match == ~0)
11134     {
11135       errmsg ("match count required");
11136       return -99;
11137     }
11138
11139   if (!is_add && table_index == ~0)
11140     {
11141       errmsg ("table index required for delete");
11142       return -99;
11143     }
11144
11145   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11146
11147   mp->is_add = is_add;
11148   mp->del_chain = del_chain;
11149   mp->table_index = ntohl (table_index);
11150   mp->nbuckets = ntohl (nbuckets);
11151   mp->memory_size = ntohl (memory_size);
11152   mp->skip_n_vectors = ntohl (skip);
11153   mp->match_n_vectors = ntohl (match);
11154   mp->next_table_index = ntohl (next_table_index);
11155   mp->miss_next_index = ntohl (miss_next_index);
11156   mp->current_data_flag = ntohl (current_data_flag);
11157   mp->current_data_offset = ntohl (current_data_offset);
11158   clib_memcpy (mp->mask, mask, vec_len (mask));
11159
11160   vec_free (mask);
11161
11162   S (mp);
11163   W (ret);
11164   return ret;
11165 }
11166
11167 #if VPP_API_TEST_BUILTIN == 0
11168 uword
11169 unformat_l4_match (unformat_input_t * input, va_list * args)
11170 {
11171   u8 **matchp = va_arg (*args, u8 **);
11172
11173   u8 *proto_header = 0;
11174   int src_port = 0;
11175   int dst_port = 0;
11176
11177   tcpudp_header_t h;
11178
11179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11180     {
11181       if (unformat (input, "src_port %d", &src_port))
11182         ;
11183       else if (unformat (input, "dst_port %d", &dst_port))
11184         ;
11185       else
11186         return 0;
11187     }
11188
11189   h.src_port = clib_host_to_net_u16 (src_port);
11190   h.dst_port = clib_host_to_net_u16 (dst_port);
11191   vec_validate (proto_header, sizeof (h) - 1);
11192   memcpy (proto_header, &h, sizeof (h));
11193
11194   *matchp = proto_header;
11195
11196   return 1;
11197 }
11198
11199 uword
11200 unformat_ip4_match (unformat_input_t * input, va_list * args)
11201 {
11202   u8 **matchp = va_arg (*args, u8 **);
11203   u8 *match = 0;
11204   ip4_header_t *ip;
11205   int version = 0;
11206   u32 version_val;
11207   int hdr_length = 0;
11208   u32 hdr_length_val;
11209   int src = 0, dst = 0;
11210   ip4_address_t src_val, dst_val;
11211   int proto = 0;
11212   u32 proto_val;
11213   int tos = 0;
11214   u32 tos_val;
11215   int length = 0;
11216   u32 length_val;
11217   int fragment_id = 0;
11218   u32 fragment_id_val;
11219   int ttl = 0;
11220   int ttl_val;
11221   int checksum = 0;
11222   u32 checksum_val;
11223
11224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11225     {
11226       if (unformat (input, "version %d", &version_val))
11227         version = 1;
11228       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11229         hdr_length = 1;
11230       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11231         src = 1;
11232       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11233         dst = 1;
11234       else if (unformat (input, "proto %d", &proto_val))
11235         proto = 1;
11236       else if (unformat (input, "tos %d", &tos_val))
11237         tos = 1;
11238       else if (unformat (input, "length %d", &length_val))
11239         length = 1;
11240       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11241         fragment_id = 1;
11242       else if (unformat (input, "ttl %d", &ttl_val))
11243         ttl = 1;
11244       else if (unformat (input, "checksum %d", &checksum_val))
11245         checksum = 1;
11246       else
11247         break;
11248     }
11249
11250   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11251       + ttl + checksum == 0)
11252     return 0;
11253
11254   /*
11255    * Aligned because we use the real comparison functions
11256    */
11257   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11258
11259   ip = (ip4_header_t *) match;
11260
11261   /* These are realistically matched in practice */
11262   if (src)
11263     ip->src_address.as_u32 = src_val.as_u32;
11264
11265   if (dst)
11266     ip->dst_address.as_u32 = dst_val.as_u32;
11267
11268   if (proto)
11269     ip->protocol = proto_val;
11270
11271
11272   /* These are not, but they're included for completeness */
11273   if (version)
11274     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11275
11276   if (hdr_length)
11277     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11278
11279   if (tos)
11280     ip->tos = tos_val;
11281
11282   if (length)
11283     ip->length = clib_host_to_net_u16 (length_val);
11284
11285   if (ttl)
11286     ip->ttl = ttl_val;
11287
11288   if (checksum)
11289     ip->checksum = clib_host_to_net_u16 (checksum_val);
11290
11291   *matchp = match;
11292   return 1;
11293 }
11294
11295 uword
11296 unformat_ip6_match (unformat_input_t * input, va_list * args)
11297 {
11298   u8 **matchp = va_arg (*args, u8 **);
11299   u8 *match = 0;
11300   ip6_header_t *ip;
11301   int version = 0;
11302   u32 version_val;
11303   u8 traffic_class = 0;
11304   u32 traffic_class_val = 0;
11305   u8 flow_label = 0;
11306   u8 flow_label_val;
11307   int src = 0, dst = 0;
11308   ip6_address_t src_val, dst_val;
11309   int proto = 0;
11310   u32 proto_val;
11311   int payload_length = 0;
11312   u32 payload_length_val;
11313   int hop_limit = 0;
11314   int hop_limit_val;
11315   u32 ip_version_traffic_class_and_flow_label;
11316
11317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11318     {
11319       if (unformat (input, "version %d", &version_val))
11320         version = 1;
11321       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11322         traffic_class = 1;
11323       else if (unformat (input, "flow_label %d", &flow_label_val))
11324         flow_label = 1;
11325       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11326         src = 1;
11327       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11328         dst = 1;
11329       else if (unformat (input, "proto %d", &proto_val))
11330         proto = 1;
11331       else if (unformat (input, "payload_length %d", &payload_length_val))
11332         payload_length = 1;
11333       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11334         hop_limit = 1;
11335       else
11336         break;
11337     }
11338
11339   if (version + traffic_class + flow_label + src + dst + proto +
11340       payload_length + hop_limit == 0)
11341     return 0;
11342
11343   /*
11344    * Aligned because we use the real comparison functions
11345    */
11346   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11347
11348   ip = (ip6_header_t *) match;
11349
11350   if (src)
11351     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11352
11353   if (dst)
11354     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11355
11356   if (proto)
11357     ip->protocol = proto_val;
11358
11359   ip_version_traffic_class_and_flow_label = 0;
11360
11361   if (version)
11362     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11363
11364   if (traffic_class)
11365     ip_version_traffic_class_and_flow_label |=
11366       (traffic_class_val & 0xFF) << 20;
11367
11368   if (flow_label)
11369     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11370
11371   ip->ip_version_traffic_class_and_flow_label =
11372     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11373
11374   if (payload_length)
11375     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11376
11377   if (hop_limit)
11378     ip->hop_limit = hop_limit_val;
11379
11380   *matchp = match;
11381   return 1;
11382 }
11383
11384 uword
11385 unformat_l3_match (unformat_input_t * input, va_list * args)
11386 {
11387   u8 **matchp = va_arg (*args, u8 **);
11388
11389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11390     {
11391       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11392         return 1;
11393       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11394         return 1;
11395       else
11396         break;
11397     }
11398   return 0;
11399 }
11400
11401 uword
11402 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11403 {
11404   u8 *tagp = va_arg (*args, u8 *);
11405   u32 tag;
11406
11407   if (unformat (input, "%d", &tag))
11408     {
11409       tagp[0] = (tag >> 8) & 0x0F;
11410       tagp[1] = tag & 0xFF;
11411       return 1;
11412     }
11413
11414   return 0;
11415 }
11416
11417 uword
11418 unformat_l2_match (unformat_input_t * input, va_list * args)
11419 {
11420   u8 **matchp = va_arg (*args, u8 **);
11421   u8 *match = 0;
11422   u8 src = 0;
11423   u8 src_val[6];
11424   u8 dst = 0;
11425   u8 dst_val[6];
11426   u8 proto = 0;
11427   u16 proto_val;
11428   u8 tag1 = 0;
11429   u8 tag1_val[2];
11430   u8 tag2 = 0;
11431   u8 tag2_val[2];
11432   int len = 14;
11433   u8 ignore_tag1 = 0;
11434   u8 ignore_tag2 = 0;
11435   u8 cos1 = 0;
11436   u8 cos2 = 0;
11437   u32 cos1_val = 0;
11438   u32 cos2_val = 0;
11439
11440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11441     {
11442       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11443         src = 1;
11444       else
11445         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11446         dst = 1;
11447       else if (unformat (input, "proto %U",
11448                          unformat_ethernet_type_host_byte_order, &proto_val))
11449         proto = 1;
11450       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11451         tag1 = 1;
11452       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11453         tag2 = 1;
11454       else if (unformat (input, "ignore-tag1"))
11455         ignore_tag1 = 1;
11456       else if (unformat (input, "ignore-tag2"))
11457         ignore_tag2 = 1;
11458       else if (unformat (input, "cos1 %d", &cos1_val))
11459         cos1 = 1;
11460       else if (unformat (input, "cos2 %d", &cos2_val))
11461         cos2 = 1;
11462       else
11463         break;
11464     }
11465   if ((src + dst + proto + tag1 + tag2 +
11466        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11467     return 0;
11468
11469   if (tag1 || ignore_tag1 || cos1)
11470     len = 18;
11471   if (tag2 || ignore_tag2 || cos2)
11472     len = 22;
11473
11474   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11475
11476   if (dst)
11477     clib_memcpy (match, dst_val, 6);
11478
11479   if (src)
11480     clib_memcpy (match + 6, src_val, 6);
11481
11482   if (tag2)
11483     {
11484       /* inner vlan tag */
11485       match[19] = tag2_val[1];
11486       match[18] = tag2_val[0];
11487       if (cos2)
11488         match[18] |= (cos2_val & 0x7) << 5;
11489       if (proto)
11490         {
11491           match[21] = proto_val & 0xff;
11492           match[20] = proto_val >> 8;
11493         }
11494       if (tag1)
11495         {
11496           match[15] = tag1_val[1];
11497           match[14] = tag1_val[0];
11498         }
11499       if (cos1)
11500         match[14] |= (cos1_val & 0x7) << 5;
11501       *matchp = match;
11502       return 1;
11503     }
11504   if (tag1)
11505     {
11506       match[15] = tag1_val[1];
11507       match[14] = tag1_val[0];
11508       if (proto)
11509         {
11510           match[17] = proto_val & 0xff;
11511           match[16] = proto_val >> 8;
11512         }
11513       if (cos1)
11514         match[14] |= (cos1_val & 0x7) << 5;
11515
11516       *matchp = match;
11517       return 1;
11518     }
11519   if (cos2)
11520     match[18] |= (cos2_val & 0x7) << 5;
11521   if (cos1)
11522     match[14] |= (cos1_val & 0x7) << 5;
11523   if (proto)
11524     {
11525       match[13] = proto_val & 0xff;
11526       match[12] = proto_val >> 8;
11527     }
11528
11529   *matchp = match;
11530   return 1;
11531 }
11532 #endif
11533
11534 uword
11535 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11536 {
11537   u8 **matchp = va_arg (*args, u8 **);
11538   u32 skip_n_vectors = va_arg (*args, u32);
11539   u32 match_n_vectors = va_arg (*args, u32);
11540
11541   u8 *match = 0;
11542   u8 *l2 = 0;
11543   u8 *l3 = 0;
11544   u8 *l4 = 0;
11545
11546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11547     {
11548       if (unformat (input, "hex %U", unformat_hex_string, &match))
11549         ;
11550       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11551         ;
11552       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11553         ;
11554       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11555         ;
11556       else
11557         break;
11558     }
11559
11560   if (l4 && !l3)
11561     {
11562       vec_free (match);
11563       vec_free (l2);
11564       vec_free (l4);
11565       return 0;
11566     }
11567
11568   if (match || l2 || l3 || l4)
11569     {
11570       if (l2 || l3 || l4)
11571         {
11572           /* "Win a free Ethernet header in every packet" */
11573           if (l2 == 0)
11574             vec_validate_aligned (l2, 13, sizeof (u32x4));
11575           match = l2;
11576           if (vec_len (l3))
11577             {
11578               vec_append_aligned (match, l3, sizeof (u32x4));
11579               vec_free (l3);
11580             }
11581           if (vec_len (l4))
11582             {
11583               vec_append_aligned (match, l4, sizeof (u32x4));
11584               vec_free (l4);
11585             }
11586         }
11587
11588       /* Make sure the vector is big enough even if key is all 0's */
11589       vec_validate_aligned
11590         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11591          sizeof (u32x4));
11592
11593       /* Set size, include skipped vectors */
11594       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11595
11596       *matchp = match;
11597
11598       return 1;
11599     }
11600
11601   return 0;
11602 }
11603
11604 static int
11605 api_classify_add_del_session (vat_main_t * vam)
11606 {
11607   unformat_input_t *i = vam->input;
11608   vl_api_classify_add_del_session_t *mp;
11609   int is_add = 1;
11610   u32 table_index = ~0;
11611   u32 hit_next_index = ~0;
11612   u32 opaque_index = ~0;
11613   u8 *match = 0;
11614   i32 advance = 0;
11615   u32 skip_n_vectors = 0;
11616   u32 match_n_vectors = 0;
11617   u32 action = 0;
11618   u32 metadata = 0;
11619   int ret;
11620
11621   /*
11622    * Warning: you have to supply skip_n and match_n
11623    * because the API client cant simply look at the classify
11624    * table object.
11625    */
11626
11627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11628     {
11629       if (unformat (i, "del"))
11630         is_add = 0;
11631       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11632                          &hit_next_index))
11633         ;
11634       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11635                          &hit_next_index))
11636         ;
11637       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11638                          &hit_next_index))
11639         ;
11640       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11641         ;
11642       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11643         ;
11644       else if (unformat (i, "opaque-index %d", &opaque_index))
11645         ;
11646       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11647         ;
11648       else if (unformat (i, "match_n %d", &match_n_vectors))
11649         ;
11650       else if (unformat (i, "match %U", api_unformat_classify_match,
11651                          &match, skip_n_vectors, match_n_vectors))
11652         ;
11653       else if (unformat (i, "advance %d", &advance))
11654         ;
11655       else if (unformat (i, "table-index %d", &table_index))
11656         ;
11657       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11658         action = 1;
11659       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11660         action = 2;
11661       else if (unformat (i, "action %d", &action))
11662         ;
11663       else if (unformat (i, "metadata %d", &metadata))
11664         ;
11665       else
11666         break;
11667     }
11668
11669   if (table_index == ~0)
11670     {
11671       errmsg ("Table index required");
11672       return -99;
11673     }
11674
11675   if (is_add && match == 0)
11676     {
11677       errmsg ("Match value required");
11678       return -99;
11679     }
11680
11681   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11682
11683   mp->is_add = is_add;
11684   mp->table_index = ntohl (table_index);
11685   mp->hit_next_index = ntohl (hit_next_index);
11686   mp->opaque_index = ntohl (opaque_index);
11687   mp->advance = ntohl (advance);
11688   mp->action = action;
11689   mp->metadata = ntohl (metadata);
11690   clib_memcpy (mp->match, match, vec_len (match));
11691   vec_free (match);
11692
11693   S (mp);
11694   W (ret);
11695   return ret;
11696 }
11697
11698 static int
11699 api_classify_set_interface_ip_table (vat_main_t * vam)
11700 {
11701   unformat_input_t *i = vam->input;
11702   vl_api_classify_set_interface_ip_table_t *mp;
11703   u32 sw_if_index;
11704   int sw_if_index_set;
11705   u32 table_index = ~0;
11706   u8 is_ipv6 = 0;
11707   int ret;
11708
11709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11710     {
11711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11712         sw_if_index_set = 1;
11713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "table %d", &table_index))
11716         ;
11717       else
11718         {
11719           clib_warning ("parse error '%U'", format_unformat_error, i);
11720           return -99;
11721         }
11722     }
11723
11724   if (sw_if_index_set == 0)
11725     {
11726       errmsg ("missing interface name or sw_if_index");
11727       return -99;
11728     }
11729
11730
11731   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11732
11733   mp->sw_if_index = ntohl (sw_if_index);
11734   mp->table_index = ntohl (table_index);
11735   mp->is_ipv6 = is_ipv6;
11736
11737   S (mp);
11738   W (ret);
11739   return ret;
11740 }
11741
11742 static int
11743 api_classify_set_interface_l2_tables (vat_main_t * vam)
11744 {
11745   unformat_input_t *i = vam->input;
11746   vl_api_classify_set_interface_l2_tables_t *mp;
11747   u32 sw_if_index;
11748   int sw_if_index_set;
11749   u32 ip4_table_index = ~0;
11750   u32 ip6_table_index = ~0;
11751   u32 other_table_index = ~0;
11752   u32 is_input = 1;
11753   int ret;
11754
11755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11756     {
11757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11758         sw_if_index_set = 1;
11759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11762         ;
11763       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11764         ;
11765       else if (unformat (i, "other-table %d", &other_table_index))
11766         ;
11767       else if (unformat (i, "is-input %d", &is_input))
11768         ;
11769       else
11770         {
11771           clib_warning ("parse error '%U'", format_unformat_error, i);
11772           return -99;
11773         }
11774     }
11775
11776   if (sw_if_index_set == 0)
11777     {
11778       errmsg ("missing interface name or sw_if_index");
11779       return -99;
11780     }
11781
11782
11783   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11784
11785   mp->sw_if_index = ntohl (sw_if_index);
11786   mp->ip4_table_index = ntohl (ip4_table_index);
11787   mp->ip6_table_index = ntohl (ip6_table_index);
11788   mp->other_table_index = ntohl (other_table_index);
11789   mp->is_input = (u8) is_input;
11790
11791   S (mp);
11792   W (ret);
11793   return ret;
11794 }
11795
11796 static int
11797 api_set_ipfix_exporter (vat_main_t * vam)
11798 {
11799   unformat_input_t *i = vam->input;
11800   vl_api_set_ipfix_exporter_t *mp;
11801   ip4_address_t collector_address;
11802   u8 collector_address_set = 0;
11803   u32 collector_port = ~0;
11804   ip4_address_t src_address;
11805   u8 src_address_set = 0;
11806   u32 vrf_id = ~0;
11807   u32 path_mtu = ~0;
11808   u32 template_interval = ~0;
11809   u8 udp_checksum = 0;
11810   int ret;
11811
11812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11813     {
11814       if (unformat (i, "collector_address %U", unformat_ip4_address,
11815                     &collector_address))
11816         collector_address_set = 1;
11817       else if (unformat (i, "collector_port %d", &collector_port))
11818         ;
11819       else if (unformat (i, "src_address %U", unformat_ip4_address,
11820                          &src_address))
11821         src_address_set = 1;
11822       else if (unformat (i, "vrf_id %d", &vrf_id))
11823         ;
11824       else if (unformat (i, "path_mtu %d", &path_mtu))
11825         ;
11826       else if (unformat (i, "template_interval %d", &template_interval))
11827         ;
11828       else if (unformat (i, "udp_checksum"))
11829         udp_checksum = 1;
11830       else
11831         break;
11832     }
11833
11834   if (collector_address_set == 0)
11835     {
11836       errmsg ("collector_address required");
11837       return -99;
11838     }
11839
11840   if (src_address_set == 0)
11841     {
11842       errmsg ("src_address required");
11843       return -99;
11844     }
11845
11846   M (SET_IPFIX_EXPORTER, mp);
11847
11848   memcpy (mp->collector_address, collector_address.data,
11849           sizeof (collector_address.data));
11850   mp->collector_port = htons ((u16) collector_port);
11851   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11852   mp->vrf_id = htonl (vrf_id);
11853   mp->path_mtu = htonl (path_mtu);
11854   mp->template_interval = htonl (template_interval);
11855   mp->udp_checksum = udp_checksum;
11856
11857   S (mp);
11858   W (ret);
11859   return ret;
11860 }
11861
11862 static int
11863 api_set_ipfix_classify_stream (vat_main_t * vam)
11864 {
11865   unformat_input_t *i = vam->input;
11866   vl_api_set_ipfix_classify_stream_t *mp;
11867   u32 domain_id = 0;
11868   u32 src_port = UDP_DST_PORT_ipfix;
11869   int ret;
11870
11871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11872     {
11873       if (unformat (i, "domain %d", &domain_id))
11874         ;
11875       else if (unformat (i, "src_port %d", &src_port))
11876         ;
11877       else
11878         {
11879           errmsg ("unknown input `%U'", format_unformat_error, i);
11880           return -99;
11881         }
11882     }
11883
11884   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11885
11886   mp->domain_id = htonl (domain_id);
11887   mp->src_port = htons ((u16) src_port);
11888
11889   S (mp);
11890   W (ret);
11891   return ret;
11892 }
11893
11894 static int
11895 api_ipfix_classify_table_add_del (vat_main_t * vam)
11896 {
11897   unformat_input_t *i = vam->input;
11898   vl_api_ipfix_classify_table_add_del_t *mp;
11899   int is_add = -1;
11900   u32 classify_table_index = ~0;
11901   u8 ip_version = 0;
11902   u8 transport_protocol = 255;
11903   int ret;
11904
11905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (i, "add"))
11908         is_add = 1;
11909       else if (unformat (i, "del"))
11910         is_add = 0;
11911       else if (unformat (i, "table %d", &classify_table_index))
11912         ;
11913       else if (unformat (i, "ip4"))
11914         ip_version = 4;
11915       else if (unformat (i, "ip6"))
11916         ip_version = 6;
11917       else if (unformat (i, "tcp"))
11918         transport_protocol = 6;
11919       else if (unformat (i, "udp"))
11920         transport_protocol = 17;
11921       else
11922         {
11923           errmsg ("unknown input `%U'", format_unformat_error, i);
11924           return -99;
11925         }
11926     }
11927
11928   if (is_add == -1)
11929     {
11930       errmsg ("expecting: add|del");
11931       return -99;
11932     }
11933   if (classify_table_index == ~0)
11934     {
11935       errmsg ("classifier table not specified");
11936       return -99;
11937     }
11938   if (ip_version == 0)
11939     {
11940       errmsg ("IP version not specified");
11941       return -99;
11942     }
11943
11944   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11945
11946   mp->is_add = is_add;
11947   mp->table_id = htonl (classify_table_index);
11948   mp->ip_version = ip_version;
11949   mp->transport_protocol = transport_protocol;
11950
11951   S (mp);
11952   W (ret);
11953   return ret;
11954 }
11955
11956 static int
11957 api_get_node_index (vat_main_t * vam)
11958 {
11959   unformat_input_t *i = vam->input;
11960   vl_api_get_node_index_t *mp;
11961   u8 *name = 0;
11962   int ret;
11963
11964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11965     {
11966       if (unformat (i, "node %s", &name))
11967         ;
11968       else
11969         break;
11970     }
11971   if (name == 0)
11972     {
11973       errmsg ("node name required");
11974       return -99;
11975     }
11976   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11977     {
11978       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11979       return -99;
11980     }
11981
11982   M (GET_NODE_INDEX, mp);
11983   clib_memcpy (mp->node_name, name, vec_len (name));
11984   vec_free (name);
11985
11986   S (mp);
11987   W (ret);
11988   return ret;
11989 }
11990
11991 static int
11992 api_get_next_index (vat_main_t * vam)
11993 {
11994   unformat_input_t *i = vam->input;
11995   vl_api_get_next_index_t *mp;
11996   u8 *node_name = 0, *next_node_name = 0;
11997   int ret;
11998
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "node-name %s", &node_name))
12002         ;
12003       else if (unformat (i, "next-node-name %s", &next_node_name))
12004         break;
12005     }
12006
12007   if (node_name == 0)
12008     {
12009       errmsg ("node name required");
12010       return -99;
12011     }
12012   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12013     {
12014       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12015       return -99;
12016     }
12017
12018   if (next_node_name == 0)
12019     {
12020       errmsg ("next node name required");
12021       return -99;
12022     }
12023   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12024     {
12025       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12026       return -99;
12027     }
12028
12029   M (GET_NEXT_INDEX, mp);
12030   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12031   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12032   vec_free (node_name);
12033   vec_free (next_node_name);
12034
12035   S (mp);
12036   W (ret);
12037   return ret;
12038 }
12039
12040 static int
12041 api_add_node_next (vat_main_t * vam)
12042 {
12043   unformat_input_t *i = vam->input;
12044   vl_api_add_node_next_t *mp;
12045   u8 *name = 0;
12046   u8 *next = 0;
12047   int ret;
12048
12049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12050     {
12051       if (unformat (i, "node %s", &name))
12052         ;
12053       else if (unformat (i, "next %s", &next))
12054         ;
12055       else
12056         break;
12057     }
12058   if (name == 0)
12059     {
12060       errmsg ("node name required");
12061       return -99;
12062     }
12063   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12064     {
12065       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12066       return -99;
12067     }
12068   if (next == 0)
12069     {
12070       errmsg ("next node required");
12071       return -99;
12072     }
12073   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12074     {
12075       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12076       return -99;
12077     }
12078
12079   M (ADD_NODE_NEXT, mp);
12080   clib_memcpy (mp->node_name, name, vec_len (name));
12081   clib_memcpy (mp->next_name, next, vec_len (next));
12082   vec_free (name);
12083   vec_free (next);
12084
12085   S (mp);
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static int
12091 api_l2tpv3_create_tunnel (vat_main_t * vam)
12092 {
12093   unformat_input_t *i = vam->input;
12094   ip6_address_t client_address, our_address;
12095   int client_address_set = 0;
12096   int our_address_set = 0;
12097   u32 local_session_id = 0;
12098   u32 remote_session_id = 0;
12099   u64 local_cookie = 0;
12100   u64 remote_cookie = 0;
12101   u8 l2_sublayer_present = 0;
12102   vl_api_l2tpv3_create_tunnel_t *mp;
12103   int ret;
12104
12105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12106     {
12107       if (unformat (i, "client_address %U", unformat_ip6_address,
12108                     &client_address))
12109         client_address_set = 1;
12110       else if (unformat (i, "our_address %U", unformat_ip6_address,
12111                          &our_address))
12112         our_address_set = 1;
12113       else if (unformat (i, "local_session_id %d", &local_session_id))
12114         ;
12115       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12116         ;
12117       else if (unformat (i, "local_cookie %lld", &local_cookie))
12118         ;
12119       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12120         ;
12121       else if (unformat (i, "l2-sublayer-present"))
12122         l2_sublayer_present = 1;
12123       else
12124         break;
12125     }
12126
12127   if (client_address_set == 0)
12128     {
12129       errmsg ("client_address required");
12130       return -99;
12131     }
12132
12133   if (our_address_set == 0)
12134     {
12135       errmsg ("our_address required");
12136       return -99;
12137     }
12138
12139   M (L2TPV3_CREATE_TUNNEL, mp);
12140
12141   clib_memcpy (mp->client_address, client_address.as_u8,
12142                sizeof (mp->client_address));
12143
12144   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12145
12146   mp->local_session_id = ntohl (local_session_id);
12147   mp->remote_session_id = ntohl (remote_session_id);
12148   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12149   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12150   mp->l2_sublayer_present = l2_sublayer_present;
12151   mp->is_ipv6 = 1;
12152
12153   S (mp);
12154   W (ret);
12155   return ret;
12156 }
12157
12158 static int
12159 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12160 {
12161   unformat_input_t *i = vam->input;
12162   u32 sw_if_index;
12163   u8 sw_if_index_set = 0;
12164   u64 new_local_cookie = 0;
12165   u64 new_remote_cookie = 0;
12166   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12167   int ret;
12168
12169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12170     {
12171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12172         sw_if_index_set = 1;
12173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12174         sw_if_index_set = 1;
12175       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12176         ;
12177       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12178         ;
12179       else
12180         break;
12181     }
12182
12183   if (sw_if_index_set == 0)
12184     {
12185       errmsg ("missing interface name or sw_if_index");
12186       return -99;
12187     }
12188
12189   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12190
12191   mp->sw_if_index = ntohl (sw_if_index);
12192   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12193   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12194
12195   S (mp);
12196   W (ret);
12197   return ret;
12198 }
12199
12200 static int
12201 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_l2tpv3_interface_enable_disable_t *mp;
12205   u32 sw_if_index;
12206   u8 sw_if_index_set = 0;
12207   u8 enable_disable = 1;
12208   int ret;
12209
12210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12211     {
12212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12213         sw_if_index_set = 1;
12214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "enable"))
12217         enable_disable = 1;
12218       else if (unformat (i, "disable"))
12219         enable_disable = 0;
12220       else
12221         break;
12222     }
12223
12224   if (sw_if_index_set == 0)
12225     {
12226       errmsg ("missing interface name or sw_if_index");
12227       return -99;
12228     }
12229
12230   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12231
12232   mp->sw_if_index = ntohl (sw_if_index);
12233   mp->enable_disable = enable_disable;
12234
12235   S (mp);
12236   W (ret);
12237   return ret;
12238 }
12239
12240 static int
12241 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12242 {
12243   unformat_input_t *i = vam->input;
12244   vl_api_l2tpv3_set_lookup_key_t *mp;
12245   u8 key = ~0;
12246   int ret;
12247
12248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12249     {
12250       if (unformat (i, "lookup_v6_src"))
12251         key = L2T_LOOKUP_SRC_ADDRESS;
12252       else if (unformat (i, "lookup_v6_dst"))
12253         key = L2T_LOOKUP_DST_ADDRESS;
12254       else if (unformat (i, "lookup_session_id"))
12255         key = L2T_LOOKUP_SESSION_ID;
12256       else
12257         break;
12258     }
12259
12260   if (key == (u8) ~ 0)
12261     {
12262       errmsg ("l2tp session lookup key unset");
12263       return -99;
12264     }
12265
12266   M (L2TPV3_SET_LOOKUP_KEY, mp);
12267
12268   mp->key = key;
12269
12270   S (mp);
12271   W (ret);
12272   return ret;
12273 }
12274
12275 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12276   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12277 {
12278   vat_main_t *vam = &vat_main;
12279
12280   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12281          format_ip6_address, mp->our_address,
12282          format_ip6_address, mp->client_address,
12283          clib_net_to_host_u32 (mp->sw_if_index));
12284
12285   print (vam->ofp,
12286          "   local cookies %016llx %016llx remote cookie %016llx",
12287          clib_net_to_host_u64 (mp->local_cookie[0]),
12288          clib_net_to_host_u64 (mp->local_cookie[1]),
12289          clib_net_to_host_u64 (mp->remote_cookie));
12290
12291   print (vam->ofp, "   local session-id %d remote session-id %d",
12292          clib_net_to_host_u32 (mp->local_session_id),
12293          clib_net_to_host_u32 (mp->remote_session_id));
12294
12295   print (vam->ofp, "   l2 specific sublayer %s\n",
12296          mp->l2_sublayer_present ? "preset" : "absent");
12297
12298 }
12299
12300 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12301   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12302 {
12303   vat_main_t *vam = &vat_main;
12304   vat_json_node_t *node = NULL;
12305   struct in6_addr addr;
12306
12307   if (VAT_JSON_ARRAY != vam->json_tree.type)
12308     {
12309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12310       vat_json_init_array (&vam->json_tree);
12311     }
12312   node = vat_json_array_add (&vam->json_tree);
12313
12314   vat_json_init_object (node);
12315
12316   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12317   vat_json_object_add_ip6 (node, "our_address", addr);
12318   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12319   vat_json_object_add_ip6 (node, "client_address", addr);
12320
12321   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12322   vat_json_init_array (lc);
12323   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12324   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12325   vat_json_object_add_uint (node, "remote_cookie",
12326                             clib_net_to_host_u64 (mp->remote_cookie));
12327
12328   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12329   vat_json_object_add_uint (node, "local_session_id",
12330                             clib_net_to_host_u32 (mp->local_session_id));
12331   vat_json_object_add_uint (node, "remote_session_id",
12332                             clib_net_to_host_u32 (mp->remote_session_id));
12333   vat_json_object_add_string_copy (node, "l2_sublayer",
12334                                    mp->l2_sublayer_present ? (u8 *) "present"
12335                                    : (u8 *) "absent");
12336 }
12337
12338 static int
12339 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12340 {
12341   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12342   vl_api_control_ping_t *mp_ping;
12343   int ret;
12344
12345   /* Get list of l2tpv3-tunnel interfaces */
12346   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12347   S (mp);
12348
12349   /* Use a control ping for synchronization */
12350   MPING (CONTROL_PING, mp_ping);
12351   S (mp_ping);
12352
12353   W (ret);
12354   return ret;
12355 }
12356
12357
12358 static void vl_api_sw_interface_tap_details_t_handler
12359   (vl_api_sw_interface_tap_details_t * mp)
12360 {
12361   vat_main_t *vam = &vat_main;
12362
12363   print (vam->ofp, "%-16s %d",
12364          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12365 }
12366
12367 static void vl_api_sw_interface_tap_details_t_handler_json
12368   (vl_api_sw_interface_tap_details_t * mp)
12369 {
12370   vat_main_t *vam = &vat_main;
12371   vat_json_node_t *node = NULL;
12372
12373   if (VAT_JSON_ARRAY != vam->json_tree.type)
12374     {
12375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12376       vat_json_init_array (&vam->json_tree);
12377     }
12378   node = vat_json_array_add (&vam->json_tree);
12379
12380   vat_json_init_object (node);
12381   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12382   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12383 }
12384
12385 static int
12386 api_sw_interface_tap_dump (vat_main_t * vam)
12387 {
12388   vl_api_sw_interface_tap_dump_t *mp;
12389   vl_api_control_ping_t *mp_ping;
12390   int ret;
12391
12392   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12393   /* Get list of tap interfaces */
12394   M (SW_INTERFACE_TAP_DUMP, mp);
12395   S (mp);
12396
12397   /* Use a control ping for synchronization */
12398   MPING (CONTROL_PING, mp_ping);
12399   S (mp_ping);
12400
12401   W (ret);
12402   return ret;
12403 }
12404
12405 static void vl_api_sw_interface_tap_v2_details_t_handler
12406   (vl_api_sw_interface_tap_v2_details_t * mp)
12407 {
12408   vat_main_t *vam = &vat_main;
12409
12410   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12411                     mp->host_ip4_prefix_len);
12412   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12413                     mp->host_ip6_prefix_len);
12414
12415   print (vam->ofp,
12416          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12417          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12418          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12419          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12420          mp->host_bridge, ip4, ip6);
12421
12422   vec_free (ip4);
12423   vec_free (ip6);
12424 }
12425
12426 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12427   (vl_api_sw_interface_tap_v2_details_t * mp)
12428 {
12429   vat_main_t *vam = &vat_main;
12430   vat_json_node_t *node = NULL;
12431
12432   if (VAT_JSON_ARRAY != vam->json_tree.type)
12433     {
12434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12435       vat_json_init_array (&vam->json_tree);
12436     }
12437   node = vat_json_array_add (&vam->json_tree);
12438
12439   vat_json_init_object (node);
12440   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12441   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12442   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12443   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12444   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12445   vat_json_object_add_string_copy (node, "host_mac_addr",
12446                                    format (0, "%U", format_ethernet_address,
12447                                            &mp->host_mac_addr));
12448   vat_json_object_add_string_copy (node, "host_namespace",
12449                                    mp->host_namespace);
12450   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12451   vat_json_object_add_string_copy (node, "host_ip4_addr",
12452                                    format (0, "%U/%d", format_ip4_address,
12453                                            mp->host_ip4_addr,
12454                                            mp->host_ip4_prefix_len));
12455   vat_json_object_add_string_copy (node, "host_ip6_addr",
12456                                    format (0, "%U/%d", format_ip6_address,
12457                                            mp->host_ip6_addr,
12458                                            mp->host_ip6_prefix_len));
12459
12460 }
12461
12462 static int
12463 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12464 {
12465   vl_api_sw_interface_tap_v2_dump_t *mp;
12466   vl_api_control_ping_t *mp_ping;
12467   int ret;
12468
12469   print (vam->ofp,
12470          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12471          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12472          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12473          "host_ip6_addr");
12474
12475   /* Get list of tap interfaces */
12476   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12477   S (mp);
12478
12479   /* Use a control ping for synchronization */
12480   MPING (CONTROL_PING, mp_ping);
12481   S (mp_ping);
12482
12483   W (ret);
12484   return ret;
12485 }
12486
12487 static uword unformat_vxlan_decap_next
12488   (unformat_input_t * input, va_list * args)
12489 {
12490   u32 *result = va_arg (*args, u32 *);
12491   u32 tmp;
12492
12493   if (unformat (input, "l2"))
12494     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12495   else if (unformat (input, "%d", &tmp))
12496     *result = tmp;
12497   else
12498     return 0;
12499   return 1;
12500 }
12501
12502 static int
12503 api_vxlan_add_del_tunnel (vat_main_t * vam)
12504 {
12505   unformat_input_t *line_input = vam->input;
12506   vl_api_vxlan_add_del_tunnel_t *mp;
12507   ip46_address_t src, dst;
12508   u8 is_add = 1;
12509   u8 ipv4_set = 0, ipv6_set = 0;
12510   u8 src_set = 0;
12511   u8 dst_set = 0;
12512   u8 grp_set = 0;
12513   u32 mcast_sw_if_index = ~0;
12514   u32 encap_vrf_id = 0;
12515   u32 decap_next_index = ~0;
12516   u32 vni = 0;
12517   int ret;
12518
12519   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12520   memset (&src, 0, sizeof src);
12521   memset (&dst, 0, sizeof dst);
12522
12523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12524     {
12525       if (unformat (line_input, "del"))
12526         is_add = 0;
12527       else
12528         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12529         {
12530           ipv4_set = 1;
12531           src_set = 1;
12532         }
12533       else
12534         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12535         {
12536           ipv4_set = 1;
12537           dst_set = 1;
12538         }
12539       else
12540         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12541         {
12542           ipv6_set = 1;
12543           src_set = 1;
12544         }
12545       else
12546         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12547         {
12548           ipv6_set = 1;
12549           dst_set = 1;
12550         }
12551       else if (unformat (line_input, "group %U %U",
12552                          unformat_ip4_address, &dst.ip4,
12553                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12554         {
12555           grp_set = dst_set = 1;
12556           ipv4_set = 1;
12557         }
12558       else if (unformat (line_input, "group %U",
12559                          unformat_ip4_address, &dst.ip4))
12560         {
12561           grp_set = dst_set = 1;
12562           ipv4_set = 1;
12563         }
12564       else if (unformat (line_input, "group %U %U",
12565                          unformat_ip6_address, &dst.ip6,
12566                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12567         {
12568           grp_set = dst_set = 1;
12569           ipv6_set = 1;
12570         }
12571       else if (unformat (line_input, "group %U",
12572                          unformat_ip6_address, &dst.ip6))
12573         {
12574           grp_set = dst_set = 1;
12575           ipv6_set = 1;
12576         }
12577       else
12578         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12579         ;
12580       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12581         ;
12582       else if (unformat (line_input, "decap-next %U",
12583                          unformat_vxlan_decap_next, &decap_next_index))
12584         ;
12585       else if (unformat (line_input, "vni %d", &vni))
12586         ;
12587       else
12588         {
12589           errmsg ("parse error '%U'", format_unformat_error, line_input);
12590           return -99;
12591         }
12592     }
12593
12594   if (src_set == 0)
12595     {
12596       errmsg ("tunnel src address not specified");
12597       return -99;
12598     }
12599   if (dst_set == 0)
12600     {
12601       errmsg ("tunnel dst address not specified");
12602       return -99;
12603     }
12604
12605   if (grp_set && !ip46_address_is_multicast (&dst))
12606     {
12607       errmsg ("tunnel group address not multicast");
12608       return -99;
12609     }
12610   if (grp_set && mcast_sw_if_index == ~0)
12611     {
12612       errmsg ("tunnel nonexistent multicast device");
12613       return -99;
12614     }
12615   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12616     {
12617       errmsg ("tunnel dst address must be unicast");
12618       return -99;
12619     }
12620
12621
12622   if (ipv4_set && ipv6_set)
12623     {
12624       errmsg ("both IPv4 and IPv6 addresses specified");
12625       return -99;
12626     }
12627
12628   if ((vni == 0) || (vni >> 24))
12629     {
12630       errmsg ("vni not specified or out of range");
12631       return -99;
12632     }
12633
12634   M (VXLAN_ADD_DEL_TUNNEL, mp);
12635
12636   if (ipv6_set)
12637     {
12638       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12639       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12640     }
12641   else
12642     {
12643       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12644       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12645     }
12646   mp->encap_vrf_id = ntohl (encap_vrf_id);
12647   mp->decap_next_index = ntohl (decap_next_index);
12648   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12649   mp->vni = ntohl (vni);
12650   mp->is_add = is_add;
12651   mp->is_ipv6 = ipv6_set;
12652
12653   S (mp);
12654   W (ret);
12655   return ret;
12656 }
12657
12658 static void vl_api_vxlan_tunnel_details_t_handler
12659   (vl_api_vxlan_tunnel_details_t * mp)
12660 {
12661   vat_main_t *vam = &vat_main;
12662   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12663   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12664
12665   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12666          ntohl (mp->sw_if_index),
12667          format_ip46_address, &src, IP46_TYPE_ANY,
12668          format_ip46_address, &dst, IP46_TYPE_ANY,
12669          ntohl (mp->encap_vrf_id),
12670          ntohl (mp->decap_next_index), ntohl (mp->vni),
12671          ntohl (mp->mcast_sw_if_index));
12672 }
12673
12674 static void vl_api_vxlan_tunnel_details_t_handler_json
12675   (vl_api_vxlan_tunnel_details_t * mp)
12676 {
12677   vat_main_t *vam = &vat_main;
12678   vat_json_node_t *node = NULL;
12679
12680   if (VAT_JSON_ARRAY != vam->json_tree.type)
12681     {
12682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12683       vat_json_init_array (&vam->json_tree);
12684     }
12685   node = vat_json_array_add (&vam->json_tree);
12686
12687   vat_json_init_object (node);
12688   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12689   if (mp->is_ipv6)
12690     {
12691       struct in6_addr ip6;
12692
12693       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12694       vat_json_object_add_ip6 (node, "src_address", ip6);
12695       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12696       vat_json_object_add_ip6 (node, "dst_address", ip6);
12697     }
12698   else
12699     {
12700       struct in_addr ip4;
12701
12702       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12703       vat_json_object_add_ip4 (node, "src_address", ip4);
12704       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12705       vat_json_object_add_ip4 (node, "dst_address", ip4);
12706     }
12707   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12708   vat_json_object_add_uint (node, "decap_next_index",
12709                             ntohl (mp->decap_next_index));
12710   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12711   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12712   vat_json_object_add_uint (node, "mcast_sw_if_index",
12713                             ntohl (mp->mcast_sw_if_index));
12714 }
12715
12716 static int
12717 api_vxlan_tunnel_dump (vat_main_t * vam)
12718 {
12719   unformat_input_t *i = vam->input;
12720   vl_api_vxlan_tunnel_dump_t *mp;
12721   vl_api_control_ping_t *mp_ping;
12722   u32 sw_if_index;
12723   u8 sw_if_index_set = 0;
12724   int ret;
12725
12726   /* Parse args required to build the message */
12727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12728     {
12729       if (unformat (i, "sw_if_index %d", &sw_if_index))
12730         sw_if_index_set = 1;
12731       else
12732         break;
12733     }
12734
12735   if (sw_if_index_set == 0)
12736     {
12737       sw_if_index = ~0;
12738     }
12739
12740   if (!vam->json_output)
12741     {
12742       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12743              "sw_if_index", "src_address", "dst_address",
12744              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12745     }
12746
12747   /* Get list of vxlan-tunnel interfaces */
12748   M (VXLAN_TUNNEL_DUMP, mp);
12749
12750   mp->sw_if_index = htonl (sw_if_index);
12751
12752   S (mp);
12753
12754   /* Use a control ping for synchronization */
12755   MPING (CONTROL_PING, mp_ping);
12756   S (mp_ping);
12757
12758   W (ret);
12759   return ret;
12760 }
12761
12762 static uword unformat_geneve_decap_next
12763   (unformat_input_t * input, va_list * args)
12764 {
12765   u32 *result = va_arg (*args, u32 *);
12766   u32 tmp;
12767
12768   if (unformat (input, "l2"))
12769     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12770   else if (unformat (input, "%d", &tmp))
12771     *result = tmp;
12772   else
12773     return 0;
12774   return 1;
12775 }
12776
12777 static int
12778 api_geneve_add_del_tunnel (vat_main_t * vam)
12779 {
12780   unformat_input_t *line_input = vam->input;
12781   vl_api_geneve_add_del_tunnel_t *mp;
12782   ip46_address_t src, dst;
12783   u8 is_add = 1;
12784   u8 ipv4_set = 0, ipv6_set = 0;
12785   u8 src_set = 0;
12786   u8 dst_set = 0;
12787   u8 grp_set = 0;
12788   u32 mcast_sw_if_index = ~0;
12789   u32 encap_vrf_id = 0;
12790   u32 decap_next_index = ~0;
12791   u32 vni = 0;
12792   int ret;
12793
12794   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12795   memset (&src, 0, sizeof src);
12796   memset (&dst, 0, sizeof dst);
12797
12798   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12799     {
12800       if (unformat (line_input, "del"))
12801         is_add = 0;
12802       else
12803         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12804         {
12805           ipv4_set = 1;
12806           src_set = 1;
12807         }
12808       else
12809         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12810         {
12811           ipv4_set = 1;
12812           dst_set = 1;
12813         }
12814       else
12815         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12816         {
12817           ipv6_set = 1;
12818           src_set = 1;
12819         }
12820       else
12821         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12822         {
12823           ipv6_set = 1;
12824           dst_set = 1;
12825         }
12826       else if (unformat (line_input, "group %U %U",
12827                          unformat_ip4_address, &dst.ip4,
12828                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12829         {
12830           grp_set = dst_set = 1;
12831           ipv4_set = 1;
12832         }
12833       else if (unformat (line_input, "group %U",
12834                          unformat_ip4_address, &dst.ip4))
12835         {
12836           grp_set = dst_set = 1;
12837           ipv4_set = 1;
12838         }
12839       else if (unformat (line_input, "group %U %U",
12840                          unformat_ip6_address, &dst.ip6,
12841                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12842         {
12843           grp_set = dst_set = 1;
12844           ipv6_set = 1;
12845         }
12846       else if (unformat (line_input, "group %U",
12847                          unformat_ip6_address, &dst.ip6))
12848         {
12849           grp_set = dst_set = 1;
12850           ipv6_set = 1;
12851         }
12852       else
12853         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12854         ;
12855       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12856         ;
12857       else if (unformat (line_input, "decap-next %U",
12858                          unformat_geneve_decap_next, &decap_next_index))
12859         ;
12860       else if (unformat (line_input, "vni %d", &vni))
12861         ;
12862       else
12863         {
12864           errmsg ("parse error '%U'", format_unformat_error, line_input);
12865           return -99;
12866         }
12867     }
12868
12869   if (src_set == 0)
12870     {
12871       errmsg ("tunnel src address not specified");
12872       return -99;
12873     }
12874   if (dst_set == 0)
12875     {
12876       errmsg ("tunnel dst address not specified");
12877       return -99;
12878     }
12879
12880   if (grp_set && !ip46_address_is_multicast (&dst))
12881     {
12882       errmsg ("tunnel group address not multicast");
12883       return -99;
12884     }
12885   if (grp_set && mcast_sw_if_index == ~0)
12886     {
12887       errmsg ("tunnel nonexistent multicast device");
12888       return -99;
12889     }
12890   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12891     {
12892       errmsg ("tunnel dst address must be unicast");
12893       return -99;
12894     }
12895
12896
12897   if (ipv4_set && ipv6_set)
12898     {
12899       errmsg ("both IPv4 and IPv6 addresses specified");
12900       return -99;
12901     }
12902
12903   if ((vni == 0) || (vni >> 24))
12904     {
12905       errmsg ("vni not specified or out of range");
12906       return -99;
12907     }
12908
12909   M (GENEVE_ADD_DEL_TUNNEL, mp);
12910
12911   if (ipv6_set)
12912     {
12913       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12914       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12915     }
12916   else
12917     {
12918       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12919       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12920     }
12921   mp->encap_vrf_id = ntohl (encap_vrf_id);
12922   mp->decap_next_index = ntohl (decap_next_index);
12923   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12924   mp->vni = ntohl (vni);
12925   mp->is_add = is_add;
12926   mp->is_ipv6 = ipv6_set;
12927
12928   S (mp);
12929   W (ret);
12930   return ret;
12931 }
12932
12933 static void vl_api_geneve_tunnel_details_t_handler
12934   (vl_api_geneve_tunnel_details_t * mp)
12935 {
12936   vat_main_t *vam = &vat_main;
12937   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12938   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12939
12940   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12941          ntohl (mp->sw_if_index),
12942          format_ip46_address, &src, IP46_TYPE_ANY,
12943          format_ip46_address, &dst, IP46_TYPE_ANY,
12944          ntohl (mp->encap_vrf_id),
12945          ntohl (mp->decap_next_index), ntohl (mp->vni),
12946          ntohl (mp->mcast_sw_if_index));
12947 }
12948
12949 static void vl_api_geneve_tunnel_details_t_handler_json
12950   (vl_api_geneve_tunnel_details_t * mp)
12951 {
12952   vat_main_t *vam = &vat_main;
12953   vat_json_node_t *node = NULL;
12954
12955   if (VAT_JSON_ARRAY != vam->json_tree.type)
12956     {
12957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12958       vat_json_init_array (&vam->json_tree);
12959     }
12960   node = vat_json_array_add (&vam->json_tree);
12961
12962   vat_json_init_object (node);
12963   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12964   if (mp->is_ipv6)
12965     {
12966       struct in6_addr ip6;
12967
12968       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12969       vat_json_object_add_ip6 (node, "src_address", ip6);
12970       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12971       vat_json_object_add_ip6 (node, "dst_address", ip6);
12972     }
12973   else
12974     {
12975       struct in_addr ip4;
12976
12977       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12978       vat_json_object_add_ip4 (node, "src_address", ip4);
12979       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12980       vat_json_object_add_ip4 (node, "dst_address", ip4);
12981     }
12982   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12983   vat_json_object_add_uint (node, "decap_next_index",
12984                             ntohl (mp->decap_next_index));
12985   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12986   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12987   vat_json_object_add_uint (node, "mcast_sw_if_index",
12988                             ntohl (mp->mcast_sw_if_index));
12989 }
12990
12991 static int
12992 api_geneve_tunnel_dump (vat_main_t * vam)
12993 {
12994   unformat_input_t *i = vam->input;
12995   vl_api_geneve_tunnel_dump_t *mp;
12996   vl_api_control_ping_t *mp_ping;
12997   u32 sw_if_index;
12998   u8 sw_if_index_set = 0;
12999   int ret;
13000
13001   /* Parse args required to build the message */
13002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13003     {
13004       if (unformat (i, "sw_if_index %d", &sw_if_index))
13005         sw_if_index_set = 1;
13006       else
13007         break;
13008     }
13009
13010   if (sw_if_index_set == 0)
13011     {
13012       sw_if_index = ~0;
13013     }
13014
13015   if (!vam->json_output)
13016     {
13017       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13018              "sw_if_index", "local_address", "remote_address",
13019              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13020     }
13021
13022   /* Get list of geneve-tunnel interfaces */
13023   M (GENEVE_TUNNEL_DUMP, mp);
13024
13025   mp->sw_if_index = htonl (sw_if_index);
13026
13027   S (mp);
13028
13029   /* Use a control ping for synchronization */
13030   M (CONTROL_PING, mp_ping);
13031   S (mp_ping);
13032
13033   W (ret);
13034   return ret;
13035 }
13036
13037 static int
13038 api_gre_add_del_tunnel (vat_main_t * vam)
13039 {
13040   unformat_input_t *line_input = vam->input;
13041   vl_api_gre_add_del_tunnel_t *mp;
13042   ip4_address_t src4, dst4;
13043   ip6_address_t src6, dst6;
13044   u8 is_add = 1;
13045   u8 ipv4_set = 0;
13046   u8 ipv6_set = 0;
13047   u8 teb = 0;
13048   u8 src_set = 0;
13049   u8 dst_set = 0;
13050   u32 outer_fib_id = 0;
13051   int ret;
13052
13053   memset (&src4, 0, sizeof src4);
13054   memset (&dst4, 0, sizeof dst4);
13055   memset (&src6, 0, sizeof src6);
13056   memset (&dst6, 0, sizeof dst6);
13057
13058   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13059     {
13060       if (unformat (line_input, "del"))
13061         is_add = 0;
13062       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13063         {
13064           src_set = 1;
13065           ipv4_set = 1;
13066         }
13067       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13068         {
13069           dst_set = 1;
13070           ipv4_set = 1;
13071         }
13072       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13073         {
13074           src_set = 1;
13075           ipv6_set = 1;
13076         }
13077       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13078         {
13079           dst_set = 1;
13080           ipv6_set = 1;
13081         }
13082       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13083         ;
13084       else if (unformat (line_input, "teb"))
13085         teb = 1;
13086       else
13087         {
13088           errmsg ("parse error '%U'", format_unformat_error, line_input);
13089           return -99;
13090         }
13091     }
13092
13093   if (src_set == 0)
13094     {
13095       errmsg ("tunnel src address not specified");
13096       return -99;
13097     }
13098   if (dst_set == 0)
13099     {
13100       errmsg ("tunnel dst address not specified");
13101       return -99;
13102     }
13103   if (ipv4_set && ipv6_set)
13104     {
13105       errmsg ("both IPv4 and IPv6 addresses specified");
13106       return -99;
13107     }
13108
13109
13110   M (GRE_ADD_DEL_TUNNEL, mp);
13111
13112   if (ipv4_set)
13113     {
13114       clib_memcpy (&mp->src_address, &src4, 4);
13115       clib_memcpy (&mp->dst_address, &dst4, 4);
13116     }
13117   else
13118     {
13119       clib_memcpy (&mp->src_address, &src6, 16);
13120       clib_memcpy (&mp->dst_address, &dst6, 16);
13121     }
13122   mp->outer_fib_id = ntohl (outer_fib_id);
13123   mp->is_add = is_add;
13124   mp->teb = teb;
13125   mp->is_ipv6 = ipv6_set;
13126
13127   S (mp);
13128   W (ret);
13129   return ret;
13130 }
13131
13132 static void vl_api_gre_tunnel_details_t_handler
13133   (vl_api_gre_tunnel_details_t * mp)
13134 {
13135   vat_main_t *vam = &vat_main;
13136   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13137   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13138
13139   print (vam->ofp, "%11d%24U%24U%6d%14d",
13140          ntohl (mp->sw_if_index),
13141          format_ip46_address, &src, IP46_TYPE_ANY,
13142          format_ip46_address, &dst, IP46_TYPE_ANY,
13143          mp->teb, ntohl (mp->outer_fib_id));
13144 }
13145
13146 static void vl_api_gre_tunnel_details_t_handler_json
13147   (vl_api_gre_tunnel_details_t * mp)
13148 {
13149   vat_main_t *vam = &vat_main;
13150   vat_json_node_t *node = NULL;
13151   struct in_addr ip4;
13152   struct in6_addr ip6;
13153
13154   if (VAT_JSON_ARRAY != vam->json_tree.type)
13155     {
13156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13157       vat_json_init_array (&vam->json_tree);
13158     }
13159   node = vat_json_array_add (&vam->json_tree);
13160
13161   vat_json_init_object (node);
13162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13163   if (!mp->is_ipv6)
13164     {
13165       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13166       vat_json_object_add_ip4 (node, "src_address", ip4);
13167       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13168       vat_json_object_add_ip4 (node, "dst_address", ip4);
13169     }
13170   else
13171     {
13172       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13173       vat_json_object_add_ip6 (node, "src_address", ip6);
13174       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13175       vat_json_object_add_ip6 (node, "dst_address", ip6);
13176     }
13177   vat_json_object_add_uint (node, "teb", mp->teb);
13178   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13179   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13180 }
13181
13182 static int
13183 api_gre_tunnel_dump (vat_main_t * vam)
13184 {
13185   unformat_input_t *i = vam->input;
13186   vl_api_gre_tunnel_dump_t *mp;
13187   vl_api_control_ping_t *mp_ping;
13188   u32 sw_if_index;
13189   u8 sw_if_index_set = 0;
13190   int ret;
13191
13192   /* Parse args required to build the message */
13193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13194     {
13195       if (unformat (i, "sw_if_index %d", &sw_if_index))
13196         sw_if_index_set = 1;
13197       else
13198         break;
13199     }
13200
13201   if (sw_if_index_set == 0)
13202     {
13203       sw_if_index = ~0;
13204     }
13205
13206   if (!vam->json_output)
13207     {
13208       print (vam->ofp, "%11s%24s%24s%6s%14s",
13209              "sw_if_index", "src_address", "dst_address", "teb",
13210              "outer_fib_id");
13211     }
13212
13213   /* Get list of gre-tunnel interfaces */
13214   M (GRE_TUNNEL_DUMP, mp);
13215
13216   mp->sw_if_index = htonl (sw_if_index);
13217
13218   S (mp);
13219
13220   /* Use a control ping for synchronization */
13221   MPING (CONTROL_PING, mp_ping);
13222   S (mp_ping);
13223
13224   W (ret);
13225   return ret;
13226 }
13227
13228 static int
13229 api_l2_fib_clear_table (vat_main_t * vam)
13230 {
13231 //  unformat_input_t * i = vam->input;
13232   vl_api_l2_fib_clear_table_t *mp;
13233   int ret;
13234
13235   M (L2_FIB_CLEAR_TABLE, mp);
13236
13237   S (mp);
13238   W (ret);
13239   return ret;
13240 }
13241
13242 static int
13243 api_l2_interface_efp_filter (vat_main_t * vam)
13244 {
13245   unformat_input_t *i = vam->input;
13246   vl_api_l2_interface_efp_filter_t *mp;
13247   u32 sw_if_index;
13248   u8 enable = 1;
13249   u8 sw_if_index_set = 0;
13250   int ret;
13251
13252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13253     {
13254       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13255         sw_if_index_set = 1;
13256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13257         sw_if_index_set = 1;
13258       else if (unformat (i, "enable"))
13259         enable = 1;
13260       else if (unformat (i, "disable"))
13261         enable = 0;
13262       else
13263         {
13264           clib_warning ("parse error '%U'", format_unformat_error, i);
13265           return -99;
13266         }
13267     }
13268
13269   if (sw_if_index_set == 0)
13270     {
13271       errmsg ("missing sw_if_index");
13272       return -99;
13273     }
13274
13275   M (L2_INTERFACE_EFP_FILTER, mp);
13276
13277   mp->sw_if_index = ntohl (sw_if_index);
13278   mp->enable_disable = enable;
13279
13280   S (mp);
13281   W (ret);
13282   return ret;
13283 }
13284
13285 #define foreach_vtr_op                          \
13286 _("disable",  L2_VTR_DISABLED)                  \
13287 _("push-1",  L2_VTR_PUSH_1)                     \
13288 _("push-2",  L2_VTR_PUSH_2)                     \
13289 _("pop-1",  L2_VTR_POP_1)                       \
13290 _("pop-2",  L2_VTR_POP_2)                       \
13291 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13292 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13293 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13294 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13295
13296 static int
13297 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13298 {
13299   unformat_input_t *i = vam->input;
13300   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13301   u32 sw_if_index;
13302   u8 sw_if_index_set = 0;
13303   u8 vtr_op_set = 0;
13304   u32 vtr_op = 0;
13305   u32 push_dot1q = 1;
13306   u32 tag1 = ~0;
13307   u32 tag2 = ~0;
13308   int ret;
13309
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13313         sw_if_index_set = 1;
13314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13315         sw_if_index_set = 1;
13316       else if (unformat (i, "vtr_op %d", &vtr_op))
13317         vtr_op_set = 1;
13318 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13319       foreach_vtr_op
13320 #undef _
13321         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13322         ;
13323       else if (unformat (i, "tag1 %d", &tag1))
13324         ;
13325       else if (unformat (i, "tag2 %d", &tag2))
13326         ;
13327       else
13328         {
13329           clib_warning ("parse error '%U'", format_unformat_error, i);
13330           return -99;
13331         }
13332     }
13333
13334   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13335     {
13336       errmsg ("missing vtr operation or sw_if_index");
13337       return -99;
13338     }
13339
13340   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13341   mp->sw_if_index = ntohl (sw_if_index);
13342   mp->vtr_op = ntohl (vtr_op);
13343   mp->push_dot1q = ntohl (push_dot1q);
13344   mp->tag1 = ntohl (tag1);
13345   mp->tag2 = ntohl (tag2);
13346
13347   S (mp);
13348   W (ret);
13349   return ret;
13350 }
13351
13352 static int
13353 api_create_vhost_user_if (vat_main_t * vam)
13354 {
13355   unformat_input_t *i = vam->input;
13356   vl_api_create_vhost_user_if_t *mp;
13357   u8 *file_name;
13358   u8 is_server = 0;
13359   u8 file_name_set = 0;
13360   u32 custom_dev_instance = ~0;
13361   u8 hwaddr[6];
13362   u8 use_custom_mac = 0;
13363   u8 *tag = 0;
13364   int ret;
13365
13366   /* Shut up coverity */
13367   memset (hwaddr, 0, sizeof (hwaddr));
13368
13369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (i, "socket %s", &file_name))
13372         {
13373           file_name_set = 1;
13374         }
13375       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13376         ;
13377       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13378         use_custom_mac = 1;
13379       else if (unformat (i, "server"))
13380         is_server = 1;
13381       else if (unformat (i, "tag %s", &tag))
13382         ;
13383       else
13384         break;
13385     }
13386
13387   if (file_name_set == 0)
13388     {
13389       errmsg ("missing socket file name");
13390       return -99;
13391     }
13392
13393   if (vec_len (file_name) > 255)
13394     {
13395       errmsg ("socket file name too long");
13396       return -99;
13397     }
13398   vec_add1 (file_name, 0);
13399
13400   M (CREATE_VHOST_USER_IF, mp);
13401
13402   mp->is_server = is_server;
13403   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13404   vec_free (file_name);
13405   if (custom_dev_instance != ~0)
13406     {
13407       mp->renumber = 1;
13408       mp->custom_dev_instance = ntohl (custom_dev_instance);
13409     }
13410   mp->use_custom_mac = use_custom_mac;
13411   clib_memcpy (mp->mac_address, hwaddr, 6);
13412   if (tag)
13413     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13414   vec_free (tag);
13415
13416   S (mp);
13417   W (ret);
13418   return ret;
13419 }
13420
13421 static int
13422 api_modify_vhost_user_if (vat_main_t * vam)
13423 {
13424   unformat_input_t *i = vam->input;
13425   vl_api_modify_vhost_user_if_t *mp;
13426   u8 *file_name;
13427   u8 is_server = 0;
13428   u8 file_name_set = 0;
13429   u32 custom_dev_instance = ~0;
13430   u8 sw_if_index_set = 0;
13431   u32 sw_if_index = (u32) ~ 0;
13432   int ret;
13433
13434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13435     {
13436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13437         sw_if_index_set = 1;
13438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13439         sw_if_index_set = 1;
13440       else if (unformat (i, "socket %s", &file_name))
13441         {
13442           file_name_set = 1;
13443         }
13444       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13445         ;
13446       else if (unformat (i, "server"))
13447         is_server = 1;
13448       else
13449         break;
13450     }
13451
13452   if (sw_if_index_set == 0)
13453     {
13454       errmsg ("missing sw_if_index or interface name");
13455       return -99;
13456     }
13457
13458   if (file_name_set == 0)
13459     {
13460       errmsg ("missing socket file name");
13461       return -99;
13462     }
13463
13464   if (vec_len (file_name) > 255)
13465     {
13466       errmsg ("socket file name too long");
13467       return -99;
13468     }
13469   vec_add1 (file_name, 0);
13470
13471   M (MODIFY_VHOST_USER_IF, mp);
13472
13473   mp->sw_if_index = ntohl (sw_if_index);
13474   mp->is_server = is_server;
13475   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13476   vec_free (file_name);
13477   if (custom_dev_instance != ~0)
13478     {
13479       mp->renumber = 1;
13480       mp->custom_dev_instance = ntohl (custom_dev_instance);
13481     }
13482
13483   S (mp);
13484   W (ret);
13485   return ret;
13486 }
13487
13488 static int
13489 api_delete_vhost_user_if (vat_main_t * vam)
13490 {
13491   unformat_input_t *i = vam->input;
13492   vl_api_delete_vhost_user_if_t *mp;
13493   u32 sw_if_index = ~0;
13494   u8 sw_if_index_set = 0;
13495   int ret;
13496
13497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13498     {
13499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13500         sw_if_index_set = 1;
13501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13502         sw_if_index_set = 1;
13503       else
13504         break;
13505     }
13506
13507   if (sw_if_index_set == 0)
13508     {
13509       errmsg ("missing sw_if_index or interface name");
13510       return -99;
13511     }
13512
13513
13514   M (DELETE_VHOST_USER_IF, mp);
13515
13516   mp->sw_if_index = ntohl (sw_if_index);
13517
13518   S (mp);
13519   W (ret);
13520   return ret;
13521 }
13522
13523 static void vl_api_sw_interface_vhost_user_details_t_handler
13524   (vl_api_sw_interface_vhost_user_details_t * mp)
13525 {
13526   vat_main_t *vam = &vat_main;
13527
13528   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13529          (char *) mp->interface_name,
13530          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13531          clib_net_to_host_u64 (mp->features), mp->is_server,
13532          ntohl (mp->num_regions), (char *) mp->sock_filename);
13533   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13534 }
13535
13536 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13537   (vl_api_sw_interface_vhost_user_details_t * mp)
13538 {
13539   vat_main_t *vam = &vat_main;
13540   vat_json_node_t *node = NULL;
13541
13542   if (VAT_JSON_ARRAY != vam->json_tree.type)
13543     {
13544       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13545       vat_json_init_array (&vam->json_tree);
13546     }
13547   node = vat_json_array_add (&vam->json_tree);
13548
13549   vat_json_init_object (node);
13550   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13551   vat_json_object_add_string_copy (node, "interface_name",
13552                                    mp->interface_name);
13553   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13554                             ntohl (mp->virtio_net_hdr_sz));
13555   vat_json_object_add_uint (node, "features",
13556                             clib_net_to_host_u64 (mp->features));
13557   vat_json_object_add_uint (node, "is_server", mp->is_server);
13558   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13559   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13560   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13561 }
13562
13563 static int
13564 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13565 {
13566   vl_api_sw_interface_vhost_user_dump_t *mp;
13567   vl_api_control_ping_t *mp_ping;
13568   int ret;
13569   print (vam->ofp,
13570          "Interface name            idx hdr_sz features server regions filename");
13571
13572   /* Get list of vhost-user interfaces */
13573   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13574   S (mp);
13575
13576   /* Use a control ping for synchronization */
13577   MPING (CONTROL_PING, mp_ping);
13578   S (mp_ping);
13579
13580   W (ret);
13581   return ret;
13582 }
13583
13584 static int
13585 api_show_version (vat_main_t * vam)
13586 {
13587   vl_api_show_version_t *mp;
13588   int ret;
13589
13590   M (SHOW_VERSION, mp);
13591
13592   S (mp);
13593   W (ret);
13594   return ret;
13595 }
13596
13597
13598 static int
13599 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13600 {
13601   unformat_input_t *line_input = vam->input;
13602   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13603   ip4_address_t local4, remote4;
13604   ip6_address_t local6, remote6;
13605   u8 is_add = 1;
13606   u8 ipv4_set = 0, ipv6_set = 0;
13607   u8 local_set = 0;
13608   u8 remote_set = 0;
13609   u8 grp_set = 0;
13610   u32 mcast_sw_if_index = ~0;
13611   u32 encap_vrf_id = 0;
13612   u32 decap_vrf_id = 0;
13613   u8 protocol = ~0;
13614   u32 vni;
13615   u8 vni_set = 0;
13616   int ret;
13617
13618   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13619   memset (&local4, 0, sizeof local4);
13620   memset (&remote4, 0, sizeof remote4);
13621   memset (&local6, 0, sizeof local6);
13622   memset (&remote6, 0, sizeof remote6);
13623
13624   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13625     {
13626       if (unformat (line_input, "del"))
13627         is_add = 0;
13628       else if (unformat (line_input, "local %U",
13629                          unformat_ip4_address, &local4))
13630         {
13631           local_set = 1;
13632           ipv4_set = 1;
13633         }
13634       else if (unformat (line_input, "remote %U",
13635                          unformat_ip4_address, &remote4))
13636         {
13637           remote_set = 1;
13638           ipv4_set = 1;
13639         }
13640       else if (unformat (line_input, "local %U",
13641                          unformat_ip6_address, &local6))
13642         {
13643           local_set = 1;
13644           ipv6_set = 1;
13645         }
13646       else if (unformat (line_input, "remote %U",
13647                          unformat_ip6_address, &remote6))
13648         {
13649           remote_set = 1;
13650           ipv6_set = 1;
13651         }
13652       else if (unformat (line_input, "group %U %U",
13653                          unformat_ip4_address, &remote4,
13654                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13655         {
13656           grp_set = remote_set = 1;
13657           ipv4_set = 1;
13658         }
13659       else if (unformat (line_input, "group %U",
13660                          unformat_ip4_address, &remote4))
13661         {
13662           grp_set = remote_set = 1;
13663           ipv4_set = 1;
13664         }
13665       else if (unformat (line_input, "group %U %U",
13666                          unformat_ip6_address, &remote6,
13667                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13668         {
13669           grp_set = remote_set = 1;
13670           ipv6_set = 1;
13671         }
13672       else if (unformat (line_input, "group %U",
13673                          unformat_ip6_address, &remote6))
13674         {
13675           grp_set = remote_set = 1;
13676           ipv6_set = 1;
13677         }
13678       else
13679         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13680         ;
13681       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13682         ;
13683       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13684         ;
13685       else if (unformat (line_input, "vni %d", &vni))
13686         vni_set = 1;
13687       else if (unformat (line_input, "next-ip4"))
13688         protocol = 1;
13689       else if (unformat (line_input, "next-ip6"))
13690         protocol = 2;
13691       else if (unformat (line_input, "next-ethernet"))
13692         protocol = 3;
13693       else if (unformat (line_input, "next-nsh"))
13694         protocol = 4;
13695       else
13696         {
13697           errmsg ("parse error '%U'", format_unformat_error, line_input);
13698           return -99;
13699         }
13700     }
13701
13702   if (local_set == 0)
13703     {
13704       errmsg ("tunnel local address not specified");
13705       return -99;
13706     }
13707   if (remote_set == 0)
13708     {
13709       errmsg ("tunnel remote address not specified");
13710       return -99;
13711     }
13712   if (grp_set && mcast_sw_if_index == ~0)
13713     {
13714       errmsg ("tunnel nonexistent multicast device");
13715       return -99;
13716     }
13717   if (ipv4_set && ipv6_set)
13718     {
13719       errmsg ("both IPv4 and IPv6 addresses specified");
13720       return -99;
13721     }
13722
13723   if (vni_set == 0)
13724     {
13725       errmsg ("vni not specified");
13726       return -99;
13727     }
13728
13729   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13730
13731
13732   if (ipv6_set)
13733     {
13734       clib_memcpy (&mp->local, &local6, sizeof (local6));
13735       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13736     }
13737   else
13738     {
13739       clib_memcpy (&mp->local, &local4, sizeof (local4));
13740       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13741     }
13742
13743   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13744   mp->encap_vrf_id = ntohl (encap_vrf_id);
13745   mp->decap_vrf_id = ntohl (decap_vrf_id);
13746   mp->protocol = protocol;
13747   mp->vni = ntohl (vni);
13748   mp->is_add = is_add;
13749   mp->is_ipv6 = ipv6_set;
13750
13751   S (mp);
13752   W (ret);
13753   return ret;
13754 }
13755
13756 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13757   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13758 {
13759   vat_main_t *vam = &vat_main;
13760   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13761   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13762
13763   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13764          ntohl (mp->sw_if_index),
13765          format_ip46_address, &local, IP46_TYPE_ANY,
13766          format_ip46_address, &remote, IP46_TYPE_ANY,
13767          ntohl (mp->vni), mp->protocol,
13768          ntohl (mp->mcast_sw_if_index),
13769          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13770 }
13771
13772
13773 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13774   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13775 {
13776   vat_main_t *vam = &vat_main;
13777   vat_json_node_t *node = NULL;
13778   struct in_addr ip4;
13779   struct in6_addr ip6;
13780
13781   if (VAT_JSON_ARRAY != vam->json_tree.type)
13782     {
13783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13784       vat_json_init_array (&vam->json_tree);
13785     }
13786   node = vat_json_array_add (&vam->json_tree);
13787
13788   vat_json_init_object (node);
13789   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13790   if (mp->is_ipv6)
13791     {
13792       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13793       vat_json_object_add_ip6 (node, "local", ip6);
13794       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13795       vat_json_object_add_ip6 (node, "remote", ip6);
13796     }
13797   else
13798     {
13799       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13800       vat_json_object_add_ip4 (node, "local", ip4);
13801       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13802       vat_json_object_add_ip4 (node, "remote", ip4);
13803     }
13804   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13805   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13806   vat_json_object_add_uint (node, "mcast_sw_if_index",
13807                             ntohl (mp->mcast_sw_if_index));
13808   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13809   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13810   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13811 }
13812
13813 static int
13814 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13815 {
13816   unformat_input_t *i = vam->input;
13817   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13818   vl_api_control_ping_t *mp_ping;
13819   u32 sw_if_index;
13820   u8 sw_if_index_set = 0;
13821   int ret;
13822
13823   /* Parse args required to build the message */
13824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13825     {
13826       if (unformat (i, "sw_if_index %d", &sw_if_index))
13827         sw_if_index_set = 1;
13828       else
13829         break;
13830     }
13831
13832   if (sw_if_index_set == 0)
13833     {
13834       sw_if_index = ~0;
13835     }
13836
13837   if (!vam->json_output)
13838     {
13839       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13840              "sw_if_index", "local", "remote", "vni",
13841              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13842     }
13843
13844   /* Get list of vxlan-tunnel interfaces */
13845   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13846
13847   mp->sw_if_index = htonl (sw_if_index);
13848
13849   S (mp);
13850
13851   /* Use a control ping for synchronization */
13852   MPING (CONTROL_PING, mp_ping);
13853   S (mp_ping);
13854
13855   W (ret);
13856   return ret;
13857 }
13858
13859 static void vl_api_l2_fib_table_details_t_handler
13860   (vl_api_l2_fib_table_details_t * mp)
13861 {
13862   vat_main_t *vam = &vat_main;
13863
13864   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13865          "       %d       %d     %d",
13866          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13867          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13868          mp->bvi_mac);
13869 }
13870
13871 static void vl_api_l2_fib_table_details_t_handler_json
13872   (vl_api_l2_fib_table_details_t * mp)
13873 {
13874   vat_main_t *vam = &vat_main;
13875   vat_json_node_t *node = NULL;
13876
13877   if (VAT_JSON_ARRAY != vam->json_tree.type)
13878     {
13879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13880       vat_json_init_array (&vam->json_tree);
13881     }
13882   node = vat_json_array_add (&vam->json_tree);
13883
13884   vat_json_init_object (node);
13885   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13886   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13887   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13888   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13889   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13890   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13891 }
13892
13893 static int
13894 api_l2_fib_table_dump (vat_main_t * vam)
13895 {
13896   unformat_input_t *i = vam->input;
13897   vl_api_l2_fib_table_dump_t *mp;
13898   vl_api_control_ping_t *mp_ping;
13899   u32 bd_id;
13900   u8 bd_id_set = 0;
13901   int ret;
13902
13903   /* Parse args required to build the message */
13904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13905     {
13906       if (unformat (i, "bd_id %d", &bd_id))
13907         bd_id_set = 1;
13908       else
13909         break;
13910     }
13911
13912   if (bd_id_set == 0)
13913     {
13914       errmsg ("missing bridge domain");
13915       return -99;
13916     }
13917
13918   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13919
13920   /* Get list of l2 fib entries */
13921   M (L2_FIB_TABLE_DUMP, mp);
13922
13923   mp->bd_id = ntohl (bd_id);
13924   S (mp);
13925
13926   /* Use a control ping for synchronization */
13927   MPING (CONTROL_PING, mp_ping);
13928   S (mp_ping);
13929
13930   W (ret);
13931   return ret;
13932 }
13933
13934
13935 static int
13936 api_interface_name_renumber (vat_main_t * vam)
13937 {
13938   unformat_input_t *line_input = vam->input;
13939   vl_api_interface_name_renumber_t *mp;
13940   u32 sw_if_index = ~0;
13941   u32 new_show_dev_instance = ~0;
13942   int ret;
13943
13944   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13945     {
13946       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13947                     &sw_if_index))
13948         ;
13949       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13950         ;
13951       else if (unformat (line_input, "new_show_dev_instance %d",
13952                          &new_show_dev_instance))
13953         ;
13954       else
13955         break;
13956     }
13957
13958   if (sw_if_index == ~0)
13959     {
13960       errmsg ("missing interface name or sw_if_index");
13961       return -99;
13962     }
13963
13964   if (new_show_dev_instance == ~0)
13965     {
13966       errmsg ("missing new_show_dev_instance");
13967       return -99;
13968     }
13969
13970   M (INTERFACE_NAME_RENUMBER, mp);
13971
13972   mp->sw_if_index = ntohl (sw_if_index);
13973   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13974
13975   S (mp);
13976   W (ret);
13977   return ret;
13978 }
13979
13980 static int
13981 api_want_ip4_arp_events (vat_main_t * vam)
13982 {
13983   unformat_input_t *line_input = vam->input;
13984   vl_api_want_ip4_arp_events_t *mp;
13985   ip4_address_t address;
13986   int address_set = 0;
13987   u32 enable_disable = 1;
13988   int ret;
13989
13990   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13991     {
13992       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13993         address_set = 1;
13994       else if (unformat (line_input, "del"))
13995         enable_disable = 0;
13996       else
13997         break;
13998     }
13999
14000   if (address_set == 0)
14001     {
14002       errmsg ("missing addresses");
14003       return -99;
14004     }
14005
14006   M (WANT_IP4_ARP_EVENTS, mp);
14007   mp->enable_disable = enable_disable;
14008   mp->pid = htonl (getpid ());
14009   mp->address = address.as_u32;
14010
14011   S (mp);
14012   W (ret);
14013   return ret;
14014 }
14015
14016 static int
14017 api_want_ip6_nd_events (vat_main_t * vam)
14018 {
14019   unformat_input_t *line_input = vam->input;
14020   vl_api_want_ip6_nd_events_t *mp;
14021   ip6_address_t address;
14022   int address_set = 0;
14023   u32 enable_disable = 1;
14024   int ret;
14025
14026   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14027     {
14028       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14029         address_set = 1;
14030       else if (unformat (line_input, "del"))
14031         enable_disable = 0;
14032       else
14033         break;
14034     }
14035
14036   if (address_set == 0)
14037     {
14038       errmsg ("missing addresses");
14039       return -99;
14040     }
14041
14042   M (WANT_IP6_ND_EVENTS, mp);
14043   mp->enable_disable = enable_disable;
14044   mp->pid = htonl (getpid ());
14045   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14046
14047   S (mp);
14048   W (ret);
14049   return ret;
14050 }
14051
14052 static int
14053 api_want_l2_macs_events (vat_main_t * vam)
14054 {
14055   unformat_input_t *line_input = vam->input;
14056   vl_api_want_l2_macs_events_t *mp;
14057   u8 enable_disable = 1;
14058   u32 scan_delay = 0;
14059   u32 max_macs_in_event = 0;
14060   u32 learn_limit = 0;
14061   int ret;
14062
14063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14064     {
14065       if (unformat (line_input, "learn-limit %d", &learn_limit))
14066         ;
14067       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14068         ;
14069       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14070         ;
14071       else if (unformat (line_input, "disable"))
14072         enable_disable = 0;
14073       else
14074         break;
14075     }
14076
14077   M (WANT_L2_MACS_EVENTS, mp);
14078   mp->enable_disable = enable_disable;
14079   mp->pid = htonl (getpid ());
14080   mp->learn_limit = htonl (learn_limit);
14081   mp->scan_delay = (u8) scan_delay;
14082   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14083   S (mp);
14084   W (ret);
14085   return ret;
14086 }
14087
14088 static int
14089 api_input_acl_set_interface (vat_main_t * vam)
14090 {
14091   unformat_input_t *i = vam->input;
14092   vl_api_input_acl_set_interface_t *mp;
14093   u32 sw_if_index;
14094   int sw_if_index_set;
14095   u32 ip4_table_index = ~0;
14096   u32 ip6_table_index = ~0;
14097   u32 l2_table_index = ~0;
14098   u8 is_add = 1;
14099   int ret;
14100
14101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14102     {
14103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14104         sw_if_index_set = 1;
14105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14106         sw_if_index_set = 1;
14107       else if (unformat (i, "del"))
14108         is_add = 0;
14109       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14110         ;
14111       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14112         ;
14113       else if (unformat (i, "l2-table %d", &l2_table_index))
14114         ;
14115       else
14116         {
14117           clib_warning ("parse error '%U'", format_unformat_error, i);
14118           return -99;
14119         }
14120     }
14121
14122   if (sw_if_index_set == 0)
14123     {
14124       errmsg ("missing interface name or sw_if_index");
14125       return -99;
14126     }
14127
14128   M (INPUT_ACL_SET_INTERFACE, mp);
14129
14130   mp->sw_if_index = ntohl (sw_if_index);
14131   mp->ip4_table_index = ntohl (ip4_table_index);
14132   mp->ip6_table_index = ntohl (ip6_table_index);
14133   mp->l2_table_index = ntohl (l2_table_index);
14134   mp->is_add = is_add;
14135
14136   S (mp);
14137   W (ret);
14138   return ret;
14139 }
14140
14141 static int
14142 api_ip_address_dump (vat_main_t * vam)
14143 {
14144   unformat_input_t *i = vam->input;
14145   vl_api_ip_address_dump_t *mp;
14146   vl_api_control_ping_t *mp_ping;
14147   u32 sw_if_index = ~0;
14148   u8 sw_if_index_set = 0;
14149   u8 ipv4_set = 0;
14150   u8 ipv6_set = 0;
14151   int ret;
14152
14153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14154     {
14155       if (unformat (i, "sw_if_index %d", &sw_if_index))
14156         sw_if_index_set = 1;
14157       else
14158         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14159         sw_if_index_set = 1;
14160       else if (unformat (i, "ipv4"))
14161         ipv4_set = 1;
14162       else if (unformat (i, "ipv6"))
14163         ipv6_set = 1;
14164       else
14165         break;
14166     }
14167
14168   if (ipv4_set && ipv6_set)
14169     {
14170       errmsg ("ipv4 and ipv6 flags cannot be both set");
14171       return -99;
14172     }
14173
14174   if ((!ipv4_set) && (!ipv6_set))
14175     {
14176       errmsg ("no ipv4 nor ipv6 flag set");
14177       return -99;
14178     }
14179
14180   if (sw_if_index_set == 0)
14181     {
14182       errmsg ("missing interface name or sw_if_index");
14183       return -99;
14184     }
14185
14186   vam->current_sw_if_index = sw_if_index;
14187   vam->is_ipv6 = ipv6_set;
14188
14189   M (IP_ADDRESS_DUMP, mp);
14190   mp->sw_if_index = ntohl (sw_if_index);
14191   mp->is_ipv6 = ipv6_set;
14192   S (mp);
14193
14194   /* Use a control ping for synchronization */
14195   MPING (CONTROL_PING, mp_ping);
14196   S (mp_ping);
14197
14198   W (ret);
14199   return ret;
14200 }
14201
14202 static int
14203 api_ip_dump (vat_main_t * vam)
14204 {
14205   vl_api_ip_dump_t *mp;
14206   vl_api_control_ping_t *mp_ping;
14207   unformat_input_t *in = vam->input;
14208   int ipv4_set = 0;
14209   int ipv6_set = 0;
14210   int is_ipv6;
14211   int i;
14212   int ret;
14213
14214   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14215     {
14216       if (unformat (in, "ipv4"))
14217         ipv4_set = 1;
14218       else if (unformat (in, "ipv6"))
14219         ipv6_set = 1;
14220       else
14221         break;
14222     }
14223
14224   if (ipv4_set && ipv6_set)
14225     {
14226       errmsg ("ipv4 and ipv6 flags cannot be both set");
14227       return -99;
14228     }
14229
14230   if ((!ipv4_set) && (!ipv6_set))
14231     {
14232       errmsg ("no ipv4 nor ipv6 flag set");
14233       return -99;
14234     }
14235
14236   is_ipv6 = ipv6_set;
14237   vam->is_ipv6 = is_ipv6;
14238
14239   /* free old data */
14240   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14241     {
14242       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14243     }
14244   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14245
14246   M (IP_DUMP, mp);
14247   mp->is_ipv6 = ipv6_set;
14248   S (mp);
14249
14250   /* Use a control ping for synchronization */
14251   MPING (CONTROL_PING, mp_ping);
14252   S (mp_ping);
14253
14254   W (ret);
14255   return ret;
14256 }
14257
14258 static int
14259 api_ipsec_spd_add_del (vat_main_t * vam)
14260 {
14261   unformat_input_t *i = vam->input;
14262   vl_api_ipsec_spd_add_del_t *mp;
14263   u32 spd_id = ~0;
14264   u8 is_add = 1;
14265   int ret;
14266
14267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14268     {
14269       if (unformat (i, "spd_id %d", &spd_id))
14270         ;
14271       else if (unformat (i, "del"))
14272         is_add = 0;
14273       else
14274         {
14275           clib_warning ("parse error '%U'", format_unformat_error, i);
14276           return -99;
14277         }
14278     }
14279   if (spd_id == ~0)
14280     {
14281       errmsg ("spd_id must be set");
14282       return -99;
14283     }
14284
14285   M (IPSEC_SPD_ADD_DEL, mp);
14286
14287   mp->spd_id = ntohl (spd_id);
14288   mp->is_add = is_add;
14289
14290   S (mp);
14291   W (ret);
14292   return ret;
14293 }
14294
14295 static int
14296 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14297 {
14298   unformat_input_t *i = vam->input;
14299   vl_api_ipsec_interface_add_del_spd_t *mp;
14300   u32 sw_if_index;
14301   u8 sw_if_index_set = 0;
14302   u32 spd_id = (u32) ~ 0;
14303   u8 is_add = 1;
14304   int ret;
14305
14306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (i, "del"))
14309         is_add = 0;
14310       else if (unformat (i, "spd_id %d", &spd_id))
14311         ;
14312       else
14313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14314         sw_if_index_set = 1;
14315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14316         sw_if_index_set = 1;
14317       else
14318         {
14319           clib_warning ("parse error '%U'", format_unformat_error, i);
14320           return -99;
14321         }
14322
14323     }
14324
14325   if (spd_id == (u32) ~ 0)
14326     {
14327       errmsg ("spd_id must be set");
14328       return -99;
14329     }
14330
14331   if (sw_if_index_set == 0)
14332     {
14333       errmsg ("missing interface name or sw_if_index");
14334       return -99;
14335     }
14336
14337   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14338
14339   mp->spd_id = ntohl (spd_id);
14340   mp->sw_if_index = ntohl (sw_if_index);
14341   mp->is_add = is_add;
14342
14343   S (mp);
14344   W (ret);
14345   return ret;
14346 }
14347
14348 static int
14349 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14350 {
14351   unformat_input_t *i = vam->input;
14352   vl_api_ipsec_spd_add_del_entry_t *mp;
14353   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14354   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14355   i32 priority = 0;
14356   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14357   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14358   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14359   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14360   int ret;
14361
14362   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14363   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14364   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14365   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14366   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14367   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14368
14369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14370     {
14371       if (unformat (i, "del"))
14372         is_add = 0;
14373       if (unformat (i, "outbound"))
14374         is_outbound = 1;
14375       if (unformat (i, "inbound"))
14376         is_outbound = 0;
14377       else if (unformat (i, "spd_id %d", &spd_id))
14378         ;
14379       else if (unformat (i, "sa_id %d", &sa_id))
14380         ;
14381       else if (unformat (i, "priority %d", &priority))
14382         ;
14383       else if (unformat (i, "protocol %d", &protocol))
14384         ;
14385       else if (unformat (i, "lport_start %d", &lport_start))
14386         ;
14387       else if (unformat (i, "lport_stop %d", &lport_stop))
14388         ;
14389       else if (unformat (i, "rport_start %d", &rport_start))
14390         ;
14391       else if (unformat (i, "rport_stop %d", &rport_stop))
14392         ;
14393       else
14394         if (unformat
14395             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14396         {
14397           is_ipv6 = 0;
14398           is_ip_any = 0;
14399         }
14400       else
14401         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14402         {
14403           is_ipv6 = 0;
14404           is_ip_any = 0;
14405         }
14406       else
14407         if (unformat
14408             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14409         {
14410           is_ipv6 = 0;
14411           is_ip_any = 0;
14412         }
14413       else
14414         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14415         {
14416           is_ipv6 = 0;
14417           is_ip_any = 0;
14418         }
14419       else
14420         if (unformat
14421             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14422         {
14423           is_ipv6 = 1;
14424           is_ip_any = 0;
14425         }
14426       else
14427         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14428         {
14429           is_ipv6 = 1;
14430           is_ip_any = 0;
14431         }
14432       else
14433         if (unformat
14434             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14435         {
14436           is_ipv6 = 1;
14437           is_ip_any = 0;
14438         }
14439       else
14440         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14441         {
14442           is_ipv6 = 1;
14443           is_ip_any = 0;
14444         }
14445       else
14446         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14447         {
14448           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14449             {
14450               clib_warning ("unsupported action: 'resolve'");
14451               return -99;
14452             }
14453         }
14454       else
14455         {
14456           clib_warning ("parse error '%U'", format_unformat_error, i);
14457           return -99;
14458         }
14459
14460     }
14461
14462   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14463
14464   mp->spd_id = ntohl (spd_id);
14465   mp->priority = ntohl (priority);
14466   mp->is_outbound = is_outbound;
14467
14468   mp->is_ipv6 = is_ipv6;
14469   if (is_ipv6 || is_ip_any)
14470     {
14471       clib_memcpy (mp->remote_address_start, &raddr6_start,
14472                    sizeof (ip6_address_t));
14473       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14474                    sizeof (ip6_address_t));
14475       clib_memcpy (mp->local_address_start, &laddr6_start,
14476                    sizeof (ip6_address_t));
14477       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14478                    sizeof (ip6_address_t));
14479     }
14480   else
14481     {
14482       clib_memcpy (mp->remote_address_start, &raddr4_start,
14483                    sizeof (ip4_address_t));
14484       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14485                    sizeof (ip4_address_t));
14486       clib_memcpy (mp->local_address_start, &laddr4_start,
14487                    sizeof (ip4_address_t));
14488       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14489                    sizeof (ip4_address_t));
14490     }
14491   mp->protocol = (u8) protocol;
14492   mp->local_port_start = ntohs ((u16) lport_start);
14493   mp->local_port_stop = ntohs ((u16) lport_stop);
14494   mp->remote_port_start = ntohs ((u16) rport_start);
14495   mp->remote_port_stop = ntohs ((u16) rport_stop);
14496   mp->policy = (u8) policy;
14497   mp->sa_id = ntohl (sa_id);
14498   mp->is_add = is_add;
14499   mp->is_ip_any = is_ip_any;
14500   S (mp);
14501   W (ret);
14502   return ret;
14503 }
14504
14505 static int
14506 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14507 {
14508   unformat_input_t *i = vam->input;
14509   vl_api_ipsec_sad_add_del_entry_t *mp;
14510   u32 sad_id = 0, spi = 0;
14511   u8 *ck = 0, *ik = 0;
14512   u8 is_add = 1;
14513
14514   u8 protocol = IPSEC_PROTOCOL_AH;
14515   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14516   u32 crypto_alg = 0, integ_alg = 0;
14517   ip4_address_t tun_src4;
14518   ip4_address_t tun_dst4;
14519   ip6_address_t tun_src6;
14520   ip6_address_t tun_dst6;
14521   int ret;
14522
14523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14524     {
14525       if (unformat (i, "del"))
14526         is_add = 0;
14527       else if (unformat (i, "sad_id %d", &sad_id))
14528         ;
14529       else if (unformat (i, "spi %d", &spi))
14530         ;
14531       else if (unformat (i, "esp"))
14532         protocol = IPSEC_PROTOCOL_ESP;
14533       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14534         {
14535           is_tunnel = 1;
14536           is_tunnel_ipv6 = 0;
14537         }
14538       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14539         {
14540           is_tunnel = 1;
14541           is_tunnel_ipv6 = 0;
14542         }
14543       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14544         {
14545           is_tunnel = 1;
14546           is_tunnel_ipv6 = 1;
14547         }
14548       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14549         {
14550           is_tunnel = 1;
14551           is_tunnel_ipv6 = 1;
14552         }
14553       else
14554         if (unformat
14555             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14556         {
14557           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14558               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14559             {
14560               clib_warning ("unsupported crypto-alg: '%U'",
14561                             format_ipsec_crypto_alg, crypto_alg);
14562               return -99;
14563             }
14564         }
14565       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14566         ;
14567       else
14568         if (unformat
14569             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14570         {
14571           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14572               integ_alg >= IPSEC_INTEG_N_ALG)
14573             {
14574               clib_warning ("unsupported integ-alg: '%U'",
14575                             format_ipsec_integ_alg, integ_alg);
14576               return -99;
14577             }
14578         }
14579       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14580         ;
14581       else
14582         {
14583           clib_warning ("parse error '%U'", format_unformat_error, i);
14584           return -99;
14585         }
14586
14587     }
14588
14589   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14590
14591   mp->sad_id = ntohl (sad_id);
14592   mp->is_add = is_add;
14593   mp->protocol = protocol;
14594   mp->spi = ntohl (spi);
14595   mp->is_tunnel = is_tunnel;
14596   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14597   mp->crypto_algorithm = crypto_alg;
14598   mp->integrity_algorithm = integ_alg;
14599   mp->crypto_key_length = vec_len (ck);
14600   mp->integrity_key_length = vec_len (ik);
14601
14602   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14603     mp->crypto_key_length = sizeof (mp->crypto_key);
14604
14605   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14606     mp->integrity_key_length = sizeof (mp->integrity_key);
14607
14608   if (ck)
14609     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14610   if (ik)
14611     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14612
14613   if (is_tunnel)
14614     {
14615       if (is_tunnel_ipv6)
14616         {
14617           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14618                        sizeof (ip6_address_t));
14619           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14620                        sizeof (ip6_address_t));
14621         }
14622       else
14623         {
14624           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14625                        sizeof (ip4_address_t));
14626           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14627                        sizeof (ip4_address_t));
14628         }
14629     }
14630
14631   S (mp);
14632   W (ret);
14633   return ret;
14634 }
14635
14636 static int
14637 api_ipsec_sa_set_key (vat_main_t * vam)
14638 {
14639   unformat_input_t *i = vam->input;
14640   vl_api_ipsec_sa_set_key_t *mp;
14641   u32 sa_id;
14642   u8 *ck = 0, *ik = 0;
14643   int ret;
14644
14645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14646     {
14647       if (unformat (i, "sa_id %d", &sa_id))
14648         ;
14649       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14650         ;
14651       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14652         ;
14653       else
14654         {
14655           clib_warning ("parse error '%U'", format_unformat_error, i);
14656           return -99;
14657         }
14658     }
14659
14660   M (IPSEC_SA_SET_KEY, mp);
14661
14662   mp->sa_id = ntohl (sa_id);
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   S (mp);
14678   W (ret);
14679   return ret;
14680 }
14681
14682 static int
14683 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14684 {
14685   unformat_input_t *i = vam->input;
14686   vl_api_ipsec_tunnel_if_add_del_t *mp;
14687   u32 local_spi = 0, remote_spi = 0;
14688   u32 crypto_alg = 0, integ_alg = 0;
14689   u8 *lck = NULL, *rck = NULL;
14690   u8 *lik = NULL, *rik = NULL;
14691   ip4_address_t local_ip = { {0} };
14692   ip4_address_t remote_ip = { {0} };
14693   u8 is_add = 1;
14694   u8 esn = 0;
14695   u8 anti_replay = 0;
14696   int ret;
14697
14698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14699     {
14700       if (unformat (i, "del"))
14701         is_add = 0;
14702       else if (unformat (i, "esn"))
14703         esn = 1;
14704       else if (unformat (i, "anti_replay"))
14705         anti_replay = 1;
14706       else if (unformat (i, "local_spi %d", &local_spi))
14707         ;
14708       else if (unformat (i, "remote_spi %d", &remote_spi))
14709         ;
14710       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14711         ;
14712       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14713         ;
14714       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14715         ;
14716       else
14717         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14718         ;
14719       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14720         ;
14721       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14722         ;
14723       else
14724         if (unformat
14725             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14726         {
14727           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14728               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14729             {
14730               errmsg ("unsupported crypto-alg: '%U'\n",
14731                       format_ipsec_crypto_alg, crypto_alg);
14732               return -99;
14733             }
14734         }
14735       else
14736         if (unformat
14737             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14738         {
14739           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14740               integ_alg >= IPSEC_INTEG_N_ALG)
14741             {
14742               errmsg ("unsupported integ-alg: '%U'\n",
14743                       format_ipsec_integ_alg, integ_alg);
14744               return -99;
14745             }
14746         }
14747       else
14748         {
14749           errmsg ("parse error '%U'\n", format_unformat_error, i);
14750           return -99;
14751         }
14752     }
14753
14754   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14755
14756   mp->is_add = is_add;
14757   mp->esn = esn;
14758   mp->anti_replay = anti_replay;
14759
14760   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14761   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14762
14763   mp->local_spi = htonl (local_spi);
14764   mp->remote_spi = htonl (remote_spi);
14765   mp->crypto_alg = (u8) crypto_alg;
14766
14767   mp->local_crypto_key_len = 0;
14768   if (lck)
14769     {
14770       mp->local_crypto_key_len = vec_len (lck);
14771       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14772         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14773       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14774     }
14775
14776   mp->remote_crypto_key_len = 0;
14777   if (rck)
14778     {
14779       mp->remote_crypto_key_len = vec_len (rck);
14780       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14781         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14782       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14783     }
14784
14785   mp->integ_alg = (u8) integ_alg;
14786
14787   mp->local_integ_key_len = 0;
14788   if (lik)
14789     {
14790       mp->local_integ_key_len = vec_len (lik);
14791       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14792         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14793       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14794     }
14795
14796   mp->remote_integ_key_len = 0;
14797   if (rik)
14798     {
14799       mp->remote_integ_key_len = vec_len (rik);
14800       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14801         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14802       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14803     }
14804
14805   S (mp);
14806   W (ret);
14807   return ret;
14808 }
14809
14810 static void
14811 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14812 {
14813   vat_main_t *vam = &vat_main;
14814
14815   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14816          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14817          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14818          "tunnel_src_addr %U tunnel_dst_addr %U "
14819          "salt %u seq_outbound %lu last_seq_inbound %lu "
14820          "replay_window %lu total_data_size %lu\n",
14821          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14822          mp->protocol,
14823          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14824          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14825          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14826          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14827          mp->tunnel_src_addr,
14828          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14829          mp->tunnel_dst_addr,
14830          ntohl (mp->salt),
14831          clib_net_to_host_u64 (mp->seq_outbound),
14832          clib_net_to_host_u64 (mp->last_seq_inbound),
14833          clib_net_to_host_u64 (mp->replay_window),
14834          clib_net_to_host_u64 (mp->total_data_size));
14835 }
14836
14837 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14838 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14839
14840 static void vl_api_ipsec_sa_details_t_handler_json
14841   (vl_api_ipsec_sa_details_t * mp)
14842 {
14843   vat_main_t *vam = &vat_main;
14844   vat_json_node_t *node = NULL;
14845   struct in_addr src_ip4, dst_ip4;
14846   struct in6_addr src_ip6, dst_ip6;
14847
14848   if (VAT_JSON_ARRAY != vam->json_tree.type)
14849     {
14850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14851       vat_json_init_array (&vam->json_tree);
14852     }
14853   node = vat_json_array_add (&vam->json_tree);
14854
14855   vat_json_init_object (node);
14856   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14857   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14858   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14859   vat_json_object_add_uint (node, "proto", mp->protocol);
14860   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14861   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14862   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14863   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14864   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14865   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14866   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14867                              mp->crypto_key_len);
14868   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14869                              mp->integ_key_len);
14870   if (mp->is_tunnel_ip6)
14871     {
14872       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14873       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14874       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14875       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14876     }
14877   else
14878     {
14879       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14880       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14881       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14882       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14883     }
14884   vat_json_object_add_uint (node, "replay_window",
14885                             clib_net_to_host_u64 (mp->replay_window));
14886   vat_json_object_add_uint (node, "total_data_size",
14887                             clib_net_to_host_u64 (mp->total_data_size));
14888
14889 }
14890
14891 static int
14892 api_ipsec_sa_dump (vat_main_t * vam)
14893 {
14894   unformat_input_t *i = vam->input;
14895   vl_api_ipsec_sa_dump_t *mp;
14896   vl_api_control_ping_t *mp_ping;
14897   u32 sa_id = ~0;
14898   int ret;
14899
14900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14901     {
14902       if (unformat (i, "sa_id %d", &sa_id))
14903         ;
14904       else
14905         {
14906           clib_warning ("parse error '%U'", format_unformat_error, i);
14907           return -99;
14908         }
14909     }
14910
14911   M (IPSEC_SA_DUMP, mp);
14912
14913   mp->sa_id = ntohl (sa_id);
14914
14915   S (mp);
14916
14917   /* Use a control ping for synchronization */
14918   M (CONTROL_PING, mp_ping);
14919   S (mp_ping);
14920
14921   W (ret);
14922   return ret;
14923 }
14924
14925 static int
14926 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14927 {
14928   unformat_input_t *i = vam->input;
14929   vl_api_ipsec_tunnel_if_set_key_t *mp;
14930   u32 sw_if_index = ~0;
14931   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14932   u8 *key = 0;
14933   u32 alg = ~0;
14934   int ret;
14935
14936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14937     {
14938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14939         ;
14940       else
14941         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14942         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14943       else
14944         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14945         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14946       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14947         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14948       else
14949         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14950         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14951       else if (unformat (i, "%U", unformat_hex_string, &key))
14952         ;
14953       else
14954         {
14955           clib_warning ("parse error '%U'", format_unformat_error, i);
14956           return -99;
14957         }
14958     }
14959
14960   if (sw_if_index == ~0)
14961     {
14962       errmsg ("interface must be specified");
14963       return -99;
14964     }
14965
14966   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14967     {
14968       errmsg ("key type must be specified");
14969       return -99;
14970     }
14971
14972   if (alg == ~0)
14973     {
14974       errmsg ("algorithm must be specified");
14975       return -99;
14976     }
14977
14978   if (vec_len (key) == 0)
14979     {
14980       errmsg ("key must be specified");
14981       return -99;
14982     }
14983
14984   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14985
14986   mp->sw_if_index = htonl (sw_if_index);
14987   mp->alg = alg;
14988   mp->key_type = key_type;
14989   mp->key_len = vec_len (key);
14990   clib_memcpy (mp->key, key, vec_len (key));
14991
14992   S (mp);
14993   W (ret);
14994
14995   return ret;
14996 }
14997
14998 static int
14999 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15000 {
15001   unformat_input_t *i = vam->input;
15002   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15003   u32 sw_if_index = ~0;
15004   u32 sa_id = ~0;
15005   u8 is_outbound = (u8) ~ 0;
15006   int ret;
15007
15008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15009     {
15010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15011         ;
15012       else if (unformat (i, "sa_id %d", &sa_id))
15013         ;
15014       else if (unformat (i, "outbound"))
15015         is_outbound = 1;
15016       else if (unformat (i, "inbound"))
15017         is_outbound = 0;
15018       else
15019         {
15020           clib_warning ("parse error '%U'", format_unformat_error, i);
15021           return -99;
15022         }
15023     }
15024
15025   if (sw_if_index == ~0)
15026     {
15027       errmsg ("interface must be specified");
15028       return -99;
15029     }
15030
15031   if (sa_id == ~0)
15032     {
15033       errmsg ("SA ID must be specified");
15034       return -99;
15035     }
15036
15037   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15038
15039   mp->sw_if_index = htonl (sw_if_index);
15040   mp->sa_id = htonl (sa_id);
15041   mp->is_outbound = is_outbound;
15042
15043   S (mp);
15044   W (ret);
15045
15046   return ret;
15047 }
15048
15049 static int
15050 api_ikev2_profile_add_del (vat_main_t * vam)
15051 {
15052   unformat_input_t *i = vam->input;
15053   vl_api_ikev2_profile_add_del_t *mp;
15054   u8 is_add = 1;
15055   u8 *name = 0;
15056   int ret;
15057
15058   const char *valid_chars = "a-zA-Z0-9_";
15059
15060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15061     {
15062       if (unformat (i, "del"))
15063         is_add = 0;
15064       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15065         vec_add1 (name, 0);
15066       else
15067         {
15068           errmsg ("parse error '%U'", format_unformat_error, i);
15069           return -99;
15070         }
15071     }
15072
15073   if (!vec_len (name))
15074     {
15075       errmsg ("profile name must be specified");
15076       return -99;
15077     }
15078
15079   if (vec_len (name) > 64)
15080     {
15081       errmsg ("profile name too long");
15082       return -99;
15083     }
15084
15085   M (IKEV2_PROFILE_ADD_DEL, mp);
15086
15087   clib_memcpy (mp->name, name, vec_len (name));
15088   mp->is_add = is_add;
15089   vec_free (name);
15090
15091   S (mp);
15092   W (ret);
15093   return ret;
15094 }
15095
15096 static int
15097 api_ikev2_profile_set_auth (vat_main_t * vam)
15098 {
15099   unformat_input_t *i = vam->input;
15100   vl_api_ikev2_profile_set_auth_t *mp;
15101   u8 *name = 0;
15102   u8 *data = 0;
15103   u32 auth_method = 0;
15104   u8 is_hex = 0;
15105   int ret;
15106
15107   const char *valid_chars = "a-zA-Z0-9_";
15108
15109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15110     {
15111       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15112         vec_add1 (name, 0);
15113       else if (unformat (i, "auth_method %U",
15114                          unformat_ikev2_auth_method, &auth_method))
15115         ;
15116       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15117         is_hex = 1;
15118       else if (unformat (i, "auth_data %v", &data))
15119         ;
15120       else
15121         {
15122           errmsg ("parse error '%U'", format_unformat_error, i);
15123           return -99;
15124         }
15125     }
15126
15127   if (!vec_len (name))
15128     {
15129       errmsg ("profile name must be specified");
15130       return -99;
15131     }
15132
15133   if (vec_len (name) > 64)
15134     {
15135       errmsg ("profile name too long");
15136       return -99;
15137     }
15138
15139   if (!vec_len (data))
15140     {
15141       errmsg ("auth_data must be specified");
15142       return -99;
15143     }
15144
15145   if (!auth_method)
15146     {
15147       errmsg ("auth_method must be specified");
15148       return -99;
15149     }
15150
15151   M (IKEV2_PROFILE_SET_AUTH, mp);
15152
15153   mp->is_hex = is_hex;
15154   mp->auth_method = (u8) auth_method;
15155   mp->data_len = vec_len (data);
15156   clib_memcpy (mp->name, name, vec_len (name));
15157   clib_memcpy (mp->data, data, vec_len (data));
15158   vec_free (name);
15159   vec_free (data);
15160
15161   S (mp);
15162   W (ret);
15163   return ret;
15164 }
15165
15166 static int
15167 api_ikev2_profile_set_id (vat_main_t * vam)
15168 {
15169   unformat_input_t *i = vam->input;
15170   vl_api_ikev2_profile_set_id_t *mp;
15171   u8 *name = 0;
15172   u8 *data = 0;
15173   u8 is_local = 0;
15174   u32 id_type = 0;
15175   ip4_address_t ip4;
15176   int ret;
15177
15178   const char *valid_chars = "a-zA-Z0-9_";
15179
15180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15181     {
15182       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15183         vec_add1 (name, 0);
15184       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15185         ;
15186       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15187         {
15188           data = vec_new (u8, 4);
15189           clib_memcpy (data, ip4.as_u8, 4);
15190         }
15191       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15192         ;
15193       else if (unformat (i, "id_data %v", &data))
15194         ;
15195       else if (unformat (i, "local"))
15196         is_local = 1;
15197       else if (unformat (i, "remote"))
15198         is_local = 0;
15199       else
15200         {
15201           errmsg ("parse error '%U'", format_unformat_error, i);
15202           return -99;
15203         }
15204     }
15205
15206   if (!vec_len (name))
15207     {
15208       errmsg ("profile name must be specified");
15209       return -99;
15210     }
15211
15212   if (vec_len (name) > 64)
15213     {
15214       errmsg ("profile name too long");
15215       return -99;
15216     }
15217
15218   if (!vec_len (data))
15219     {
15220       errmsg ("id_data must be specified");
15221       return -99;
15222     }
15223
15224   if (!id_type)
15225     {
15226       errmsg ("id_type must be specified");
15227       return -99;
15228     }
15229
15230   M (IKEV2_PROFILE_SET_ID, mp);
15231
15232   mp->is_local = is_local;
15233   mp->id_type = (u8) id_type;
15234   mp->data_len = vec_len (data);
15235   clib_memcpy (mp->name, name, vec_len (name));
15236   clib_memcpy (mp->data, data, vec_len (data));
15237   vec_free (name);
15238   vec_free (data);
15239
15240   S (mp);
15241   W (ret);
15242   return ret;
15243 }
15244
15245 static int
15246 api_ikev2_profile_set_ts (vat_main_t * vam)
15247 {
15248   unformat_input_t *i = vam->input;
15249   vl_api_ikev2_profile_set_ts_t *mp;
15250   u8 *name = 0;
15251   u8 is_local = 0;
15252   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15253   ip4_address_t start_addr, end_addr;
15254
15255   const char *valid_chars = "a-zA-Z0-9_";
15256   int ret;
15257
15258   start_addr.as_u32 = 0;
15259   end_addr.as_u32 = (u32) ~ 0;
15260
15261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15262     {
15263       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15264         vec_add1 (name, 0);
15265       else if (unformat (i, "protocol %d", &proto))
15266         ;
15267       else if (unformat (i, "start_port %d", &start_port))
15268         ;
15269       else if (unformat (i, "end_port %d", &end_port))
15270         ;
15271       else
15272         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15273         ;
15274       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15275         ;
15276       else if (unformat (i, "local"))
15277         is_local = 1;
15278       else if (unformat (i, "remote"))
15279         is_local = 0;
15280       else
15281         {
15282           errmsg ("parse error '%U'", format_unformat_error, i);
15283           return -99;
15284         }
15285     }
15286
15287   if (!vec_len (name))
15288     {
15289       errmsg ("profile name must be specified");
15290       return -99;
15291     }
15292
15293   if (vec_len (name) > 64)
15294     {
15295       errmsg ("profile name too long");
15296       return -99;
15297     }
15298
15299   M (IKEV2_PROFILE_SET_TS, mp);
15300
15301   mp->is_local = is_local;
15302   mp->proto = (u8) proto;
15303   mp->start_port = (u16) start_port;
15304   mp->end_port = (u16) end_port;
15305   mp->start_addr = start_addr.as_u32;
15306   mp->end_addr = end_addr.as_u32;
15307   clib_memcpy (mp->name, name, vec_len (name));
15308   vec_free (name);
15309
15310   S (mp);
15311   W (ret);
15312   return ret;
15313 }
15314
15315 static int
15316 api_ikev2_set_local_key (vat_main_t * vam)
15317 {
15318   unformat_input_t *i = vam->input;
15319   vl_api_ikev2_set_local_key_t *mp;
15320   u8 *file = 0;
15321   int ret;
15322
15323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15324     {
15325       if (unformat (i, "file %v", &file))
15326         vec_add1 (file, 0);
15327       else
15328         {
15329           errmsg ("parse error '%U'", format_unformat_error, i);
15330           return -99;
15331         }
15332     }
15333
15334   if (!vec_len (file))
15335     {
15336       errmsg ("RSA key file must be specified");
15337       return -99;
15338     }
15339
15340   if (vec_len (file) > 256)
15341     {
15342       errmsg ("file name too long");
15343       return -99;
15344     }
15345
15346   M (IKEV2_SET_LOCAL_KEY, mp);
15347
15348   clib_memcpy (mp->key_file, file, vec_len (file));
15349   vec_free (file);
15350
15351   S (mp);
15352   W (ret);
15353   return ret;
15354 }
15355
15356 static int
15357 api_ikev2_set_responder (vat_main_t * vam)
15358 {
15359   unformat_input_t *i = vam->input;
15360   vl_api_ikev2_set_responder_t *mp;
15361   int ret;
15362   u8 *name = 0;
15363   u32 sw_if_index = ~0;
15364   ip4_address_t address;
15365
15366   const char *valid_chars = "a-zA-Z0-9_";
15367
15368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat
15371           (i, "%U interface %d address %U", unformat_token, valid_chars,
15372            &name, &sw_if_index, unformat_ip4_address, &address))
15373         vec_add1 (name, 0);
15374       else
15375         {
15376           errmsg ("parse error '%U'", format_unformat_error, i);
15377           return -99;
15378         }
15379     }
15380
15381   if (!vec_len (name))
15382     {
15383       errmsg ("profile name must be specified");
15384       return -99;
15385     }
15386
15387   if (vec_len (name) > 64)
15388     {
15389       errmsg ("profile name too long");
15390       return -99;
15391     }
15392
15393   M (IKEV2_SET_RESPONDER, mp);
15394
15395   clib_memcpy (mp->name, name, vec_len (name));
15396   vec_free (name);
15397
15398   mp->sw_if_index = sw_if_index;
15399   clib_memcpy (mp->address, &address, sizeof (address));
15400
15401   S (mp);
15402   W (ret);
15403   return ret;
15404 }
15405
15406 static int
15407 api_ikev2_set_ike_transforms (vat_main_t * vam)
15408 {
15409   unformat_input_t *i = vam->input;
15410   vl_api_ikev2_set_ike_transforms_t *mp;
15411   int ret;
15412   u8 *name = 0;
15413   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15414
15415   const char *valid_chars = "a-zA-Z0-9_";
15416
15417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15418     {
15419       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15420                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15421         vec_add1 (name, 0);
15422       else
15423         {
15424           errmsg ("parse error '%U'", format_unformat_error, i);
15425           return -99;
15426         }
15427     }
15428
15429   if (!vec_len (name))
15430     {
15431       errmsg ("profile name must be specified");
15432       return -99;
15433     }
15434
15435   if (vec_len (name) > 64)
15436     {
15437       errmsg ("profile name too long");
15438       return -99;
15439     }
15440
15441   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15442
15443   clib_memcpy (mp->name, name, vec_len (name));
15444   vec_free (name);
15445   mp->crypto_alg = crypto_alg;
15446   mp->crypto_key_size = crypto_key_size;
15447   mp->integ_alg = integ_alg;
15448   mp->dh_group = dh_group;
15449
15450   S (mp);
15451   W (ret);
15452   return ret;
15453 }
15454
15455
15456 static int
15457 api_ikev2_set_esp_transforms (vat_main_t * vam)
15458 {
15459   unformat_input_t *i = vam->input;
15460   vl_api_ikev2_set_esp_transforms_t *mp;
15461   int ret;
15462   u8 *name = 0;
15463   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15464
15465   const char *valid_chars = "a-zA-Z0-9_";
15466
15467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15468     {
15469       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15470                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15471         vec_add1 (name, 0);
15472       else
15473         {
15474           errmsg ("parse error '%U'", format_unformat_error, i);
15475           return -99;
15476         }
15477     }
15478
15479   if (!vec_len (name))
15480     {
15481       errmsg ("profile name must be specified");
15482       return -99;
15483     }
15484
15485   if (vec_len (name) > 64)
15486     {
15487       errmsg ("profile name too long");
15488       return -99;
15489     }
15490
15491   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15492
15493   clib_memcpy (mp->name, name, vec_len (name));
15494   vec_free (name);
15495   mp->crypto_alg = crypto_alg;
15496   mp->crypto_key_size = crypto_key_size;
15497   mp->integ_alg = integ_alg;
15498   mp->dh_group = dh_group;
15499
15500   S (mp);
15501   W (ret);
15502   return ret;
15503 }
15504
15505 static int
15506 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15507 {
15508   unformat_input_t *i = vam->input;
15509   vl_api_ikev2_set_sa_lifetime_t *mp;
15510   int ret;
15511   u8 *name = 0;
15512   u64 lifetime, lifetime_maxdata;
15513   u32 lifetime_jitter, handover;
15514
15515   const char *valid_chars = "a-zA-Z0-9_";
15516
15517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15518     {
15519       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15520                     &lifetime, &lifetime_jitter, &handover,
15521                     &lifetime_maxdata))
15522         vec_add1 (name, 0);
15523       else
15524         {
15525           errmsg ("parse error '%U'", format_unformat_error, i);
15526           return -99;
15527         }
15528     }
15529
15530   if (!vec_len (name))
15531     {
15532       errmsg ("profile name must be specified");
15533       return -99;
15534     }
15535
15536   if (vec_len (name) > 64)
15537     {
15538       errmsg ("profile name too long");
15539       return -99;
15540     }
15541
15542   M (IKEV2_SET_SA_LIFETIME, mp);
15543
15544   clib_memcpy (mp->name, name, vec_len (name));
15545   vec_free (name);
15546   mp->lifetime = lifetime;
15547   mp->lifetime_jitter = lifetime_jitter;
15548   mp->handover = handover;
15549   mp->lifetime_maxdata = lifetime_maxdata;
15550
15551   S (mp);
15552   W (ret);
15553   return ret;
15554 }
15555
15556 static int
15557 api_ikev2_initiate_sa_init (vat_main_t * vam)
15558 {
15559   unformat_input_t *i = vam->input;
15560   vl_api_ikev2_initiate_sa_init_t *mp;
15561   int ret;
15562   u8 *name = 0;
15563
15564   const char *valid_chars = "a-zA-Z0-9_";
15565
15566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15567     {
15568       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15569         vec_add1 (name, 0);
15570       else
15571         {
15572           errmsg ("parse error '%U'", format_unformat_error, i);
15573           return -99;
15574         }
15575     }
15576
15577   if (!vec_len (name))
15578     {
15579       errmsg ("profile name must be specified");
15580       return -99;
15581     }
15582
15583   if (vec_len (name) > 64)
15584     {
15585       errmsg ("profile name too long");
15586       return -99;
15587     }
15588
15589   M (IKEV2_INITIATE_SA_INIT, mp);
15590
15591   clib_memcpy (mp->name, name, vec_len (name));
15592   vec_free (name);
15593
15594   S (mp);
15595   W (ret);
15596   return ret;
15597 }
15598
15599 static int
15600 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15601 {
15602   unformat_input_t *i = vam->input;
15603   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15604   int ret;
15605   u64 ispi;
15606
15607
15608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (i, "%lx", &ispi))
15611         ;
15612       else
15613         {
15614           errmsg ("parse error '%U'", format_unformat_error, i);
15615           return -99;
15616         }
15617     }
15618
15619   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15620
15621   mp->ispi = ispi;
15622
15623   S (mp);
15624   W (ret);
15625   return ret;
15626 }
15627
15628 static int
15629 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15630 {
15631   unformat_input_t *i = vam->input;
15632   vl_api_ikev2_initiate_del_child_sa_t *mp;
15633   int ret;
15634   u32 ispi;
15635
15636
15637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15638     {
15639       if (unformat (i, "%x", &ispi))
15640         ;
15641       else
15642         {
15643           errmsg ("parse error '%U'", format_unformat_error, i);
15644           return -99;
15645         }
15646     }
15647
15648   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15649
15650   mp->ispi = ispi;
15651
15652   S (mp);
15653   W (ret);
15654   return ret;
15655 }
15656
15657 static int
15658 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15659 {
15660   unformat_input_t *i = vam->input;
15661   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15662   int ret;
15663   u32 ispi;
15664
15665
15666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (i, "%x", &ispi))
15669         ;
15670       else
15671         {
15672           errmsg ("parse error '%U'", format_unformat_error, i);
15673           return -99;
15674         }
15675     }
15676
15677   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15678
15679   mp->ispi = ispi;
15680
15681   S (mp);
15682   W (ret);
15683   return ret;
15684 }
15685
15686 /*
15687  * MAP
15688  */
15689 static int
15690 api_map_add_domain (vat_main_t * vam)
15691 {
15692   unformat_input_t *i = vam->input;
15693   vl_api_map_add_domain_t *mp;
15694
15695   ip4_address_t ip4_prefix;
15696   ip6_address_t ip6_prefix;
15697   ip6_address_t ip6_src;
15698   u32 num_m_args = 0;
15699   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15700     0, psid_length = 0;
15701   u8 is_translation = 0;
15702   u32 mtu = 0;
15703   u32 ip6_src_len = 128;
15704   int ret;
15705
15706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15707     {
15708       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15709                     &ip4_prefix, &ip4_prefix_len))
15710         num_m_args++;
15711       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15712                          &ip6_prefix, &ip6_prefix_len))
15713         num_m_args++;
15714       else
15715         if (unformat
15716             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15717              &ip6_src_len))
15718         num_m_args++;
15719       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15720         num_m_args++;
15721       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15722         num_m_args++;
15723       else if (unformat (i, "psid-offset %d", &psid_offset))
15724         num_m_args++;
15725       else if (unformat (i, "psid-len %d", &psid_length))
15726         num_m_args++;
15727       else if (unformat (i, "mtu %d", &mtu))
15728         num_m_args++;
15729       else if (unformat (i, "map-t"))
15730         is_translation = 1;
15731       else
15732         {
15733           clib_warning ("parse error '%U'", format_unformat_error, i);
15734           return -99;
15735         }
15736     }
15737
15738   if (num_m_args < 3)
15739     {
15740       errmsg ("mandatory argument(s) missing");
15741       return -99;
15742     }
15743
15744   /* Construct the API message */
15745   M (MAP_ADD_DOMAIN, mp);
15746
15747   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15748   mp->ip4_prefix_len = ip4_prefix_len;
15749
15750   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15751   mp->ip6_prefix_len = ip6_prefix_len;
15752
15753   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15754   mp->ip6_src_prefix_len = ip6_src_len;
15755
15756   mp->ea_bits_len = ea_bits_len;
15757   mp->psid_offset = psid_offset;
15758   mp->psid_length = psid_length;
15759   mp->is_translation = is_translation;
15760   mp->mtu = htons (mtu);
15761
15762   /* send it... */
15763   S (mp);
15764
15765   /* Wait for a reply, return good/bad news  */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 static int
15771 api_map_del_domain (vat_main_t * vam)
15772 {
15773   unformat_input_t *i = vam->input;
15774   vl_api_map_del_domain_t *mp;
15775
15776   u32 num_m_args = 0;
15777   u32 index;
15778   int ret;
15779
15780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15781     {
15782       if (unformat (i, "index %d", &index))
15783         num_m_args++;
15784       else
15785         {
15786           clib_warning ("parse error '%U'", format_unformat_error, i);
15787           return -99;
15788         }
15789     }
15790
15791   if (num_m_args != 1)
15792     {
15793       errmsg ("mandatory argument(s) missing");
15794       return -99;
15795     }
15796
15797   /* Construct the API message */
15798   M (MAP_DEL_DOMAIN, mp);
15799
15800   mp->index = ntohl (index);
15801
15802   /* send it... */
15803   S (mp);
15804
15805   /* Wait for a reply, return good/bad news  */
15806   W (ret);
15807   return ret;
15808 }
15809
15810 static int
15811 api_map_add_del_rule (vat_main_t * vam)
15812 {
15813   unformat_input_t *i = vam->input;
15814   vl_api_map_add_del_rule_t *mp;
15815   u8 is_add = 1;
15816   ip6_address_t ip6_dst;
15817   u32 num_m_args = 0, index, psid = 0;
15818   int ret;
15819
15820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15821     {
15822       if (unformat (i, "index %d", &index))
15823         num_m_args++;
15824       else if (unformat (i, "psid %d", &psid))
15825         num_m_args++;
15826       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15827         num_m_args++;
15828       else if (unformat (i, "del"))
15829         {
15830           is_add = 0;
15831         }
15832       else
15833         {
15834           clib_warning ("parse error '%U'", format_unformat_error, i);
15835           return -99;
15836         }
15837     }
15838
15839   /* Construct the API message */
15840   M (MAP_ADD_DEL_RULE, mp);
15841
15842   mp->index = ntohl (index);
15843   mp->is_add = is_add;
15844   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15845   mp->psid = ntohs (psid);
15846
15847   /* send it... */
15848   S (mp);
15849
15850   /* Wait for a reply, return good/bad news  */
15851   W (ret);
15852   return ret;
15853 }
15854
15855 static int
15856 api_map_domain_dump (vat_main_t * vam)
15857 {
15858   vl_api_map_domain_dump_t *mp;
15859   vl_api_control_ping_t *mp_ping;
15860   int ret;
15861
15862   /* Construct the API message */
15863   M (MAP_DOMAIN_DUMP, mp);
15864
15865   /* send it... */
15866   S (mp);
15867
15868   /* Use a control ping for synchronization */
15869   MPING (CONTROL_PING, mp_ping);
15870   S (mp_ping);
15871
15872   W (ret);
15873   return ret;
15874 }
15875
15876 static int
15877 api_map_rule_dump (vat_main_t * vam)
15878 {
15879   unformat_input_t *i = vam->input;
15880   vl_api_map_rule_dump_t *mp;
15881   vl_api_control_ping_t *mp_ping;
15882   u32 domain_index = ~0;
15883   int ret;
15884
15885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15886     {
15887       if (unformat (i, "index %u", &domain_index))
15888         ;
15889       else
15890         break;
15891     }
15892
15893   if (domain_index == ~0)
15894     {
15895       clib_warning ("parse error: domain index expected");
15896       return -99;
15897     }
15898
15899   /* Construct the API message */
15900   M (MAP_RULE_DUMP, mp);
15901
15902   mp->domain_index = htonl (domain_index);
15903
15904   /* send it... */
15905   S (mp);
15906
15907   /* Use a control ping for synchronization */
15908   MPING (CONTROL_PING, mp_ping);
15909   S (mp_ping);
15910
15911   W (ret);
15912   return ret;
15913 }
15914
15915 static void vl_api_map_add_domain_reply_t_handler
15916   (vl_api_map_add_domain_reply_t * mp)
15917 {
15918   vat_main_t *vam = &vat_main;
15919   i32 retval = ntohl (mp->retval);
15920
15921   if (vam->async_mode)
15922     {
15923       vam->async_errors += (retval < 0);
15924     }
15925   else
15926     {
15927       vam->retval = retval;
15928       vam->result_ready = 1;
15929     }
15930 }
15931
15932 static void vl_api_map_add_domain_reply_t_handler_json
15933   (vl_api_map_add_domain_reply_t * mp)
15934 {
15935   vat_main_t *vam = &vat_main;
15936   vat_json_node_t node;
15937
15938   vat_json_init_object (&node);
15939   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15940   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15941
15942   vat_json_print (vam->ofp, &node);
15943   vat_json_free (&node);
15944
15945   vam->retval = ntohl (mp->retval);
15946   vam->result_ready = 1;
15947 }
15948
15949 static int
15950 api_get_first_msg_id (vat_main_t * vam)
15951 {
15952   vl_api_get_first_msg_id_t *mp;
15953   unformat_input_t *i = vam->input;
15954   u8 *name;
15955   u8 name_set = 0;
15956   int ret;
15957
15958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15959     {
15960       if (unformat (i, "client %s", &name))
15961         name_set = 1;
15962       else
15963         break;
15964     }
15965
15966   if (name_set == 0)
15967     {
15968       errmsg ("missing client name");
15969       return -99;
15970     }
15971   vec_add1 (name, 0);
15972
15973   if (vec_len (name) > 63)
15974     {
15975       errmsg ("client name too long");
15976       return -99;
15977     }
15978
15979   M (GET_FIRST_MSG_ID, mp);
15980   clib_memcpy (mp->name, name, vec_len (name));
15981   S (mp);
15982   W (ret);
15983   return ret;
15984 }
15985
15986 static int
15987 api_cop_interface_enable_disable (vat_main_t * vam)
15988 {
15989   unformat_input_t *line_input = vam->input;
15990   vl_api_cop_interface_enable_disable_t *mp;
15991   u32 sw_if_index = ~0;
15992   u8 enable_disable = 1;
15993   int ret;
15994
15995   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15996     {
15997       if (unformat (line_input, "disable"))
15998         enable_disable = 0;
15999       if (unformat (line_input, "enable"))
16000         enable_disable = 1;
16001       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16002                          vam, &sw_if_index))
16003         ;
16004       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16005         ;
16006       else
16007         break;
16008     }
16009
16010   if (sw_if_index == ~0)
16011     {
16012       errmsg ("missing interface name or sw_if_index");
16013       return -99;
16014     }
16015
16016   /* Construct the API message */
16017   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16018   mp->sw_if_index = ntohl (sw_if_index);
16019   mp->enable_disable = enable_disable;
16020
16021   /* send it... */
16022   S (mp);
16023   /* Wait for the reply */
16024   W (ret);
16025   return ret;
16026 }
16027
16028 static int
16029 api_cop_whitelist_enable_disable (vat_main_t * vam)
16030 {
16031   unformat_input_t *line_input = vam->input;
16032   vl_api_cop_whitelist_enable_disable_t *mp;
16033   u32 sw_if_index = ~0;
16034   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16035   u32 fib_id = 0;
16036   int ret;
16037
16038   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16039     {
16040       if (unformat (line_input, "ip4"))
16041         ip4 = 1;
16042       else if (unformat (line_input, "ip6"))
16043         ip6 = 1;
16044       else if (unformat (line_input, "default"))
16045         default_cop = 1;
16046       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16047                          vam, &sw_if_index))
16048         ;
16049       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16050         ;
16051       else if (unformat (line_input, "fib-id %d", &fib_id))
16052         ;
16053       else
16054         break;
16055     }
16056
16057   if (sw_if_index == ~0)
16058     {
16059       errmsg ("missing interface name or sw_if_index");
16060       return -99;
16061     }
16062
16063   /* Construct the API message */
16064   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16065   mp->sw_if_index = ntohl (sw_if_index);
16066   mp->fib_id = ntohl (fib_id);
16067   mp->ip4 = ip4;
16068   mp->ip6 = ip6;
16069   mp->default_cop = default_cop;
16070
16071   /* send it... */
16072   S (mp);
16073   /* Wait for the reply */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 static int
16079 api_get_node_graph (vat_main_t * vam)
16080 {
16081   vl_api_get_node_graph_t *mp;
16082   int ret;
16083
16084   M (GET_NODE_GRAPH, mp);
16085
16086   /* send it... */
16087   S (mp);
16088   /* Wait for the reply */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 /* *INDENT-OFF* */
16094 /** Used for parsing LISP eids */
16095 typedef CLIB_PACKED(struct{
16096   u8 addr[16];   /**< eid address */
16097   u32 len;       /**< prefix length if IP */
16098   u8 type;      /**< type of eid */
16099 }) lisp_eid_vat_t;
16100 /* *INDENT-ON* */
16101
16102 static uword
16103 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16104 {
16105   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16106
16107   memset (a, 0, sizeof (a[0]));
16108
16109   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16110     {
16111       a->type = 0;              /* ipv4 type */
16112     }
16113   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16114     {
16115       a->type = 1;              /* ipv6 type */
16116     }
16117   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16118     {
16119       a->type = 2;              /* mac type */
16120     }
16121   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16122     {
16123       a->type = 3;              /* NSH type */
16124       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16125       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16126     }
16127   else
16128     {
16129       return 0;
16130     }
16131
16132   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16133     {
16134       return 0;
16135     }
16136
16137   return 1;
16138 }
16139
16140 static int
16141 lisp_eid_size_vat (u8 type)
16142 {
16143   switch (type)
16144     {
16145     case 0:
16146       return 4;
16147     case 1:
16148       return 16;
16149     case 2:
16150       return 6;
16151     case 3:
16152       return 5;
16153     }
16154   return 0;
16155 }
16156
16157 static void
16158 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16159 {
16160   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16161 }
16162
16163 static int
16164 api_one_add_del_locator_set (vat_main_t * vam)
16165 {
16166   unformat_input_t *input = vam->input;
16167   vl_api_one_add_del_locator_set_t *mp;
16168   u8 is_add = 1;
16169   u8 *locator_set_name = NULL;
16170   u8 locator_set_name_set = 0;
16171   vl_api_local_locator_t locator, *locators = 0;
16172   u32 sw_if_index, priority, weight;
16173   u32 data_len = 0;
16174
16175   int ret;
16176   /* Parse args required to build the message */
16177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16178     {
16179       if (unformat (input, "del"))
16180         {
16181           is_add = 0;
16182         }
16183       else if (unformat (input, "locator-set %s", &locator_set_name))
16184         {
16185           locator_set_name_set = 1;
16186         }
16187       else if (unformat (input, "sw_if_index %u p %u w %u",
16188                          &sw_if_index, &priority, &weight))
16189         {
16190           locator.sw_if_index = htonl (sw_if_index);
16191           locator.priority = priority;
16192           locator.weight = weight;
16193           vec_add1 (locators, locator);
16194         }
16195       else
16196         if (unformat
16197             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16198              &sw_if_index, &priority, &weight))
16199         {
16200           locator.sw_if_index = htonl (sw_if_index);
16201           locator.priority = priority;
16202           locator.weight = weight;
16203           vec_add1 (locators, locator);
16204         }
16205       else
16206         break;
16207     }
16208
16209   if (locator_set_name_set == 0)
16210     {
16211       errmsg ("missing locator-set name");
16212       vec_free (locators);
16213       return -99;
16214     }
16215
16216   if (vec_len (locator_set_name) > 64)
16217     {
16218       errmsg ("locator-set name too long");
16219       vec_free (locator_set_name);
16220       vec_free (locators);
16221       return -99;
16222     }
16223   vec_add1 (locator_set_name, 0);
16224
16225   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16226
16227   /* Construct the API message */
16228   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16229
16230   mp->is_add = is_add;
16231   clib_memcpy (mp->locator_set_name, locator_set_name,
16232                vec_len (locator_set_name));
16233   vec_free (locator_set_name);
16234
16235   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16236   if (locators)
16237     clib_memcpy (mp->locators, locators, data_len);
16238   vec_free (locators);
16239
16240   /* send it... */
16241   S (mp);
16242
16243   /* Wait for a reply... */
16244   W (ret);
16245   return ret;
16246 }
16247
16248 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16249
16250 static int
16251 api_one_add_del_locator (vat_main_t * vam)
16252 {
16253   unformat_input_t *input = vam->input;
16254   vl_api_one_add_del_locator_t *mp;
16255   u32 tmp_if_index = ~0;
16256   u32 sw_if_index = ~0;
16257   u8 sw_if_index_set = 0;
16258   u8 sw_if_index_if_name_set = 0;
16259   u32 priority = ~0;
16260   u8 priority_set = 0;
16261   u32 weight = ~0;
16262   u8 weight_set = 0;
16263   u8 is_add = 1;
16264   u8 *locator_set_name = NULL;
16265   u8 locator_set_name_set = 0;
16266   int ret;
16267
16268   /* Parse args required to build the message */
16269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16270     {
16271       if (unformat (input, "del"))
16272         {
16273           is_add = 0;
16274         }
16275       else if (unformat (input, "locator-set %s", &locator_set_name))
16276         {
16277           locator_set_name_set = 1;
16278         }
16279       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16280                          &tmp_if_index))
16281         {
16282           sw_if_index_if_name_set = 1;
16283           sw_if_index = tmp_if_index;
16284         }
16285       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16286         {
16287           sw_if_index_set = 1;
16288           sw_if_index = tmp_if_index;
16289         }
16290       else if (unformat (input, "p %d", &priority))
16291         {
16292           priority_set = 1;
16293         }
16294       else if (unformat (input, "w %d", &weight))
16295         {
16296           weight_set = 1;
16297         }
16298       else
16299         break;
16300     }
16301
16302   if (locator_set_name_set == 0)
16303     {
16304       errmsg ("missing locator-set name");
16305       return -99;
16306     }
16307
16308   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16309     {
16310       errmsg ("missing sw_if_index");
16311       vec_free (locator_set_name);
16312       return -99;
16313     }
16314
16315   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16316     {
16317       errmsg ("cannot use both params interface name and sw_if_index");
16318       vec_free (locator_set_name);
16319       return -99;
16320     }
16321
16322   if (priority_set == 0)
16323     {
16324       errmsg ("missing locator-set priority");
16325       vec_free (locator_set_name);
16326       return -99;
16327     }
16328
16329   if (weight_set == 0)
16330     {
16331       errmsg ("missing locator-set weight");
16332       vec_free (locator_set_name);
16333       return -99;
16334     }
16335
16336   if (vec_len (locator_set_name) > 64)
16337     {
16338       errmsg ("locator-set name too long");
16339       vec_free (locator_set_name);
16340       return -99;
16341     }
16342   vec_add1 (locator_set_name, 0);
16343
16344   /* Construct the API message */
16345   M (ONE_ADD_DEL_LOCATOR, mp);
16346
16347   mp->is_add = is_add;
16348   mp->sw_if_index = ntohl (sw_if_index);
16349   mp->priority = priority;
16350   mp->weight = weight;
16351   clib_memcpy (mp->locator_set_name, locator_set_name,
16352                vec_len (locator_set_name));
16353   vec_free (locator_set_name);
16354
16355   /* send it... */
16356   S (mp);
16357
16358   /* Wait for a reply... */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 #define api_lisp_add_del_locator api_one_add_del_locator
16364
16365 uword
16366 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16367 {
16368   u32 *key_id = va_arg (*args, u32 *);
16369   u8 *s = 0;
16370
16371   if (unformat (input, "%s", &s))
16372     {
16373       if (!strcmp ((char *) s, "sha1"))
16374         key_id[0] = HMAC_SHA_1_96;
16375       else if (!strcmp ((char *) s, "sha256"))
16376         key_id[0] = HMAC_SHA_256_128;
16377       else
16378         {
16379           clib_warning ("invalid key_id: '%s'", s);
16380           key_id[0] = HMAC_NO_KEY;
16381         }
16382     }
16383   else
16384     return 0;
16385
16386   vec_free (s);
16387   return 1;
16388 }
16389
16390 static int
16391 api_one_add_del_local_eid (vat_main_t * vam)
16392 {
16393   unformat_input_t *input = vam->input;
16394   vl_api_one_add_del_local_eid_t *mp;
16395   u8 is_add = 1;
16396   u8 eid_set = 0;
16397   lisp_eid_vat_t _eid, *eid = &_eid;
16398   u8 *locator_set_name = 0;
16399   u8 locator_set_name_set = 0;
16400   u32 vni = 0;
16401   u16 key_id = 0;
16402   u8 *key = 0;
16403   int ret;
16404
16405   /* Parse args required to build the message */
16406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16407     {
16408       if (unformat (input, "del"))
16409         {
16410           is_add = 0;
16411         }
16412       else if (unformat (input, "vni %d", &vni))
16413         {
16414           ;
16415         }
16416       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16417         {
16418           eid_set = 1;
16419         }
16420       else if (unformat (input, "locator-set %s", &locator_set_name))
16421         {
16422           locator_set_name_set = 1;
16423         }
16424       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16425         ;
16426       else if (unformat (input, "secret-key %_%v%_", &key))
16427         ;
16428       else
16429         break;
16430     }
16431
16432   if (locator_set_name_set == 0)
16433     {
16434       errmsg ("missing locator-set name");
16435       return -99;
16436     }
16437
16438   if (0 == eid_set)
16439     {
16440       errmsg ("EID address not set!");
16441       vec_free (locator_set_name);
16442       return -99;
16443     }
16444
16445   if (key && (0 == key_id))
16446     {
16447       errmsg ("invalid key_id!");
16448       return -99;
16449     }
16450
16451   if (vec_len (key) > 64)
16452     {
16453       errmsg ("key too long");
16454       vec_free (key);
16455       return -99;
16456     }
16457
16458   if (vec_len (locator_set_name) > 64)
16459     {
16460       errmsg ("locator-set name too long");
16461       vec_free (locator_set_name);
16462       return -99;
16463     }
16464   vec_add1 (locator_set_name, 0);
16465
16466   /* Construct the API message */
16467   M (ONE_ADD_DEL_LOCAL_EID, mp);
16468
16469   mp->is_add = is_add;
16470   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16471   mp->eid_type = eid->type;
16472   mp->prefix_len = eid->len;
16473   mp->vni = clib_host_to_net_u32 (vni);
16474   mp->key_id = clib_host_to_net_u16 (key_id);
16475   clib_memcpy (mp->locator_set_name, locator_set_name,
16476                vec_len (locator_set_name));
16477   clib_memcpy (mp->key, key, vec_len (key));
16478
16479   vec_free (locator_set_name);
16480   vec_free (key);
16481
16482   /* send it... */
16483   S (mp);
16484
16485   /* Wait for a reply... */
16486   W (ret);
16487   return ret;
16488 }
16489
16490 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16491
16492 static int
16493 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16494 {
16495   u32 dp_table = 0, vni = 0;;
16496   unformat_input_t *input = vam->input;
16497   vl_api_gpe_add_del_fwd_entry_t *mp;
16498   u8 is_add = 1;
16499   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16500   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16501   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16502   u32 action = ~0, w;
16503   ip4_address_t rmt_rloc4, lcl_rloc4;
16504   ip6_address_t rmt_rloc6, lcl_rloc6;
16505   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16506   int ret;
16507
16508   memset (&rloc, 0, sizeof (rloc));
16509
16510   /* Parse args required to build the message */
16511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16512     {
16513       if (unformat (input, "del"))
16514         is_add = 0;
16515       else if (unformat (input, "add"))
16516         is_add = 1;
16517       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16518         {
16519           rmt_eid_set = 1;
16520         }
16521       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16522         {
16523           lcl_eid_set = 1;
16524         }
16525       else if (unformat (input, "vrf %d", &dp_table))
16526         ;
16527       else if (unformat (input, "bd %d", &dp_table))
16528         ;
16529       else if (unformat (input, "vni %d", &vni))
16530         ;
16531       else if (unformat (input, "w %d", &w))
16532         {
16533           if (!curr_rloc)
16534             {
16535               errmsg ("No RLOC configured for setting priority/weight!");
16536               return -99;
16537             }
16538           curr_rloc->weight = w;
16539         }
16540       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16541                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16542         {
16543           rloc.is_ip4 = 1;
16544
16545           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16546           rloc.weight = 0;
16547           vec_add1 (lcl_locs, rloc);
16548
16549           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16550           vec_add1 (rmt_locs, rloc);
16551           /* weight saved in rmt loc */
16552           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16553         }
16554       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16555                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16556         {
16557           rloc.is_ip4 = 0;
16558           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16559           rloc.weight = 0;
16560           vec_add1 (lcl_locs, rloc);
16561
16562           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16563           vec_add1 (rmt_locs, rloc);
16564           /* weight saved in rmt loc */
16565           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16566         }
16567       else if (unformat (input, "action %d", &action))
16568         {
16569           ;
16570         }
16571       else
16572         {
16573           clib_warning ("parse error '%U'", format_unformat_error, input);
16574           return -99;
16575         }
16576     }
16577
16578   if (!rmt_eid_set)
16579     {
16580       errmsg ("remote eid addresses not set");
16581       return -99;
16582     }
16583
16584   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16585     {
16586       errmsg ("eid types don't match");
16587       return -99;
16588     }
16589
16590   if (0 == rmt_locs && (u32) ~ 0 == action)
16591     {
16592       errmsg ("action not set for negative mapping");
16593       return -99;
16594     }
16595
16596   /* Construct the API message */
16597   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16598       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16599
16600   mp->is_add = is_add;
16601   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16602   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16603   mp->eid_type = rmt_eid->type;
16604   mp->dp_table = clib_host_to_net_u32 (dp_table);
16605   mp->vni = clib_host_to_net_u32 (vni);
16606   mp->rmt_len = rmt_eid->len;
16607   mp->lcl_len = lcl_eid->len;
16608   mp->action = action;
16609
16610   if (0 != rmt_locs && 0 != lcl_locs)
16611     {
16612       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16613       clib_memcpy (mp->locs, lcl_locs,
16614                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16615
16616       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16617       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16618                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16619     }
16620   vec_free (lcl_locs);
16621   vec_free (rmt_locs);
16622
16623   /* send it... */
16624   S (mp);
16625
16626   /* Wait for a reply... */
16627   W (ret);
16628   return ret;
16629 }
16630
16631 static int
16632 api_one_add_del_map_server (vat_main_t * vam)
16633 {
16634   unformat_input_t *input = vam->input;
16635   vl_api_one_add_del_map_server_t *mp;
16636   u8 is_add = 1;
16637   u8 ipv4_set = 0;
16638   u8 ipv6_set = 0;
16639   ip4_address_t ipv4;
16640   ip6_address_t ipv6;
16641   int ret;
16642
16643   /* Parse args required to build the message */
16644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16645     {
16646       if (unformat (input, "del"))
16647         {
16648           is_add = 0;
16649         }
16650       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16651         {
16652           ipv4_set = 1;
16653         }
16654       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16655         {
16656           ipv6_set = 1;
16657         }
16658       else
16659         break;
16660     }
16661
16662   if (ipv4_set && ipv6_set)
16663     {
16664       errmsg ("both eid v4 and v6 addresses set");
16665       return -99;
16666     }
16667
16668   if (!ipv4_set && !ipv6_set)
16669     {
16670       errmsg ("eid addresses not set");
16671       return -99;
16672     }
16673
16674   /* Construct the API message */
16675   M (ONE_ADD_DEL_MAP_SERVER, mp);
16676
16677   mp->is_add = is_add;
16678   if (ipv6_set)
16679     {
16680       mp->is_ipv6 = 1;
16681       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16682     }
16683   else
16684     {
16685       mp->is_ipv6 = 0;
16686       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16687     }
16688
16689   /* send it... */
16690   S (mp);
16691
16692   /* Wait for a reply... */
16693   W (ret);
16694   return ret;
16695 }
16696
16697 #define api_lisp_add_del_map_server api_one_add_del_map_server
16698
16699 static int
16700 api_one_add_del_map_resolver (vat_main_t * vam)
16701 {
16702   unformat_input_t *input = vam->input;
16703   vl_api_one_add_del_map_resolver_t *mp;
16704   u8 is_add = 1;
16705   u8 ipv4_set = 0;
16706   u8 ipv6_set = 0;
16707   ip4_address_t ipv4;
16708   ip6_address_t ipv6;
16709   int ret;
16710
16711   /* Parse args required to build the message */
16712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16713     {
16714       if (unformat (input, "del"))
16715         {
16716           is_add = 0;
16717         }
16718       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16719         {
16720           ipv4_set = 1;
16721         }
16722       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16723         {
16724           ipv6_set = 1;
16725         }
16726       else
16727         break;
16728     }
16729
16730   if (ipv4_set && ipv6_set)
16731     {
16732       errmsg ("both eid v4 and v6 addresses set");
16733       return -99;
16734     }
16735
16736   if (!ipv4_set && !ipv6_set)
16737     {
16738       errmsg ("eid addresses not set");
16739       return -99;
16740     }
16741
16742   /* Construct the API message */
16743   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16744
16745   mp->is_add = is_add;
16746   if (ipv6_set)
16747     {
16748       mp->is_ipv6 = 1;
16749       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16750     }
16751   else
16752     {
16753       mp->is_ipv6 = 0;
16754       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16755     }
16756
16757   /* send it... */
16758   S (mp);
16759
16760   /* Wait for a reply... */
16761   W (ret);
16762   return ret;
16763 }
16764
16765 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16766
16767 static int
16768 api_lisp_gpe_enable_disable (vat_main_t * vam)
16769 {
16770   unformat_input_t *input = vam->input;
16771   vl_api_gpe_enable_disable_t *mp;
16772   u8 is_set = 0;
16773   u8 is_en = 1;
16774   int ret;
16775
16776   /* Parse args required to build the message */
16777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16778     {
16779       if (unformat (input, "enable"))
16780         {
16781           is_set = 1;
16782           is_en = 1;
16783         }
16784       else if (unformat (input, "disable"))
16785         {
16786           is_set = 1;
16787           is_en = 0;
16788         }
16789       else
16790         break;
16791     }
16792
16793   if (is_set == 0)
16794     {
16795       errmsg ("Value not set");
16796       return -99;
16797     }
16798
16799   /* Construct the API message */
16800   M (GPE_ENABLE_DISABLE, mp);
16801
16802   mp->is_en = is_en;
16803
16804   /* send it... */
16805   S (mp);
16806
16807   /* Wait for a reply... */
16808   W (ret);
16809   return ret;
16810 }
16811
16812 static int
16813 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16814 {
16815   unformat_input_t *input = vam->input;
16816   vl_api_one_rloc_probe_enable_disable_t *mp;
16817   u8 is_set = 0;
16818   u8 is_en = 0;
16819   int ret;
16820
16821   /* Parse args required to build the message */
16822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (input, "enable"))
16825         {
16826           is_set = 1;
16827           is_en = 1;
16828         }
16829       else if (unformat (input, "disable"))
16830         is_set = 1;
16831       else
16832         break;
16833     }
16834
16835   if (!is_set)
16836     {
16837       errmsg ("Value not set");
16838       return -99;
16839     }
16840
16841   /* Construct the API message */
16842   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16843
16844   mp->is_enabled = is_en;
16845
16846   /* send it... */
16847   S (mp);
16848
16849   /* Wait for a reply... */
16850   W (ret);
16851   return ret;
16852 }
16853
16854 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16855
16856 static int
16857 api_one_map_register_enable_disable (vat_main_t * vam)
16858 {
16859   unformat_input_t *input = vam->input;
16860   vl_api_one_map_register_enable_disable_t *mp;
16861   u8 is_set = 0;
16862   u8 is_en = 0;
16863   int ret;
16864
16865   /* Parse args required to build the message */
16866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16867     {
16868       if (unformat (input, "enable"))
16869         {
16870           is_set = 1;
16871           is_en = 1;
16872         }
16873       else if (unformat (input, "disable"))
16874         is_set = 1;
16875       else
16876         break;
16877     }
16878
16879   if (!is_set)
16880     {
16881       errmsg ("Value not set");
16882       return -99;
16883     }
16884
16885   /* Construct the API message */
16886   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16887
16888   mp->is_enabled = is_en;
16889
16890   /* send it... */
16891   S (mp);
16892
16893   /* Wait for a reply... */
16894   W (ret);
16895   return ret;
16896 }
16897
16898 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16899
16900 static int
16901 api_one_enable_disable (vat_main_t * vam)
16902 {
16903   unformat_input_t *input = vam->input;
16904   vl_api_one_enable_disable_t *mp;
16905   u8 is_set = 0;
16906   u8 is_en = 0;
16907   int ret;
16908
16909   /* Parse args required to build the message */
16910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (input, "enable"))
16913         {
16914           is_set = 1;
16915           is_en = 1;
16916         }
16917       else if (unformat (input, "disable"))
16918         {
16919           is_set = 1;
16920         }
16921       else
16922         break;
16923     }
16924
16925   if (!is_set)
16926     {
16927       errmsg ("Value not set");
16928       return -99;
16929     }
16930
16931   /* Construct the API message */
16932   M (ONE_ENABLE_DISABLE, mp);
16933
16934   mp->is_en = is_en;
16935
16936   /* send it... */
16937   S (mp);
16938
16939   /* Wait for a reply... */
16940   W (ret);
16941   return ret;
16942 }
16943
16944 #define api_lisp_enable_disable api_one_enable_disable
16945
16946 static int
16947 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16948 {
16949   unformat_input_t *input = vam->input;
16950   vl_api_one_enable_disable_xtr_mode_t *mp;
16951   u8 is_set = 0;
16952   u8 is_en = 0;
16953   int ret;
16954
16955   /* Parse args required to build the message */
16956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16957     {
16958       if (unformat (input, "enable"))
16959         {
16960           is_set = 1;
16961           is_en = 1;
16962         }
16963       else if (unformat (input, "disable"))
16964         {
16965           is_set = 1;
16966         }
16967       else
16968         break;
16969     }
16970
16971   if (!is_set)
16972     {
16973       errmsg ("Value not set");
16974       return -99;
16975     }
16976
16977   /* Construct the API message */
16978   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16979
16980   mp->is_en = is_en;
16981
16982   /* send it... */
16983   S (mp);
16984
16985   /* Wait for a reply... */
16986   W (ret);
16987   return ret;
16988 }
16989
16990 static int
16991 api_one_show_xtr_mode (vat_main_t * vam)
16992 {
16993   vl_api_one_show_xtr_mode_t *mp;
16994   int ret;
16995
16996   /* Construct the API message */
16997   M (ONE_SHOW_XTR_MODE, mp);
16998
16999   /* send it... */
17000   S (mp);
17001
17002   /* Wait for a reply... */
17003   W (ret);
17004   return ret;
17005 }
17006
17007 static int
17008 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17009 {
17010   unformat_input_t *input = vam->input;
17011   vl_api_one_enable_disable_pitr_mode_t *mp;
17012   u8 is_set = 0;
17013   u8 is_en = 0;
17014   int ret;
17015
17016   /* Parse args required to build the message */
17017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17018     {
17019       if (unformat (input, "enable"))
17020         {
17021           is_set = 1;
17022           is_en = 1;
17023         }
17024       else if (unformat (input, "disable"))
17025         {
17026           is_set = 1;
17027         }
17028       else
17029         break;
17030     }
17031
17032   if (!is_set)
17033     {
17034       errmsg ("Value not set");
17035       return -99;
17036     }
17037
17038   /* Construct the API message */
17039   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17040
17041   mp->is_en = is_en;
17042
17043   /* send it... */
17044   S (mp);
17045
17046   /* Wait for a reply... */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 static int
17052 api_one_show_pitr_mode (vat_main_t * vam)
17053 {
17054   vl_api_one_show_pitr_mode_t *mp;
17055   int ret;
17056
17057   /* Construct the API message */
17058   M (ONE_SHOW_PITR_MODE, mp);
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 static int
17069 api_one_enable_disable_petr_mode (vat_main_t * vam)
17070 {
17071   unformat_input_t *input = vam->input;
17072   vl_api_one_enable_disable_petr_mode_t *mp;
17073   u8 is_set = 0;
17074   u8 is_en = 0;
17075   int ret;
17076
17077   /* Parse args required to build the message */
17078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17079     {
17080       if (unformat (input, "enable"))
17081         {
17082           is_set = 1;
17083           is_en = 1;
17084         }
17085       else if (unformat (input, "disable"))
17086         {
17087           is_set = 1;
17088         }
17089       else
17090         break;
17091     }
17092
17093   if (!is_set)
17094     {
17095       errmsg ("Value not set");
17096       return -99;
17097     }
17098
17099   /* Construct the API message */
17100   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17101
17102   mp->is_en = is_en;
17103
17104   /* send it... */
17105   S (mp);
17106
17107   /* Wait for a reply... */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 static int
17113 api_one_show_petr_mode (vat_main_t * vam)
17114 {
17115   vl_api_one_show_petr_mode_t *mp;
17116   int ret;
17117
17118   /* Construct the API message */
17119   M (ONE_SHOW_PETR_MODE, mp);
17120
17121   /* send it... */
17122   S (mp);
17123
17124   /* Wait for a reply... */
17125   W (ret);
17126   return ret;
17127 }
17128
17129 static int
17130 api_show_one_map_register_state (vat_main_t * vam)
17131 {
17132   vl_api_show_one_map_register_state_t *mp;
17133   int ret;
17134
17135   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17136
17137   /* send */
17138   S (mp);
17139
17140   /* wait for reply */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 #define api_show_lisp_map_register_state api_show_one_map_register_state
17146
17147 static int
17148 api_show_one_rloc_probe_state (vat_main_t * vam)
17149 {
17150   vl_api_show_one_rloc_probe_state_t *mp;
17151   int ret;
17152
17153   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17154
17155   /* send */
17156   S (mp);
17157
17158   /* wait for reply */
17159   W (ret);
17160   return ret;
17161 }
17162
17163 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17164
17165 static int
17166 api_one_add_del_ndp_entry (vat_main_t * vam)
17167 {
17168   vl_api_one_add_del_ndp_entry_t *mp;
17169   unformat_input_t *input = vam->input;
17170   u8 is_add = 1;
17171   u8 mac_set = 0;
17172   u8 bd_set = 0;
17173   u8 ip_set = 0;
17174   u8 mac[6] = { 0, };
17175   u8 ip6[16] = { 0, };
17176   u32 bd = ~0;
17177   int ret;
17178
17179   /* Parse args required to build the message */
17180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17181     {
17182       if (unformat (input, "del"))
17183         is_add = 0;
17184       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17185         mac_set = 1;
17186       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17187         ip_set = 1;
17188       else if (unformat (input, "bd %d", &bd))
17189         bd_set = 1;
17190       else
17191         {
17192           errmsg ("parse error '%U'", format_unformat_error, input);
17193           return -99;
17194         }
17195     }
17196
17197   if (!bd_set || !ip_set || (!mac_set && is_add))
17198     {
17199       errmsg ("Missing BD, IP or MAC!");
17200       return -99;
17201     }
17202
17203   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17204   mp->is_add = is_add;
17205   clib_memcpy (mp->mac, mac, 6);
17206   mp->bd = clib_host_to_net_u32 (bd);
17207   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17208
17209   /* send */
17210   S (mp);
17211
17212   /* wait for reply */
17213   W (ret);
17214   return ret;
17215 }
17216
17217 static int
17218 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17219 {
17220   vl_api_one_add_del_l2_arp_entry_t *mp;
17221   unformat_input_t *input = vam->input;
17222   u8 is_add = 1;
17223   u8 mac_set = 0;
17224   u8 bd_set = 0;
17225   u8 ip_set = 0;
17226   u8 mac[6] = { 0, };
17227   u32 ip4 = 0, bd = ~0;
17228   int ret;
17229
17230   /* Parse args required to build the message */
17231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17232     {
17233       if (unformat (input, "del"))
17234         is_add = 0;
17235       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17236         mac_set = 1;
17237       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17238         ip_set = 1;
17239       else if (unformat (input, "bd %d", &bd))
17240         bd_set = 1;
17241       else
17242         {
17243           errmsg ("parse error '%U'", format_unformat_error, input);
17244           return -99;
17245         }
17246     }
17247
17248   if (!bd_set || !ip_set || (!mac_set && is_add))
17249     {
17250       errmsg ("Missing BD, IP or MAC!");
17251       return -99;
17252     }
17253
17254   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17255   mp->is_add = is_add;
17256   clib_memcpy (mp->mac, mac, 6);
17257   mp->bd = clib_host_to_net_u32 (bd);
17258   mp->ip4 = ip4;
17259
17260   /* send */
17261   S (mp);
17262
17263   /* wait for reply */
17264   W (ret);
17265   return ret;
17266 }
17267
17268 static int
17269 api_one_ndp_bd_get (vat_main_t * vam)
17270 {
17271   vl_api_one_ndp_bd_get_t *mp;
17272   int ret;
17273
17274   M (ONE_NDP_BD_GET, mp);
17275
17276   /* send */
17277   S (mp);
17278
17279   /* wait for reply */
17280   W (ret);
17281   return ret;
17282 }
17283
17284 static int
17285 api_one_ndp_entries_get (vat_main_t * vam)
17286 {
17287   vl_api_one_ndp_entries_get_t *mp;
17288   unformat_input_t *input = vam->input;
17289   u8 bd_set = 0;
17290   u32 bd = ~0;
17291   int ret;
17292
17293   /* Parse args required to build the message */
17294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17295     {
17296       if (unformat (input, "bd %d", &bd))
17297         bd_set = 1;
17298       else
17299         {
17300           errmsg ("parse error '%U'", format_unformat_error, input);
17301           return -99;
17302         }
17303     }
17304
17305   if (!bd_set)
17306     {
17307       errmsg ("Expected bridge domain!");
17308       return -99;
17309     }
17310
17311   M (ONE_NDP_ENTRIES_GET, mp);
17312   mp->bd = clib_host_to_net_u32 (bd);
17313
17314   /* send */
17315   S (mp);
17316
17317   /* wait for reply */
17318   W (ret);
17319   return ret;
17320 }
17321
17322 static int
17323 api_one_l2_arp_bd_get (vat_main_t * vam)
17324 {
17325   vl_api_one_l2_arp_bd_get_t *mp;
17326   int ret;
17327
17328   M (ONE_L2_ARP_BD_GET, mp);
17329
17330   /* send */
17331   S (mp);
17332
17333   /* wait for reply */
17334   W (ret);
17335   return ret;
17336 }
17337
17338 static int
17339 api_one_l2_arp_entries_get (vat_main_t * vam)
17340 {
17341   vl_api_one_l2_arp_entries_get_t *mp;
17342   unformat_input_t *input = vam->input;
17343   u8 bd_set = 0;
17344   u32 bd = ~0;
17345   int ret;
17346
17347   /* Parse args required to build the message */
17348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17349     {
17350       if (unformat (input, "bd %d", &bd))
17351         bd_set = 1;
17352       else
17353         {
17354           errmsg ("parse error '%U'", format_unformat_error, input);
17355           return -99;
17356         }
17357     }
17358
17359   if (!bd_set)
17360     {
17361       errmsg ("Expected bridge domain!");
17362       return -99;
17363     }
17364
17365   M (ONE_L2_ARP_ENTRIES_GET, mp);
17366   mp->bd = clib_host_to_net_u32 (bd);
17367
17368   /* send */
17369   S (mp);
17370
17371   /* wait for reply */
17372   W (ret);
17373   return ret;
17374 }
17375
17376 static int
17377 api_one_stats_enable_disable (vat_main_t * vam)
17378 {
17379   vl_api_one_stats_enable_disable_t *mp;
17380   unformat_input_t *input = vam->input;
17381   u8 is_set = 0;
17382   u8 is_en = 0;
17383   int ret;
17384
17385   /* Parse args required to build the message */
17386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17387     {
17388       if (unformat (input, "enable"))
17389         {
17390           is_set = 1;
17391           is_en = 1;
17392         }
17393       else if (unformat (input, "disable"))
17394         {
17395           is_set = 1;
17396         }
17397       else
17398         break;
17399     }
17400
17401   if (!is_set)
17402     {
17403       errmsg ("Value not set");
17404       return -99;
17405     }
17406
17407   M (ONE_STATS_ENABLE_DISABLE, mp);
17408   mp->is_en = is_en;
17409
17410   /* send */
17411   S (mp);
17412
17413   /* wait for reply */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 static int
17419 api_show_one_stats_enable_disable (vat_main_t * vam)
17420 {
17421   vl_api_show_one_stats_enable_disable_t *mp;
17422   int ret;
17423
17424   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17425
17426   /* send */
17427   S (mp);
17428
17429   /* wait for reply */
17430   W (ret);
17431   return ret;
17432 }
17433
17434 static int
17435 api_show_one_map_request_mode (vat_main_t * vam)
17436 {
17437   vl_api_show_one_map_request_mode_t *mp;
17438   int ret;
17439
17440   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17441
17442   /* send */
17443   S (mp);
17444
17445   /* wait for reply */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17451
17452 static int
17453 api_one_map_request_mode (vat_main_t * vam)
17454 {
17455   unformat_input_t *input = vam->input;
17456   vl_api_one_map_request_mode_t *mp;
17457   u8 mode = 0;
17458   int ret;
17459
17460   /* Parse args required to build the message */
17461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17462     {
17463       if (unformat (input, "dst-only"))
17464         mode = 0;
17465       else if (unformat (input, "src-dst"))
17466         mode = 1;
17467       else
17468         {
17469           errmsg ("parse error '%U'", format_unformat_error, input);
17470           return -99;
17471         }
17472     }
17473
17474   M (ONE_MAP_REQUEST_MODE, mp);
17475
17476   mp->mode = mode;
17477
17478   /* send */
17479   S (mp);
17480
17481   /* wait for reply */
17482   W (ret);
17483   return ret;
17484 }
17485
17486 #define api_lisp_map_request_mode api_one_map_request_mode
17487
17488 /**
17489  * Enable/disable ONE proxy ITR.
17490  *
17491  * @param vam vpp API test context
17492  * @return return code
17493  */
17494 static int
17495 api_one_pitr_set_locator_set (vat_main_t * vam)
17496 {
17497   u8 ls_name_set = 0;
17498   unformat_input_t *input = vam->input;
17499   vl_api_one_pitr_set_locator_set_t *mp;
17500   u8 is_add = 1;
17501   u8 *ls_name = 0;
17502   int ret;
17503
17504   /* Parse args required to build the message */
17505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17506     {
17507       if (unformat (input, "del"))
17508         is_add = 0;
17509       else if (unformat (input, "locator-set %s", &ls_name))
17510         ls_name_set = 1;
17511       else
17512         {
17513           errmsg ("parse error '%U'", format_unformat_error, input);
17514           return -99;
17515         }
17516     }
17517
17518   if (!ls_name_set)
17519     {
17520       errmsg ("locator-set name not set!");
17521       return -99;
17522     }
17523
17524   M (ONE_PITR_SET_LOCATOR_SET, mp);
17525
17526   mp->is_add = is_add;
17527   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17528   vec_free (ls_name);
17529
17530   /* send */
17531   S (mp);
17532
17533   /* wait for reply */
17534   W (ret);
17535   return ret;
17536 }
17537
17538 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17539
17540 static int
17541 api_one_nsh_set_locator_set (vat_main_t * vam)
17542 {
17543   u8 ls_name_set = 0;
17544   unformat_input_t *input = vam->input;
17545   vl_api_one_nsh_set_locator_set_t *mp;
17546   u8 is_add = 1;
17547   u8 *ls_name = 0;
17548   int ret;
17549
17550   /* Parse args required to build the message */
17551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17552     {
17553       if (unformat (input, "del"))
17554         is_add = 0;
17555       else if (unformat (input, "ls %s", &ls_name))
17556         ls_name_set = 1;
17557       else
17558         {
17559           errmsg ("parse error '%U'", format_unformat_error, input);
17560           return -99;
17561         }
17562     }
17563
17564   if (!ls_name_set && is_add)
17565     {
17566       errmsg ("locator-set name not set!");
17567       return -99;
17568     }
17569
17570   M (ONE_NSH_SET_LOCATOR_SET, mp);
17571
17572   mp->is_add = is_add;
17573   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17574   vec_free (ls_name);
17575
17576   /* send */
17577   S (mp);
17578
17579   /* wait for reply */
17580   W (ret);
17581   return ret;
17582 }
17583
17584 static int
17585 api_show_one_pitr (vat_main_t * vam)
17586 {
17587   vl_api_show_one_pitr_t *mp;
17588   int ret;
17589
17590   if (!vam->json_output)
17591     {
17592       print (vam->ofp, "%=20s", "lisp status:");
17593     }
17594
17595   M (SHOW_ONE_PITR, mp);
17596   /* send it... */
17597   S (mp);
17598
17599   /* Wait for a reply... */
17600   W (ret);
17601   return ret;
17602 }
17603
17604 #define api_show_lisp_pitr api_show_one_pitr
17605
17606 static int
17607 api_one_use_petr (vat_main_t * vam)
17608 {
17609   unformat_input_t *input = vam->input;
17610   vl_api_one_use_petr_t *mp;
17611   u8 is_add = 0;
17612   ip_address_t ip;
17613   int ret;
17614
17615   memset (&ip, 0, sizeof (ip));
17616
17617   /* Parse args required to build the message */
17618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17619     {
17620       if (unformat (input, "disable"))
17621         is_add = 0;
17622       else
17623         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17624         {
17625           is_add = 1;
17626           ip_addr_version (&ip) = IP4;
17627         }
17628       else
17629         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17630         {
17631           is_add = 1;
17632           ip_addr_version (&ip) = IP6;
17633         }
17634       else
17635         {
17636           errmsg ("parse error '%U'", format_unformat_error, input);
17637           return -99;
17638         }
17639     }
17640
17641   M (ONE_USE_PETR, mp);
17642
17643   mp->is_add = is_add;
17644   if (is_add)
17645     {
17646       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17647       if (mp->is_ip4)
17648         clib_memcpy (mp->address, &ip, 4);
17649       else
17650         clib_memcpy (mp->address, &ip, 16);
17651     }
17652
17653   /* send */
17654   S (mp);
17655
17656   /* wait for reply */
17657   W (ret);
17658   return ret;
17659 }
17660
17661 #define api_lisp_use_petr api_one_use_petr
17662
17663 static int
17664 api_show_one_nsh_mapping (vat_main_t * vam)
17665 {
17666   vl_api_show_one_use_petr_t *mp;
17667   int ret;
17668
17669   if (!vam->json_output)
17670     {
17671       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17672     }
17673
17674   M (SHOW_ONE_NSH_MAPPING, mp);
17675   /* send it... */
17676   S (mp);
17677
17678   /* Wait for a reply... */
17679   W (ret);
17680   return ret;
17681 }
17682
17683 static int
17684 api_show_one_use_petr (vat_main_t * vam)
17685 {
17686   vl_api_show_one_use_petr_t *mp;
17687   int ret;
17688
17689   if (!vam->json_output)
17690     {
17691       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17692     }
17693
17694   M (SHOW_ONE_USE_PETR, mp);
17695   /* send it... */
17696   S (mp);
17697
17698   /* Wait for a reply... */
17699   W (ret);
17700   return ret;
17701 }
17702
17703 #define api_show_lisp_use_petr api_show_one_use_petr
17704
17705 /**
17706  * Add/delete mapping between vni and vrf
17707  */
17708 static int
17709 api_one_eid_table_add_del_map (vat_main_t * vam)
17710 {
17711   unformat_input_t *input = vam->input;
17712   vl_api_one_eid_table_add_del_map_t *mp;
17713   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17714   u32 vni, vrf, bd_index;
17715   int ret;
17716
17717   /* Parse args required to build the message */
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "del"))
17721         is_add = 0;
17722       else if (unformat (input, "vrf %d", &vrf))
17723         vrf_set = 1;
17724       else if (unformat (input, "bd_index %d", &bd_index))
17725         bd_index_set = 1;
17726       else if (unformat (input, "vni %d", &vni))
17727         vni_set = 1;
17728       else
17729         break;
17730     }
17731
17732   if (!vni_set || (!vrf_set && !bd_index_set))
17733     {
17734       errmsg ("missing arguments!");
17735       return -99;
17736     }
17737
17738   if (vrf_set && bd_index_set)
17739     {
17740       errmsg ("error: both vrf and bd entered!");
17741       return -99;
17742     }
17743
17744   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17745
17746   mp->is_add = is_add;
17747   mp->vni = htonl (vni);
17748   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17749   mp->is_l2 = bd_index_set;
17750
17751   /* send */
17752   S (mp);
17753
17754   /* wait for reply */
17755   W (ret);
17756   return ret;
17757 }
17758
17759 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17760
17761 uword
17762 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17763 {
17764   u32 *action = va_arg (*args, u32 *);
17765   u8 *s = 0;
17766
17767   if (unformat (input, "%s", &s))
17768     {
17769       if (!strcmp ((char *) s, "no-action"))
17770         action[0] = 0;
17771       else if (!strcmp ((char *) s, "natively-forward"))
17772         action[0] = 1;
17773       else if (!strcmp ((char *) s, "send-map-request"))
17774         action[0] = 2;
17775       else if (!strcmp ((char *) s, "drop"))
17776         action[0] = 3;
17777       else
17778         {
17779           clib_warning ("invalid action: '%s'", s);
17780           action[0] = 3;
17781         }
17782     }
17783   else
17784     return 0;
17785
17786   vec_free (s);
17787   return 1;
17788 }
17789
17790 /**
17791  * Add/del remote mapping to/from ONE control plane
17792  *
17793  * @param vam vpp API test context
17794  * @return return code
17795  */
17796 static int
17797 api_one_add_del_remote_mapping (vat_main_t * vam)
17798 {
17799   unformat_input_t *input = vam->input;
17800   vl_api_one_add_del_remote_mapping_t *mp;
17801   u32 vni = 0;
17802   lisp_eid_vat_t _eid, *eid = &_eid;
17803   lisp_eid_vat_t _seid, *seid = &_seid;
17804   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17805   u32 action = ~0, p, w, data_len;
17806   ip4_address_t rloc4;
17807   ip6_address_t rloc6;
17808   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17809   int ret;
17810
17811   memset (&rloc, 0, sizeof (rloc));
17812
17813   /* Parse args required to build the message */
17814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (input, "del-all"))
17817         {
17818           del_all = 1;
17819         }
17820       else if (unformat (input, "del"))
17821         {
17822           is_add = 0;
17823         }
17824       else if (unformat (input, "add"))
17825         {
17826           is_add = 1;
17827         }
17828       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17829         {
17830           eid_set = 1;
17831         }
17832       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17833         {
17834           seid_set = 1;
17835         }
17836       else if (unformat (input, "vni %d", &vni))
17837         {
17838           ;
17839         }
17840       else if (unformat (input, "p %d w %d", &p, &w))
17841         {
17842           if (!curr_rloc)
17843             {
17844               errmsg ("No RLOC configured for setting priority/weight!");
17845               return -99;
17846             }
17847           curr_rloc->priority = p;
17848           curr_rloc->weight = w;
17849         }
17850       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17851         {
17852           rloc.is_ip4 = 1;
17853           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17854           vec_add1 (rlocs, rloc);
17855           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17856         }
17857       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17858         {
17859           rloc.is_ip4 = 0;
17860           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17861           vec_add1 (rlocs, rloc);
17862           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17863         }
17864       else if (unformat (input, "action %U",
17865                          unformat_negative_mapping_action, &action))
17866         {
17867           ;
17868         }
17869       else
17870         {
17871           clib_warning ("parse error '%U'", format_unformat_error, input);
17872           return -99;
17873         }
17874     }
17875
17876   if (0 == eid_set)
17877     {
17878       errmsg ("missing params!");
17879       return -99;
17880     }
17881
17882   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17883     {
17884       errmsg ("no action set for negative map-reply!");
17885       return -99;
17886     }
17887
17888   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17889
17890   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17891   mp->is_add = is_add;
17892   mp->vni = htonl (vni);
17893   mp->action = (u8) action;
17894   mp->is_src_dst = seid_set;
17895   mp->eid_len = eid->len;
17896   mp->seid_len = seid->len;
17897   mp->del_all = del_all;
17898   mp->eid_type = eid->type;
17899   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17900   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17901
17902   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17903   clib_memcpy (mp->rlocs, rlocs, data_len);
17904   vec_free (rlocs);
17905
17906   /* send it... */
17907   S (mp);
17908
17909   /* Wait for a reply... */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17915
17916 /**
17917  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17918  * forwarding entries in data-plane accordingly.
17919  *
17920  * @param vam vpp API test context
17921  * @return return code
17922  */
17923 static int
17924 api_one_add_del_adjacency (vat_main_t * vam)
17925 {
17926   unformat_input_t *input = vam->input;
17927   vl_api_one_add_del_adjacency_t *mp;
17928   u32 vni = 0;
17929   ip4_address_t leid4, reid4;
17930   ip6_address_t leid6, reid6;
17931   u8 reid_mac[6] = { 0 };
17932   u8 leid_mac[6] = { 0 };
17933   u8 reid_type, leid_type;
17934   u32 leid_len = 0, reid_len = 0, len;
17935   u8 is_add = 1;
17936   int ret;
17937
17938   leid_type = reid_type = (u8) ~ 0;
17939
17940   /* Parse args required to build the message */
17941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17942     {
17943       if (unformat (input, "del"))
17944         {
17945           is_add = 0;
17946         }
17947       else if (unformat (input, "add"))
17948         {
17949           is_add = 1;
17950         }
17951       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17952                          &reid4, &len))
17953         {
17954           reid_type = 0;        /* ipv4 */
17955           reid_len = len;
17956         }
17957       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17958                          &reid6, &len))
17959         {
17960           reid_type = 1;        /* ipv6 */
17961           reid_len = len;
17962         }
17963       else if (unformat (input, "reid %U", unformat_ethernet_address,
17964                          reid_mac))
17965         {
17966           reid_type = 2;        /* mac */
17967         }
17968       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17969                          &leid4, &len))
17970         {
17971           leid_type = 0;        /* ipv4 */
17972           leid_len = len;
17973         }
17974       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17975                          &leid6, &len))
17976         {
17977           leid_type = 1;        /* ipv6 */
17978           leid_len = len;
17979         }
17980       else if (unformat (input, "leid %U", unformat_ethernet_address,
17981                          leid_mac))
17982         {
17983           leid_type = 2;        /* mac */
17984         }
17985       else if (unformat (input, "vni %d", &vni))
17986         {
17987           ;
17988         }
17989       else
17990         {
17991           errmsg ("parse error '%U'", format_unformat_error, input);
17992           return -99;
17993         }
17994     }
17995
17996   if ((u8) ~ 0 == reid_type)
17997     {
17998       errmsg ("missing params!");
17999       return -99;
18000     }
18001
18002   if (leid_type != reid_type)
18003     {
18004       errmsg ("remote and local EIDs are of different types!");
18005       return -99;
18006     }
18007
18008   M (ONE_ADD_DEL_ADJACENCY, mp);
18009   mp->is_add = is_add;
18010   mp->vni = htonl (vni);
18011   mp->leid_len = leid_len;
18012   mp->reid_len = reid_len;
18013   mp->eid_type = reid_type;
18014
18015   switch (mp->eid_type)
18016     {
18017     case 0:
18018       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18019       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18020       break;
18021     case 1:
18022       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18023       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18024       break;
18025     case 2:
18026       clib_memcpy (mp->leid, leid_mac, 6);
18027       clib_memcpy (mp->reid, reid_mac, 6);
18028       break;
18029     default:
18030       errmsg ("unknown EID type %d!", mp->eid_type);
18031       return 0;
18032     }
18033
18034   /* send it... */
18035   S (mp);
18036
18037   /* Wait for a reply... */
18038   W (ret);
18039   return ret;
18040 }
18041
18042 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18043
18044 uword
18045 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18046 {
18047   u32 *mode = va_arg (*args, u32 *);
18048
18049   if (unformat (input, "lisp"))
18050     *mode = 0;
18051   else if (unformat (input, "vxlan"))
18052     *mode = 1;
18053   else
18054     return 0;
18055
18056   return 1;
18057 }
18058
18059 static int
18060 api_gpe_get_encap_mode (vat_main_t * vam)
18061 {
18062   vl_api_gpe_get_encap_mode_t *mp;
18063   int ret;
18064
18065   /* Construct the API message */
18066   M (GPE_GET_ENCAP_MODE, mp);
18067
18068   /* send it... */
18069   S (mp);
18070
18071   /* Wait for a reply... */
18072   W (ret);
18073   return ret;
18074 }
18075
18076 static int
18077 api_gpe_set_encap_mode (vat_main_t * vam)
18078 {
18079   unformat_input_t *input = vam->input;
18080   vl_api_gpe_set_encap_mode_t *mp;
18081   int ret;
18082   u32 mode = 0;
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18088         ;
18089       else
18090         break;
18091     }
18092
18093   /* Construct the API message */
18094   M (GPE_SET_ENCAP_MODE, mp);
18095
18096   mp->mode = mode;
18097
18098   /* send it... */
18099   S (mp);
18100
18101   /* Wait for a reply... */
18102   W (ret);
18103   return ret;
18104 }
18105
18106 static int
18107 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18108 {
18109   unformat_input_t *input = vam->input;
18110   vl_api_gpe_add_del_iface_t *mp;
18111   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18112   u32 dp_table = 0, vni = 0;
18113   int ret;
18114
18115   /* Parse args required to build the message */
18116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18117     {
18118       if (unformat (input, "up"))
18119         {
18120           action_set = 1;
18121           is_add = 1;
18122         }
18123       else if (unformat (input, "down"))
18124         {
18125           action_set = 1;
18126           is_add = 0;
18127         }
18128       else if (unformat (input, "table_id %d", &dp_table))
18129         {
18130           dp_table_set = 1;
18131         }
18132       else if (unformat (input, "bd_id %d", &dp_table))
18133         {
18134           dp_table_set = 1;
18135           is_l2 = 1;
18136         }
18137       else if (unformat (input, "vni %d", &vni))
18138         {
18139           vni_set = 1;
18140         }
18141       else
18142         break;
18143     }
18144
18145   if (action_set == 0)
18146     {
18147       errmsg ("Action not set");
18148       return -99;
18149     }
18150   if (dp_table_set == 0 || vni_set == 0)
18151     {
18152       errmsg ("vni and dp_table must be set");
18153       return -99;
18154     }
18155
18156   /* Construct the API message */
18157   M (GPE_ADD_DEL_IFACE, mp);
18158
18159   mp->is_add = is_add;
18160   mp->dp_table = clib_host_to_net_u32 (dp_table);
18161   mp->is_l2 = is_l2;
18162   mp->vni = clib_host_to_net_u32 (vni);
18163
18164   /* send it... */
18165   S (mp);
18166
18167   /* Wait for a reply... */
18168   W (ret);
18169   return ret;
18170 }
18171
18172 static int
18173 api_one_map_register_fallback_threshold (vat_main_t * vam)
18174 {
18175   unformat_input_t *input = vam->input;
18176   vl_api_one_map_register_fallback_threshold_t *mp;
18177   u32 value = 0;
18178   u8 is_set = 0;
18179   int ret;
18180
18181   /* Parse args required to build the message */
18182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18183     {
18184       if (unformat (input, "%u", &value))
18185         is_set = 1;
18186       else
18187         {
18188           clib_warning ("parse error '%U'", format_unformat_error, input);
18189           return -99;
18190         }
18191     }
18192
18193   if (!is_set)
18194     {
18195       errmsg ("fallback threshold value is missing!");
18196       return -99;
18197     }
18198
18199   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18200   mp->value = clib_host_to_net_u32 (value);
18201
18202   /* send it... */
18203   S (mp);
18204
18205   /* Wait for a reply... */
18206   W (ret);
18207   return ret;
18208 }
18209
18210 static int
18211 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18212 {
18213   vl_api_show_one_map_register_fallback_threshold_t *mp;
18214   int ret;
18215
18216   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18217
18218   /* send it... */
18219   S (mp);
18220
18221   /* Wait for a reply... */
18222   W (ret);
18223   return ret;
18224 }
18225
18226 uword
18227 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18228 {
18229   u32 *proto = va_arg (*args, u32 *);
18230
18231   if (unformat (input, "udp"))
18232     *proto = 1;
18233   else if (unformat (input, "api"))
18234     *proto = 2;
18235   else
18236     return 0;
18237
18238   return 1;
18239 }
18240
18241 static int
18242 api_one_set_transport_protocol (vat_main_t * vam)
18243 {
18244   unformat_input_t *input = vam->input;
18245   vl_api_one_set_transport_protocol_t *mp;
18246   u8 is_set = 0;
18247   u32 protocol = 0;
18248   int ret;
18249
18250   /* Parse args required to build the message */
18251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18252     {
18253       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18254         is_set = 1;
18255       else
18256         {
18257           clib_warning ("parse error '%U'", format_unformat_error, input);
18258           return -99;
18259         }
18260     }
18261
18262   if (!is_set)
18263     {
18264       errmsg ("Transport protocol missing!");
18265       return -99;
18266     }
18267
18268   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18269   mp->protocol = (u8) protocol;
18270
18271   /* send it... */
18272   S (mp);
18273
18274   /* Wait for a reply... */
18275   W (ret);
18276   return ret;
18277 }
18278
18279 static int
18280 api_one_get_transport_protocol (vat_main_t * vam)
18281 {
18282   vl_api_one_get_transport_protocol_t *mp;
18283   int ret;
18284
18285   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18286
18287   /* send it... */
18288   S (mp);
18289
18290   /* Wait for a reply... */
18291   W (ret);
18292   return ret;
18293 }
18294
18295 static int
18296 api_one_map_register_set_ttl (vat_main_t * vam)
18297 {
18298   unformat_input_t *input = vam->input;
18299   vl_api_one_map_register_set_ttl_t *mp;
18300   u32 ttl = 0;
18301   u8 is_set = 0;
18302   int ret;
18303
18304   /* Parse args required to build the message */
18305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18306     {
18307       if (unformat (input, "%u", &ttl))
18308         is_set = 1;
18309       else
18310         {
18311           clib_warning ("parse error '%U'", format_unformat_error, input);
18312           return -99;
18313         }
18314     }
18315
18316   if (!is_set)
18317     {
18318       errmsg ("TTL value missing!");
18319       return -99;
18320     }
18321
18322   M (ONE_MAP_REGISTER_SET_TTL, mp);
18323   mp->ttl = clib_host_to_net_u32 (ttl);
18324
18325   /* send it... */
18326   S (mp);
18327
18328   /* Wait for a reply... */
18329   W (ret);
18330   return ret;
18331 }
18332
18333 static int
18334 api_show_one_map_register_ttl (vat_main_t * vam)
18335 {
18336   vl_api_show_one_map_register_ttl_t *mp;
18337   int ret;
18338
18339   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18340
18341   /* send it... */
18342   S (mp);
18343
18344   /* Wait for a reply... */
18345   W (ret);
18346   return ret;
18347 }
18348
18349 /**
18350  * Add/del map request itr rlocs from ONE control plane and updates
18351  *
18352  * @param vam vpp API test context
18353  * @return return code
18354  */
18355 static int
18356 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18357 {
18358   unformat_input_t *input = vam->input;
18359   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18360   u8 *locator_set_name = 0;
18361   u8 locator_set_name_set = 0;
18362   u8 is_add = 1;
18363   int ret;
18364
18365   /* Parse args required to build the message */
18366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18367     {
18368       if (unformat (input, "del"))
18369         {
18370           is_add = 0;
18371         }
18372       else if (unformat (input, "%_%v%_", &locator_set_name))
18373         {
18374           locator_set_name_set = 1;
18375         }
18376       else
18377         {
18378           clib_warning ("parse error '%U'", format_unformat_error, input);
18379           return -99;
18380         }
18381     }
18382
18383   if (is_add && !locator_set_name_set)
18384     {
18385       errmsg ("itr-rloc is not set!");
18386       return -99;
18387     }
18388
18389   if (is_add && vec_len (locator_set_name) > 64)
18390     {
18391       errmsg ("itr-rloc locator-set name too long");
18392       vec_free (locator_set_name);
18393       return -99;
18394     }
18395
18396   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18397   mp->is_add = is_add;
18398   if (is_add)
18399     {
18400       clib_memcpy (mp->locator_set_name, locator_set_name,
18401                    vec_len (locator_set_name));
18402     }
18403   else
18404     {
18405       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18406     }
18407   vec_free (locator_set_name);
18408
18409   /* send it... */
18410   S (mp);
18411
18412   /* Wait for a reply... */
18413   W (ret);
18414   return ret;
18415 }
18416
18417 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18418
18419 static int
18420 api_one_locator_dump (vat_main_t * vam)
18421 {
18422   unformat_input_t *input = vam->input;
18423   vl_api_one_locator_dump_t *mp;
18424   vl_api_control_ping_t *mp_ping;
18425   u8 is_index_set = 0, is_name_set = 0;
18426   u8 *ls_name = 0;
18427   u32 ls_index = ~0;
18428   int ret;
18429
18430   /* Parse args required to build the message */
18431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18432     {
18433       if (unformat (input, "ls_name %_%v%_", &ls_name))
18434         {
18435           is_name_set = 1;
18436         }
18437       else if (unformat (input, "ls_index %d", &ls_index))
18438         {
18439           is_index_set = 1;
18440         }
18441       else
18442         {
18443           errmsg ("parse error '%U'", format_unformat_error, input);
18444           return -99;
18445         }
18446     }
18447
18448   if (!is_index_set && !is_name_set)
18449     {
18450       errmsg ("error: expected one of index or name!");
18451       return -99;
18452     }
18453
18454   if (is_index_set && is_name_set)
18455     {
18456       errmsg ("error: only one param expected!");
18457       return -99;
18458     }
18459
18460   if (vec_len (ls_name) > 62)
18461     {
18462       errmsg ("error: locator set name too long!");
18463       return -99;
18464     }
18465
18466   if (!vam->json_output)
18467     {
18468       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18469     }
18470
18471   M (ONE_LOCATOR_DUMP, mp);
18472   mp->is_index_set = is_index_set;
18473
18474   if (is_index_set)
18475     mp->ls_index = clib_host_to_net_u32 (ls_index);
18476   else
18477     {
18478       vec_add1 (ls_name, 0);
18479       strncpy ((char *) mp->ls_name, (char *) ls_name,
18480                sizeof (mp->ls_name) - 1);
18481     }
18482
18483   /* send it... */
18484   S (mp);
18485
18486   /* Use a control ping for synchronization */
18487   MPING (CONTROL_PING, mp_ping);
18488   S (mp_ping);
18489
18490   /* Wait for a reply... */
18491   W (ret);
18492   return ret;
18493 }
18494
18495 #define api_lisp_locator_dump api_one_locator_dump
18496
18497 static int
18498 api_one_locator_set_dump (vat_main_t * vam)
18499 {
18500   vl_api_one_locator_set_dump_t *mp;
18501   vl_api_control_ping_t *mp_ping;
18502   unformat_input_t *input = vam->input;
18503   u8 filter = 0;
18504   int ret;
18505
18506   /* Parse args required to build the message */
18507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18508     {
18509       if (unformat (input, "local"))
18510         {
18511           filter = 1;
18512         }
18513       else if (unformat (input, "remote"))
18514         {
18515           filter = 2;
18516         }
18517       else
18518         {
18519           errmsg ("parse error '%U'", format_unformat_error, input);
18520           return -99;
18521         }
18522     }
18523
18524   if (!vam->json_output)
18525     {
18526       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18527     }
18528
18529   M (ONE_LOCATOR_SET_DUMP, mp);
18530
18531   mp->filter = filter;
18532
18533   /* send it... */
18534   S (mp);
18535
18536   /* Use a control ping for synchronization */
18537   MPING (CONTROL_PING, mp_ping);
18538   S (mp_ping);
18539
18540   /* Wait for a reply... */
18541   W (ret);
18542   return ret;
18543 }
18544
18545 #define api_lisp_locator_set_dump api_one_locator_set_dump
18546
18547 static int
18548 api_one_eid_table_map_dump (vat_main_t * vam)
18549 {
18550   u8 is_l2 = 0;
18551   u8 mode_set = 0;
18552   unformat_input_t *input = vam->input;
18553   vl_api_one_eid_table_map_dump_t *mp;
18554   vl_api_control_ping_t *mp_ping;
18555   int ret;
18556
18557   /* Parse args required to build the message */
18558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18559     {
18560       if (unformat (input, "l2"))
18561         {
18562           is_l2 = 1;
18563           mode_set = 1;
18564         }
18565       else if (unformat (input, "l3"))
18566         {
18567           is_l2 = 0;
18568           mode_set = 1;
18569         }
18570       else
18571         {
18572           errmsg ("parse error '%U'", format_unformat_error, input);
18573           return -99;
18574         }
18575     }
18576
18577   if (!mode_set)
18578     {
18579       errmsg ("expected one of 'l2' or 'l3' parameter!");
18580       return -99;
18581     }
18582
18583   if (!vam->json_output)
18584     {
18585       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18586     }
18587
18588   M (ONE_EID_TABLE_MAP_DUMP, mp);
18589   mp->is_l2 = is_l2;
18590
18591   /* send it... */
18592   S (mp);
18593
18594   /* Use a control ping for synchronization */
18595   MPING (CONTROL_PING, mp_ping);
18596   S (mp_ping);
18597
18598   /* Wait for a reply... */
18599   W (ret);
18600   return ret;
18601 }
18602
18603 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18604
18605 static int
18606 api_one_eid_table_vni_dump (vat_main_t * vam)
18607 {
18608   vl_api_one_eid_table_vni_dump_t *mp;
18609   vl_api_control_ping_t *mp_ping;
18610   int ret;
18611
18612   if (!vam->json_output)
18613     {
18614       print (vam->ofp, "VNI");
18615     }
18616
18617   M (ONE_EID_TABLE_VNI_DUMP, mp);
18618
18619   /* send it... */
18620   S (mp);
18621
18622   /* Use a control ping for synchronization */
18623   MPING (CONTROL_PING, mp_ping);
18624   S (mp_ping);
18625
18626   /* Wait for a reply... */
18627   W (ret);
18628   return ret;
18629 }
18630
18631 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18632
18633 static int
18634 api_one_eid_table_dump (vat_main_t * vam)
18635 {
18636   unformat_input_t *i = vam->input;
18637   vl_api_one_eid_table_dump_t *mp;
18638   vl_api_control_ping_t *mp_ping;
18639   struct in_addr ip4;
18640   struct in6_addr ip6;
18641   u8 mac[6];
18642   u8 eid_type = ~0, eid_set = 0;
18643   u32 prefix_length = ~0, t, vni = 0;
18644   u8 filter = 0;
18645   int ret;
18646   lisp_nsh_api_t nsh;
18647
18648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18649     {
18650       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18651         {
18652           eid_set = 1;
18653           eid_type = 0;
18654           prefix_length = t;
18655         }
18656       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18657         {
18658           eid_set = 1;
18659           eid_type = 1;
18660           prefix_length = t;
18661         }
18662       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18663         {
18664           eid_set = 1;
18665           eid_type = 2;
18666         }
18667       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18668         {
18669           eid_set = 1;
18670           eid_type = 3;
18671         }
18672       else if (unformat (i, "vni %d", &t))
18673         {
18674           vni = t;
18675         }
18676       else if (unformat (i, "local"))
18677         {
18678           filter = 1;
18679         }
18680       else if (unformat (i, "remote"))
18681         {
18682           filter = 2;
18683         }
18684       else
18685         {
18686           errmsg ("parse error '%U'", format_unformat_error, i);
18687           return -99;
18688         }
18689     }
18690
18691   if (!vam->json_output)
18692     {
18693       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18694              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18695     }
18696
18697   M (ONE_EID_TABLE_DUMP, mp);
18698
18699   mp->filter = filter;
18700   if (eid_set)
18701     {
18702       mp->eid_set = 1;
18703       mp->vni = htonl (vni);
18704       mp->eid_type = eid_type;
18705       switch (eid_type)
18706         {
18707         case 0:
18708           mp->prefix_length = prefix_length;
18709           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18710           break;
18711         case 1:
18712           mp->prefix_length = prefix_length;
18713           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18714           break;
18715         case 2:
18716           clib_memcpy (mp->eid, mac, sizeof (mac));
18717           break;
18718         case 3:
18719           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18720           break;
18721         default:
18722           errmsg ("unknown EID type %d!", eid_type);
18723           return -99;
18724         }
18725     }
18726
18727   /* send it... */
18728   S (mp);
18729
18730   /* Use a control ping for synchronization */
18731   MPING (CONTROL_PING, mp_ping);
18732   S (mp_ping);
18733
18734   /* Wait for a reply... */
18735   W (ret);
18736   return ret;
18737 }
18738
18739 #define api_lisp_eid_table_dump api_one_eid_table_dump
18740
18741 static int
18742 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18743 {
18744   unformat_input_t *i = vam->input;
18745   vl_api_gpe_fwd_entries_get_t *mp;
18746   u8 vni_set = 0;
18747   u32 vni = ~0;
18748   int ret;
18749
18750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (i, "vni %d", &vni))
18753         {
18754           vni_set = 1;
18755         }
18756       else
18757         {
18758           errmsg ("parse error '%U'", format_unformat_error, i);
18759           return -99;
18760         }
18761     }
18762
18763   if (!vni_set)
18764     {
18765       errmsg ("vni not set!");
18766       return -99;
18767     }
18768
18769   if (!vam->json_output)
18770     {
18771       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18772              "leid", "reid");
18773     }
18774
18775   M (GPE_FWD_ENTRIES_GET, mp);
18776   mp->vni = clib_host_to_net_u32 (vni);
18777
18778   /* send it... */
18779   S (mp);
18780
18781   /* Wait for a reply... */
18782   W (ret);
18783   return ret;
18784 }
18785
18786 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18787 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18788 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18789 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18790 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18791 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18792 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18793 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18794
18795 static int
18796 api_one_adjacencies_get (vat_main_t * vam)
18797 {
18798   unformat_input_t *i = vam->input;
18799   vl_api_one_adjacencies_get_t *mp;
18800   u8 vni_set = 0;
18801   u32 vni = ~0;
18802   int ret;
18803
18804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18805     {
18806       if (unformat (i, "vni %d", &vni))
18807         {
18808           vni_set = 1;
18809         }
18810       else
18811         {
18812           errmsg ("parse error '%U'", format_unformat_error, i);
18813           return -99;
18814         }
18815     }
18816
18817   if (!vni_set)
18818     {
18819       errmsg ("vni not set!");
18820       return -99;
18821     }
18822
18823   if (!vam->json_output)
18824     {
18825       print (vam->ofp, "%s %40s", "leid", "reid");
18826     }
18827
18828   M (ONE_ADJACENCIES_GET, mp);
18829   mp->vni = clib_host_to_net_u32 (vni);
18830
18831   /* send it... */
18832   S (mp);
18833
18834   /* Wait for a reply... */
18835   W (ret);
18836   return ret;
18837 }
18838
18839 #define api_lisp_adjacencies_get api_one_adjacencies_get
18840
18841 static int
18842 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18843 {
18844   unformat_input_t *i = vam->input;
18845   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18846   int ret;
18847   u8 ip_family_set = 0, is_ip4 = 1;
18848
18849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18850     {
18851       if (unformat (i, "ip4"))
18852         {
18853           ip_family_set = 1;
18854           is_ip4 = 1;
18855         }
18856       else if (unformat (i, "ip6"))
18857         {
18858           ip_family_set = 1;
18859           is_ip4 = 0;
18860         }
18861       else
18862         {
18863           errmsg ("parse error '%U'", format_unformat_error, i);
18864           return -99;
18865         }
18866     }
18867
18868   if (!ip_family_set)
18869     {
18870       errmsg ("ip family not set!");
18871       return -99;
18872     }
18873
18874   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18875   mp->is_ip4 = is_ip4;
18876
18877   /* send it... */
18878   S (mp);
18879
18880   /* Wait for a reply... */
18881   W (ret);
18882   return ret;
18883 }
18884
18885 static int
18886 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18887 {
18888   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18889   int ret;
18890
18891   if (!vam->json_output)
18892     {
18893       print (vam->ofp, "VNIs");
18894     }
18895
18896   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18897
18898   /* send it... */
18899   S (mp);
18900
18901   /* Wait for a reply... */
18902   W (ret);
18903   return ret;
18904 }
18905
18906 static int
18907 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18908 {
18909   unformat_input_t *i = vam->input;
18910   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18911   int ret = 0;
18912   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18913   struct in_addr ip4;
18914   struct in6_addr ip6;
18915   u32 table_id = 0, nh_sw_if_index = ~0;
18916
18917   memset (&ip4, 0, sizeof (ip4));
18918   memset (&ip6, 0, sizeof (ip6));
18919
18920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18921     {
18922       if (unformat (i, "del"))
18923         is_add = 0;
18924       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18925                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18926         {
18927           ip_set = 1;
18928           is_ip4 = 1;
18929         }
18930       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18931                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18932         {
18933           ip_set = 1;
18934           is_ip4 = 0;
18935         }
18936       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18937         {
18938           ip_set = 1;
18939           is_ip4 = 1;
18940           nh_sw_if_index = ~0;
18941         }
18942       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18943         {
18944           ip_set = 1;
18945           is_ip4 = 0;
18946           nh_sw_if_index = ~0;
18947         }
18948       else if (unformat (i, "table %d", &table_id))
18949         ;
18950       else
18951         {
18952           errmsg ("parse error '%U'", format_unformat_error, i);
18953           return -99;
18954         }
18955     }
18956
18957   if (!ip_set)
18958     {
18959       errmsg ("nh addr not set!");
18960       return -99;
18961     }
18962
18963   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18964   mp->is_add = is_add;
18965   mp->table_id = clib_host_to_net_u32 (table_id);
18966   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18967   mp->is_ip4 = is_ip4;
18968   if (is_ip4)
18969     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18970   else
18971     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18972
18973   /* send it... */
18974   S (mp);
18975
18976   /* Wait for a reply... */
18977   W (ret);
18978   return ret;
18979 }
18980
18981 static int
18982 api_one_map_server_dump (vat_main_t * vam)
18983 {
18984   vl_api_one_map_server_dump_t *mp;
18985   vl_api_control_ping_t *mp_ping;
18986   int ret;
18987
18988   if (!vam->json_output)
18989     {
18990       print (vam->ofp, "%=20s", "Map server");
18991     }
18992
18993   M (ONE_MAP_SERVER_DUMP, mp);
18994   /* send it... */
18995   S (mp);
18996
18997   /* Use a control ping for synchronization */
18998   MPING (CONTROL_PING, mp_ping);
18999   S (mp_ping);
19000
19001   /* Wait for a reply... */
19002   W (ret);
19003   return ret;
19004 }
19005
19006 #define api_lisp_map_server_dump api_one_map_server_dump
19007
19008 static int
19009 api_one_map_resolver_dump (vat_main_t * vam)
19010 {
19011   vl_api_one_map_resolver_dump_t *mp;
19012   vl_api_control_ping_t *mp_ping;
19013   int ret;
19014
19015   if (!vam->json_output)
19016     {
19017       print (vam->ofp, "%=20s", "Map resolver");
19018     }
19019
19020   M (ONE_MAP_RESOLVER_DUMP, mp);
19021   /* send it... */
19022   S (mp);
19023
19024   /* Use a control ping for synchronization */
19025   MPING (CONTROL_PING, mp_ping);
19026   S (mp_ping);
19027
19028   /* Wait for a reply... */
19029   W (ret);
19030   return ret;
19031 }
19032
19033 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19034
19035 static int
19036 api_one_stats_flush (vat_main_t * vam)
19037 {
19038   vl_api_one_stats_flush_t *mp;
19039   int ret = 0;
19040
19041   M (ONE_STATS_FLUSH, mp);
19042   S (mp);
19043   W (ret);
19044   return ret;
19045 }
19046
19047 static int
19048 api_one_stats_dump (vat_main_t * vam)
19049 {
19050   vl_api_one_stats_dump_t *mp;
19051   vl_api_control_ping_t *mp_ping;
19052   int ret;
19053
19054   M (ONE_STATS_DUMP, mp);
19055   /* send it... */
19056   S (mp);
19057
19058   /* Use a control ping for synchronization */
19059   MPING (CONTROL_PING, mp_ping);
19060   S (mp_ping);
19061
19062   /* Wait for a reply... */
19063   W (ret);
19064   return ret;
19065 }
19066
19067 static int
19068 api_show_one_status (vat_main_t * vam)
19069 {
19070   vl_api_show_one_status_t *mp;
19071   int ret;
19072
19073   if (!vam->json_output)
19074     {
19075       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19076     }
19077
19078   M (SHOW_ONE_STATUS, mp);
19079   /* send it... */
19080   S (mp);
19081   /* Wait for a reply... */
19082   W (ret);
19083   return ret;
19084 }
19085
19086 #define api_show_lisp_status api_show_one_status
19087
19088 static int
19089 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19090 {
19091   vl_api_gpe_fwd_entry_path_dump_t *mp;
19092   vl_api_control_ping_t *mp_ping;
19093   unformat_input_t *i = vam->input;
19094   u32 fwd_entry_index = ~0;
19095   int ret;
19096
19097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19098     {
19099       if (unformat (i, "index %d", &fwd_entry_index))
19100         ;
19101       else
19102         break;
19103     }
19104
19105   if (~0 == fwd_entry_index)
19106     {
19107       errmsg ("no index specified!");
19108       return -99;
19109     }
19110
19111   if (!vam->json_output)
19112     {
19113       print (vam->ofp, "first line");
19114     }
19115
19116   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19117
19118   /* send it... */
19119   S (mp);
19120   /* Use a control ping for synchronization */
19121   MPING (CONTROL_PING, mp_ping);
19122   S (mp_ping);
19123
19124   /* Wait for a reply... */
19125   W (ret);
19126   return ret;
19127 }
19128
19129 static int
19130 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19131 {
19132   vl_api_one_get_map_request_itr_rlocs_t *mp;
19133   int ret;
19134
19135   if (!vam->json_output)
19136     {
19137       print (vam->ofp, "%=20s", "itr-rlocs:");
19138     }
19139
19140   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19141   /* send it... */
19142   S (mp);
19143   /* Wait for a reply... */
19144   W (ret);
19145   return ret;
19146 }
19147
19148 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19149
19150 static int
19151 api_af_packet_create (vat_main_t * vam)
19152 {
19153   unformat_input_t *i = vam->input;
19154   vl_api_af_packet_create_t *mp;
19155   u8 *host_if_name = 0;
19156   u8 hw_addr[6];
19157   u8 random_hw_addr = 1;
19158   int ret;
19159
19160   memset (hw_addr, 0, sizeof (hw_addr));
19161
19162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19163     {
19164       if (unformat (i, "name %s", &host_if_name))
19165         vec_add1 (host_if_name, 0);
19166       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19167         random_hw_addr = 0;
19168       else
19169         break;
19170     }
19171
19172   if (!vec_len (host_if_name))
19173     {
19174       errmsg ("host-interface name must be specified");
19175       return -99;
19176     }
19177
19178   if (vec_len (host_if_name) > 64)
19179     {
19180       errmsg ("host-interface name too long");
19181       return -99;
19182     }
19183
19184   M (AF_PACKET_CREATE, mp);
19185
19186   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19187   clib_memcpy (mp->hw_addr, hw_addr, 6);
19188   mp->use_random_hw_addr = random_hw_addr;
19189   vec_free (host_if_name);
19190
19191   S (mp);
19192
19193   /* *INDENT-OFF* */
19194   W2 (ret,
19195       ({
19196         if (ret == 0)
19197           fprintf (vam->ofp ? vam->ofp : stderr,
19198                    " new sw_if_index = %d\n", vam->sw_if_index);
19199       }));
19200   /* *INDENT-ON* */
19201   return ret;
19202 }
19203
19204 static int
19205 api_af_packet_delete (vat_main_t * vam)
19206 {
19207   unformat_input_t *i = vam->input;
19208   vl_api_af_packet_delete_t *mp;
19209   u8 *host_if_name = 0;
19210   int ret;
19211
19212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19213     {
19214       if (unformat (i, "name %s", &host_if_name))
19215         vec_add1 (host_if_name, 0);
19216       else
19217         break;
19218     }
19219
19220   if (!vec_len (host_if_name))
19221     {
19222       errmsg ("host-interface name must be specified");
19223       return -99;
19224     }
19225
19226   if (vec_len (host_if_name) > 64)
19227     {
19228       errmsg ("host-interface name too long");
19229       return -99;
19230     }
19231
19232   M (AF_PACKET_DELETE, mp);
19233
19234   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19235   vec_free (host_if_name);
19236
19237   S (mp);
19238   W (ret);
19239   return ret;
19240 }
19241
19242 static int
19243 api_policer_add_del (vat_main_t * vam)
19244 {
19245   unformat_input_t *i = vam->input;
19246   vl_api_policer_add_del_t *mp;
19247   u8 is_add = 1;
19248   u8 *name = 0;
19249   u32 cir = 0;
19250   u32 eir = 0;
19251   u64 cb = 0;
19252   u64 eb = 0;
19253   u8 rate_type = 0;
19254   u8 round_type = 0;
19255   u8 type = 0;
19256   u8 color_aware = 0;
19257   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19258   int ret;
19259
19260   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19261   conform_action.dscp = 0;
19262   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19263   exceed_action.dscp = 0;
19264   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19265   violate_action.dscp = 0;
19266
19267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19268     {
19269       if (unformat (i, "del"))
19270         is_add = 0;
19271       else if (unformat (i, "name %s", &name))
19272         vec_add1 (name, 0);
19273       else if (unformat (i, "cir %u", &cir))
19274         ;
19275       else if (unformat (i, "eir %u", &eir))
19276         ;
19277       else if (unformat (i, "cb %u", &cb))
19278         ;
19279       else if (unformat (i, "eb %u", &eb))
19280         ;
19281       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19282                          &rate_type))
19283         ;
19284       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19285                          &round_type))
19286         ;
19287       else if (unformat (i, "type %U", unformat_policer_type, &type))
19288         ;
19289       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19290                          &conform_action))
19291         ;
19292       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19293                          &exceed_action))
19294         ;
19295       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19296                          &violate_action))
19297         ;
19298       else if (unformat (i, "color-aware"))
19299         color_aware = 1;
19300       else
19301         break;
19302     }
19303
19304   if (!vec_len (name))
19305     {
19306       errmsg ("policer name must be specified");
19307       return -99;
19308     }
19309
19310   if (vec_len (name) > 64)
19311     {
19312       errmsg ("policer name too long");
19313       return -99;
19314     }
19315
19316   M (POLICER_ADD_DEL, mp);
19317
19318   clib_memcpy (mp->name, name, vec_len (name));
19319   vec_free (name);
19320   mp->is_add = is_add;
19321   mp->cir = ntohl (cir);
19322   mp->eir = ntohl (eir);
19323   mp->cb = clib_net_to_host_u64 (cb);
19324   mp->eb = clib_net_to_host_u64 (eb);
19325   mp->rate_type = rate_type;
19326   mp->round_type = round_type;
19327   mp->type = type;
19328   mp->conform_action_type = conform_action.action_type;
19329   mp->conform_dscp = conform_action.dscp;
19330   mp->exceed_action_type = exceed_action.action_type;
19331   mp->exceed_dscp = exceed_action.dscp;
19332   mp->violate_action_type = violate_action.action_type;
19333   mp->violate_dscp = violate_action.dscp;
19334   mp->color_aware = color_aware;
19335
19336   S (mp);
19337   W (ret);
19338   return ret;
19339 }
19340
19341 static int
19342 api_policer_dump (vat_main_t * vam)
19343 {
19344   unformat_input_t *i = vam->input;
19345   vl_api_policer_dump_t *mp;
19346   vl_api_control_ping_t *mp_ping;
19347   u8 *match_name = 0;
19348   u8 match_name_valid = 0;
19349   int ret;
19350
19351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19352     {
19353       if (unformat (i, "name %s", &match_name))
19354         {
19355           vec_add1 (match_name, 0);
19356           match_name_valid = 1;
19357         }
19358       else
19359         break;
19360     }
19361
19362   M (POLICER_DUMP, mp);
19363   mp->match_name_valid = match_name_valid;
19364   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19365   vec_free (match_name);
19366   /* send it... */
19367   S (mp);
19368
19369   /* Use a control ping for synchronization */
19370   MPING (CONTROL_PING, mp_ping);
19371   S (mp_ping);
19372
19373   /* Wait for a reply... */
19374   W (ret);
19375   return ret;
19376 }
19377
19378 static int
19379 api_policer_classify_set_interface (vat_main_t * vam)
19380 {
19381   unformat_input_t *i = vam->input;
19382   vl_api_policer_classify_set_interface_t *mp;
19383   u32 sw_if_index;
19384   int sw_if_index_set;
19385   u32 ip4_table_index = ~0;
19386   u32 ip6_table_index = ~0;
19387   u32 l2_table_index = ~0;
19388   u8 is_add = 1;
19389   int ret;
19390
19391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19392     {
19393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19394         sw_if_index_set = 1;
19395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19396         sw_if_index_set = 1;
19397       else if (unformat (i, "del"))
19398         is_add = 0;
19399       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19400         ;
19401       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19402         ;
19403       else if (unformat (i, "l2-table %d", &l2_table_index))
19404         ;
19405       else
19406         {
19407           clib_warning ("parse error '%U'", format_unformat_error, i);
19408           return -99;
19409         }
19410     }
19411
19412   if (sw_if_index_set == 0)
19413     {
19414       errmsg ("missing interface name or sw_if_index");
19415       return -99;
19416     }
19417
19418   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19419
19420   mp->sw_if_index = ntohl (sw_if_index);
19421   mp->ip4_table_index = ntohl (ip4_table_index);
19422   mp->ip6_table_index = ntohl (ip6_table_index);
19423   mp->l2_table_index = ntohl (l2_table_index);
19424   mp->is_add = is_add;
19425
19426   S (mp);
19427   W (ret);
19428   return ret;
19429 }
19430
19431 static int
19432 api_policer_classify_dump (vat_main_t * vam)
19433 {
19434   unformat_input_t *i = vam->input;
19435   vl_api_policer_classify_dump_t *mp;
19436   vl_api_control_ping_t *mp_ping;
19437   u8 type = POLICER_CLASSIFY_N_TABLES;
19438   int ret;
19439
19440   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19441     ;
19442   else
19443     {
19444       errmsg ("classify table type must be specified");
19445       return -99;
19446     }
19447
19448   if (!vam->json_output)
19449     {
19450       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19451     }
19452
19453   M (POLICER_CLASSIFY_DUMP, mp);
19454   mp->type = type;
19455   /* send it... */
19456   S (mp);
19457
19458   /* Use a control ping for synchronization */
19459   MPING (CONTROL_PING, mp_ping);
19460   S (mp_ping);
19461
19462   /* Wait for a reply... */
19463   W (ret);
19464   return ret;
19465 }
19466
19467 static int
19468 api_netmap_create (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_netmap_create_t *mp;
19472   u8 *if_name = 0;
19473   u8 hw_addr[6];
19474   u8 random_hw_addr = 1;
19475   u8 is_pipe = 0;
19476   u8 is_master = 0;
19477   int ret;
19478
19479   memset (hw_addr, 0, sizeof (hw_addr));
19480
19481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19482     {
19483       if (unformat (i, "name %s", &if_name))
19484         vec_add1 (if_name, 0);
19485       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19486         random_hw_addr = 0;
19487       else if (unformat (i, "pipe"))
19488         is_pipe = 1;
19489       else if (unformat (i, "master"))
19490         is_master = 1;
19491       else if (unformat (i, "slave"))
19492         is_master = 0;
19493       else
19494         break;
19495     }
19496
19497   if (!vec_len (if_name))
19498     {
19499       errmsg ("interface name must be specified");
19500       return -99;
19501     }
19502
19503   if (vec_len (if_name) > 64)
19504     {
19505       errmsg ("interface name too long");
19506       return -99;
19507     }
19508
19509   M (NETMAP_CREATE, mp);
19510
19511   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19512   clib_memcpy (mp->hw_addr, hw_addr, 6);
19513   mp->use_random_hw_addr = random_hw_addr;
19514   mp->is_pipe = is_pipe;
19515   mp->is_master = is_master;
19516   vec_free (if_name);
19517
19518   S (mp);
19519   W (ret);
19520   return ret;
19521 }
19522
19523 static int
19524 api_netmap_delete (vat_main_t * vam)
19525 {
19526   unformat_input_t *i = vam->input;
19527   vl_api_netmap_delete_t *mp;
19528   u8 *if_name = 0;
19529   int ret;
19530
19531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19532     {
19533       if (unformat (i, "name %s", &if_name))
19534         vec_add1 (if_name, 0);
19535       else
19536         break;
19537     }
19538
19539   if (!vec_len (if_name))
19540     {
19541       errmsg ("interface name must be specified");
19542       return -99;
19543     }
19544
19545   if (vec_len (if_name) > 64)
19546     {
19547       errmsg ("interface name too long");
19548       return -99;
19549     }
19550
19551   M (NETMAP_DELETE, mp);
19552
19553   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19554   vec_free (if_name);
19555
19556   S (mp);
19557   W (ret);
19558   return ret;
19559 }
19560
19561 static void
19562 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19563 {
19564   if (fp->afi == IP46_TYPE_IP6)
19565     print (vam->ofp,
19566            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19567            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19568            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19569            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19570            format_ip6_address, fp->next_hop);
19571   else if (fp->afi == IP46_TYPE_IP4)
19572     print (vam->ofp,
19573            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19574            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19575            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19576            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19577            format_ip4_address, fp->next_hop);
19578 }
19579
19580 static void
19581 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19582                                  vl_api_fib_path2_t * fp)
19583 {
19584   struct in_addr ip4;
19585   struct in6_addr ip6;
19586
19587   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19588   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19589   vat_json_object_add_uint (node, "is_local", fp->is_local);
19590   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19591   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19592   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19593   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19594   if (fp->afi == IP46_TYPE_IP4)
19595     {
19596       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19597       vat_json_object_add_ip4 (node, "next_hop", ip4);
19598     }
19599   else if (fp->afi == IP46_TYPE_IP6)
19600     {
19601       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19602       vat_json_object_add_ip6 (node, "next_hop", ip6);
19603     }
19604 }
19605
19606 static void
19607 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19608 {
19609   vat_main_t *vam = &vat_main;
19610   int count = ntohl (mp->mt_count);
19611   vl_api_fib_path2_t *fp;
19612   i32 i;
19613
19614   print (vam->ofp, "[%d]: sw_if_index %d via:",
19615          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19616   fp = mp->mt_paths;
19617   for (i = 0; i < count; i++)
19618     {
19619       vl_api_mpls_fib_path_print (vam, fp);
19620       fp++;
19621     }
19622
19623   print (vam->ofp, "");
19624 }
19625
19626 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19627 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19628
19629 static void
19630 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19631 {
19632   vat_main_t *vam = &vat_main;
19633   vat_json_node_t *node = NULL;
19634   int count = ntohl (mp->mt_count);
19635   vl_api_fib_path2_t *fp;
19636   i32 i;
19637
19638   if (VAT_JSON_ARRAY != vam->json_tree.type)
19639     {
19640       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19641       vat_json_init_array (&vam->json_tree);
19642     }
19643   node = vat_json_array_add (&vam->json_tree);
19644
19645   vat_json_init_object (node);
19646   vat_json_object_add_uint (node, "tunnel_index",
19647                             ntohl (mp->mt_tunnel_index));
19648   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19649
19650   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19651
19652   fp = mp->mt_paths;
19653   for (i = 0; i < count; i++)
19654     {
19655       vl_api_mpls_fib_path_json_print (node, fp);
19656       fp++;
19657     }
19658 }
19659
19660 static int
19661 api_mpls_tunnel_dump (vat_main_t * vam)
19662 {
19663   vl_api_mpls_tunnel_dump_t *mp;
19664   vl_api_control_ping_t *mp_ping;
19665   i32 index = -1;
19666   int ret;
19667
19668   /* Parse args required to build the message */
19669   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19670     {
19671       if (!unformat (vam->input, "tunnel_index %d", &index))
19672         {
19673           index = -1;
19674           break;
19675         }
19676     }
19677
19678   print (vam->ofp, "  tunnel_index %d", index);
19679
19680   M (MPLS_TUNNEL_DUMP, mp);
19681   mp->tunnel_index = htonl (index);
19682   S (mp);
19683
19684   /* Use a control ping for synchronization */
19685   MPING (CONTROL_PING, mp_ping);
19686   S (mp_ping);
19687
19688   W (ret);
19689   return ret;
19690 }
19691
19692 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19693 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19694
19695
19696 static void
19697 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19698 {
19699   vat_main_t *vam = &vat_main;
19700   int count = ntohl (mp->count);
19701   vl_api_fib_path2_t *fp;
19702   int i;
19703
19704   print (vam->ofp,
19705          "table-id %d, label %u, ess_bit %u",
19706          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19707   fp = mp->path;
19708   for (i = 0; i < count; i++)
19709     {
19710       vl_api_mpls_fib_path_print (vam, fp);
19711       fp++;
19712     }
19713 }
19714
19715 static void vl_api_mpls_fib_details_t_handler_json
19716   (vl_api_mpls_fib_details_t * mp)
19717 {
19718   vat_main_t *vam = &vat_main;
19719   int count = ntohl (mp->count);
19720   vat_json_node_t *node = NULL;
19721   vl_api_fib_path2_t *fp;
19722   int i;
19723
19724   if (VAT_JSON_ARRAY != vam->json_tree.type)
19725     {
19726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19727       vat_json_init_array (&vam->json_tree);
19728     }
19729   node = vat_json_array_add (&vam->json_tree);
19730
19731   vat_json_init_object (node);
19732   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19733   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19734   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19735   vat_json_object_add_uint (node, "path_count", count);
19736   fp = mp->path;
19737   for (i = 0; i < count; i++)
19738     {
19739       vl_api_mpls_fib_path_json_print (node, fp);
19740       fp++;
19741     }
19742 }
19743
19744 static int
19745 api_mpls_fib_dump (vat_main_t * vam)
19746 {
19747   vl_api_mpls_fib_dump_t *mp;
19748   vl_api_control_ping_t *mp_ping;
19749   int ret;
19750
19751   M (MPLS_FIB_DUMP, mp);
19752   S (mp);
19753
19754   /* Use a control ping for synchronization */
19755   MPING (CONTROL_PING, mp_ping);
19756   S (mp_ping);
19757
19758   W (ret);
19759   return ret;
19760 }
19761
19762 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19763 #define vl_api_ip_fib_details_t_print vl_noop_handler
19764
19765 static void
19766 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19767 {
19768   vat_main_t *vam = &vat_main;
19769   int count = ntohl (mp->count);
19770   vl_api_fib_path_t *fp;
19771   int i;
19772
19773   print (vam->ofp,
19774          "table-id %d, prefix %U/%d",
19775          ntohl (mp->table_id), format_ip4_address, mp->address,
19776          mp->address_length);
19777   fp = mp->path;
19778   for (i = 0; i < count; i++)
19779     {
19780       if (fp->afi == IP46_TYPE_IP6)
19781         print (vam->ofp,
19782                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19783                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19784                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19785                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19786                format_ip6_address, fp->next_hop);
19787       else if (fp->afi == IP46_TYPE_IP4)
19788         print (vam->ofp,
19789                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19790                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19791                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19792                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19793                format_ip4_address, fp->next_hop);
19794       fp++;
19795     }
19796 }
19797
19798 static void vl_api_ip_fib_details_t_handler_json
19799   (vl_api_ip_fib_details_t * mp)
19800 {
19801   vat_main_t *vam = &vat_main;
19802   int count = ntohl (mp->count);
19803   vat_json_node_t *node = NULL;
19804   struct in_addr ip4;
19805   struct in6_addr ip6;
19806   vl_api_fib_path_t *fp;
19807   int i;
19808
19809   if (VAT_JSON_ARRAY != vam->json_tree.type)
19810     {
19811       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19812       vat_json_init_array (&vam->json_tree);
19813     }
19814   node = vat_json_array_add (&vam->json_tree);
19815
19816   vat_json_init_object (node);
19817   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19818   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19819   vat_json_object_add_ip4 (node, "prefix", ip4);
19820   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19821   vat_json_object_add_uint (node, "path_count", count);
19822   fp = mp->path;
19823   for (i = 0; i < count; i++)
19824     {
19825       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19826       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19827       vat_json_object_add_uint (node, "is_local", fp->is_local);
19828       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19829       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19830       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19831       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19832       if (fp->afi == IP46_TYPE_IP4)
19833         {
19834           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19835           vat_json_object_add_ip4 (node, "next_hop", ip4);
19836         }
19837       else if (fp->afi == IP46_TYPE_IP6)
19838         {
19839           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19840           vat_json_object_add_ip6 (node, "next_hop", ip6);
19841         }
19842     }
19843 }
19844
19845 static int
19846 api_ip_fib_dump (vat_main_t * vam)
19847 {
19848   vl_api_ip_fib_dump_t *mp;
19849   vl_api_control_ping_t *mp_ping;
19850   int ret;
19851
19852   M (IP_FIB_DUMP, mp);
19853   S (mp);
19854
19855   /* Use a control ping for synchronization */
19856   MPING (CONTROL_PING, mp_ping);
19857   S (mp_ping);
19858
19859   W (ret);
19860   return ret;
19861 }
19862
19863 static int
19864 api_ip_mfib_dump (vat_main_t * vam)
19865 {
19866   vl_api_ip_mfib_dump_t *mp;
19867   vl_api_control_ping_t *mp_ping;
19868   int ret;
19869
19870   M (IP_MFIB_DUMP, mp);
19871   S (mp);
19872
19873   /* Use a control ping for synchronization */
19874   MPING (CONTROL_PING, mp_ping);
19875   S (mp_ping);
19876
19877   W (ret);
19878   return ret;
19879 }
19880
19881 static void vl_api_ip_neighbor_details_t_handler
19882   (vl_api_ip_neighbor_details_t * mp)
19883 {
19884   vat_main_t *vam = &vat_main;
19885
19886   print (vam->ofp, "%c %U %U",
19887          (mp->is_static) ? 'S' : 'D',
19888          format_ethernet_address, &mp->mac_address,
19889          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19890          &mp->ip_address);
19891 }
19892
19893 static void vl_api_ip_neighbor_details_t_handler_json
19894   (vl_api_ip_neighbor_details_t * mp)
19895 {
19896
19897   vat_main_t *vam = &vat_main;
19898   vat_json_node_t *node;
19899   struct in_addr ip4;
19900   struct in6_addr ip6;
19901
19902   if (VAT_JSON_ARRAY != vam->json_tree.type)
19903     {
19904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19905       vat_json_init_array (&vam->json_tree);
19906     }
19907   node = vat_json_array_add (&vam->json_tree);
19908
19909   vat_json_init_object (node);
19910   vat_json_object_add_string_copy (node, "flag",
19911                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19912                                    "dynamic");
19913
19914   vat_json_object_add_string_copy (node, "link_layer",
19915                                    format (0, "%U", format_ethernet_address,
19916                                            &mp->mac_address));
19917
19918   if (mp->is_ipv6)
19919     {
19920       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19921       vat_json_object_add_ip6 (node, "ip_address", ip6);
19922     }
19923   else
19924     {
19925       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19926       vat_json_object_add_ip4 (node, "ip_address", ip4);
19927     }
19928 }
19929
19930 static int
19931 api_ip_neighbor_dump (vat_main_t * vam)
19932 {
19933   unformat_input_t *i = vam->input;
19934   vl_api_ip_neighbor_dump_t *mp;
19935   vl_api_control_ping_t *mp_ping;
19936   u8 is_ipv6 = 0;
19937   u32 sw_if_index = ~0;
19938   int ret;
19939
19940   /* Parse args required to build the message */
19941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19942     {
19943       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19944         ;
19945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19946         ;
19947       else if (unformat (i, "ip6"))
19948         is_ipv6 = 1;
19949       else
19950         break;
19951     }
19952
19953   if (sw_if_index == ~0)
19954     {
19955       errmsg ("missing interface name or sw_if_index");
19956       return -99;
19957     }
19958
19959   M (IP_NEIGHBOR_DUMP, mp);
19960   mp->is_ipv6 = (u8) is_ipv6;
19961   mp->sw_if_index = ntohl (sw_if_index);
19962   S (mp);
19963
19964   /* Use a control ping for synchronization */
19965   MPING (CONTROL_PING, mp_ping);
19966   S (mp_ping);
19967
19968   W (ret);
19969   return ret;
19970 }
19971
19972 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19973 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19974
19975 static void
19976 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19977 {
19978   vat_main_t *vam = &vat_main;
19979   int count = ntohl (mp->count);
19980   vl_api_fib_path_t *fp;
19981   int i;
19982
19983   print (vam->ofp,
19984          "table-id %d, prefix %U/%d",
19985          ntohl (mp->table_id), format_ip6_address, mp->address,
19986          mp->address_length);
19987   fp = mp->path;
19988   for (i = 0; i < count; i++)
19989     {
19990       if (fp->afi == IP46_TYPE_IP6)
19991         print (vam->ofp,
19992                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19993                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19994                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19995                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19996                format_ip6_address, fp->next_hop);
19997       else if (fp->afi == IP46_TYPE_IP4)
19998         print (vam->ofp,
19999                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20000                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20001                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20002                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20003                format_ip4_address, fp->next_hop);
20004       fp++;
20005     }
20006 }
20007
20008 static void vl_api_ip6_fib_details_t_handler_json
20009   (vl_api_ip6_fib_details_t * mp)
20010 {
20011   vat_main_t *vam = &vat_main;
20012   int count = ntohl (mp->count);
20013   vat_json_node_t *node = NULL;
20014   struct in_addr ip4;
20015   struct in6_addr ip6;
20016   vl_api_fib_path_t *fp;
20017   int i;
20018
20019   if (VAT_JSON_ARRAY != vam->json_tree.type)
20020     {
20021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20022       vat_json_init_array (&vam->json_tree);
20023     }
20024   node = vat_json_array_add (&vam->json_tree);
20025
20026   vat_json_init_object (node);
20027   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20028   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20029   vat_json_object_add_ip6 (node, "prefix", ip6);
20030   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20031   vat_json_object_add_uint (node, "path_count", count);
20032   fp = mp->path;
20033   for (i = 0; i < count; i++)
20034     {
20035       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20036       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20037       vat_json_object_add_uint (node, "is_local", fp->is_local);
20038       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20039       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20040       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20041       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20042       if (fp->afi == IP46_TYPE_IP4)
20043         {
20044           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20045           vat_json_object_add_ip4 (node, "next_hop", ip4);
20046         }
20047       else if (fp->afi == IP46_TYPE_IP6)
20048         {
20049           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20050           vat_json_object_add_ip6 (node, "next_hop", ip6);
20051         }
20052     }
20053 }
20054
20055 static int
20056 api_ip6_fib_dump (vat_main_t * vam)
20057 {
20058   vl_api_ip6_fib_dump_t *mp;
20059   vl_api_control_ping_t *mp_ping;
20060   int ret;
20061
20062   M (IP6_FIB_DUMP, mp);
20063   S (mp);
20064
20065   /* Use a control ping for synchronization */
20066   MPING (CONTROL_PING, mp_ping);
20067   S (mp_ping);
20068
20069   W (ret);
20070   return ret;
20071 }
20072
20073 static int
20074 api_ip6_mfib_dump (vat_main_t * vam)
20075 {
20076   vl_api_ip6_mfib_dump_t *mp;
20077   vl_api_control_ping_t *mp_ping;
20078   int ret;
20079
20080   M (IP6_MFIB_DUMP, mp);
20081   S (mp);
20082
20083   /* Use a control ping for synchronization */
20084   MPING (CONTROL_PING, mp_ping);
20085   S (mp_ping);
20086
20087   W (ret);
20088   return ret;
20089 }
20090
20091 int
20092 api_classify_table_ids (vat_main_t * vam)
20093 {
20094   vl_api_classify_table_ids_t *mp;
20095   int ret;
20096
20097   /* Construct the API message */
20098   M (CLASSIFY_TABLE_IDS, mp);
20099   mp->context = 0;
20100
20101   S (mp);
20102   W (ret);
20103   return ret;
20104 }
20105
20106 int
20107 api_classify_table_by_interface (vat_main_t * vam)
20108 {
20109   unformat_input_t *input = vam->input;
20110   vl_api_classify_table_by_interface_t *mp;
20111
20112   u32 sw_if_index = ~0;
20113   int ret;
20114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20115     {
20116       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20117         ;
20118       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20119         ;
20120       else
20121         break;
20122     }
20123   if (sw_if_index == ~0)
20124     {
20125       errmsg ("missing interface name or sw_if_index");
20126       return -99;
20127     }
20128
20129   /* Construct the API message */
20130   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20131   mp->context = 0;
20132   mp->sw_if_index = ntohl (sw_if_index);
20133
20134   S (mp);
20135   W (ret);
20136   return ret;
20137 }
20138
20139 int
20140 api_classify_table_info (vat_main_t * vam)
20141 {
20142   unformat_input_t *input = vam->input;
20143   vl_api_classify_table_info_t *mp;
20144
20145   u32 table_id = ~0;
20146   int ret;
20147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20148     {
20149       if (unformat (input, "table_id %d", &table_id))
20150         ;
20151       else
20152         break;
20153     }
20154   if (table_id == ~0)
20155     {
20156       errmsg ("missing table id");
20157       return -99;
20158     }
20159
20160   /* Construct the API message */
20161   M (CLASSIFY_TABLE_INFO, mp);
20162   mp->context = 0;
20163   mp->table_id = ntohl (table_id);
20164
20165   S (mp);
20166   W (ret);
20167   return ret;
20168 }
20169
20170 int
20171 api_classify_session_dump (vat_main_t * vam)
20172 {
20173   unformat_input_t *input = vam->input;
20174   vl_api_classify_session_dump_t *mp;
20175   vl_api_control_ping_t *mp_ping;
20176
20177   u32 table_id = ~0;
20178   int ret;
20179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20180     {
20181       if (unformat (input, "table_id %d", &table_id))
20182         ;
20183       else
20184         break;
20185     }
20186   if (table_id == ~0)
20187     {
20188       errmsg ("missing table id");
20189       return -99;
20190     }
20191
20192   /* Construct the API message */
20193   M (CLASSIFY_SESSION_DUMP, mp);
20194   mp->context = 0;
20195   mp->table_id = ntohl (table_id);
20196   S (mp);
20197
20198   /* Use a control ping for synchronization */
20199   MPING (CONTROL_PING, mp_ping);
20200   S (mp_ping);
20201
20202   W (ret);
20203   return ret;
20204 }
20205
20206 static void
20207 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20208 {
20209   vat_main_t *vam = &vat_main;
20210
20211   print (vam->ofp, "collector_address %U, collector_port %d, "
20212          "src_address %U, vrf_id %d, path_mtu %u, "
20213          "template_interval %u, udp_checksum %d",
20214          format_ip4_address, mp->collector_address,
20215          ntohs (mp->collector_port),
20216          format_ip4_address, mp->src_address,
20217          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20218          ntohl (mp->template_interval), mp->udp_checksum);
20219
20220   vam->retval = 0;
20221   vam->result_ready = 1;
20222 }
20223
20224 static void
20225   vl_api_ipfix_exporter_details_t_handler_json
20226   (vl_api_ipfix_exporter_details_t * mp)
20227 {
20228   vat_main_t *vam = &vat_main;
20229   vat_json_node_t node;
20230   struct in_addr collector_address;
20231   struct in_addr src_address;
20232
20233   vat_json_init_object (&node);
20234   clib_memcpy (&collector_address, &mp->collector_address,
20235                sizeof (collector_address));
20236   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20237   vat_json_object_add_uint (&node, "collector_port",
20238                             ntohs (mp->collector_port));
20239   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20240   vat_json_object_add_ip4 (&node, "src_address", src_address);
20241   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20242   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20243   vat_json_object_add_uint (&node, "template_interval",
20244                             ntohl (mp->template_interval));
20245   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20246
20247   vat_json_print (vam->ofp, &node);
20248   vat_json_free (&node);
20249   vam->retval = 0;
20250   vam->result_ready = 1;
20251 }
20252
20253 int
20254 api_ipfix_exporter_dump (vat_main_t * vam)
20255 {
20256   vl_api_ipfix_exporter_dump_t *mp;
20257   int ret;
20258
20259   /* Construct the API message */
20260   M (IPFIX_EXPORTER_DUMP, mp);
20261   mp->context = 0;
20262
20263   S (mp);
20264   W (ret);
20265   return ret;
20266 }
20267
20268 static int
20269 api_ipfix_classify_stream_dump (vat_main_t * vam)
20270 {
20271   vl_api_ipfix_classify_stream_dump_t *mp;
20272   int ret;
20273
20274   /* Construct the API message */
20275   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20276   mp->context = 0;
20277
20278   S (mp);
20279   W (ret);
20280   return ret;
20281   /* NOTREACHED */
20282   return 0;
20283 }
20284
20285 static void
20286   vl_api_ipfix_classify_stream_details_t_handler
20287   (vl_api_ipfix_classify_stream_details_t * mp)
20288 {
20289   vat_main_t *vam = &vat_main;
20290   print (vam->ofp, "domain_id %d, src_port %d",
20291          ntohl (mp->domain_id), ntohs (mp->src_port));
20292   vam->retval = 0;
20293   vam->result_ready = 1;
20294 }
20295
20296 static void
20297   vl_api_ipfix_classify_stream_details_t_handler_json
20298   (vl_api_ipfix_classify_stream_details_t * mp)
20299 {
20300   vat_main_t *vam = &vat_main;
20301   vat_json_node_t node;
20302
20303   vat_json_init_object (&node);
20304   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20305   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20306
20307   vat_json_print (vam->ofp, &node);
20308   vat_json_free (&node);
20309   vam->retval = 0;
20310   vam->result_ready = 1;
20311 }
20312
20313 static int
20314 api_ipfix_classify_table_dump (vat_main_t * vam)
20315 {
20316   vl_api_ipfix_classify_table_dump_t *mp;
20317   vl_api_control_ping_t *mp_ping;
20318   int ret;
20319
20320   if (!vam->json_output)
20321     {
20322       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20323              "transport_protocol");
20324     }
20325
20326   /* Construct the API message */
20327   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20328
20329   /* send it... */
20330   S (mp);
20331
20332   /* Use a control ping for synchronization */
20333   MPING (CONTROL_PING, mp_ping);
20334   S (mp_ping);
20335
20336   W (ret);
20337   return ret;
20338 }
20339
20340 static void
20341   vl_api_ipfix_classify_table_details_t_handler
20342   (vl_api_ipfix_classify_table_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20346          mp->transport_protocol);
20347 }
20348
20349 static void
20350   vl_api_ipfix_classify_table_details_t_handler_json
20351   (vl_api_ipfix_classify_table_details_t * mp)
20352 {
20353   vat_json_node_t *node = NULL;
20354   vat_main_t *vam = &vat_main;
20355
20356   if (VAT_JSON_ARRAY != vam->json_tree.type)
20357     {
20358       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20359       vat_json_init_array (&vam->json_tree);
20360     }
20361
20362   node = vat_json_array_add (&vam->json_tree);
20363   vat_json_init_object (node);
20364
20365   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20366   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20367   vat_json_object_add_uint (node, "transport_protocol",
20368                             mp->transport_protocol);
20369 }
20370
20371 static int
20372 api_sw_interface_span_enable_disable (vat_main_t * vam)
20373 {
20374   unformat_input_t *i = vam->input;
20375   vl_api_sw_interface_span_enable_disable_t *mp;
20376   u32 src_sw_if_index = ~0;
20377   u32 dst_sw_if_index = ~0;
20378   u8 state = 3;
20379   int ret;
20380   u8 is_l2 = 0;
20381
20382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20383     {
20384       if (unformat
20385           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20386         ;
20387       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20388         ;
20389       else
20390         if (unformat
20391             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20392         ;
20393       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20394         ;
20395       else if (unformat (i, "disable"))
20396         state = 0;
20397       else if (unformat (i, "rx"))
20398         state = 1;
20399       else if (unformat (i, "tx"))
20400         state = 2;
20401       else if (unformat (i, "both"))
20402         state = 3;
20403       else if (unformat (i, "l2"))
20404         is_l2 = 1;
20405       else
20406         break;
20407     }
20408
20409   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20410
20411   mp->sw_if_index_from = htonl (src_sw_if_index);
20412   mp->sw_if_index_to = htonl (dst_sw_if_index);
20413   mp->state = state;
20414   mp->is_l2 = is_l2;
20415
20416   S (mp);
20417   W (ret);
20418   return ret;
20419 }
20420
20421 static void
20422 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20423                                             * mp)
20424 {
20425   vat_main_t *vam = &vat_main;
20426   u8 *sw_if_from_name = 0;
20427   u8 *sw_if_to_name = 0;
20428   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20429   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20430   char *states[] = { "none", "rx", "tx", "both" };
20431   hash_pair_t *p;
20432
20433   /* *INDENT-OFF* */
20434   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20435   ({
20436     if ((u32) p->value[0] == sw_if_index_from)
20437       {
20438         sw_if_from_name = (u8 *)(p->key);
20439         if (sw_if_to_name)
20440           break;
20441       }
20442     if ((u32) p->value[0] == sw_if_index_to)
20443       {
20444         sw_if_to_name = (u8 *)(p->key);
20445         if (sw_if_from_name)
20446           break;
20447       }
20448   }));
20449   /* *INDENT-ON* */
20450   print (vam->ofp, "%20s => %20s (%s)",
20451          sw_if_from_name, sw_if_to_name, states[mp->state]);
20452 }
20453
20454 static void
20455   vl_api_sw_interface_span_details_t_handler_json
20456   (vl_api_sw_interface_span_details_t * mp)
20457 {
20458   vat_main_t *vam = &vat_main;
20459   vat_json_node_t *node = NULL;
20460   u8 *sw_if_from_name = 0;
20461   u8 *sw_if_to_name = 0;
20462   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20463   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20464   hash_pair_t *p;
20465
20466   /* *INDENT-OFF* */
20467   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20468   ({
20469     if ((u32) p->value[0] == sw_if_index_from)
20470       {
20471         sw_if_from_name = (u8 *)(p->key);
20472         if (sw_if_to_name)
20473           break;
20474       }
20475     if ((u32) p->value[0] == sw_if_index_to)
20476       {
20477         sw_if_to_name = (u8 *)(p->key);
20478         if (sw_if_from_name)
20479           break;
20480       }
20481   }));
20482   /* *INDENT-ON* */
20483
20484   if (VAT_JSON_ARRAY != vam->json_tree.type)
20485     {
20486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20487       vat_json_init_array (&vam->json_tree);
20488     }
20489   node = vat_json_array_add (&vam->json_tree);
20490
20491   vat_json_init_object (node);
20492   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20493   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20494   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20495   if (0 != sw_if_to_name)
20496     {
20497       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20498     }
20499   vat_json_object_add_uint (node, "state", mp->state);
20500 }
20501
20502 static int
20503 api_sw_interface_span_dump (vat_main_t * vam)
20504 {
20505   unformat_input_t *input = vam->input;
20506   vl_api_sw_interface_span_dump_t *mp;
20507   vl_api_control_ping_t *mp_ping;
20508   u8 is_l2 = 0;
20509   int ret;
20510
20511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20512     {
20513       if (unformat (input, "l2"))
20514         is_l2 = 1;
20515       else
20516         break;
20517     }
20518
20519   M (SW_INTERFACE_SPAN_DUMP, mp);
20520   mp->is_l2 = is_l2;
20521   S (mp);
20522
20523   /* Use a control ping for synchronization */
20524   MPING (CONTROL_PING, mp_ping);
20525   S (mp_ping);
20526
20527   W (ret);
20528   return ret;
20529 }
20530
20531 int
20532 api_pg_create_interface (vat_main_t * vam)
20533 {
20534   unformat_input_t *input = vam->input;
20535   vl_api_pg_create_interface_t *mp;
20536
20537   u32 if_id = ~0;
20538   int ret;
20539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20540     {
20541       if (unformat (input, "if_id %d", &if_id))
20542         ;
20543       else
20544         break;
20545     }
20546   if (if_id == ~0)
20547     {
20548       errmsg ("missing pg interface index");
20549       return -99;
20550     }
20551
20552   /* Construct the API message */
20553   M (PG_CREATE_INTERFACE, mp);
20554   mp->context = 0;
20555   mp->interface_id = ntohl (if_id);
20556
20557   S (mp);
20558   W (ret);
20559   return ret;
20560 }
20561
20562 int
20563 api_pg_capture (vat_main_t * vam)
20564 {
20565   unformat_input_t *input = vam->input;
20566   vl_api_pg_capture_t *mp;
20567
20568   u32 if_id = ~0;
20569   u8 enable = 1;
20570   u32 count = 1;
20571   u8 pcap_file_set = 0;
20572   u8 *pcap_file = 0;
20573   int ret;
20574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20575     {
20576       if (unformat (input, "if_id %d", &if_id))
20577         ;
20578       else if (unformat (input, "pcap %s", &pcap_file))
20579         pcap_file_set = 1;
20580       else if (unformat (input, "count %d", &count))
20581         ;
20582       else if (unformat (input, "disable"))
20583         enable = 0;
20584       else
20585         break;
20586     }
20587   if (if_id == ~0)
20588     {
20589       errmsg ("missing pg interface index");
20590       return -99;
20591     }
20592   if (pcap_file_set > 0)
20593     {
20594       if (vec_len (pcap_file) > 255)
20595         {
20596           errmsg ("pcap file name is too long");
20597           return -99;
20598         }
20599     }
20600
20601   u32 name_len = vec_len (pcap_file);
20602   /* Construct the API message */
20603   M (PG_CAPTURE, mp);
20604   mp->context = 0;
20605   mp->interface_id = ntohl (if_id);
20606   mp->is_enabled = enable;
20607   mp->count = ntohl (count);
20608   mp->pcap_name_length = ntohl (name_len);
20609   if (pcap_file_set != 0)
20610     {
20611       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20612     }
20613   vec_free (pcap_file);
20614
20615   S (mp);
20616   W (ret);
20617   return ret;
20618 }
20619
20620 int
20621 api_pg_enable_disable (vat_main_t * vam)
20622 {
20623   unformat_input_t *input = vam->input;
20624   vl_api_pg_enable_disable_t *mp;
20625
20626   u8 enable = 1;
20627   u8 stream_name_set = 0;
20628   u8 *stream_name = 0;
20629   int ret;
20630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20631     {
20632       if (unformat (input, "stream %s", &stream_name))
20633         stream_name_set = 1;
20634       else if (unformat (input, "disable"))
20635         enable = 0;
20636       else
20637         break;
20638     }
20639
20640   if (stream_name_set > 0)
20641     {
20642       if (vec_len (stream_name) > 255)
20643         {
20644           errmsg ("stream name too long");
20645           return -99;
20646         }
20647     }
20648
20649   u32 name_len = vec_len (stream_name);
20650   /* Construct the API message */
20651   M (PG_ENABLE_DISABLE, mp);
20652   mp->context = 0;
20653   mp->is_enabled = enable;
20654   if (stream_name_set != 0)
20655     {
20656       mp->stream_name_length = ntohl (name_len);
20657       clib_memcpy (mp->stream_name, stream_name, name_len);
20658     }
20659   vec_free (stream_name);
20660
20661   S (mp);
20662   W (ret);
20663   return ret;
20664 }
20665
20666 int
20667 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20668 {
20669   unformat_input_t *input = vam->input;
20670   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20671
20672   u16 *low_ports = 0;
20673   u16 *high_ports = 0;
20674   u16 this_low;
20675   u16 this_hi;
20676   ip4_address_t ip4_addr;
20677   ip6_address_t ip6_addr;
20678   u32 length;
20679   u32 tmp, tmp2;
20680   u8 prefix_set = 0;
20681   u32 vrf_id = ~0;
20682   u8 is_add = 1;
20683   u8 is_ipv6 = 0;
20684   int ret;
20685
20686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20687     {
20688       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20689         {
20690           prefix_set = 1;
20691         }
20692       else
20693         if (unformat
20694             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20695         {
20696           prefix_set = 1;
20697           is_ipv6 = 1;
20698         }
20699       else if (unformat (input, "vrf %d", &vrf_id))
20700         ;
20701       else if (unformat (input, "del"))
20702         is_add = 0;
20703       else if (unformat (input, "port %d", &tmp))
20704         {
20705           if (tmp == 0 || tmp > 65535)
20706             {
20707               errmsg ("port %d out of range", tmp);
20708               return -99;
20709             }
20710           this_low = tmp;
20711           this_hi = this_low + 1;
20712           vec_add1 (low_ports, this_low);
20713           vec_add1 (high_ports, this_hi);
20714         }
20715       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20716         {
20717           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20718             {
20719               errmsg ("incorrect range parameters");
20720               return -99;
20721             }
20722           this_low = tmp;
20723           /* Note: in debug CLI +1 is added to high before
20724              passing to real fn that does "the work"
20725              (ip_source_and_port_range_check_add_del).
20726              This fn is a wrapper around the binary API fn a
20727              control plane will call, which expects this increment
20728              to have occurred. Hence letting the binary API control
20729              plane fn do the increment for consistency between VAT
20730              and other control planes.
20731            */
20732           this_hi = tmp2;
20733           vec_add1 (low_ports, this_low);
20734           vec_add1 (high_ports, this_hi);
20735         }
20736       else
20737         break;
20738     }
20739
20740   if (prefix_set == 0)
20741     {
20742       errmsg ("<address>/<mask> not specified");
20743       return -99;
20744     }
20745
20746   if (vrf_id == ~0)
20747     {
20748       errmsg ("VRF ID required, not specified");
20749       return -99;
20750     }
20751
20752   if (vrf_id == 0)
20753     {
20754       errmsg
20755         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20756       return -99;
20757     }
20758
20759   if (vec_len (low_ports) == 0)
20760     {
20761       errmsg ("At least one port or port range required");
20762       return -99;
20763     }
20764
20765   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20766
20767   mp->is_add = is_add;
20768
20769   if (is_ipv6)
20770     {
20771       mp->is_ipv6 = 1;
20772       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20773     }
20774   else
20775     {
20776       mp->is_ipv6 = 0;
20777       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20778     }
20779
20780   mp->mask_length = length;
20781   mp->number_of_ranges = vec_len (low_ports);
20782
20783   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20784   vec_free (low_ports);
20785
20786   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20787   vec_free (high_ports);
20788
20789   mp->vrf_id = ntohl (vrf_id);
20790
20791   S (mp);
20792   W (ret);
20793   return ret;
20794 }
20795
20796 int
20797 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20798 {
20799   unformat_input_t *input = vam->input;
20800   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20801   u32 sw_if_index = ~0;
20802   int vrf_set = 0;
20803   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20804   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20805   u8 is_add = 1;
20806   int ret;
20807
20808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20809     {
20810       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20811         ;
20812       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20813         ;
20814       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20815         vrf_set = 1;
20816       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20817         vrf_set = 1;
20818       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20819         vrf_set = 1;
20820       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20821         vrf_set = 1;
20822       else if (unformat (input, "del"))
20823         is_add = 0;
20824       else
20825         break;
20826     }
20827
20828   if (sw_if_index == ~0)
20829     {
20830       errmsg ("Interface required but not specified");
20831       return -99;
20832     }
20833
20834   if (vrf_set == 0)
20835     {
20836       errmsg ("VRF ID required but not specified");
20837       return -99;
20838     }
20839
20840   if (tcp_out_vrf_id == 0
20841       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20842     {
20843       errmsg
20844         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20845       return -99;
20846     }
20847
20848   /* Construct the API message */
20849   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20850
20851   mp->sw_if_index = ntohl (sw_if_index);
20852   mp->is_add = is_add;
20853   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20854   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20855   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20856   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20857
20858   /* send it... */
20859   S (mp);
20860
20861   /* Wait for a reply... */
20862   W (ret);
20863   return ret;
20864 }
20865
20866 static int
20867 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20868 {
20869   unformat_input_t *i = vam->input;
20870   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20871   u32 local_sa_id = 0;
20872   u32 remote_sa_id = 0;
20873   ip4_address_t src_address;
20874   ip4_address_t dst_address;
20875   u8 is_add = 1;
20876   int ret;
20877
20878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20879     {
20880       if (unformat (i, "local_sa %d", &local_sa_id))
20881         ;
20882       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20883         ;
20884       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20885         ;
20886       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20887         ;
20888       else if (unformat (i, "del"))
20889         is_add = 0;
20890       else
20891         {
20892           clib_warning ("parse error '%U'", format_unformat_error, i);
20893           return -99;
20894         }
20895     }
20896
20897   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20898
20899   mp->local_sa_id = ntohl (local_sa_id);
20900   mp->remote_sa_id = ntohl (remote_sa_id);
20901   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20902   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20903   mp->is_add = is_add;
20904
20905   S (mp);
20906   W (ret);
20907   return ret;
20908 }
20909
20910 static int
20911 api_punt (vat_main_t * vam)
20912 {
20913   unformat_input_t *i = vam->input;
20914   vl_api_punt_t *mp;
20915   u32 ipv = ~0;
20916   u32 protocol = ~0;
20917   u32 port = ~0;
20918   int is_add = 1;
20919   int ret;
20920
20921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20922     {
20923       if (unformat (i, "ip %d", &ipv))
20924         ;
20925       else if (unformat (i, "protocol %d", &protocol))
20926         ;
20927       else if (unformat (i, "port %d", &port))
20928         ;
20929       else if (unformat (i, "del"))
20930         is_add = 0;
20931       else
20932         {
20933           clib_warning ("parse error '%U'", format_unformat_error, i);
20934           return -99;
20935         }
20936     }
20937
20938   M (PUNT, mp);
20939
20940   mp->is_add = (u8) is_add;
20941   mp->ipv = (u8) ipv;
20942   mp->l4_protocol = (u8) protocol;
20943   mp->l4_port = htons ((u16) port);
20944
20945   S (mp);
20946   W (ret);
20947   return ret;
20948 }
20949
20950 static void vl_api_ipsec_gre_tunnel_details_t_handler
20951   (vl_api_ipsec_gre_tunnel_details_t * mp)
20952 {
20953   vat_main_t *vam = &vat_main;
20954
20955   print (vam->ofp, "%11d%15U%15U%14d%14d",
20956          ntohl (mp->sw_if_index),
20957          format_ip4_address, &mp->src_address,
20958          format_ip4_address, &mp->dst_address,
20959          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20960 }
20961
20962 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20963   (vl_api_ipsec_gre_tunnel_details_t * mp)
20964 {
20965   vat_main_t *vam = &vat_main;
20966   vat_json_node_t *node = NULL;
20967   struct in_addr ip4;
20968
20969   if (VAT_JSON_ARRAY != vam->json_tree.type)
20970     {
20971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20972       vat_json_init_array (&vam->json_tree);
20973     }
20974   node = vat_json_array_add (&vam->json_tree);
20975
20976   vat_json_init_object (node);
20977   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20978   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20979   vat_json_object_add_ip4 (node, "src_address", ip4);
20980   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20981   vat_json_object_add_ip4 (node, "dst_address", ip4);
20982   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20983   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20984 }
20985
20986 static int
20987 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20988 {
20989   unformat_input_t *i = vam->input;
20990   vl_api_ipsec_gre_tunnel_dump_t *mp;
20991   vl_api_control_ping_t *mp_ping;
20992   u32 sw_if_index;
20993   u8 sw_if_index_set = 0;
20994   int ret;
20995
20996   /* Parse args required to build the message */
20997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20998     {
20999       if (unformat (i, "sw_if_index %d", &sw_if_index))
21000         sw_if_index_set = 1;
21001       else
21002         break;
21003     }
21004
21005   if (sw_if_index_set == 0)
21006     {
21007       sw_if_index = ~0;
21008     }
21009
21010   if (!vam->json_output)
21011     {
21012       print (vam->ofp, "%11s%15s%15s%14s%14s",
21013              "sw_if_index", "src_address", "dst_address",
21014              "local_sa_id", "remote_sa_id");
21015     }
21016
21017   /* Get list of gre-tunnel interfaces */
21018   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21019
21020   mp->sw_if_index = htonl (sw_if_index);
21021
21022   S (mp);
21023
21024   /* Use a control ping for synchronization */
21025   MPING (CONTROL_PING, mp_ping);
21026   S (mp_ping);
21027
21028   W (ret);
21029   return ret;
21030 }
21031
21032 static int
21033 api_delete_subif (vat_main_t * vam)
21034 {
21035   unformat_input_t *i = vam->input;
21036   vl_api_delete_subif_t *mp;
21037   u32 sw_if_index = ~0;
21038   int ret;
21039
21040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21041     {
21042       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21043         ;
21044       if (unformat (i, "sw_if_index %d", &sw_if_index))
21045         ;
21046       else
21047         break;
21048     }
21049
21050   if (sw_if_index == ~0)
21051     {
21052       errmsg ("missing sw_if_index");
21053       return -99;
21054     }
21055
21056   /* Construct the API message */
21057   M (DELETE_SUBIF, mp);
21058   mp->sw_if_index = ntohl (sw_if_index);
21059
21060   S (mp);
21061   W (ret);
21062   return ret;
21063 }
21064
21065 #define foreach_pbb_vtr_op      \
21066 _("disable",  L2_VTR_DISABLED)  \
21067 _("pop",  L2_VTR_POP_2)         \
21068 _("push",  L2_VTR_PUSH_2)
21069
21070 static int
21071 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21072 {
21073   unformat_input_t *i = vam->input;
21074   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21075   u32 sw_if_index = ~0, vtr_op = ~0;
21076   u16 outer_tag = ~0;
21077   u8 dmac[6], smac[6];
21078   u8 dmac_set = 0, smac_set = 0;
21079   u16 vlanid = 0;
21080   u32 sid = ~0;
21081   u32 tmp;
21082   int ret;
21083
21084   /* Shut up coverity */
21085   memset (dmac, 0, sizeof (dmac));
21086   memset (smac, 0, sizeof (smac));
21087
21088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21089     {
21090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21091         ;
21092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21093         ;
21094       else if (unformat (i, "vtr_op %d", &vtr_op))
21095         ;
21096 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21097       foreach_pbb_vtr_op
21098 #undef _
21099         else if (unformat (i, "translate_pbb_stag"))
21100         {
21101           if (unformat (i, "%d", &tmp))
21102             {
21103               vtr_op = L2_VTR_TRANSLATE_2_1;
21104               outer_tag = tmp;
21105             }
21106           else
21107             {
21108               errmsg
21109                 ("translate_pbb_stag operation requires outer tag definition");
21110               return -99;
21111             }
21112         }
21113       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21114         dmac_set++;
21115       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21116         smac_set++;
21117       else if (unformat (i, "sid %d", &sid))
21118         ;
21119       else if (unformat (i, "vlanid %d", &tmp))
21120         vlanid = tmp;
21121       else
21122         {
21123           clib_warning ("parse error '%U'", format_unformat_error, i);
21124           return -99;
21125         }
21126     }
21127
21128   if ((sw_if_index == ~0) || (vtr_op == ~0))
21129     {
21130       errmsg ("missing sw_if_index or vtr operation");
21131       return -99;
21132     }
21133   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21134       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21135     {
21136       errmsg
21137         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21138       return -99;
21139     }
21140
21141   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21142   mp->sw_if_index = ntohl (sw_if_index);
21143   mp->vtr_op = ntohl (vtr_op);
21144   mp->outer_tag = ntohs (outer_tag);
21145   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21146   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21147   mp->b_vlanid = ntohs (vlanid);
21148   mp->i_sid = ntohl (sid);
21149
21150   S (mp);
21151   W (ret);
21152   return ret;
21153 }
21154
21155 static int
21156 api_flow_classify_set_interface (vat_main_t * vam)
21157 {
21158   unformat_input_t *i = vam->input;
21159   vl_api_flow_classify_set_interface_t *mp;
21160   u32 sw_if_index;
21161   int sw_if_index_set;
21162   u32 ip4_table_index = ~0;
21163   u32 ip6_table_index = ~0;
21164   u8 is_add = 1;
21165   int ret;
21166
21167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21168     {
21169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21170         sw_if_index_set = 1;
21171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21172         sw_if_index_set = 1;
21173       else if (unformat (i, "del"))
21174         is_add = 0;
21175       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21176         ;
21177       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21178         ;
21179       else
21180         {
21181           clib_warning ("parse error '%U'", format_unformat_error, i);
21182           return -99;
21183         }
21184     }
21185
21186   if (sw_if_index_set == 0)
21187     {
21188       errmsg ("missing interface name or sw_if_index");
21189       return -99;
21190     }
21191
21192   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21193
21194   mp->sw_if_index = ntohl (sw_if_index);
21195   mp->ip4_table_index = ntohl (ip4_table_index);
21196   mp->ip6_table_index = ntohl (ip6_table_index);
21197   mp->is_add = is_add;
21198
21199   S (mp);
21200   W (ret);
21201   return ret;
21202 }
21203
21204 static int
21205 api_flow_classify_dump (vat_main_t * vam)
21206 {
21207   unformat_input_t *i = vam->input;
21208   vl_api_flow_classify_dump_t *mp;
21209   vl_api_control_ping_t *mp_ping;
21210   u8 type = FLOW_CLASSIFY_N_TABLES;
21211   int ret;
21212
21213   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21214     ;
21215   else
21216     {
21217       errmsg ("classify table type must be specified");
21218       return -99;
21219     }
21220
21221   if (!vam->json_output)
21222     {
21223       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21224     }
21225
21226   M (FLOW_CLASSIFY_DUMP, mp);
21227   mp->type = type;
21228   /* send it... */
21229   S (mp);
21230
21231   /* Use a control ping for synchronization */
21232   MPING (CONTROL_PING, mp_ping);
21233   S (mp_ping);
21234
21235   /* Wait for a reply... */
21236   W (ret);
21237   return ret;
21238 }
21239
21240 static int
21241 api_feature_enable_disable (vat_main_t * vam)
21242 {
21243   unformat_input_t *i = vam->input;
21244   vl_api_feature_enable_disable_t *mp;
21245   u8 *arc_name = 0;
21246   u8 *feature_name = 0;
21247   u32 sw_if_index = ~0;
21248   u8 enable = 1;
21249   int ret;
21250
21251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21252     {
21253       if (unformat (i, "arc_name %s", &arc_name))
21254         ;
21255       else if (unformat (i, "feature_name %s", &feature_name))
21256         ;
21257       else
21258         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21259         ;
21260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21261         ;
21262       else if (unformat (i, "disable"))
21263         enable = 0;
21264       else
21265         break;
21266     }
21267
21268   if (arc_name == 0)
21269     {
21270       errmsg ("missing arc name");
21271       return -99;
21272     }
21273   if (vec_len (arc_name) > 63)
21274     {
21275       errmsg ("arc name too long");
21276     }
21277
21278   if (feature_name == 0)
21279     {
21280       errmsg ("missing feature name");
21281       return -99;
21282     }
21283   if (vec_len (feature_name) > 63)
21284     {
21285       errmsg ("feature name too long");
21286     }
21287
21288   if (sw_if_index == ~0)
21289     {
21290       errmsg ("missing interface name or sw_if_index");
21291       return -99;
21292     }
21293
21294   /* Construct the API message */
21295   M (FEATURE_ENABLE_DISABLE, mp);
21296   mp->sw_if_index = ntohl (sw_if_index);
21297   mp->enable = enable;
21298   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21299   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21300   vec_free (arc_name);
21301   vec_free (feature_name);
21302
21303   S (mp);
21304   W (ret);
21305   return ret;
21306 }
21307
21308 static int
21309 api_sw_interface_tag_add_del (vat_main_t * vam)
21310 {
21311   unformat_input_t *i = vam->input;
21312   vl_api_sw_interface_tag_add_del_t *mp;
21313   u32 sw_if_index = ~0;
21314   u8 *tag = 0;
21315   u8 enable = 1;
21316   int ret;
21317
21318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21319     {
21320       if (unformat (i, "tag %s", &tag))
21321         ;
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, "del"))
21327         enable = 0;
21328       else
21329         break;
21330     }
21331
21332   if (sw_if_index == ~0)
21333     {
21334       errmsg ("missing interface name or sw_if_index");
21335       return -99;
21336     }
21337
21338   if (enable && (tag == 0))
21339     {
21340       errmsg ("no tag specified");
21341       return -99;
21342     }
21343
21344   /* Construct the API message */
21345   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21346   mp->sw_if_index = ntohl (sw_if_index);
21347   mp->is_add = enable;
21348   if (enable)
21349     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21350   vec_free (tag);
21351
21352   S (mp);
21353   W (ret);
21354   return ret;
21355 }
21356
21357 static void vl_api_l2_xconnect_details_t_handler
21358   (vl_api_l2_xconnect_details_t * mp)
21359 {
21360   vat_main_t *vam = &vat_main;
21361
21362   print (vam->ofp, "%15d%15d",
21363          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21364 }
21365
21366 static void vl_api_l2_xconnect_details_t_handler_json
21367   (vl_api_l2_xconnect_details_t * mp)
21368 {
21369   vat_main_t *vam = &vat_main;
21370   vat_json_node_t *node = NULL;
21371
21372   if (VAT_JSON_ARRAY != vam->json_tree.type)
21373     {
21374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21375       vat_json_init_array (&vam->json_tree);
21376     }
21377   node = vat_json_array_add (&vam->json_tree);
21378
21379   vat_json_init_object (node);
21380   vat_json_object_add_uint (node, "rx_sw_if_index",
21381                             ntohl (mp->rx_sw_if_index));
21382   vat_json_object_add_uint (node, "tx_sw_if_index",
21383                             ntohl (mp->tx_sw_if_index));
21384 }
21385
21386 static int
21387 api_l2_xconnect_dump (vat_main_t * vam)
21388 {
21389   vl_api_l2_xconnect_dump_t *mp;
21390   vl_api_control_ping_t *mp_ping;
21391   int ret;
21392
21393   if (!vam->json_output)
21394     {
21395       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21396     }
21397
21398   M (L2_XCONNECT_DUMP, mp);
21399
21400   S (mp);
21401
21402   /* Use a control ping for synchronization */
21403   MPING (CONTROL_PING, mp_ping);
21404   S (mp_ping);
21405
21406   W (ret);
21407   return ret;
21408 }
21409
21410 static int
21411 api_sw_interface_set_mtu (vat_main_t * vam)
21412 {
21413   unformat_input_t *i = vam->input;
21414   vl_api_sw_interface_set_mtu_t *mp;
21415   u32 sw_if_index = ~0;
21416   u32 mtu = 0;
21417   int ret;
21418
21419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21420     {
21421       if (unformat (i, "mtu %d", &mtu))
21422         ;
21423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21424         ;
21425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21426         ;
21427       else
21428         break;
21429     }
21430
21431   if (sw_if_index == ~0)
21432     {
21433       errmsg ("missing interface name or sw_if_index");
21434       return -99;
21435     }
21436
21437   if (mtu == 0)
21438     {
21439       errmsg ("no mtu specified");
21440       return -99;
21441     }
21442
21443   /* Construct the API message */
21444   M (SW_INTERFACE_SET_MTU, mp);
21445   mp->sw_if_index = ntohl (sw_if_index);
21446   mp->mtu = ntohs ((u16) mtu);
21447
21448   S (mp);
21449   W (ret);
21450   return ret;
21451 }
21452
21453 static int
21454 api_p2p_ethernet_add (vat_main_t * vam)
21455 {
21456   unformat_input_t *i = vam->input;
21457   vl_api_p2p_ethernet_add_t *mp;
21458   u32 parent_if_index = ~0;
21459   u32 sub_id = ~0;
21460   u8 remote_mac[6];
21461   u8 mac_set = 0;
21462   int ret;
21463
21464   memset (remote_mac, 0, sizeof (remote_mac));
21465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21466     {
21467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21468         ;
21469       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21470         ;
21471       else
21472         if (unformat
21473             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21474         mac_set++;
21475       else if (unformat (i, "sub_id %d", &sub_id))
21476         ;
21477       else
21478         {
21479           clib_warning ("parse error '%U'", format_unformat_error, i);
21480           return -99;
21481         }
21482     }
21483
21484   if (parent_if_index == ~0)
21485     {
21486       errmsg ("missing interface name or sw_if_index");
21487       return -99;
21488     }
21489   if (mac_set == 0)
21490     {
21491       errmsg ("missing remote mac address");
21492       return -99;
21493     }
21494   if (sub_id == ~0)
21495     {
21496       errmsg ("missing sub-interface id");
21497       return -99;
21498     }
21499
21500   M (P2P_ETHERNET_ADD, mp);
21501   mp->parent_if_index = ntohl (parent_if_index);
21502   mp->subif_id = ntohl (sub_id);
21503   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21504
21505   S (mp);
21506   W (ret);
21507   return ret;
21508 }
21509
21510 static int
21511 api_p2p_ethernet_del (vat_main_t * vam)
21512 {
21513   unformat_input_t *i = vam->input;
21514   vl_api_p2p_ethernet_del_t *mp;
21515   u32 parent_if_index = ~0;
21516   u8 remote_mac[6];
21517   u8 mac_set = 0;
21518   int ret;
21519
21520   memset (remote_mac, 0, sizeof (remote_mac));
21521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21522     {
21523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21524         ;
21525       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21526         ;
21527       else
21528         if (unformat
21529             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21530         mac_set++;
21531       else
21532         {
21533           clib_warning ("parse error '%U'", format_unformat_error, i);
21534           return -99;
21535         }
21536     }
21537
21538   if (parent_if_index == ~0)
21539     {
21540       errmsg ("missing interface name or sw_if_index");
21541       return -99;
21542     }
21543   if (mac_set == 0)
21544     {
21545       errmsg ("missing remote mac address");
21546       return -99;
21547     }
21548
21549   M (P2P_ETHERNET_DEL, mp);
21550   mp->parent_if_index = ntohl (parent_if_index);
21551   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21552
21553   S (mp);
21554   W (ret);
21555   return ret;
21556 }
21557
21558 static int
21559 api_lldp_config (vat_main_t * vam)
21560 {
21561   unformat_input_t *i = vam->input;
21562   vl_api_lldp_config_t *mp;
21563   int tx_hold = 0;
21564   int tx_interval = 0;
21565   u8 *sys_name = NULL;
21566   int ret;
21567
21568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21569     {
21570       if (unformat (i, "system-name %s", &sys_name))
21571         ;
21572       else if (unformat (i, "tx-hold %d", &tx_hold))
21573         ;
21574       else if (unformat (i, "tx-interval %d", &tx_interval))
21575         ;
21576       else
21577         {
21578           clib_warning ("parse error '%U'", format_unformat_error, i);
21579           return -99;
21580         }
21581     }
21582
21583   vec_add1 (sys_name, 0);
21584
21585   M (LLDP_CONFIG, mp);
21586   mp->tx_hold = htonl (tx_hold);
21587   mp->tx_interval = htonl (tx_interval);
21588   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21589   vec_free (sys_name);
21590
21591   S (mp);
21592   W (ret);
21593   return ret;
21594 }
21595
21596 static int
21597 api_sw_interface_set_lldp (vat_main_t * vam)
21598 {
21599   unformat_input_t *i = vam->input;
21600   vl_api_sw_interface_set_lldp_t *mp;
21601   u32 sw_if_index = ~0;
21602   u32 enable = 1;
21603   u8 *port_desc = NULL, *mgmt_oid = NULL;
21604   ip4_address_t ip4_addr;
21605   ip6_address_t ip6_addr;
21606   int ret;
21607
21608   memset (&ip4_addr, 0, sizeof (ip4_addr));
21609   memset (&ip6_addr, 0, sizeof (ip6_addr));
21610
21611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21612     {
21613       if (unformat (i, "disable"))
21614         enable = 0;
21615       else
21616         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21617         ;
21618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21619         ;
21620       else if (unformat (i, "port-desc %s", &port_desc))
21621         ;
21622       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21623         ;
21624       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21625         ;
21626       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21627         ;
21628       else
21629         break;
21630     }
21631
21632   if (sw_if_index == ~0)
21633     {
21634       errmsg ("missing interface name or sw_if_index");
21635       return -99;
21636     }
21637
21638   /* Construct the API message */
21639   vec_add1 (port_desc, 0);
21640   vec_add1 (mgmt_oid, 0);
21641   M (SW_INTERFACE_SET_LLDP, mp);
21642   mp->sw_if_index = ntohl (sw_if_index);
21643   mp->enable = enable;
21644   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21645   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21646   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21647   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21648   vec_free (port_desc);
21649   vec_free (mgmt_oid);
21650
21651   S (mp);
21652   W (ret);
21653   return ret;
21654 }
21655
21656 static int
21657 api_tcp_configure_src_addresses (vat_main_t * vam)
21658 {
21659   vl_api_tcp_configure_src_addresses_t *mp;
21660   unformat_input_t *i = vam->input;
21661   ip4_address_t v4first, v4last;
21662   ip6_address_t v6first, v6last;
21663   u8 range_set = 0;
21664   u32 vrf_id = 0;
21665   int ret;
21666
21667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21668     {
21669       if (unformat (i, "%U - %U",
21670                     unformat_ip4_address, &v4first,
21671                     unformat_ip4_address, &v4last))
21672         {
21673           if (range_set)
21674             {
21675               errmsg ("one range per message (range already set)");
21676               return -99;
21677             }
21678           range_set = 1;
21679         }
21680       else if (unformat (i, "%U - %U",
21681                          unformat_ip6_address, &v6first,
21682                          unformat_ip6_address, &v6last))
21683         {
21684           if (range_set)
21685             {
21686               errmsg ("one range per message (range already set)");
21687               return -99;
21688             }
21689           range_set = 2;
21690         }
21691       else if (unformat (i, "vrf %d", &vrf_id))
21692         ;
21693       else
21694         break;
21695     }
21696
21697   if (range_set == 0)
21698     {
21699       errmsg ("address range not set");
21700       return -99;
21701     }
21702
21703   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21704   mp->vrf_id = ntohl (vrf_id);
21705   /* ipv6? */
21706   if (range_set == 2)
21707     {
21708       mp->is_ipv6 = 1;
21709       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21710       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21711     }
21712   else
21713     {
21714       mp->is_ipv6 = 0;
21715       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21716       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21717     }
21718   S (mp);
21719   W (ret);
21720   return ret;
21721 }
21722
21723 static void vl_api_app_namespace_add_del_reply_t_handler
21724   (vl_api_app_namespace_add_del_reply_t * mp)
21725 {
21726   vat_main_t *vam = &vat_main;
21727   i32 retval = ntohl (mp->retval);
21728   if (vam->async_mode)
21729     {
21730       vam->async_errors += (retval < 0);
21731     }
21732   else
21733     {
21734       vam->retval = retval;
21735       if (retval == 0)
21736         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21737       vam->result_ready = 1;
21738     }
21739 }
21740
21741 static void vl_api_app_namespace_add_del_reply_t_handler_json
21742   (vl_api_app_namespace_add_del_reply_t * mp)
21743 {
21744   vat_main_t *vam = &vat_main;
21745   vat_json_node_t node;
21746
21747   vat_json_init_object (&node);
21748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21749   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21750
21751   vat_json_print (vam->ofp, &node);
21752   vat_json_free (&node);
21753
21754   vam->retval = ntohl (mp->retval);
21755   vam->result_ready = 1;
21756 }
21757
21758 static int
21759 api_app_namespace_add_del (vat_main_t * vam)
21760 {
21761   vl_api_app_namespace_add_del_t *mp;
21762   unformat_input_t *i = vam->input;
21763   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21764   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21765   u64 secret;
21766   int ret;
21767
21768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21769     {
21770       if (unformat (i, "id %_%v%_", &ns_id))
21771         ;
21772       else if (unformat (i, "secret %lu", &secret))
21773         secret_set = 1;
21774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21775         sw_if_index_set = 1;
21776       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21777         ;
21778       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21779         ;
21780       else
21781         break;
21782     }
21783   if (!ns_id || !secret_set || !sw_if_index_set)
21784     {
21785       errmsg ("namespace id, secret and sw_if_index must be set");
21786       return -99;
21787     }
21788   if (vec_len (ns_id) > 64)
21789     {
21790       errmsg ("namespace id too long");
21791       return -99;
21792     }
21793   M (APP_NAMESPACE_ADD_DEL, mp);
21794
21795   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21796   mp->namespace_id_len = vec_len (ns_id);
21797   mp->secret = clib_host_to_net_u64 (secret);
21798   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21799   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21800   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21801   vec_free (ns_id);
21802   S (mp);
21803   W (ret);
21804   return ret;
21805 }
21806
21807 static int
21808 api_memfd_segment_create (vat_main_t * vam)
21809 {
21810 #if VPP_API_TEST_BUILTIN == 0
21811   unformat_input_t *i = vam->input;
21812   vl_api_memfd_segment_create_t *mp;
21813   u64 size = 64 << 20;
21814   int ret;
21815
21816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21817     {
21818       if (unformat (i, "size %U", unformat_memory_size, &size))
21819         ;
21820       else
21821         break;
21822     }
21823
21824   M (MEMFD_SEGMENT_CREATE, mp);
21825   mp->requested_size = size;
21826   S (mp);
21827   W (ret);
21828   return ret;
21829
21830 #else
21831   errmsg ("memfd_segment_create (builtin) not supported");
21832   return -99;
21833 #endif
21834 }
21835
21836 static int
21837 api_sock_init_shm (vat_main_t * vam)
21838 {
21839 #if VPP_API_TEST_BUILTIN == 0
21840   unformat_input_t *i = vam->input;
21841   vl_api_shm_elem_config_t *config = 0;
21842   u64 size = 64 << 20;
21843   int rv;
21844
21845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21846     {
21847       if (unformat (i, "size %U", unformat_memory_size, &size))
21848         ;
21849       else
21850         break;
21851     }
21852
21853   /* Try customized config to see if it works */
21854   vec_validate (config, 3);
21855   config[0].type = VL_API_VLIB_RING;
21856   config[0].count = 256;
21857   config[0].size = 256;
21858   config[1].type = VL_API_CLIENT_RING;
21859   config[1].count = 256;
21860   config[1].size = 1024;
21861   config[2].type = VL_API_CLIENT_RING;
21862   config[2].count = 8;
21863   config[2].size = 4096;
21864   config[3].type = VL_API_QUEUE;
21865   config[3].count = 256;
21866   config[3].size = sizeof (uword);
21867   rv = vl_socket_client_init_shm (config);
21868   if (!rv)
21869     vam->client_index_invalid = 1;
21870   return rv;
21871 #else
21872   return -99;
21873 #endif
21874 }
21875
21876 static int
21877 api_dns_enable_disable (vat_main_t * vam)
21878 {
21879   unformat_input_t *line_input = vam->input;
21880   vl_api_dns_enable_disable_t *mp;
21881   u8 enable_disable = 1;
21882   int ret;
21883
21884   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21885     {
21886       if (unformat (line_input, "disable"))
21887         enable_disable = 0;
21888       if (unformat (line_input, "enable"))
21889         enable_disable = 1;
21890       else
21891         break;
21892     }
21893
21894   /* Construct the API message */
21895   M (DNS_ENABLE_DISABLE, mp);
21896   mp->enable = enable_disable;
21897
21898   /* send it... */
21899   S (mp);
21900   /* Wait for the reply */
21901   W (ret);
21902   return ret;
21903 }
21904
21905 static int
21906 api_dns_resolve_name (vat_main_t * vam)
21907 {
21908   unformat_input_t *line_input = vam->input;
21909   vl_api_dns_resolve_name_t *mp;
21910   u8 *name = 0;
21911   int ret;
21912
21913   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21914     {
21915       if (unformat (line_input, "%s", &name))
21916         ;
21917       else
21918         break;
21919     }
21920
21921   if (vec_len (name) > 127)
21922     {
21923       errmsg ("name too long");
21924       return -99;
21925     }
21926
21927   /* Construct the API message */
21928   M (DNS_RESOLVE_NAME, mp);
21929   memcpy (mp->name, name, vec_len (name));
21930   vec_free (name);
21931
21932   /* send it... */
21933   S (mp);
21934   /* Wait for the reply */
21935   W (ret);
21936   return ret;
21937 }
21938
21939 static int
21940 api_dns_resolve_ip (vat_main_t * vam)
21941 {
21942   unformat_input_t *line_input = vam->input;
21943   vl_api_dns_resolve_ip_t *mp;
21944   int is_ip6 = -1;
21945   ip4_address_t addr4;
21946   ip6_address_t addr6;
21947   int ret;
21948
21949   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21950     {
21951       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21952         is_ip6 = 1;
21953       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21954         is_ip6 = 0;
21955       else
21956         break;
21957     }
21958
21959   if (is_ip6 == -1)
21960     {
21961       errmsg ("missing address");
21962       return -99;
21963     }
21964
21965   /* Construct the API message */
21966   M (DNS_RESOLVE_IP, mp);
21967   mp->is_ip6 = is_ip6;
21968   if (is_ip6)
21969     memcpy (mp->address, &addr6, sizeof (addr6));
21970   else
21971     memcpy (mp->address, &addr4, sizeof (addr4));
21972
21973   /* send it... */
21974   S (mp);
21975   /* Wait for the reply */
21976   W (ret);
21977   return ret;
21978 }
21979
21980 static int
21981 api_dns_name_server_add_del (vat_main_t * vam)
21982 {
21983   unformat_input_t *i = vam->input;
21984   vl_api_dns_name_server_add_del_t *mp;
21985   u8 is_add = 1;
21986   ip6_address_t ip6_server;
21987   ip4_address_t ip4_server;
21988   int ip6_set = 0;
21989   int ip4_set = 0;
21990   int ret = 0;
21991
21992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21993     {
21994       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21995         ip6_set = 1;
21996       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21997         ip4_set = 1;
21998       else if (unformat (i, "del"))
21999         is_add = 0;
22000       else
22001         {
22002           clib_warning ("parse error '%U'", format_unformat_error, i);
22003           return -99;
22004         }
22005     }
22006
22007   if (ip4_set && ip6_set)
22008     {
22009       errmsg ("Only one server address allowed per message");
22010       return -99;
22011     }
22012   if ((ip4_set + ip6_set) == 0)
22013     {
22014       errmsg ("Server address required");
22015       return -99;
22016     }
22017
22018   /* Construct the API message */
22019   M (DNS_NAME_SERVER_ADD_DEL, mp);
22020
22021   if (ip6_set)
22022     {
22023       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22024       mp->is_ip6 = 1;
22025     }
22026   else
22027     {
22028       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22029       mp->is_ip6 = 0;
22030     }
22031
22032   mp->is_add = is_add;
22033
22034   /* send it... */
22035   S (mp);
22036
22037   /* Wait for a reply, return good/bad news  */
22038   W (ret);
22039   return ret;
22040 }
22041
22042 static void
22043 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22044 {
22045   vat_main_t *vam = &vat_main;
22046
22047   if (mp->is_ip4)
22048     {
22049       print (vam->ofp,
22050              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22051              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22052              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22053              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22054              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22055              clib_net_to_host_u32 (mp->action_index), mp->tag);
22056     }
22057   else
22058     {
22059       print (vam->ofp,
22060              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22061              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22062              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22063              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22064              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22065              clib_net_to_host_u32 (mp->action_index), mp->tag);
22066     }
22067 }
22068
22069 static void
22070 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22071                                              mp)
22072 {
22073   vat_main_t *vam = &vat_main;
22074   vat_json_node_t *node = NULL;
22075   struct in6_addr ip6;
22076   struct in_addr ip4;
22077
22078   if (VAT_JSON_ARRAY != vam->json_tree.type)
22079     {
22080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22081       vat_json_init_array (&vam->json_tree);
22082     }
22083   node = vat_json_array_add (&vam->json_tree);
22084   vat_json_init_object (node);
22085
22086   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22087   vat_json_object_add_uint (node, "appns_index",
22088                             clib_net_to_host_u32 (mp->appns_index));
22089   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22090   vat_json_object_add_uint (node, "scope", mp->scope);
22091   vat_json_object_add_uint (node, "action_index",
22092                             clib_net_to_host_u32 (mp->action_index));
22093   vat_json_object_add_uint (node, "lcl_port",
22094                             clib_net_to_host_u16 (mp->lcl_port));
22095   vat_json_object_add_uint (node, "rmt_port",
22096                             clib_net_to_host_u16 (mp->rmt_port));
22097   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22098   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22099   vat_json_object_add_string_copy (node, "tag", mp->tag);
22100   if (mp->is_ip4)
22101     {
22102       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22103       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22104       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22105       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22106     }
22107   else
22108     {
22109       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22110       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22111       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22112       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22113     }
22114 }
22115
22116 static int
22117 api_session_rule_add_del (vat_main_t * vam)
22118 {
22119   vl_api_session_rule_add_del_t *mp;
22120   unformat_input_t *i = vam->input;
22121   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22122   u32 appns_index = 0, scope = 0;
22123   ip4_address_t lcl_ip4, rmt_ip4;
22124   ip6_address_t lcl_ip6, rmt_ip6;
22125   u8 is_ip4 = 1, conn_set = 0;
22126   u8 is_add = 1, *tag = 0;
22127   int ret;
22128
22129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22130     {
22131       if (unformat (i, "del"))
22132         is_add = 0;
22133       else if (unformat (i, "add"))
22134         ;
22135       else if (unformat (i, "proto tcp"))
22136         proto = 0;
22137       else if (unformat (i, "proto udp"))
22138         proto = 1;
22139       else if (unformat (i, "appns %d", &appns_index))
22140         ;
22141       else if (unformat (i, "scope %d", &scope))
22142         ;
22143       else if (unformat (i, "tag %_%v%_", &tag))
22144         ;
22145       else
22146         if (unformat
22147             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22148              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22149              &rmt_port))
22150         {
22151           is_ip4 = 1;
22152           conn_set = 1;
22153         }
22154       else
22155         if (unformat
22156             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22157              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22158              &rmt_port))
22159         {
22160           is_ip4 = 0;
22161           conn_set = 1;
22162         }
22163       else if (unformat (i, "action %d", &action))
22164         ;
22165       else
22166         break;
22167     }
22168   if (proto == ~0 || !conn_set || action == ~0)
22169     {
22170       errmsg ("transport proto, connection and action must be set");
22171       return -99;
22172     }
22173
22174   if (scope > 3)
22175     {
22176       errmsg ("scope should be 0-3");
22177       return -99;
22178     }
22179
22180   M (SESSION_RULE_ADD_DEL, mp);
22181
22182   mp->is_ip4 = is_ip4;
22183   mp->transport_proto = proto;
22184   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22185   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22186   mp->lcl_plen = lcl_plen;
22187   mp->rmt_plen = rmt_plen;
22188   mp->action_index = clib_host_to_net_u32 (action);
22189   mp->appns_index = clib_host_to_net_u32 (appns_index);
22190   mp->scope = scope;
22191   mp->is_add = is_add;
22192   if (is_ip4)
22193     {
22194       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22195       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22196     }
22197   else
22198     {
22199       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22200       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22201     }
22202   if (tag)
22203     {
22204       clib_memcpy (mp->tag, tag, vec_len (tag));
22205       vec_free (tag);
22206     }
22207
22208   S (mp);
22209   W (ret);
22210   return ret;
22211 }
22212
22213 static int
22214 api_session_rules_dump (vat_main_t * vam)
22215 {
22216   vl_api_session_rules_dump_t *mp;
22217   vl_api_control_ping_t *mp_ping;
22218   int ret;
22219
22220   if (!vam->json_output)
22221     {
22222       print (vam->ofp, "%=20s", "Session Rules");
22223     }
22224
22225   M (SESSION_RULES_DUMP, mp);
22226   /* send it... */
22227   S (mp);
22228
22229   /* Use a control ping for synchronization */
22230   MPING (CONTROL_PING, mp_ping);
22231   S (mp_ping);
22232
22233   /* Wait for a reply... */
22234   W (ret);
22235   return ret;
22236 }
22237
22238 static int
22239 api_ip_container_proxy_add_del (vat_main_t * vam)
22240 {
22241   vl_api_ip_container_proxy_add_del_t *mp;
22242   unformat_input_t *i = vam->input;
22243   u32 plen = ~0, sw_if_index = ~0;
22244   ip4_address_t ip4;
22245   ip6_address_t ip6;
22246   u8 is_ip4 = 1;
22247   u8 is_add = 1;
22248   int ret;
22249
22250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22251     {
22252       if (unformat (i, "del"))
22253         is_add = 0;
22254       else if (unformat (i, "add"))
22255         ;
22256       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22257         {
22258           is_ip4 = 1;
22259           plen = 32;
22260         }
22261       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22262         {
22263           is_ip4 = 0;
22264           plen = 128;
22265         }
22266       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22267         ;
22268       else
22269         break;
22270     }
22271   if (sw_if_index == ~0 || plen == ~0)
22272     {
22273       errmsg ("address and sw_if_index must be set");
22274       return -99;
22275     }
22276
22277   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22278
22279   mp->is_ip4 = is_ip4;
22280   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22281   mp->plen = plen;
22282   mp->is_add = is_add;
22283   if (is_ip4)
22284     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22285   else
22286     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22287
22288   S (mp);
22289   W (ret);
22290   return ret;
22291 }
22292
22293 static int
22294 q_or_quit (vat_main_t * vam)
22295 {
22296 #if VPP_API_TEST_BUILTIN == 0
22297   longjmp (vam->jump_buf, 1);
22298 #endif
22299   return 0;                     /* not so much */
22300 }
22301
22302 static int
22303 q (vat_main_t * vam)
22304 {
22305   return q_or_quit (vam);
22306 }
22307
22308 static int
22309 quit (vat_main_t * vam)
22310 {
22311   return q_or_quit (vam);
22312 }
22313
22314 static int
22315 comment (vat_main_t * vam)
22316 {
22317   return 0;
22318 }
22319
22320 static int
22321 cmd_cmp (void *a1, void *a2)
22322 {
22323   u8 **c1 = a1;
22324   u8 **c2 = a2;
22325
22326   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22327 }
22328
22329 static int
22330 help (vat_main_t * vam)
22331 {
22332   u8 **cmds = 0;
22333   u8 *name = 0;
22334   hash_pair_t *p;
22335   unformat_input_t *i = vam->input;
22336   int j;
22337
22338   if (unformat (i, "%s", &name))
22339     {
22340       uword *hs;
22341
22342       vec_add1 (name, 0);
22343
22344       hs = hash_get_mem (vam->help_by_name, name);
22345       if (hs)
22346         print (vam->ofp, "usage: %s %s", name, hs[0]);
22347       else
22348         print (vam->ofp, "No such msg / command '%s'", name);
22349       vec_free (name);
22350       return 0;
22351     }
22352
22353   print (vam->ofp, "Help is available for the following:");
22354
22355     /* *INDENT-OFF* */
22356     hash_foreach_pair (p, vam->function_by_name,
22357     ({
22358       vec_add1 (cmds, (u8 *)(p->key));
22359     }));
22360     /* *INDENT-ON* */
22361
22362   vec_sort_with_function (cmds, cmd_cmp);
22363
22364   for (j = 0; j < vec_len (cmds); j++)
22365     print (vam->ofp, "%s", cmds[j]);
22366
22367   vec_free (cmds);
22368   return 0;
22369 }
22370
22371 static int
22372 set (vat_main_t * vam)
22373 {
22374   u8 *name = 0, *value = 0;
22375   unformat_input_t *i = vam->input;
22376
22377   if (unformat (i, "%s", &name))
22378     {
22379       /* The input buffer is a vector, not a string. */
22380       value = vec_dup (i->buffer);
22381       vec_delete (value, i->index, 0);
22382       /* Almost certainly has a trailing newline */
22383       if (value[vec_len (value) - 1] == '\n')
22384         value[vec_len (value) - 1] = 0;
22385       /* Make sure it's a proper string, one way or the other */
22386       vec_add1 (value, 0);
22387       (void) clib_macro_set_value (&vam->macro_main,
22388                                    (char *) name, (char *) value);
22389     }
22390   else
22391     errmsg ("usage: set <name> <value>");
22392
22393   vec_free (name);
22394   vec_free (value);
22395   return 0;
22396 }
22397
22398 static int
22399 unset (vat_main_t * vam)
22400 {
22401   u8 *name = 0;
22402
22403   if (unformat (vam->input, "%s", &name))
22404     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22405       errmsg ("unset: %s wasn't set", name);
22406   vec_free (name);
22407   return 0;
22408 }
22409
22410 typedef struct
22411 {
22412   u8 *name;
22413   u8 *value;
22414 } macro_sort_t;
22415
22416
22417 static int
22418 macro_sort_cmp (void *a1, void *a2)
22419 {
22420   macro_sort_t *s1 = a1;
22421   macro_sort_t *s2 = a2;
22422
22423   return strcmp ((char *) (s1->name), (char *) (s2->name));
22424 }
22425
22426 static int
22427 dump_macro_table (vat_main_t * vam)
22428 {
22429   macro_sort_t *sort_me = 0, *sm;
22430   int i;
22431   hash_pair_t *p;
22432
22433     /* *INDENT-OFF* */
22434     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22435     ({
22436       vec_add2 (sort_me, sm, 1);
22437       sm->name = (u8 *)(p->key);
22438       sm->value = (u8 *) (p->value[0]);
22439     }));
22440     /* *INDENT-ON* */
22441
22442   vec_sort_with_function (sort_me, macro_sort_cmp);
22443
22444   if (vec_len (sort_me))
22445     print (vam->ofp, "%-15s%s", "Name", "Value");
22446   else
22447     print (vam->ofp, "The macro table is empty...");
22448
22449   for (i = 0; i < vec_len (sort_me); i++)
22450     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22451   return 0;
22452 }
22453
22454 static int
22455 dump_node_table (vat_main_t * vam)
22456 {
22457   int i, j;
22458   vlib_node_t *node, *next_node;
22459
22460   if (vec_len (vam->graph_nodes) == 0)
22461     {
22462       print (vam->ofp, "Node table empty, issue get_node_graph...");
22463       return 0;
22464     }
22465
22466   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22467     {
22468       node = vam->graph_nodes[i];
22469       print (vam->ofp, "[%d] %s", i, node->name);
22470       for (j = 0; j < vec_len (node->next_nodes); j++)
22471         {
22472           if (node->next_nodes[j] != ~0)
22473             {
22474               next_node = vam->graph_nodes[node->next_nodes[j]];
22475               print (vam->ofp, "  [%d] %s", j, next_node->name);
22476             }
22477         }
22478     }
22479   return 0;
22480 }
22481
22482 static int
22483 value_sort_cmp (void *a1, void *a2)
22484 {
22485   name_sort_t *n1 = a1;
22486   name_sort_t *n2 = a2;
22487
22488   if (n1->value < n2->value)
22489     return -1;
22490   if (n1->value > n2->value)
22491     return 1;
22492   return 0;
22493 }
22494
22495
22496 static int
22497 dump_msg_api_table (vat_main_t * vam)
22498 {
22499   api_main_t *am = &api_main;
22500   name_sort_t *nses = 0, *ns;
22501   hash_pair_t *hp;
22502   int i;
22503
22504   /* *INDENT-OFF* */
22505   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22506   ({
22507     vec_add2 (nses, ns, 1);
22508     ns->name = (u8 *)(hp->key);
22509     ns->value = (u32) hp->value[0];
22510   }));
22511   /* *INDENT-ON* */
22512
22513   vec_sort_with_function (nses, value_sort_cmp);
22514
22515   for (i = 0; i < vec_len (nses); i++)
22516     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22517   vec_free (nses);
22518   return 0;
22519 }
22520
22521 static int
22522 get_msg_id (vat_main_t * vam)
22523 {
22524   u8 *name_and_crc;
22525   u32 message_index;
22526
22527   if (unformat (vam->input, "%s", &name_and_crc))
22528     {
22529       message_index = vl_msg_api_get_msg_index (name_and_crc);
22530       if (message_index == ~0)
22531         {
22532           print (vam->ofp, " '%s' not found", name_and_crc);
22533           return 0;
22534         }
22535       print (vam->ofp, " '%s' has message index %d",
22536              name_and_crc, message_index);
22537       return 0;
22538     }
22539   errmsg ("name_and_crc required...");
22540   return 0;
22541 }
22542
22543 static int
22544 search_node_table (vat_main_t * vam)
22545 {
22546   unformat_input_t *line_input = vam->input;
22547   u8 *node_to_find;
22548   int j;
22549   vlib_node_t *node, *next_node;
22550   uword *p;
22551
22552   if (vam->graph_node_index_by_name == 0)
22553     {
22554       print (vam->ofp, "Node table empty, issue get_node_graph...");
22555       return 0;
22556     }
22557
22558   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22559     {
22560       if (unformat (line_input, "%s", &node_to_find))
22561         {
22562           vec_add1 (node_to_find, 0);
22563           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22564           if (p == 0)
22565             {
22566               print (vam->ofp, "%s not found...", node_to_find);
22567               goto out;
22568             }
22569           node = vam->graph_nodes[p[0]];
22570           print (vam->ofp, "[%d] %s", p[0], node->name);
22571           for (j = 0; j < vec_len (node->next_nodes); j++)
22572             {
22573               if (node->next_nodes[j] != ~0)
22574                 {
22575                   next_node = vam->graph_nodes[node->next_nodes[j]];
22576                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22577                 }
22578             }
22579         }
22580
22581       else
22582         {
22583           clib_warning ("parse error '%U'", format_unformat_error,
22584                         line_input);
22585           return -99;
22586         }
22587
22588     out:
22589       vec_free (node_to_find);
22590
22591     }
22592
22593   return 0;
22594 }
22595
22596
22597 static int
22598 script (vat_main_t * vam)
22599 {
22600 #if (VPP_API_TEST_BUILTIN==0)
22601   u8 *s = 0;
22602   char *save_current_file;
22603   unformat_input_t save_input;
22604   jmp_buf save_jump_buf;
22605   u32 save_line_number;
22606
22607   FILE *new_fp, *save_ifp;
22608
22609   if (unformat (vam->input, "%s", &s))
22610     {
22611       new_fp = fopen ((char *) s, "r");
22612       if (new_fp == 0)
22613         {
22614           errmsg ("Couldn't open script file %s", s);
22615           vec_free (s);
22616           return -99;
22617         }
22618     }
22619   else
22620     {
22621       errmsg ("Missing script name");
22622       return -99;
22623     }
22624
22625   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22626   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22627   save_ifp = vam->ifp;
22628   save_line_number = vam->input_line_number;
22629   save_current_file = (char *) vam->current_file;
22630
22631   vam->input_line_number = 0;
22632   vam->ifp = new_fp;
22633   vam->current_file = s;
22634   do_one_file (vam);
22635
22636   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22637   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22638   vam->ifp = save_ifp;
22639   vam->input_line_number = save_line_number;
22640   vam->current_file = (u8 *) save_current_file;
22641   vec_free (s);
22642
22643   return 0;
22644 #else
22645   clib_warning ("use the exec command...");
22646   return -99;
22647 #endif
22648 }
22649
22650 static int
22651 echo (vat_main_t * vam)
22652 {
22653   print (vam->ofp, "%v", vam->input->buffer);
22654   return 0;
22655 }
22656
22657 /* List of API message constructors, CLI names map to api_xxx */
22658 #define foreach_vpe_api_msg                                             \
22659 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22660 _(sw_interface_dump,"")                                                 \
22661 _(sw_interface_set_flags,                                               \
22662   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22663 _(sw_interface_add_del_address,                                         \
22664   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22665 _(sw_interface_set_rx_mode,                                             \
22666   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22667 _(sw_interface_set_table,                                               \
22668   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22669 _(sw_interface_set_mpls_enable,                                         \
22670   "<intfc> | sw_if_index [disable | dis]")                              \
22671 _(sw_interface_set_vpath,                                               \
22672   "<intfc> | sw_if_index <id> enable | disable")                        \
22673 _(sw_interface_set_vxlan_bypass,                                        \
22674   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22675 _(sw_interface_set_geneve_bypass,                                       \
22676   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22677 _(sw_interface_set_l2_xconnect,                                         \
22678   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22679   "enable | disable")                                                   \
22680 _(sw_interface_set_l2_bridge,                                           \
22681   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22682   "[shg <split-horizon-group>] [bvi]\n"                                 \
22683   "enable | disable")                                                   \
22684 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22685 _(bridge_domain_add_del,                                                \
22686   "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") \
22687 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22688 _(l2fib_add_del,                                                        \
22689   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22690 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22691 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22692 _(l2_flags,                                                             \
22693   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22694 _(bridge_flags,                                                         \
22695   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22696 _(tap_connect,                                                          \
22697   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22698 _(tap_modify,                                                           \
22699   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22700 _(tap_delete,                                                           \
22701   "<vpp-if-name> | sw_if_index <id>")                                   \
22702 _(sw_interface_tap_dump, "")                                            \
22703 _(tap_create_v2,                                                        \
22704   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22705 _(tap_delete_v2,                                                        \
22706   "<vpp-if-name> | sw_if_index <id>")                                   \
22707 _(sw_interface_tap_v2_dump, "")                                         \
22708 _(ip_table_add_del,                                                     \
22709   "table-id <n> [ipv6]\n")                                              \
22710 _(ip_add_del_route,                                                     \
22711   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22712   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22713   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22714   "[multipath] [count <n>]")                                            \
22715 _(ip_mroute_add_del,                                                    \
22716   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22717   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22718 _(mpls_table_add_del,                                                   \
22719   "table-id <n>\n")                                                     \
22720 _(mpls_route_add_del,                                                   \
22721   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22722   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22723   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22724   "[multipath] [count <n>]")                                            \
22725 _(mpls_ip_bind_unbind,                                                  \
22726   "<label> <addr/len>")                                                 \
22727 _(mpls_tunnel_add_del,                                                  \
22728   " via <addr> [table-id <n>]\n"                                        \
22729   "sw_if_index <id>] [l2]  [del]")                                      \
22730 _(bier_table_add_del,                                                   \
22731   "<label> <sub-domain> <set> <bsl> [del]")                             \
22732 _(bier_route_add_del,                                                   \
22733   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22734   "[<intfc> | sw_if_index <id>]"                                        \
22735   "[weight <n>] [del] [multipath]")                                     \
22736 _(proxy_arp_add_del,                                                    \
22737   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22738 _(proxy_arp_intfc_enable_disable,                                       \
22739   "<intfc> | sw_if_index <id> enable | disable")                        \
22740 _(sw_interface_set_unnumbered,                                          \
22741   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22742 _(ip_neighbor_add_del,                                                  \
22743   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22744   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22745 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22746 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22747   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22748   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22749   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22750 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22751 _(reset_fib, "vrf <n> [ipv6]")                                          \
22752 _(dhcp_proxy_config,                                                    \
22753   "svr <v46-address> src <v46-address>\n"                               \
22754    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22755 _(dhcp_proxy_set_vss,                                                   \
22756   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22757 _(dhcp_proxy_dump, "ip6")                                               \
22758 _(dhcp_client_config,                                                   \
22759   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22760 _(set_ip_flow_hash,                                                     \
22761   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22762 _(sw_interface_ip6_enable_disable,                                      \
22763   "<intfc> | sw_if_index <id> enable | disable")                        \
22764 _(sw_interface_ip6_set_link_local_address,                              \
22765   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22766 _(ip6nd_proxy_add_del,                                                  \
22767   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22768 _(ip6nd_proxy_dump, "")                                                 \
22769 _(sw_interface_ip6nd_ra_prefix,                                         \
22770   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22771   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22772   "[nolink] [isno]")                                                    \
22773 _(sw_interface_ip6nd_ra_config,                                         \
22774   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22775   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22776   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22777 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22778 _(l2_patch_add_del,                                                     \
22779   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22780   "enable | disable")                                                   \
22781 _(sr_localsid_add_del,                                                  \
22782   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22783   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22784 _(classify_add_del_table,                                               \
22785   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22786   " [del] [del-chain] mask <mask-value>\n"                              \
22787   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22788   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22789 _(classify_add_del_session,                                             \
22790   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22791   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22792   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22793   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22794 _(classify_set_interface_ip_table,                                      \
22795   "<intfc> | sw_if_index <nn> table <nn>")                              \
22796 _(classify_set_interface_l2_tables,                                     \
22797   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22798   "  [other-table <nn>]")                                               \
22799 _(get_node_index, "node <node-name")                                    \
22800 _(add_node_next, "node <node-name> next <next-node-name>")              \
22801 _(l2tpv3_create_tunnel,                                                 \
22802   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22803   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22804   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22805 _(l2tpv3_set_tunnel_cookies,                                            \
22806   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22807   "[new_remote_cookie <nn>]\n")                                         \
22808 _(l2tpv3_interface_enable_disable,                                      \
22809   "<intfc> | sw_if_index <nn> enable | disable")                        \
22810 _(l2tpv3_set_lookup_key,                                                \
22811   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22812 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22813 _(vxlan_add_del_tunnel,                                                 \
22814   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22815   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22816   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22817 _(geneve_add_del_tunnel,                                                \
22818   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22819   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22820   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22821 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22822 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22823 _(gre_add_del_tunnel,                                                   \
22824   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22825 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22826 _(l2_fib_clear_table, "")                                               \
22827 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22828 _(l2_interface_vlan_tag_rewrite,                                        \
22829   "<intfc> | sw_if_index <nn> \n"                                       \
22830   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22831   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22832 _(create_vhost_user_if,                                                 \
22833         "socket <filename> [server] [renumber <dev_instance>] "         \
22834         "[mac <mac_address>]")                                          \
22835 _(modify_vhost_user_if,                                                 \
22836         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22837         "[server] [renumber <dev_instance>]")                           \
22838 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22839 _(sw_interface_vhost_user_dump, "")                                     \
22840 _(show_version, "")                                                     \
22841 _(vxlan_gpe_add_del_tunnel,                                             \
22842   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22843   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22844   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22845   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22846 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22847 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22848 _(interface_name_renumber,                                              \
22849   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22850 _(input_acl_set_interface,                                              \
22851   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22852   "  [l2-table <nn>] [del]")                                            \
22853 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22854 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22855 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22856 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22857 _(ip_dump, "ipv4 | ipv6")                                               \
22858 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22859 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22860   "  spid_id <n> ")                                                     \
22861 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22862   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22863   "  integ_alg <alg> integ_key <hex>")                                  \
22864 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22865   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22866   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22867   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22868 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22869 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22870   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22871   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22872   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22873 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22874 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22875   "  <alg> <hex>\n")                                                    \
22876 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22877 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22878 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22879   "(auth_data 0x<data> | auth_data <data>)")                            \
22880 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22881   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22882 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22883   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22884   "(local|remote)")                                                     \
22885 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22886 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22887 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22888 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22889 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22890 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22891 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22892 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22893 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22894 _(delete_loopback,"sw_if_index <nn>")                                   \
22895 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22896 _(map_add_domain,                                                       \
22897   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22898   "ip6-src <ip6addr> "                                                  \
22899   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22900 _(map_del_domain, "index <n>")                                          \
22901 _(map_add_del_rule,                                                     \
22902   "index <n> psid <n> dst <ip6addr> [del]")                             \
22903 _(map_domain_dump, "")                                                  \
22904 _(map_rule_dump, "index <map-domain>")                                  \
22905 _(want_interface_events,  "enable|disable")                             \
22906 _(want_stats,"enable|disable")                                          \
22907 _(get_first_msg_id, "client <name>")                                    \
22908 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22909 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22910   "fib-id <nn> [ip4][ip6][default]")                                    \
22911 _(get_node_graph, " ")                                                  \
22912 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22913 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22914 _(ioam_disable, "")                                                     \
22915 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22916                             " sw_if_index <sw_if_index> p <priority> "  \
22917                             "w <weight>] [del]")                        \
22918 _(one_add_del_locator, "locator-set <locator_name> "                    \
22919                         "iface <intf> | sw_if_index <sw_if_index> "     \
22920                         "p <priority> w <weight> [del]")                \
22921 _(one_add_del_local_eid,"vni <vni> eid "                                \
22922                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22923                          "locator-set <locator_name> [del]"             \
22924                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22925 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22926 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22927 _(one_enable_disable, "enable|disable")                                 \
22928 _(one_map_register_enable_disable, "enable|disable")                    \
22929 _(one_map_register_fallback_threshold, "<value>")                       \
22930 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22931 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22932                                "[seid <seid>] "                         \
22933                                "rloc <locator> p <prio> "               \
22934                                "w <weight> [rloc <loc> ... ] "          \
22935                                "action <action> [del-all]")             \
22936 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22937                           "<local-eid>")                                \
22938 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22939 _(one_use_petr, "ip-address> | disable")                                \
22940 _(one_map_request_mode, "src-dst|dst-only")                             \
22941 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22942 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22943 _(one_locator_set_dump, "[local | remote]")                             \
22944 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22945 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22946                        "[local] | [remote]")                            \
22947 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22948 _(one_ndp_bd_get, "")                                                   \
22949 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22950 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22951 _(one_l2_arp_bd_get, "")                                                \
22952 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22953 _(one_stats_enable_disable, "enable|disalbe")                           \
22954 _(show_one_stats_enable_disable, "")                                    \
22955 _(one_eid_table_vni_dump, "")                                           \
22956 _(one_eid_table_map_dump, "l2|l3")                                      \
22957 _(one_map_resolver_dump, "")                                            \
22958 _(one_map_server_dump, "")                                              \
22959 _(one_adjacencies_get, "vni <vni>")                                     \
22960 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22961 _(show_one_rloc_probe_state, "")                                        \
22962 _(show_one_map_register_state, "")                                      \
22963 _(show_one_status, "")                                                  \
22964 _(one_stats_dump, "")                                                   \
22965 _(one_stats_flush, "")                                                  \
22966 _(one_get_map_request_itr_rlocs, "")                                    \
22967 _(one_map_register_set_ttl, "<ttl>")                                    \
22968 _(one_set_transport_protocol, "udp|api")                                \
22969 _(one_get_transport_protocol, "")                                       \
22970 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22971 _(one_show_xtr_mode, "")                                                \
22972 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22973 _(one_show_pitr_mode, "")                                               \
22974 _(one_enable_disable_petr_mode, "enable|disable")                       \
22975 _(one_show_petr_mode, "")                                               \
22976 _(show_one_nsh_mapping, "")                                             \
22977 _(show_one_pitr, "")                                                    \
22978 _(show_one_use_petr, "")                                                \
22979 _(show_one_map_request_mode, "")                                        \
22980 _(show_one_map_register_ttl, "")                                        \
22981 _(show_one_map_register_fallback_threshold, "")                         \
22982 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22983                             " sw_if_index <sw_if_index> p <priority> "  \
22984                             "w <weight>] [del]")                        \
22985 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22986                         "iface <intf> | sw_if_index <sw_if_index> "     \
22987                         "p <priority> w <weight> [del]")                \
22988 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22989                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22990                          "locator-set <locator_name> [del]"             \
22991                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22992 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22993 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22994 _(lisp_enable_disable, "enable|disable")                                \
22995 _(lisp_map_register_enable_disable, "enable|disable")                   \
22996 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22997 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22998                                "[seid <seid>] "                         \
22999                                "rloc <locator> p <prio> "               \
23000                                "w <weight> [rloc <loc> ... ] "          \
23001                                "action <action> [del-all]")             \
23002 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23003                           "<local-eid>")                                \
23004 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23005 _(lisp_use_petr, "<ip-address> | disable")                              \
23006 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23007 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23008 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23009 _(lisp_locator_set_dump, "[local | remote]")                            \
23010 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23011 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23012                        "[local] | [remote]")                            \
23013 _(lisp_eid_table_vni_dump, "")                                          \
23014 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23015 _(lisp_map_resolver_dump, "")                                           \
23016 _(lisp_map_server_dump, "")                                             \
23017 _(lisp_adjacencies_get, "vni <vni>")                                    \
23018 _(gpe_fwd_entry_vnis_get, "")                                           \
23019 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23020 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23021                                 "[table <table-id>]")                   \
23022 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23023 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23024 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23025 _(gpe_get_encap_mode, "")                                               \
23026 _(lisp_gpe_add_del_iface, "up|down")                                    \
23027 _(lisp_gpe_enable_disable, "enable|disable")                            \
23028 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23029   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23030 _(show_lisp_rloc_probe_state, "")                                       \
23031 _(show_lisp_map_register_state, "")                                     \
23032 _(show_lisp_status, "")                                                 \
23033 _(lisp_get_map_request_itr_rlocs, "")                                   \
23034 _(show_lisp_pitr, "")                                                   \
23035 _(show_lisp_use_petr, "")                                               \
23036 _(show_lisp_map_request_mode, "")                                       \
23037 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23038 _(af_packet_delete, "name <host interface name>")                       \
23039 _(policer_add_del, "name <policer name> <params> [del]")                \
23040 _(policer_dump, "[name <policer name>]")                                \
23041 _(policer_classify_set_interface,                                       \
23042   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23043   "  [l2-table <nn>] [del]")                                            \
23044 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23045 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23046     "[master|slave]")                                                   \
23047 _(netmap_delete, "name <interface name>")                               \
23048 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23049 _(mpls_fib_dump, "")                                                    \
23050 _(classify_table_ids, "")                                               \
23051 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23052 _(classify_table_info, "table_id <nn>")                                 \
23053 _(classify_session_dump, "table_id <nn>")                               \
23054 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23055     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23056     "[template_interval <nn>] [udp_checksum]")                          \
23057 _(ipfix_exporter_dump, "")                                              \
23058 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23059 _(ipfix_classify_stream_dump, "")                                       \
23060 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23061 _(ipfix_classify_table_dump, "")                                        \
23062 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23063 _(sw_interface_span_dump, "[l2]")                                           \
23064 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23065 _(pg_create_interface, "if_id <nn>")                                    \
23066 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23067 _(pg_enable_disable, "[stream <id>] disable")                           \
23068 _(ip_source_and_port_range_check_add_del,                               \
23069   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23070 _(ip_source_and_port_range_check_interface_add_del,                     \
23071   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23072   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23073 _(ipsec_gre_add_del_tunnel,                                             \
23074   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23075 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23076 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23077 _(l2_interface_pbb_tag_rewrite,                                         \
23078   "<intfc> | sw_if_index <nn> \n"                                       \
23079   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23080   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23081 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23082 _(flow_classify_set_interface,                                          \
23083   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23084 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23085 _(ip_fib_dump, "")                                                      \
23086 _(ip_mfib_dump, "")                                                     \
23087 _(ip6_fib_dump, "")                                                     \
23088 _(ip6_mfib_dump, "")                                                    \
23089 _(feature_enable_disable, "arc_name <arc_name> "                        \
23090   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23091 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23092 "[disable]")                                                            \
23093 _(l2_xconnect_dump, "")                                                 \
23094 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23095 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23096 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23097 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23098 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23099 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23100 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23101   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23102 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23103 _(memfd_segment_create,"size <nnn>")                                    \
23104 _(sock_init_shm, "size <nnn>")                                          \
23105 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23106 _(dns_enable_disable, "[enable][disable]")                              \
23107 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23108 _(dns_resolve_name, "<hostname>")                                       \
23109 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23110 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23111 _(dns_resolve_name, "<hostname>")                                       \
23112 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23113   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23114 _(session_rules_dump, "")                                               \
23115 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23116
23117 /* List of command functions, CLI names map directly to functions */
23118 #define foreach_cli_function                                    \
23119 _(comment, "usage: comment <ignore-rest-of-line>")              \
23120 _(dump_interface_table, "usage: dump_interface_table")          \
23121 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23122 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23123 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23124 _(dump_stats_table, "usage: dump_stats_table")                  \
23125 _(dump_macro_table, "usage: dump_macro_table ")                 \
23126 _(dump_node_table, "usage: dump_node_table")                    \
23127 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23128 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23129 _(echo, "usage: echo <message>")                                \
23130 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23131 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23132 _(help, "usage: help")                                          \
23133 _(q, "usage: quit")                                             \
23134 _(quit, "usage: quit")                                          \
23135 _(search_node_table, "usage: search_node_table <name>...")      \
23136 _(set, "usage: set <variable-name> <value>")                    \
23137 _(script, "usage: script <file-name>")                          \
23138 _(unset, "usage: unset <variable-name>")
23139 #define _(N,n)                                  \
23140     static void vl_api_##n##_t_handler_uni      \
23141     (vl_api_##n##_t * mp)                       \
23142     {                                           \
23143         vat_main_t * vam = &vat_main;           \
23144         if (vam->json_output) {                 \
23145             vl_api_##n##_t_handler_json(mp);    \
23146         } else {                                \
23147             vl_api_##n##_t_handler(mp);         \
23148         }                                       \
23149     }
23150 foreach_vpe_api_reply_msg;
23151 #if VPP_API_TEST_BUILTIN == 0
23152 foreach_standalone_reply_msg;
23153 #endif
23154 #undef _
23155
23156 void
23157 vat_api_hookup (vat_main_t * vam)
23158 {
23159 #define _(N,n)                                                  \
23160     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23161                            vl_api_##n##_t_handler_uni,          \
23162                            vl_noop_handler,                     \
23163                            vl_api_##n##_t_endian,               \
23164                            vl_api_##n##_t_print,                \
23165                            sizeof(vl_api_##n##_t), 1);
23166   foreach_vpe_api_reply_msg;
23167 #if VPP_API_TEST_BUILTIN == 0
23168   foreach_standalone_reply_msg;
23169 #endif
23170 #undef _
23171
23172 #if (VPP_API_TEST_BUILTIN==0)
23173   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23174
23175   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23176
23177   vam->function_by_name = hash_create_string (0, sizeof (uword));
23178
23179   vam->help_by_name = hash_create_string (0, sizeof (uword));
23180 #endif
23181
23182   /* API messages we can send */
23183 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23184   foreach_vpe_api_msg;
23185 #undef _
23186
23187   /* Help strings */
23188 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23189   foreach_vpe_api_msg;
23190 #undef _
23191
23192   /* CLI functions */
23193 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23194   foreach_cli_function;
23195 #undef _
23196
23197   /* Help strings */
23198 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23199   foreach_cli_function;
23200 #undef _
23201 }
23202
23203 #if VPP_API_TEST_BUILTIN
23204 static clib_error_t *
23205 vat_api_hookup_shim (vlib_main_t * vm)
23206 {
23207   vat_api_hookup (&vat_main);
23208   return 0;
23209 }
23210
23211 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23212 #endif
23213
23214 /*
23215  * fd.io coding-style-patch-verification: ON
23216  *
23217  * Local Variables:
23218  * eval: (c-set-style "gnu")
23219  * End:
23220  */