classifier-based ACL: refactor + add output ACL
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/in_out_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   vam->socket_client_main = &socket_client_main;
91   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
92                                    0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 int
102 vl_socket_client_read (int wait)
103 {
104   return -1;
105 };
106
107 int
108 vl_socket_client_write ()
109 {
110   return -1;
111 };
112
113 void *
114 vl_socket_client_msg_alloc (int nbytes)
115 {
116   return 0;
117 }
118 #endif
119
120
121 f64
122 vat_time_now (vat_main_t * vam)
123 {
124 #if VPP_API_TEST_BUILTIN
125   return vlib_time_now (vam->vlib_main);
126 #else
127   return clib_time_now (&vam->clib_time);
128 #endif
129 }
130
131 void
132 errmsg (char *fmt, ...)
133 {
134   vat_main_t *vam = &vat_main;
135   va_list va;
136   u8 *s;
137
138   va_start (va, fmt);
139   s = va_format (0, fmt, &va);
140   va_end (va);
141
142   vec_add1 (s, 0);
143
144 #if VPP_API_TEST_BUILTIN
145   vlib_cli_output (vam->vlib_main, (char *) s);
146 #else
147   {
148     if (vam->ifp != stdin)
149       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
150                vam->input_line_number);
151     fformat (vam->ofp, (char *) s);
152     fflush (vam->ofp);
153   }
154 #endif
155
156   vec_free (s);
157 }
158
159 #if VPP_API_TEST_BUILTIN == 0
160 static uword
161 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
162 {
163   vat_main_t *vam = va_arg (*args, vat_main_t *);
164   u32 *result = va_arg (*args, u32 *);
165   u8 *if_name;
166   uword *p;
167
168   if (!unformat (input, "%s", &if_name))
169     return 0;
170
171   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
172   if (p == 0)
173     return 0;
174   *result = p[0];
175   return 1;
176 }
177
178 /* Parse an IP4 address %d.%d.%d.%d. */
179 uword
180 unformat_ip4_address (unformat_input_t * input, va_list * args)
181 {
182   u8 *result = va_arg (*args, u8 *);
183   unsigned a[4];
184
185   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
186     return 0;
187
188   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
189     return 0;
190
191   result[0] = a[0];
192   result[1] = a[1];
193   result[2] = a[2];
194   result[3] = a[3];
195
196   return 1;
197 }
198
199 uword
200 unformat_ethernet_address (unformat_input_t * input, va_list * args)
201 {
202   u8 *result = va_arg (*args, u8 *);
203   u32 i, a[6];
204
205   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
206                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
207     return 0;
208
209   /* Check range. */
210   for (i = 0; i < 6; i++)
211     if (a[i] >= (1 << 8))
212       return 0;
213
214   for (i = 0; i < 6; i++)
215     result[i] = a[i];
216
217   return 1;
218 }
219
220 /* Returns ethernet type as an int in host byte order. */
221 uword
222 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
223                                         va_list * args)
224 {
225   u16 *result = va_arg (*args, u16 *);
226   int type;
227
228   /* Numeric type. */
229   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
230     {
231       if (type >= (1 << 16))
232         return 0;
233       *result = type;
234       return 1;
235     }
236   return 0;
237 }
238
239 /* Parse an IP6 address. */
240 uword
241 unformat_ip6_address (unformat_input_t * input, va_list * args)
242 {
243   ip6_address_t *result = va_arg (*args, ip6_address_t *);
244   u16 hex_quads[8];
245   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
246   uword c, n_colon, double_colon_index;
247
248   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
249   double_colon_index = ARRAY_LEN (hex_quads);
250   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
251     {
252       hex_digit = 16;
253       if (c >= '0' && c <= '9')
254         hex_digit = c - '0';
255       else if (c >= 'a' && c <= 'f')
256         hex_digit = c + 10 - 'a';
257       else if (c >= 'A' && c <= 'F')
258         hex_digit = c + 10 - 'A';
259       else if (c == ':' && n_colon < 2)
260         n_colon++;
261       else
262         {
263           unformat_put_input (input);
264           break;
265         }
266
267       /* Too many hex quads. */
268       if (n_hex_quads >= ARRAY_LEN (hex_quads))
269         return 0;
270
271       if (hex_digit < 16)
272         {
273           hex_quad = (hex_quad << 4) | hex_digit;
274
275           /* Hex quad must fit in 16 bits. */
276           if (n_hex_digits >= 4)
277             return 0;
278
279           n_colon = 0;
280           n_hex_digits++;
281         }
282
283       /* Save position of :: */
284       if (n_colon == 2)
285         {
286           /* More than one :: ? */
287           if (double_colon_index < ARRAY_LEN (hex_quads))
288             return 0;
289           double_colon_index = n_hex_quads;
290         }
291
292       if (n_colon > 0 && n_hex_digits > 0)
293         {
294           hex_quads[n_hex_quads++] = hex_quad;
295           hex_quad = 0;
296           n_hex_digits = 0;
297         }
298     }
299
300   if (n_hex_digits > 0)
301     hex_quads[n_hex_quads++] = hex_quad;
302
303   {
304     word i;
305
306     /* Expand :: to appropriate number of zero hex quads. */
307     if (double_colon_index < ARRAY_LEN (hex_quads))
308       {
309         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
310
311         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
312           hex_quads[n_zero + i] = hex_quads[i];
313
314         for (i = 0; i < n_zero; i++)
315           hex_quads[double_colon_index + i] = 0;
316
317         n_hex_quads = ARRAY_LEN (hex_quads);
318       }
319
320     /* Too few hex quads given. */
321     if (n_hex_quads < ARRAY_LEN (hex_quads))
322       return 0;
323
324     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
325       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
326
327     return 1;
328   }
329 }
330
331 uword
332 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
338   foreach_ipsec_policy_action
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 uword
346 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
347 {
348   u32 *r = va_arg (*args, u32 *);
349
350   if (0);
351 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
352   foreach_ipsec_crypto_alg
353 #undef _
354     else
355     return 0;
356   return 1;
357 }
358
359 u8 *
360 format_ipsec_crypto_alg (u8 * s, va_list * args)
361 {
362   u32 i = va_arg (*args, u32);
363   u8 *t = 0;
364
365   switch (i)
366     {
367 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
368       foreach_ipsec_crypto_alg
369 #undef _
370     default:
371       return format (s, "unknown");
372     }
373   return format (s, "%s", t);
374 }
375
376 uword
377 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
383   foreach_ipsec_integ_alg
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 uword
408 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
409 {
410   u32 *r = va_arg (*args, u32 *);
411
412   if (0);
413 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
414   foreach_ikev2_auth_method
415 #undef _
416     else
417     return 0;
418   return 1;
419 }
420
421 uword
422 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
423 {
424   u32 *r = va_arg (*args, u32 *);
425
426   if (0);
427 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
428   foreach_ikev2_id_type
429 #undef _
430     else
431     return 0;
432   return 1;
433 }
434 #else /* VPP_API_TEST_BUILTIN == 1 */
435 static uword
436 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
437 {
438   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
439   vnet_main_t *vnm = vnet_get_main ();
440   u32 *result = va_arg (*args, u32 *);
441   u32 sw_if_index;
442
443   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
444     return 0;
445
446   *result = sw_if_index;
447   return 1;
448 }
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 static uword
452 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
453 {
454   u8 *r = va_arg (*args, u8 *);
455
456   if (unformat (input, "kbps"))
457     *r = SSE2_QOS_RATE_KBPS;
458   else if (unformat (input, "pps"))
459     *r = SSE2_QOS_RATE_PPS;
460   else
461     return 0;
462   return 1;
463 }
464
465 static uword
466 unformat_policer_round_type (unformat_input_t * input, va_list * args)
467 {
468   u8 *r = va_arg (*args, u8 *);
469
470   if (unformat (input, "closest"))
471     *r = SSE2_QOS_ROUND_TO_CLOSEST;
472   else if (unformat (input, "up"))
473     *r = SSE2_QOS_ROUND_TO_UP;
474   else if (unformat (input, "down"))
475     *r = SSE2_QOS_ROUND_TO_DOWN;
476   else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "1r2c"))
487     *r = SSE2_QOS_POLICER_TYPE_1R2C;
488   else if (unformat (input, "1r3c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
490   else if (unformat (input, "2r3c-2698"))
491     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
492   else if (unformat (input, "2r3c-4115"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
494   else if (unformat (input, "2r3c-mef5cf1"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
496   else
497     return 0;
498   return 1;
499 }
500
501 static uword
502 unformat_dscp (unformat_input_t * input, va_list * va)
503 {
504   u8 *r = va_arg (*va, u8 *);
505
506   if (0);
507 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
508   foreach_vnet_dscp
509 #undef _
510     else
511     return 0;
512   return 1;
513 }
514
515 static uword
516 unformat_policer_action_type (unformat_input_t * input, va_list * va)
517 {
518   sse2_qos_pol_action_params_st *a
519     = va_arg (*va, sse2_qos_pol_action_params_st *);
520
521   if (unformat (input, "drop"))
522     a->action_type = SSE2_QOS_ACTION_DROP;
523   else if (unformat (input, "transmit"))
524     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
525   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
526     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
527   else
528     return 0;
529   return 1;
530 }
531
532 static uword
533 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
534 {
535   u32 *r = va_arg (*va, u32 *);
536   u32 tid;
537
538   if (unformat (input, "ip4"))
539     tid = POLICER_CLASSIFY_TABLE_IP4;
540   else if (unformat (input, "ip6"))
541     tid = POLICER_CLASSIFY_TABLE_IP6;
542   else if (unformat (input, "l2"))
543     tid = POLICER_CLASSIFY_TABLE_L2;
544   else
545     return 0;
546
547   *r = tid;
548   return 1;
549 }
550
551 static uword
552 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
553 {
554   u32 *r = va_arg (*va, u32 *);
555   u32 tid;
556
557   if (unformat (input, "ip4"))
558     tid = FLOW_CLASSIFY_TABLE_IP4;
559   else if (unformat (input, "ip6"))
560     tid = FLOW_CLASSIFY_TABLE_IP6;
561   else
562     return 0;
563
564   *r = tid;
565   return 1;
566 }
567
568 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
569 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
570 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
571 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
572
573 #if (VPP_API_TEST_BUILTIN==0)
574 uword
575 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
576 {
577   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
578   mfib_itf_attribute_t attr;
579
580   old = *iflags;
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_long_names[attr]))
584       *iflags |= (1 << attr);
585   }
586   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
587   {
588     if (unformat (input, mfib_itf_flag_names[attr]))
589       *iflags |= (1 << attr);
590   }
591
592   return (old == *iflags ? 0 : 1);
593 }
594
595 uword
596 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
597 {
598   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
599   mfib_entry_attribute_t attr;
600
601   old = *eflags;
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_long_names[attr]))
605       *eflags |= (1 << attr);
606   }
607   FOR_EACH_MFIB_ATTRIBUTE (attr)
608   {
609     if (unformat (input, mfib_flag_names[attr]))
610       *eflags |= (1 << attr);
611   }
612
613   return (old == *eflags ? 0 : 1);
614 }
615
616 u8 *
617 format_ip4_address (u8 * s, va_list * args)
618 {
619   u8 *a = va_arg (*args, u8 *);
620   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
621 }
622
623 u8 *
624 format_ip6_address (u8 * s, va_list * args)
625 {
626   ip6_address_t *a = va_arg (*args, ip6_address_t *);
627   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
628
629   i_max_n_zero = ARRAY_LEN (a->as_u16);
630   max_n_zeros = 0;
631   i_first_zero = i_max_n_zero;
632   n_zeros = 0;
633   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
634     {
635       u32 is_zero = a->as_u16[i] == 0;
636       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
637         {
638           i_first_zero = i;
639           n_zeros = 0;
640         }
641       n_zeros += is_zero;
642       if ((!is_zero && n_zeros > max_n_zeros)
643           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
644         {
645           i_max_n_zero = i_first_zero;
646           max_n_zeros = n_zeros;
647           i_first_zero = ARRAY_LEN (a->as_u16);
648           n_zeros = 0;
649         }
650     }
651
652   last_double_colon = 0;
653   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
654     {
655       if (i == i_max_n_zero && max_n_zeros > 1)
656         {
657           s = format (s, "::");
658           i += max_n_zeros - 1;
659           last_double_colon = 1;
660         }
661       else
662         {
663           s = format (s, "%s%x",
664                       (last_double_colon || i == 0) ? "" : ":",
665                       clib_net_to_host_u16 (a->as_u16[i]));
666           last_double_colon = 0;
667         }
668     }
669
670   return s;
671 }
672
673 /* Format an IP46 address. */
674 u8 *
675 format_ip46_address (u8 * s, va_list * args)
676 {
677   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
678   ip46_type_t type = va_arg (*args, ip46_type_t);
679   int is_ip4 = 1;
680
681   switch (type)
682     {
683     case IP46_TYPE_ANY:
684       is_ip4 = ip46_address_is_ip4 (ip46);
685       break;
686     case IP46_TYPE_IP4:
687       is_ip4 = 1;
688       break;
689     case IP46_TYPE_IP6:
690       is_ip4 = 0;
691       break;
692     }
693
694   return is_ip4 ?
695     format (s, "%U", format_ip4_address, &ip46->ip4) :
696     format (s, "%U", format_ip6_address, &ip46->ip6);
697 }
698
699 u8 *
700 format_ethernet_address (u8 * s, va_list * args)
701 {
702   u8 *a = va_arg (*args, u8 *);
703
704   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
705                  a[0], a[1], a[2], a[3], a[4], a[5]);
706 }
707 #endif
708
709 static void
710 increment_v4_address (ip4_address_t * a)
711 {
712   u32 v;
713
714   v = ntohl (a->as_u32) + 1;
715   a->as_u32 = ntohl (v);
716 }
717
718 static void
719 increment_v6_address (ip6_address_t * a)
720 {
721   u64 v0, v1;
722
723   v0 = clib_net_to_host_u64 (a->as_u64[0]);
724   v1 = clib_net_to_host_u64 (a->as_u64[1]);
725
726   v1 += 1;
727   if (v1 == 0)
728     v0 += 1;
729   a->as_u64[0] = clib_net_to_host_u64 (v0);
730   a->as_u64[1] = clib_net_to_host_u64 (v1);
731 }
732
733 static void
734 increment_mac_address (u8 * mac)
735 {
736   u64 tmp = *((u64 *) mac);
737   tmp = clib_net_to_host_u64 (tmp);
738   tmp += 1 << 16;               /* skip unused (least significant) octets */
739   tmp = clib_host_to_net_u64 (tmp);
740
741   clib_memcpy (mac, &tmp, 6);
742 }
743
744 static void vl_api_create_loopback_reply_t_handler
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   i32 retval = ntohl (mp->retval);
749
750   vam->retval = retval;
751   vam->regenerate_interface_table = 1;
752   vam->sw_if_index = ntohl (mp->sw_if_index);
753   vam->result_ready = 1;
754 }
755
756 static void vl_api_create_loopback_reply_t_handler_json
757   (vl_api_create_loopback_reply_t * mp)
758 {
759   vat_main_t *vam = &vat_main;
760   vat_json_node_t node;
761
762   vat_json_init_object (&node);
763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
765
766   vat_json_print (vam->ofp, &node);
767   vat_json_free (&node);
768   vam->retval = ntohl (mp->retval);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   i32 retval = ntohl (mp->retval);
777
778   vam->retval = retval;
779   vam->regenerate_interface_table = 1;
780   vam->sw_if_index = ntohl (mp->sw_if_index);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_loopback_instance_reply_t_handler_json
785   (vl_api_create_loopback_instance_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   vat_json_node_t node;
789
790   vat_json_init_object (&node);
791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
792   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
793
794   vat_json_print (vam->ofp, &node);
795   vat_json_free (&node);
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->sw_if_index = ntohl (mp->sw_if_index);
809   vam->result_ready = 1;
810 }
811
812 static void vl_api_af_packet_create_reply_t_handler_json
813   (vl_api_af_packet_create_reply_t * mp)
814 {
815   vat_main_t *vam = &vat_main;
816   vat_json_node_t node;
817
818   vat_json_init_object (&node);
819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
821
822   vat_json_print (vam->ofp, &node);
823   vat_json_free (&node);
824
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_vlan_subif_reply_t_handler_json
842   (vl_api_create_vlan_subif_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_subif_reply_t_handler_json
871   (vl_api_create_subif_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_interface_name_renumber_reply_t_handler
888   (vl_api_interface_name_renumber_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_interface_name_renumber_reply_t_handler_json
899   (vl_api_interface_name_renumber_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 /*
915  * Special-case: build the interface table, maintain
916  * the next loopback sw_if_index vbl.
917  */
918 static void vl_api_sw_interface_details_t_handler
919   (vl_api_sw_interface_details_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   u8 *s = format (0, "%s%c", mp->interface_name, 0);
923
924   hash_set_mem (vam->sw_if_index_by_interface_name, s,
925                 ntohl (mp->sw_if_index));
926
927   /* In sub interface case, fill the sub interface table entry */
928   if (mp->sw_if_index != mp->sup_sw_if_index)
929     {
930       sw_interface_subif_t *sub = NULL;
931
932       vec_add2 (vam->sw_if_subif_table, sub, 1);
933
934       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
935       strncpy ((char *) sub->interface_name, (char *) s,
936                vec_len (sub->interface_name));
937       sub->sw_if_index = ntohl (mp->sw_if_index);
938       sub->sub_id = ntohl (mp->sub_id);
939
940       sub->sub_dot1ad = mp->sub_dot1ad;
941       sub->sub_number_of_tags = mp->sub_number_of_tags;
942       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
943       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
944       sub->sub_exact_match = mp->sub_exact_match;
945       sub->sub_default = mp->sub_default;
946       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
947       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
948
949       /* vlan tag rewrite */
950       sub->vtr_op = ntohl (mp->vtr_op);
951       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
952       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
953       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
954     }
955 }
956
957 static void vl_api_sw_interface_details_t_handler_json
958   (vl_api_sw_interface_details_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   vat_json_node_t *node = NULL;
962
963   if (VAT_JSON_ARRAY != vam->json_tree.type)
964     {
965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
966       vat_json_init_array (&vam->json_tree);
967     }
968   node = vat_json_array_add (&vam->json_tree);
969
970   vat_json_init_object (node);
971   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
972   vat_json_object_add_uint (node, "sup_sw_if_index",
973                             ntohl (mp->sup_sw_if_index));
974   vat_json_object_add_uint (node, "l2_address_length",
975                             ntohl (mp->l2_address_length));
976   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
977                              sizeof (mp->l2_address));
978   vat_json_object_add_string_copy (node, "interface_name",
979                                    mp->interface_name);
980   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
981   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
982   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
983   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
984   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
985   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
986   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
987   vat_json_object_add_uint (node, "sub_number_of_tags",
988                             mp->sub_number_of_tags);
989   vat_json_object_add_uint (node, "sub_outer_vlan_id",
990                             ntohs (mp->sub_outer_vlan_id));
991   vat_json_object_add_uint (node, "sub_inner_vlan_id",
992                             ntohs (mp->sub_inner_vlan_id));
993   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
994   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
995   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
996                             mp->sub_outer_vlan_id_any);
997   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
998                             mp->sub_inner_vlan_id_any);
999   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1000   vat_json_object_add_uint (node, "vtr_push_dot1q",
1001                             ntohl (mp->vtr_push_dot1q));
1002   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1003   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1004   if (mp->sub_dot1ah)
1005     {
1006       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1007                                        format (0, "%U",
1008                                                format_ethernet_address,
1009                                                &mp->b_dmac));
1010       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1011                                        format (0, "%U",
1012                                                format_ethernet_address,
1013                                                &mp->b_smac));
1014       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1015       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1016     }
1017 }
1018
1019 #if VPP_API_TEST_BUILTIN == 0
1020 static void vl_api_sw_interface_event_t_handler
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   if (vam->interface_event_display)
1025     errmsg ("interface flags: sw_if_index %d %s %s",
1026             ntohl (mp->sw_if_index),
1027             mp->admin_up_down ? "admin-up" : "admin-down",
1028             mp->link_up_down ? "link-up" : "link-down");
1029 }
1030 #endif
1031
1032 static void vl_api_sw_interface_event_t_handler_json
1033   (vl_api_sw_interface_event_t * mp)
1034 {
1035   /* JSON output not supported */
1036 }
1037
1038 static void
1039 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1040 {
1041   vat_main_t *vam = &vat_main;
1042   i32 retval = ntohl (mp->retval);
1043
1044   vam->retval = retval;
1045   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1046   vam->result_ready = 1;
1047 }
1048
1049 static void
1050 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1051 {
1052   vat_main_t *vam = &vat_main;
1053   vat_json_node_t node;
1054   api_main_t *am = &api_main;
1055   void *oldheap;
1056   u8 *reply;
1057
1058   vat_json_init_object (&node);
1059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1060   vat_json_object_add_uint (&node, "reply_in_shmem",
1061                             ntohl (mp->reply_in_shmem));
1062   /* Toss the shared-memory original... */
1063   pthread_mutex_lock (&am->vlib_rp->mutex);
1064   oldheap = svm_push_data_heap (am->vlib_rp);
1065
1066   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1067   vec_free (reply);
1068
1069   svm_pop_heap (oldheap);
1070   pthread_mutex_unlock (&am->vlib_rp->mutex);
1071
1072   vat_json_print (vam->ofp, &node);
1073   vat_json_free (&node);
1074
1075   vam->retval = ntohl (mp->retval);
1076   vam->result_ready = 1;
1077 }
1078
1079 static void
1080 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   i32 retval = ntohl (mp->retval);
1084   u32 length = ntohl (mp->length);
1085
1086   vec_reset_length (vam->cmd_reply);
1087
1088   vam->retval = retval;
1089   if (retval == 0)
1090     {
1091       vec_validate (vam->cmd_reply, length);
1092       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1093       vam->cmd_reply[length] = 0;
1094     }
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103
1104   vec_reset_length (vam->cmd_reply);
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_classify_add_del_table_reply_t_handler
1118   (vl_api_classify_add_del_table_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0 &&
1130           ((mp->new_table_index != 0xFFFFFFFF) ||
1131            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1132            (mp->match_n_vectors != 0xFFFFFFFF)))
1133         /*
1134          * Note: this is just barely thread-safe, depends on
1135          * the main thread spinning waiting for an answer...
1136          */
1137         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1138                 ntohl (mp->new_table_index),
1139                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1140       vam->result_ready = 1;
1141     }
1142 }
1143
1144 static void vl_api_classify_add_del_table_reply_t_handler_json
1145   (vl_api_classify_add_del_table_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vat_json_init_object (&node);
1151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1152   vat_json_object_add_uint (&node, "new_table_index",
1153                             ntohl (mp->new_table_index));
1154   vat_json_object_add_uint (&node, "skip_n_vectors",
1155                             ntohl (mp->skip_n_vectors));
1156   vat_json_object_add_uint (&node, "match_n_vectors",
1157                             ntohl (mp->match_n_vectors));
1158
1159   vat_json_print (vam->ofp, &node);
1160   vat_json_free (&node);
1161
1162   vam->retval = ntohl (mp->retval);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void vl_api_get_node_index_reply_t_handler
1167   (vl_api_get_node_index_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   i32 retval = ntohl (mp->retval);
1171   if (vam->async_mode)
1172     {
1173       vam->async_errors += (retval < 0);
1174     }
1175   else
1176     {
1177       vam->retval = retval;
1178       if (retval == 0)
1179         errmsg ("node index %d", ntohl (mp->node_index));
1180       vam->result_ready = 1;
1181     }
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler_json
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   vat_json_node_t node;
1189
1190   vat_json_init_object (&node);
1191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1192   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1193
1194   vat_json_print (vam->ofp, &node);
1195   vat_json_free (&node);
1196
1197   vam->retval = ntohl (mp->retval);
1198   vam->result_ready = 1;
1199 }
1200
1201 static void vl_api_get_next_index_reply_t_handler
1202   (vl_api_get_next_index_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   i32 retval = ntohl (mp->retval);
1206   if (vam->async_mode)
1207     {
1208       vam->async_errors += (retval < 0);
1209     }
1210   else
1211     {
1212       vam->retval = retval;
1213       if (retval == 0)
1214         errmsg ("next node index %d", ntohl (mp->next_index));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler_json
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1228
1229   vat_json_print (vam->ofp, &node);
1230   vat_json_free (&node);
1231
1232   vam->retval = ntohl (mp->retval);
1233   vam->result_ready = 1;
1234 }
1235
1236 static void vl_api_add_node_next_reply_t_handler
1237   (vl_api_add_node_next_reply_t * mp)
1238 {
1239   vat_main_t *vam = &vat_main;
1240   i32 retval = ntohl (mp->retval);
1241   if (vam->async_mode)
1242     {
1243       vam->async_errors += (retval < 0);
1244     }
1245   else
1246     {
1247       vam->retval = retval;
1248       if (retval == 0)
1249         errmsg ("next index %d", ntohl (mp->next_index));
1250       vam->result_ready = 1;
1251     }
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler_json
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   vat_json_node_t node;
1259
1260   vat_json_init_object (&node);
1261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1262   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1263
1264   vat_json_print (vam->ofp, &node);
1265   vat_json_free (&node);
1266
1267   vam->retval = ntohl (mp->retval);
1268   vam->result_ready = 1;
1269 }
1270
1271 static void vl_api_show_version_reply_t_handler
1272   (vl_api_show_version_reply_t * mp)
1273 {
1274   vat_main_t *vam = &vat_main;
1275   i32 retval = ntohl (mp->retval);
1276
1277   if (retval >= 0)
1278     {
1279       errmsg ("        program: %s", mp->program);
1280       errmsg ("        version: %s", mp->version);
1281       errmsg ("     build date: %s", mp->build_date);
1282       errmsg ("build directory: %s", mp->build_directory);
1283     }
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_show_version_reply_t_handler_json
1289   (vl_api_show_version_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   vat_json_node_t node;
1293
1294   vat_json_init_object (&node);
1295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1296   vat_json_object_add_string_copy (&node, "program", mp->program);
1297   vat_json_object_add_string_copy (&node, "version", mp->version);
1298   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1299   vat_json_object_add_string_copy (&node, "build_directory",
1300                                    mp->build_directory);
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void
1310 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1311 {
1312   u32 sw_if_index = ntohl (mp->sw_if_index);
1313   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1314           mp->mac_ip ? "mac/ip binding" : "address resolution",
1315           ntohl (mp->pid), format_ip4_address, &mp->address,
1316           format_ethernet_address, mp->new_mac, sw_if_index);
1317 }
1318
1319 static void
1320 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1321 {
1322   /* JSON output not supported */
1323 }
1324
1325 static void
1326 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1327 {
1328   u32 sw_if_index = ntohl (mp->sw_if_index);
1329   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1330           mp->mac_ip ? "mac/ip binding" : "address resolution",
1331           ntohl (mp->pid), format_ip6_address, mp->address,
1332           format_ethernet_address, mp->new_mac, sw_if_index);
1333 }
1334
1335 static void
1336 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1337 {
1338   /* JSON output not supported */
1339 }
1340
1341 static void
1342 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1343 {
1344   u32 n_macs = ntohl (mp->n_macs);
1345   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1346           ntohl (mp->pid), mp->client_index, n_macs);
1347   int i;
1348   for (i = 0; i < n_macs; i++)
1349     {
1350       vl_api_mac_entry_t *mac = &mp->mac[i];
1351       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->is_del);
1354       if (i == 1000)
1355         break;
1356     }
1357 }
1358
1359 static void
1360 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1361 {
1362   /* JSON output not supported */
1363 }
1364
1365 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1366 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1367
1368 /*
1369  * Special-case: build the bridge domain table, maintain
1370  * the next bd id vbl.
1371  */
1372 static void vl_api_bridge_domain_details_t_handler
1373   (vl_api_bridge_domain_details_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1377   int i;
1378
1379   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1380          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1381
1382   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1383          ntohl (mp->bd_id), mp->learn, mp->forward,
1384          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1385
1386   if (n_sw_ifs)
1387     {
1388       vl_api_bridge_domain_sw_if_t *sw_ifs;
1389       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1390              "Interface Name");
1391
1392       sw_ifs = mp->sw_if_details;
1393       for (i = 0; i < n_sw_ifs; i++)
1394         {
1395           u8 *sw_if_name = 0;
1396           u32 sw_if_index;
1397           hash_pair_t *p;
1398
1399           sw_if_index = ntohl (sw_ifs->sw_if_index);
1400
1401           /* *INDENT-OFF* */
1402           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1403                              ({
1404                                if ((u32) p->value[0] == sw_if_index)
1405                                  {
1406                                    sw_if_name = (u8 *)(p->key);
1407                                    break;
1408                                  }
1409                              }));
1410           /* *INDENT-ON* */
1411           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1412                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1413                  "sw_if_index not found!");
1414
1415           sw_ifs++;
1416         }
1417     }
1418 }
1419
1420 static void vl_api_bridge_domain_details_t_handler_json
1421   (vl_api_bridge_domain_details_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   vat_json_node_t *node, *array = NULL;
1425   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1426
1427   if (VAT_JSON_ARRAY != vam->json_tree.type)
1428     {
1429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1430       vat_json_init_array (&vam->json_tree);
1431     }
1432   node = vat_json_array_add (&vam->json_tree);
1433
1434   vat_json_init_object (node);
1435   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1436   vat_json_object_add_uint (node, "flood", mp->flood);
1437   vat_json_object_add_uint (node, "forward", mp->forward);
1438   vat_json_object_add_uint (node, "learn", mp->learn);
1439   vat_json_object_add_uint (node, "bvi_sw_if_index",
1440                             ntohl (mp->bvi_sw_if_index));
1441   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1442   array = vat_json_object_add (node, "sw_if");
1443   vat_json_init_array (array);
1444
1445
1446
1447   if (n_sw_ifs)
1448     {
1449       vl_api_bridge_domain_sw_if_t *sw_ifs;
1450       int i;
1451
1452       sw_ifs = mp->sw_if_details;
1453       for (i = 0; i < n_sw_ifs; i++)
1454         {
1455           node = vat_json_array_add (array);
1456           vat_json_init_object (node);
1457           vat_json_object_add_uint (node, "sw_if_index",
1458                                     ntohl (sw_ifs->sw_if_index));
1459           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1460           sw_ifs++;
1461         }
1462     }
1463 }
1464
1465 static void vl_api_control_ping_reply_t_handler
1466   (vl_api_control_ping_reply_t * mp)
1467 {
1468   vat_main_t *vam = &vat_main;
1469   i32 retval = ntohl (mp->retval);
1470   if (vam->async_mode)
1471     {
1472       vam->async_errors += (retval < 0);
1473     }
1474   else
1475     {
1476       vam->retval = retval;
1477       vam->result_ready = 1;
1478     }
1479   if (vam->socket_client_main)
1480     vam->socket_client_main->control_pings_outstanding--;
1481 }
1482
1483 static void vl_api_control_ping_reply_t_handler_json
1484   (vl_api_control_ping_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488
1489   if (VAT_JSON_NONE != vam->json_tree.type)
1490     {
1491       vat_json_print (vam->ofp, &vam->json_tree);
1492       vat_json_free (&vam->json_tree);
1493       vam->json_tree.type = VAT_JSON_NONE;
1494     }
1495   else
1496     {
1497       /* just print [] */
1498       vat_json_init_array (&vam->json_tree);
1499       vat_json_print (vam->ofp, &vam->json_tree);
1500       vam->json_tree.type = VAT_JSON_NONE;
1501     }
1502
1503   vam->retval = retval;
1504   vam->result_ready = 1;
1505 }
1506
1507 static void
1508   vl_api_bridge_domain_set_mac_age_reply_t_handler
1509   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1525   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void
1541 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2_flags_reply_t_handler_json
1557   (vl_api_l2_flags_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1565                             ntohl (mp->resulting_feature_bitmap));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_bridge_flags_reply_t_handler
1575   (vl_api_bridge_flags_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_bridge_flags_reply_t_handler_json
1591   (vl_api_bridge_flags_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1599                             ntohl (mp->resulting_feature_bitmap));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_tap_connect_reply_t_handler
1609   (vl_api_tap_connect_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623
1624 }
1625
1626 static void vl_api_tap_connect_reply_t_handler_json
1627   (vl_api_tap_connect_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641
1642 }
1643
1644 static void
1645 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_tap_modify_reply_t_handler_json
1662   (vl_api_tap_modify_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void
1679 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   i32 retval = ntohl (mp->retval);
1683   if (vam->async_mode)
1684     {
1685       vam->async_errors += (retval < 0);
1686     }
1687   else
1688     {
1689       vam->retval = retval;
1690       vam->result_ready = 1;
1691     }
1692 }
1693
1694 static void vl_api_tap_delete_reply_t_handler_json
1695   (vl_api_tap_delete_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   vat_json_node_t node;
1699
1700   vat_json_init_object (&node);
1701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void
1711 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   i32 retval = ntohl (mp->retval);
1715   if (vam->async_mode)
1716     {
1717       vam->async_errors += (retval < 0);
1718     }
1719   else
1720     {
1721       vam->retval = retval;
1722       vam->sw_if_index = ntohl (mp->sw_if_index);
1723       vam->result_ready = 1;
1724     }
1725
1726 }
1727
1728 static void vl_api_tap_create_v2_reply_t_handler_json
1729   (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   vat_json_node_t node;
1733
1734   vat_json_init_object (&node);
1735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1736   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1737
1738   vat_json_print (vam->ofp, &node);
1739   vat_json_free (&node);
1740
1741   vam->retval = ntohl (mp->retval);
1742   vam->result_ready = 1;
1743
1744 }
1745
1746 static void
1747 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   i32 retval = ntohl (mp->retval);
1751   if (vam->async_mode)
1752     {
1753       vam->async_errors += (retval < 0);
1754     }
1755   else
1756     {
1757       vam->retval = retval;
1758       vam->result_ready = 1;
1759     }
1760 }
1761
1762 static void vl_api_tap_delete_v2_reply_t_handler_json
1763   (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   vat_json_node_t node;
1767
1768   vat_json_init_object (&node);
1769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1770
1771   vat_json_print (vam->ofp, &node);
1772   vat_json_free (&node);
1773
1774   vam->retval = ntohl (mp->retval);
1775   vam->result_ready = 1;
1776 }
1777
1778 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1779   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   i32 retval = ntohl (mp->retval);
1783   if (vam->async_mode)
1784     {
1785       vam->async_errors += (retval < 0);
1786     }
1787   else
1788     {
1789       vam->retval = retval;
1790       vam->result_ready = 1;
1791     }
1792 }
1793
1794 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1795   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   vat_json_node_t node;
1799
1800   vat_json_init_object (&node);
1801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1802   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1803                             ntohl (mp->sw_if_index));
1804
1805   vat_json_print (vam->ofp, &node);
1806   vat_json_free (&node);
1807
1808   vam->retval = ntohl (mp->retval);
1809   vam->result_ready = 1;
1810 }
1811
1812 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1813   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   i32 retval = ntohl (mp->retval);
1817   if (vam->async_mode)
1818     {
1819       vam->async_errors += (retval < 0);
1820     }
1821   else
1822     {
1823       vam->retval = retval;
1824       vam->sw_if_index = ntohl (mp->sw_if_index);
1825       vam->result_ready = 1;
1826     }
1827 }
1828
1829 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1830   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   vat_json_node_t node;
1834
1835   vat_json_init_object (&node);
1836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1838
1839   vat_json_print (vam->ofp, &node);
1840   vat_json_free (&node);
1841
1842   vam->retval = ntohl (mp->retval);
1843   vam->result_ready = 1;
1844 }
1845
1846 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1847   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1863   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870   vat_json_object_add_uint (&node, "fwd_entry_index",
1871                             clib_net_to_host_u32 (mp->fwd_entry_index));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 u8 *
1881 format_lisp_transport_protocol (u8 * s, va_list * args)
1882 {
1883   u32 proto = va_arg (*args, u32);
1884
1885   switch (proto)
1886     {
1887     case 1:
1888       return format (s, "udp");
1889     case 2:
1890       return format (s, "api");
1891     default:
1892       return 0;
1893     }
1894   return 0;
1895 }
1896
1897 static void vl_api_one_get_transport_protocol_reply_t_handler
1898   (vl_api_one_get_transport_protocol_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       u32 proto = mp->protocol;
1909       print (vam->ofp, "Transport protocol: %U",
1910              format_lisp_transport_protocol, proto);
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1917   (vl_api_one_get_transport_protocol_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921   u8 *s;
1922
1923   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1924   vec_add1 (s, 0);
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1929
1930   vec_free (s);
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void vl_api_one_add_del_locator_set_reply_t_handler
1939   (vl_api_one_add_del_locator_set_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1955   (vl_api_one_add_del_locator_set_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1972   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->sw_if_index = ntohl (mp->sw_if_index);
1984       vam->result_ready = 1;
1985     }
1986   vam->regenerate_interface_table = 1;
1987 }
1988
1989 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1990   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2007   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   i32 retval = ntohl (mp->retval);
2011   if (vam->async_mode)
2012     {
2013       vam->async_errors += (retval < 0);
2014     }
2015   else
2016     {
2017       vam->retval = retval;
2018       vam->sw_if_index = ntohl (mp->sw_if_index);
2019       vam->result_ready = 1;
2020     }
2021 }
2022
2023 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2024   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t node;
2028
2029   vat_json_init_object (&node);
2030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2031   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2032
2033   vat_json_print (vam->ofp, &node);
2034   vat_json_free (&node);
2035
2036   vam->retval = ntohl (mp->retval);
2037   vam->result_ready = 1;
2038 }
2039
2040 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2041   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044   i32 retval = ntohl (mp->retval);
2045   if (vam->async_mode)
2046     {
2047       vam->async_errors += (retval < 0);
2048     }
2049   else
2050     {
2051       vam->retval = retval;
2052       vam->sw_if_index = ntohl (mp->sw_if_index);
2053       vam->result_ready = 1;
2054     }
2055   vam->regenerate_interface_table = 1;
2056 }
2057
2058 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2059   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2060 {
2061   vat_main_t *vam = &vat_main;
2062   vat_json_node_t node;
2063
2064   vat_json_init_object (&node);
2065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2066   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2067
2068   vat_json_print (vam->ofp, &node);
2069   vat_json_free (&node);
2070
2071   vam->retval = ntohl (mp->retval);
2072   vam->result_ready = 1;
2073 }
2074
2075 static void vl_api_gre_add_del_tunnel_reply_t_handler
2076   (vl_api_gre_add_del_tunnel_reply_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   i32 retval = ntohl (mp->retval);
2080   if (vam->async_mode)
2081     {
2082       vam->async_errors += (retval < 0);
2083     }
2084   else
2085     {
2086       vam->retval = retval;
2087       vam->sw_if_index = ntohl (mp->sw_if_index);
2088       vam->result_ready = 1;
2089     }
2090 }
2091
2092 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2093   (vl_api_gre_add_del_tunnel_reply_t * mp)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   vat_json_node_t node;
2097
2098   vat_json_init_object (&node);
2099   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2100   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2101
2102   vat_json_print (vam->ofp, &node);
2103   vat_json_free (&node);
2104
2105   vam->retval = ntohl (mp->retval);
2106   vam->result_ready = 1;
2107 }
2108
2109 static void vl_api_create_vhost_user_if_reply_t_handler
2110   (vl_api_create_vhost_user_if_reply_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113   i32 retval = ntohl (mp->retval);
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->sw_if_index = ntohl (mp->sw_if_index);
2122       vam->result_ready = 1;
2123     }
2124   vam->regenerate_interface_table = 1;
2125 }
2126
2127 static void vl_api_create_vhost_user_if_reply_t_handler_json
2128   (vl_api_create_vhost_user_if_reply_t * mp)
2129 {
2130   vat_main_t *vam = &vat_main;
2131   vat_json_node_t node;
2132
2133   vat_json_init_object (&node);
2134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2135   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2136
2137   vat_json_print (vam->ofp, &node);
2138   vat_json_free (&node);
2139
2140   vam->retval = ntohl (mp->retval);
2141   vam->result_ready = 1;
2142 }
2143
2144 static clib_error_t *
2145 receive_fd_msg (int socket_fd, int *my_fd)
2146 {
2147   char msgbuf[16];
2148   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2149   struct msghdr mh = { 0 };
2150   struct iovec iov[1];
2151   ssize_t size;
2152   struct ucred *cr = 0;
2153   struct cmsghdr *cmsg;
2154   pid_t pid __attribute__ ((unused));
2155   uid_t uid __attribute__ ((unused));
2156   gid_t gid __attribute__ ((unused));
2157
2158   iov[0].iov_base = msgbuf;
2159   iov[0].iov_len = 5;
2160   mh.msg_iov = iov;
2161   mh.msg_iovlen = 1;
2162   mh.msg_control = ctl;
2163   mh.msg_controllen = sizeof (ctl);
2164
2165   memset (ctl, 0, sizeof (ctl));
2166
2167   /* receive the incoming message */
2168   size = recvmsg (socket_fd, &mh, 0);
2169   if (size != 5)
2170     {
2171       return (size == 0) ? clib_error_return (0, "disconnected") :
2172         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2173                                 socket_fd);
2174     }
2175
2176   cmsg = CMSG_FIRSTHDR (&mh);
2177   while (cmsg)
2178     {
2179       if (cmsg->cmsg_level == SOL_SOCKET)
2180         {
2181           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2182             {
2183               cr = (struct ucred *) CMSG_DATA (cmsg);
2184               uid = cr->uid;
2185               gid = cr->gid;
2186               pid = cr->pid;
2187             }
2188           else if (cmsg->cmsg_type == SCM_RIGHTS)
2189             {
2190               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2191             }
2192         }
2193       cmsg = CMSG_NXTHDR (&mh, cmsg);
2194     }
2195   return 0;
2196 }
2197
2198 static void vl_api_memfd_segment_create_reply_t_handler
2199   (vl_api_memfd_segment_create_reply_t * mp)
2200 {
2201   /* Dont bother in the builtin version */
2202 #if VPP_API_TEST_BUILTIN == 0
2203   vat_main_t *vam = &vat_main;
2204   api_main_t *am = &api_main;
2205   socket_client_main_t *scm = vam->socket_client_main;
2206   int my_fd = -1;
2207   clib_error_t *error;
2208   ssvm_private_t memfd;
2209   i32 retval = ntohl (mp->retval);
2210
2211   if (retval == 0)
2212     {
2213       error = receive_fd_msg (scm->socket_fd, &my_fd);
2214       if (error)
2215         {
2216           retval = -99;
2217           goto out;
2218         }
2219
2220       memset (&memfd, 0, sizeof (memfd));
2221       memfd.fd = my_fd;
2222
2223       vam->client_index_invalid = 1;
2224
2225       /* Note: this closes memfd.fd */
2226       retval = ssvm_slave_init_memfd (&memfd);
2227       if (retval)
2228         clib_warning ("WARNING: segment map returned %d", retval);
2229
2230       /* Pivot to the memory client segment that vpp just created */
2231
2232       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2233
2234       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2235
2236       vl_client_install_client_message_handlers ();
2237
2238       vl_client_connect_to_vlib_no_map ("pvt",
2239                                         "vpp_api_test(p)",
2240                                         32 /* input_queue_length */ );
2241       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2242
2243       vl_socket_client_enable_disable (0 /* disable socket */ );
2244     }
2245
2246 out:
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->result_ready = 1;
2255     }
2256 #endif
2257 }
2258
2259 static void vl_api_memfd_segment_create_reply_t_handler_json
2260   (vl_api_memfd_segment_create_reply_t * mp)
2261 {
2262   clib_warning ("no");
2263 }
2264
2265 static void vl_api_dns_resolve_name_reply_t_handler
2266   (vl_api_dns_resolve_name_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   i32 retval = ntohl (mp->retval);
2270   if (vam->async_mode)
2271     {
2272       vam->async_errors += (retval < 0);
2273     }
2274   else
2275     {
2276       vam->retval = retval;
2277       vam->result_ready = 1;
2278
2279       if (retval == 0)
2280         {
2281           if (mp->ip4_set)
2282             clib_warning ("ip4 address %U", format_ip4_address,
2283                           (ip4_address_t *) mp->ip4_address);
2284           if (mp->ip6_set)
2285             clib_warning ("ip6 address %U", format_ip6_address,
2286                           (ip6_address_t *) mp->ip6_address);
2287         }
2288       else
2289         clib_warning ("retval %d", retval);
2290     }
2291 }
2292
2293 static void vl_api_dns_resolve_name_reply_t_handler_json
2294   (vl_api_dns_resolve_name_reply_t * mp)
2295 {
2296   clib_warning ("not implemented");
2297 }
2298
2299 static void vl_api_dns_resolve_ip_reply_t_handler
2300   (vl_api_dns_resolve_ip_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312
2313       if (retval == 0)
2314         {
2315           clib_warning ("canonical name %s", mp->name);
2316         }
2317       else
2318         clib_warning ("retval %d", retval);
2319     }
2320 }
2321
2322 static void vl_api_dns_resolve_ip_reply_t_handler_json
2323   (vl_api_dns_resolve_ip_reply_t * mp)
2324 {
2325   clib_warning ("not implemented");
2326 }
2327
2328
2329 static void vl_api_ip_address_details_t_handler
2330   (vl_api_ip_address_details_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   static ip_address_details_t empty_ip_address_details = { {0} };
2334   ip_address_details_t *address = NULL;
2335   ip_details_t *current_ip_details = NULL;
2336   ip_details_t *details = NULL;
2337
2338   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2339
2340   if (!details || vam->current_sw_if_index >= vec_len (details)
2341       || !details[vam->current_sw_if_index].present)
2342     {
2343       errmsg ("ip address details arrived but not stored");
2344       errmsg ("ip_dump should be called first");
2345       return;
2346     }
2347
2348   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2349
2350 #define addresses (current_ip_details->addr)
2351
2352   vec_validate_init_empty (addresses, vec_len (addresses),
2353                            empty_ip_address_details);
2354
2355   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2356
2357   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2358   address->prefix_length = mp->prefix_length;
2359 #undef addresses
2360 }
2361
2362 static void vl_api_ip_address_details_t_handler_json
2363   (vl_api_ip_address_details_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t *node = NULL;
2367   struct in6_addr ip6;
2368   struct in_addr ip4;
2369
2370   if (VAT_JSON_ARRAY != vam->json_tree.type)
2371     {
2372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2373       vat_json_init_array (&vam->json_tree);
2374     }
2375   node = vat_json_array_add (&vam->json_tree);
2376
2377   vat_json_init_object (node);
2378   if (vam->is_ipv6)
2379     {
2380       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2381       vat_json_object_add_ip6 (node, "ip", ip6);
2382     }
2383   else
2384     {
2385       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2386       vat_json_object_add_ip4 (node, "ip", ip4);
2387     }
2388   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2389 }
2390
2391 static void
2392 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   static ip_details_t empty_ip_details = { 0 };
2396   ip_details_t *ip = NULL;
2397   u32 sw_if_index = ~0;
2398
2399   sw_if_index = ntohl (mp->sw_if_index);
2400
2401   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2402                            sw_if_index, empty_ip_details);
2403
2404   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2405                          sw_if_index);
2406
2407   ip->present = 1;
2408 }
2409
2410 static void
2411 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2412 {
2413   vat_main_t *vam = &vat_main;
2414
2415   if (VAT_JSON_ARRAY != vam->json_tree.type)
2416     {
2417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418       vat_json_init_array (&vam->json_tree);
2419     }
2420   vat_json_array_add_uint (&vam->json_tree,
2421                            clib_net_to_host_u32 (mp->sw_if_index));
2422 }
2423
2424 static void vl_api_map_domain_details_t_handler_json
2425   (vl_api_map_domain_details_t * mp)
2426 {
2427   vat_json_node_t *node = NULL;
2428   vat_main_t *vam = &vat_main;
2429   struct in6_addr ip6;
2430   struct in_addr ip4;
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437
2438   node = vat_json_array_add (&vam->json_tree);
2439   vat_json_init_object (node);
2440
2441   vat_json_object_add_uint (node, "domain_index",
2442                             clib_net_to_host_u32 (mp->domain_index));
2443   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2444   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2445   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2446   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2447   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2448   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2449   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2450   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2451   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2452   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2453   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2454   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2455   vat_json_object_add_uint (node, "flags", mp->flags);
2456   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2457   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2458 }
2459
2460 static void vl_api_map_domain_details_t_handler
2461   (vl_api_map_domain_details_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464
2465   if (mp->is_translation)
2466     {
2467       print (vam->ofp,
2468              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2469              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2470              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2471              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2472              clib_net_to_host_u32 (mp->domain_index));
2473     }
2474   else
2475     {
2476       print (vam->ofp,
2477              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2478              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2479              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2480              format_ip6_address, mp->ip6_src,
2481              clib_net_to_host_u32 (mp->domain_index));
2482     }
2483   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2484          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2485          mp->is_translation ? "map-t" : "");
2486 }
2487
2488 static void vl_api_map_rule_details_t_handler_json
2489   (vl_api_map_rule_details_t * mp)
2490 {
2491   struct in6_addr ip6;
2492   vat_json_node_t *node = NULL;
2493   vat_main_t *vam = &vat_main;
2494
2495   if (VAT_JSON_ARRAY != vam->json_tree.type)
2496     {
2497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2498       vat_json_init_array (&vam->json_tree);
2499     }
2500
2501   node = vat_json_array_add (&vam->json_tree);
2502   vat_json_init_object (node);
2503
2504   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2505   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2506   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2507 }
2508
2509 static void
2510 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2514          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2515 }
2516
2517 static void
2518 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2519 {
2520   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2521           "router_addr %U host_mac %U",
2522           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2523           format_ip4_address, &mp->host_address,
2524           format_ip4_address, &mp->router_address,
2525           format_ethernet_address, mp->host_mac);
2526 }
2527
2528 static void vl_api_dhcp_compl_event_t_handler_json
2529   (vl_api_dhcp_compl_event_t * mp)
2530 {
2531   /* JSON output not supported */
2532 }
2533
2534 static void
2535 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2536                               u32 counter)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   static u64 default_counter = 0;
2540
2541   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2542                            NULL);
2543   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2544                            sw_if_index, default_counter);
2545   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2546 }
2547
2548 static void
2549 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2550                                 interface_counter_t counter)
2551 {
2552   vat_main_t *vam = &vat_main;
2553   static interface_counter_t default_counter = { 0, };
2554
2555   vec_validate_init_empty (vam->combined_interface_counters,
2556                            vnet_counter_type, NULL);
2557   vec_validate_init_empty (vam->combined_interface_counters
2558                            [vnet_counter_type], sw_if_index, default_counter);
2559   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2560 }
2561
2562 static void vl_api_vnet_interface_simple_counters_t_handler
2563   (vl_api_vnet_interface_simple_counters_t * mp)
2564 {
2565   /* not supported */
2566 }
2567
2568 static void vl_api_vnet_interface_combined_counters_t_handler
2569   (vl_api_vnet_interface_combined_counters_t * mp)
2570 {
2571   /* not supported */
2572 }
2573
2574 static void vl_api_vnet_interface_simple_counters_t_handler_json
2575   (vl_api_vnet_interface_simple_counters_t * mp)
2576 {
2577   u64 *v_packets;
2578   u64 packets;
2579   u32 count;
2580   u32 first_sw_if_index;
2581   int i;
2582
2583   count = ntohl (mp->count);
2584   first_sw_if_index = ntohl (mp->first_sw_if_index);
2585
2586   v_packets = (u64 *) & mp->data;
2587   for (i = 0; i < count; i++)
2588     {
2589       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2590       set_simple_interface_counter (mp->vnet_counter_type,
2591                                     first_sw_if_index + i, packets);
2592       v_packets++;
2593     }
2594 }
2595
2596 static void vl_api_vnet_interface_combined_counters_t_handler_json
2597   (vl_api_vnet_interface_combined_counters_t * mp)
2598 {
2599   interface_counter_t counter;
2600   vlib_counter_t *v;
2601   u32 first_sw_if_index;
2602   int i;
2603   u32 count;
2604
2605   count = ntohl (mp->count);
2606   first_sw_if_index = ntohl (mp->first_sw_if_index);
2607
2608   v = (vlib_counter_t *) & mp->data;
2609   for (i = 0; i < count; i++)
2610     {
2611       counter.packets =
2612         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2613       counter.bytes =
2614         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2615       set_combined_interface_counter (mp->vnet_counter_type,
2616                                       first_sw_if_index + i, counter);
2617       v++;
2618     }
2619 }
2620
2621 static u32
2622 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2623 {
2624   vat_main_t *vam = &vat_main;
2625   u32 i;
2626
2627   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2628     {
2629       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2630         {
2631           return i;
2632         }
2633     }
2634   return ~0;
2635 }
2636
2637 static u32
2638 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   u32 i;
2642
2643   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2644     {
2645       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2646         {
2647           return i;
2648         }
2649     }
2650   return ~0;
2651 }
2652
2653 static void vl_api_vnet_ip4_fib_counters_t_handler
2654   (vl_api_vnet_ip4_fib_counters_t * mp)
2655 {
2656   /* not supported */
2657 }
2658
2659 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2660   (vl_api_vnet_ip4_fib_counters_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   vl_api_ip4_fib_counter_t *v;
2664   ip4_fib_counter_t *counter;
2665   struct in_addr ip4;
2666   u32 vrf_id;
2667   u32 vrf_index;
2668   u32 count;
2669   int i;
2670
2671   vrf_id = ntohl (mp->vrf_id);
2672   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2673   if (~0 == vrf_index)
2674     {
2675       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2676       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2677       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2678       vec_validate (vam->ip4_fib_counters, vrf_index);
2679       vam->ip4_fib_counters[vrf_index] = NULL;
2680     }
2681
2682   vec_free (vam->ip4_fib_counters[vrf_index]);
2683   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2684   count = ntohl (mp->count);
2685   for (i = 0; i < count; i++)
2686     {
2687       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2688       counter = &vam->ip4_fib_counters[vrf_index][i];
2689       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2690       counter->address = ip4;
2691       counter->address_length = v->address_length;
2692       counter->packets = clib_net_to_host_u64 (v->packets);
2693       counter->bytes = clib_net_to_host_u64 (v->bytes);
2694       v++;
2695     }
2696 }
2697
2698 static void vl_api_vnet_ip4_nbr_counters_t_handler
2699   (vl_api_vnet_ip4_nbr_counters_t * mp)
2700 {
2701   /* not supported */
2702 }
2703
2704 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2705   (vl_api_vnet_ip4_nbr_counters_t * mp)
2706 {
2707   vat_main_t *vam = &vat_main;
2708   vl_api_ip4_nbr_counter_t *v;
2709   ip4_nbr_counter_t *counter;
2710   u32 sw_if_index;
2711   u32 count;
2712   int i;
2713
2714   sw_if_index = ntohl (mp->sw_if_index);
2715   count = ntohl (mp->count);
2716   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2717
2718   if (mp->begin)
2719     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2720
2721   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2722   for (i = 0; i < count; i++)
2723     {
2724       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2725       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2726       counter->address.s_addr = v->address;
2727       counter->packets = clib_net_to_host_u64 (v->packets);
2728       counter->bytes = clib_net_to_host_u64 (v->bytes);
2729       counter->linkt = v->link_type;
2730       v++;
2731     }
2732 }
2733
2734 static void vl_api_vnet_ip6_fib_counters_t_handler
2735   (vl_api_vnet_ip6_fib_counters_t * mp)
2736 {
2737   /* not supported */
2738 }
2739
2740 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2741   (vl_api_vnet_ip6_fib_counters_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744   vl_api_ip6_fib_counter_t *v;
2745   ip6_fib_counter_t *counter;
2746   struct in6_addr ip6;
2747   u32 vrf_id;
2748   u32 vrf_index;
2749   u32 count;
2750   int i;
2751
2752   vrf_id = ntohl (mp->vrf_id);
2753   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2754   if (~0 == vrf_index)
2755     {
2756       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2757       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2758       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2759       vec_validate (vam->ip6_fib_counters, vrf_index);
2760       vam->ip6_fib_counters[vrf_index] = NULL;
2761     }
2762
2763   vec_free (vam->ip6_fib_counters[vrf_index]);
2764   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2765   count = ntohl (mp->count);
2766   for (i = 0; i < count; i++)
2767     {
2768       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2769       counter = &vam->ip6_fib_counters[vrf_index][i];
2770       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2771       counter->address = ip6;
2772       counter->address_length = v->address_length;
2773       counter->packets = clib_net_to_host_u64 (v->packets);
2774       counter->bytes = clib_net_to_host_u64 (v->bytes);
2775       v++;
2776     }
2777 }
2778
2779 static void vl_api_vnet_ip6_nbr_counters_t_handler
2780   (vl_api_vnet_ip6_nbr_counters_t * mp)
2781 {
2782   /* not supported */
2783 }
2784
2785 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2786   (vl_api_vnet_ip6_nbr_counters_t * mp)
2787 {
2788   vat_main_t *vam = &vat_main;
2789   vl_api_ip6_nbr_counter_t *v;
2790   ip6_nbr_counter_t *counter;
2791   struct in6_addr ip6;
2792   u32 sw_if_index;
2793   u32 count;
2794   int i;
2795
2796   sw_if_index = ntohl (mp->sw_if_index);
2797   count = ntohl (mp->count);
2798   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2799
2800   if (mp->begin)
2801     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2802
2803   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2804   for (i = 0; i < count; i++)
2805     {
2806       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2807       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2808       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2809       counter->address = ip6;
2810       counter->packets = clib_net_to_host_u64 (v->packets);
2811       counter->bytes = clib_net_to_host_u64 (v->bytes);
2812       v++;
2813     }
2814 }
2815
2816 static void vl_api_get_first_msg_id_reply_t_handler
2817   (vl_api_get_first_msg_id_reply_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   i32 retval = ntohl (mp->retval);
2821
2822   if (vam->async_mode)
2823     {
2824       vam->async_errors += (retval < 0);
2825     }
2826   else
2827     {
2828       vam->retval = retval;
2829       vam->result_ready = 1;
2830     }
2831   if (retval >= 0)
2832     {
2833       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2834     }
2835 }
2836
2837 static void vl_api_get_first_msg_id_reply_t_handler_json
2838   (vl_api_get_first_msg_id_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t node;
2842
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "first_msg_id",
2846                             (uint) ntohs (mp->first_msg_id));
2847
2848   vat_json_print (vam->ofp, &node);
2849   vat_json_free (&node);
2850
2851   vam->retval = ntohl (mp->retval);
2852   vam->result_ready = 1;
2853 }
2854
2855 static void vl_api_get_node_graph_reply_t_handler
2856   (vl_api_get_node_graph_reply_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   api_main_t *am = &api_main;
2860   i32 retval = ntohl (mp->retval);
2861   u8 *pvt_copy, *reply;
2862   void *oldheap;
2863   vlib_node_t *node;
2864   int i;
2865
2866   if (vam->async_mode)
2867     {
2868       vam->async_errors += (retval < 0);
2869     }
2870   else
2871     {
2872       vam->retval = retval;
2873       vam->result_ready = 1;
2874     }
2875
2876   /* "Should never happen..." */
2877   if (retval != 0)
2878     return;
2879
2880   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2881   pvt_copy = vec_dup (reply);
2882
2883   /* Toss the shared-memory original... */
2884   pthread_mutex_lock (&am->vlib_rp->mutex);
2885   oldheap = svm_push_data_heap (am->vlib_rp);
2886
2887   vec_free (reply);
2888
2889   svm_pop_heap (oldheap);
2890   pthread_mutex_unlock (&am->vlib_rp->mutex);
2891
2892   if (vam->graph_nodes)
2893     {
2894       hash_free (vam->graph_node_index_by_name);
2895
2896       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2897         {
2898           node = vam->graph_nodes[i];
2899           vec_free (node->name);
2900           vec_free (node->next_nodes);
2901           vec_free (node);
2902         }
2903       vec_free (vam->graph_nodes);
2904     }
2905
2906   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2907   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2908   vec_free (pvt_copy);
2909
2910   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2911     {
2912       node = vam->graph_nodes[i];
2913       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2914     }
2915 }
2916
2917 static void vl_api_get_node_graph_reply_t_handler_json
2918   (vl_api_get_node_graph_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   api_main_t *am = &api_main;
2922   void *oldheap;
2923   vat_json_node_t node;
2924   u8 *reply;
2925
2926   /* $$$$ make this real? */
2927   vat_json_init_object (&node);
2928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2929   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2930
2931   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2932
2933   /* Toss the shared-memory original... */
2934   pthread_mutex_lock (&am->vlib_rp->mutex);
2935   oldheap = svm_push_data_heap (am->vlib_rp);
2936
2937   vec_free (reply);
2938
2939   svm_pop_heap (oldheap);
2940   pthread_mutex_unlock (&am->vlib_rp->mutex);
2941
2942   vat_json_print (vam->ofp, &node);
2943   vat_json_free (&node);
2944
2945   vam->retval = ntohl (mp->retval);
2946   vam->result_ready = 1;
2947 }
2948
2949 static void
2950 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0;
2954
2955   if (mp->local)
2956     {
2957       s = format (s, "%=16d%=16d%=16d",
2958                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2959     }
2960   else
2961     {
2962       s = format (s, "%=16U%=16d%=16d",
2963                   mp->is_ipv6 ? format_ip6_address :
2964                   format_ip4_address,
2965                   mp->ip_address, mp->priority, mp->weight);
2966     }
2967
2968   print (vam->ofp, "%v", s);
2969   vec_free (s);
2970 }
2971
2972 static void
2973 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2974 {
2975   vat_main_t *vam = &vat_main;
2976   vat_json_node_t *node = NULL;
2977   struct in6_addr ip6;
2978   struct in_addr ip4;
2979
2980   if (VAT_JSON_ARRAY != vam->json_tree.type)
2981     {
2982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2983       vat_json_init_array (&vam->json_tree);
2984     }
2985   node = vat_json_array_add (&vam->json_tree);
2986   vat_json_init_object (node);
2987
2988   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2989   vat_json_object_add_uint (node, "priority", mp->priority);
2990   vat_json_object_add_uint (node, "weight", mp->weight);
2991
2992   if (mp->local)
2993     vat_json_object_add_uint (node, "sw_if_index",
2994                               clib_net_to_host_u32 (mp->sw_if_index));
2995   else
2996     {
2997       if (mp->is_ipv6)
2998         {
2999           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3000           vat_json_object_add_ip6 (node, "address", ip6);
3001         }
3002       else
3003         {
3004           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3005           vat_json_object_add_ip4 (node, "address", ip4);
3006         }
3007     }
3008 }
3009
3010 static void
3011 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3012                                           mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018
3019   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3020          ls_name);
3021   vec_free (ls_name);
3022 }
3023
3024 static void
3025   vl_api_one_locator_set_details_t_handler_json
3026   (vl_api_one_locator_set_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = 0;
3030   u8 *ls_name = 0;
3031
3032   ls_name = format (0, "%s", mp->ls_name);
3033   vec_add1 (ls_name, 0);
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3044   vat_json_object_add_uint (node, "ls_index",
3045                             clib_net_to_host_u32 (mp->ls_index));
3046   vec_free (ls_name);
3047 }
3048
3049 typedef struct
3050 {
3051   u32 spi;
3052   u8 si;
3053 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3054
3055 uword
3056 unformat_nsh_address (unformat_input_t * input, va_list * args)
3057 {
3058   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3059   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3060 }
3061
3062 u8 *
3063 format_nsh_address_vat (u8 * s, va_list * args)
3064 {
3065   nsh_t *a = va_arg (*args, nsh_t *);
3066   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3067 }
3068
3069 static u8 *
3070 format_lisp_flat_eid (u8 * s, va_list * args)
3071 {
3072   u32 type = va_arg (*args, u32);
3073   u8 *eid = va_arg (*args, u8 *);
3074   u32 eid_len = va_arg (*args, u32);
3075
3076   switch (type)
3077     {
3078     case 0:
3079       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3080     case 1:
3081       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3082     case 2:
3083       return format (s, "%U", format_ethernet_address, eid);
3084     case 3:
3085       return format (s, "%U", format_nsh_address_vat, eid);
3086     }
3087   return 0;
3088 }
3089
3090 static u8 *
3091 format_lisp_eid_vat (u8 * s, va_list * args)
3092 {
3093   u32 type = va_arg (*args, u32);
3094   u8 *eid = va_arg (*args, u8 *);
3095   u32 eid_len = va_arg (*args, u32);
3096   u8 *seid = va_arg (*args, u8 *);
3097   u32 seid_len = va_arg (*args, u32);
3098   u32 is_src_dst = va_arg (*args, u32);
3099
3100   if (is_src_dst)
3101     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3102
3103   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3104
3105   return s;
3106 }
3107
3108 static void
3109 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *s = 0, *eid = 0;
3113
3114   if (~0 == mp->locator_set_index)
3115     s = format (0, "action: %d", mp->action);
3116   else
3117     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3118
3119   eid = format (0, "%U", format_lisp_eid_vat,
3120                 mp->eid_type,
3121                 mp->eid,
3122                 mp->eid_prefix_len,
3123                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3124   vec_add1 (eid, 0);
3125
3126   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3127          clib_net_to_host_u32 (mp->vni),
3128          eid,
3129          mp->is_local ? "local" : "remote",
3130          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3131          clib_net_to_host_u16 (mp->key_id), mp->key);
3132
3133   vec_free (s);
3134   vec_free (eid);
3135 }
3136
3137 static void
3138 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3139                                              * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = 0;
3143   u8 *eid = 0;
3144
3145   if (VAT_JSON_ARRAY != vam->json_tree.type)
3146     {
3147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3148       vat_json_init_array (&vam->json_tree);
3149     }
3150   node = vat_json_array_add (&vam->json_tree);
3151
3152   vat_json_init_object (node);
3153   if (~0 == mp->locator_set_index)
3154     vat_json_object_add_uint (node, "action", mp->action);
3155   else
3156     vat_json_object_add_uint (node, "locator_set_index",
3157                               clib_net_to_host_u32 (mp->locator_set_index));
3158
3159   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3160   if (mp->eid_type == 3)
3161     {
3162       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3163       vat_json_init_object (nsh_json);
3164       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3165       vat_json_object_add_uint (nsh_json, "spi",
3166                                 clib_net_to_host_u32 (nsh->spi));
3167       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3168     }
3169   else
3170     {
3171       eid = format (0, "%U", format_lisp_eid_vat,
3172                     mp->eid_type,
3173                     mp->eid,
3174                     mp->eid_prefix_len,
3175                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3176       vec_add1 (eid, 0);
3177       vat_json_object_add_string_copy (node, "eid", eid);
3178       vec_free (eid);
3179     }
3180   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3181   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3182   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3183
3184   if (mp->key_id)
3185     {
3186       vat_json_object_add_uint (node, "key_id",
3187                                 clib_net_to_host_u16 (mp->key_id));
3188       vat_json_object_add_string_copy (node, "key", mp->key);
3189     }
3190 }
3191
3192 static void
3193 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   u8 *seid = 0, *deid = 0;
3197   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3198
3199   deid = format (0, "%U", format_lisp_eid_vat,
3200                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3201
3202   seid = format (0, "%U", format_lisp_eid_vat,
3203                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3204
3205   vec_add1 (deid, 0);
3206   vec_add1 (seid, 0);
3207
3208   if (mp->is_ip4)
3209     format_ip_address_fcn = format_ip4_address;
3210   else
3211     format_ip_address_fcn = format_ip6_address;
3212
3213
3214   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3215          clib_net_to_host_u32 (mp->vni),
3216          seid, deid,
3217          format_ip_address_fcn, mp->lloc,
3218          format_ip_address_fcn, mp->rloc,
3219          clib_net_to_host_u32 (mp->pkt_count),
3220          clib_net_to_host_u32 (mp->bytes));
3221
3222   vec_free (deid);
3223   vec_free (seid);
3224 }
3225
3226 static void
3227 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3228 {
3229   struct in6_addr ip6;
3230   struct in_addr ip4;
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t *node = 0;
3233   u8 *deid = 0, *seid = 0;
3234
3235   if (VAT_JSON_ARRAY != vam->json_tree.type)
3236     {
3237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3238       vat_json_init_array (&vam->json_tree);
3239     }
3240   node = vat_json_array_add (&vam->json_tree);
3241
3242   vat_json_init_object (node);
3243   deid = format (0, "%U", format_lisp_eid_vat,
3244                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3245
3246   seid = format (0, "%U", format_lisp_eid_vat,
3247                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3248
3249   vec_add1 (deid, 0);
3250   vec_add1 (seid, 0);
3251
3252   vat_json_object_add_string_copy (node, "seid", seid);
3253   vat_json_object_add_string_copy (node, "deid", deid);
3254   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3255
3256   if (mp->is_ip4)
3257     {
3258       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3259       vat_json_object_add_ip4 (node, "lloc", ip4);
3260       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3261       vat_json_object_add_ip4 (node, "rloc", ip4);
3262     }
3263   else
3264     {
3265       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3266       vat_json_object_add_ip6 (node, "lloc", ip6);
3267       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3268       vat_json_object_add_ip6 (node, "rloc", ip6);
3269     }
3270   vat_json_object_add_uint (node, "pkt_count",
3271                             clib_net_to_host_u32 (mp->pkt_count));
3272   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3273
3274   vec_free (deid);
3275   vec_free (seid);
3276 }
3277
3278 static void
3279   vl_api_one_eid_table_map_details_t_handler
3280   (vl_api_one_eid_table_map_details_t * mp)
3281 {
3282   vat_main_t *vam = &vat_main;
3283
3284   u8 *line = format (0, "%=10d%=10d",
3285                      clib_net_to_host_u32 (mp->vni),
3286                      clib_net_to_host_u32 (mp->dp_table));
3287   print (vam->ofp, "%v", line);
3288   vec_free (line);
3289 }
3290
3291 static void
3292   vl_api_one_eid_table_map_details_t_handler_json
3293   (vl_api_one_eid_table_map_details_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t *node = NULL;
3297
3298   if (VAT_JSON_ARRAY != vam->json_tree.type)
3299     {
3300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3301       vat_json_init_array (&vam->json_tree);
3302     }
3303   node = vat_json_array_add (&vam->json_tree);
3304   vat_json_init_object (node);
3305   vat_json_object_add_uint (node, "dp_table",
3306                             clib_net_to_host_u32 (mp->dp_table));
3307   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3308 }
3309
3310 static void
3311   vl_api_one_eid_table_vni_details_t_handler
3312   (vl_api_one_eid_table_vni_details_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315
3316   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3317   print (vam->ofp, "%v", line);
3318   vec_free (line);
3319 }
3320
3321 static void
3322   vl_api_one_eid_table_vni_details_t_handler_json
3323   (vl_api_one_eid_table_vni_details_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t *node = NULL;
3327
3328   if (VAT_JSON_ARRAY != vam->json_tree.type)
3329     {
3330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3331       vat_json_init_array (&vam->json_tree);
3332     }
3333   node = vat_json_array_add (&vam->json_tree);
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3336 }
3337
3338 static void
3339   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3340   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   print (vam->ofp, "fallback threshold value: %d", mp->value);
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3354   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t _node, *node = &_node;
3358   int retval = clib_net_to_host_u32 (mp->retval);
3359
3360   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "value", mp->value);
3363
3364   vat_json_print (vam->ofp, node);
3365   vat_json_free (node);
3366
3367   vam->retval = retval;
3368   vam->result_ready = 1;
3369 }
3370
3371 static void
3372   vl_api_show_one_map_register_state_reply_t_handler
3373   (vl_api_show_one_map_register_state_reply_t * mp)
3374 {
3375   vat_main_t *vam = &vat_main;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3379
3380   vam->retval = retval;
3381   vam->result_ready = 1;
3382 }
3383
3384 static void
3385   vl_api_show_one_map_register_state_reply_t_handler_json
3386   (vl_api_show_one_map_register_state_reply_t * mp)
3387 {
3388   vat_main_t *vam = &vat_main;
3389   vat_json_node_t _node, *node = &_node;
3390   int retval = clib_net_to_host_u32 (mp->retval);
3391
3392   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3393
3394   vat_json_init_object (node);
3395   vat_json_object_add_string_copy (node, "state", s);
3396
3397   vat_json_print (vam->ofp, node);
3398   vat_json_free (node);
3399
3400   vam->retval = retval;
3401   vam->result_ready = 1;
3402   vec_free (s);
3403 }
3404
3405 static void
3406   vl_api_show_one_rloc_probe_state_reply_t_handler
3407   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   int retval = clib_net_to_host_u32 (mp->retval);
3411
3412   if (retval)
3413     goto end;
3414
3415   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3416 end:
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3423   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   vat_json_node_t _node, *node = &_node;
3427   int retval = clib_net_to_host_u32 (mp->retval);
3428
3429   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3430   vat_json_init_object (node);
3431   vat_json_object_add_string_copy (node, "state", s);
3432
3433   vat_json_print (vam->ofp, node);
3434   vat_json_free (node);
3435
3436   vam->retval = retval;
3437   vam->result_ready = 1;
3438   vec_free (s);
3439 }
3440
3441 static void
3442   vl_api_show_one_stats_enable_disable_reply_t_handler
3443   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   int retval = clib_net_to_host_u32 (mp->retval);
3447
3448   if (retval)
3449     goto end;
3450
3451   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3452 end:
3453   vam->retval = retval;
3454   vam->result_ready = 1;
3455 }
3456
3457 static void
3458   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3459   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   vat_json_node_t _node, *node = &_node;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464
3465   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3466   vat_json_init_object (node);
3467   vat_json_object_add_string_copy (node, "state", s);
3468
3469   vat_json_print (vam->ofp, node);
3470   vat_json_free (node);
3471
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474   vec_free (s);
3475 }
3476
3477 static void
3478 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3479 {
3480   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3481   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3482   e->vni = clib_net_to_host_u32 (e->vni);
3483 }
3484
3485 static void
3486   gpe_fwd_entries_get_reply_t_net_to_host
3487   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3488 {
3489   u32 i;
3490
3491   mp->count = clib_net_to_host_u32 (mp->count);
3492   for (i = 0; i < mp->count; i++)
3493     {
3494       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3495     }
3496 }
3497
3498 static u8 *
3499 format_gpe_encap_mode (u8 * s, va_list * args)
3500 {
3501   u32 mode = va_arg (*args, u32);
3502
3503   switch (mode)
3504     {
3505     case 0:
3506       return format (s, "lisp");
3507     case 1:
3508       return format (s, "vxlan");
3509     }
3510   return 0;
3511 }
3512
3513 static void
3514   vl_api_gpe_get_encap_mode_reply_t_handler
3515   (vl_api_gpe_get_encap_mode_reply_t * mp)
3516 {
3517   vat_main_t *vam = &vat_main;
3518
3519   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3520   vam->retval = ntohl (mp->retval);
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_get_encap_mode_reply_t_handler_json
3526   (vl_api_gpe_get_encap_mode_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t node;
3530
3531   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3532   vec_add1 (encap_mode, 0);
3533
3534   vat_json_init_object (&node);
3535   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3536
3537   vec_free (encap_mode);
3538   vat_json_print (vam->ofp, &node);
3539   vat_json_free (&node);
3540
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_gpe_fwd_entry_path_details_t_handler
3547   (vl_api_gpe_fwd_entry_path_details_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3551
3552   if (mp->lcl_loc.is_ip4)
3553     format_ip_address_fcn = format_ip4_address;
3554   else
3555     format_ip_address_fcn = format_ip6_address;
3556
3557   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3558          format_ip_address_fcn, &mp->lcl_loc,
3559          format_ip_address_fcn, &mp->rmt_loc);
3560 }
3561
3562 static void
3563 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3564 {
3565   struct in6_addr ip6;
3566   struct in_addr ip4;
3567
3568   if (loc->is_ip4)
3569     {
3570       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3571       vat_json_object_add_ip4 (n, "address", ip4);
3572     }
3573   else
3574     {
3575       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3576       vat_json_object_add_ip6 (n, "address", ip6);
3577     }
3578   vat_json_object_add_uint (n, "weight", loc->weight);
3579 }
3580
3581 static void
3582   vl_api_gpe_fwd_entry_path_details_t_handler_json
3583   (vl_api_gpe_fwd_entry_path_details_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t *node = NULL;
3587   vat_json_node_t *loc_node;
3588
3589   if (VAT_JSON_ARRAY != vam->json_tree.type)
3590     {
3591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3592       vat_json_init_array (&vam->json_tree);
3593     }
3594   node = vat_json_array_add (&vam->json_tree);
3595   vat_json_init_object (node);
3596
3597   loc_node = vat_json_object_add (node, "local_locator");
3598   vat_json_init_object (loc_node);
3599   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3600
3601   loc_node = vat_json_object_add (node, "remote_locator");
3602   vat_json_init_object (loc_node);
3603   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3604 }
3605
3606 static void
3607   vl_api_gpe_fwd_entries_get_reply_t_handler
3608   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   u32 i;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613   vl_api_gpe_fwd_entry_t *e;
3614
3615   if (retval)
3616     goto end;
3617
3618   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3619
3620   for (i = 0; i < mp->count; i++)
3621     {
3622       e = &mp->entries[i];
3623       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3624              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3625              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3626     }
3627
3628 end:
3629   vam->retval = retval;
3630   vam->result_ready = 1;
3631 }
3632
3633 static void
3634   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3635   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3636 {
3637   u8 *s = 0;
3638   vat_main_t *vam = &vat_main;
3639   vat_json_node_t *e = 0, root;
3640   u32 i;
3641   int retval = clib_net_to_host_u32 (mp->retval);
3642   vl_api_gpe_fwd_entry_t *fwd;
3643
3644   if (retval)
3645     goto end;
3646
3647   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3648   vat_json_init_array (&root);
3649
3650   for (i = 0; i < mp->count; i++)
3651     {
3652       e = vat_json_array_add (&root);
3653       fwd = &mp->entries[i];
3654
3655       vat_json_init_object (e);
3656       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3657       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3658       vat_json_object_add_int (e, "vni", fwd->vni);
3659       vat_json_object_add_int (e, "action", fwd->action);
3660
3661       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3662                   fwd->leid_prefix_len);
3663       vec_add1 (s, 0);
3664       vat_json_object_add_string_copy (e, "leid", s);
3665       vec_free (s);
3666
3667       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3668                   fwd->reid_prefix_len);
3669       vec_add1 (s, 0);
3670       vat_json_object_add_string_copy (e, "reid", s);
3671       vec_free (s);
3672     }
3673
3674   vat_json_print (vam->ofp, &root);
3675   vat_json_free (&root);
3676
3677 end:
3678   vam->retval = retval;
3679   vam->result_ready = 1;
3680 }
3681
3682 static void
3683   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3684   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3685 {
3686   vat_main_t *vam = &vat_main;
3687   u32 i, n;
3688   int retval = clib_net_to_host_u32 (mp->retval);
3689   vl_api_gpe_native_fwd_rpath_t *r;
3690
3691   if (retval)
3692     goto end;
3693
3694   n = clib_net_to_host_u32 (mp->count);
3695
3696   for (i = 0; i < n; i++)
3697     {
3698       r = &mp->entries[i];
3699       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3700              clib_net_to_host_u32 (r->fib_index),
3701              clib_net_to_host_u32 (r->nh_sw_if_index),
3702              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3703     }
3704
3705 end:
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3712   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   vat_json_node_t root, *e;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718   vl_api_gpe_native_fwd_rpath_t *r;
3719   u8 *s;
3720
3721   if (retval)
3722     goto end;
3723
3724   n = clib_net_to_host_u32 (mp->count);
3725   vat_json_init_array (&root);
3726
3727   for (i = 0; i < n; i++)
3728     {
3729       e = vat_json_array_add (&root);
3730       vat_json_init_object (e);
3731       r = &mp->entries[i];
3732       s =
3733         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3734                 r->nh_addr);
3735       vec_add1 (s, 0);
3736       vat_json_object_add_string_copy (e, "ip4", s);
3737       vec_free (s);
3738
3739       vat_json_object_add_uint (e, "fib_index",
3740                                 clib_net_to_host_u32 (r->fib_index));
3741       vat_json_object_add_uint (e, "nh_sw_if_index",
3742                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3743     }
3744
3745   vat_json_print (vam->ofp, &root);
3746   vat_json_free (&root);
3747
3748 end:
3749   vam->retval = retval;
3750   vam->result_ready = 1;
3751 }
3752
3753 static void
3754   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3755   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3756 {
3757   vat_main_t *vam = &vat_main;
3758   u32 i, n;
3759   int retval = clib_net_to_host_u32 (mp->retval);
3760
3761   if (retval)
3762     goto end;
3763
3764   n = clib_net_to_host_u32 (mp->count);
3765
3766   for (i = 0; i < n; i++)
3767     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3776   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3777 {
3778   vat_main_t *vam = &vat_main;
3779   vat_json_node_t root;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787   vat_json_init_array (&root);
3788
3789   for (i = 0; i < n; i++)
3790     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_ndp_entries_get_reply_t_handler
3802   (vl_api_one_ndp_entries_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3815            format_ethernet_address, mp->entries[i].mac);
3816
3817 end:
3818   vam->retval = retval;
3819   vam->result_ready = 1;
3820 }
3821
3822 static void
3823   vl_api_one_ndp_entries_get_reply_t_handler_json
3824   (vl_api_one_ndp_entries_get_reply_t * mp)
3825 {
3826   u8 *s = 0;
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t *e = 0, root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831   vl_api_one_ndp_entry_t *arp_entry;
3832
3833   if (retval)
3834     goto end;
3835
3836   n = clib_net_to_host_u32 (mp->count);
3837   vat_json_init_array (&root);
3838
3839   for (i = 0; i < n; i++)
3840     {
3841       e = vat_json_array_add (&root);
3842       arp_entry = &mp->entries[i];
3843
3844       vat_json_init_object (e);
3845       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3846       vec_add1 (s, 0);
3847
3848       vat_json_object_add_string_copy (e, "mac", s);
3849       vec_free (s);
3850
3851       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3852       vec_add1 (s, 0);
3853       vat_json_object_add_string_copy (e, "ip6", s);
3854       vec_free (s);
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866   vl_api_one_l2_arp_entries_get_reply_t_handler
3867   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3868 {
3869   vat_main_t *vam = &vat_main;
3870   u32 i, n;
3871   int retval = clib_net_to_host_u32 (mp->retval);
3872
3873   if (retval)
3874     goto end;
3875
3876   n = clib_net_to_host_u32 (mp->count);
3877
3878   for (i = 0; i < n; i++)
3879     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3880            format_ethernet_address, mp->entries[i].mac);
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3889   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3890 {
3891   u8 *s = 0;
3892   vat_main_t *vam = &vat_main;
3893   vat_json_node_t *e = 0, root;
3894   u32 i, n;
3895   int retval = clib_net_to_host_u32 (mp->retval);
3896   vl_api_one_l2_arp_entry_t *arp_entry;
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       e = vat_json_array_add (&root);
3907       arp_entry = &mp->entries[i];
3908
3909       vat_json_init_object (e);
3910       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3911       vec_add1 (s, 0);
3912
3913       vat_json_object_add_string_copy (e, "mac", s);
3914       vec_free (s);
3915
3916       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3917       vec_add1 (s, 0);
3918       vat_json_object_add_string_copy (e, "ip4", s);
3919       vec_free (s);
3920     }
3921
3922   vat_json_print (vam->ofp, &root);
3923   vat_json_free (&root);
3924
3925 end:
3926   vam->retval = retval;
3927   vam->result_ready = 1;
3928 }
3929
3930 static void
3931 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3932 {
3933   vat_main_t *vam = &vat_main;
3934   u32 i, n;
3935   int retval = clib_net_to_host_u32 (mp->retval);
3936
3937   if (retval)
3938     goto end;
3939
3940   n = clib_net_to_host_u32 (mp->count);
3941
3942   for (i = 0; i < n; i++)
3943     {
3944       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3945     }
3946
3947 end:
3948   vam->retval = retval;
3949   vam->result_ready = 1;
3950 }
3951
3952 static void
3953   vl_api_one_ndp_bd_get_reply_t_handler_json
3954   (vl_api_one_ndp_bd_get_reply_t * mp)
3955 {
3956   vat_main_t *vam = &vat_main;
3957   vat_json_node_t root;
3958   u32 i, n;
3959   int retval = clib_net_to_host_u32 (mp->retval);
3960
3961   if (retval)
3962     goto end;
3963
3964   n = clib_net_to_host_u32 (mp->count);
3965   vat_json_init_array (&root);
3966
3967   for (i = 0; i < n; i++)
3968     {
3969       vat_json_array_add_uint (&root,
3970                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3971     }
3972
3973   vat_json_print (vam->ofp, &root);
3974   vat_json_free (&root);
3975
3976 end:
3977   vam->retval = retval;
3978   vam->result_ready = 1;
3979 }
3980
3981 static void
3982   vl_api_one_l2_arp_bd_get_reply_t_handler
3983   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3984 {
3985   vat_main_t *vam = &vat_main;
3986   u32 i, n;
3987   int retval = clib_net_to_host_u32 (mp->retval);
3988
3989   if (retval)
3990     goto end;
3991
3992   n = clib_net_to_host_u32 (mp->count);
3993
3994   for (i = 0; i < n; i++)
3995     {
3996       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3997     }
3998
3999 end:
4000   vam->retval = retval;
4001   vam->result_ready = 1;
4002 }
4003
4004 static void
4005   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4006   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4007 {
4008   vat_main_t *vam = &vat_main;
4009   vat_json_node_t root;
4010   u32 i, n;
4011   int retval = clib_net_to_host_u32 (mp->retval);
4012
4013   if (retval)
4014     goto end;
4015
4016   n = clib_net_to_host_u32 (mp->count);
4017   vat_json_init_array (&root);
4018
4019   for (i = 0; i < n; i++)
4020     {
4021       vat_json_array_add_uint (&root,
4022                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4023     }
4024
4025   vat_json_print (vam->ofp, &root);
4026   vat_json_free (&root);
4027
4028 end:
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_one_adjacencies_get_reply_t_handler
4035   (vl_api_one_adjacencies_get_reply_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   u32 i, n;
4039   int retval = clib_net_to_host_u32 (mp->retval);
4040   vl_api_one_adjacency_t *a;
4041
4042   if (retval)
4043     goto end;
4044
4045   n = clib_net_to_host_u32 (mp->count);
4046
4047   for (i = 0; i < n; i++)
4048     {
4049       a = &mp->adjacencies[i];
4050       print (vam->ofp, "%U %40U",
4051              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4052              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4053     }
4054
4055 end:
4056   vam->retval = retval;
4057   vam->result_ready = 1;
4058 }
4059
4060 static void
4061   vl_api_one_adjacencies_get_reply_t_handler_json
4062   (vl_api_one_adjacencies_get_reply_t * mp)
4063 {
4064   u8 *s = 0;
4065   vat_main_t *vam = &vat_main;
4066   vat_json_node_t *e = 0, root;
4067   u32 i, n;
4068   int retval = clib_net_to_host_u32 (mp->retval);
4069   vl_api_one_adjacency_t *a;
4070
4071   if (retval)
4072     goto end;
4073
4074   n = clib_net_to_host_u32 (mp->count);
4075   vat_json_init_array (&root);
4076
4077   for (i = 0; i < n; i++)
4078     {
4079       e = vat_json_array_add (&root);
4080       a = &mp->adjacencies[i];
4081
4082       vat_json_init_object (e);
4083       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4084                   a->leid_prefix_len);
4085       vec_add1 (s, 0);
4086       vat_json_object_add_string_copy (e, "leid", s);
4087       vec_free (s);
4088
4089       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4090                   a->reid_prefix_len);
4091       vec_add1 (s, 0);
4092       vat_json_object_add_string_copy (e, "reid", s);
4093       vec_free (s);
4094     }
4095
4096   vat_json_print (vam->ofp, &root);
4097   vat_json_free (&root);
4098
4099 end:
4100   vam->retval = retval;
4101   vam->result_ready = 1;
4102 }
4103
4104 static void
4105 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108
4109   print (vam->ofp, "%=20U",
4110          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4111          mp->ip_address);
4112 }
4113
4114 static void
4115   vl_api_one_map_server_details_t_handler_json
4116   (vl_api_one_map_server_details_t * mp)
4117 {
4118   vat_main_t *vam = &vat_main;
4119   vat_json_node_t *node = NULL;
4120   struct in6_addr ip6;
4121   struct in_addr ip4;
4122
4123   if (VAT_JSON_ARRAY != vam->json_tree.type)
4124     {
4125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4126       vat_json_init_array (&vam->json_tree);
4127     }
4128   node = vat_json_array_add (&vam->json_tree);
4129
4130   vat_json_init_object (node);
4131   if (mp->is_ipv6)
4132     {
4133       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4134       vat_json_object_add_ip6 (node, "map-server", ip6);
4135     }
4136   else
4137     {
4138       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4139       vat_json_object_add_ip4 (node, "map-server", ip4);
4140     }
4141 }
4142
4143 static void
4144 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4145                                            * mp)
4146 {
4147   vat_main_t *vam = &vat_main;
4148
4149   print (vam->ofp, "%=20U",
4150          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4151          mp->ip_address);
4152 }
4153
4154 static void
4155   vl_api_one_map_resolver_details_t_handler_json
4156   (vl_api_one_map_resolver_details_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t *node = NULL;
4160   struct in6_addr ip6;
4161   struct in_addr ip4;
4162
4163   if (VAT_JSON_ARRAY != vam->json_tree.type)
4164     {
4165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4166       vat_json_init_array (&vam->json_tree);
4167     }
4168   node = vat_json_array_add (&vam->json_tree);
4169
4170   vat_json_init_object (node);
4171   if (mp->is_ipv6)
4172     {
4173       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4174       vat_json_object_add_ip6 (node, "map resolver", ip6);
4175     }
4176   else
4177     {
4178       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4179       vat_json_object_add_ip4 (node, "map resolver", ip4);
4180     }
4181 }
4182
4183 static void
4184 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   i32 retval = ntohl (mp->retval);
4188
4189   if (0 <= retval)
4190     {
4191       print (vam->ofp, "feature: %s\ngpe: %s",
4192              mp->feature_status ? "enabled" : "disabled",
4193              mp->gpe_status ? "enabled" : "disabled");
4194     }
4195
4196   vam->retval = retval;
4197   vam->result_ready = 1;
4198 }
4199
4200 static void
4201   vl_api_show_one_status_reply_t_handler_json
4202   (vl_api_show_one_status_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   vat_json_node_t node;
4206   u8 *gpe_status = NULL;
4207   u8 *feature_status = NULL;
4208
4209   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4210   feature_status = format (0, "%s",
4211                            mp->feature_status ? "enabled" : "disabled");
4212   vec_add1 (gpe_status, 0);
4213   vec_add1 (feature_status, 0);
4214
4215   vat_json_init_object (&node);
4216   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4217   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4218
4219   vec_free (gpe_status);
4220   vec_free (feature_status);
4221
4222   vat_json_print (vam->ofp, &node);
4223   vat_json_free (&node);
4224
4225   vam->retval = ntohl (mp->retval);
4226   vam->result_ready = 1;
4227 }
4228
4229 static void
4230   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4231   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4232 {
4233   vat_main_t *vam = &vat_main;
4234   i32 retval = ntohl (mp->retval);
4235
4236   if (retval >= 0)
4237     {
4238       print (vam->ofp, "%=20s", mp->locator_set_name);
4239     }
4240
4241   vam->retval = retval;
4242   vam->result_ready = 1;
4243 }
4244
4245 static void
4246   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4247   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   vat_json_node_t *node = NULL;
4251
4252   if (VAT_JSON_ARRAY != vam->json_tree.type)
4253     {
4254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4255       vat_json_init_array (&vam->json_tree);
4256     }
4257   node = vat_json_array_add (&vam->json_tree);
4258
4259   vat_json_init_object (node);
4260   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4261
4262   vat_json_print (vam->ofp, node);
4263   vat_json_free (node);
4264
4265   vam->retval = ntohl (mp->retval);
4266   vam->result_ready = 1;
4267 }
4268
4269 static u8 *
4270 format_lisp_map_request_mode (u8 * s, va_list * args)
4271 {
4272   u32 mode = va_arg (*args, u32);
4273
4274   switch (mode)
4275     {
4276     case 0:
4277       return format (0, "dst-only");
4278     case 1:
4279       return format (0, "src-dst");
4280     }
4281   return 0;
4282 }
4283
4284 static void
4285   vl_api_show_one_map_request_mode_reply_t_handler
4286   (vl_api_show_one_map_request_mode_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       u32 mode = mp->mode;
4294       print (vam->ofp, "map_request_mode: %U",
4295              format_lisp_map_request_mode, mode);
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_map_request_mode_reply_t_handler_json
4304   (vl_api_show_one_map_request_mode_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *s = 0;
4309   u32 mode;
4310
4311   mode = mp->mode;
4312   s = format (0, "%U", format_lisp_map_request_mode, mode);
4313   vec_add1 (s, 0);
4314
4315   vat_json_init_object (&node);
4316   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vec_free (s);
4321   vam->retval = ntohl (mp->retval);
4322   vam->result_ready = 1;
4323 }
4324
4325 static void
4326   vl_api_one_show_xtr_mode_reply_t_handler
4327   (vl_api_one_show_xtr_mode_reply_t * mp)
4328 {
4329   vat_main_t *vam = &vat_main;
4330   i32 retval = ntohl (mp->retval);
4331
4332   if (0 <= retval)
4333     {
4334       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4335     }
4336
4337   vam->retval = retval;
4338   vam->result_ready = 1;
4339 }
4340
4341 static void
4342   vl_api_one_show_xtr_mode_reply_t_handler_json
4343   (vl_api_one_show_xtr_mode_reply_t * mp)
4344 {
4345   vat_main_t *vam = &vat_main;
4346   vat_json_node_t node;
4347   u8 *status = 0;
4348
4349   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4350   vec_add1 (status, 0);
4351
4352   vat_json_init_object (&node);
4353   vat_json_object_add_string_copy (&node, "status", status);
4354
4355   vec_free (status);
4356
4357   vat_json_print (vam->ofp, &node);
4358   vat_json_free (&node);
4359
4360   vam->retval = ntohl (mp->retval);
4361   vam->result_ready = 1;
4362 }
4363
4364 static void
4365   vl_api_one_show_pitr_mode_reply_t_handler
4366   (vl_api_one_show_pitr_mode_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369   i32 retval = ntohl (mp->retval);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_one_show_pitr_mode_reply_t_handler_json
4382   (vl_api_one_show_pitr_mode_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386   u8 *status = 0;
4387
4388   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4389   vec_add1 (status, 0);
4390
4391   vat_json_init_object (&node);
4392   vat_json_object_add_string_copy (&node, "status", status);
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_one_show_petr_mode_reply_t_handler
4405   (vl_api_one_show_petr_mode_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   if (0 <= retval)
4411     {
4412       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4413     }
4414
4415   vam->retval = retval;
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_one_show_petr_mode_reply_t_handler_json
4421   (vl_api_one_show_petr_mode_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   vat_json_node_t node;
4425   u8 *status = 0;
4426
4427   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4428   vec_add1 (status, 0);
4429
4430   vat_json_init_object (&node);
4431   vat_json_object_add_string_copy (&node, "status", status);
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static void
4443   vl_api_show_one_use_petr_reply_t_handler
4444   (vl_api_show_one_use_petr_reply_t * mp)
4445 {
4446   vat_main_t *vam = &vat_main;
4447   i32 retval = ntohl (mp->retval);
4448
4449   if (0 <= retval)
4450     {
4451       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4452       if (mp->status)
4453         {
4454           print (vam->ofp, "Proxy-ETR address; %U",
4455                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4456                  mp->address);
4457         }
4458     }
4459
4460   vam->retval = retval;
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465   vl_api_show_one_use_petr_reply_t_handler_json
4466   (vl_api_show_one_use_petr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   vat_json_node_t node;
4470   u8 *status = 0;
4471   struct in_addr ip4;
4472   struct in6_addr ip6;
4473
4474   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4475   vec_add1 (status, 0);
4476
4477   vat_json_init_object (&node);
4478   vat_json_object_add_string_copy (&node, "status", status);
4479   if (mp->status)
4480     {
4481       if (mp->is_ip4)
4482         {
4483           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4484           vat_json_object_add_ip6 (&node, "address", ip6);
4485         }
4486       else
4487         {
4488           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4489           vat_json_object_add_ip4 (&node, "address", ip4);
4490         }
4491     }
4492
4493   vec_free (status);
4494
4495   vat_json_print (vam->ofp, &node);
4496   vat_json_free (&node);
4497
4498   vam->retval = ntohl (mp->retval);
4499   vam->result_ready = 1;
4500 }
4501
4502 static void
4503   vl_api_show_one_nsh_mapping_reply_t_handler
4504   (vl_api_show_one_nsh_mapping_reply_t * mp)
4505 {
4506   vat_main_t *vam = &vat_main;
4507   i32 retval = ntohl (mp->retval);
4508
4509   if (0 <= retval)
4510     {
4511       print (vam->ofp, "%-20s%-16s",
4512              mp->is_set ? "set" : "not-set",
4513              mp->is_set ? (char *) mp->locator_set_name : "");
4514     }
4515
4516   vam->retval = retval;
4517   vam->result_ready = 1;
4518 }
4519
4520 static void
4521   vl_api_show_one_nsh_mapping_reply_t_handler_json
4522   (vl_api_show_one_nsh_mapping_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   vat_json_node_t node;
4526   u8 *status = 0;
4527
4528   status = format (0, "%s", mp->is_set ? "yes" : "no");
4529   vec_add1 (status, 0);
4530
4531   vat_json_init_object (&node);
4532   vat_json_object_add_string_copy (&node, "is_set", status);
4533   if (mp->is_set)
4534     {
4535       vat_json_object_add_string_copy (&node, "locator_set",
4536                                        mp->locator_set_name);
4537     }
4538
4539   vec_free (status);
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void
4549   vl_api_show_one_map_register_ttl_reply_t_handler
4550   (vl_api_show_one_map_register_ttl_reply_t * mp)
4551 {
4552   vat_main_t *vam = &vat_main;
4553   i32 retval = ntohl (mp->retval);
4554
4555   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4556
4557   if (0 <= retval)
4558     {
4559       print (vam->ofp, "ttl: %u", mp->ttl);
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_map_register_ttl_reply_t_handler_json
4568   (vl_api_show_one_map_register_ttl_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572
4573   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4574   vat_json_init_object (&node);
4575   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4576
4577   vat_json_print (vam->ofp, &node);
4578   vat_json_free (&node);
4579
4580   vam->retval = ntohl (mp->retval);
4581   vam->result_ready = 1;
4582 }
4583
4584 static void
4585 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4586 {
4587   vat_main_t *vam = &vat_main;
4588   i32 retval = ntohl (mp->retval);
4589
4590   if (0 <= retval)
4591     {
4592       print (vam->ofp, "%-20s%-16s",
4593              mp->status ? "enabled" : "disabled",
4594              mp->status ? (char *) mp->locator_set_name : "");
4595     }
4596
4597   vam->retval = retval;
4598   vam->result_ready = 1;
4599 }
4600
4601 static void
4602 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4603 {
4604   vat_main_t *vam = &vat_main;
4605   vat_json_node_t node;
4606   u8 *status = 0;
4607
4608   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4609   vec_add1 (status, 0);
4610
4611   vat_json_init_object (&node);
4612   vat_json_object_add_string_copy (&node, "status", status);
4613   if (mp->status)
4614     {
4615       vat_json_object_add_string_copy (&node, "locator_set",
4616                                        mp->locator_set_name);
4617     }
4618
4619   vec_free (status);
4620
4621   vat_json_print (vam->ofp, &node);
4622   vat_json_free (&node);
4623
4624   vam->retval = ntohl (mp->retval);
4625   vam->result_ready = 1;
4626 }
4627
4628 static u8 *
4629 format_policer_type (u8 * s, va_list * va)
4630 {
4631   u32 i = va_arg (*va, u32);
4632
4633   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4634     s = format (s, "1r2c");
4635   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4636     s = format (s, "1r3c");
4637   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4638     s = format (s, "2r3c-2698");
4639   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4640     s = format (s, "2r3c-4115");
4641   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4642     s = format (s, "2r3c-mef5cf1");
4643   else
4644     s = format (s, "ILLEGAL");
4645   return s;
4646 }
4647
4648 static u8 *
4649 format_policer_rate_type (u8 * s, va_list * va)
4650 {
4651   u32 i = va_arg (*va, u32);
4652
4653   if (i == SSE2_QOS_RATE_KBPS)
4654     s = format (s, "kbps");
4655   else if (i == SSE2_QOS_RATE_PPS)
4656     s = format (s, "pps");
4657   else
4658     s = format (s, "ILLEGAL");
4659   return s;
4660 }
4661
4662 static u8 *
4663 format_policer_round_type (u8 * s, va_list * va)
4664 {
4665   u32 i = va_arg (*va, u32);
4666
4667   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4668     s = format (s, "closest");
4669   else if (i == SSE2_QOS_ROUND_TO_UP)
4670     s = format (s, "up");
4671   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4672     s = format (s, "down");
4673   else
4674     s = format (s, "ILLEGAL");
4675   return s;
4676 }
4677
4678 static u8 *
4679 format_policer_action_type (u8 * s, va_list * va)
4680 {
4681   u32 i = va_arg (*va, u32);
4682
4683   if (i == SSE2_QOS_ACTION_DROP)
4684     s = format (s, "drop");
4685   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4686     s = format (s, "transmit");
4687   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4688     s = format (s, "mark-and-transmit");
4689   else
4690     s = format (s, "ILLEGAL");
4691   return s;
4692 }
4693
4694 static u8 *
4695 format_dscp (u8 * s, va_list * va)
4696 {
4697   u32 i = va_arg (*va, u32);
4698   char *t = 0;
4699
4700   switch (i)
4701     {
4702 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4703       foreach_vnet_dscp
4704 #undef _
4705     default:
4706       return format (s, "ILLEGAL");
4707     }
4708   s = format (s, "%s", t);
4709   return s;
4710 }
4711
4712 static void
4713 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4714 {
4715   vat_main_t *vam = &vat_main;
4716   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4717
4718   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4719     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4720   else
4721     conform_dscp_str = format (0, "");
4722
4723   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4724     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4725   else
4726     exceed_dscp_str = format (0, "");
4727
4728   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4729     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4730   else
4731     violate_dscp_str = format (0, "");
4732
4733   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4734          "rate type %U, round type %U, %s rate, %s color-aware, "
4735          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4736          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4737          "conform action %U%s, exceed action %U%s, violate action %U%s",
4738          mp->name,
4739          format_policer_type, mp->type,
4740          ntohl (mp->cir),
4741          ntohl (mp->eir),
4742          clib_net_to_host_u64 (mp->cb),
4743          clib_net_to_host_u64 (mp->eb),
4744          format_policer_rate_type, mp->rate_type,
4745          format_policer_round_type, mp->round_type,
4746          mp->single_rate ? "single" : "dual",
4747          mp->color_aware ? "is" : "not",
4748          ntohl (mp->cir_tokens_per_period),
4749          ntohl (mp->pir_tokens_per_period),
4750          ntohl (mp->scale),
4751          ntohl (mp->current_limit),
4752          ntohl (mp->current_bucket),
4753          ntohl (mp->extended_limit),
4754          ntohl (mp->extended_bucket),
4755          clib_net_to_host_u64 (mp->last_update_time),
4756          format_policer_action_type, mp->conform_action_type,
4757          conform_dscp_str,
4758          format_policer_action_type, mp->exceed_action_type,
4759          exceed_dscp_str,
4760          format_policer_action_type, mp->violate_action_type,
4761          violate_dscp_str);
4762
4763   vec_free (conform_dscp_str);
4764   vec_free (exceed_dscp_str);
4765   vec_free (violate_dscp_str);
4766 }
4767
4768 static void vl_api_policer_details_t_handler_json
4769   (vl_api_policer_details_t * mp)
4770 {
4771   vat_main_t *vam = &vat_main;
4772   vat_json_node_t *node;
4773   u8 *rate_type_str, *round_type_str, *type_str;
4774   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4775
4776   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4777   round_type_str =
4778     format (0, "%U", format_policer_round_type, mp->round_type);
4779   type_str = format (0, "%U", format_policer_type, mp->type);
4780   conform_action_str = format (0, "%U", format_policer_action_type,
4781                                mp->conform_action_type);
4782   exceed_action_str = format (0, "%U", format_policer_action_type,
4783                               mp->exceed_action_type);
4784   violate_action_str = format (0, "%U", format_policer_action_type,
4785                                mp->violate_action_type);
4786
4787   if (VAT_JSON_ARRAY != vam->json_tree.type)
4788     {
4789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4790       vat_json_init_array (&vam->json_tree);
4791     }
4792   node = vat_json_array_add (&vam->json_tree);
4793
4794   vat_json_init_object (node);
4795   vat_json_object_add_string_copy (node, "name", mp->name);
4796   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4797   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4798   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4799   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4800   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4801   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4802   vat_json_object_add_string_copy (node, "type", type_str);
4803   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4804   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4805   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4806   vat_json_object_add_uint (node, "cir_tokens_per_period",
4807                             ntohl (mp->cir_tokens_per_period));
4808   vat_json_object_add_uint (node, "eir_tokens_per_period",
4809                             ntohl (mp->pir_tokens_per_period));
4810   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4811   vat_json_object_add_uint (node, "current_bucket",
4812                             ntohl (mp->current_bucket));
4813   vat_json_object_add_uint (node, "extended_limit",
4814                             ntohl (mp->extended_limit));
4815   vat_json_object_add_uint (node, "extended_bucket",
4816                             ntohl (mp->extended_bucket));
4817   vat_json_object_add_uint (node, "last_update_time",
4818                             ntohl (mp->last_update_time));
4819   vat_json_object_add_string_copy (node, "conform_action",
4820                                    conform_action_str);
4821   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4824       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4828   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4829     {
4830       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4831       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4832       vec_free (dscp_str);
4833     }
4834   vat_json_object_add_string_copy (node, "violate_action",
4835                                    violate_action_str);
4836   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4837     {
4838       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4839       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4840       vec_free (dscp_str);
4841     }
4842
4843   vec_free (rate_type_str);
4844   vec_free (round_type_str);
4845   vec_free (type_str);
4846   vec_free (conform_action_str);
4847   vec_free (exceed_action_str);
4848   vec_free (violate_action_str);
4849 }
4850
4851 static void
4852 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4853                                            mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   int i, count = ntohl (mp->count);
4857
4858   if (count > 0)
4859     print (vam->ofp, "classify table ids (%d) : ", count);
4860   for (i = 0; i < count; i++)
4861     {
4862       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4863       print (vam->ofp, (i < count - 1) ? "," : "");
4864     }
4865   vam->retval = ntohl (mp->retval);
4866   vam->result_ready = 1;
4867 }
4868
4869 static void
4870   vl_api_classify_table_ids_reply_t_handler_json
4871   (vl_api_classify_table_ids_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   int i, count = ntohl (mp->count);
4875
4876   if (count > 0)
4877     {
4878       vat_json_node_t node;
4879
4880       vat_json_init_object (&node);
4881       for (i = 0; i < count; i++)
4882         {
4883           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4884         }
4885       vat_json_print (vam->ofp, &node);
4886       vat_json_free (&node);
4887     }
4888   vam->retval = ntohl (mp->retval);
4889   vam->result_ready = 1;
4890 }
4891
4892 static void
4893   vl_api_classify_table_by_interface_reply_t_handler
4894   (vl_api_classify_table_by_interface_reply_t * mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897   u32 table_id;
4898
4899   table_id = ntohl (mp->l2_table_id);
4900   if (table_id != ~0)
4901     print (vam->ofp, "l2 table id : %d", table_id);
4902   else
4903     print (vam->ofp, "l2 table id : No input ACL tables configured");
4904   table_id = ntohl (mp->ip4_table_id);
4905   if (table_id != ~0)
4906     print (vam->ofp, "ip4 table id : %d", table_id);
4907   else
4908     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4909   table_id = ntohl (mp->ip6_table_id);
4910   if (table_id != ~0)
4911     print (vam->ofp, "ip6 table id : %d", table_id);
4912   else
4913     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4914   vam->retval = ntohl (mp->retval);
4915   vam->result_ready = 1;
4916 }
4917
4918 static void
4919   vl_api_classify_table_by_interface_reply_t_handler_json
4920   (vl_api_classify_table_by_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   vat_json_init_object (&node);
4926
4927   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4928   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4929   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4930
4931   vat_json_print (vam->ofp, &node);
4932   vat_json_free (&node);
4933
4934   vam->retval = ntohl (mp->retval);
4935   vam->result_ready = 1;
4936 }
4937
4938 static void vl_api_policer_add_del_reply_t_handler
4939   (vl_api_policer_add_del_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   i32 retval = ntohl (mp->retval);
4943   if (vam->async_mode)
4944     {
4945       vam->async_errors += (retval < 0);
4946     }
4947   else
4948     {
4949       vam->retval = retval;
4950       vam->result_ready = 1;
4951       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4952         /*
4953          * Note: this is just barely thread-safe, depends on
4954          * the main thread spinning waiting for an answer...
4955          */
4956         errmsg ("policer index %d", ntohl (mp->policer_index));
4957     }
4958 }
4959
4960 static void vl_api_policer_add_del_reply_t_handler_json
4961   (vl_api_policer_add_del_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   vat_json_init_object (&node);
4967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4968   vat_json_object_add_uint (&node, "policer_index",
4969                             ntohl (mp->policer_index));
4970
4971   vat_json_print (vam->ofp, &node);
4972   vat_json_free (&node);
4973
4974   vam->retval = ntohl (mp->retval);
4975   vam->result_ready = 1;
4976 }
4977
4978 /* Format hex dump. */
4979 u8 *
4980 format_hex_bytes (u8 * s, va_list * va)
4981 {
4982   u8 *bytes = va_arg (*va, u8 *);
4983   int n_bytes = va_arg (*va, int);
4984   uword i;
4985
4986   /* Print short or long form depending on byte count. */
4987   uword short_form = n_bytes <= 32;
4988   u32 indent = format_get_indent (s);
4989
4990   if (n_bytes == 0)
4991     return s;
4992
4993   for (i = 0; i < n_bytes; i++)
4994     {
4995       if (!short_form && (i % 32) == 0)
4996         s = format (s, "%08x: ", i);
4997       s = format (s, "%02x", bytes[i]);
4998       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4999         s = format (s, "\n%U", format_white_space, indent);
5000     }
5001
5002   return s;
5003 }
5004
5005 static void
5006 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5007                                             * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010   i32 retval = ntohl (mp->retval);
5011   if (retval == 0)
5012     {
5013       print (vam->ofp, "classify table info :");
5014       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5015              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5016              ntohl (mp->miss_next_index));
5017       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5018              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5019              ntohl (mp->match_n_vectors));
5020       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5021              ntohl (mp->mask_length));
5022     }
5023   vam->retval = retval;
5024   vam->result_ready = 1;
5025 }
5026
5027 static void
5028   vl_api_classify_table_info_reply_t_handler_json
5029   (vl_api_classify_table_info_reply_t * mp)
5030 {
5031   vat_main_t *vam = &vat_main;
5032   vat_json_node_t node;
5033
5034   i32 retval = ntohl (mp->retval);
5035   if (retval == 0)
5036     {
5037       vat_json_init_object (&node);
5038
5039       vat_json_object_add_int (&node, "sessions",
5040                                ntohl (mp->active_sessions));
5041       vat_json_object_add_int (&node, "nexttbl",
5042                                ntohl (mp->next_table_index));
5043       vat_json_object_add_int (&node, "nextnode",
5044                                ntohl (mp->miss_next_index));
5045       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5046       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5047       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5048       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5049                       ntohl (mp->mask_length), 0);
5050       vat_json_object_add_string_copy (&node, "mask", s);
5051
5052       vat_json_print (vam->ofp, &node);
5053       vat_json_free (&node);
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void
5060 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5061                                            mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064
5065   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5066          ntohl (mp->hit_next_index), ntohl (mp->advance),
5067          ntohl (mp->opaque_index));
5068   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5069          ntohl (mp->match_length));
5070 }
5071
5072 static void
5073   vl_api_classify_session_details_t_handler_json
5074   (vl_api_classify_session_details_t * mp)
5075 {
5076   vat_main_t *vam = &vat_main;
5077   vat_json_node_t *node = NULL;
5078
5079   if (VAT_JSON_ARRAY != vam->json_tree.type)
5080     {
5081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5082       vat_json_init_array (&vam->json_tree);
5083     }
5084   node = vat_json_array_add (&vam->json_tree);
5085
5086   vat_json_init_object (node);
5087   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5088   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5089   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5090   u8 *s =
5091     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5092             0);
5093   vat_json_object_add_string_copy (node, "match", s);
5094 }
5095
5096 static void vl_api_pg_create_interface_reply_t_handler
5097   (vl_api_pg_create_interface_reply_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100
5101   vam->retval = ntohl (mp->retval);
5102   vam->result_ready = 1;
5103 }
5104
5105 static void vl_api_pg_create_interface_reply_t_handler_json
5106   (vl_api_pg_create_interface_reply_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t node;
5110
5111   i32 retval = ntohl (mp->retval);
5112   if (retval == 0)
5113     {
5114       vat_json_init_object (&node);
5115
5116       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5117
5118       vat_json_print (vam->ofp, &node);
5119       vat_json_free (&node);
5120     }
5121   vam->retval = ntohl (mp->retval);
5122   vam->result_ready = 1;
5123 }
5124
5125 static void vl_api_policer_classify_details_t_handler
5126   (vl_api_policer_classify_details_t * mp)
5127 {
5128   vat_main_t *vam = &vat_main;
5129
5130   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5131          ntohl (mp->table_index));
5132 }
5133
5134 static void vl_api_policer_classify_details_t_handler_json
5135   (vl_api_policer_classify_details_t * mp)
5136 {
5137   vat_main_t *vam = &vat_main;
5138   vat_json_node_t *node;
5139
5140   if (VAT_JSON_ARRAY != vam->json_tree.type)
5141     {
5142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5143       vat_json_init_array (&vam->json_tree);
5144     }
5145   node = vat_json_array_add (&vam->json_tree);
5146
5147   vat_json_init_object (node);
5148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5149   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5150 }
5151
5152 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5153   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5154 {
5155   vat_main_t *vam = &vat_main;
5156   i32 retval = ntohl (mp->retval);
5157   if (vam->async_mode)
5158     {
5159       vam->async_errors += (retval < 0);
5160     }
5161   else
5162     {
5163       vam->retval = retval;
5164       vam->sw_if_index = ntohl (mp->sw_if_index);
5165       vam->result_ready = 1;
5166     }
5167   vam->regenerate_interface_table = 1;
5168 }
5169
5170 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5171   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5172 {
5173   vat_main_t *vam = &vat_main;
5174   vat_json_node_t node;
5175
5176   vat_json_init_object (&node);
5177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5178   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5179
5180   vat_json_print (vam->ofp, &node);
5181   vat_json_free (&node);
5182
5183   vam->retval = ntohl (mp->retval);
5184   vam->result_ready = 1;
5185 }
5186
5187 static void vl_api_flow_classify_details_t_handler
5188   (vl_api_flow_classify_details_t * mp)
5189 {
5190   vat_main_t *vam = &vat_main;
5191
5192   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5193          ntohl (mp->table_index));
5194 }
5195
5196 static void vl_api_flow_classify_details_t_handler_json
5197   (vl_api_flow_classify_details_t * mp)
5198 {
5199   vat_main_t *vam = &vat_main;
5200   vat_json_node_t *node;
5201
5202   if (VAT_JSON_ARRAY != vam->json_tree.type)
5203     {
5204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5205       vat_json_init_array (&vam->json_tree);
5206     }
5207   node = vat_json_array_add (&vam->json_tree);
5208
5209   vat_json_init_object (node);
5210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5211   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5212 }
5213
5214 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5215 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5216 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5217 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5218 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5219 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5220 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5221 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5222 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5223 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5224 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5225 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5226 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5227 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5228 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5229 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5230 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5232 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5233 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5234 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5235 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5236
5237 /*
5238  * Generate boilerplate reply handlers, which
5239  * dig the return value out of the xxx_reply_t API message,
5240  * stick it into vam->retval, and set vam->result_ready
5241  *
5242  * Could also do this by pointing N message decode slots at
5243  * a single function, but that could break in subtle ways.
5244  */
5245
5246 #define foreach_standard_reply_retval_handler           \
5247 _(sw_interface_set_flags_reply)                         \
5248 _(sw_interface_add_del_address_reply)                   \
5249 _(sw_interface_set_rx_mode_reply)                       \
5250 _(sw_interface_set_table_reply)                         \
5251 _(sw_interface_set_mpls_enable_reply)                   \
5252 _(sw_interface_set_vpath_reply)                         \
5253 _(sw_interface_set_vxlan_bypass_reply)                  \
5254 _(sw_interface_set_geneve_bypass_reply)                 \
5255 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5256 _(sw_interface_set_l2_bridge_reply)                     \
5257 _(bridge_domain_add_del_reply)                          \
5258 _(sw_interface_set_l2_xconnect_reply)                   \
5259 _(l2fib_add_del_reply)                                  \
5260 _(l2fib_flush_int_reply)                                \
5261 _(l2fib_flush_bd_reply)                                 \
5262 _(ip_add_del_route_reply)                               \
5263 _(ip_table_add_del_reply)                               \
5264 _(ip_mroute_add_del_reply)                              \
5265 _(mpls_route_add_del_reply)                             \
5266 _(mpls_table_add_del_reply)                             \
5267 _(mpls_ip_bind_unbind_reply)                            \
5268 _(bier_route_add_del_reply)                             \
5269 _(bier_table_add_del_reply)                             \
5270 _(proxy_arp_add_del_reply)                              \
5271 _(proxy_arp_intfc_enable_disable_reply)                 \
5272 _(sw_interface_set_unnumbered_reply)                    \
5273 _(ip_neighbor_add_del_reply)                            \
5274 _(oam_add_del_reply)                                    \
5275 _(reset_fib_reply)                                      \
5276 _(dhcp_proxy_config_reply)                              \
5277 _(dhcp_proxy_set_vss_reply)                             \
5278 _(dhcp_client_config_reply)                             \
5279 _(set_ip_flow_hash_reply)                               \
5280 _(sw_interface_ip6_enable_disable_reply)                \
5281 _(sw_interface_ip6_set_link_local_address_reply)        \
5282 _(ip6nd_proxy_add_del_reply)                            \
5283 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5284 _(sw_interface_ip6nd_ra_config_reply)                   \
5285 _(set_arp_neighbor_limit_reply)                         \
5286 _(l2_patch_add_del_reply)                               \
5287 _(sr_policy_add_reply)                                  \
5288 _(sr_policy_mod_reply)                                  \
5289 _(sr_policy_del_reply)                                  \
5290 _(sr_localsid_add_del_reply)                            \
5291 _(sr_steering_add_del_reply)                            \
5292 _(classify_add_del_session_reply)                       \
5293 _(classify_set_interface_ip_table_reply)                \
5294 _(classify_set_interface_l2_tables_reply)               \
5295 _(l2tpv3_set_tunnel_cookies_reply)                      \
5296 _(l2tpv3_interface_enable_disable_reply)                \
5297 _(l2tpv3_set_lookup_key_reply)                          \
5298 _(l2_fib_clear_table_reply)                             \
5299 _(l2_interface_efp_filter_reply)                        \
5300 _(l2_interface_vlan_tag_rewrite_reply)                  \
5301 _(modify_vhost_user_if_reply)                           \
5302 _(delete_vhost_user_if_reply)                           \
5303 _(want_ip4_arp_events_reply)                            \
5304 _(want_ip6_nd_events_reply)                             \
5305 _(want_l2_macs_events_reply)                            \
5306 _(input_acl_set_interface_reply)                        \
5307 _(ipsec_spd_add_del_reply)                              \
5308 _(ipsec_interface_add_del_spd_reply)                    \
5309 _(ipsec_spd_add_del_entry_reply)                        \
5310 _(ipsec_sad_add_del_entry_reply)                        \
5311 _(ipsec_sa_set_key_reply)                               \
5312 _(ipsec_tunnel_if_add_del_reply)                        \
5313 _(ipsec_tunnel_if_set_key_reply)                        \
5314 _(ipsec_tunnel_if_set_sa_reply)                         \
5315 _(ikev2_profile_add_del_reply)                          \
5316 _(ikev2_profile_set_auth_reply)                         \
5317 _(ikev2_profile_set_id_reply)                           \
5318 _(ikev2_profile_set_ts_reply)                           \
5319 _(ikev2_set_local_key_reply)                            \
5320 _(ikev2_set_responder_reply)                            \
5321 _(ikev2_set_ike_transforms_reply)                       \
5322 _(ikev2_set_esp_transforms_reply)                       \
5323 _(ikev2_set_sa_lifetime_reply)                          \
5324 _(ikev2_initiate_sa_init_reply)                         \
5325 _(ikev2_initiate_del_ike_sa_reply)                      \
5326 _(ikev2_initiate_del_child_sa_reply)                    \
5327 _(ikev2_initiate_rekey_child_sa_reply)                  \
5328 _(delete_loopback_reply)                                \
5329 _(bd_ip_mac_add_del_reply)                              \
5330 _(map_del_domain_reply)                                 \
5331 _(map_add_del_rule_reply)                               \
5332 _(want_interface_events_reply)                          \
5333 _(want_stats_reply)                                     \
5334 _(cop_interface_enable_disable_reply)                   \
5335 _(cop_whitelist_enable_disable_reply)                   \
5336 _(sw_interface_clear_stats_reply)                       \
5337 _(ioam_enable_reply)                                    \
5338 _(ioam_disable_reply)                                   \
5339 _(one_add_del_locator_reply)                            \
5340 _(one_add_del_local_eid_reply)                          \
5341 _(one_add_del_remote_mapping_reply)                     \
5342 _(one_add_del_adjacency_reply)                          \
5343 _(one_add_del_map_resolver_reply)                       \
5344 _(one_add_del_map_server_reply)                         \
5345 _(one_enable_disable_reply)                             \
5346 _(one_rloc_probe_enable_disable_reply)                  \
5347 _(one_map_register_enable_disable_reply)                \
5348 _(one_map_register_set_ttl_reply)                       \
5349 _(one_set_transport_protocol_reply)                     \
5350 _(one_map_register_fallback_threshold_reply)            \
5351 _(one_pitr_set_locator_set_reply)                       \
5352 _(one_map_request_mode_reply)                           \
5353 _(one_add_del_map_request_itr_rlocs_reply)              \
5354 _(one_eid_table_add_del_map_reply)                      \
5355 _(one_use_petr_reply)                                   \
5356 _(one_stats_enable_disable_reply)                       \
5357 _(one_add_del_l2_arp_entry_reply)                       \
5358 _(one_add_del_ndp_entry_reply)                          \
5359 _(one_stats_flush_reply)                                \
5360 _(one_enable_disable_xtr_mode_reply)                    \
5361 _(one_enable_disable_pitr_mode_reply)                   \
5362 _(one_enable_disable_petr_mode_reply)                   \
5363 _(gpe_enable_disable_reply)                             \
5364 _(gpe_set_encap_mode_reply)                             \
5365 _(gpe_add_del_iface_reply)                              \
5366 _(gpe_add_del_native_fwd_rpath_reply)                   \
5367 _(af_packet_delete_reply)                               \
5368 _(policer_classify_set_interface_reply)                 \
5369 _(netmap_create_reply)                                  \
5370 _(netmap_delete_reply)                                  \
5371 _(set_ipfix_exporter_reply)                             \
5372 _(set_ipfix_classify_stream_reply)                      \
5373 _(ipfix_classify_table_add_del_reply)                   \
5374 _(flow_classify_set_interface_reply)                    \
5375 _(sw_interface_span_enable_disable_reply)               \
5376 _(pg_capture_reply)                                     \
5377 _(pg_enable_disable_reply)                              \
5378 _(ip_source_and_port_range_check_add_del_reply)         \
5379 _(ip_source_and_port_range_check_interface_add_del_reply)\
5380 _(delete_subif_reply)                                   \
5381 _(l2_interface_pbb_tag_rewrite_reply)                   \
5382 _(punt_reply)                                           \
5383 _(feature_enable_disable_reply)                         \
5384 _(sw_interface_tag_add_del_reply)                       \
5385 _(sw_interface_set_mtu_reply)                           \
5386 _(p2p_ethernet_add_reply)                               \
5387 _(p2p_ethernet_del_reply)                               \
5388 _(lldp_config_reply)                                    \
5389 _(sw_interface_set_lldp_reply)                          \
5390 _(tcp_configure_src_addresses_reply)                    \
5391 _(dns_enable_disable_reply)                             \
5392 _(dns_name_server_add_del_reply)                        \
5393 _(session_rule_add_del_reply)                           \
5394 _(ip_container_proxy_add_del_reply)                     \
5395 _(output_acl_set_interface_reply)
5396
5397 #define _(n)                                    \
5398     static void vl_api_##n##_t_handler          \
5399     (vl_api_##n##_t * mp)                       \
5400     {                                           \
5401         vat_main_t * vam = &vat_main;           \
5402         i32 retval = ntohl(mp->retval);         \
5403         if (vam->async_mode) {                  \
5404             vam->async_errors += (retval < 0);  \
5405         } else {                                \
5406             vam->retval = retval;               \
5407             vam->result_ready = 1;              \
5408         }                                       \
5409     }
5410 foreach_standard_reply_retval_handler;
5411 #undef _
5412
5413 #define _(n)                                    \
5414     static void vl_api_##n##_t_handler_json     \
5415     (vl_api_##n##_t * mp)                       \
5416     {                                           \
5417         vat_main_t * vam = &vat_main;           \
5418         vat_json_node_t node;                   \
5419         vat_json_init_object(&node);            \
5420         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5421         vat_json_print(vam->ofp, &node);        \
5422         vam->retval = ntohl(mp->retval);        \
5423         vam->result_ready = 1;                  \
5424     }
5425 foreach_standard_reply_retval_handler;
5426 #undef _
5427
5428 /*
5429  * Table of message reply handlers, must include boilerplate handlers
5430  * we just generated
5431  */
5432
5433 #define foreach_vpe_api_reply_msg                                       \
5434 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5435 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5436 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5437 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5438 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5439 _(CLI_REPLY, cli_reply)                                                 \
5440 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5441 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5442   sw_interface_add_del_address_reply)                                   \
5443 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5444 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5445 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5446 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5447 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5448 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5449 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5450 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5451   sw_interface_set_l2_xconnect_reply)                                   \
5452 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5453   sw_interface_set_l2_bridge_reply)                                     \
5454 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5455 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5456 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5457 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5458 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5459 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5460 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5461 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5462 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5463 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5464 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5465 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5466 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5467 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5468 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5469 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5470 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5471 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5472 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5473 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5474 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5475 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5476 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5477 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5478 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5479   proxy_arp_intfc_enable_disable_reply)                                 \
5480 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5481 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5482   sw_interface_set_unnumbered_reply)                                    \
5483 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5484 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5485 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5486 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5487 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5488 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5489 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5490 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5491 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5492 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5493 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5494   sw_interface_ip6_enable_disable_reply)                                \
5495 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5496   sw_interface_ip6_set_link_local_address_reply)                        \
5497 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5498 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5499 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5500   sw_interface_ip6nd_ra_prefix_reply)                                   \
5501 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5502   sw_interface_ip6nd_ra_config_reply)                                   \
5503 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5504 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5505 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5506 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5507 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5508 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5509 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5510 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5511 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5512 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5513 classify_set_interface_ip_table_reply)                                  \
5514 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5515   classify_set_interface_l2_tables_reply)                               \
5516 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5517 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5518 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5519 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5520 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5521   l2tpv3_interface_enable_disable_reply)                                \
5522 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5523 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5524 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5525 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5526 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5527 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5528 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5529 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5530 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5531 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5532 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5533 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5534 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5535 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5536 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5537 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5538 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5539 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5540 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5541 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5542 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5543 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5544 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5545 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5546 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5547 _(L2_MACS_EVENT, l2_macs_event)                                         \
5548 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5549 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5550 _(IP_DETAILS, ip_details)                                               \
5551 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5552 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5553 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5554 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5555 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5556 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5557 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5558 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5559 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5560 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5561 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5562 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5563 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5564 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5565 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5566 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5567 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5568 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5569 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5570 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5571 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5572 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5573 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5574 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5575 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5576 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5577 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5578 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5579 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5580 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5581 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5582 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5583 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5584 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5585 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5586 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5587 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5588 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5589 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5590 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5591 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5592 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5593 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5594 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5595 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5596 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5597 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5598 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5599   one_map_register_enable_disable_reply)                                \
5600 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5601 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5602 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5603 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5604   one_map_register_fallback_threshold_reply)                            \
5605 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5606   one_rloc_probe_enable_disable_reply)                                  \
5607 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5608 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5609 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5610 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5611 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5612 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5613 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5614 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5615 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5616 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5617 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5618 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5619 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5620 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5621 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5622 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5623   show_one_stats_enable_disable_reply)                                  \
5624 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5625 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5626 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5627 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5628 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5629 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5630 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5631 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5632   one_enable_disable_pitr_mode_reply)                                   \
5633 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5634   one_enable_disable_petr_mode_reply)                                   \
5635 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5636 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5637 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5638 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5639 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5640 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5641 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5642 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5643 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5644 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5645 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5646 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5647   gpe_add_del_native_fwd_rpath_reply)                                   \
5648 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5649   gpe_fwd_entry_path_details)                                           \
5650 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5651 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5652   one_add_del_map_request_itr_rlocs_reply)                              \
5653 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5654   one_get_map_request_itr_rlocs_reply)                                  \
5655 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5656 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5657 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5658 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5659 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5660 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5661   show_one_map_register_state_reply)                                    \
5662 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5663 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5664   show_one_map_register_fallback_threshold_reply)                       \
5665 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5666 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5667 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5668 _(POLICER_DETAILS, policer_details)                                     \
5669 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5670 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5671 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5672 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5673 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5674 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5675 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5676 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5677 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5678 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5679 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5680 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5681 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5682 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5683 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5684 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5685 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5686 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5687 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5688 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5689 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5690 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5691 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5692 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5693 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5694  ip_source_and_port_range_check_add_del_reply)                          \
5695 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5696  ip_source_and_port_range_check_interface_add_del_reply)                \
5697 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5698 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5699 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5700 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5701 _(PUNT_REPLY, punt_reply)                                               \
5702 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5703 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5704 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5705 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5706 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5707 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5708 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5709 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5710 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5711 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5712 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5713 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5714 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5715 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5716 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5717 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5718 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5719 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5720 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5721 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5722 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5723 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5724
5725 #define foreach_standalone_reply_msg                                    \
5726 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5727 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5728 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5729 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5730 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5731 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5732 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5733 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5734
5735 typedef struct
5736 {
5737   u8 *name;
5738   u32 value;
5739 } name_sort_t;
5740
5741
5742 #define STR_VTR_OP_CASE(op)     \
5743     case L2_VTR_ ## op:         \
5744         return "" # op;
5745
5746 static const char *
5747 str_vtr_op (u32 vtr_op)
5748 {
5749   switch (vtr_op)
5750     {
5751       STR_VTR_OP_CASE (DISABLED);
5752       STR_VTR_OP_CASE (PUSH_1);
5753       STR_VTR_OP_CASE (PUSH_2);
5754       STR_VTR_OP_CASE (POP_1);
5755       STR_VTR_OP_CASE (POP_2);
5756       STR_VTR_OP_CASE (TRANSLATE_1_1);
5757       STR_VTR_OP_CASE (TRANSLATE_1_2);
5758       STR_VTR_OP_CASE (TRANSLATE_2_1);
5759       STR_VTR_OP_CASE (TRANSLATE_2_2);
5760     }
5761
5762   return "UNKNOWN";
5763 }
5764
5765 static int
5766 dump_sub_interface_table (vat_main_t * vam)
5767 {
5768   const sw_interface_subif_t *sub = NULL;
5769
5770   if (vam->json_output)
5771     {
5772       clib_warning
5773         ("JSON output supported only for VPE API calls and dump_stats_table");
5774       return -99;
5775     }
5776
5777   print (vam->ofp,
5778          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5779          "Interface", "sw_if_index",
5780          "sub id", "dot1ad", "tags", "outer id",
5781          "inner id", "exact", "default", "outer any", "inner any");
5782
5783   vec_foreach (sub, vam->sw_if_subif_table)
5784   {
5785     print (vam->ofp,
5786            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5787            sub->interface_name,
5788            sub->sw_if_index,
5789            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5790            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5791            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5792            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5793     if (sub->vtr_op != L2_VTR_DISABLED)
5794       {
5795         print (vam->ofp,
5796                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5797                "tag1: %d tag2: %d ]",
5798                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5799                sub->vtr_tag1, sub->vtr_tag2);
5800       }
5801   }
5802
5803   return 0;
5804 }
5805
5806 static int
5807 name_sort_cmp (void *a1, void *a2)
5808 {
5809   name_sort_t *n1 = a1;
5810   name_sort_t *n2 = a2;
5811
5812   return strcmp ((char *) n1->name, (char *) n2->name);
5813 }
5814
5815 static int
5816 dump_interface_table (vat_main_t * vam)
5817 {
5818   hash_pair_t *p;
5819   name_sort_t *nses = 0, *ns;
5820
5821   if (vam->json_output)
5822     {
5823       clib_warning
5824         ("JSON output supported only for VPE API calls and dump_stats_table");
5825       return -99;
5826     }
5827
5828   /* *INDENT-OFF* */
5829   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5830   ({
5831     vec_add2 (nses, ns, 1);
5832     ns->name = (u8 *)(p->key);
5833     ns->value = (u32) p->value[0];
5834   }));
5835   /* *INDENT-ON* */
5836
5837   vec_sort_with_function (nses, name_sort_cmp);
5838
5839   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5840   vec_foreach (ns, nses)
5841   {
5842     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5843   }
5844   vec_free (nses);
5845   return 0;
5846 }
5847
5848 static int
5849 dump_ip_table (vat_main_t * vam, int is_ipv6)
5850 {
5851   const ip_details_t *det = NULL;
5852   const ip_address_details_t *address = NULL;
5853   u32 i = ~0;
5854
5855   print (vam->ofp, "%-12s", "sw_if_index");
5856
5857   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5858   {
5859     i++;
5860     if (!det->present)
5861       {
5862         continue;
5863       }
5864     print (vam->ofp, "%-12d", i);
5865     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5866     if (!det->addr)
5867       {
5868         continue;
5869       }
5870     vec_foreach (address, det->addr)
5871     {
5872       print (vam->ofp,
5873              "            %-30U%-13d",
5874              is_ipv6 ? format_ip6_address : format_ip4_address,
5875              address->ip, address->prefix_length);
5876     }
5877   }
5878
5879   return 0;
5880 }
5881
5882 static int
5883 dump_ipv4_table (vat_main_t * vam)
5884 {
5885   if (vam->json_output)
5886     {
5887       clib_warning
5888         ("JSON output supported only for VPE API calls and dump_stats_table");
5889       return -99;
5890     }
5891
5892   return dump_ip_table (vam, 0);
5893 }
5894
5895 static int
5896 dump_ipv6_table (vat_main_t * vam)
5897 {
5898   if (vam->json_output)
5899     {
5900       clib_warning
5901         ("JSON output supported only for VPE API calls and dump_stats_table");
5902       return -99;
5903     }
5904
5905   return dump_ip_table (vam, 1);
5906 }
5907
5908 static char *
5909 counter_type_to_str (u8 counter_type, u8 is_combined)
5910 {
5911   if (!is_combined)
5912     {
5913       switch (counter_type)
5914         {
5915         case VNET_INTERFACE_COUNTER_DROP:
5916           return "drop";
5917         case VNET_INTERFACE_COUNTER_PUNT:
5918           return "punt";
5919         case VNET_INTERFACE_COUNTER_IP4:
5920           return "ip4";
5921         case VNET_INTERFACE_COUNTER_IP6:
5922           return "ip6";
5923         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5924           return "rx-no-buf";
5925         case VNET_INTERFACE_COUNTER_RX_MISS:
5926           return "rx-miss";
5927         case VNET_INTERFACE_COUNTER_RX_ERROR:
5928           return "rx-error";
5929         case VNET_INTERFACE_COUNTER_TX_ERROR:
5930           return "tx-error";
5931         default:
5932           return "INVALID-COUNTER-TYPE";
5933         }
5934     }
5935   else
5936     {
5937       switch (counter_type)
5938         {
5939         case VNET_INTERFACE_COUNTER_RX:
5940           return "rx";
5941         case VNET_INTERFACE_COUNTER_TX:
5942           return "tx";
5943         default:
5944           return "INVALID-COUNTER-TYPE";
5945         }
5946     }
5947 }
5948
5949 static int
5950 dump_stats_table (vat_main_t * vam)
5951 {
5952   vat_json_node_t node;
5953   vat_json_node_t *msg_array;
5954   vat_json_node_t *msg;
5955   vat_json_node_t *counter_array;
5956   vat_json_node_t *counter;
5957   interface_counter_t c;
5958   u64 packets;
5959   ip4_fib_counter_t *c4;
5960   ip6_fib_counter_t *c6;
5961   ip4_nbr_counter_t *n4;
5962   ip6_nbr_counter_t *n6;
5963   int i, j;
5964
5965   if (!vam->json_output)
5966     {
5967       clib_warning ("dump_stats_table supported only in JSON format");
5968       return -99;
5969     }
5970
5971   vat_json_init_object (&node);
5972
5973   /* interface counters */
5974   msg_array = vat_json_object_add (&node, "interface_counters");
5975   vat_json_init_array (msg_array);
5976   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5977     {
5978       msg = vat_json_array_add (msg_array);
5979       vat_json_init_object (msg);
5980       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5981                                        (u8 *) counter_type_to_str (i, 0));
5982       vat_json_object_add_int (msg, "is_combined", 0);
5983       counter_array = vat_json_object_add (msg, "data");
5984       vat_json_init_array (counter_array);
5985       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5986         {
5987           packets = vam->simple_interface_counters[i][j];
5988           vat_json_array_add_uint (counter_array, packets);
5989         }
5990     }
5991   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5992     {
5993       msg = vat_json_array_add (msg_array);
5994       vat_json_init_object (msg);
5995       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5996                                        (u8 *) counter_type_to_str (i, 1));
5997       vat_json_object_add_int (msg, "is_combined", 1);
5998       counter_array = vat_json_object_add (msg, "data");
5999       vat_json_init_array (counter_array);
6000       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6001         {
6002           c = vam->combined_interface_counters[i][j];
6003           counter = vat_json_array_add (counter_array);
6004           vat_json_init_object (counter);
6005           vat_json_object_add_uint (counter, "packets", c.packets);
6006           vat_json_object_add_uint (counter, "bytes", c.bytes);
6007         }
6008     }
6009
6010   /* ip4 fib counters */
6011   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6012   vat_json_init_array (msg_array);
6013   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6014     {
6015       msg = vat_json_array_add (msg_array);
6016       vat_json_init_object (msg);
6017       vat_json_object_add_uint (msg, "vrf_id",
6018                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6019       counter_array = vat_json_object_add (msg, "c");
6020       vat_json_init_array (counter_array);
6021       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6022         {
6023           counter = vat_json_array_add (counter_array);
6024           vat_json_init_object (counter);
6025           c4 = &vam->ip4_fib_counters[i][j];
6026           vat_json_object_add_ip4 (counter, "address", c4->address);
6027           vat_json_object_add_uint (counter, "address_length",
6028                                     c4->address_length);
6029           vat_json_object_add_uint (counter, "packets", c4->packets);
6030           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6031         }
6032     }
6033
6034   /* ip6 fib counters */
6035   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6036   vat_json_init_array (msg_array);
6037   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6038     {
6039       msg = vat_json_array_add (msg_array);
6040       vat_json_init_object (msg);
6041       vat_json_object_add_uint (msg, "vrf_id",
6042                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6043       counter_array = vat_json_object_add (msg, "c");
6044       vat_json_init_array (counter_array);
6045       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6046         {
6047           counter = vat_json_array_add (counter_array);
6048           vat_json_init_object (counter);
6049           c6 = &vam->ip6_fib_counters[i][j];
6050           vat_json_object_add_ip6 (counter, "address", c6->address);
6051           vat_json_object_add_uint (counter, "address_length",
6052                                     c6->address_length);
6053           vat_json_object_add_uint (counter, "packets", c6->packets);
6054           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6055         }
6056     }
6057
6058   /* ip4 nbr counters */
6059   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6060   vat_json_init_array (msg_array);
6061   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6062     {
6063       msg = vat_json_array_add (msg_array);
6064       vat_json_init_object (msg);
6065       vat_json_object_add_uint (msg, "sw_if_index", i);
6066       counter_array = vat_json_object_add (msg, "c");
6067       vat_json_init_array (counter_array);
6068       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6069         {
6070           counter = vat_json_array_add (counter_array);
6071           vat_json_init_object (counter);
6072           n4 = &vam->ip4_nbr_counters[i][j];
6073           vat_json_object_add_ip4 (counter, "address", n4->address);
6074           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6075           vat_json_object_add_uint (counter, "packets", n4->packets);
6076           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6077         }
6078     }
6079
6080   /* ip6 nbr counters */
6081   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6082   vat_json_init_array (msg_array);
6083   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6084     {
6085       msg = vat_json_array_add (msg_array);
6086       vat_json_init_object (msg);
6087       vat_json_object_add_uint (msg, "sw_if_index", i);
6088       counter_array = vat_json_object_add (msg, "c");
6089       vat_json_init_array (counter_array);
6090       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6091         {
6092           counter = vat_json_array_add (counter_array);
6093           vat_json_init_object (counter);
6094           n6 = &vam->ip6_nbr_counters[i][j];
6095           vat_json_object_add_ip6 (counter, "address", n6->address);
6096           vat_json_object_add_uint (counter, "packets", n6->packets);
6097           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6098         }
6099     }
6100
6101   vat_json_print (vam->ofp, &node);
6102   vat_json_free (&node);
6103
6104   return 0;
6105 }
6106
6107 /*
6108  * Pass CLI buffers directly in the CLI_INBAND API message,
6109  * instead of an additional shared memory area.
6110  */
6111 static int
6112 exec_inband (vat_main_t * vam)
6113 {
6114   vl_api_cli_inband_t *mp;
6115   unformat_input_t *i = vam->input;
6116   int ret;
6117
6118   if (vec_len (i->buffer) == 0)
6119     return -1;
6120
6121   if (vam->exec_mode == 0 && unformat (i, "mode"))
6122     {
6123       vam->exec_mode = 1;
6124       return 0;
6125     }
6126   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6127     {
6128       vam->exec_mode = 0;
6129       return 0;
6130     }
6131
6132   /*
6133    * In order for the CLI command to work, it
6134    * must be a vector ending in \n, not a C-string ending
6135    * in \n\0.
6136    */
6137   u32 len = vec_len (vam->input->buffer);
6138   M2 (CLI_INBAND, mp, len);
6139   clib_memcpy (mp->cmd, vam->input->buffer, len);
6140   mp->length = htonl (len);
6141
6142   S (mp);
6143   W (ret);
6144   /* json responses may or may not include a useful reply... */
6145   if (vec_len (vam->cmd_reply))
6146     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6147   return ret;
6148 }
6149
6150 int
6151 exec (vat_main_t * vam)
6152 {
6153   return exec_inband (vam);
6154 }
6155
6156 static int
6157 api_create_loopback (vat_main_t * vam)
6158 {
6159   unformat_input_t *i = vam->input;
6160   vl_api_create_loopback_t *mp;
6161   vl_api_create_loopback_instance_t *mp_lbi;
6162   u8 mac_address[6];
6163   u8 mac_set = 0;
6164   u8 is_specified = 0;
6165   u32 user_instance = 0;
6166   int ret;
6167
6168   memset (mac_address, 0, sizeof (mac_address));
6169
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6173         mac_set = 1;
6174       if (unformat (i, "instance %d", &user_instance))
6175         is_specified = 1;
6176       else
6177         break;
6178     }
6179
6180   if (is_specified)
6181     {
6182       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6183       mp_lbi->is_specified = is_specified;
6184       if (is_specified)
6185         mp_lbi->user_instance = htonl (user_instance);
6186       if (mac_set)
6187         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6188       S (mp_lbi);
6189     }
6190   else
6191     {
6192       /* Construct the API message */
6193       M (CREATE_LOOPBACK, mp);
6194       if (mac_set)
6195         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6196       S (mp);
6197     }
6198
6199   W (ret);
6200   return ret;
6201 }
6202
6203 static int
6204 api_delete_loopback (vat_main_t * vam)
6205 {
6206   unformat_input_t *i = vam->input;
6207   vl_api_delete_loopback_t *mp;
6208   u32 sw_if_index = ~0;
6209   int ret;
6210
6211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6212     {
6213       if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         ;
6215       else
6216         break;
6217     }
6218
6219   if (sw_if_index == ~0)
6220     {
6221       errmsg ("missing sw_if_index");
6222       return -99;
6223     }
6224
6225   /* Construct the API message */
6226   M (DELETE_LOOPBACK, mp);
6227   mp->sw_if_index = ntohl (sw_if_index);
6228
6229   S (mp);
6230   W (ret);
6231   return ret;
6232 }
6233
6234 static int
6235 api_want_stats (vat_main_t * vam)
6236 {
6237   unformat_input_t *i = vam->input;
6238   vl_api_want_stats_t *mp;
6239   int enable = -1;
6240   int ret;
6241
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "enable"))
6245         enable = 1;
6246       else if (unformat (i, "disable"))
6247         enable = 0;
6248       else
6249         break;
6250     }
6251
6252   if (enable == -1)
6253     {
6254       errmsg ("missing enable|disable");
6255       return -99;
6256     }
6257
6258   M (WANT_STATS, mp);
6259   mp->enable_disable = enable;
6260
6261   S (mp);
6262   W (ret);
6263   return ret;
6264 }
6265
6266 static int
6267 api_want_interface_events (vat_main_t * vam)
6268 {
6269   unformat_input_t *i = vam->input;
6270   vl_api_want_interface_events_t *mp;
6271   int enable = -1;
6272   int ret;
6273
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "enable"))
6277         enable = 1;
6278       else if (unformat (i, "disable"))
6279         enable = 0;
6280       else
6281         break;
6282     }
6283
6284   if (enable == -1)
6285     {
6286       errmsg ("missing enable|disable");
6287       return -99;
6288     }
6289
6290   M (WANT_INTERFACE_EVENTS, mp);
6291   mp->enable_disable = enable;
6292
6293   vam->interface_event_display = enable;
6294
6295   S (mp);
6296   W (ret);
6297   return ret;
6298 }
6299
6300
6301 /* Note: non-static, called once to set up the initial intfc table */
6302 int
6303 api_sw_interface_dump (vat_main_t * vam)
6304 {
6305   vl_api_sw_interface_dump_t *mp;
6306   vl_api_control_ping_t *mp_ping;
6307   hash_pair_t *p;
6308   name_sort_t *nses = 0, *ns;
6309   sw_interface_subif_t *sub = NULL;
6310   int ret;
6311
6312   /* Toss the old name table */
6313   /* *INDENT-OFF* */
6314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6315   ({
6316     vec_add2 (nses, ns, 1);
6317     ns->name = (u8 *)(p->key);
6318     ns->value = (u32) p->value[0];
6319   }));
6320   /* *INDENT-ON* */
6321
6322   hash_free (vam->sw_if_index_by_interface_name);
6323
6324   vec_foreach (ns, nses) vec_free (ns->name);
6325
6326   vec_free (nses);
6327
6328   vec_foreach (sub, vam->sw_if_subif_table)
6329   {
6330     vec_free (sub->interface_name);
6331   }
6332   vec_free (vam->sw_if_subif_table);
6333
6334   /* recreate the interface name hash table */
6335   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6336
6337   /*
6338    * Ask for all interface names. Otherwise, the epic catalog of
6339    * name filters becomes ridiculously long, and vat ends up needing
6340    * to be taught about new interface types.
6341    */
6342   M (SW_INTERFACE_DUMP, mp);
6343   S (mp);
6344
6345   /* Use a control ping for synchronization */
6346   MPING (CONTROL_PING, mp_ping);
6347   S (mp_ping);
6348
6349   W (ret);
6350   return ret;
6351 }
6352
6353 static int
6354 api_sw_interface_set_flags (vat_main_t * vam)
6355 {
6356   unformat_input_t *i = vam->input;
6357   vl_api_sw_interface_set_flags_t *mp;
6358   u32 sw_if_index;
6359   u8 sw_if_index_set = 0;
6360   u8 admin_up = 0;
6361   int ret;
6362
6363   /* Parse args required to build the message */
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "admin-up"))
6367         admin_up = 1;
6368       else if (unformat (i, "admin-down"))
6369         admin_up = 0;
6370       else
6371         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   /* Construct the API message */
6386   M (SW_INTERFACE_SET_FLAGS, mp);
6387   mp->sw_if_index = ntohl (sw_if_index);
6388   mp->admin_up_down = admin_up;
6389
6390   /* send it... */
6391   S (mp);
6392
6393   /* Wait for a reply, return the good/bad news... */
6394   W (ret);
6395   return ret;
6396 }
6397
6398 static int
6399 api_sw_interface_set_rx_mode (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_sw_interface_set_rx_mode_t *mp;
6403   u32 sw_if_index;
6404   u8 sw_if_index_set = 0;
6405   int ret;
6406   u8 queue_id_valid = 0;
6407   u32 queue_id;
6408   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6409
6410   /* Parse args required to build the message */
6411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6412     {
6413       if (unformat (i, "queue %d", &queue_id))
6414         queue_id_valid = 1;
6415       else if (unformat (i, "polling"))
6416         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6417       else if (unformat (i, "interrupt"))
6418         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6419       else if (unformat (i, "adaptive"))
6420         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6421       else
6422         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6423         sw_if_index_set = 1;
6424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6425         sw_if_index_set = 1;
6426       else
6427         break;
6428     }
6429
6430   if (sw_if_index_set == 0)
6431     {
6432       errmsg ("missing interface name or sw_if_index");
6433       return -99;
6434     }
6435   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6436     {
6437       errmsg ("missing rx-mode");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (SW_INTERFACE_SET_RX_MODE, mp);
6443   mp->sw_if_index = ntohl (sw_if_index);
6444   mp->mode = mode;
6445   mp->queue_id_valid = queue_id_valid;
6446   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6447
6448   /* send it... */
6449   S (mp);
6450
6451   /* Wait for a reply, return the good/bad news... */
6452   W (ret);
6453   return ret;
6454 }
6455
6456 static int
6457 api_sw_interface_clear_stats (vat_main_t * vam)
6458 {
6459   unformat_input_t *i = vam->input;
6460   vl_api_sw_interface_clear_stats_t *mp;
6461   u32 sw_if_index;
6462   u8 sw_if_index_set = 0;
6463   int ret;
6464
6465   /* Parse args required to build the message */
6466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6467     {
6468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6471         sw_if_index_set = 1;
6472       else
6473         break;
6474     }
6475
6476   /* Construct the API message */
6477   M (SW_INTERFACE_CLEAR_STATS, mp);
6478
6479   if (sw_if_index_set == 1)
6480     mp->sw_if_index = ntohl (sw_if_index);
6481   else
6482     mp->sw_if_index = ~0;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply, return the good/bad news... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_add_del_address (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_add_del_address_t *mp;
6497   u32 sw_if_index;
6498   u8 sw_if_index_set = 0;
6499   u8 is_add = 1, del_all = 0;
6500   u32 address_length = 0;
6501   u8 v4_address_set = 0;
6502   u8 v6_address_set = 0;
6503   ip4_address_t v4address;
6504   ip6_address_t v6address;
6505   int ret;
6506
6507   /* Parse args required to build the message */
6508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6509     {
6510       if (unformat (i, "del-all"))
6511         del_all = 1;
6512       else if (unformat (i, "del"))
6513         is_add = 0;
6514       else
6515         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "%U/%d",
6520                          unformat_ip4_address, &v4address, &address_length))
6521         v4_address_set = 1;
6522       else if (unformat (i, "%U/%d",
6523                          unformat_ip6_address, &v6address, &address_length))
6524         v6_address_set = 1;
6525       else
6526         break;
6527     }
6528
6529   if (sw_if_index_set == 0)
6530     {
6531       errmsg ("missing interface name or sw_if_index");
6532       return -99;
6533     }
6534   if (v4_address_set && v6_address_set)
6535     {
6536       errmsg ("both v4 and v6 addresses set");
6537       return -99;
6538     }
6539   if (!v4_address_set && !v6_address_set && !del_all)
6540     {
6541       errmsg ("no addresses set");
6542       return -99;
6543     }
6544
6545   /* Construct the API message */
6546   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6547
6548   mp->sw_if_index = ntohl (sw_if_index);
6549   mp->is_add = is_add;
6550   mp->del_all = del_all;
6551   if (v6_address_set)
6552     {
6553       mp->is_ipv6 = 1;
6554       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6555     }
6556   else
6557     {
6558       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6559     }
6560   mp->address_length = address_length;
6561
6562   /* send it... */
6563   S (mp);
6564
6565   /* Wait for a reply, return good/bad news  */
6566   W (ret);
6567   return ret;
6568 }
6569
6570 static int
6571 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_mpls_enable_t *mp;
6575   u32 sw_if_index;
6576   u8 sw_if_index_set = 0;
6577   u8 enable = 1;
6578   int ret;
6579
6580   /* Parse args required to build the message */
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586         sw_if_index_set = 1;
6587       else if (unformat (i, "disable"))
6588         enable = 0;
6589       else if (unformat (i, "dis"))
6590         enable = 0;
6591       else
6592         break;
6593     }
6594
6595   if (sw_if_index_set == 0)
6596     {
6597       errmsg ("missing interface name or sw_if_index");
6598       return -99;
6599     }
6600
6601   /* Construct the API message */
6602   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6603
6604   mp->sw_if_index = ntohl (sw_if_index);
6605   mp->enable = enable;
6606
6607   /* send it... */
6608   S (mp);
6609
6610   /* Wait for a reply... */
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_sw_interface_set_table (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_sw_interface_set_table_t *mp;
6620   u32 sw_if_index, vrf_id = 0;
6621   u8 sw_if_index_set = 0;
6622   u8 is_ipv6 = 0;
6623   int ret;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6631         sw_if_index_set = 1;
6632       else if (unformat (i, "vrf %d", &vrf_id))
6633         ;
6634       else if (unformat (i, "ipv6"))
6635         is_ipv6 = 1;
6636       else
6637         break;
6638     }
6639
6640   if (sw_if_index_set == 0)
6641     {
6642       errmsg ("missing interface name or sw_if_index");
6643       return -99;
6644     }
6645
6646   /* Construct the API message */
6647   M (SW_INTERFACE_SET_TABLE, mp);
6648
6649   mp->sw_if_index = ntohl (sw_if_index);
6650   mp->is_ipv6 = is_ipv6;
6651   mp->vrf_id = ntohl (vrf_id);
6652
6653   /* send it... */
6654   S (mp);
6655
6656   /* Wait for a reply... */
6657   W (ret);
6658   return ret;
6659 }
6660
6661 static void vl_api_sw_interface_get_table_reply_t_handler
6662   (vl_api_sw_interface_get_table_reply_t * mp)
6663 {
6664   vat_main_t *vam = &vat_main;
6665
6666   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6667
6668   vam->retval = ntohl (mp->retval);
6669   vam->result_ready = 1;
6670
6671 }
6672
6673 static void vl_api_sw_interface_get_table_reply_t_handler_json
6674   (vl_api_sw_interface_get_table_reply_t * mp)
6675 {
6676   vat_main_t *vam = &vat_main;
6677   vat_json_node_t node;
6678
6679   vat_json_init_object (&node);
6680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6681   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6682
6683   vat_json_print (vam->ofp, &node);
6684   vat_json_free (&node);
6685
6686   vam->retval = ntohl (mp->retval);
6687   vam->result_ready = 1;
6688 }
6689
6690 static int
6691 api_sw_interface_get_table (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_sw_interface_get_table_t *mp;
6695   u32 sw_if_index;
6696   u8 sw_if_index_set = 0;
6697   u8 is_ipv6 = 0;
6698   int ret;
6699
6700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6701     {
6702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6705         sw_if_index_set = 1;
6706       else if (unformat (i, "ipv6"))
6707         is_ipv6 = 1;
6708       else
6709         break;
6710     }
6711
6712   if (sw_if_index_set == 0)
6713     {
6714       errmsg ("missing interface name or sw_if_index");
6715       return -99;
6716     }
6717
6718   M (SW_INTERFACE_GET_TABLE, mp);
6719   mp->sw_if_index = htonl (sw_if_index);
6720   mp->is_ipv6 = is_ipv6;
6721
6722   S (mp);
6723   W (ret);
6724   return ret;
6725 }
6726
6727 static int
6728 api_sw_interface_set_vpath (vat_main_t * vam)
6729 {
6730   unformat_input_t *i = vam->input;
6731   vl_api_sw_interface_set_vpath_t *mp;
6732   u32 sw_if_index = 0;
6733   u8 sw_if_index_set = 0;
6734   u8 is_enable = 0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6743         sw_if_index_set = 1;
6744       else if (unformat (i, "enable"))
6745         is_enable = 1;
6746       else if (unformat (i, "disable"))
6747         is_enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (sw_if_index_set == 0)
6753     {
6754       errmsg ("missing interface name or sw_if_index");
6755       return -99;
6756     }
6757
6758   /* Construct the API message */
6759   M (SW_INTERFACE_SET_VPATH, mp);
6760
6761   mp->sw_if_index = ntohl (sw_if_index);
6762   mp->enable = is_enable;
6763
6764   /* send it... */
6765   S (mp);
6766
6767   /* Wait for a reply... */
6768   W (ret);
6769   return ret;
6770 }
6771
6772 static int
6773 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6777   u32 sw_if_index = 0;
6778   u8 sw_if_index_set = 0;
6779   u8 is_enable = 1;
6780   u8 is_ipv6 = 0;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6787         sw_if_index_set = 1;
6788       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6789         sw_if_index_set = 1;
6790       else if (unformat (i, "enable"))
6791         is_enable = 1;
6792       else if (unformat (i, "disable"))
6793         is_enable = 0;
6794       else if (unformat (i, "ip4"))
6795         is_ipv6 = 0;
6796       else if (unformat (i, "ip6"))
6797         is_ipv6 = 1;
6798       else
6799         break;
6800     }
6801
6802   if (sw_if_index_set == 0)
6803     {
6804       errmsg ("missing interface name or sw_if_index");
6805       return -99;
6806     }
6807
6808   /* Construct the API message */
6809   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6810
6811   mp->sw_if_index = ntohl (sw_if_index);
6812   mp->enable = is_enable;
6813   mp->is_ipv6 = is_ipv6;
6814
6815   /* send it... */
6816   S (mp);
6817
6818   /* Wait for a reply... */
6819   W (ret);
6820   return ret;
6821 }
6822
6823 static int
6824 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_sw_interface_set_geneve_bypass_t *mp;
6828   u32 sw_if_index = 0;
6829   u8 sw_if_index_set = 0;
6830   u8 is_enable = 1;
6831   u8 is_ipv6 = 0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "enable"))
6842         is_enable = 1;
6843       else if (unformat (i, "disable"))
6844         is_enable = 0;
6845       else if (unformat (i, "ip4"))
6846         is_ipv6 = 0;
6847       else if (unformat (i, "ip6"))
6848         is_ipv6 = 1;
6849       else
6850         break;
6851     }
6852
6853   if (sw_if_index_set == 0)
6854     {
6855       errmsg ("missing interface name or sw_if_index");
6856       return -99;
6857     }
6858
6859   /* Construct the API message */
6860   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6861
6862   mp->sw_if_index = ntohl (sw_if_index);
6863   mp->enable = is_enable;
6864   mp->is_ipv6 = is_ipv6;
6865
6866   /* send it... */
6867   S (mp);
6868
6869   /* Wait for a reply... */
6870   W (ret);
6871   return ret;
6872 }
6873
6874 static int
6875 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6876 {
6877   unformat_input_t *i = vam->input;
6878   vl_api_sw_interface_set_l2_xconnect_t *mp;
6879   u32 rx_sw_if_index;
6880   u8 rx_sw_if_index_set = 0;
6881   u32 tx_sw_if_index;
6882   u8 tx_sw_if_index_set = 0;
6883   u8 enable = 1;
6884   int ret;
6885
6886   /* Parse args required to build the message */
6887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6888     {
6889       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6890         rx_sw_if_index_set = 1;
6891       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6892         tx_sw_if_index_set = 1;
6893       else if (unformat (i, "rx"))
6894         {
6895           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896             {
6897               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6898                             &rx_sw_if_index))
6899                 rx_sw_if_index_set = 1;
6900             }
6901           else
6902             break;
6903         }
6904       else if (unformat (i, "tx"))
6905         {
6906           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907             {
6908               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6909                             &tx_sw_if_index))
6910                 tx_sw_if_index_set = 1;
6911             }
6912           else
6913             break;
6914         }
6915       else if (unformat (i, "enable"))
6916         enable = 1;
6917       else if (unformat (i, "disable"))
6918         enable = 0;
6919       else
6920         break;
6921     }
6922
6923   if (rx_sw_if_index_set == 0)
6924     {
6925       errmsg ("missing rx interface name or rx_sw_if_index");
6926       return -99;
6927     }
6928
6929   if (enable && (tx_sw_if_index_set == 0))
6930     {
6931       errmsg ("missing tx interface name or tx_sw_if_index");
6932       return -99;
6933     }
6934
6935   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6936
6937   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6938   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6939   mp->enable = enable;
6940
6941   S (mp);
6942   W (ret);
6943   return ret;
6944 }
6945
6946 static int
6947 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6948 {
6949   unformat_input_t *i = vam->input;
6950   vl_api_sw_interface_set_l2_bridge_t *mp;
6951   u32 rx_sw_if_index;
6952   u8 rx_sw_if_index_set = 0;
6953   u32 bd_id;
6954   u8 bd_id_set = 0;
6955   u8 bvi = 0;
6956   u32 shg = 0;
6957   u8 enable = 1;
6958   int ret;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6964         rx_sw_if_index_set = 1;
6965       else if (unformat (i, "bd_id %d", &bd_id))
6966         bd_id_set = 1;
6967       else
6968         if (unformat
6969             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6970         rx_sw_if_index_set = 1;
6971       else if (unformat (i, "shg %d", &shg))
6972         ;
6973       else if (unformat (i, "bvi"))
6974         bvi = 1;
6975       else if (unformat (i, "enable"))
6976         enable = 1;
6977       else if (unformat (i, "disable"))
6978         enable = 0;
6979       else
6980         break;
6981     }
6982
6983   if (rx_sw_if_index_set == 0)
6984     {
6985       errmsg ("missing rx interface name or sw_if_index");
6986       return -99;
6987     }
6988
6989   if (enable && (bd_id_set == 0))
6990     {
6991       errmsg ("missing bridge domain");
6992       return -99;
6993     }
6994
6995   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6996
6997   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6998   mp->bd_id = ntohl (bd_id);
6999   mp->shg = (u8) shg;
7000   mp->bvi = bvi;
7001   mp->enable = enable;
7002
7003   S (mp);
7004   W (ret);
7005   return ret;
7006 }
7007
7008 static int
7009 api_bridge_domain_dump (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_bridge_domain_dump_t *mp;
7013   vl_api_control_ping_t *mp_ping;
7014   u32 bd_id = ~0;
7015   int ret;
7016
7017   /* Parse args required to build the message */
7018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7019     {
7020       if (unformat (i, "bd_id %d", &bd_id))
7021         ;
7022       else
7023         break;
7024     }
7025
7026   M (BRIDGE_DOMAIN_DUMP, mp);
7027   mp->bd_id = ntohl (bd_id);
7028   S (mp);
7029
7030   /* Use a control ping for synchronization */
7031   MPING (CONTROL_PING, mp_ping);
7032   S (mp_ping);
7033
7034   W (ret);
7035   return ret;
7036 }
7037
7038 static int
7039 api_bridge_domain_add_del (vat_main_t * vam)
7040 {
7041   unformat_input_t *i = vam->input;
7042   vl_api_bridge_domain_add_del_t *mp;
7043   u32 bd_id = ~0;
7044   u8 is_add = 1;
7045   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7046   u8 *bd_tag = NULL;
7047   u32 mac_age = 0;
7048   int ret;
7049
7050   /* Parse args required to build the message */
7051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7052     {
7053       if (unformat (i, "bd_id %d", &bd_id))
7054         ;
7055       else if (unformat (i, "flood %d", &flood))
7056         ;
7057       else if (unformat (i, "uu-flood %d", &uu_flood))
7058         ;
7059       else if (unformat (i, "forward %d", &forward))
7060         ;
7061       else if (unformat (i, "learn %d", &learn))
7062         ;
7063       else if (unformat (i, "arp-term %d", &arp_term))
7064         ;
7065       else if (unformat (i, "mac-age %d", &mac_age))
7066         ;
7067       else if (unformat (i, "bd-tag %s", &bd_tag))
7068         ;
7069       else if (unformat (i, "del"))
7070         {
7071           is_add = 0;
7072           flood = uu_flood = forward = learn = 0;
7073         }
7074       else
7075         break;
7076     }
7077
7078   if (bd_id == ~0)
7079     {
7080       errmsg ("missing bridge domain");
7081       ret = -99;
7082       goto done;
7083     }
7084
7085   if (mac_age > 255)
7086     {
7087       errmsg ("mac age must be less than 256 ");
7088       ret = -99;
7089       goto done;
7090     }
7091
7092   if ((bd_tag) && (vec_len (bd_tag) > 63))
7093     {
7094       errmsg ("bd-tag cannot be longer than 63");
7095       ret = -99;
7096       goto done;
7097     }
7098
7099   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7100
7101   mp->bd_id = ntohl (bd_id);
7102   mp->flood = flood;
7103   mp->uu_flood = uu_flood;
7104   mp->forward = forward;
7105   mp->learn = learn;
7106   mp->arp_term = arp_term;
7107   mp->is_add = is_add;
7108   mp->mac_age = (u8) mac_age;
7109   if (bd_tag)
7110     {
7111       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7112       mp->bd_tag[vec_len (bd_tag)] = 0;
7113     }
7114   S (mp);
7115   W (ret);
7116
7117 done:
7118   vec_free (bd_tag);
7119   return ret;
7120 }
7121
7122 static int
7123 api_l2fib_flush_bd (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_l2fib_flush_bd_t *mp;
7127   u32 bd_id = ~0;
7128   int ret;
7129
7130   /* Parse args required to build the message */
7131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7132     {
7133       if (unformat (i, "bd_id %d", &bd_id));
7134       else
7135         break;
7136     }
7137
7138   if (bd_id == ~0)
7139     {
7140       errmsg ("missing bridge domain");
7141       return -99;
7142     }
7143
7144   M (L2FIB_FLUSH_BD, mp);
7145
7146   mp->bd_id = htonl (bd_id);
7147
7148   S (mp);
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_l2fib_flush_int (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_l2fib_flush_int_t *mp;
7158   u32 sw_if_index = ~0;
7159   int ret;
7160
7161   /* Parse args required to build the message */
7162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7163     {
7164       if (unformat (i, "sw_if_index %d", &sw_if_index));
7165       else
7166         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7167       else
7168         break;
7169     }
7170
7171   if (sw_if_index == ~0)
7172     {
7173       errmsg ("missing interface name or sw_if_index");
7174       return -99;
7175     }
7176
7177   M (L2FIB_FLUSH_INT, mp);
7178
7179   mp->sw_if_index = ntohl (sw_if_index);
7180
7181   S (mp);
7182   W (ret);
7183   return ret;
7184 }
7185
7186 static int
7187 api_l2fib_add_del (vat_main_t * vam)
7188 {
7189   unformat_input_t *i = vam->input;
7190   vl_api_l2fib_add_del_t *mp;
7191   f64 timeout;
7192   u8 mac[6] = { 0 };
7193   u8 mac_set = 0;
7194   u32 bd_id;
7195   u8 bd_id_set = 0;
7196   u32 sw_if_index = ~0;
7197   u8 sw_if_index_set = 0;
7198   u8 is_add = 1;
7199   u8 static_mac = 0;
7200   u8 filter_mac = 0;
7201   u8 bvi_mac = 0;
7202   int count = 1;
7203   f64 before = 0;
7204   int j;
7205
7206   /* Parse args required to build the message */
7207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7208     {
7209       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7210         mac_set = 1;
7211       else if (unformat (i, "bd_id %d", &bd_id))
7212         bd_id_set = 1;
7213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7214         sw_if_index_set = 1;
7215       else if (unformat (i, "sw_if"))
7216         {
7217           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218             {
7219               if (unformat
7220                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7221                 sw_if_index_set = 1;
7222             }
7223           else
7224             break;
7225         }
7226       else if (unformat (i, "static"))
7227         static_mac = 1;
7228       else if (unformat (i, "filter"))
7229         {
7230           filter_mac = 1;
7231           static_mac = 1;
7232         }
7233       else if (unformat (i, "bvi"))
7234         {
7235           bvi_mac = 1;
7236           static_mac = 1;
7237         }
7238       else if (unformat (i, "del"))
7239         is_add = 0;
7240       else if (unformat (i, "count %d", &count))
7241         ;
7242       else
7243         break;
7244     }
7245
7246   if (mac_set == 0)
7247     {
7248       errmsg ("missing mac address");
7249       return -99;
7250     }
7251
7252   if (bd_id_set == 0)
7253     {
7254       errmsg ("missing bridge domain");
7255       return -99;
7256     }
7257
7258   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7259     {
7260       errmsg ("missing interface name or sw_if_index");
7261       return -99;
7262     }
7263
7264   if (count > 1)
7265     {
7266       /* Turn on async mode */
7267       vam->async_mode = 1;
7268       vam->async_errors = 0;
7269       before = vat_time_now (vam);
7270     }
7271
7272   for (j = 0; j < count; j++)
7273     {
7274       M (L2FIB_ADD_DEL, mp);
7275
7276       clib_memcpy (mp->mac, mac, 6);
7277       mp->bd_id = ntohl (bd_id);
7278       mp->is_add = is_add;
7279
7280       if (is_add)
7281         {
7282           mp->sw_if_index = ntohl (sw_if_index);
7283           mp->static_mac = static_mac;
7284           mp->filter_mac = filter_mac;
7285           mp->bvi_mac = bvi_mac;
7286         }
7287       increment_mac_address (mac);
7288       /* send it... */
7289       S (mp);
7290     }
7291
7292   if (count > 1)
7293     {
7294       vl_api_control_ping_t *mp_ping;
7295       f64 after;
7296
7297       /* Shut off async mode */
7298       vam->async_mode = 0;
7299
7300       MPING (CONTROL_PING, mp_ping);
7301       S (mp_ping);
7302
7303       timeout = vat_time_now (vam) + 1.0;
7304       while (vat_time_now (vam) < timeout)
7305         if (vam->result_ready == 1)
7306           goto out;
7307       vam->retval = -99;
7308
7309     out:
7310       if (vam->retval == -99)
7311         errmsg ("timeout");
7312
7313       if (vam->async_errors > 0)
7314         {
7315           errmsg ("%d asynchronous errors", vam->async_errors);
7316           vam->retval = -98;
7317         }
7318       vam->async_errors = 0;
7319       after = vat_time_now (vam);
7320
7321       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7322              count, after - before, count / (after - before));
7323     }
7324   else
7325     {
7326       int ret;
7327
7328       /* Wait for a reply... */
7329       W (ret);
7330       return ret;
7331     }
7332   /* Return the good/bad news */
7333   return (vam->retval);
7334 }
7335
7336 static int
7337 api_bridge_domain_set_mac_age (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_bridge_domain_set_mac_age_t *mp;
7341   u32 bd_id = ~0;
7342   u32 mac_age = 0;
7343   int ret;
7344
7345   /* Parse args required to build the message */
7346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7347     {
7348       if (unformat (i, "bd_id %d", &bd_id));
7349       else if (unformat (i, "mac-age %d", &mac_age));
7350       else
7351         break;
7352     }
7353
7354   if (bd_id == ~0)
7355     {
7356       errmsg ("missing bridge domain");
7357       return -99;
7358     }
7359
7360   if (mac_age > 255)
7361     {
7362       errmsg ("mac age must be less than 256 ");
7363       return -99;
7364     }
7365
7366   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7367
7368   mp->bd_id = htonl (bd_id);
7369   mp->mac_age = (u8) mac_age;
7370
7371   S (mp);
7372   W (ret);
7373   return ret;
7374 }
7375
7376 static int
7377 api_l2_flags (vat_main_t * vam)
7378 {
7379   unformat_input_t *i = vam->input;
7380   vl_api_l2_flags_t *mp;
7381   u32 sw_if_index;
7382   u32 flags = 0;
7383   u8 sw_if_index_set = 0;
7384   u8 is_set = 0;
7385   int ret;
7386
7387   /* Parse args required to build the message */
7388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389     {
7390       if (unformat (i, "sw_if_index %d", &sw_if_index))
7391         sw_if_index_set = 1;
7392       else if (unformat (i, "sw_if"))
7393         {
7394           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395             {
7396               if (unformat
7397                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7398                 sw_if_index_set = 1;
7399             }
7400           else
7401             break;
7402         }
7403       else if (unformat (i, "learn"))
7404         flags |= L2_LEARN;
7405       else if (unformat (i, "forward"))
7406         flags |= L2_FWD;
7407       else if (unformat (i, "flood"))
7408         flags |= L2_FLOOD;
7409       else if (unformat (i, "uu-flood"))
7410         flags |= L2_UU_FLOOD;
7411       else if (unformat (i, "arp-term"))
7412         flags |= L2_ARP_TERM;
7413       else if (unformat (i, "off"))
7414         is_set = 0;
7415       else if (unformat (i, "disable"))
7416         is_set = 0;
7417       else
7418         break;
7419     }
7420
7421   if (sw_if_index_set == 0)
7422     {
7423       errmsg ("missing interface name or sw_if_index");
7424       return -99;
7425     }
7426
7427   M (L2_FLAGS, mp);
7428
7429   mp->sw_if_index = ntohl (sw_if_index);
7430   mp->feature_bitmap = ntohl (flags);
7431   mp->is_set = is_set;
7432
7433   S (mp);
7434   W (ret);
7435   return ret;
7436 }
7437
7438 static int
7439 api_bridge_flags (vat_main_t * vam)
7440 {
7441   unformat_input_t *i = vam->input;
7442   vl_api_bridge_flags_t *mp;
7443   u32 bd_id;
7444   u8 bd_id_set = 0;
7445   u8 is_set = 1;
7446   u32 flags = 0;
7447   int ret;
7448
7449   /* Parse args required to build the message */
7450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7451     {
7452       if (unformat (i, "bd_id %d", &bd_id))
7453         bd_id_set = 1;
7454       else if (unformat (i, "learn"))
7455         flags |= L2_LEARN;
7456       else if (unformat (i, "forward"))
7457         flags |= L2_FWD;
7458       else if (unformat (i, "flood"))
7459         flags |= L2_FLOOD;
7460       else if (unformat (i, "uu-flood"))
7461         flags |= L2_UU_FLOOD;
7462       else if (unformat (i, "arp-term"))
7463         flags |= L2_ARP_TERM;
7464       else if (unformat (i, "off"))
7465         is_set = 0;
7466       else if (unformat (i, "disable"))
7467         is_set = 0;
7468       else
7469         break;
7470     }
7471
7472   if (bd_id_set == 0)
7473     {
7474       errmsg ("missing bridge domain");
7475       return -99;
7476     }
7477
7478   M (BRIDGE_FLAGS, mp);
7479
7480   mp->bd_id = ntohl (bd_id);
7481   mp->feature_bitmap = ntohl (flags);
7482   mp->is_set = is_set;
7483
7484   S (mp);
7485   W (ret);
7486   return ret;
7487 }
7488
7489 static int
7490 api_bd_ip_mac_add_del (vat_main_t * vam)
7491 {
7492   unformat_input_t *i = vam->input;
7493   vl_api_bd_ip_mac_add_del_t *mp;
7494   u32 bd_id;
7495   u8 is_ipv6 = 0;
7496   u8 is_add = 1;
7497   u8 bd_id_set = 0;
7498   u8 ip_set = 0;
7499   u8 mac_set = 0;
7500   ip4_address_t v4addr;
7501   ip6_address_t v6addr;
7502   u8 macaddr[6];
7503   int ret;
7504
7505
7506   /* Parse args required to build the message */
7507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7508     {
7509       if (unformat (i, "bd_id %d", &bd_id))
7510         {
7511           bd_id_set++;
7512         }
7513       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7514         {
7515           ip_set++;
7516         }
7517       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7518         {
7519           ip_set++;
7520           is_ipv6++;
7521         }
7522       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7523         {
7524           mac_set++;
7525         }
7526       else if (unformat (i, "del"))
7527         is_add = 0;
7528       else
7529         break;
7530     }
7531
7532   if (bd_id_set == 0)
7533     {
7534       errmsg ("missing bridge domain");
7535       return -99;
7536     }
7537   else if (ip_set == 0)
7538     {
7539       errmsg ("missing IP address");
7540       return -99;
7541     }
7542   else if (mac_set == 0)
7543     {
7544       errmsg ("missing MAC address");
7545       return -99;
7546     }
7547
7548   M (BD_IP_MAC_ADD_DEL, mp);
7549
7550   mp->bd_id = ntohl (bd_id);
7551   mp->is_ipv6 = is_ipv6;
7552   mp->is_add = is_add;
7553   if (is_ipv6)
7554     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7555   else
7556     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7557   clib_memcpy (mp->mac_address, macaddr, 6);
7558   S (mp);
7559   W (ret);
7560   return ret;
7561 }
7562
7563 static int
7564 api_tap_connect (vat_main_t * vam)
7565 {
7566   unformat_input_t *i = vam->input;
7567   vl_api_tap_connect_t *mp;
7568   u8 mac_address[6];
7569   u8 random_mac = 1;
7570   u8 name_set = 0;
7571   u8 *tap_name;
7572   u8 *tag = 0;
7573   ip4_address_t ip4_address;
7574   u32 ip4_mask_width;
7575   int ip4_address_set = 0;
7576   ip6_address_t ip6_address;
7577   u32 ip6_mask_width;
7578   int ip6_address_set = 0;
7579   int ret;
7580
7581   memset (mac_address, 0, sizeof (mac_address));
7582
7583   /* Parse args required to build the message */
7584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7585     {
7586       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7587         {
7588           random_mac = 0;
7589         }
7590       else if (unformat (i, "random-mac"))
7591         random_mac = 1;
7592       else if (unformat (i, "tapname %s", &tap_name))
7593         name_set = 1;
7594       else if (unformat (i, "tag %s", &tag))
7595         ;
7596       else if (unformat (i, "address %U/%d",
7597                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7598         ip4_address_set = 1;
7599       else if (unformat (i, "address %U/%d",
7600                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7601         ip6_address_set = 1;
7602       else
7603         break;
7604     }
7605
7606   if (name_set == 0)
7607     {
7608       errmsg ("missing tap name");
7609       return -99;
7610     }
7611   if (vec_len (tap_name) > 63)
7612     {
7613       errmsg ("tap name too long");
7614       return -99;
7615     }
7616   vec_add1 (tap_name, 0);
7617
7618   if (vec_len (tag) > 63)
7619     {
7620       errmsg ("tag too long");
7621       return -99;
7622     }
7623
7624   /* Construct the API message */
7625   M (TAP_CONNECT, mp);
7626
7627   mp->use_random_mac = random_mac;
7628   clib_memcpy (mp->mac_address, mac_address, 6);
7629   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7630   if (tag)
7631     clib_memcpy (mp->tag, tag, vec_len (tag));
7632
7633   if (ip4_address_set)
7634     {
7635       mp->ip4_address_set = 1;
7636       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7637       mp->ip4_mask_width = ip4_mask_width;
7638     }
7639   if (ip6_address_set)
7640     {
7641       mp->ip6_address_set = 1;
7642       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7643       mp->ip6_mask_width = ip6_mask_width;
7644     }
7645
7646   vec_free (tap_name);
7647   vec_free (tag);
7648
7649   /* send it... */
7650   S (mp);
7651
7652   /* Wait for a reply... */
7653   W (ret);
7654   return ret;
7655 }
7656
7657 static int
7658 api_tap_modify (vat_main_t * vam)
7659 {
7660   unformat_input_t *i = vam->input;
7661   vl_api_tap_modify_t *mp;
7662   u8 mac_address[6];
7663   u8 random_mac = 1;
7664   u8 name_set = 0;
7665   u8 *tap_name;
7666   u32 sw_if_index = ~0;
7667   u8 sw_if_index_set = 0;
7668   int ret;
7669
7670   memset (mac_address, 0, sizeof (mac_address));
7671
7672   /* Parse args required to build the message */
7673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7674     {
7675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7676         sw_if_index_set = 1;
7677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7678         sw_if_index_set = 1;
7679       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7680         {
7681           random_mac = 0;
7682         }
7683       else if (unformat (i, "random-mac"))
7684         random_mac = 1;
7685       else if (unformat (i, "tapname %s", &tap_name))
7686         name_set = 1;
7687       else
7688         break;
7689     }
7690
7691   if (sw_if_index_set == 0)
7692     {
7693       errmsg ("missing vpp interface name");
7694       return -99;
7695     }
7696   if (name_set == 0)
7697     {
7698       errmsg ("missing tap name");
7699       return -99;
7700     }
7701   if (vec_len (tap_name) > 63)
7702     {
7703       errmsg ("tap name too long");
7704     }
7705   vec_add1 (tap_name, 0);
7706
7707   /* Construct the API message */
7708   M (TAP_MODIFY, mp);
7709
7710   mp->use_random_mac = random_mac;
7711   mp->sw_if_index = ntohl (sw_if_index);
7712   clib_memcpy (mp->mac_address, mac_address, 6);
7713   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7714   vec_free (tap_name);
7715
7716   /* send it... */
7717   S (mp);
7718
7719   /* Wait for a reply... */
7720   W (ret);
7721   return ret;
7722 }
7723
7724 static int
7725 api_tap_delete (vat_main_t * vam)
7726 {
7727   unformat_input_t *i = vam->input;
7728   vl_api_tap_delete_t *mp;
7729   u32 sw_if_index = ~0;
7730   u8 sw_if_index_set = 0;
7731   int ret;
7732
7733   /* Parse args required to build the message */
7734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7735     {
7736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7737         sw_if_index_set = 1;
7738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7739         sw_if_index_set = 1;
7740       else
7741         break;
7742     }
7743
7744   if (sw_if_index_set == 0)
7745     {
7746       errmsg ("missing vpp interface name");
7747       return -99;
7748     }
7749
7750   /* Construct the API message */
7751   M (TAP_DELETE, mp);
7752
7753   mp->sw_if_index = ntohl (sw_if_index);
7754
7755   /* send it... */
7756   S (mp);
7757
7758   /* Wait for a reply... */
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_tap_create_v2 (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_tap_create_v2_t *mp;
7768   u8 mac_address[6];
7769   u8 random_mac = 1;
7770   u32 id = ~0;
7771   u8 *host_if_name = 0;
7772   u8 *host_ns = 0;
7773   u8 host_mac_addr[6];
7774   u8 host_mac_addr_set = 0;
7775   u8 *host_bridge = 0;
7776   ip4_address_t host_ip4_addr;
7777   ip4_address_t host_ip4_gw;
7778   u8 host_ip4_gw_set = 0;
7779   u32 host_ip4_prefix_len = 0;
7780   ip6_address_t host_ip6_addr;
7781   ip6_address_t host_ip6_gw;
7782   u8 host_ip6_gw_set = 0;
7783   u32 host_ip6_prefix_len = 0;
7784   int ret;
7785   int rx_ring_sz = 0, tx_ring_sz = 0;
7786
7787   memset (mac_address, 0, sizeof (mac_address));
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7793         {
7794           random_mac = 0;
7795         }
7796       else if (unformat (i, "id %s", &id))
7797         ;
7798       else if (unformat (i, "host-if-name %s", &host_if_name))
7799         ;
7800       else if (unformat (i, "host-ns %s", &host_ns))
7801         ;
7802       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7803                          host_mac_addr))
7804         host_mac_addr_set = 1;
7805       else if (unformat (i, "host-bridge %s", &host_bridge))
7806         ;
7807       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7808                          &host_ip4_addr, &host_ip4_prefix_len))
7809         ;
7810       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7811                          &host_ip6_addr, &host_ip6_prefix_len))
7812         ;
7813       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7814                          &host_ip4_gw))
7815         host_ip4_gw_set = 1;
7816       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7817                          &host_ip6_gw))
7818         host_ip6_gw_set = 1;
7819       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7820         ;
7821       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7822         ;
7823       else
7824         break;
7825     }
7826
7827   if (vec_len (host_if_name) > 63)
7828     {
7829       errmsg ("tap name too long. ");
7830       return -99;
7831     }
7832   if (vec_len (host_ns) > 63)
7833     {
7834       errmsg ("host name space too long. ");
7835       return -99;
7836     }
7837   if (vec_len (host_bridge) > 63)
7838     {
7839       errmsg ("host bridge name too long. ");
7840       return -99;
7841     }
7842   if (host_ip4_prefix_len > 32)
7843     {
7844       errmsg ("host ip4 prefix length not valid. ");
7845       return -99;
7846     }
7847   if (host_ip6_prefix_len > 128)
7848     {
7849       errmsg ("host ip6 prefix length not valid. ");
7850       return -99;
7851     }
7852   if (!is_pow2 (rx_ring_sz))
7853     {
7854       errmsg ("rx ring size must be power of 2. ");
7855       return -99;
7856     }
7857   if (rx_ring_sz > 32768)
7858     {
7859       errmsg ("rx ring size must be 32768 or lower. ");
7860       return -99;
7861     }
7862   if (!is_pow2 (tx_ring_sz))
7863     {
7864       errmsg ("tx ring size must be power of 2. ");
7865       return -99;
7866     }
7867   if (tx_ring_sz > 32768)
7868     {
7869       errmsg ("tx ring size must be 32768 or lower. ");
7870       return -99;
7871     }
7872
7873   /* Construct the API message */
7874   M (TAP_CREATE_V2, mp);
7875
7876   mp->use_random_mac = random_mac;
7877
7878   mp->id = id;
7879   mp->host_namespace_set = host_ns != 0;
7880   mp->host_bridge_set = host_bridge != 0;
7881   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7882   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7883   mp->rx_ring_sz = rx_ring_sz;
7884   mp->tx_ring_sz = tx_ring_sz;
7885
7886   if (random_mac)
7887     clib_memcpy (mp->mac_address, mac_address, 6);
7888   if (host_mac_addr_set)
7889     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7890   if (host_if_name)
7891     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7892   if (host_ns)
7893     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7894   if (host_bridge)
7895     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7896   if (host_ip4_prefix_len)
7897     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7898   if (host_ip4_prefix_len)
7899     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7900   if (host_ip4_gw_set)
7901     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7902   if (host_ip6_gw_set)
7903     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7904
7905   vec_free (host_ns);
7906   vec_free (host_if_name);
7907   vec_free (host_bridge);
7908
7909   /* send it... */
7910   S (mp);
7911
7912   /* Wait for a reply... */
7913   W (ret);
7914   return ret;
7915 }
7916
7917 static int
7918 api_tap_delete_v2 (vat_main_t * vam)
7919 {
7920   unformat_input_t *i = vam->input;
7921   vl_api_tap_delete_v2_t *mp;
7922   u32 sw_if_index = ~0;
7923   u8 sw_if_index_set = 0;
7924   int ret;
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7930         sw_if_index_set = 1;
7931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7932         sw_if_index_set = 1;
7933       else
7934         break;
7935     }
7936
7937   if (sw_if_index_set == 0)
7938     {
7939       errmsg ("missing vpp interface name. ");
7940       return -99;
7941     }
7942
7943   /* Construct the API message */
7944   M (TAP_DELETE_V2, mp);
7945
7946   mp->sw_if_index = ntohl (sw_if_index);
7947
7948   /* send it... */
7949   S (mp);
7950
7951   /* Wait for a reply... */
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_ip_table_add_del (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_ip_table_add_del_t *mp;
7961   u32 table_id = ~0;
7962   u8 is_ipv6 = 0;
7963   u8 is_add = 1;
7964   int ret = 0;
7965
7966   /* Parse args required to build the message */
7967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (i, "ipv6"))
7970         is_ipv6 = 1;
7971       else if (unformat (i, "del"))
7972         is_add = 0;
7973       else if (unformat (i, "add"))
7974         is_add = 1;
7975       else if (unformat (i, "table %d", &table_id))
7976         ;
7977       else
7978         {
7979           clib_warning ("parse error '%U'", format_unformat_error, i);
7980           return -99;
7981         }
7982     }
7983
7984   if (~0 == table_id)
7985     {
7986       errmsg ("missing table-ID");
7987       return -99;
7988     }
7989
7990   /* Construct the API message */
7991   M (IP_TABLE_ADD_DEL, mp);
7992
7993   mp->table_id = ntohl (table_id);
7994   mp->is_ipv6 = is_ipv6;
7995   mp->is_add = is_add;
7996
7997   /* send it... */
7998   S (mp);
7999
8000   /* Wait for a reply... */
8001   W (ret);
8002
8003   return ret;
8004 }
8005
8006 static int
8007 api_ip_add_del_route (vat_main_t * vam)
8008 {
8009   unformat_input_t *i = vam->input;
8010   vl_api_ip_add_del_route_t *mp;
8011   u32 sw_if_index = ~0, vrf_id = 0;
8012   u8 is_ipv6 = 0;
8013   u8 is_local = 0, is_drop = 0;
8014   u8 is_unreach = 0, is_prohibit = 0;
8015   u8 is_add = 1;
8016   u32 next_hop_weight = 1;
8017   u8 is_multipath = 0;
8018   u8 address_set = 0;
8019   u8 address_length_set = 0;
8020   u32 next_hop_table_id = 0;
8021   u32 resolve_attempts = 0;
8022   u32 dst_address_length = 0;
8023   u8 next_hop_set = 0;
8024   ip4_address_t v4_dst_address, v4_next_hop_address;
8025   ip6_address_t v6_dst_address, v6_next_hop_address;
8026   int count = 1;
8027   int j;
8028   f64 before = 0;
8029   u32 random_add_del = 0;
8030   u32 *random_vector = 0;
8031   uword *random_hash;
8032   u32 random_seed = 0xdeaddabe;
8033   u32 classify_table_index = ~0;
8034   u8 is_classify = 0;
8035   u8 resolve_host = 0, resolve_attached = 0;
8036   mpls_label_t *next_hop_out_label_stack = NULL;
8037   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8038   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8039
8040   /* Parse args required to build the message */
8041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8042     {
8043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8044         ;
8045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8046         ;
8047       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8048         {
8049           address_set = 1;
8050           is_ipv6 = 0;
8051         }
8052       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8053         {
8054           address_set = 1;
8055           is_ipv6 = 1;
8056         }
8057       else if (unformat (i, "/%d", &dst_address_length))
8058         {
8059           address_length_set = 1;
8060         }
8061
8062       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8063                                          &v4_next_hop_address))
8064         {
8065           next_hop_set = 1;
8066         }
8067       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8068                                          &v6_next_hop_address))
8069         {
8070           next_hop_set = 1;
8071         }
8072       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8073         ;
8074       else if (unformat (i, "weight %d", &next_hop_weight))
8075         ;
8076       else if (unformat (i, "drop"))
8077         {
8078           is_drop = 1;
8079         }
8080       else if (unformat (i, "null-send-unreach"))
8081         {
8082           is_unreach = 1;
8083         }
8084       else if (unformat (i, "null-send-prohibit"))
8085         {
8086           is_prohibit = 1;
8087         }
8088       else if (unformat (i, "local"))
8089         {
8090           is_local = 1;
8091         }
8092       else if (unformat (i, "classify %d", &classify_table_index))
8093         {
8094           is_classify = 1;
8095         }
8096       else if (unformat (i, "del"))
8097         is_add = 0;
8098       else if (unformat (i, "add"))
8099         is_add = 1;
8100       else if (unformat (i, "resolve-via-host"))
8101         resolve_host = 1;
8102       else if (unformat (i, "resolve-via-attached"))
8103         resolve_attached = 1;
8104       else if (unformat (i, "multipath"))
8105         is_multipath = 1;
8106       else if (unformat (i, "vrf %d", &vrf_id))
8107         ;
8108       else if (unformat (i, "count %d", &count))
8109         ;
8110       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8111         ;
8112       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8113         ;
8114       else if (unformat (i, "out-label %d", &next_hop_out_label))
8115         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8116       else if (unformat (i, "via-label %d", &next_hop_via_label))
8117         ;
8118       else if (unformat (i, "random"))
8119         random_add_del = 1;
8120       else if (unformat (i, "seed %d", &random_seed))
8121         ;
8122       else
8123         {
8124           clib_warning ("parse error '%U'", format_unformat_error, i);
8125           return -99;
8126         }
8127     }
8128
8129   if (!next_hop_set && !is_drop && !is_local &&
8130       !is_classify && !is_unreach && !is_prohibit &&
8131       MPLS_LABEL_INVALID == next_hop_via_label)
8132     {
8133       errmsg
8134         ("next hop / local / drop / unreach / prohibit / classify not set");
8135       return -99;
8136     }
8137
8138   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8139     {
8140       errmsg ("next hop and next-hop via label set");
8141       return -99;
8142     }
8143   if (address_set == 0)
8144     {
8145       errmsg ("missing addresses");
8146       return -99;
8147     }
8148
8149   if (address_length_set == 0)
8150     {
8151       errmsg ("missing address length");
8152       return -99;
8153     }
8154
8155   /* Generate a pile of unique, random routes */
8156   if (random_add_del)
8157     {
8158       u32 this_random_address;
8159       random_hash = hash_create (count, sizeof (uword));
8160
8161       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8162       for (j = 0; j <= count; j++)
8163         {
8164           do
8165             {
8166               this_random_address = random_u32 (&random_seed);
8167               this_random_address =
8168                 clib_host_to_net_u32 (this_random_address);
8169             }
8170           while (hash_get (random_hash, this_random_address));
8171           vec_add1 (random_vector, this_random_address);
8172           hash_set (random_hash, this_random_address, 1);
8173         }
8174       hash_free (random_hash);
8175       v4_dst_address.as_u32 = random_vector[0];
8176     }
8177
8178   if (count > 1)
8179     {
8180       /* Turn on async mode */
8181       vam->async_mode = 1;
8182       vam->async_errors = 0;
8183       before = vat_time_now (vam);
8184     }
8185
8186   for (j = 0; j < count; j++)
8187     {
8188       /* Construct the API message */
8189       M2 (IP_ADD_DEL_ROUTE, mp,
8190           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8191
8192       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8193       mp->table_id = ntohl (vrf_id);
8194
8195       mp->is_add = is_add;
8196       mp->is_drop = is_drop;
8197       mp->is_unreach = is_unreach;
8198       mp->is_prohibit = is_prohibit;
8199       mp->is_ipv6 = is_ipv6;
8200       mp->is_local = is_local;
8201       mp->is_classify = is_classify;
8202       mp->is_multipath = is_multipath;
8203       mp->is_resolve_host = resolve_host;
8204       mp->is_resolve_attached = resolve_attached;
8205       mp->next_hop_weight = next_hop_weight;
8206       mp->dst_address_length = dst_address_length;
8207       mp->next_hop_table_id = ntohl (next_hop_table_id);
8208       mp->classify_table_index = ntohl (classify_table_index);
8209       mp->next_hop_via_label = ntohl (next_hop_via_label);
8210       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8211       if (0 != mp->next_hop_n_out_labels)
8212         {
8213           memcpy (mp->next_hop_out_label_stack,
8214                   next_hop_out_label_stack,
8215                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8216           vec_free (next_hop_out_label_stack);
8217         }
8218
8219       if (is_ipv6)
8220         {
8221           clib_memcpy (mp->dst_address, &v6_dst_address,
8222                        sizeof (v6_dst_address));
8223           if (next_hop_set)
8224             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8225                          sizeof (v6_next_hop_address));
8226           increment_v6_address (&v6_dst_address);
8227         }
8228       else
8229         {
8230           clib_memcpy (mp->dst_address, &v4_dst_address,
8231                        sizeof (v4_dst_address));
8232           if (next_hop_set)
8233             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8234                          sizeof (v4_next_hop_address));
8235           if (random_add_del)
8236             v4_dst_address.as_u32 = random_vector[j + 1];
8237           else
8238             increment_v4_address (&v4_dst_address);
8239         }
8240       /* send it... */
8241       S (mp);
8242       /* If we receive SIGTERM, stop now... */
8243       if (vam->do_exit)
8244         break;
8245     }
8246
8247   /* When testing multiple add/del ops, use a control-ping to sync */
8248   if (count > 1)
8249     {
8250       vl_api_control_ping_t *mp_ping;
8251       f64 after;
8252       f64 timeout;
8253
8254       /* Shut off async mode */
8255       vam->async_mode = 0;
8256
8257       MPING (CONTROL_PING, mp_ping);
8258       S (mp_ping);
8259
8260       timeout = vat_time_now (vam) + 1.0;
8261       while (vat_time_now (vam) < timeout)
8262         if (vam->result_ready == 1)
8263           goto out;
8264       vam->retval = -99;
8265
8266     out:
8267       if (vam->retval == -99)
8268         errmsg ("timeout");
8269
8270       if (vam->async_errors > 0)
8271         {
8272           errmsg ("%d asynchronous errors", vam->async_errors);
8273           vam->retval = -98;
8274         }
8275       vam->async_errors = 0;
8276       after = vat_time_now (vam);
8277
8278       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8279       if (j > 0)
8280         count = j;
8281
8282       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8283              count, after - before, count / (after - before));
8284     }
8285   else
8286     {
8287       int ret;
8288
8289       /* Wait for a reply... */
8290       W (ret);
8291       return ret;
8292     }
8293
8294   /* Return the good/bad news */
8295   return (vam->retval);
8296 }
8297
8298 static int
8299 api_ip_mroute_add_del (vat_main_t * vam)
8300 {
8301   unformat_input_t *i = vam->input;
8302   vl_api_ip_mroute_add_del_t *mp;
8303   u32 sw_if_index = ~0, vrf_id = 0;
8304   u8 is_ipv6 = 0;
8305   u8 is_local = 0;
8306   u8 is_add = 1;
8307   u8 address_set = 0;
8308   u32 grp_address_length = 0;
8309   ip4_address_t v4_grp_address, v4_src_address;
8310   ip6_address_t v6_grp_address, v6_src_address;
8311   mfib_itf_flags_t iflags = 0;
8312   mfib_entry_flags_t eflags = 0;
8313   int ret;
8314
8315   /* Parse args required to build the message */
8316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8317     {
8318       if (unformat (i, "sw_if_index %d", &sw_if_index))
8319         ;
8320       else if (unformat (i, "%U %U",
8321                          unformat_ip4_address, &v4_src_address,
8322                          unformat_ip4_address, &v4_grp_address))
8323         {
8324           grp_address_length = 64;
8325           address_set = 1;
8326           is_ipv6 = 0;
8327         }
8328       else if (unformat (i, "%U %U",
8329                          unformat_ip6_address, &v6_src_address,
8330                          unformat_ip6_address, &v6_grp_address))
8331         {
8332           grp_address_length = 256;
8333           address_set = 1;
8334           is_ipv6 = 1;
8335         }
8336       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8337         {
8338           memset (&v4_src_address, 0, sizeof (v4_src_address));
8339           grp_address_length = 32;
8340           address_set = 1;
8341           is_ipv6 = 0;
8342         }
8343       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8344         {
8345           memset (&v6_src_address, 0, sizeof (v6_src_address));
8346           grp_address_length = 128;
8347           address_set = 1;
8348           is_ipv6 = 1;
8349         }
8350       else if (unformat (i, "/%d", &grp_address_length))
8351         ;
8352       else if (unformat (i, "local"))
8353         {
8354           is_local = 1;
8355         }
8356       else if (unformat (i, "del"))
8357         is_add = 0;
8358       else if (unformat (i, "add"))
8359         is_add = 1;
8360       else if (unformat (i, "vrf %d", &vrf_id))
8361         ;
8362       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8363         ;
8364       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8365         ;
8366       else
8367         {
8368           clib_warning ("parse error '%U'", format_unformat_error, i);
8369           return -99;
8370         }
8371     }
8372
8373   if (address_set == 0)
8374     {
8375       errmsg ("missing addresses\n");
8376       return -99;
8377     }
8378
8379   /* Construct the API message */
8380   M (IP_MROUTE_ADD_DEL, mp);
8381
8382   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8383   mp->table_id = ntohl (vrf_id);
8384
8385   mp->is_add = is_add;
8386   mp->is_ipv6 = is_ipv6;
8387   mp->is_local = is_local;
8388   mp->itf_flags = ntohl (iflags);
8389   mp->entry_flags = ntohl (eflags);
8390   mp->grp_address_length = grp_address_length;
8391   mp->grp_address_length = ntohs (mp->grp_address_length);
8392
8393   if (is_ipv6)
8394     {
8395       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8396       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8397     }
8398   else
8399     {
8400       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8401       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8402
8403     }
8404
8405   /* send it... */
8406   S (mp);
8407   /* Wait for a reply... */
8408   W (ret);
8409   return ret;
8410 }
8411
8412 static int
8413 api_mpls_table_add_del (vat_main_t * vam)
8414 {
8415   unformat_input_t *i = vam->input;
8416   vl_api_mpls_table_add_del_t *mp;
8417   u32 table_id = ~0;
8418   u8 is_add = 1;
8419   int ret = 0;
8420
8421   /* Parse args required to build the message */
8422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8423     {
8424       if (unformat (i, "table %d", &table_id))
8425         ;
8426       else if (unformat (i, "del"))
8427         is_add = 0;
8428       else if (unformat (i, "add"))
8429         is_add = 1;
8430       else
8431         {
8432           clib_warning ("parse error '%U'", format_unformat_error, i);
8433           return -99;
8434         }
8435     }
8436
8437   if (~0 == table_id)
8438     {
8439       errmsg ("missing table-ID");
8440       return -99;
8441     }
8442
8443   /* Construct the API message */
8444   M (MPLS_TABLE_ADD_DEL, mp);
8445
8446   mp->mt_table_id = ntohl (table_id);
8447   mp->mt_is_add = is_add;
8448
8449   /* send it... */
8450   S (mp);
8451
8452   /* Wait for a reply... */
8453   W (ret);
8454
8455   return ret;
8456 }
8457
8458 static int
8459 api_mpls_route_add_del (vat_main_t * vam)
8460 {
8461   unformat_input_t *i = vam->input;
8462   vl_api_mpls_route_add_del_t *mp;
8463   u32 sw_if_index = ~0, table_id = 0;
8464   u8 is_add = 1;
8465   u32 next_hop_weight = 1;
8466   u8 is_multipath = 0;
8467   u32 next_hop_table_id = 0;
8468   u8 next_hop_set = 0;
8469   ip4_address_t v4_next_hop_address = {
8470     .as_u32 = 0,
8471   };
8472   ip6_address_t v6_next_hop_address = { {0} };
8473   int count = 1;
8474   int j;
8475   f64 before = 0;
8476   u32 classify_table_index = ~0;
8477   u8 is_classify = 0;
8478   u8 resolve_host = 0, resolve_attached = 0;
8479   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8480   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8481   mpls_label_t *next_hop_out_label_stack = NULL;
8482   mpls_label_t local_label = MPLS_LABEL_INVALID;
8483   u8 is_eos = 0;
8484   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8485
8486   /* Parse args required to build the message */
8487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8490         ;
8491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8492         ;
8493       else if (unformat (i, "%d", &local_label))
8494         ;
8495       else if (unformat (i, "eos"))
8496         is_eos = 1;
8497       else if (unformat (i, "non-eos"))
8498         is_eos = 0;
8499       else if (unformat (i, "via %U", unformat_ip4_address,
8500                          &v4_next_hop_address))
8501         {
8502           next_hop_set = 1;
8503           next_hop_proto = DPO_PROTO_IP4;
8504         }
8505       else if (unformat (i, "via %U", unformat_ip6_address,
8506                          &v6_next_hop_address))
8507         {
8508           next_hop_set = 1;
8509           next_hop_proto = DPO_PROTO_IP6;
8510         }
8511       else if (unformat (i, "weight %d", &next_hop_weight))
8512         ;
8513       else if (unformat (i, "classify %d", &classify_table_index))
8514         {
8515           is_classify = 1;
8516         }
8517       else if (unformat (i, "del"))
8518         is_add = 0;
8519       else if (unformat (i, "add"))
8520         is_add = 1;
8521       else if (unformat (i, "resolve-via-host"))
8522         resolve_host = 1;
8523       else if (unformat (i, "resolve-via-attached"))
8524         resolve_attached = 1;
8525       else if (unformat (i, "multipath"))
8526         is_multipath = 1;
8527       else if (unformat (i, "count %d", &count))
8528         ;
8529       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8530         {
8531           next_hop_set = 1;
8532           next_hop_proto = DPO_PROTO_IP4;
8533         }
8534       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8535         {
8536           next_hop_set = 1;
8537           next_hop_proto = DPO_PROTO_IP6;
8538         }
8539       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8540         ;
8541       else if (unformat (i, "via-label %d", &next_hop_via_label))
8542         ;
8543       else if (unformat (i, "out-label %d", &next_hop_out_label))
8544         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8545       else
8546         {
8547           clib_warning ("parse error '%U'", format_unformat_error, i);
8548           return -99;
8549         }
8550     }
8551
8552   if (!next_hop_set && !is_classify)
8553     {
8554       errmsg ("next hop / classify not set");
8555       return -99;
8556     }
8557
8558   if (MPLS_LABEL_INVALID == local_label)
8559     {
8560       errmsg ("missing label");
8561       return -99;
8562     }
8563
8564   if (count > 1)
8565     {
8566       /* Turn on async mode */
8567       vam->async_mode = 1;
8568       vam->async_errors = 0;
8569       before = vat_time_now (vam);
8570     }
8571
8572   for (j = 0; j < count; j++)
8573     {
8574       /* Construct the API message */
8575       M2 (MPLS_ROUTE_ADD_DEL, mp,
8576           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8577
8578       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8579       mp->mr_table_id = ntohl (table_id);
8580
8581       mp->mr_is_add = is_add;
8582       mp->mr_next_hop_proto = next_hop_proto;
8583       mp->mr_is_classify = is_classify;
8584       mp->mr_is_multipath = is_multipath;
8585       mp->mr_is_resolve_host = resolve_host;
8586       mp->mr_is_resolve_attached = resolve_attached;
8587       mp->mr_next_hop_weight = next_hop_weight;
8588       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8589       mp->mr_classify_table_index = ntohl (classify_table_index);
8590       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8591       mp->mr_label = ntohl (local_label);
8592       mp->mr_eos = is_eos;
8593
8594       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8595       if (0 != mp->mr_next_hop_n_out_labels)
8596         {
8597           memcpy (mp->mr_next_hop_out_label_stack,
8598                   next_hop_out_label_stack,
8599                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8600           vec_free (next_hop_out_label_stack);
8601         }
8602
8603       if (next_hop_set)
8604         {
8605           if (DPO_PROTO_IP4 == next_hop_proto)
8606             {
8607               clib_memcpy (mp->mr_next_hop,
8608                            &v4_next_hop_address,
8609                            sizeof (v4_next_hop_address));
8610             }
8611           else if (DPO_PROTO_IP6 == next_hop_proto)
8612
8613             {
8614               clib_memcpy (mp->mr_next_hop,
8615                            &v6_next_hop_address,
8616                            sizeof (v6_next_hop_address));
8617             }
8618         }
8619       local_label++;
8620
8621       /* send it... */
8622       S (mp);
8623       /* If we receive SIGTERM, stop now... */
8624       if (vam->do_exit)
8625         break;
8626     }
8627
8628   /* When testing multiple add/del ops, use a control-ping to sync */
8629   if (count > 1)
8630     {
8631       vl_api_control_ping_t *mp_ping;
8632       f64 after;
8633       f64 timeout;
8634
8635       /* Shut off async mode */
8636       vam->async_mode = 0;
8637
8638       MPING (CONTROL_PING, mp_ping);
8639       S (mp_ping);
8640
8641       timeout = vat_time_now (vam) + 1.0;
8642       while (vat_time_now (vam) < timeout)
8643         if (vam->result_ready == 1)
8644           goto out;
8645       vam->retval = -99;
8646
8647     out:
8648       if (vam->retval == -99)
8649         errmsg ("timeout");
8650
8651       if (vam->async_errors > 0)
8652         {
8653           errmsg ("%d asynchronous errors", vam->async_errors);
8654           vam->retval = -98;
8655         }
8656       vam->async_errors = 0;
8657       after = vat_time_now (vam);
8658
8659       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8660       if (j > 0)
8661         count = j;
8662
8663       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8664              count, after - before, count / (after - before));
8665     }
8666   else
8667     {
8668       int ret;
8669
8670       /* Wait for a reply... */
8671       W (ret);
8672       return ret;
8673     }
8674
8675   /* Return the good/bad news */
8676   return (vam->retval);
8677 }
8678
8679 static int
8680 api_mpls_ip_bind_unbind (vat_main_t * vam)
8681 {
8682   unformat_input_t *i = vam->input;
8683   vl_api_mpls_ip_bind_unbind_t *mp;
8684   u32 ip_table_id = 0;
8685   u8 is_bind = 1;
8686   u8 is_ip4 = 1;
8687   ip4_address_t v4_address;
8688   ip6_address_t v6_address;
8689   u32 address_length;
8690   u8 address_set = 0;
8691   mpls_label_t local_label = MPLS_LABEL_INVALID;
8692   int ret;
8693
8694   /* Parse args required to build the message */
8695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8696     {
8697       if (unformat (i, "%U/%d", unformat_ip4_address,
8698                     &v4_address, &address_length))
8699         {
8700           is_ip4 = 1;
8701           address_set = 1;
8702         }
8703       else if (unformat (i, "%U/%d", unformat_ip6_address,
8704                          &v6_address, &address_length))
8705         {
8706           is_ip4 = 0;
8707           address_set = 1;
8708         }
8709       else if (unformat (i, "%d", &local_label))
8710         ;
8711       else if (unformat (i, "table-id %d", &ip_table_id))
8712         ;
8713       else if (unformat (i, "unbind"))
8714         is_bind = 0;
8715       else if (unformat (i, "bind"))
8716         is_bind = 1;
8717       else
8718         {
8719           clib_warning ("parse error '%U'", format_unformat_error, i);
8720           return -99;
8721         }
8722     }
8723
8724   if (!address_set)
8725     {
8726       errmsg ("IP addres not set");
8727       return -99;
8728     }
8729
8730   if (MPLS_LABEL_INVALID == local_label)
8731     {
8732       errmsg ("missing label");
8733       return -99;
8734     }
8735
8736   /* Construct the API message */
8737   M (MPLS_IP_BIND_UNBIND, mp);
8738
8739   mp->mb_is_bind = is_bind;
8740   mp->mb_is_ip4 = is_ip4;
8741   mp->mb_ip_table_id = ntohl (ip_table_id);
8742   mp->mb_mpls_table_id = 0;
8743   mp->mb_label = ntohl (local_label);
8744   mp->mb_address_length = address_length;
8745
8746   if (is_ip4)
8747     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8748   else
8749     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8750
8751   /* send it... */
8752   S (mp);
8753
8754   /* Wait for a reply... */
8755   W (ret);
8756   return ret;
8757 }
8758
8759 static int
8760 api_bier_table_add_del (vat_main_t * vam)
8761 {
8762   unformat_input_t *i = vam->input;
8763   vl_api_bier_table_add_del_t *mp;
8764   u8 is_add = 1;
8765   u32 set = 0, sub_domain = 0, hdr_len = 3;
8766   mpls_label_t local_label = MPLS_LABEL_INVALID;
8767   int ret;
8768
8769   /* Parse args required to build the message */
8770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8771     {
8772       if (unformat (i, "sub-domain %d", &sub_domain))
8773         ;
8774       else if (unformat (i, "set %d", &set))
8775         ;
8776       else if (unformat (i, "label %d", &local_label))
8777         ;
8778       else if (unformat (i, "hdr-len %d", &hdr_len))
8779         ;
8780       else if (unformat (i, "add"))
8781         is_add = 1;
8782       else if (unformat (i, "del"))
8783         is_add = 0;
8784       else
8785         {
8786           clib_warning ("parse error '%U'", format_unformat_error, i);
8787           return -99;
8788         }
8789     }
8790
8791   if (MPLS_LABEL_INVALID == local_label)
8792     {
8793       errmsg ("missing label\n");
8794       return -99;
8795     }
8796
8797   /* Construct the API message */
8798   M (BIER_TABLE_ADD_DEL, mp);
8799
8800   mp->bt_is_add = is_add;
8801   mp->bt_label = ntohl (local_label);
8802   mp->bt_tbl_id.bt_set = set;
8803   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8804   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8805
8806   /* send it... */
8807   S (mp);
8808
8809   /* Wait for a reply... */
8810   W (ret);
8811
8812   return (ret);
8813 }
8814
8815 static int
8816 api_bier_route_add_del (vat_main_t * vam)
8817 {
8818   unformat_input_t *i = vam->input;
8819   vl_api_bier_route_add_del_t *mp;
8820   u8 is_add = 1;
8821   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8822   ip4_address_t v4_next_hop_address;
8823   ip6_address_t v6_next_hop_address;
8824   u8 next_hop_set = 0;
8825   u8 next_hop_proto_is_ip4 = 1;
8826   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8827   int ret;
8828
8829   /* Parse args required to build the message */
8830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8833         {
8834           next_hop_proto_is_ip4 = 1;
8835           next_hop_set = 1;
8836         }
8837       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8838         {
8839           next_hop_proto_is_ip4 = 0;
8840           next_hop_set = 1;
8841         }
8842       if (unformat (i, "sub-domain %d", &sub_domain))
8843         ;
8844       else if (unformat (i, "set %d", &set))
8845         ;
8846       else if (unformat (i, "hdr-len %d", &hdr_len))
8847         ;
8848       else if (unformat (i, "bp %d", &bp))
8849         ;
8850       else if (unformat (i, "add"))
8851         is_add = 1;
8852       else if (unformat (i, "del"))
8853         is_add = 0;
8854       else if (unformat (i, "out-label %d", &next_hop_out_label))
8855         ;
8856       else
8857         {
8858           clib_warning ("parse error '%U'", format_unformat_error, i);
8859           return -99;
8860         }
8861     }
8862
8863   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8864     {
8865       errmsg ("next hop / label set\n");
8866       return -99;
8867     }
8868   if (0 == bp)
8869     {
8870       errmsg ("bit=position not set\n");
8871       return -99;
8872     }
8873
8874   /* Construct the API message */
8875   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8876
8877   mp->br_is_add = is_add;
8878   mp->br_tbl_id.bt_set = set;
8879   mp->br_tbl_id.bt_sub_domain = sub_domain;
8880   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8881   mp->br_bp = ntohs (bp);
8882   mp->br_n_paths = 1;
8883   mp->br_paths[0].n_labels = 1;
8884   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8885   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8886
8887   if (next_hop_proto_is_ip4)
8888     {
8889       clib_memcpy (mp->br_paths[0].next_hop,
8890                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8891     }
8892   else
8893     {
8894       clib_memcpy (mp->br_paths[0].next_hop,
8895                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8896     }
8897
8898   /* send it... */
8899   S (mp);
8900
8901   /* Wait for a reply... */
8902   W (ret);
8903
8904   return (ret);
8905 }
8906
8907 static int
8908 api_proxy_arp_add_del (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_proxy_arp_add_del_t *mp;
8912   u32 vrf_id = 0;
8913   u8 is_add = 1;
8914   ip4_address_t lo, hi;
8915   u8 range_set = 0;
8916   int ret;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "vrf %d", &vrf_id))
8921         ;
8922       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8923                          unformat_ip4_address, &hi))
8924         range_set = 1;
8925       else if (unformat (i, "del"))
8926         is_add = 0;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (range_set == 0)
8935     {
8936       errmsg ("address range not set");
8937       return -99;
8938     }
8939
8940   M (PROXY_ARP_ADD_DEL, mp);
8941
8942   mp->vrf_id = ntohl (vrf_id);
8943   mp->is_add = is_add;
8944   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8945   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8946
8947   S (mp);
8948   W (ret);
8949   return ret;
8950 }
8951
8952 static int
8953 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8957   u32 sw_if_index;
8958   u8 enable = 1;
8959   u8 sw_if_index_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "enable"))
8969         enable = 1;
8970       else if (unformat (i, "disable"))
8971         enable = 0;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index_set == 0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984
8985   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->enable_disable = enable;
8989
8990   S (mp);
8991   W (ret);
8992   return ret;
8993 }
8994
8995 static int
8996 api_mpls_tunnel_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_mpls_tunnel_add_del_t *mp;
9000
9001   u8 is_add = 1;
9002   u8 l2_only = 0;
9003   u32 sw_if_index = ~0;
9004   u32 next_hop_sw_if_index = ~0;
9005   u32 next_hop_proto_is_ip4 = 1;
9006
9007   u32 next_hop_table_id = 0;
9008   ip4_address_t v4_next_hop_address = {
9009     .as_u32 = 0,
9010   };
9011   ip6_address_t v6_next_hop_address = { {0} };
9012   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9013   int ret;
9014
9015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9016     {
9017       if (unformat (i, "add"))
9018         is_add = 1;
9019       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9020         is_add = 0;
9021       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9022         ;
9023       else if (unformat (i, "via %U",
9024                          unformat_ip4_address, &v4_next_hop_address))
9025         {
9026           next_hop_proto_is_ip4 = 1;
9027         }
9028       else if (unformat (i, "via %U",
9029                          unformat_ip6_address, &v6_next_hop_address))
9030         {
9031           next_hop_proto_is_ip4 = 0;
9032         }
9033       else if (unformat (i, "l2-only"))
9034         l2_only = 1;
9035       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9036         ;
9037       else if (unformat (i, "out-label %d", &next_hop_out_label))
9038         vec_add1 (labels, ntohl (next_hop_out_label));
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9047
9048   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9049   mp->mt_sw_if_index = ntohl (sw_if_index);
9050   mp->mt_is_add = is_add;
9051   mp->mt_l2_only = l2_only;
9052   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9053   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9054
9055   mp->mt_next_hop_n_out_labels = vec_len (labels);
9056
9057   if (0 != mp->mt_next_hop_n_out_labels)
9058     {
9059       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9060                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9061       vec_free (labels);
9062     }
9063
9064   if (next_hop_proto_is_ip4)
9065     {
9066       clib_memcpy (mp->mt_next_hop,
9067                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9068     }
9069   else
9070     {
9071       clib_memcpy (mp->mt_next_hop,
9072                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9073     }
9074
9075   S (mp);
9076   W (ret);
9077   return ret;
9078 }
9079
9080 static int
9081 api_sw_interface_set_unnumbered (vat_main_t * vam)
9082 {
9083   unformat_input_t *i = vam->input;
9084   vl_api_sw_interface_set_unnumbered_t *mp;
9085   u32 sw_if_index;
9086   u32 unnum_sw_index = ~0;
9087   u8 is_add = 1;
9088   u8 sw_if_index_set = 0;
9089   int ret;
9090
9091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9094         sw_if_index_set = 1;
9095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9098         ;
9099       else if (unformat (i, "del"))
9100         is_add = 0;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (sw_if_index_set == 0)
9109     {
9110       errmsg ("missing interface name or sw_if_index");
9111       return -99;
9112     }
9113
9114   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9115
9116   mp->sw_if_index = ntohl (sw_if_index);
9117   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9118   mp->is_add = is_add;
9119
9120   S (mp);
9121   W (ret);
9122   return ret;
9123 }
9124
9125 static int
9126 api_ip_neighbor_add_del (vat_main_t * vam)
9127 {
9128   unformat_input_t *i = vam->input;
9129   vl_api_ip_neighbor_add_del_t *mp;
9130   u32 sw_if_index;
9131   u8 sw_if_index_set = 0;
9132   u8 is_add = 1;
9133   u8 is_static = 0;
9134   u8 is_no_fib_entry = 0;
9135   u8 mac_address[6];
9136   u8 mac_set = 0;
9137   u8 v4_address_set = 0;
9138   u8 v6_address_set = 0;
9139   ip4_address_t v4address;
9140   ip6_address_t v6address;
9141   int ret;
9142
9143   memset (mac_address, 0, sizeof (mac_address));
9144
9145   /* Parse args required to build the message */
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9149         {
9150           mac_set = 1;
9151         }
9152       else if (unformat (i, "del"))
9153         is_add = 0;
9154       else
9155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "is_static"))
9160         is_static = 1;
9161       else if (unformat (i, "no-fib-entry"))
9162         is_no_fib_entry = 1;
9163       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9164         v4_address_set = 1;
9165       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9166         v6_address_set = 1;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179   if (v4_address_set && v6_address_set)
9180     {
9181       errmsg ("both v4 and v6 addresses set");
9182       return -99;
9183     }
9184   if (!v4_address_set && !v6_address_set)
9185     {
9186       errmsg ("no address set");
9187       return -99;
9188     }
9189
9190   /* Construct the API message */
9191   M (IP_NEIGHBOR_ADD_DEL, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->is_add = is_add;
9195   mp->is_static = is_static;
9196   mp->is_no_adj_fib = is_no_fib_entry;
9197   if (mac_set)
9198     clib_memcpy (mp->mac_address, mac_address, 6);
9199   if (v6_address_set)
9200     {
9201       mp->is_ipv6 = 1;
9202       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9203     }
9204   else
9205     {
9206       /* mp->is_ipv6 = 0; via memset in M macro above */
9207       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9208     }
9209
9210   /* send it... */
9211   S (mp);
9212
9213   /* Wait for a reply, return good/bad news  */
9214   W (ret);
9215   return ret;
9216 }
9217
9218 static int
9219 api_create_vlan_subif (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_create_vlan_subif_t *mp;
9223   u32 sw_if_index;
9224   u8 sw_if_index_set = 0;
9225   u32 vlan_id;
9226   u8 vlan_id_set = 0;
9227   int ret;
9228
9229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9230     {
9231       if (unformat (i, "sw_if_index %d", &sw_if_index))
9232         sw_if_index_set = 1;
9233       else
9234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9235         sw_if_index_set = 1;
9236       else if (unformat (i, "vlan %d", &vlan_id))
9237         vlan_id_set = 1;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (sw_if_index_set == 0)
9246     {
9247       errmsg ("missing interface name or sw_if_index");
9248       return -99;
9249     }
9250
9251   if (vlan_id_set == 0)
9252     {
9253       errmsg ("missing vlan_id");
9254       return -99;
9255     }
9256   M (CREATE_VLAN_SUBIF, mp);
9257
9258   mp->sw_if_index = ntohl (sw_if_index);
9259   mp->vlan_id = ntohl (vlan_id);
9260
9261   S (mp);
9262   W (ret);
9263   return ret;
9264 }
9265
9266 #define foreach_create_subif_bit                \
9267 _(no_tags)                                      \
9268 _(one_tag)                                      \
9269 _(two_tags)                                     \
9270 _(dot1ad)                                       \
9271 _(exact_match)                                  \
9272 _(default_sub)                                  \
9273 _(outer_vlan_id_any)                            \
9274 _(inner_vlan_id_any)
9275
9276 static int
9277 api_create_subif (vat_main_t * vam)
9278 {
9279   unformat_input_t *i = vam->input;
9280   vl_api_create_subif_t *mp;
9281   u32 sw_if_index;
9282   u8 sw_if_index_set = 0;
9283   u32 sub_id;
9284   u8 sub_id_set = 0;
9285   u32 no_tags = 0;
9286   u32 one_tag = 0;
9287   u32 two_tags = 0;
9288   u32 dot1ad = 0;
9289   u32 exact_match = 0;
9290   u32 default_sub = 0;
9291   u32 outer_vlan_id_any = 0;
9292   u32 inner_vlan_id_any = 0;
9293   u32 tmp;
9294   u16 outer_vlan_id = 0;
9295   u16 inner_vlan_id = 0;
9296   int ret;
9297
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "sw_if_index %d", &sw_if_index))
9301         sw_if_index_set = 1;
9302       else
9303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "sub_id %d", &sub_id))
9306         sub_id_set = 1;
9307       else if (unformat (i, "outer_vlan_id %d", &tmp))
9308         outer_vlan_id = tmp;
9309       else if (unformat (i, "inner_vlan_id %d", &tmp))
9310         inner_vlan_id = tmp;
9311
9312 #define _(a) else if (unformat (i, #a)) a = 1 ;
9313       foreach_create_subif_bit
9314 #undef _
9315         else
9316         {
9317           clib_warning ("parse error '%U'", format_unformat_error, i);
9318           return -99;
9319         }
9320     }
9321
9322   if (sw_if_index_set == 0)
9323     {
9324       errmsg ("missing interface name or sw_if_index");
9325       return -99;
9326     }
9327
9328   if (sub_id_set == 0)
9329     {
9330       errmsg ("missing sub_id");
9331       return -99;
9332     }
9333   M (CREATE_SUBIF, mp);
9334
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->sub_id = ntohl (sub_id);
9337
9338 #define _(a) mp->a = a;
9339   foreach_create_subif_bit;
9340 #undef _
9341
9342   mp->outer_vlan_id = ntohs (outer_vlan_id);
9343   mp->inner_vlan_id = ntohs (inner_vlan_id);
9344
9345   S (mp);
9346   W (ret);
9347   return ret;
9348 }
9349
9350 static int
9351 api_oam_add_del (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_oam_add_del_t *mp;
9355   u32 vrf_id = 0;
9356   u8 is_add = 1;
9357   ip4_address_t src, dst;
9358   u8 src_set = 0;
9359   u8 dst_set = 0;
9360   int ret;
9361
9362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (i, "vrf %d", &vrf_id))
9365         ;
9366       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9367         src_set = 1;
9368       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9369         dst_set = 1;
9370       else if (unformat (i, "del"))
9371         is_add = 0;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (src_set == 0)
9380     {
9381       errmsg ("missing src addr");
9382       return -99;
9383     }
9384
9385   if (dst_set == 0)
9386     {
9387       errmsg ("missing dst addr");
9388       return -99;
9389     }
9390
9391   M (OAM_ADD_DEL, mp);
9392
9393   mp->vrf_id = ntohl (vrf_id);
9394   mp->is_add = is_add;
9395   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9396   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_reset_fib (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_reset_fib_t *mp;
9408   u32 vrf_id = 0;
9409   u8 is_ipv6 = 0;
9410   u8 vrf_id_set = 0;
9411
9412   int ret;
9413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (i, "vrf %d", &vrf_id))
9416         vrf_id_set = 1;
9417       else if (unformat (i, "ipv6"))
9418         is_ipv6 = 1;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (vrf_id_set == 0)
9427     {
9428       errmsg ("missing vrf id");
9429       return -99;
9430     }
9431
9432   M (RESET_FIB, mp);
9433
9434   mp->vrf_id = ntohl (vrf_id);
9435   mp->is_ipv6 = is_ipv6;
9436
9437   S (mp);
9438   W (ret);
9439   return ret;
9440 }
9441
9442 static int
9443 api_dhcp_proxy_config (vat_main_t * vam)
9444 {
9445   unformat_input_t *i = vam->input;
9446   vl_api_dhcp_proxy_config_t *mp;
9447   u32 rx_vrf_id = 0;
9448   u32 server_vrf_id = 0;
9449   u8 is_add = 1;
9450   u8 v4_address_set = 0;
9451   u8 v6_address_set = 0;
9452   ip4_address_t v4address;
9453   ip6_address_t v6address;
9454   u8 v4_src_address_set = 0;
9455   u8 v6_src_address_set = 0;
9456   ip4_address_t v4srcaddress;
9457   ip6_address_t v6srcaddress;
9458   int ret;
9459
9460   /* Parse args required to build the message */
9461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (i, "del"))
9464         is_add = 0;
9465       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9466         ;
9467       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9468         ;
9469       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9470         v4_address_set = 1;
9471       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9472         v6_address_set = 1;
9473       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9474         v4_src_address_set = 1;
9475       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9476         v6_src_address_set = 1;
9477       else
9478         break;
9479     }
9480
9481   if (v4_address_set && v6_address_set)
9482     {
9483       errmsg ("both v4 and v6 server addresses set");
9484       return -99;
9485     }
9486   if (!v4_address_set && !v6_address_set)
9487     {
9488       errmsg ("no server addresses set");
9489       return -99;
9490     }
9491
9492   if (v4_src_address_set && v6_src_address_set)
9493     {
9494       errmsg ("both v4 and v6  src addresses set");
9495       return -99;
9496     }
9497   if (!v4_src_address_set && !v6_src_address_set)
9498     {
9499       errmsg ("no src addresses set");
9500       return -99;
9501     }
9502
9503   if (!(v4_src_address_set && v4_address_set) &&
9504       !(v6_src_address_set && v6_address_set))
9505     {
9506       errmsg ("no matching server and src addresses set");
9507       return -99;
9508     }
9509
9510   /* Construct the API message */
9511   M (DHCP_PROXY_CONFIG, mp);
9512
9513   mp->is_add = is_add;
9514   mp->rx_vrf_id = ntohl (rx_vrf_id);
9515   mp->server_vrf_id = ntohl (server_vrf_id);
9516   if (v6_address_set)
9517     {
9518       mp->is_ipv6 = 1;
9519       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9520       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9521     }
9522   else
9523     {
9524       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9525       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9526     }
9527
9528   /* send it... */
9529   S (mp);
9530
9531   /* Wait for a reply, return good/bad news  */
9532   W (ret);
9533   return ret;
9534 }
9535
9536 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9537 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9538
9539 static void
9540 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9541 {
9542   vat_main_t *vam = &vat_main;
9543   u32 i, count = mp->count;
9544   vl_api_dhcp_server_t *s;
9545
9546   if (mp->is_ipv6)
9547     print (vam->ofp,
9548            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9549            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9550            ntohl (mp->rx_vrf_id),
9551            format_ip6_address, mp->dhcp_src_address,
9552            mp->vss_type, mp->vss_vpn_ascii_id,
9553            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9554   else
9555     print (vam->ofp,
9556            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9557            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9558            ntohl (mp->rx_vrf_id),
9559            format_ip4_address, mp->dhcp_src_address,
9560            mp->vss_type, mp->vss_vpn_ascii_id,
9561            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9562
9563   for (i = 0; i < count; i++)
9564     {
9565       s = &mp->servers[i];
9566
9567       if (mp->is_ipv6)
9568         print (vam->ofp,
9569                " Server Table-ID %d, Server Address %U",
9570                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9571       else
9572         print (vam->ofp,
9573                " Server Table-ID %d, Server Address %U",
9574                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9575     }
9576 }
9577
9578 static void vl_api_dhcp_proxy_details_t_handler_json
9579   (vl_api_dhcp_proxy_details_t * mp)
9580 {
9581   vat_main_t *vam = &vat_main;
9582   vat_json_node_t *node = NULL;
9583   u32 i, count = mp->count;
9584   struct in_addr ip4;
9585   struct in6_addr ip6;
9586   vl_api_dhcp_server_t *s;
9587
9588   if (VAT_JSON_ARRAY != vam->json_tree.type)
9589     {
9590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9591       vat_json_init_array (&vam->json_tree);
9592     }
9593   node = vat_json_array_add (&vam->json_tree);
9594
9595   vat_json_init_object (node);
9596   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9597   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9598                              sizeof (mp->vss_type));
9599   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9600                                    mp->vss_vpn_ascii_id);
9601   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9602   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9603
9604   if (mp->is_ipv6)
9605     {
9606       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9607       vat_json_object_add_ip6 (node, "src_address", ip6);
9608     }
9609   else
9610     {
9611       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9612       vat_json_object_add_ip4 (node, "src_address", ip4);
9613     }
9614
9615   for (i = 0; i < count; i++)
9616     {
9617       s = &mp->servers[i];
9618
9619       vat_json_object_add_uint (node, "server-table-id",
9620                                 ntohl (s->server_vrf_id));
9621
9622       if (mp->is_ipv6)
9623         {
9624           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9625           vat_json_object_add_ip4 (node, "src_address", ip4);
9626         }
9627       else
9628         {
9629           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9630           vat_json_object_add_ip6 (node, "server_address", ip6);
9631         }
9632     }
9633 }
9634
9635 static int
9636 api_dhcp_proxy_dump (vat_main_t * vam)
9637 {
9638   unformat_input_t *i = vam->input;
9639   vl_api_control_ping_t *mp_ping;
9640   vl_api_dhcp_proxy_dump_t *mp;
9641   u8 is_ipv6 = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "ipv6"))
9647         is_ipv6 = 1;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   M (DHCP_PROXY_DUMP, mp);
9656
9657   mp->is_ip6 = is_ipv6;
9658   S (mp);
9659
9660   /* Use a control ping for synchronization */
9661   MPING (CONTROL_PING, mp_ping);
9662   S (mp_ping);
9663
9664   W (ret);
9665   return ret;
9666 }
9667
9668 static int
9669 api_dhcp_proxy_set_vss (vat_main_t * vam)
9670 {
9671   unformat_input_t *i = vam->input;
9672   vl_api_dhcp_proxy_set_vss_t *mp;
9673   u8 is_ipv6 = 0;
9674   u8 is_add = 1;
9675   u32 tbl_id = ~0;
9676   u8 vss_type = VSS_TYPE_DEFAULT;
9677   u8 *vpn_ascii_id = 0;
9678   u32 oui = 0;
9679   u32 fib_id = 0;
9680   int ret;
9681
9682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (i, "tbl_id %d", &tbl_id))
9685         ;
9686       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9687         vss_type = VSS_TYPE_ASCII;
9688       else if (unformat (i, "fib_id %d", &fib_id))
9689         vss_type = VSS_TYPE_VPN_ID;
9690       else if (unformat (i, "oui %d", &oui))
9691         vss_type = VSS_TYPE_VPN_ID;
9692       else if (unformat (i, "ipv6"))
9693         is_ipv6 = 1;
9694       else if (unformat (i, "del"))
9695         is_add = 0;
9696       else
9697         break;
9698     }
9699
9700   if (tbl_id == ~0)
9701     {
9702       errmsg ("missing tbl_id ");
9703       vec_free (vpn_ascii_id);
9704       return -99;
9705     }
9706
9707   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9708     {
9709       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9710       vec_free (vpn_ascii_id);
9711       return -99;
9712     }
9713
9714   M (DHCP_PROXY_SET_VSS, mp);
9715   mp->tbl_id = ntohl (tbl_id);
9716   mp->vss_type = vss_type;
9717   if (vpn_ascii_id)
9718     {
9719       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9720       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9721     }
9722   mp->vpn_index = ntohl (fib_id);
9723   mp->oui = ntohl (oui);
9724   mp->is_ipv6 = is_ipv6;
9725   mp->is_add = is_add;
9726
9727   S (mp);
9728   W (ret);
9729
9730   vec_free (vpn_ascii_id);
9731   return ret;
9732 }
9733
9734 static int
9735 api_dhcp_client_config (vat_main_t * vam)
9736 {
9737   unformat_input_t *i = vam->input;
9738   vl_api_dhcp_client_config_t *mp;
9739   u32 sw_if_index;
9740   u8 sw_if_index_set = 0;
9741   u8 is_add = 1;
9742   u8 *hostname = 0;
9743   u8 disable_event = 0;
9744   int ret;
9745
9746   /* Parse args required to build the message */
9747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (i, "del"))
9750         is_add = 0;
9751       else
9752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9753         sw_if_index_set = 1;
9754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9755         sw_if_index_set = 1;
9756       else if (unformat (i, "hostname %s", &hostname))
9757         ;
9758       else if (unformat (i, "disable_event"))
9759         disable_event = 1;
9760       else
9761         break;
9762     }
9763
9764   if (sw_if_index_set == 0)
9765     {
9766       errmsg ("missing interface name or sw_if_index");
9767       return -99;
9768     }
9769
9770   if (vec_len (hostname) > 63)
9771     {
9772       errmsg ("hostname too long");
9773     }
9774   vec_add1 (hostname, 0);
9775
9776   /* Construct the API message */
9777   M (DHCP_CLIENT_CONFIG, mp);
9778
9779   mp->sw_if_index = htonl (sw_if_index);
9780   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9781   vec_free (hostname);
9782   mp->is_add = is_add;
9783   mp->want_dhcp_event = disable_event ? 0 : 1;
9784   mp->pid = htonl (getpid ());
9785
9786   /* send it... */
9787   S (mp);
9788
9789   /* Wait for a reply, return good/bad news  */
9790   W (ret);
9791   return ret;
9792 }
9793
9794 static int
9795 api_set_ip_flow_hash (vat_main_t * vam)
9796 {
9797   unformat_input_t *i = vam->input;
9798   vl_api_set_ip_flow_hash_t *mp;
9799   u32 vrf_id = 0;
9800   u8 is_ipv6 = 0;
9801   u8 vrf_id_set = 0;
9802   u8 src = 0;
9803   u8 dst = 0;
9804   u8 sport = 0;
9805   u8 dport = 0;
9806   u8 proto = 0;
9807   u8 reverse = 0;
9808   int ret;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "vrf %d", &vrf_id))
9813         vrf_id_set = 1;
9814       else if (unformat (i, "ipv6"))
9815         is_ipv6 = 1;
9816       else if (unformat (i, "src"))
9817         src = 1;
9818       else if (unformat (i, "dst"))
9819         dst = 1;
9820       else if (unformat (i, "sport"))
9821         sport = 1;
9822       else if (unformat (i, "dport"))
9823         dport = 1;
9824       else if (unformat (i, "proto"))
9825         proto = 1;
9826       else if (unformat (i, "reverse"))
9827         reverse = 1;
9828
9829       else
9830         {
9831           clib_warning ("parse error '%U'", format_unformat_error, i);
9832           return -99;
9833         }
9834     }
9835
9836   if (vrf_id_set == 0)
9837     {
9838       errmsg ("missing vrf id");
9839       return -99;
9840     }
9841
9842   M (SET_IP_FLOW_HASH, mp);
9843   mp->src = src;
9844   mp->dst = dst;
9845   mp->sport = sport;
9846   mp->dport = dport;
9847   mp->proto = proto;
9848   mp->reverse = reverse;
9849   mp->vrf_id = ntohl (vrf_id);
9850   mp->is_ipv6 = is_ipv6;
9851
9852   S (mp);
9853   W (ret);
9854   return ret;
9855 }
9856
9857 static int
9858 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_sw_interface_ip6_enable_disable_t *mp;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable = 0;
9865   int ret;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable = 1;
9875       else if (unformat (i, "disable"))
9876         enable = 0;
9877       else
9878         {
9879           clib_warning ("parse error '%U'", format_unformat_error, i);
9880           return -99;
9881         }
9882     }
9883
9884   if (sw_if_index_set == 0)
9885     {
9886       errmsg ("missing interface name or sw_if_index");
9887       return -99;
9888     }
9889
9890   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9891
9892   mp->sw_if_index = ntohl (sw_if_index);
9893   mp->enable = enable;
9894
9895   S (mp);
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u8 v6_address_set = 0;
9908   ip6_address_t v6address;
9909   int ret;
9910
9911   /* Parse args required to build the message */
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9919         v6_address_set = 1;
9920       else
9921         break;
9922     }
9923
9924   if (sw_if_index_set == 0)
9925     {
9926       errmsg ("missing interface name or sw_if_index");
9927       return -99;
9928     }
9929   if (!v6_address_set)
9930     {
9931       errmsg ("no address set");
9932       return -99;
9933     }
9934
9935   /* Construct the API message */
9936   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9937
9938   mp->sw_if_index = ntohl (sw_if_index);
9939   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9940
9941   /* send it... */
9942   S (mp);
9943
9944   /* Wait for a reply, return good/bad news  */
9945   W (ret);
9946   return ret;
9947 }
9948
9949 static int
9950 api_ip6nd_proxy_add_del (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_ip6nd_proxy_add_del_t *mp;
9954   u32 sw_if_index = ~0;
9955   u8 v6_address_set = 0;
9956   ip6_address_t v6address;
9957   u8 is_del = 0;
9958   int ret;
9959
9960   /* Parse args required to build the message */
9961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9962     {
9963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9964         ;
9965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9966         ;
9967       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9968         v6_address_set = 1;
9969       if (unformat (i, "del"))
9970         is_del = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index == ~0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983   if (!v6_address_set)
9984     {
9985       errmsg ("no address set");
9986       return -99;
9987     }
9988
9989   /* Construct the API message */
9990   M (IP6ND_PROXY_ADD_DEL, mp);
9991
9992   mp->is_del = is_del;
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9995
9996   /* send it... */
9997   S (mp);
9998
9999   /* Wait for a reply, return good/bad news  */
10000   W (ret);
10001   return ret;
10002 }
10003
10004 static int
10005 api_ip6nd_proxy_dump (vat_main_t * vam)
10006 {
10007   vl_api_ip6nd_proxy_dump_t *mp;
10008   vl_api_control_ping_t *mp_ping;
10009   int ret;
10010
10011   M (IP6ND_PROXY_DUMP, mp);
10012
10013   S (mp);
10014
10015   /* Use a control ping for synchronization */
10016   MPING (CONTROL_PING, mp_ping);
10017   S (mp_ping);
10018
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static void vl_api_ip6nd_proxy_details_t_handler
10024   (vl_api_ip6nd_proxy_details_t * mp)
10025 {
10026   vat_main_t *vam = &vat_main;
10027
10028   print (vam->ofp, "host %U sw_if_index %d",
10029          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10030 }
10031
10032 static void vl_api_ip6nd_proxy_details_t_handler_json
10033   (vl_api_ip6nd_proxy_details_t * mp)
10034 {
10035   vat_main_t *vam = &vat_main;
10036   struct in6_addr ip6;
10037   vat_json_node_t *node = NULL;
10038
10039   if (VAT_JSON_ARRAY != vam->json_tree.type)
10040     {
10041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10042       vat_json_init_array (&vam->json_tree);
10043     }
10044   node = vat_json_array_add (&vam->json_tree);
10045
10046   vat_json_init_object (node);
10047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10048
10049   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10050   vat_json_object_add_ip6 (node, "host", ip6);
10051 }
10052
10053 static int
10054 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10058   u32 sw_if_index;
10059   u8 sw_if_index_set = 0;
10060   u32 address_length = 0;
10061   u8 v6_address_set = 0;
10062   ip6_address_t v6address;
10063   u8 use_default = 0;
10064   u8 no_advertise = 0;
10065   u8 off_link = 0;
10066   u8 no_autoconfig = 0;
10067   u8 no_onlink = 0;
10068   u8 is_no = 0;
10069   u32 val_lifetime = 0;
10070   u32 pref_lifetime = 0;
10071   int ret;
10072
10073   /* Parse args required to build the message */
10074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10075     {
10076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10079         sw_if_index_set = 1;
10080       else if (unformat (i, "%U/%d",
10081                          unformat_ip6_address, &v6address, &address_length))
10082         v6_address_set = 1;
10083       else if (unformat (i, "val_life %d", &val_lifetime))
10084         ;
10085       else if (unformat (i, "pref_life %d", &pref_lifetime))
10086         ;
10087       else if (unformat (i, "def"))
10088         use_default = 1;
10089       else if (unformat (i, "noadv"))
10090         no_advertise = 1;
10091       else if (unformat (i, "offl"))
10092         off_link = 1;
10093       else if (unformat (i, "noauto"))
10094         no_autoconfig = 1;
10095       else if (unformat (i, "nolink"))
10096         no_onlink = 1;
10097       else if (unformat (i, "isno"))
10098         is_no = 1;
10099       else
10100         {
10101           clib_warning ("parse error '%U'", format_unformat_error, i);
10102           return -99;
10103         }
10104     }
10105
10106   if (sw_if_index_set == 0)
10107     {
10108       errmsg ("missing interface name or sw_if_index");
10109       return -99;
10110     }
10111   if (!v6_address_set)
10112     {
10113       errmsg ("no address set");
10114       return -99;
10115     }
10116
10117   /* Construct the API message */
10118   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10122   mp->address_length = address_length;
10123   mp->use_default = use_default;
10124   mp->no_advertise = no_advertise;
10125   mp->off_link = off_link;
10126   mp->no_autoconfig = no_autoconfig;
10127   mp->no_onlink = no_onlink;
10128   mp->is_no = is_no;
10129   mp->val_lifetime = ntohl (val_lifetime);
10130   mp->pref_lifetime = ntohl (pref_lifetime);
10131
10132   /* send it... */
10133   S (mp);
10134
10135   /* Wait for a reply, return good/bad news  */
10136   W (ret);
10137   return ret;
10138 }
10139
10140 static int
10141 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10145   u32 sw_if_index;
10146   u8 sw_if_index_set = 0;
10147   u8 suppress = 0;
10148   u8 managed = 0;
10149   u8 other = 0;
10150   u8 ll_option = 0;
10151   u8 send_unicast = 0;
10152   u8 cease = 0;
10153   u8 is_no = 0;
10154   u8 default_router = 0;
10155   u32 max_interval = 0;
10156   u32 min_interval = 0;
10157   u32 lifetime = 0;
10158   u32 initial_count = 0;
10159   u32 initial_interval = 0;
10160   int ret;
10161
10162
10163   /* Parse args required to build the message */
10164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169         sw_if_index_set = 1;
10170       else if (unformat (i, "maxint %d", &max_interval))
10171         ;
10172       else if (unformat (i, "minint %d", &min_interval))
10173         ;
10174       else if (unformat (i, "life %d", &lifetime))
10175         ;
10176       else if (unformat (i, "count %d", &initial_count))
10177         ;
10178       else if (unformat (i, "interval %d", &initial_interval))
10179         ;
10180       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10181         suppress = 1;
10182       else if (unformat (i, "managed"))
10183         managed = 1;
10184       else if (unformat (i, "other"))
10185         other = 1;
10186       else if (unformat (i, "ll"))
10187         ll_option = 1;
10188       else if (unformat (i, "send"))
10189         send_unicast = 1;
10190       else if (unformat (i, "cease"))
10191         cease = 1;
10192       else if (unformat (i, "isno"))
10193         is_no = 1;
10194       else if (unformat (i, "def"))
10195         default_router = 1;
10196       else
10197         {
10198           clib_warning ("parse error '%U'", format_unformat_error, i);
10199           return -99;
10200         }
10201     }
10202
10203   if (sw_if_index_set == 0)
10204     {
10205       errmsg ("missing interface name or sw_if_index");
10206       return -99;
10207     }
10208
10209   /* Construct the API message */
10210   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10211
10212   mp->sw_if_index = ntohl (sw_if_index);
10213   mp->max_interval = ntohl (max_interval);
10214   mp->min_interval = ntohl (min_interval);
10215   mp->lifetime = ntohl (lifetime);
10216   mp->initial_count = ntohl (initial_count);
10217   mp->initial_interval = ntohl (initial_interval);
10218   mp->suppress = suppress;
10219   mp->managed = managed;
10220   mp->other = other;
10221   mp->ll_option = ll_option;
10222   mp->send_unicast = send_unicast;
10223   mp->cease = cease;
10224   mp->is_no = is_no;
10225   mp->default_router = default_router;
10226
10227   /* send it... */
10228   S (mp);
10229
10230   /* Wait for a reply, return good/bad news  */
10231   W (ret);
10232   return ret;
10233 }
10234
10235 static int
10236 api_set_arp_neighbor_limit (vat_main_t * vam)
10237 {
10238   unformat_input_t *i = vam->input;
10239   vl_api_set_arp_neighbor_limit_t *mp;
10240   u32 arp_nbr_limit;
10241   u8 limit_set = 0;
10242   u8 is_ipv6 = 0;
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10248         limit_set = 1;
10249       else if (unformat (i, "ipv6"))
10250         is_ipv6 = 1;
10251       else
10252         {
10253           clib_warning ("parse error '%U'", format_unformat_error, i);
10254           return -99;
10255         }
10256     }
10257
10258   if (limit_set == 0)
10259     {
10260       errmsg ("missing limit value");
10261       return -99;
10262     }
10263
10264   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10265
10266   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10267   mp->is_ipv6 = is_ipv6;
10268
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_l2_patch_add_del (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_l2_patch_add_del_t *mp;
10279   u32 rx_sw_if_index;
10280   u8 rx_sw_if_index_set = 0;
10281   u32 tx_sw_if_index;
10282   u8 tx_sw_if_index_set = 0;
10283   u8 is_add = 1;
10284   int ret;
10285
10286   /* Parse args required to build the message */
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10290         rx_sw_if_index_set = 1;
10291       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10292         tx_sw_if_index_set = 1;
10293       else if (unformat (i, "rx"))
10294         {
10295           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10296             {
10297               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10298                             &rx_sw_if_index))
10299                 rx_sw_if_index_set = 1;
10300             }
10301           else
10302             break;
10303         }
10304       else if (unformat (i, "tx"))
10305         {
10306           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307             {
10308               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10309                             &tx_sw_if_index))
10310                 tx_sw_if_index_set = 1;
10311             }
10312           else
10313             break;
10314         }
10315       else if (unformat (i, "del"))
10316         is_add = 0;
10317       else
10318         break;
10319     }
10320
10321   if (rx_sw_if_index_set == 0)
10322     {
10323       errmsg ("missing rx interface name or rx_sw_if_index");
10324       return -99;
10325     }
10326
10327   if (tx_sw_if_index_set == 0)
10328     {
10329       errmsg ("missing tx interface name or tx_sw_if_index");
10330       return -99;
10331     }
10332
10333   M (L2_PATCH_ADD_DEL, mp);
10334
10335   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10336   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10337   mp->is_add = is_add;
10338
10339   S (mp);
10340   W (ret);
10341   return ret;
10342 }
10343
10344 u8 is_del;
10345 u8 localsid_addr[16];
10346 u8 end_psp;
10347 u8 behavior;
10348 u32 sw_if_index;
10349 u32 vlan_index;
10350 u32 fib_table;
10351 u8 nh_addr[16];
10352
10353 static int
10354 api_sr_localsid_add_del (vat_main_t * vam)
10355 {
10356   unformat_input_t *i = vam->input;
10357   vl_api_sr_localsid_add_del_t *mp;
10358
10359   u8 is_del;
10360   ip6_address_t localsid;
10361   u8 end_psp = 0;
10362   u8 behavior = ~0;
10363   u32 sw_if_index;
10364   u32 fib_table = ~(u32) 0;
10365   ip6_address_t next_hop;
10366
10367   bool nexthop_set = 0;
10368
10369   int ret;
10370
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "del"))
10374         is_del = 1;
10375       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10376       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10377         nexthop_set = 1;
10378       else if (unformat (i, "behavior %u", &behavior));
10379       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10380       else if (unformat (i, "fib-table %u", &fib_table));
10381       else if (unformat (i, "end.psp %u", &behavior));
10382       else
10383         break;
10384     }
10385
10386   M (SR_LOCALSID_ADD_DEL, mp);
10387
10388   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10389   if (nexthop_set)
10390     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10391   mp->behavior = behavior;
10392   mp->sw_if_index = ntohl (sw_if_index);
10393   mp->fib_table = ntohl (fib_table);
10394   mp->end_psp = end_psp;
10395   mp->is_del = is_del;
10396
10397   S (mp);
10398   W (ret);
10399   return ret;
10400 }
10401
10402 static int
10403 api_ioam_enable (vat_main_t * vam)
10404 {
10405   unformat_input_t *input = vam->input;
10406   vl_api_ioam_enable_t *mp;
10407   u32 id = 0;
10408   int has_trace_option = 0;
10409   int has_pot_option = 0;
10410   int has_seqno_option = 0;
10411   int has_analyse_option = 0;
10412   int ret;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "trace"))
10417         has_trace_option = 1;
10418       else if (unformat (input, "pot"))
10419         has_pot_option = 1;
10420       else if (unformat (input, "seqno"))
10421         has_seqno_option = 1;
10422       else if (unformat (input, "analyse"))
10423         has_analyse_option = 1;
10424       else
10425         break;
10426     }
10427   M (IOAM_ENABLE, mp);
10428   mp->id = htons (id);
10429   mp->seqno = has_seqno_option;
10430   mp->analyse = has_analyse_option;
10431   mp->pot_enable = has_pot_option;
10432   mp->trace_enable = has_trace_option;
10433
10434   S (mp);
10435   W (ret);
10436   return ret;
10437 }
10438
10439
10440 static int
10441 api_ioam_disable (vat_main_t * vam)
10442 {
10443   vl_api_ioam_disable_t *mp;
10444   int ret;
10445
10446   M (IOAM_DISABLE, mp);
10447   S (mp);
10448   W (ret);
10449   return ret;
10450 }
10451
10452 #define foreach_tcp_proto_field                 \
10453 _(src_port)                                     \
10454 _(dst_port)
10455
10456 #define foreach_udp_proto_field                 \
10457 _(src_port)                                     \
10458 _(dst_port)
10459
10460 #define foreach_ip4_proto_field                 \
10461 _(src_address)                                  \
10462 _(dst_address)                                  \
10463 _(tos)                                          \
10464 _(length)                                       \
10465 _(fragment_id)                                  \
10466 _(ttl)                                          \
10467 _(protocol)                                     \
10468 _(checksum)
10469
10470 typedef struct
10471 {
10472   u16 src_port, dst_port;
10473 } tcpudp_header_t;
10474
10475 #if VPP_API_TEST_BUILTIN == 0
10476 uword
10477 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10478 {
10479   u8 **maskp = va_arg (*args, u8 **);
10480   u8 *mask = 0;
10481   u8 found_something = 0;
10482   tcp_header_t *tcp;
10483
10484 #define _(a) u8 a=0;
10485   foreach_tcp_proto_field;
10486 #undef _
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (0);
10491 #define _(a) else if (unformat (input, #a)) a=1;
10492       foreach_tcp_proto_field
10493 #undef _
10494         else
10495         break;
10496     }
10497
10498 #define _(a) found_something += a;
10499   foreach_tcp_proto_field;
10500 #undef _
10501
10502   if (found_something == 0)
10503     return 0;
10504
10505   vec_validate (mask, sizeof (*tcp) - 1);
10506
10507   tcp = (tcp_header_t *) mask;
10508
10509 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10510   foreach_tcp_proto_field;
10511 #undef _
10512
10513   *maskp = mask;
10514   return 1;
10515 }
10516
10517 uword
10518 unformat_udp_mask (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **maskp = va_arg (*args, u8 **);
10521   u8 *mask = 0;
10522   u8 found_something = 0;
10523   udp_header_t *udp;
10524
10525 #define _(a) u8 a=0;
10526   foreach_udp_proto_field;
10527 #undef _
10528
10529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10530     {
10531       if (0);
10532 #define _(a) else if (unformat (input, #a)) a=1;
10533       foreach_udp_proto_field
10534 #undef _
10535         else
10536         break;
10537     }
10538
10539 #define _(a) found_something += a;
10540   foreach_udp_proto_field;
10541 #undef _
10542
10543   if (found_something == 0)
10544     return 0;
10545
10546   vec_validate (mask, sizeof (*udp) - 1);
10547
10548   udp = (udp_header_t *) mask;
10549
10550 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10551   foreach_udp_proto_field;
10552 #undef _
10553
10554   *maskp = mask;
10555   return 1;
10556 }
10557
10558 uword
10559 unformat_l4_mask (unformat_input_t * input, va_list * args)
10560 {
10561   u8 **maskp = va_arg (*args, u8 **);
10562   u16 src_port = 0, dst_port = 0;
10563   tcpudp_header_t *tcpudp;
10564
10565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10568         return 1;
10569       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10570         return 1;
10571       else if (unformat (input, "src_port"))
10572         src_port = 0xFFFF;
10573       else if (unformat (input, "dst_port"))
10574         dst_port = 0xFFFF;
10575       else
10576         return 0;
10577     }
10578
10579   if (!src_port && !dst_port)
10580     return 0;
10581
10582   u8 *mask = 0;
10583   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10584
10585   tcpudp = (tcpudp_header_t *) mask;
10586   tcpudp->src_port = src_port;
10587   tcpudp->dst_port = dst_port;
10588
10589   *maskp = mask;
10590
10591   return 1;
10592 }
10593
10594 uword
10595 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10596 {
10597   u8 **maskp = va_arg (*args, u8 **);
10598   u8 *mask = 0;
10599   u8 found_something = 0;
10600   ip4_header_t *ip;
10601
10602 #define _(a) u8 a=0;
10603   foreach_ip4_proto_field;
10604 #undef _
10605   u8 version = 0;
10606   u8 hdr_length = 0;
10607
10608
10609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (input, "version"))
10612         version = 1;
10613       else if (unformat (input, "hdr_length"))
10614         hdr_length = 1;
10615       else if (unformat (input, "src"))
10616         src_address = 1;
10617       else if (unformat (input, "dst"))
10618         dst_address = 1;
10619       else if (unformat (input, "proto"))
10620         protocol = 1;
10621
10622 #define _(a) else if (unformat (input, #a)) a=1;
10623       foreach_ip4_proto_field
10624 #undef _
10625         else
10626         break;
10627     }
10628
10629 #define _(a) found_something += a;
10630   foreach_ip4_proto_field;
10631 #undef _
10632
10633   if (found_something == 0)
10634     return 0;
10635
10636   vec_validate (mask, sizeof (*ip) - 1);
10637
10638   ip = (ip4_header_t *) mask;
10639
10640 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10641   foreach_ip4_proto_field;
10642 #undef _
10643
10644   ip->ip_version_and_header_length = 0;
10645
10646   if (version)
10647     ip->ip_version_and_header_length |= 0xF0;
10648
10649   if (hdr_length)
10650     ip->ip_version_and_header_length |= 0x0F;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 #define foreach_ip6_proto_field                 \
10657 _(src_address)                                  \
10658 _(dst_address)                                  \
10659 _(payload_length)                               \
10660 _(hop_limit)                                    \
10661 _(protocol)
10662
10663 uword
10664 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10665 {
10666   u8 **maskp = va_arg (*args, u8 **);
10667   u8 *mask = 0;
10668   u8 found_something = 0;
10669   ip6_header_t *ip;
10670   u32 ip_version_traffic_class_and_flow_label;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip6_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 traffic_class = 0;
10677   u8 flow_label = 0;
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "traffic-class"))
10684         traffic_class = 1;
10685       else if (unformat (input, "flow-label"))
10686         flow_label = 1;
10687       else if (unformat (input, "src"))
10688         src_address = 1;
10689       else if (unformat (input, "dst"))
10690         dst_address = 1;
10691       else if (unformat (input, "proto"))
10692         protocol = 1;
10693
10694 #define _(a) else if (unformat (input, #a)) a=1;
10695       foreach_ip6_proto_field
10696 #undef _
10697         else
10698         break;
10699     }
10700
10701 #define _(a) found_something += a;
10702   foreach_ip6_proto_field;
10703 #undef _
10704
10705   if (found_something == 0)
10706     return 0;
10707
10708   vec_validate (mask, sizeof (*ip) - 1);
10709
10710   ip = (ip6_header_t *) mask;
10711
10712 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10713   foreach_ip6_proto_field;
10714 #undef _
10715
10716   ip_version_traffic_class_and_flow_label = 0;
10717
10718   if (version)
10719     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10720
10721   if (traffic_class)
10722     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10723
10724   if (flow_label)
10725     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10726
10727   ip->ip_version_traffic_class_and_flow_label =
10728     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10729
10730   *maskp = mask;
10731   return 1;
10732 }
10733
10734 uword
10735 unformat_l3_mask (unformat_input_t * input, va_list * args)
10736 {
10737   u8 **maskp = va_arg (*args, u8 **);
10738
10739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10742         return 1;
10743       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10744         return 1;
10745       else
10746         break;
10747     }
10748   return 0;
10749 }
10750
10751 uword
10752 unformat_l2_mask (unformat_input_t * input, va_list * args)
10753 {
10754   u8 **maskp = va_arg (*args, u8 **);
10755   u8 *mask = 0;
10756   u8 src = 0;
10757   u8 dst = 0;
10758   u8 proto = 0;
10759   u8 tag1 = 0;
10760   u8 tag2 = 0;
10761   u8 ignore_tag1 = 0;
10762   u8 ignore_tag2 = 0;
10763   u8 cos1 = 0;
10764   u8 cos2 = 0;
10765   u8 dot1q = 0;
10766   u8 dot1ad = 0;
10767   int len = 14;
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "src"))
10772         src = 1;
10773       else if (unformat (input, "dst"))
10774         dst = 1;
10775       else if (unformat (input, "proto"))
10776         proto = 1;
10777       else if (unformat (input, "tag1"))
10778         tag1 = 1;
10779       else if (unformat (input, "tag2"))
10780         tag2 = 1;
10781       else if (unformat (input, "ignore-tag1"))
10782         ignore_tag1 = 1;
10783       else if (unformat (input, "ignore-tag2"))
10784         ignore_tag2 = 1;
10785       else if (unformat (input, "cos1"))
10786         cos1 = 1;
10787       else if (unformat (input, "cos2"))
10788         cos2 = 1;
10789       else if (unformat (input, "dot1q"))
10790         dot1q = 1;
10791       else if (unformat (input, "dot1ad"))
10792         dot1ad = 1;
10793       else
10794         break;
10795     }
10796   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10797        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10798     return 0;
10799
10800   if (tag1 || ignore_tag1 || cos1 || dot1q)
10801     len = 18;
10802   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10803     len = 22;
10804
10805   vec_validate (mask, len - 1);
10806
10807   if (dst)
10808     memset (mask, 0xff, 6);
10809
10810   if (src)
10811     memset (mask + 6, 0xff, 6);
10812
10813   if (tag2 || dot1ad)
10814     {
10815       /* inner vlan tag */
10816       if (tag2)
10817         {
10818           mask[19] = 0xff;
10819           mask[18] = 0x0f;
10820         }
10821       if (cos2)
10822         mask[18] |= 0xe0;
10823       if (proto)
10824         mask[21] = mask[20] = 0xff;
10825       if (tag1)
10826         {
10827           mask[15] = 0xff;
10828           mask[14] = 0x0f;
10829         }
10830       if (cos1)
10831         mask[14] |= 0xe0;
10832       *maskp = mask;
10833       return 1;
10834     }
10835   if (tag1 | dot1q)
10836     {
10837       if (tag1)
10838         {
10839           mask[15] = 0xff;
10840           mask[14] = 0x0f;
10841         }
10842       if (cos1)
10843         mask[14] |= 0xe0;
10844       if (proto)
10845         mask[16] = mask[17] = 0xff;
10846
10847       *maskp = mask;
10848       return 1;
10849     }
10850   if (cos2)
10851     mask[18] |= 0xe0;
10852   if (cos1)
10853     mask[14] |= 0xe0;
10854   if (proto)
10855     mask[12] = mask[13] = 0xff;
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_classify_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u32 *skipp = va_arg (*args, u32 *);
10866   u32 *matchp = va_arg (*args, u32 *);
10867   u32 match;
10868   u8 *mask = 0;
10869   u8 *l2 = 0;
10870   u8 *l3 = 0;
10871   u8 *l4 = 0;
10872   int i;
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10877         ;
10878       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10879         ;
10880       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10881         ;
10882       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10883         ;
10884       else
10885         break;
10886     }
10887
10888   if (l4 && !l3)
10889     {
10890       vec_free (mask);
10891       vec_free (l2);
10892       vec_free (l4);
10893       return 0;
10894     }
10895
10896   if (mask || l2 || l3 || l4)
10897     {
10898       if (l2 || l3 || l4)
10899         {
10900           /* "With a free Ethernet header in every package" */
10901           if (l2 == 0)
10902             vec_validate (l2, 13);
10903           mask = l2;
10904           if (vec_len (l3))
10905             {
10906               vec_append (mask, l3);
10907               vec_free (l3);
10908             }
10909           if (vec_len (l4))
10910             {
10911               vec_append (mask, l4);
10912               vec_free (l4);
10913             }
10914         }
10915
10916       /* Scan forward looking for the first significant mask octet */
10917       for (i = 0; i < vec_len (mask); i++)
10918         if (mask[i])
10919           break;
10920
10921       /* compute (skip, match) params */
10922       *skipp = i / sizeof (u32x4);
10923       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10924
10925       /* Pad mask to an even multiple of the vector size */
10926       while (vec_len (mask) % sizeof (u32x4))
10927         vec_add1 (mask, 0);
10928
10929       match = vec_len (mask) / sizeof (u32x4);
10930
10931       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10932         {
10933           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10934           if (*tmp || *(tmp + 1))
10935             break;
10936           match--;
10937         }
10938       if (match == 0)
10939         clib_warning ("BUG: match 0");
10940
10941       _vec_len (mask) = match * sizeof (u32x4);
10942
10943       *matchp = match;
10944       *maskp = mask;
10945
10946       return 1;
10947     }
10948
10949   return 0;
10950 }
10951 #endif /* VPP_API_TEST_BUILTIN */
10952
10953 #define foreach_l2_next                         \
10954 _(drop, DROP)                                   \
10955 _(ethernet, ETHERNET_INPUT)                     \
10956 _(ip4, IP4_INPUT)                               \
10957 _(ip6, IP6_INPUT)
10958
10959 uword
10960 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10961 {
10962   u32 *miss_next_indexp = va_arg (*args, u32 *);
10963   u32 next_index = 0;
10964   u32 tmp;
10965
10966 #define _(n,N) \
10967   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10968   foreach_l2_next;
10969 #undef _
10970
10971   if (unformat (input, "%d", &tmp))
10972     {
10973       next_index = tmp;
10974       goto out;
10975     }
10976
10977   return 0;
10978
10979 out:
10980   *miss_next_indexp = next_index;
10981   return 1;
10982 }
10983
10984 #define foreach_ip_next                         \
10985 _(drop, DROP)                                   \
10986 _(local, LOCAL)                                 \
10987 _(rewrite, REWRITE)
10988
10989 uword
10990 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10991 {
10992   u32 *miss_next_indexp = va_arg (*args, u32 *);
10993   u32 next_index = 0;
10994   u32 tmp;
10995
10996 #define _(n,N) \
10997   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10998   foreach_ip_next;
10999 #undef _
11000
11001   if (unformat (input, "%d", &tmp))
11002     {
11003       next_index = tmp;
11004       goto out;
11005     }
11006
11007   return 0;
11008
11009 out:
11010   *miss_next_indexp = next_index;
11011   return 1;
11012 }
11013
11014 #define foreach_acl_next                        \
11015 _(deny, DENY)
11016
11017 uword
11018 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11019 {
11020   u32 *miss_next_indexp = va_arg (*args, u32 *);
11021   u32 next_index = 0;
11022   u32 tmp;
11023
11024 #define _(n,N) \
11025   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11026   foreach_acl_next;
11027 #undef _
11028
11029   if (unformat (input, "permit"))
11030     {
11031       next_index = ~0;
11032       goto out;
11033     }
11034   else if (unformat (input, "%d", &tmp))
11035     {
11036       next_index = tmp;
11037       goto out;
11038     }
11039
11040   return 0;
11041
11042 out:
11043   *miss_next_indexp = next_index;
11044   return 1;
11045 }
11046
11047 uword
11048 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *r = va_arg (*args, u32 *);
11051
11052   if (unformat (input, "conform-color"))
11053     *r = POLICE_CONFORM;
11054   else if (unformat (input, "exceed-color"))
11055     *r = POLICE_EXCEED;
11056   else
11057     return 0;
11058
11059   return 1;
11060 }
11061
11062 static int
11063 api_classify_add_del_table (vat_main_t * vam)
11064 {
11065   unformat_input_t *i = vam->input;
11066   vl_api_classify_add_del_table_t *mp;
11067
11068   u32 nbuckets = 2;
11069   u32 skip = ~0;
11070   u32 match = ~0;
11071   int is_add = 1;
11072   int del_chain = 0;
11073   u32 table_index = ~0;
11074   u32 next_table_index = ~0;
11075   u32 miss_next_index = ~0;
11076   u32 memory_size = 32 << 20;
11077   u8 *mask = 0;
11078   u32 current_data_flag = 0;
11079   int current_data_offset = 0;
11080   int ret;
11081
11082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11083     {
11084       if (unformat (i, "del"))
11085         is_add = 0;
11086       else if (unformat (i, "del-chain"))
11087         {
11088           is_add = 0;
11089           del_chain = 1;
11090         }
11091       else if (unformat (i, "buckets %d", &nbuckets))
11092         ;
11093       else if (unformat (i, "memory_size %d", &memory_size))
11094         ;
11095       else if (unformat (i, "skip %d", &skip))
11096         ;
11097       else if (unformat (i, "match %d", &match))
11098         ;
11099       else if (unformat (i, "table %d", &table_index))
11100         ;
11101       else if (unformat (i, "mask %U", unformat_classify_mask,
11102                          &mask, &skip, &match))
11103         ;
11104       else if (unformat (i, "next-table %d", &next_table_index))
11105         ;
11106       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11107                          &miss_next_index))
11108         ;
11109       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11110                          &miss_next_index))
11111         ;
11112       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11113                          &miss_next_index))
11114         ;
11115       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11116         ;
11117       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11118         ;
11119       else
11120         break;
11121     }
11122
11123   if (is_add && mask == 0)
11124     {
11125       errmsg ("Mask required");
11126       return -99;
11127     }
11128
11129   if (is_add && skip == ~0)
11130     {
11131       errmsg ("skip count required");
11132       return -99;
11133     }
11134
11135   if (is_add && match == ~0)
11136     {
11137       errmsg ("match count required");
11138       return -99;
11139     }
11140
11141   if (!is_add && table_index == ~0)
11142     {
11143       errmsg ("table index required for delete");
11144       return -99;
11145     }
11146
11147   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11148
11149   mp->is_add = is_add;
11150   mp->del_chain = del_chain;
11151   mp->table_index = ntohl (table_index);
11152   mp->nbuckets = ntohl (nbuckets);
11153   mp->memory_size = ntohl (memory_size);
11154   mp->skip_n_vectors = ntohl (skip);
11155   mp->match_n_vectors = ntohl (match);
11156   mp->next_table_index = ntohl (next_table_index);
11157   mp->miss_next_index = ntohl (miss_next_index);
11158   mp->current_data_flag = ntohl (current_data_flag);
11159   mp->current_data_offset = ntohl (current_data_offset);
11160   clib_memcpy (mp->mask, mask, vec_len (mask));
11161
11162   vec_free (mask);
11163
11164   S (mp);
11165   W (ret);
11166   return ret;
11167 }
11168
11169 #if VPP_API_TEST_BUILTIN == 0
11170 uword
11171 unformat_l4_match (unformat_input_t * input, va_list * args)
11172 {
11173   u8 **matchp = va_arg (*args, u8 **);
11174
11175   u8 *proto_header = 0;
11176   int src_port = 0;
11177   int dst_port = 0;
11178
11179   tcpudp_header_t h;
11180
11181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (input, "src_port %d", &src_port))
11184         ;
11185       else if (unformat (input, "dst_port %d", &dst_port))
11186         ;
11187       else
11188         return 0;
11189     }
11190
11191   h.src_port = clib_host_to_net_u16 (src_port);
11192   h.dst_port = clib_host_to_net_u16 (dst_port);
11193   vec_validate (proto_header, sizeof (h) - 1);
11194   memcpy (proto_header, &h, sizeof (h));
11195
11196   *matchp = proto_header;
11197
11198   return 1;
11199 }
11200
11201 uword
11202 unformat_ip4_match (unformat_input_t * input, va_list * args)
11203 {
11204   u8 **matchp = va_arg (*args, u8 **);
11205   u8 *match = 0;
11206   ip4_header_t *ip;
11207   int version = 0;
11208   u32 version_val;
11209   int hdr_length = 0;
11210   u32 hdr_length_val;
11211   int src = 0, dst = 0;
11212   ip4_address_t src_val, dst_val;
11213   int proto = 0;
11214   u32 proto_val;
11215   int tos = 0;
11216   u32 tos_val;
11217   int length = 0;
11218   u32 length_val;
11219   int fragment_id = 0;
11220   u32 fragment_id_val;
11221   int ttl = 0;
11222   int ttl_val;
11223   int checksum = 0;
11224   u32 checksum_val;
11225
11226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11227     {
11228       if (unformat (input, "version %d", &version_val))
11229         version = 1;
11230       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11231         hdr_length = 1;
11232       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11233         src = 1;
11234       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11235         dst = 1;
11236       else if (unformat (input, "proto %d", &proto_val))
11237         proto = 1;
11238       else if (unformat (input, "tos %d", &tos_val))
11239         tos = 1;
11240       else if (unformat (input, "length %d", &length_val))
11241         length = 1;
11242       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11243         fragment_id = 1;
11244       else if (unformat (input, "ttl %d", &ttl_val))
11245         ttl = 1;
11246       else if (unformat (input, "checksum %d", &checksum_val))
11247         checksum = 1;
11248       else
11249         break;
11250     }
11251
11252   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11253       + ttl + checksum == 0)
11254     return 0;
11255
11256   /*
11257    * Aligned because we use the real comparison functions
11258    */
11259   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11260
11261   ip = (ip4_header_t *) match;
11262
11263   /* These are realistically matched in practice */
11264   if (src)
11265     ip->src_address.as_u32 = src_val.as_u32;
11266
11267   if (dst)
11268     ip->dst_address.as_u32 = dst_val.as_u32;
11269
11270   if (proto)
11271     ip->protocol = proto_val;
11272
11273
11274   /* These are not, but they're included for completeness */
11275   if (version)
11276     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11277
11278   if (hdr_length)
11279     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11280
11281   if (tos)
11282     ip->tos = tos_val;
11283
11284   if (length)
11285     ip->length = clib_host_to_net_u16 (length_val);
11286
11287   if (ttl)
11288     ip->ttl = ttl_val;
11289
11290   if (checksum)
11291     ip->checksum = clib_host_to_net_u16 (checksum_val);
11292
11293   *matchp = match;
11294   return 1;
11295 }
11296
11297 uword
11298 unformat_ip6_match (unformat_input_t * input, va_list * args)
11299 {
11300   u8 **matchp = va_arg (*args, u8 **);
11301   u8 *match = 0;
11302   ip6_header_t *ip;
11303   int version = 0;
11304   u32 version_val;
11305   u8 traffic_class = 0;
11306   u32 traffic_class_val = 0;
11307   u8 flow_label = 0;
11308   u8 flow_label_val;
11309   int src = 0, dst = 0;
11310   ip6_address_t src_val, dst_val;
11311   int proto = 0;
11312   u32 proto_val;
11313   int payload_length = 0;
11314   u32 payload_length_val;
11315   int hop_limit = 0;
11316   int hop_limit_val;
11317   u32 ip_version_traffic_class_and_flow_label;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "version %d", &version_val))
11322         version = 1;
11323       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11324         traffic_class = 1;
11325       else if (unformat (input, "flow_label %d", &flow_label_val))
11326         flow_label = 1;
11327       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11328         src = 1;
11329       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11330         dst = 1;
11331       else if (unformat (input, "proto %d", &proto_val))
11332         proto = 1;
11333       else if (unformat (input, "payload_length %d", &payload_length_val))
11334         payload_length = 1;
11335       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11336         hop_limit = 1;
11337       else
11338         break;
11339     }
11340
11341   if (version + traffic_class + flow_label + src + dst + proto +
11342       payload_length + hop_limit == 0)
11343     return 0;
11344
11345   /*
11346    * Aligned because we use the real comparison functions
11347    */
11348   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11349
11350   ip = (ip6_header_t *) match;
11351
11352   if (src)
11353     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11354
11355   if (dst)
11356     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11357
11358   if (proto)
11359     ip->protocol = proto_val;
11360
11361   ip_version_traffic_class_and_flow_label = 0;
11362
11363   if (version)
11364     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11365
11366   if (traffic_class)
11367     ip_version_traffic_class_and_flow_label |=
11368       (traffic_class_val & 0xFF) << 20;
11369
11370   if (flow_label)
11371     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11372
11373   ip->ip_version_traffic_class_and_flow_label =
11374     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11375
11376   if (payload_length)
11377     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11378
11379   if (hop_limit)
11380     ip->hop_limit = hop_limit_val;
11381
11382   *matchp = match;
11383   return 1;
11384 }
11385
11386 uword
11387 unformat_l3_match (unformat_input_t * input, va_list * args)
11388 {
11389   u8 **matchp = va_arg (*args, u8 **);
11390
11391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11394         return 1;
11395       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11396         return 1;
11397       else
11398         break;
11399     }
11400   return 0;
11401 }
11402
11403 uword
11404 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11405 {
11406   u8 *tagp = va_arg (*args, u8 *);
11407   u32 tag;
11408
11409   if (unformat (input, "%d", &tag))
11410     {
11411       tagp[0] = (tag >> 8) & 0x0F;
11412       tagp[1] = tag & 0xFF;
11413       return 1;
11414     }
11415
11416   return 0;
11417 }
11418
11419 uword
11420 unformat_l2_match (unformat_input_t * input, va_list * args)
11421 {
11422   u8 **matchp = va_arg (*args, u8 **);
11423   u8 *match = 0;
11424   u8 src = 0;
11425   u8 src_val[6];
11426   u8 dst = 0;
11427   u8 dst_val[6];
11428   u8 proto = 0;
11429   u16 proto_val;
11430   u8 tag1 = 0;
11431   u8 tag1_val[2];
11432   u8 tag2 = 0;
11433   u8 tag2_val[2];
11434   int len = 14;
11435   u8 ignore_tag1 = 0;
11436   u8 ignore_tag2 = 0;
11437   u8 cos1 = 0;
11438   u8 cos2 = 0;
11439   u32 cos1_val = 0;
11440   u32 cos2_val = 0;
11441
11442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11445         src = 1;
11446       else
11447         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11448         dst = 1;
11449       else if (unformat (input, "proto %U",
11450                          unformat_ethernet_type_host_byte_order, &proto_val))
11451         proto = 1;
11452       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11453         tag1 = 1;
11454       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11455         tag2 = 1;
11456       else if (unformat (input, "ignore-tag1"))
11457         ignore_tag1 = 1;
11458       else if (unformat (input, "ignore-tag2"))
11459         ignore_tag2 = 1;
11460       else if (unformat (input, "cos1 %d", &cos1_val))
11461         cos1 = 1;
11462       else if (unformat (input, "cos2 %d", &cos2_val))
11463         cos2 = 1;
11464       else
11465         break;
11466     }
11467   if ((src + dst + proto + tag1 + tag2 +
11468        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11469     return 0;
11470
11471   if (tag1 || ignore_tag1 || cos1)
11472     len = 18;
11473   if (tag2 || ignore_tag2 || cos2)
11474     len = 22;
11475
11476   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11477
11478   if (dst)
11479     clib_memcpy (match, dst_val, 6);
11480
11481   if (src)
11482     clib_memcpy (match + 6, src_val, 6);
11483
11484   if (tag2)
11485     {
11486       /* inner vlan tag */
11487       match[19] = tag2_val[1];
11488       match[18] = tag2_val[0];
11489       if (cos2)
11490         match[18] |= (cos2_val & 0x7) << 5;
11491       if (proto)
11492         {
11493           match[21] = proto_val & 0xff;
11494           match[20] = proto_val >> 8;
11495         }
11496       if (tag1)
11497         {
11498           match[15] = tag1_val[1];
11499           match[14] = tag1_val[0];
11500         }
11501       if (cos1)
11502         match[14] |= (cos1_val & 0x7) << 5;
11503       *matchp = match;
11504       return 1;
11505     }
11506   if (tag1)
11507     {
11508       match[15] = tag1_val[1];
11509       match[14] = tag1_val[0];
11510       if (proto)
11511         {
11512           match[17] = proto_val & 0xff;
11513           match[16] = proto_val >> 8;
11514         }
11515       if (cos1)
11516         match[14] |= (cos1_val & 0x7) << 5;
11517
11518       *matchp = match;
11519       return 1;
11520     }
11521   if (cos2)
11522     match[18] |= (cos2_val & 0x7) << 5;
11523   if (cos1)
11524     match[14] |= (cos1_val & 0x7) << 5;
11525   if (proto)
11526     {
11527       match[13] = proto_val & 0xff;
11528       match[12] = proto_val >> 8;
11529     }
11530
11531   *matchp = match;
11532   return 1;
11533 }
11534 #endif
11535
11536 uword
11537 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11538 {
11539   u8 **matchp = va_arg (*args, u8 **);
11540   u32 skip_n_vectors = va_arg (*args, u32);
11541   u32 match_n_vectors = va_arg (*args, u32);
11542
11543   u8 *match = 0;
11544   u8 *l2 = 0;
11545   u8 *l3 = 0;
11546   u8 *l4 = 0;
11547
11548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (input, "hex %U", unformat_hex_string, &match))
11551         ;
11552       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11553         ;
11554       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11555         ;
11556       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11557         ;
11558       else
11559         break;
11560     }
11561
11562   if (l4 && !l3)
11563     {
11564       vec_free (match);
11565       vec_free (l2);
11566       vec_free (l4);
11567       return 0;
11568     }
11569
11570   if (match || l2 || l3 || l4)
11571     {
11572       if (l2 || l3 || l4)
11573         {
11574           /* "Win a free Ethernet header in every packet" */
11575           if (l2 == 0)
11576             vec_validate_aligned (l2, 13, sizeof (u32x4));
11577           match = l2;
11578           if (vec_len (l3))
11579             {
11580               vec_append_aligned (match, l3, sizeof (u32x4));
11581               vec_free (l3);
11582             }
11583           if (vec_len (l4))
11584             {
11585               vec_append_aligned (match, l4, sizeof (u32x4));
11586               vec_free (l4);
11587             }
11588         }
11589
11590       /* Make sure the vector is big enough even if key is all 0's */
11591       vec_validate_aligned
11592         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11593          sizeof (u32x4));
11594
11595       /* Set size, include skipped vectors */
11596       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11597
11598       *matchp = match;
11599
11600       return 1;
11601     }
11602
11603   return 0;
11604 }
11605
11606 static int
11607 api_classify_add_del_session (vat_main_t * vam)
11608 {
11609   unformat_input_t *i = vam->input;
11610   vl_api_classify_add_del_session_t *mp;
11611   int is_add = 1;
11612   u32 table_index = ~0;
11613   u32 hit_next_index = ~0;
11614   u32 opaque_index = ~0;
11615   u8 *match = 0;
11616   i32 advance = 0;
11617   u32 skip_n_vectors = 0;
11618   u32 match_n_vectors = 0;
11619   u32 action = 0;
11620   u32 metadata = 0;
11621   int ret;
11622
11623   /*
11624    * Warning: you have to supply skip_n and match_n
11625    * because the API client cant simply look at the classify
11626    * table object.
11627    */
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "del"))
11632         is_add = 0;
11633       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11634                          &hit_next_index))
11635         ;
11636       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11637                          &hit_next_index))
11638         ;
11639       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11640                          &hit_next_index))
11641         ;
11642       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11643         ;
11644       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11645         ;
11646       else if (unformat (i, "opaque-index %d", &opaque_index))
11647         ;
11648       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11649         ;
11650       else if (unformat (i, "match_n %d", &match_n_vectors))
11651         ;
11652       else if (unformat (i, "match %U", api_unformat_classify_match,
11653                          &match, skip_n_vectors, match_n_vectors))
11654         ;
11655       else if (unformat (i, "advance %d", &advance))
11656         ;
11657       else if (unformat (i, "table-index %d", &table_index))
11658         ;
11659       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11660         action = 1;
11661       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11662         action = 2;
11663       else if (unformat (i, "action %d", &action))
11664         ;
11665       else if (unformat (i, "metadata %d", &metadata))
11666         ;
11667       else
11668         break;
11669     }
11670
11671   if (table_index == ~0)
11672     {
11673       errmsg ("Table index required");
11674       return -99;
11675     }
11676
11677   if (is_add && match == 0)
11678     {
11679       errmsg ("Match value required");
11680       return -99;
11681     }
11682
11683   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11684
11685   mp->is_add = is_add;
11686   mp->table_index = ntohl (table_index);
11687   mp->hit_next_index = ntohl (hit_next_index);
11688   mp->opaque_index = ntohl (opaque_index);
11689   mp->advance = ntohl (advance);
11690   mp->action = action;
11691   mp->metadata = ntohl (metadata);
11692   clib_memcpy (mp->match, match, vec_len (match));
11693   vec_free (match);
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_classify_set_interface_ip_table (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_classify_set_interface_ip_table_t *mp;
11705   u32 sw_if_index;
11706   int sw_if_index_set;
11707   u32 table_index = ~0;
11708   u8 is_ipv6 = 0;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "table %d", &table_index))
11718         ;
11719       else
11720         {
11721           clib_warning ("parse error '%U'", format_unformat_error, i);
11722           return -99;
11723         }
11724     }
11725
11726   if (sw_if_index_set == 0)
11727     {
11728       errmsg ("missing interface name or sw_if_index");
11729       return -99;
11730     }
11731
11732
11733   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11734
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->table_index = ntohl (table_index);
11737   mp->is_ipv6 = is_ipv6;
11738
11739   S (mp);
11740   W (ret);
11741   return ret;
11742 }
11743
11744 static int
11745 api_classify_set_interface_l2_tables (vat_main_t * vam)
11746 {
11747   unformat_input_t *i = vam->input;
11748   vl_api_classify_set_interface_l2_tables_t *mp;
11749   u32 sw_if_index;
11750   int sw_if_index_set;
11751   u32 ip4_table_index = ~0;
11752   u32 ip6_table_index = ~0;
11753   u32 other_table_index = ~0;
11754   u32 is_input = 1;
11755   int ret;
11756
11757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11758     {
11759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11762         sw_if_index_set = 1;
11763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11764         ;
11765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11766         ;
11767       else if (unformat (i, "other-table %d", &other_table_index))
11768         ;
11769       else if (unformat (i, "is-input %d", &is_input))
11770         ;
11771       else
11772         {
11773           clib_warning ("parse error '%U'", format_unformat_error, i);
11774           return -99;
11775         }
11776     }
11777
11778   if (sw_if_index_set == 0)
11779     {
11780       errmsg ("missing interface name or sw_if_index");
11781       return -99;
11782     }
11783
11784
11785   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11786
11787   mp->sw_if_index = ntohl (sw_if_index);
11788   mp->ip4_table_index = ntohl (ip4_table_index);
11789   mp->ip6_table_index = ntohl (ip6_table_index);
11790   mp->other_table_index = ntohl (other_table_index);
11791   mp->is_input = (u8) is_input;
11792
11793   S (mp);
11794   W (ret);
11795   return ret;
11796 }
11797
11798 static int
11799 api_set_ipfix_exporter (vat_main_t * vam)
11800 {
11801   unformat_input_t *i = vam->input;
11802   vl_api_set_ipfix_exporter_t *mp;
11803   ip4_address_t collector_address;
11804   u8 collector_address_set = 0;
11805   u32 collector_port = ~0;
11806   ip4_address_t src_address;
11807   u8 src_address_set = 0;
11808   u32 vrf_id = ~0;
11809   u32 path_mtu = ~0;
11810   u32 template_interval = ~0;
11811   u8 udp_checksum = 0;
11812   int ret;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "collector_address %U", unformat_ip4_address,
11817                     &collector_address))
11818         collector_address_set = 1;
11819       else if (unformat (i, "collector_port %d", &collector_port))
11820         ;
11821       else if (unformat (i, "src_address %U", unformat_ip4_address,
11822                          &src_address))
11823         src_address_set = 1;
11824       else if (unformat (i, "vrf_id %d", &vrf_id))
11825         ;
11826       else if (unformat (i, "path_mtu %d", &path_mtu))
11827         ;
11828       else if (unformat (i, "template_interval %d", &template_interval))
11829         ;
11830       else if (unformat (i, "udp_checksum"))
11831         udp_checksum = 1;
11832       else
11833         break;
11834     }
11835
11836   if (collector_address_set == 0)
11837     {
11838       errmsg ("collector_address required");
11839       return -99;
11840     }
11841
11842   if (src_address_set == 0)
11843     {
11844       errmsg ("src_address required");
11845       return -99;
11846     }
11847
11848   M (SET_IPFIX_EXPORTER, mp);
11849
11850   memcpy (mp->collector_address, collector_address.data,
11851           sizeof (collector_address.data));
11852   mp->collector_port = htons ((u16) collector_port);
11853   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11854   mp->vrf_id = htonl (vrf_id);
11855   mp->path_mtu = htonl (path_mtu);
11856   mp->template_interval = htonl (template_interval);
11857   mp->udp_checksum = udp_checksum;
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_set_ipfix_classify_stream (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_set_ipfix_classify_stream_t *mp;
11869   u32 domain_id = 0;
11870   u32 src_port = UDP_DST_PORT_ipfix;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "domain %d", &domain_id))
11876         ;
11877       else if (unformat (i, "src_port %d", &src_port))
11878         ;
11879       else
11880         {
11881           errmsg ("unknown input `%U'", format_unformat_error, i);
11882           return -99;
11883         }
11884     }
11885
11886   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11887
11888   mp->domain_id = htonl (domain_id);
11889   mp->src_port = htons ((u16) src_port);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_ipfix_classify_table_add_del (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_ipfix_classify_table_add_del_t *mp;
11901   int is_add = -1;
11902   u32 classify_table_index = ~0;
11903   u8 ip_version = 0;
11904   u8 transport_protocol = 255;
11905   int ret;
11906
11907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11908     {
11909       if (unformat (i, "add"))
11910         is_add = 1;
11911       else if (unformat (i, "del"))
11912         is_add = 0;
11913       else if (unformat (i, "table %d", &classify_table_index))
11914         ;
11915       else if (unformat (i, "ip4"))
11916         ip_version = 4;
11917       else if (unformat (i, "ip6"))
11918         ip_version = 6;
11919       else if (unformat (i, "tcp"))
11920         transport_protocol = 6;
11921       else if (unformat (i, "udp"))
11922         transport_protocol = 17;
11923       else
11924         {
11925           errmsg ("unknown input `%U'", format_unformat_error, i);
11926           return -99;
11927         }
11928     }
11929
11930   if (is_add == -1)
11931     {
11932       errmsg ("expecting: add|del");
11933       return -99;
11934     }
11935   if (classify_table_index == ~0)
11936     {
11937       errmsg ("classifier table not specified");
11938       return -99;
11939     }
11940   if (ip_version == 0)
11941     {
11942       errmsg ("IP version not specified");
11943       return -99;
11944     }
11945
11946   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11947
11948   mp->is_add = is_add;
11949   mp->table_id = htonl (classify_table_index);
11950   mp->ip_version = ip_version;
11951   mp->transport_protocol = transport_protocol;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_get_node_index (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_get_node_index_t *mp;
11963   u8 *name = 0;
11964   int ret;
11965
11966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (i, "node %s", &name))
11969         ;
11970       else
11971         break;
11972     }
11973   if (name == 0)
11974     {
11975       errmsg ("node name required");
11976       return -99;
11977     }
11978   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11979     {
11980       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11981       return -99;
11982     }
11983
11984   M (GET_NODE_INDEX, mp);
11985   clib_memcpy (mp->node_name, name, vec_len (name));
11986   vec_free (name);
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993 static int
11994 api_get_next_index (vat_main_t * vam)
11995 {
11996   unformat_input_t *i = vam->input;
11997   vl_api_get_next_index_t *mp;
11998   u8 *node_name = 0, *next_node_name = 0;
11999   int ret;
12000
12001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (i, "node-name %s", &node_name))
12004         ;
12005       else if (unformat (i, "next-node-name %s", &next_node_name))
12006         break;
12007     }
12008
12009   if (node_name == 0)
12010     {
12011       errmsg ("node name required");
12012       return -99;
12013     }
12014   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12015     {
12016       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12017       return -99;
12018     }
12019
12020   if (next_node_name == 0)
12021     {
12022       errmsg ("next node name required");
12023       return -99;
12024     }
12025   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12026     {
12027       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12028       return -99;
12029     }
12030
12031   M (GET_NEXT_INDEX, mp);
12032   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12033   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12034   vec_free (node_name);
12035   vec_free (next_node_name);
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_add_node_next (vat_main_t * vam)
12044 {
12045   unformat_input_t *i = vam->input;
12046   vl_api_add_node_next_t *mp;
12047   u8 *name = 0;
12048   u8 *next = 0;
12049   int ret;
12050
12051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (i, "node %s", &name))
12054         ;
12055       else if (unformat (i, "next %s", &next))
12056         ;
12057       else
12058         break;
12059     }
12060   if (name == 0)
12061     {
12062       errmsg ("node name required");
12063       return -99;
12064     }
12065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12066     {
12067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12068       return -99;
12069     }
12070   if (next == 0)
12071     {
12072       errmsg ("next node required");
12073       return -99;
12074     }
12075   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12076     {
12077       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12078       return -99;
12079     }
12080
12081   M (ADD_NODE_NEXT, mp);
12082   clib_memcpy (mp->node_name, name, vec_len (name));
12083   clib_memcpy (mp->next_name, next, vec_len (next));
12084   vec_free (name);
12085   vec_free (next);
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_l2tpv3_create_tunnel (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   ip6_address_t client_address, our_address;
12097   int client_address_set = 0;
12098   int our_address_set = 0;
12099   u32 local_session_id = 0;
12100   u32 remote_session_id = 0;
12101   u64 local_cookie = 0;
12102   u64 remote_cookie = 0;
12103   u8 l2_sublayer_present = 0;
12104   vl_api_l2tpv3_create_tunnel_t *mp;
12105   int ret;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "client_address %U", unformat_ip6_address,
12110                     &client_address))
12111         client_address_set = 1;
12112       else if (unformat (i, "our_address %U", unformat_ip6_address,
12113                          &our_address))
12114         our_address_set = 1;
12115       else if (unformat (i, "local_session_id %d", &local_session_id))
12116         ;
12117       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12118         ;
12119       else if (unformat (i, "local_cookie %lld", &local_cookie))
12120         ;
12121       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12122         ;
12123       else if (unformat (i, "l2-sublayer-present"))
12124         l2_sublayer_present = 1;
12125       else
12126         break;
12127     }
12128
12129   if (client_address_set == 0)
12130     {
12131       errmsg ("client_address required");
12132       return -99;
12133     }
12134
12135   if (our_address_set == 0)
12136     {
12137       errmsg ("our_address required");
12138       return -99;
12139     }
12140
12141   M (L2TPV3_CREATE_TUNNEL, mp);
12142
12143   clib_memcpy (mp->client_address, client_address.as_u8,
12144                sizeof (mp->client_address));
12145
12146   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12147
12148   mp->local_session_id = ntohl (local_session_id);
12149   mp->remote_session_id = ntohl (remote_session_id);
12150   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12151   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12152   mp->l2_sublayer_present = l2_sublayer_present;
12153   mp->is_ipv6 = 1;
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   u32 sw_if_index;
12165   u8 sw_if_index_set = 0;
12166   u64 new_local_cookie = 0;
12167   u64 new_remote_cookie = 0;
12168   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12174         sw_if_index_set = 1;
12175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12178         ;
12179       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12180         ;
12181       else
12182         break;
12183     }
12184
12185   if (sw_if_index_set == 0)
12186     {
12187       errmsg ("missing interface name or sw_if_index");
12188       return -99;
12189     }
12190
12191   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12192
12193   mp->sw_if_index = ntohl (sw_if_index);
12194   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12195   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_l2tpv3_interface_enable_disable_t *mp;
12207   u32 sw_if_index;
12208   u8 sw_if_index_set = 0;
12209   u8 enable_disable = 1;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "enable"))
12219         enable_disable = 1;
12220       else if (unformat (i, "disable"))
12221         enable_disable = 0;
12222       else
12223         break;
12224     }
12225
12226   if (sw_if_index_set == 0)
12227     {
12228       errmsg ("missing interface name or sw_if_index");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12233
12234   mp->sw_if_index = ntohl (sw_if_index);
12235   mp->enable_disable = enable_disable;
12236
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 static int
12243 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12244 {
12245   unformat_input_t *i = vam->input;
12246   vl_api_l2tpv3_set_lookup_key_t *mp;
12247   u8 key = ~0;
12248   int ret;
12249
12250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12251     {
12252       if (unformat (i, "lookup_v6_src"))
12253         key = L2T_LOOKUP_SRC_ADDRESS;
12254       else if (unformat (i, "lookup_v6_dst"))
12255         key = L2T_LOOKUP_DST_ADDRESS;
12256       else if (unformat (i, "lookup_session_id"))
12257         key = L2T_LOOKUP_SESSION_ID;
12258       else
12259         break;
12260     }
12261
12262   if (key == (u8) ~ 0)
12263     {
12264       errmsg ("l2tp session lookup key unset");
12265       return -99;
12266     }
12267
12268   M (L2TPV3_SET_LOOKUP_KEY, mp);
12269
12270   mp->key = key;
12271
12272   S (mp);
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12278   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281
12282   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12283          format_ip6_address, mp->our_address,
12284          format_ip6_address, mp->client_address,
12285          clib_net_to_host_u32 (mp->sw_if_index));
12286
12287   print (vam->ofp,
12288          "   local cookies %016llx %016llx remote cookie %016llx",
12289          clib_net_to_host_u64 (mp->local_cookie[0]),
12290          clib_net_to_host_u64 (mp->local_cookie[1]),
12291          clib_net_to_host_u64 (mp->remote_cookie));
12292
12293   print (vam->ofp, "   local session-id %d remote session-id %d",
12294          clib_net_to_host_u32 (mp->local_session_id),
12295          clib_net_to_host_u32 (mp->remote_session_id));
12296
12297   print (vam->ofp, "   l2 specific sublayer %s\n",
12298          mp->l2_sublayer_present ? "preset" : "absent");
12299
12300 }
12301
12302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12304 {
12305   vat_main_t *vam = &vat_main;
12306   vat_json_node_t *node = NULL;
12307   struct in6_addr addr;
12308
12309   if (VAT_JSON_ARRAY != vam->json_tree.type)
12310     {
12311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12312       vat_json_init_array (&vam->json_tree);
12313     }
12314   node = vat_json_array_add (&vam->json_tree);
12315
12316   vat_json_init_object (node);
12317
12318   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12319   vat_json_object_add_ip6 (node, "our_address", addr);
12320   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12321   vat_json_object_add_ip6 (node, "client_address", addr);
12322
12323   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12324   vat_json_init_array (lc);
12325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12327   vat_json_object_add_uint (node, "remote_cookie",
12328                             clib_net_to_host_u64 (mp->remote_cookie));
12329
12330   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12331   vat_json_object_add_uint (node, "local_session_id",
12332                             clib_net_to_host_u32 (mp->local_session_id));
12333   vat_json_object_add_uint (node, "remote_session_id",
12334                             clib_net_to_host_u32 (mp->remote_session_id));
12335   vat_json_object_add_string_copy (node, "l2_sublayer",
12336                                    mp->l2_sublayer_present ? (u8 *) "present"
12337                                    : (u8 *) "absent");
12338 }
12339
12340 static int
12341 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12342 {
12343   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12344   vl_api_control_ping_t *mp_ping;
12345   int ret;
12346
12347   /* Get list of l2tpv3-tunnel interfaces */
12348   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12349   S (mp);
12350
12351   /* Use a control ping for synchronization */
12352   MPING (CONTROL_PING, mp_ping);
12353   S (mp_ping);
12354
12355   W (ret);
12356   return ret;
12357 }
12358
12359
12360 static void vl_api_sw_interface_tap_details_t_handler
12361   (vl_api_sw_interface_tap_details_t * mp)
12362 {
12363   vat_main_t *vam = &vat_main;
12364
12365   print (vam->ofp, "%-16s %d",
12366          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12367 }
12368
12369 static void vl_api_sw_interface_tap_details_t_handler_json
12370   (vl_api_sw_interface_tap_details_t * mp)
12371 {
12372   vat_main_t *vam = &vat_main;
12373   vat_json_node_t *node = NULL;
12374
12375   if (VAT_JSON_ARRAY != vam->json_tree.type)
12376     {
12377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12378       vat_json_init_array (&vam->json_tree);
12379     }
12380   node = vat_json_array_add (&vam->json_tree);
12381
12382   vat_json_init_object (node);
12383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12384   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12385 }
12386
12387 static int
12388 api_sw_interface_tap_dump (vat_main_t * vam)
12389 {
12390   vl_api_sw_interface_tap_dump_t *mp;
12391   vl_api_control_ping_t *mp_ping;
12392   int ret;
12393
12394   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12395   /* Get list of tap interfaces */
12396   M (SW_INTERFACE_TAP_DUMP, mp);
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   MPING (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static void vl_api_sw_interface_tap_v2_details_t_handler
12408   (vl_api_sw_interface_tap_v2_details_t * mp)
12409 {
12410   vat_main_t *vam = &vat_main;
12411
12412   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12413                     mp->host_ip4_prefix_len);
12414   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12415                     mp->host_ip6_prefix_len);
12416
12417   print (vam->ofp,
12418          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12419          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12420          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12421          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12422          mp->host_bridge, ip4, ip6);
12423
12424   vec_free (ip4);
12425   vec_free (ip6);
12426 }
12427
12428 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12429   (vl_api_sw_interface_tap_v2_details_t * mp)
12430 {
12431   vat_main_t *vam = &vat_main;
12432   vat_json_node_t *node = NULL;
12433
12434   if (VAT_JSON_ARRAY != vam->json_tree.type)
12435     {
12436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12437       vat_json_init_array (&vam->json_tree);
12438     }
12439   node = vat_json_array_add (&vam->json_tree);
12440
12441   vat_json_init_object (node);
12442   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12444   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12445   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12446   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12447   vat_json_object_add_string_copy (node, "host_mac_addr",
12448                                    format (0, "%U", format_ethernet_address,
12449                                            &mp->host_mac_addr));
12450   vat_json_object_add_string_copy (node, "host_namespace",
12451                                    mp->host_namespace);
12452   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12453   vat_json_object_add_string_copy (node, "host_ip4_addr",
12454                                    format (0, "%U/%d", format_ip4_address,
12455                                            mp->host_ip4_addr,
12456                                            mp->host_ip4_prefix_len));
12457   vat_json_object_add_string_copy (node, "host_ip6_addr",
12458                                    format (0, "%U/%d", format_ip6_address,
12459                                            mp->host_ip6_addr,
12460                                            mp->host_ip6_prefix_len));
12461
12462 }
12463
12464 static int
12465 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12466 {
12467   vl_api_sw_interface_tap_v2_dump_t *mp;
12468   vl_api_control_ping_t *mp_ping;
12469   int ret;
12470
12471   print (vam->ofp,
12472          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12473          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12474          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12475          "host_ip6_addr");
12476
12477   /* Get list of tap interfaces */
12478   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12479   S (mp);
12480
12481   /* Use a control ping for synchronization */
12482   MPING (CONTROL_PING, mp_ping);
12483   S (mp_ping);
12484
12485   W (ret);
12486   return ret;
12487 }
12488
12489 static uword unformat_vxlan_decap_next
12490   (unformat_input_t * input, va_list * args)
12491 {
12492   u32 *result = va_arg (*args, u32 *);
12493   u32 tmp;
12494
12495   if (unformat (input, "l2"))
12496     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12497   else if (unformat (input, "%d", &tmp))
12498     *result = tmp;
12499   else
12500     return 0;
12501   return 1;
12502 }
12503
12504 static int
12505 api_vxlan_add_del_tunnel (vat_main_t * vam)
12506 {
12507   unformat_input_t *line_input = vam->input;
12508   vl_api_vxlan_add_del_tunnel_t *mp;
12509   ip46_address_t src, dst;
12510   u8 is_add = 1;
12511   u8 ipv4_set = 0, ipv6_set = 0;
12512   u8 src_set = 0;
12513   u8 dst_set = 0;
12514   u8 grp_set = 0;
12515   u32 mcast_sw_if_index = ~0;
12516   u32 encap_vrf_id = 0;
12517   u32 decap_next_index = ~0;
12518   u32 vni = 0;
12519   int ret;
12520
12521   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12522   memset (&src, 0, sizeof src);
12523   memset (&dst, 0, sizeof dst);
12524
12525   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (line_input, "del"))
12528         is_add = 0;
12529       else
12530         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12531         {
12532           ipv4_set = 1;
12533           src_set = 1;
12534         }
12535       else
12536         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12537         {
12538           ipv4_set = 1;
12539           dst_set = 1;
12540         }
12541       else
12542         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12543         {
12544           ipv6_set = 1;
12545           src_set = 1;
12546         }
12547       else
12548         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12549         {
12550           ipv6_set = 1;
12551           dst_set = 1;
12552         }
12553       else if (unformat (line_input, "group %U %U",
12554                          unformat_ip4_address, &dst.ip4,
12555                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12556         {
12557           grp_set = dst_set = 1;
12558           ipv4_set = 1;
12559         }
12560       else if (unformat (line_input, "group %U",
12561                          unformat_ip4_address, &dst.ip4))
12562         {
12563           grp_set = dst_set = 1;
12564           ipv4_set = 1;
12565         }
12566       else if (unformat (line_input, "group %U %U",
12567                          unformat_ip6_address, &dst.ip6,
12568                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12569         {
12570           grp_set = dst_set = 1;
12571           ipv6_set = 1;
12572         }
12573       else if (unformat (line_input, "group %U",
12574                          unformat_ip6_address, &dst.ip6))
12575         {
12576           grp_set = dst_set = 1;
12577           ipv6_set = 1;
12578         }
12579       else
12580         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12581         ;
12582       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12583         ;
12584       else if (unformat (line_input, "decap-next %U",
12585                          unformat_vxlan_decap_next, &decap_next_index))
12586         ;
12587       else if (unformat (line_input, "vni %d", &vni))
12588         ;
12589       else
12590         {
12591           errmsg ("parse error '%U'", format_unformat_error, line_input);
12592           return -99;
12593         }
12594     }
12595
12596   if (src_set == 0)
12597     {
12598       errmsg ("tunnel src address not specified");
12599       return -99;
12600     }
12601   if (dst_set == 0)
12602     {
12603       errmsg ("tunnel dst address not specified");
12604       return -99;
12605     }
12606
12607   if (grp_set && !ip46_address_is_multicast (&dst))
12608     {
12609       errmsg ("tunnel group address not multicast");
12610       return -99;
12611     }
12612   if (grp_set && mcast_sw_if_index == ~0)
12613     {
12614       errmsg ("tunnel nonexistent multicast device");
12615       return -99;
12616     }
12617   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12618     {
12619       errmsg ("tunnel dst address must be unicast");
12620       return -99;
12621     }
12622
12623
12624   if (ipv4_set && ipv6_set)
12625     {
12626       errmsg ("both IPv4 and IPv6 addresses specified");
12627       return -99;
12628     }
12629
12630   if ((vni == 0) || (vni >> 24))
12631     {
12632       errmsg ("vni not specified or out of range");
12633       return -99;
12634     }
12635
12636   M (VXLAN_ADD_DEL_TUNNEL, mp);
12637
12638   if (ipv6_set)
12639     {
12640       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12641       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12642     }
12643   else
12644     {
12645       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12646       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12647     }
12648   mp->encap_vrf_id = ntohl (encap_vrf_id);
12649   mp->decap_next_index = ntohl (decap_next_index);
12650   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12651   mp->vni = ntohl (vni);
12652   mp->is_add = is_add;
12653   mp->is_ipv6 = ipv6_set;
12654
12655   S (mp);
12656   W (ret);
12657   return ret;
12658 }
12659
12660 static void vl_api_vxlan_tunnel_details_t_handler
12661   (vl_api_vxlan_tunnel_details_t * mp)
12662 {
12663   vat_main_t *vam = &vat_main;
12664   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12665   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12666
12667   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12668          ntohl (mp->sw_if_index),
12669          format_ip46_address, &src, IP46_TYPE_ANY,
12670          format_ip46_address, &dst, IP46_TYPE_ANY,
12671          ntohl (mp->encap_vrf_id),
12672          ntohl (mp->decap_next_index), ntohl (mp->vni),
12673          ntohl (mp->mcast_sw_if_index));
12674 }
12675
12676 static void vl_api_vxlan_tunnel_details_t_handler_json
12677   (vl_api_vxlan_tunnel_details_t * mp)
12678 {
12679   vat_main_t *vam = &vat_main;
12680   vat_json_node_t *node = NULL;
12681
12682   if (VAT_JSON_ARRAY != vam->json_tree.type)
12683     {
12684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12685       vat_json_init_array (&vam->json_tree);
12686     }
12687   node = vat_json_array_add (&vam->json_tree);
12688
12689   vat_json_init_object (node);
12690   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12691   if (mp->is_ipv6)
12692     {
12693       struct in6_addr ip6;
12694
12695       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12696       vat_json_object_add_ip6 (node, "src_address", ip6);
12697       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12698       vat_json_object_add_ip6 (node, "dst_address", ip6);
12699     }
12700   else
12701     {
12702       struct in_addr ip4;
12703
12704       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12705       vat_json_object_add_ip4 (node, "src_address", ip4);
12706       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12707       vat_json_object_add_ip4 (node, "dst_address", ip4);
12708     }
12709   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12710   vat_json_object_add_uint (node, "decap_next_index",
12711                             ntohl (mp->decap_next_index));
12712   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12713   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12714   vat_json_object_add_uint (node, "mcast_sw_if_index",
12715                             ntohl (mp->mcast_sw_if_index));
12716 }
12717
12718 static int
12719 api_vxlan_tunnel_dump (vat_main_t * vam)
12720 {
12721   unformat_input_t *i = vam->input;
12722   vl_api_vxlan_tunnel_dump_t *mp;
12723   vl_api_control_ping_t *mp_ping;
12724   u32 sw_if_index;
12725   u8 sw_if_index_set = 0;
12726   int ret;
12727
12728   /* Parse args required to build the message */
12729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12730     {
12731       if (unformat (i, "sw_if_index %d", &sw_if_index))
12732         sw_if_index_set = 1;
12733       else
12734         break;
12735     }
12736
12737   if (sw_if_index_set == 0)
12738     {
12739       sw_if_index = ~0;
12740     }
12741
12742   if (!vam->json_output)
12743     {
12744       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12745              "sw_if_index", "src_address", "dst_address",
12746              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12747     }
12748
12749   /* Get list of vxlan-tunnel interfaces */
12750   M (VXLAN_TUNNEL_DUMP, mp);
12751
12752   mp->sw_if_index = htonl (sw_if_index);
12753
12754   S (mp);
12755
12756   /* Use a control ping for synchronization */
12757   MPING (CONTROL_PING, mp_ping);
12758   S (mp_ping);
12759
12760   W (ret);
12761   return ret;
12762 }
12763
12764 static uword unformat_geneve_decap_next
12765   (unformat_input_t * input, va_list * args)
12766 {
12767   u32 *result = va_arg (*args, u32 *);
12768   u32 tmp;
12769
12770   if (unformat (input, "l2"))
12771     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12772   else if (unformat (input, "%d", &tmp))
12773     *result = tmp;
12774   else
12775     return 0;
12776   return 1;
12777 }
12778
12779 static int
12780 api_geneve_add_del_tunnel (vat_main_t * vam)
12781 {
12782   unformat_input_t *line_input = vam->input;
12783   vl_api_geneve_add_del_tunnel_t *mp;
12784   ip46_address_t src, dst;
12785   u8 is_add = 1;
12786   u8 ipv4_set = 0, ipv6_set = 0;
12787   u8 src_set = 0;
12788   u8 dst_set = 0;
12789   u8 grp_set = 0;
12790   u32 mcast_sw_if_index = ~0;
12791   u32 encap_vrf_id = 0;
12792   u32 decap_next_index = ~0;
12793   u32 vni = 0;
12794   int ret;
12795
12796   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12797   memset (&src, 0, sizeof src);
12798   memset (&dst, 0, sizeof dst);
12799
12800   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12801     {
12802       if (unformat (line_input, "del"))
12803         is_add = 0;
12804       else
12805         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12806         {
12807           ipv4_set = 1;
12808           src_set = 1;
12809         }
12810       else
12811         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12812         {
12813           ipv4_set = 1;
12814           dst_set = 1;
12815         }
12816       else
12817         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12818         {
12819           ipv6_set = 1;
12820           src_set = 1;
12821         }
12822       else
12823         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12824         {
12825           ipv6_set = 1;
12826           dst_set = 1;
12827         }
12828       else if (unformat (line_input, "group %U %U",
12829                          unformat_ip4_address, &dst.ip4,
12830                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12831         {
12832           grp_set = dst_set = 1;
12833           ipv4_set = 1;
12834         }
12835       else if (unformat (line_input, "group %U",
12836                          unformat_ip4_address, &dst.ip4))
12837         {
12838           grp_set = dst_set = 1;
12839           ipv4_set = 1;
12840         }
12841       else if (unformat (line_input, "group %U %U",
12842                          unformat_ip6_address, &dst.ip6,
12843                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12844         {
12845           grp_set = dst_set = 1;
12846           ipv6_set = 1;
12847         }
12848       else if (unformat (line_input, "group %U",
12849                          unformat_ip6_address, &dst.ip6))
12850         {
12851           grp_set = dst_set = 1;
12852           ipv6_set = 1;
12853         }
12854       else
12855         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12856         ;
12857       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12858         ;
12859       else if (unformat (line_input, "decap-next %U",
12860                          unformat_geneve_decap_next, &decap_next_index))
12861         ;
12862       else if (unformat (line_input, "vni %d", &vni))
12863         ;
12864       else
12865         {
12866           errmsg ("parse error '%U'", format_unformat_error, line_input);
12867           return -99;
12868         }
12869     }
12870
12871   if (src_set == 0)
12872     {
12873       errmsg ("tunnel src address not specified");
12874       return -99;
12875     }
12876   if (dst_set == 0)
12877     {
12878       errmsg ("tunnel dst address not specified");
12879       return -99;
12880     }
12881
12882   if (grp_set && !ip46_address_is_multicast (&dst))
12883     {
12884       errmsg ("tunnel group address not multicast");
12885       return -99;
12886     }
12887   if (grp_set && mcast_sw_if_index == ~0)
12888     {
12889       errmsg ("tunnel nonexistent multicast device");
12890       return -99;
12891     }
12892   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12893     {
12894       errmsg ("tunnel dst address must be unicast");
12895       return -99;
12896     }
12897
12898
12899   if (ipv4_set && ipv6_set)
12900     {
12901       errmsg ("both IPv4 and IPv6 addresses specified");
12902       return -99;
12903     }
12904
12905   if ((vni == 0) || (vni >> 24))
12906     {
12907       errmsg ("vni not specified or out of range");
12908       return -99;
12909     }
12910
12911   M (GENEVE_ADD_DEL_TUNNEL, mp);
12912
12913   if (ipv6_set)
12914     {
12915       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12916       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12917     }
12918   else
12919     {
12920       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12921       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12922     }
12923   mp->encap_vrf_id = ntohl (encap_vrf_id);
12924   mp->decap_next_index = ntohl (decap_next_index);
12925   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12926   mp->vni = ntohl (vni);
12927   mp->is_add = is_add;
12928   mp->is_ipv6 = ipv6_set;
12929
12930   S (mp);
12931   W (ret);
12932   return ret;
12933 }
12934
12935 static void vl_api_geneve_tunnel_details_t_handler
12936   (vl_api_geneve_tunnel_details_t * mp)
12937 {
12938   vat_main_t *vam = &vat_main;
12939   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12940   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12941
12942   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12943          ntohl (mp->sw_if_index),
12944          format_ip46_address, &src, IP46_TYPE_ANY,
12945          format_ip46_address, &dst, IP46_TYPE_ANY,
12946          ntohl (mp->encap_vrf_id),
12947          ntohl (mp->decap_next_index), ntohl (mp->vni),
12948          ntohl (mp->mcast_sw_if_index));
12949 }
12950
12951 static void vl_api_geneve_tunnel_details_t_handler_json
12952   (vl_api_geneve_tunnel_details_t * mp)
12953 {
12954   vat_main_t *vam = &vat_main;
12955   vat_json_node_t *node = NULL;
12956
12957   if (VAT_JSON_ARRAY != vam->json_tree.type)
12958     {
12959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12960       vat_json_init_array (&vam->json_tree);
12961     }
12962   node = vat_json_array_add (&vam->json_tree);
12963
12964   vat_json_init_object (node);
12965   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12966   if (mp->is_ipv6)
12967     {
12968       struct in6_addr ip6;
12969
12970       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12971       vat_json_object_add_ip6 (node, "src_address", ip6);
12972       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12973       vat_json_object_add_ip6 (node, "dst_address", ip6);
12974     }
12975   else
12976     {
12977       struct in_addr ip4;
12978
12979       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12980       vat_json_object_add_ip4 (node, "src_address", ip4);
12981       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12982       vat_json_object_add_ip4 (node, "dst_address", ip4);
12983     }
12984   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12985   vat_json_object_add_uint (node, "decap_next_index",
12986                             ntohl (mp->decap_next_index));
12987   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12988   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12989   vat_json_object_add_uint (node, "mcast_sw_if_index",
12990                             ntohl (mp->mcast_sw_if_index));
12991 }
12992
12993 static int
12994 api_geneve_tunnel_dump (vat_main_t * vam)
12995 {
12996   unformat_input_t *i = vam->input;
12997   vl_api_geneve_tunnel_dump_t *mp;
12998   vl_api_control_ping_t *mp_ping;
12999   u32 sw_if_index;
13000   u8 sw_if_index_set = 0;
13001   int ret;
13002
13003   /* Parse args required to build the message */
13004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13005     {
13006       if (unformat (i, "sw_if_index %d", &sw_if_index))
13007         sw_if_index_set = 1;
13008       else
13009         break;
13010     }
13011
13012   if (sw_if_index_set == 0)
13013     {
13014       sw_if_index = ~0;
13015     }
13016
13017   if (!vam->json_output)
13018     {
13019       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13020              "sw_if_index", "local_address", "remote_address",
13021              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13022     }
13023
13024   /* Get list of geneve-tunnel interfaces */
13025   M (GENEVE_TUNNEL_DUMP, mp);
13026
13027   mp->sw_if_index = htonl (sw_if_index);
13028
13029   S (mp);
13030
13031   /* Use a control ping for synchronization */
13032   M (CONTROL_PING, mp_ping);
13033   S (mp_ping);
13034
13035   W (ret);
13036   return ret;
13037 }
13038
13039 static int
13040 api_gre_add_del_tunnel (vat_main_t * vam)
13041 {
13042   unformat_input_t *line_input = vam->input;
13043   vl_api_gre_add_del_tunnel_t *mp;
13044   ip4_address_t src4, dst4;
13045   ip6_address_t src6, dst6;
13046   u8 is_add = 1;
13047   u8 ipv4_set = 0;
13048   u8 ipv6_set = 0;
13049   u8 teb = 0;
13050   u8 src_set = 0;
13051   u8 dst_set = 0;
13052   u32 outer_fib_id = 0;
13053   int ret;
13054
13055   memset (&src4, 0, sizeof src4);
13056   memset (&dst4, 0, sizeof dst4);
13057   memset (&src6, 0, sizeof src6);
13058   memset (&dst6, 0, sizeof dst6);
13059
13060   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13061     {
13062       if (unformat (line_input, "del"))
13063         is_add = 0;
13064       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13065         {
13066           src_set = 1;
13067           ipv4_set = 1;
13068         }
13069       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13070         {
13071           dst_set = 1;
13072           ipv4_set = 1;
13073         }
13074       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13075         {
13076           src_set = 1;
13077           ipv6_set = 1;
13078         }
13079       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13080         {
13081           dst_set = 1;
13082           ipv6_set = 1;
13083         }
13084       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13085         ;
13086       else if (unformat (line_input, "teb"))
13087         teb = 1;
13088       else
13089         {
13090           errmsg ("parse error '%U'", format_unformat_error, line_input);
13091           return -99;
13092         }
13093     }
13094
13095   if (src_set == 0)
13096     {
13097       errmsg ("tunnel src address not specified");
13098       return -99;
13099     }
13100   if (dst_set == 0)
13101     {
13102       errmsg ("tunnel dst address not specified");
13103       return -99;
13104     }
13105   if (ipv4_set && ipv6_set)
13106     {
13107       errmsg ("both IPv4 and IPv6 addresses specified");
13108       return -99;
13109     }
13110
13111
13112   M (GRE_ADD_DEL_TUNNEL, mp);
13113
13114   if (ipv4_set)
13115     {
13116       clib_memcpy (&mp->src_address, &src4, 4);
13117       clib_memcpy (&mp->dst_address, &dst4, 4);
13118     }
13119   else
13120     {
13121       clib_memcpy (&mp->src_address, &src6, 16);
13122       clib_memcpy (&mp->dst_address, &dst6, 16);
13123     }
13124   mp->outer_fib_id = ntohl (outer_fib_id);
13125   mp->is_add = is_add;
13126   mp->teb = teb;
13127   mp->is_ipv6 = ipv6_set;
13128
13129   S (mp);
13130   W (ret);
13131   return ret;
13132 }
13133
13134 static void vl_api_gre_tunnel_details_t_handler
13135   (vl_api_gre_tunnel_details_t * mp)
13136 {
13137   vat_main_t *vam = &vat_main;
13138   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13139   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13140
13141   print (vam->ofp, "%11d%24U%24U%6d%14d",
13142          ntohl (mp->sw_if_index),
13143          format_ip46_address, &src, IP46_TYPE_ANY,
13144          format_ip46_address, &dst, IP46_TYPE_ANY,
13145          mp->teb, ntohl (mp->outer_fib_id));
13146 }
13147
13148 static void vl_api_gre_tunnel_details_t_handler_json
13149   (vl_api_gre_tunnel_details_t * mp)
13150 {
13151   vat_main_t *vam = &vat_main;
13152   vat_json_node_t *node = NULL;
13153   struct in_addr ip4;
13154   struct in6_addr ip6;
13155
13156   if (VAT_JSON_ARRAY != vam->json_tree.type)
13157     {
13158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13159       vat_json_init_array (&vam->json_tree);
13160     }
13161   node = vat_json_array_add (&vam->json_tree);
13162
13163   vat_json_init_object (node);
13164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13165   if (!mp->is_ipv6)
13166     {
13167       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13168       vat_json_object_add_ip4 (node, "src_address", ip4);
13169       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13170       vat_json_object_add_ip4 (node, "dst_address", ip4);
13171     }
13172   else
13173     {
13174       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13175       vat_json_object_add_ip6 (node, "src_address", ip6);
13176       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13177       vat_json_object_add_ip6 (node, "dst_address", ip6);
13178     }
13179   vat_json_object_add_uint (node, "teb", mp->teb);
13180   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13181   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13182 }
13183
13184 static int
13185 api_gre_tunnel_dump (vat_main_t * vam)
13186 {
13187   unformat_input_t *i = vam->input;
13188   vl_api_gre_tunnel_dump_t *mp;
13189   vl_api_control_ping_t *mp_ping;
13190   u32 sw_if_index;
13191   u8 sw_if_index_set = 0;
13192   int ret;
13193
13194   /* Parse args required to build the message */
13195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13196     {
13197       if (unformat (i, "sw_if_index %d", &sw_if_index))
13198         sw_if_index_set = 1;
13199       else
13200         break;
13201     }
13202
13203   if (sw_if_index_set == 0)
13204     {
13205       sw_if_index = ~0;
13206     }
13207
13208   if (!vam->json_output)
13209     {
13210       print (vam->ofp, "%11s%24s%24s%6s%14s",
13211              "sw_if_index", "src_address", "dst_address", "teb",
13212              "outer_fib_id");
13213     }
13214
13215   /* Get list of gre-tunnel interfaces */
13216   M (GRE_TUNNEL_DUMP, mp);
13217
13218   mp->sw_if_index = htonl (sw_if_index);
13219
13220   S (mp);
13221
13222   /* Use a control ping for synchronization */
13223   MPING (CONTROL_PING, mp_ping);
13224   S (mp_ping);
13225
13226   W (ret);
13227   return ret;
13228 }
13229
13230 static int
13231 api_l2_fib_clear_table (vat_main_t * vam)
13232 {
13233 //  unformat_input_t * i = vam->input;
13234   vl_api_l2_fib_clear_table_t *mp;
13235   int ret;
13236
13237   M (L2_FIB_CLEAR_TABLE, mp);
13238
13239   S (mp);
13240   W (ret);
13241   return ret;
13242 }
13243
13244 static int
13245 api_l2_interface_efp_filter (vat_main_t * vam)
13246 {
13247   unformat_input_t *i = vam->input;
13248   vl_api_l2_interface_efp_filter_t *mp;
13249   u32 sw_if_index;
13250   u8 enable = 1;
13251   u8 sw_if_index_set = 0;
13252   int ret;
13253
13254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13255     {
13256       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13257         sw_if_index_set = 1;
13258       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13259         sw_if_index_set = 1;
13260       else if (unformat (i, "enable"))
13261         enable = 1;
13262       else if (unformat (i, "disable"))
13263         enable = 0;
13264       else
13265         {
13266           clib_warning ("parse error '%U'", format_unformat_error, i);
13267           return -99;
13268         }
13269     }
13270
13271   if (sw_if_index_set == 0)
13272     {
13273       errmsg ("missing sw_if_index");
13274       return -99;
13275     }
13276
13277   M (L2_INTERFACE_EFP_FILTER, mp);
13278
13279   mp->sw_if_index = ntohl (sw_if_index);
13280   mp->enable_disable = enable;
13281
13282   S (mp);
13283   W (ret);
13284   return ret;
13285 }
13286
13287 #define foreach_vtr_op                          \
13288 _("disable",  L2_VTR_DISABLED)                  \
13289 _("push-1",  L2_VTR_PUSH_1)                     \
13290 _("push-2",  L2_VTR_PUSH_2)                     \
13291 _("pop-1",  L2_VTR_POP_1)                       \
13292 _("pop-2",  L2_VTR_POP_2)                       \
13293 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13294 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13295 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13296 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13297
13298 static int
13299 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13300 {
13301   unformat_input_t *i = vam->input;
13302   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13303   u32 sw_if_index;
13304   u8 sw_if_index_set = 0;
13305   u8 vtr_op_set = 0;
13306   u32 vtr_op = 0;
13307   u32 push_dot1q = 1;
13308   u32 tag1 = ~0;
13309   u32 tag2 = ~0;
13310   int ret;
13311
13312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13313     {
13314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13315         sw_if_index_set = 1;
13316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13317         sw_if_index_set = 1;
13318       else if (unformat (i, "vtr_op %d", &vtr_op))
13319         vtr_op_set = 1;
13320 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13321       foreach_vtr_op
13322 #undef _
13323         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13324         ;
13325       else if (unformat (i, "tag1 %d", &tag1))
13326         ;
13327       else if (unformat (i, "tag2 %d", &tag2))
13328         ;
13329       else
13330         {
13331           clib_warning ("parse error '%U'", format_unformat_error, i);
13332           return -99;
13333         }
13334     }
13335
13336   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13337     {
13338       errmsg ("missing vtr operation or sw_if_index");
13339       return -99;
13340     }
13341
13342   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13343   mp->sw_if_index = ntohl (sw_if_index);
13344   mp->vtr_op = ntohl (vtr_op);
13345   mp->push_dot1q = ntohl (push_dot1q);
13346   mp->tag1 = ntohl (tag1);
13347   mp->tag2 = ntohl (tag2);
13348
13349   S (mp);
13350   W (ret);
13351   return ret;
13352 }
13353
13354 static int
13355 api_create_vhost_user_if (vat_main_t * vam)
13356 {
13357   unformat_input_t *i = vam->input;
13358   vl_api_create_vhost_user_if_t *mp;
13359   u8 *file_name;
13360   u8 is_server = 0;
13361   u8 file_name_set = 0;
13362   u32 custom_dev_instance = ~0;
13363   u8 hwaddr[6];
13364   u8 use_custom_mac = 0;
13365   u8 *tag = 0;
13366   int ret;
13367
13368   /* Shut up coverity */
13369   memset (hwaddr, 0, sizeof (hwaddr));
13370
13371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13372     {
13373       if (unformat (i, "socket %s", &file_name))
13374         {
13375           file_name_set = 1;
13376         }
13377       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13378         ;
13379       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13380         use_custom_mac = 1;
13381       else if (unformat (i, "server"))
13382         is_server = 1;
13383       else if (unformat (i, "tag %s", &tag))
13384         ;
13385       else
13386         break;
13387     }
13388
13389   if (file_name_set == 0)
13390     {
13391       errmsg ("missing socket file name");
13392       return -99;
13393     }
13394
13395   if (vec_len (file_name) > 255)
13396     {
13397       errmsg ("socket file name too long");
13398       return -99;
13399     }
13400   vec_add1 (file_name, 0);
13401
13402   M (CREATE_VHOST_USER_IF, mp);
13403
13404   mp->is_server = is_server;
13405   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13406   vec_free (file_name);
13407   if (custom_dev_instance != ~0)
13408     {
13409       mp->renumber = 1;
13410       mp->custom_dev_instance = ntohl (custom_dev_instance);
13411     }
13412   mp->use_custom_mac = use_custom_mac;
13413   clib_memcpy (mp->mac_address, hwaddr, 6);
13414   if (tag)
13415     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13416   vec_free (tag);
13417
13418   S (mp);
13419   W (ret);
13420   return ret;
13421 }
13422
13423 static int
13424 api_modify_vhost_user_if (vat_main_t * vam)
13425 {
13426   unformat_input_t *i = vam->input;
13427   vl_api_modify_vhost_user_if_t *mp;
13428   u8 *file_name;
13429   u8 is_server = 0;
13430   u8 file_name_set = 0;
13431   u32 custom_dev_instance = ~0;
13432   u8 sw_if_index_set = 0;
13433   u32 sw_if_index = (u32) ~ 0;
13434   int ret;
13435
13436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13437     {
13438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13439         sw_if_index_set = 1;
13440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13441         sw_if_index_set = 1;
13442       else if (unformat (i, "socket %s", &file_name))
13443         {
13444           file_name_set = 1;
13445         }
13446       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13447         ;
13448       else if (unformat (i, "server"))
13449         is_server = 1;
13450       else
13451         break;
13452     }
13453
13454   if (sw_if_index_set == 0)
13455     {
13456       errmsg ("missing sw_if_index or interface name");
13457       return -99;
13458     }
13459
13460   if (file_name_set == 0)
13461     {
13462       errmsg ("missing socket file name");
13463       return -99;
13464     }
13465
13466   if (vec_len (file_name) > 255)
13467     {
13468       errmsg ("socket file name too long");
13469       return -99;
13470     }
13471   vec_add1 (file_name, 0);
13472
13473   M (MODIFY_VHOST_USER_IF, mp);
13474
13475   mp->sw_if_index = ntohl (sw_if_index);
13476   mp->is_server = is_server;
13477   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13478   vec_free (file_name);
13479   if (custom_dev_instance != ~0)
13480     {
13481       mp->renumber = 1;
13482       mp->custom_dev_instance = ntohl (custom_dev_instance);
13483     }
13484
13485   S (mp);
13486   W (ret);
13487   return ret;
13488 }
13489
13490 static int
13491 api_delete_vhost_user_if (vat_main_t * vam)
13492 {
13493   unformat_input_t *i = vam->input;
13494   vl_api_delete_vhost_user_if_t *mp;
13495   u32 sw_if_index = ~0;
13496   u8 sw_if_index_set = 0;
13497   int ret;
13498
13499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13500     {
13501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13502         sw_if_index_set = 1;
13503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13504         sw_if_index_set = 1;
13505       else
13506         break;
13507     }
13508
13509   if (sw_if_index_set == 0)
13510     {
13511       errmsg ("missing sw_if_index or interface name");
13512       return -99;
13513     }
13514
13515
13516   M (DELETE_VHOST_USER_IF, mp);
13517
13518   mp->sw_if_index = ntohl (sw_if_index);
13519
13520   S (mp);
13521   W (ret);
13522   return ret;
13523 }
13524
13525 static void vl_api_sw_interface_vhost_user_details_t_handler
13526   (vl_api_sw_interface_vhost_user_details_t * mp)
13527 {
13528   vat_main_t *vam = &vat_main;
13529
13530   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13531          (char *) mp->interface_name,
13532          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13533          clib_net_to_host_u64 (mp->features), mp->is_server,
13534          ntohl (mp->num_regions), (char *) mp->sock_filename);
13535   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13536 }
13537
13538 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13539   (vl_api_sw_interface_vhost_user_details_t * mp)
13540 {
13541   vat_main_t *vam = &vat_main;
13542   vat_json_node_t *node = NULL;
13543
13544   if (VAT_JSON_ARRAY != vam->json_tree.type)
13545     {
13546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13547       vat_json_init_array (&vam->json_tree);
13548     }
13549   node = vat_json_array_add (&vam->json_tree);
13550
13551   vat_json_init_object (node);
13552   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13553   vat_json_object_add_string_copy (node, "interface_name",
13554                                    mp->interface_name);
13555   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13556                             ntohl (mp->virtio_net_hdr_sz));
13557   vat_json_object_add_uint (node, "features",
13558                             clib_net_to_host_u64 (mp->features));
13559   vat_json_object_add_uint (node, "is_server", mp->is_server);
13560   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13561   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13562   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13563 }
13564
13565 static int
13566 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13567 {
13568   vl_api_sw_interface_vhost_user_dump_t *mp;
13569   vl_api_control_ping_t *mp_ping;
13570   int ret;
13571   print (vam->ofp,
13572          "Interface name            idx hdr_sz features server regions filename");
13573
13574   /* Get list of vhost-user interfaces */
13575   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13576   S (mp);
13577
13578   /* Use a control ping for synchronization */
13579   MPING (CONTROL_PING, mp_ping);
13580   S (mp_ping);
13581
13582   W (ret);
13583   return ret;
13584 }
13585
13586 static int
13587 api_show_version (vat_main_t * vam)
13588 {
13589   vl_api_show_version_t *mp;
13590   int ret;
13591
13592   M (SHOW_VERSION, mp);
13593
13594   S (mp);
13595   W (ret);
13596   return ret;
13597 }
13598
13599
13600 static int
13601 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13602 {
13603   unformat_input_t *line_input = vam->input;
13604   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13605   ip4_address_t local4, remote4;
13606   ip6_address_t local6, remote6;
13607   u8 is_add = 1;
13608   u8 ipv4_set = 0, ipv6_set = 0;
13609   u8 local_set = 0;
13610   u8 remote_set = 0;
13611   u8 grp_set = 0;
13612   u32 mcast_sw_if_index = ~0;
13613   u32 encap_vrf_id = 0;
13614   u32 decap_vrf_id = 0;
13615   u8 protocol = ~0;
13616   u32 vni;
13617   u8 vni_set = 0;
13618   int ret;
13619
13620   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13621   memset (&local4, 0, sizeof local4);
13622   memset (&remote4, 0, sizeof remote4);
13623   memset (&local6, 0, sizeof local6);
13624   memset (&remote6, 0, sizeof remote6);
13625
13626   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13627     {
13628       if (unformat (line_input, "del"))
13629         is_add = 0;
13630       else if (unformat (line_input, "local %U",
13631                          unformat_ip4_address, &local4))
13632         {
13633           local_set = 1;
13634           ipv4_set = 1;
13635         }
13636       else if (unformat (line_input, "remote %U",
13637                          unformat_ip4_address, &remote4))
13638         {
13639           remote_set = 1;
13640           ipv4_set = 1;
13641         }
13642       else if (unformat (line_input, "local %U",
13643                          unformat_ip6_address, &local6))
13644         {
13645           local_set = 1;
13646           ipv6_set = 1;
13647         }
13648       else if (unformat (line_input, "remote %U",
13649                          unformat_ip6_address, &remote6))
13650         {
13651           remote_set = 1;
13652           ipv6_set = 1;
13653         }
13654       else if (unformat (line_input, "group %U %U",
13655                          unformat_ip4_address, &remote4,
13656                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13657         {
13658           grp_set = remote_set = 1;
13659           ipv4_set = 1;
13660         }
13661       else if (unformat (line_input, "group %U",
13662                          unformat_ip4_address, &remote4))
13663         {
13664           grp_set = remote_set = 1;
13665           ipv4_set = 1;
13666         }
13667       else if (unformat (line_input, "group %U %U",
13668                          unformat_ip6_address, &remote6,
13669                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13670         {
13671           grp_set = remote_set = 1;
13672           ipv6_set = 1;
13673         }
13674       else if (unformat (line_input, "group %U",
13675                          unformat_ip6_address, &remote6))
13676         {
13677           grp_set = remote_set = 1;
13678           ipv6_set = 1;
13679         }
13680       else
13681         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13682         ;
13683       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13684         ;
13685       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13686         ;
13687       else if (unformat (line_input, "vni %d", &vni))
13688         vni_set = 1;
13689       else if (unformat (line_input, "next-ip4"))
13690         protocol = 1;
13691       else if (unformat (line_input, "next-ip6"))
13692         protocol = 2;
13693       else if (unformat (line_input, "next-ethernet"))
13694         protocol = 3;
13695       else if (unformat (line_input, "next-nsh"))
13696         protocol = 4;
13697       else
13698         {
13699           errmsg ("parse error '%U'", format_unformat_error, line_input);
13700           return -99;
13701         }
13702     }
13703
13704   if (local_set == 0)
13705     {
13706       errmsg ("tunnel local address not specified");
13707       return -99;
13708     }
13709   if (remote_set == 0)
13710     {
13711       errmsg ("tunnel remote address not specified");
13712       return -99;
13713     }
13714   if (grp_set && mcast_sw_if_index == ~0)
13715     {
13716       errmsg ("tunnel nonexistent multicast device");
13717       return -99;
13718     }
13719   if (ipv4_set && ipv6_set)
13720     {
13721       errmsg ("both IPv4 and IPv6 addresses specified");
13722       return -99;
13723     }
13724
13725   if (vni_set == 0)
13726     {
13727       errmsg ("vni not specified");
13728       return -99;
13729     }
13730
13731   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13732
13733
13734   if (ipv6_set)
13735     {
13736       clib_memcpy (&mp->local, &local6, sizeof (local6));
13737       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13738     }
13739   else
13740     {
13741       clib_memcpy (&mp->local, &local4, sizeof (local4));
13742       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13743     }
13744
13745   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13746   mp->encap_vrf_id = ntohl (encap_vrf_id);
13747   mp->decap_vrf_id = ntohl (decap_vrf_id);
13748   mp->protocol = protocol;
13749   mp->vni = ntohl (vni);
13750   mp->is_add = is_add;
13751   mp->is_ipv6 = ipv6_set;
13752
13753   S (mp);
13754   W (ret);
13755   return ret;
13756 }
13757
13758 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13759   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13760 {
13761   vat_main_t *vam = &vat_main;
13762   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13763   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13764
13765   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13766          ntohl (mp->sw_if_index),
13767          format_ip46_address, &local, IP46_TYPE_ANY,
13768          format_ip46_address, &remote, IP46_TYPE_ANY,
13769          ntohl (mp->vni), mp->protocol,
13770          ntohl (mp->mcast_sw_if_index),
13771          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13772 }
13773
13774
13775 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13776   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13777 {
13778   vat_main_t *vam = &vat_main;
13779   vat_json_node_t *node = NULL;
13780   struct in_addr ip4;
13781   struct in6_addr ip6;
13782
13783   if (VAT_JSON_ARRAY != vam->json_tree.type)
13784     {
13785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13786       vat_json_init_array (&vam->json_tree);
13787     }
13788   node = vat_json_array_add (&vam->json_tree);
13789
13790   vat_json_init_object (node);
13791   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13792   if (mp->is_ipv6)
13793     {
13794       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13795       vat_json_object_add_ip6 (node, "local", ip6);
13796       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13797       vat_json_object_add_ip6 (node, "remote", ip6);
13798     }
13799   else
13800     {
13801       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13802       vat_json_object_add_ip4 (node, "local", ip4);
13803       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13804       vat_json_object_add_ip4 (node, "remote", ip4);
13805     }
13806   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13807   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13808   vat_json_object_add_uint (node, "mcast_sw_if_index",
13809                             ntohl (mp->mcast_sw_if_index));
13810   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13811   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13812   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13813 }
13814
13815 static int
13816 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13817 {
13818   unformat_input_t *i = vam->input;
13819   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13820   vl_api_control_ping_t *mp_ping;
13821   u32 sw_if_index;
13822   u8 sw_if_index_set = 0;
13823   int ret;
13824
13825   /* Parse args required to build the message */
13826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13827     {
13828       if (unformat (i, "sw_if_index %d", &sw_if_index))
13829         sw_if_index_set = 1;
13830       else
13831         break;
13832     }
13833
13834   if (sw_if_index_set == 0)
13835     {
13836       sw_if_index = ~0;
13837     }
13838
13839   if (!vam->json_output)
13840     {
13841       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13842              "sw_if_index", "local", "remote", "vni",
13843              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13844     }
13845
13846   /* Get list of vxlan-tunnel interfaces */
13847   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13848
13849   mp->sw_if_index = htonl (sw_if_index);
13850
13851   S (mp);
13852
13853   /* Use a control ping for synchronization */
13854   MPING (CONTROL_PING, mp_ping);
13855   S (mp_ping);
13856
13857   W (ret);
13858   return ret;
13859 }
13860
13861 static void vl_api_l2_fib_table_details_t_handler
13862   (vl_api_l2_fib_table_details_t * mp)
13863 {
13864   vat_main_t *vam = &vat_main;
13865
13866   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13867          "       %d       %d     %d",
13868          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13869          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13870          mp->bvi_mac);
13871 }
13872
13873 static void vl_api_l2_fib_table_details_t_handler_json
13874   (vl_api_l2_fib_table_details_t * mp)
13875 {
13876   vat_main_t *vam = &vat_main;
13877   vat_json_node_t *node = NULL;
13878
13879   if (VAT_JSON_ARRAY != vam->json_tree.type)
13880     {
13881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13882       vat_json_init_array (&vam->json_tree);
13883     }
13884   node = vat_json_array_add (&vam->json_tree);
13885
13886   vat_json_init_object (node);
13887   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13888   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13889   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13890   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13891   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13892   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13893 }
13894
13895 static int
13896 api_l2_fib_table_dump (vat_main_t * vam)
13897 {
13898   unformat_input_t *i = vam->input;
13899   vl_api_l2_fib_table_dump_t *mp;
13900   vl_api_control_ping_t *mp_ping;
13901   u32 bd_id;
13902   u8 bd_id_set = 0;
13903   int ret;
13904
13905   /* Parse args required to build the message */
13906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13907     {
13908       if (unformat (i, "bd_id %d", &bd_id))
13909         bd_id_set = 1;
13910       else
13911         break;
13912     }
13913
13914   if (bd_id_set == 0)
13915     {
13916       errmsg ("missing bridge domain");
13917       return -99;
13918     }
13919
13920   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13921
13922   /* Get list of l2 fib entries */
13923   M (L2_FIB_TABLE_DUMP, mp);
13924
13925   mp->bd_id = ntohl (bd_id);
13926   S (mp);
13927
13928   /* Use a control ping for synchronization */
13929   MPING (CONTROL_PING, mp_ping);
13930   S (mp_ping);
13931
13932   W (ret);
13933   return ret;
13934 }
13935
13936
13937 static int
13938 api_interface_name_renumber (vat_main_t * vam)
13939 {
13940   unformat_input_t *line_input = vam->input;
13941   vl_api_interface_name_renumber_t *mp;
13942   u32 sw_if_index = ~0;
13943   u32 new_show_dev_instance = ~0;
13944   int ret;
13945
13946   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13947     {
13948       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13949                     &sw_if_index))
13950         ;
13951       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13952         ;
13953       else if (unformat (line_input, "new_show_dev_instance %d",
13954                          &new_show_dev_instance))
13955         ;
13956       else
13957         break;
13958     }
13959
13960   if (sw_if_index == ~0)
13961     {
13962       errmsg ("missing interface name or sw_if_index");
13963       return -99;
13964     }
13965
13966   if (new_show_dev_instance == ~0)
13967     {
13968       errmsg ("missing new_show_dev_instance");
13969       return -99;
13970     }
13971
13972   M (INTERFACE_NAME_RENUMBER, mp);
13973
13974   mp->sw_if_index = ntohl (sw_if_index);
13975   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13976
13977   S (mp);
13978   W (ret);
13979   return ret;
13980 }
13981
13982 static int
13983 api_want_ip4_arp_events (vat_main_t * vam)
13984 {
13985   unformat_input_t *line_input = vam->input;
13986   vl_api_want_ip4_arp_events_t *mp;
13987   ip4_address_t address;
13988   int address_set = 0;
13989   u32 enable_disable = 1;
13990   int ret;
13991
13992   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13993     {
13994       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13995         address_set = 1;
13996       else if (unformat (line_input, "del"))
13997         enable_disable = 0;
13998       else
13999         break;
14000     }
14001
14002   if (address_set == 0)
14003     {
14004       errmsg ("missing addresses");
14005       return -99;
14006     }
14007
14008   M (WANT_IP4_ARP_EVENTS, mp);
14009   mp->enable_disable = enable_disable;
14010   mp->pid = htonl (getpid ());
14011   mp->address = address.as_u32;
14012
14013   S (mp);
14014   W (ret);
14015   return ret;
14016 }
14017
14018 static int
14019 api_want_ip6_nd_events (vat_main_t * vam)
14020 {
14021   unformat_input_t *line_input = vam->input;
14022   vl_api_want_ip6_nd_events_t *mp;
14023   ip6_address_t address;
14024   int address_set = 0;
14025   u32 enable_disable = 1;
14026   int ret;
14027
14028   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14029     {
14030       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14031         address_set = 1;
14032       else if (unformat (line_input, "del"))
14033         enable_disable = 0;
14034       else
14035         break;
14036     }
14037
14038   if (address_set == 0)
14039     {
14040       errmsg ("missing addresses");
14041       return -99;
14042     }
14043
14044   M (WANT_IP6_ND_EVENTS, mp);
14045   mp->enable_disable = enable_disable;
14046   mp->pid = htonl (getpid ());
14047   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14048
14049   S (mp);
14050   W (ret);
14051   return ret;
14052 }
14053
14054 static int
14055 api_want_l2_macs_events (vat_main_t * vam)
14056 {
14057   unformat_input_t *line_input = vam->input;
14058   vl_api_want_l2_macs_events_t *mp;
14059   u8 enable_disable = 1;
14060   u32 scan_delay = 0;
14061   u32 max_macs_in_event = 0;
14062   u32 learn_limit = 0;
14063   int ret;
14064
14065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat (line_input, "learn-limit %d", &learn_limit))
14068         ;
14069       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14070         ;
14071       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14072         ;
14073       else if (unformat (line_input, "disable"))
14074         enable_disable = 0;
14075       else
14076         break;
14077     }
14078
14079   M (WANT_L2_MACS_EVENTS, mp);
14080   mp->enable_disable = enable_disable;
14081   mp->pid = htonl (getpid ());
14082   mp->learn_limit = htonl (learn_limit);
14083   mp->scan_delay = (u8) scan_delay;
14084   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14085   S (mp);
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_input_acl_set_interface (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_input_acl_set_interface_t *mp;
14095   u32 sw_if_index;
14096   int sw_if_index_set;
14097   u32 ip4_table_index = ~0;
14098   u32 ip6_table_index = ~0;
14099   u32 l2_table_index = ~0;
14100   u8 is_add = 1;
14101   int ret;
14102
14103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14104     {
14105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14106         sw_if_index_set = 1;
14107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14108         sw_if_index_set = 1;
14109       else if (unformat (i, "del"))
14110         is_add = 0;
14111       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14112         ;
14113       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14114         ;
14115       else if (unformat (i, "l2-table %d", &l2_table_index))
14116         ;
14117       else
14118         {
14119           clib_warning ("parse error '%U'", format_unformat_error, i);
14120           return -99;
14121         }
14122     }
14123
14124   if (sw_if_index_set == 0)
14125     {
14126       errmsg ("missing interface name or sw_if_index");
14127       return -99;
14128     }
14129
14130   M (INPUT_ACL_SET_INTERFACE, mp);
14131
14132   mp->sw_if_index = ntohl (sw_if_index);
14133   mp->ip4_table_index = ntohl (ip4_table_index);
14134   mp->ip6_table_index = ntohl (ip6_table_index);
14135   mp->l2_table_index = ntohl (l2_table_index);
14136   mp->is_add = is_add;
14137
14138   S (mp);
14139   W (ret);
14140   return ret;
14141 }
14142
14143 static int
14144 api_output_acl_set_interface (vat_main_t * vam)
14145 {
14146   unformat_input_t *i = vam->input;
14147   vl_api_output_acl_set_interface_t *mp;
14148   u32 sw_if_index;
14149   int sw_if_index_set;
14150   u32 ip4_table_index = ~0;
14151   u32 ip6_table_index = ~0;
14152   u32 l2_table_index = ~0;
14153   u8 is_add = 1;
14154   int ret;
14155
14156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14157     {
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, "sw_if_index %d", &sw_if_index))
14161         sw_if_index_set = 1;
14162       else if (unformat (i, "del"))
14163         is_add = 0;
14164       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14165         ;
14166       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14167         ;
14168       else if (unformat (i, "l2-table %d", &l2_table_index))
14169         ;
14170       else
14171         {
14172           clib_warning ("parse error '%U'", format_unformat_error, i);
14173           return -99;
14174         }
14175     }
14176
14177   if (sw_if_index_set == 0)
14178     {
14179       errmsg ("missing interface name or sw_if_index");
14180       return -99;
14181     }
14182
14183   M (OUTPUT_ACL_SET_INTERFACE, mp);
14184
14185   mp->sw_if_index = ntohl (sw_if_index);
14186   mp->ip4_table_index = ntohl (ip4_table_index);
14187   mp->ip6_table_index = ntohl (ip6_table_index);
14188   mp->l2_table_index = ntohl (l2_table_index);
14189   mp->is_add = is_add;
14190
14191   S (mp);
14192   W (ret);
14193   return ret;
14194 }
14195
14196 static int
14197 api_ip_address_dump (vat_main_t * vam)
14198 {
14199   unformat_input_t *i = vam->input;
14200   vl_api_ip_address_dump_t *mp;
14201   vl_api_control_ping_t *mp_ping;
14202   u32 sw_if_index = ~0;
14203   u8 sw_if_index_set = 0;
14204   u8 ipv4_set = 0;
14205   u8 ipv6_set = 0;
14206   int ret;
14207
14208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14209     {
14210       if (unformat (i, "sw_if_index %d", &sw_if_index))
14211         sw_if_index_set = 1;
14212       else
14213         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14214         sw_if_index_set = 1;
14215       else if (unformat (i, "ipv4"))
14216         ipv4_set = 1;
14217       else if (unformat (i, "ipv6"))
14218         ipv6_set = 1;
14219       else
14220         break;
14221     }
14222
14223   if (ipv4_set && ipv6_set)
14224     {
14225       errmsg ("ipv4 and ipv6 flags cannot be both set");
14226       return -99;
14227     }
14228
14229   if ((!ipv4_set) && (!ipv6_set))
14230     {
14231       errmsg ("no ipv4 nor ipv6 flag set");
14232       return -99;
14233     }
14234
14235   if (sw_if_index_set == 0)
14236     {
14237       errmsg ("missing interface name or sw_if_index");
14238       return -99;
14239     }
14240
14241   vam->current_sw_if_index = sw_if_index;
14242   vam->is_ipv6 = ipv6_set;
14243
14244   M (IP_ADDRESS_DUMP, mp);
14245   mp->sw_if_index = ntohl (sw_if_index);
14246   mp->is_ipv6 = ipv6_set;
14247   S (mp);
14248
14249   /* Use a control ping for synchronization */
14250   MPING (CONTROL_PING, mp_ping);
14251   S (mp_ping);
14252
14253   W (ret);
14254   return ret;
14255 }
14256
14257 static int
14258 api_ip_dump (vat_main_t * vam)
14259 {
14260   vl_api_ip_dump_t *mp;
14261   vl_api_control_ping_t *mp_ping;
14262   unformat_input_t *in = vam->input;
14263   int ipv4_set = 0;
14264   int ipv6_set = 0;
14265   int is_ipv6;
14266   int i;
14267   int ret;
14268
14269   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14270     {
14271       if (unformat (in, "ipv4"))
14272         ipv4_set = 1;
14273       else if (unformat (in, "ipv6"))
14274         ipv6_set = 1;
14275       else
14276         break;
14277     }
14278
14279   if (ipv4_set && ipv6_set)
14280     {
14281       errmsg ("ipv4 and ipv6 flags cannot be both set");
14282       return -99;
14283     }
14284
14285   if ((!ipv4_set) && (!ipv6_set))
14286     {
14287       errmsg ("no ipv4 nor ipv6 flag set");
14288       return -99;
14289     }
14290
14291   is_ipv6 = ipv6_set;
14292   vam->is_ipv6 = is_ipv6;
14293
14294   /* free old data */
14295   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14296     {
14297       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14298     }
14299   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14300
14301   M (IP_DUMP, mp);
14302   mp->is_ipv6 = ipv6_set;
14303   S (mp);
14304
14305   /* Use a control ping for synchronization */
14306   MPING (CONTROL_PING, mp_ping);
14307   S (mp_ping);
14308
14309   W (ret);
14310   return ret;
14311 }
14312
14313 static int
14314 api_ipsec_spd_add_del (vat_main_t * vam)
14315 {
14316   unformat_input_t *i = vam->input;
14317   vl_api_ipsec_spd_add_del_t *mp;
14318   u32 spd_id = ~0;
14319   u8 is_add = 1;
14320   int ret;
14321
14322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14323     {
14324       if (unformat (i, "spd_id %d", &spd_id))
14325         ;
14326       else if (unformat (i, "del"))
14327         is_add = 0;
14328       else
14329         {
14330           clib_warning ("parse error '%U'", format_unformat_error, i);
14331           return -99;
14332         }
14333     }
14334   if (spd_id == ~0)
14335     {
14336       errmsg ("spd_id must be set");
14337       return -99;
14338     }
14339
14340   M (IPSEC_SPD_ADD_DEL, mp);
14341
14342   mp->spd_id = ntohl (spd_id);
14343   mp->is_add = is_add;
14344
14345   S (mp);
14346   W (ret);
14347   return ret;
14348 }
14349
14350 static int
14351 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14352 {
14353   unformat_input_t *i = vam->input;
14354   vl_api_ipsec_interface_add_del_spd_t *mp;
14355   u32 sw_if_index;
14356   u8 sw_if_index_set = 0;
14357   u32 spd_id = (u32) ~ 0;
14358   u8 is_add = 1;
14359   int ret;
14360
14361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14362     {
14363       if (unformat (i, "del"))
14364         is_add = 0;
14365       else if (unformat (i, "spd_id %d", &spd_id))
14366         ;
14367       else
14368         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14369         sw_if_index_set = 1;
14370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14371         sw_if_index_set = 1;
14372       else
14373         {
14374           clib_warning ("parse error '%U'", format_unformat_error, i);
14375           return -99;
14376         }
14377
14378     }
14379
14380   if (spd_id == (u32) ~ 0)
14381     {
14382       errmsg ("spd_id must be set");
14383       return -99;
14384     }
14385
14386   if (sw_if_index_set == 0)
14387     {
14388       errmsg ("missing interface name or sw_if_index");
14389       return -99;
14390     }
14391
14392   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14393
14394   mp->spd_id = ntohl (spd_id);
14395   mp->sw_if_index = ntohl (sw_if_index);
14396   mp->is_add = is_add;
14397
14398   S (mp);
14399   W (ret);
14400   return ret;
14401 }
14402
14403 static int
14404 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14405 {
14406   unformat_input_t *i = vam->input;
14407   vl_api_ipsec_spd_add_del_entry_t *mp;
14408   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14409   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14410   i32 priority = 0;
14411   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14412   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14413   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14414   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14415   int ret;
14416
14417   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14418   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14419   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14420   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14421   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14422   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14423
14424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14425     {
14426       if (unformat (i, "del"))
14427         is_add = 0;
14428       if (unformat (i, "outbound"))
14429         is_outbound = 1;
14430       if (unformat (i, "inbound"))
14431         is_outbound = 0;
14432       else if (unformat (i, "spd_id %d", &spd_id))
14433         ;
14434       else if (unformat (i, "sa_id %d", &sa_id))
14435         ;
14436       else if (unformat (i, "priority %d", &priority))
14437         ;
14438       else if (unformat (i, "protocol %d", &protocol))
14439         ;
14440       else if (unformat (i, "lport_start %d", &lport_start))
14441         ;
14442       else if (unformat (i, "lport_stop %d", &lport_stop))
14443         ;
14444       else if (unformat (i, "rport_start %d", &rport_start))
14445         ;
14446       else if (unformat (i, "rport_stop %d", &rport_stop))
14447         ;
14448       else
14449         if (unformat
14450             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14451         {
14452           is_ipv6 = 0;
14453           is_ip_any = 0;
14454         }
14455       else
14456         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14457         {
14458           is_ipv6 = 0;
14459           is_ip_any = 0;
14460         }
14461       else
14462         if (unformat
14463             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14464         {
14465           is_ipv6 = 0;
14466           is_ip_any = 0;
14467         }
14468       else
14469         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14470         {
14471           is_ipv6 = 0;
14472           is_ip_any = 0;
14473         }
14474       else
14475         if (unformat
14476             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14477         {
14478           is_ipv6 = 1;
14479           is_ip_any = 0;
14480         }
14481       else
14482         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14483         {
14484           is_ipv6 = 1;
14485           is_ip_any = 0;
14486         }
14487       else
14488         if (unformat
14489             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14490         {
14491           is_ipv6 = 1;
14492           is_ip_any = 0;
14493         }
14494       else
14495         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14496         {
14497           is_ipv6 = 1;
14498           is_ip_any = 0;
14499         }
14500       else
14501         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14502         {
14503           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14504             {
14505               clib_warning ("unsupported action: 'resolve'");
14506               return -99;
14507             }
14508         }
14509       else
14510         {
14511           clib_warning ("parse error '%U'", format_unformat_error, i);
14512           return -99;
14513         }
14514
14515     }
14516
14517   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14518
14519   mp->spd_id = ntohl (spd_id);
14520   mp->priority = ntohl (priority);
14521   mp->is_outbound = is_outbound;
14522
14523   mp->is_ipv6 = is_ipv6;
14524   if (is_ipv6 || is_ip_any)
14525     {
14526       clib_memcpy (mp->remote_address_start, &raddr6_start,
14527                    sizeof (ip6_address_t));
14528       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14529                    sizeof (ip6_address_t));
14530       clib_memcpy (mp->local_address_start, &laddr6_start,
14531                    sizeof (ip6_address_t));
14532       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14533                    sizeof (ip6_address_t));
14534     }
14535   else
14536     {
14537       clib_memcpy (mp->remote_address_start, &raddr4_start,
14538                    sizeof (ip4_address_t));
14539       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14540                    sizeof (ip4_address_t));
14541       clib_memcpy (mp->local_address_start, &laddr4_start,
14542                    sizeof (ip4_address_t));
14543       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14544                    sizeof (ip4_address_t));
14545     }
14546   mp->protocol = (u8) protocol;
14547   mp->local_port_start = ntohs ((u16) lport_start);
14548   mp->local_port_stop = ntohs ((u16) lport_stop);
14549   mp->remote_port_start = ntohs ((u16) rport_start);
14550   mp->remote_port_stop = ntohs ((u16) rport_stop);
14551   mp->policy = (u8) policy;
14552   mp->sa_id = ntohl (sa_id);
14553   mp->is_add = is_add;
14554   mp->is_ip_any = is_ip_any;
14555   S (mp);
14556   W (ret);
14557   return ret;
14558 }
14559
14560 static int
14561 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14562 {
14563   unformat_input_t *i = vam->input;
14564   vl_api_ipsec_sad_add_del_entry_t *mp;
14565   u32 sad_id = 0, spi = 0;
14566   u8 *ck = 0, *ik = 0;
14567   u8 is_add = 1;
14568
14569   u8 protocol = IPSEC_PROTOCOL_AH;
14570   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14571   u32 crypto_alg = 0, integ_alg = 0;
14572   ip4_address_t tun_src4;
14573   ip4_address_t tun_dst4;
14574   ip6_address_t tun_src6;
14575   ip6_address_t tun_dst6;
14576   int ret;
14577
14578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14579     {
14580       if (unformat (i, "del"))
14581         is_add = 0;
14582       else if (unformat (i, "sad_id %d", &sad_id))
14583         ;
14584       else if (unformat (i, "spi %d", &spi))
14585         ;
14586       else if (unformat (i, "esp"))
14587         protocol = IPSEC_PROTOCOL_ESP;
14588       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14589         {
14590           is_tunnel = 1;
14591           is_tunnel_ipv6 = 0;
14592         }
14593       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14594         {
14595           is_tunnel = 1;
14596           is_tunnel_ipv6 = 0;
14597         }
14598       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14599         {
14600           is_tunnel = 1;
14601           is_tunnel_ipv6 = 1;
14602         }
14603       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14604         {
14605           is_tunnel = 1;
14606           is_tunnel_ipv6 = 1;
14607         }
14608       else
14609         if (unformat
14610             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14611         {
14612           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14613               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14614             {
14615               clib_warning ("unsupported crypto-alg: '%U'",
14616                             format_ipsec_crypto_alg, crypto_alg);
14617               return -99;
14618             }
14619         }
14620       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14621         ;
14622       else
14623         if (unformat
14624             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14625         {
14626           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14627               integ_alg >= IPSEC_INTEG_N_ALG)
14628             {
14629               clib_warning ("unsupported integ-alg: '%U'",
14630                             format_ipsec_integ_alg, integ_alg);
14631               return -99;
14632             }
14633         }
14634       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14635         ;
14636       else
14637         {
14638           clib_warning ("parse error '%U'", format_unformat_error, i);
14639           return -99;
14640         }
14641
14642     }
14643
14644   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14645
14646   mp->sad_id = ntohl (sad_id);
14647   mp->is_add = is_add;
14648   mp->protocol = protocol;
14649   mp->spi = ntohl (spi);
14650   mp->is_tunnel = is_tunnel;
14651   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14652   mp->crypto_algorithm = crypto_alg;
14653   mp->integrity_algorithm = integ_alg;
14654   mp->crypto_key_length = vec_len (ck);
14655   mp->integrity_key_length = vec_len (ik);
14656
14657   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14658     mp->crypto_key_length = sizeof (mp->crypto_key);
14659
14660   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14661     mp->integrity_key_length = sizeof (mp->integrity_key);
14662
14663   if (ck)
14664     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14665   if (ik)
14666     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14667
14668   if (is_tunnel)
14669     {
14670       if (is_tunnel_ipv6)
14671         {
14672           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14673                        sizeof (ip6_address_t));
14674           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14675                        sizeof (ip6_address_t));
14676         }
14677       else
14678         {
14679           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14680                        sizeof (ip4_address_t));
14681           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14682                        sizeof (ip4_address_t));
14683         }
14684     }
14685
14686   S (mp);
14687   W (ret);
14688   return ret;
14689 }
14690
14691 static int
14692 api_ipsec_sa_set_key (vat_main_t * vam)
14693 {
14694   unformat_input_t *i = vam->input;
14695   vl_api_ipsec_sa_set_key_t *mp;
14696   u32 sa_id;
14697   u8 *ck = 0, *ik = 0;
14698   int ret;
14699
14700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14701     {
14702       if (unformat (i, "sa_id %d", &sa_id))
14703         ;
14704       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14705         ;
14706       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14707         ;
14708       else
14709         {
14710           clib_warning ("parse error '%U'", format_unformat_error, i);
14711           return -99;
14712         }
14713     }
14714
14715   M (IPSEC_SA_SET_KEY, mp);
14716
14717   mp->sa_id = ntohl (sa_id);
14718   mp->crypto_key_length = vec_len (ck);
14719   mp->integrity_key_length = vec_len (ik);
14720
14721   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14722     mp->crypto_key_length = sizeof (mp->crypto_key);
14723
14724   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14725     mp->integrity_key_length = sizeof (mp->integrity_key);
14726
14727   if (ck)
14728     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14729   if (ik)
14730     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14731
14732   S (mp);
14733   W (ret);
14734   return ret;
14735 }
14736
14737 static int
14738 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14739 {
14740   unformat_input_t *i = vam->input;
14741   vl_api_ipsec_tunnel_if_add_del_t *mp;
14742   u32 local_spi = 0, remote_spi = 0;
14743   u32 crypto_alg = 0, integ_alg = 0;
14744   u8 *lck = NULL, *rck = NULL;
14745   u8 *lik = NULL, *rik = NULL;
14746   ip4_address_t local_ip = { {0} };
14747   ip4_address_t remote_ip = { {0} };
14748   u8 is_add = 1;
14749   u8 esn = 0;
14750   u8 anti_replay = 0;
14751   int ret;
14752
14753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14754     {
14755       if (unformat (i, "del"))
14756         is_add = 0;
14757       else if (unformat (i, "esn"))
14758         esn = 1;
14759       else if (unformat (i, "anti_replay"))
14760         anti_replay = 1;
14761       else if (unformat (i, "local_spi %d", &local_spi))
14762         ;
14763       else if (unformat (i, "remote_spi %d", &remote_spi))
14764         ;
14765       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14766         ;
14767       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14768         ;
14769       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14770         ;
14771       else
14772         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14773         ;
14774       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14775         ;
14776       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14777         ;
14778       else
14779         if (unformat
14780             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14781         {
14782           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14783               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14784             {
14785               errmsg ("unsupported crypto-alg: '%U'\n",
14786                       format_ipsec_crypto_alg, crypto_alg);
14787               return -99;
14788             }
14789         }
14790       else
14791         if (unformat
14792             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14793         {
14794           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14795               integ_alg >= IPSEC_INTEG_N_ALG)
14796             {
14797               errmsg ("unsupported integ-alg: '%U'\n",
14798                       format_ipsec_integ_alg, integ_alg);
14799               return -99;
14800             }
14801         }
14802       else
14803         {
14804           errmsg ("parse error '%U'\n", format_unformat_error, i);
14805           return -99;
14806         }
14807     }
14808
14809   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14810
14811   mp->is_add = is_add;
14812   mp->esn = esn;
14813   mp->anti_replay = anti_replay;
14814
14815   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14816   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14817
14818   mp->local_spi = htonl (local_spi);
14819   mp->remote_spi = htonl (remote_spi);
14820   mp->crypto_alg = (u8) crypto_alg;
14821
14822   mp->local_crypto_key_len = 0;
14823   if (lck)
14824     {
14825       mp->local_crypto_key_len = vec_len (lck);
14826       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14827         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14828       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14829     }
14830
14831   mp->remote_crypto_key_len = 0;
14832   if (rck)
14833     {
14834       mp->remote_crypto_key_len = vec_len (rck);
14835       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14836         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14837       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14838     }
14839
14840   mp->integ_alg = (u8) integ_alg;
14841
14842   mp->local_integ_key_len = 0;
14843   if (lik)
14844     {
14845       mp->local_integ_key_len = vec_len (lik);
14846       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14847         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14848       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14849     }
14850
14851   mp->remote_integ_key_len = 0;
14852   if (rik)
14853     {
14854       mp->remote_integ_key_len = vec_len (rik);
14855       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14856         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14857       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14858     }
14859
14860   S (mp);
14861   W (ret);
14862   return ret;
14863 }
14864
14865 static void
14866 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14867 {
14868   vat_main_t *vam = &vat_main;
14869
14870   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14871          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14872          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14873          "tunnel_src_addr %U tunnel_dst_addr %U "
14874          "salt %u seq_outbound %lu last_seq_inbound %lu "
14875          "replay_window %lu total_data_size %lu\n",
14876          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14877          mp->protocol,
14878          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14879          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14880          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14881          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14882          mp->tunnel_src_addr,
14883          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14884          mp->tunnel_dst_addr,
14885          ntohl (mp->salt),
14886          clib_net_to_host_u64 (mp->seq_outbound),
14887          clib_net_to_host_u64 (mp->last_seq_inbound),
14888          clib_net_to_host_u64 (mp->replay_window),
14889          clib_net_to_host_u64 (mp->total_data_size));
14890 }
14891
14892 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14893 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14894
14895 static void vl_api_ipsec_sa_details_t_handler_json
14896   (vl_api_ipsec_sa_details_t * mp)
14897 {
14898   vat_main_t *vam = &vat_main;
14899   vat_json_node_t *node = NULL;
14900   struct in_addr src_ip4, dst_ip4;
14901   struct in6_addr src_ip6, dst_ip6;
14902
14903   if (VAT_JSON_ARRAY != vam->json_tree.type)
14904     {
14905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14906       vat_json_init_array (&vam->json_tree);
14907     }
14908   node = vat_json_array_add (&vam->json_tree);
14909
14910   vat_json_init_object (node);
14911   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14912   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14913   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14914   vat_json_object_add_uint (node, "proto", mp->protocol);
14915   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14916   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14917   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14918   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14919   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14920   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14921   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14922                              mp->crypto_key_len);
14923   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14924                              mp->integ_key_len);
14925   if (mp->is_tunnel_ip6)
14926     {
14927       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14928       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14929       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14930       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14931     }
14932   else
14933     {
14934       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14935       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14936       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14937       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14938     }
14939   vat_json_object_add_uint (node, "replay_window",
14940                             clib_net_to_host_u64 (mp->replay_window));
14941   vat_json_object_add_uint (node, "total_data_size",
14942                             clib_net_to_host_u64 (mp->total_data_size));
14943
14944 }
14945
14946 static int
14947 api_ipsec_sa_dump (vat_main_t * vam)
14948 {
14949   unformat_input_t *i = vam->input;
14950   vl_api_ipsec_sa_dump_t *mp;
14951   vl_api_control_ping_t *mp_ping;
14952   u32 sa_id = ~0;
14953   int ret;
14954
14955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14956     {
14957       if (unformat (i, "sa_id %d", &sa_id))
14958         ;
14959       else
14960         {
14961           clib_warning ("parse error '%U'", format_unformat_error, i);
14962           return -99;
14963         }
14964     }
14965
14966   M (IPSEC_SA_DUMP, mp);
14967
14968   mp->sa_id = ntohl (sa_id);
14969
14970   S (mp);
14971
14972   /* Use a control ping for synchronization */
14973   M (CONTROL_PING, mp_ping);
14974   S (mp_ping);
14975
14976   W (ret);
14977   return ret;
14978 }
14979
14980 static int
14981 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14982 {
14983   unformat_input_t *i = vam->input;
14984   vl_api_ipsec_tunnel_if_set_key_t *mp;
14985   u32 sw_if_index = ~0;
14986   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14987   u8 *key = 0;
14988   u32 alg = ~0;
14989   int ret;
14990
14991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14992     {
14993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14994         ;
14995       else
14996         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14997         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14998       else
14999         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15000         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15001       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15002         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15003       else
15004         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15005         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15006       else if (unformat (i, "%U", unformat_hex_string, &key))
15007         ;
15008       else
15009         {
15010           clib_warning ("parse error '%U'", format_unformat_error, i);
15011           return -99;
15012         }
15013     }
15014
15015   if (sw_if_index == ~0)
15016     {
15017       errmsg ("interface must be specified");
15018       return -99;
15019     }
15020
15021   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15022     {
15023       errmsg ("key type must be specified");
15024       return -99;
15025     }
15026
15027   if (alg == ~0)
15028     {
15029       errmsg ("algorithm must be specified");
15030       return -99;
15031     }
15032
15033   if (vec_len (key) == 0)
15034     {
15035       errmsg ("key must be specified");
15036       return -99;
15037     }
15038
15039   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15040
15041   mp->sw_if_index = htonl (sw_if_index);
15042   mp->alg = alg;
15043   mp->key_type = key_type;
15044   mp->key_len = vec_len (key);
15045   clib_memcpy (mp->key, key, vec_len (key));
15046
15047   S (mp);
15048   W (ret);
15049
15050   return ret;
15051 }
15052
15053 static int
15054 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15055 {
15056   unformat_input_t *i = vam->input;
15057   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15058   u32 sw_if_index = ~0;
15059   u32 sa_id = ~0;
15060   u8 is_outbound = (u8) ~ 0;
15061   int ret;
15062
15063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15064     {
15065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15066         ;
15067       else if (unformat (i, "sa_id %d", &sa_id))
15068         ;
15069       else if (unformat (i, "outbound"))
15070         is_outbound = 1;
15071       else if (unformat (i, "inbound"))
15072         is_outbound = 0;
15073       else
15074         {
15075           clib_warning ("parse error '%U'", format_unformat_error, i);
15076           return -99;
15077         }
15078     }
15079
15080   if (sw_if_index == ~0)
15081     {
15082       errmsg ("interface must be specified");
15083       return -99;
15084     }
15085
15086   if (sa_id == ~0)
15087     {
15088       errmsg ("SA ID must be specified");
15089       return -99;
15090     }
15091
15092   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15093
15094   mp->sw_if_index = htonl (sw_if_index);
15095   mp->sa_id = htonl (sa_id);
15096   mp->is_outbound = is_outbound;
15097
15098   S (mp);
15099   W (ret);
15100
15101   return ret;
15102 }
15103
15104 static int
15105 api_ikev2_profile_add_del (vat_main_t * vam)
15106 {
15107   unformat_input_t *i = vam->input;
15108   vl_api_ikev2_profile_add_del_t *mp;
15109   u8 is_add = 1;
15110   u8 *name = 0;
15111   int ret;
15112
15113   const char *valid_chars = "a-zA-Z0-9_";
15114
15115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15116     {
15117       if (unformat (i, "del"))
15118         is_add = 0;
15119       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15120         vec_add1 (name, 0);
15121       else
15122         {
15123           errmsg ("parse error '%U'", format_unformat_error, i);
15124           return -99;
15125         }
15126     }
15127
15128   if (!vec_len (name))
15129     {
15130       errmsg ("profile name must be specified");
15131       return -99;
15132     }
15133
15134   if (vec_len (name) > 64)
15135     {
15136       errmsg ("profile name too long");
15137       return -99;
15138     }
15139
15140   M (IKEV2_PROFILE_ADD_DEL, mp);
15141
15142   clib_memcpy (mp->name, name, vec_len (name));
15143   mp->is_add = is_add;
15144   vec_free (name);
15145
15146   S (mp);
15147   W (ret);
15148   return ret;
15149 }
15150
15151 static int
15152 api_ikev2_profile_set_auth (vat_main_t * vam)
15153 {
15154   unformat_input_t *i = vam->input;
15155   vl_api_ikev2_profile_set_auth_t *mp;
15156   u8 *name = 0;
15157   u8 *data = 0;
15158   u32 auth_method = 0;
15159   u8 is_hex = 0;
15160   int ret;
15161
15162   const char *valid_chars = "a-zA-Z0-9_";
15163
15164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15165     {
15166       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15167         vec_add1 (name, 0);
15168       else if (unformat (i, "auth_method %U",
15169                          unformat_ikev2_auth_method, &auth_method))
15170         ;
15171       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15172         is_hex = 1;
15173       else if (unformat (i, "auth_data %v", &data))
15174         ;
15175       else
15176         {
15177           errmsg ("parse error '%U'", format_unformat_error, i);
15178           return -99;
15179         }
15180     }
15181
15182   if (!vec_len (name))
15183     {
15184       errmsg ("profile name must be specified");
15185       return -99;
15186     }
15187
15188   if (vec_len (name) > 64)
15189     {
15190       errmsg ("profile name too long");
15191       return -99;
15192     }
15193
15194   if (!vec_len (data))
15195     {
15196       errmsg ("auth_data must be specified");
15197       return -99;
15198     }
15199
15200   if (!auth_method)
15201     {
15202       errmsg ("auth_method must be specified");
15203       return -99;
15204     }
15205
15206   M (IKEV2_PROFILE_SET_AUTH, mp);
15207
15208   mp->is_hex = is_hex;
15209   mp->auth_method = (u8) auth_method;
15210   mp->data_len = vec_len (data);
15211   clib_memcpy (mp->name, name, vec_len (name));
15212   clib_memcpy (mp->data, data, vec_len (data));
15213   vec_free (name);
15214   vec_free (data);
15215
15216   S (mp);
15217   W (ret);
15218   return ret;
15219 }
15220
15221 static int
15222 api_ikev2_profile_set_id (vat_main_t * vam)
15223 {
15224   unformat_input_t *i = vam->input;
15225   vl_api_ikev2_profile_set_id_t *mp;
15226   u8 *name = 0;
15227   u8 *data = 0;
15228   u8 is_local = 0;
15229   u32 id_type = 0;
15230   ip4_address_t ip4;
15231   int ret;
15232
15233   const char *valid_chars = "a-zA-Z0-9_";
15234
15235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15236     {
15237       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15238         vec_add1 (name, 0);
15239       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15240         ;
15241       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15242         {
15243           data = vec_new (u8, 4);
15244           clib_memcpy (data, ip4.as_u8, 4);
15245         }
15246       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15247         ;
15248       else if (unformat (i, "id_data %v", &data))
15249         ;
15250       else if (unformat (i, "local"))
15251         is_local = 1;
15252       else if (unformat (i, "remote"))
15253         is_local = 0;
15254       else
15255         {
15256           errmsg ("parse error '%U'", format_unformat_error, i);
15257           return -99;
15258         }
15259     }
15260
15261   if (!vec_len (name))
15262     {
15263       errmsg ("profile name must be specified");
15264       return -99;
15265     }
15266
15267   if (vec_len (name) > 64)
15268     {
15269       errmsg ("profile name too long");
15270       return -99;
15271     }
15272
15273   if (!vec_len (data))
15274     {
15275       errmsg ("id_data must be specified");
15276       return -99;
15277     }
15278
15279   if (!id_type)
15280     {
15281       errmsg ("id_type must be specified");
15282       return -99;
15283     }
15284
15285   M (IKEV2_PROFILE_SET_ID, mp);
15286
15287   mp->is_local = is_local;
15288   mp->id_type = (u8) id_type;
15289   mp->data_len = vec_len (data);
15290   clib_memcpy (mp->name, name, vec_len (name));
15291   clib_memcpy (mp->data, data, vec_len (data));
15292   vec_free (name);
15293   vec_free (data);
15294
15295   S (mp);
15296   W (ret);
15297   return ret;
15298 }
15299
15300 static int
15301 api_ikev2_profile_set_ts (vat_main_t * vam)
15302 {
15303   unformat_input_t *i = vam->input;
15304   vl_api_ikev2_profile_set_ts_t *mp;
15305   u8 *name = 0;
15306   u8 is_local = 0;
15307   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15308   ip4_address_t start_addr, end_addr;
15309
15310   const char *valid_chars = "a-zA-Z0-9_";
15311   int ret;
15312
15313   start_addr.as_u32 = 0;
15314   end_addr.as_u32 = (u32) ~ 0;
15315
15316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15317     {
15318       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15319         vec_add1 (name, 0);
15320       else if (unformat (i, "protocol %d", &proto))
15321         ;
15322       else if (unformat (i, "start_port %d", &start_port))
15323         ;
15324       else if (unformat (i, "end_port %d", &end_port))
15325         ;
15326       else
15327         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15328         ;
15329       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15330         ;
15331       else if (unformat (i, "local"))
15332         is_local = 1;
15333       else if (unformat (i, "remote"))
15334         is_local = 0;
15335       else
15336         {
15337           errmsg ("parse error '%U'", format_unformat_error, i);
15338           return -99;
15339         }
15340     }
15341
15342   if (!vec_len (name))
15343     {
15344       errmsg ("profile name must be specified");
15345       return -99;
15346     }
15347
15348   if (vec_len (name) > 64)
15349     {
15350       errmsg ("profile name too long");
15351       return -99;
15352     }
15353
15354   M (IKEV2_PROFILE_SET_TS, mp);
15355
15356   mp->is_local = is_local;
15357   mp->proto = (u8) proto;
15358   mp->start_port = (u16) start_port;
15359   mp->end_port = (u16) end_port;
15360   mp->start_addr = start_addr.as_u32;
15361   mp->end_addr = end_addr.as_u32;
15362   clib_memcpy (mp->name, name, vec_len (name));
15363   vec_free (name);
15364
15365   S (mp);
15366   W (ret);
15367   return ret;
15368 }
15369
15370 static int
15371 api_ikev2_set_local_key (vat_main_t * vam)
15372 {
15373   unformat_input_t *i = vam->input;
15374   vl_api_ikev2_set_local_key_t *mp;
15375   u8 *file = 0;
15376   int ret;
15377
15378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15379     {
15380       if (unformat (i, "file %v", &file))
15381         vec_add1 (file, 0);
15382       else
15383         {
15384           errmsg ("parse error '%U'", format_unformat_error, i);
15385           return -99;
15386         }
15387     }
15388
15389   if (!vec_len (file))
15390     {
15391       errmsg ("RSA key file must be specified");
15392       return -99;
15393     }
15394
15395   if (vec_len (file) > 256)
15396     {
15397       errmsg ("file name too long");
15398       return -99;
15399     }
15400
15401   M (IKEV2_SET_LOCAL_KEY, mp);
15402
15403   clib_memcpy (mp->key_file, file, vec_len (file));
15404   vec_free (file);
15405
15406   S (mp);
15407   W (ret);
15408   return ret;
15409 }
15410
15411 static int
15412 api_ikev2_set_responder (vat_main_t * vam)
15413 {
15414   unformat_input_t *i = vam->input;
15415   vl_api_ikev2_set_responder_t *mp;
15416   int ret;
15417   u8 *name = 0;
15418   u32 sw_if_index = ~0;
15419   ip4_address_t address;
15420
15421   const char *valid_chars = "a-zA-Z0-9_";
15422
15423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15424     {
15425       if (unformat
15426           (i, "%U interface %d address %U", unformat_token, valid_chars,
15427            &name, &sw_if_index, unformat_ip4_address, &address))
15428         vec_add1 (name, 0);
15429       else
15430         {
15431           errmsg ("parse error '%U'", format_unformat_error, i);
15432           return -99;
15433         }
15434     }
15435
15436   if (!vec_len (name))
15437     {
15438       errmsg ("profile name must be specified");
15439       return -99;
15440     }
15441
15442   if (vec_len (name) > 64)
15443     {
15444       errmsg ("profile name too long");
15445       return -99;
15446     }
15447
15448   M (IKEV2_SET_RESPONDER, mp);
15449
15450   clib_memcpy (mp->name, name, vec_len (name));
15451   vec_free (name);
15452
15453   mp->sw_if_index = sw_if_index;
15454   clib_memcpy (mp->address, &address, sizeof (address));
15455
15456   S (mp);
15457   W (ret);
15458   return ret;
15459 }
15460
15461 static int
15462 api_ikev2_set_ike_transforms (vat_main_t * vam)
15463 {
15464   unformat_input_t *i = vam->input;
15465   vl_api_ikev2_set_ike_transforms_t *mp;
15466   int ret;
15467   u8 *name = 0;
15468   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15469
15470   const char *valid_chars = "a-zA-Z0-9_";
15471
15472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15473     {
15474       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15475                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15476         vec_add1 (name, 0);
15477       else
15478         {
15479           errmsg ("parse error '%U'", format_unformat_error, i);
15480           return -99;
15481         }
15482     }
15483
15484   if (!vec_len (name))
15485     {
15486       errmsg ("profile name must be specified");
15487       return -99;
15488     }
15489
15490   if (vec_len (name) > 64)
15491     {
15492       errmsg ("profile name too long");
15493       return -99;
15494     }
15495
15496   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15497
15498   clib_memcpy (mp->name, name, vec_len (name));
15499   vec_free (name);
15500   mp->crypto_alg = crypto_alg;
15501   mp->crypto_key_size = crypto_key_size;
15502   mp->integ_alg = integ_alg;
15503   mp->dh_group = dh_group;
15504
15505   S (mp);
15506   W (ret);
15507   return ret;
15508 }
15509
15510
15511 static int
15512 api_ikev2_set_esp_transforms (vat_main_t * vam)
15513 {
15514   unformat_input_t *i = vam->input;
15515   vl_api_ikev2_set_esp_transforms_t *mp;
15516   int ret;
15517   u8 *name = 0;
15518   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15519
15520   const char *valid_chars = "a-zA-Z0-9_";
15521
15522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15523     {
15524       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15525                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15526         vec_add1 (name, 0);
15527       else
15528         {
15529           errmsg ("parse error '%U'", format_unformat_error, i);
15530           return -99;
15531         }
15532     }
15533
15534   if (!vec_len (name))
15535     {
15536       errmsg ("profile name must be specified");
15537       return -99;
15538     }
15539
15540   if (vec_len (name) > 64)
15541     {
15542       errmsg ("profile name too long");
15543       return -99;
15544     }
15545
15546   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15547
15548   clib_memcpy (mp->name, name, vec_len (name));
15549   vec_free (name);
15550   mp->crypto_alg = crypto_alg;
15551   mp->crypto_key_size = crypto_key_size;
15552   mp->integ_alg = integ_alg;
15553   mp->dh_group = dh_group;
15554
15555   S (mp);
15556   W (ret);
15557   return ret;
15558 }
15559
15560 static int
15561 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15562 {
15563   unformat_input_t *i = vam->input;
15564   vl_api_ikev2_set_sa_lifetime_t *mp;
15565   int ret;
15566   u8 *name = 0;
15567   u64 lifetime, lifetime_maxdata;
15568   u32 lifetime_jitter, handover;
15569
15570   const char *valid_chars = "a-zA-Z0-9_";
15571
15572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15573     {
15574       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15575                     &lifetime, &lifetime_jitter, &handover,
15576                     &lifetime_maxdata))
15577         vec_add1 (name, 0);
15578       else
15579         {
15580           errmsg ("parse error '%U'", format_unformat_error, i);
15581           return -99;
15582         }
15583     }
15584
15585   if (!vec_len (name))
15586     {
15587       errmsg ("profile name must be specified");
15588       return -99;
15589     }
15590
15591   if (vec_len (name) > 64)
15592     {
15593       errmsg ("profile name too long");
15594       return -99;
15595     }
15596
15597   M (IKEV2_SET_SA_LIFETIME, mp);
15598
15599   clib_memcpy (mp->name, name, vec_len (name));
15600   vec_free (name);
15601   mp->lifetime = lifetime;
15602   mp->lifetime_jitter = lifetime_jitter;
15603   mp->handover = handover;
15604   mp->lifetime_maxdata = lifetime_maxdata;
15605
15606   S (mp);
15607   W (ret);
15608   return ret;
15609 }
15610
15611 static int
15612 api_ikev2_initiate_sa_init (vat_main_t * vam)
15613 {
15614   unformat_input_t *i = vam->input;
15615   vl_api_ikev2_initiate_sa_init_t *mp;
15616   int ret;
15617   u8 *name = 0;
15618
15619   const char *valid_chars = "a-zA-Z0-9_";
15620
15621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15622     {
15623       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15624         vec_add1 (name, 0);
15625       else
15626         {
15627           errmsg ("parse error '%U'", format_unformat_error, i);
15628           return -99;
15629         }
15630     }
15631
15632   if (!vec_len (name))
15633     {
15634       errmsg ("profile name must be specified");
15635       return -99;
15636     }
15637
15638   if (vec_len (name) > 64)
15639     {
15640       errmsg ("profile name too long");
15641       return -99;
15642     }
15643
15644   M (IKEV2_INITIATE_SA_INIT, mp);
15645
15646   clib_memcpy (mp->name, name, vec_len (name));
15647   vec_free (name);
15648
15649   S (mp);
15650   W (ret);
15651   return ret;
15652 }
15653
15654 static int
15655 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15656 {
15657   unformat_input_t *i = vam->input;
15658   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15659   int ret;
15660   u64 ispi;
15661
15662
15663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15664     {
15665       if (unformat (i, "%lx", &ispi))
15666         ;
15667       else
15668         {
15669           errmsg ("parse error '%U'", format_unformat_error, i);
15670           return -99;
15671         }
15672     }
15673
15674   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15675
15676   mp->ispi = ispi;
15677
15678   S (mp);
15679   W (ret);
15680   return ret;
15681 }
15682
15683 static int
15684 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15685 {
15686   unformat_input_t *i = vam->input;
15687   vl_api_ikev2_initiate_del_child_sa_t *mp;
15688   int ret;
15689   u32 ispi;
15690
15691
15692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15693     {
15694       if (unformat (i, "%x", &ispi))
15695         ;
15696       else
15697         {
15698           errmsg ("parse error '%U'", format_unformat_error, i);
15699           return -99;
15700         }
15701     }
15702
15703   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15704
15705   mp->ispi = ispi;
15706
15707   S (mp);
15708   W (ret);
15709   return ret;
15710 }
15711
15712 static int
15713 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15714 {
15715   unformat_input_t *i = vam->input;
15716   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15717   int ret;
15718   u32 ispi;
15719
15720
15721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15722     {
15723       if (unformat (i, "%x", &ispi))
15724         ;
15725       else
15726         {
15727           errmsg ("parse error '%U'", format_unformat_error, i);
15728           return -99;
15729         }
15730     }
15731
15732   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15733
15734   mp->ispi = ispi;
15735
15736   S (mp);
15737   W (ret);
15738   return ret;
15739 }
15740
15741 /*
15742  * MAP
15743  */
15744 static int
15745 api_map_add_domain (vat_main_t * vam)
15746 {
15747   unformat_input_t *i = vam->input;
15748   vl_api_map_add_domain_t *mp;
15749
15750   ip4_address_t ip4_prefix;
15751   ip6_address_t ip6_prefix;
15752   ip6_address_t ip6_src;
15753   u32 num_m_args = 0;
15754   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15755     0, psid_length = 0;
15756   u8 is_translation = 0;
15757   u32 mtu = 0;
15758   u32 ip6_src_len = 128;
15759   int ret;
15760
15761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15762     {
15763       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15764                     &ip4_prefix, &ip4_prefix_len))
15765         num_m_args++;
15766       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15767                          &ip6_prefix, &ip6_prefix_len))
15768         num_m_args++;
15769       else
15770         if (unformat
15771             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15772              &ip6_src_len))
15773         num_m_args++;
15774       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15775         num_m_args++;
15776       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15777         num_m_args++;
15778       else if (unformat (i, "psid-offset %d", &psid_offset))
15779         num_m_args++;
15780       else if (unformat (i, "psid-len %d", &psid_length))
15781         num_m_args++;
15782       else if (unformat (i, "mtu %d", &mtu))
15783         num_m_args++;
15784       else if (unformat (i, "map-t"))
15785         is_translation = 1;
15786       else
15787         {
15788           clib_warning ("parse error '%U'", format_unformat_error, i);
15789           return -99;
15790         }
15791     }
15792
15793   if (num_m_args < 3)
15794     {
15795       errmsg ("mandatory argument(s) missing");
15796       return -99;
15797     }
15798
15799   /* Construct the API message */
15800   M (MAP_ADD_DOMAIN, mp);
15801
15802   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15803   mp->ip4_prefix_len = ip4_prefix_len;
15804
15805   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15806   mp->ip6_prefix_len = ip6_prefix_len;
15807
15808   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15809   mp->ip6_src_prefix_len = ip6_src_len;
15810
15811   mp->ea_bits_len = ea_bits_len;
15812   mp->psid_offset = psid_offset;
15813   mp->psid_length = psid_length;
15814   mp->is_translation = is_translation;
15815   mp->mtu = htons (mtu);
15816
15817   /* send it... */
15818   S (mp);
15819
15820   /* Wait for a reply, return good/bad news  */
15821   W (ret);
15822   return ret;
15823 }
15824
15825 static int
15826 api_map_del_domain (vat_main_t * vam)
15827 {
15828   unformat_input_t *i = vam->input;
15829   vl_api_map_del_domain_t *mp;
15830
15831   u32 num_m_args = 0;
15832   u32 index;
15833   int ret;
15834
15835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15836     {
15837       if (unformat (i, "index %d", &index))
15838         num_m_args++;
15839       else
15840         {
15841           clib_warning ("parse error '%U'", format_unformat_error, i);
15842           return -99;
15843         }
15844     }
15845
15846   if (num_m_args != 1)
15847     {
15848       errmsg ("mandatory argument(s) missing");
15849       return -99;
15850     }
15851
15852   /* Construct the API message */
15853   M (MAP_DEL_DOMAIN, mp);
15854
15855   mp->index = ntohl (index);
15856
15857   /* send it... */
15858   S (mp);
15859
15860   /* Wait for a reply, return good/bad news  */
15861   W (ret);
15862   return ret;
15863 }
15864
15865 static int
15866 api_map_add_del_rule (vat_main_t * vam)
15867 {
15868   unformat_input_t *i = vam->input;
15869   vl_api_map_add_del_rule_t *mp;
15870   u8 is_add = 1;
15871   ip6_address_t ip6_dst;
15872   u32 num_m_args = 0, index, psid = 0;
15873   int ret;
15874
15875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15876     {
15877       if (unformat (i, "index %d", &index))
15878         num_m_args++;
15879       else if (unformat (i, "psid %d", &psid))
15880         num_m_args++;
15881       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15882         num_m_args++;
15883       else if (unformat (i, "del"))
15884         {
15885           is_add = 0;
15886         }
15887       else
15888         {
15889           clib_warning ("parse error '%U'", format_unformat_error, i);
15890           return -99;
15891         }
15892     }
15893
15894   /* Construct the API message */
15895   M (MAP_ADD_DEL_RULE, mp);
15896
15897   mp->index = ntohl (index);
15898   mp->is_add = is_add;
15899   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15900   mp->psid = ntohs (psid);
15901
15902   /* send it... */
15903   S (mp);
15904
15905   /* Wait for a reply, return good/bad news  */
15906   W (ret);
15907   return ret;
15908 }
15909
15910 static int
15911 api_map_domain_dump (vat_main_t * vam)
15912 {
15913   vl_api_map_domain_dump_t *mp;
15914   vl_api_control_ping_t *mp_ping;
15915   int ret;
15916
15917   /* Construct the API message */
15918   M (MAP_DOMAIN_DUMP, mp);
15919
15920   /* send it... */
15921   S (mp);
15922
15923   /* Use a control ping for synchronization */
15924   MPING (CONTROL_PING, mp_ping);
15925   S (mp_ping);
15926
15927   W (ret);
15928   return ret;
15929 }
15930
15931 static int
15932 api_map_rule_dump (vat_main_t * vam)
15933 {
15934   unformat_input_t *i = vam->input;
15935   vl_api_map_rule_dump_t *mp;
15936   vl_api_control_ping_t *mp_ping;
15937   u32 domain_index = ~0;
15938   int ret;
15939
15940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15941     {
15942       if (unformat (i, "index %u", &domain_index))
15943         ;
15944       else
15945         break;
15946     }
15947
15948   if (domain_index == ~0)
15949     {
15950       clib_warning ("parse error: domain index expected");
15951       return -99;
15952     }
15953
15954   /* Construct the API message */
15955   M (MAP_RULE_DUMP, mp);
15956
15957   mp->domain_index = htonl (domain_index);
15958
15959   /* send it... */
15960   S (mp);
15961
15962   /* Use a control ping for synchronization */
15963   MPING (CONTROL_PING, mp_ping);
15964   S (mp_ping);
15965
15966   W (ret);
15967   return ret;
15968 }
15969
15970 static void vl_api_map_add_domain_reply_t_handler
15971   (vl_api_map_add_domain_reply_t * mp)
15972 {
15973   vat_main_t *vam = &vat_main;
15974   i32 retval = ntohl (mp->retval);
15975
15976   if (vam->async_mode)
15977     {
15978       vam->async_errors += (retval < 0);
15979     }
15980   else
15981     {
15982       vam->retval = retval;
15983       vam->result_ready = 1;
15984     }
15985 }
15986
15987 static void vl_api_map_add_domain_reply_t_handler_json
15988   (vl_api_map_add_domain_reply_t * mp)
15989 {
15990   vat_main_t *vam = &vat_main;
15991   vat_json_node_t node;
15992
15993   vat_json_init_object (&node);
15994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15995   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15996
15997   vat_json_print (vam->ofp, &node);
15998   vat_json_free (&node);
15999
16000   vam->retval = ntohl (mp->retval);
16001   vam->result_ready = 1;
16002 }
16003
16004 static int
16005 api_get_first_msg_id (vat_main_t * vam)
16006 {
16007   vl_api_get_first_msg_id_t *mp;
16008   unformat_input_t *i = vam->input;
16009   u8 *name;
16010   u8 name_set = 0;
16011   int ret;
16012
16013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16014     {
16015       if (unformat (i, "client %s", &name))
16016         name_set = 1;
16017       else
16018         break;
16019     }
16020
16021   if (name_set == 0)
16022     {
16023       errmsg ("missing client name");
16024       return -99;
16025     }
16026   vec_add1 (name, 0);
16027
16028   if (vec_len (name) > 63)
16029     {
16030       errmsg ("client name too long");
16031       return -99;
16032     }
16033
16034   M (GET_FIRST_MSG_ID, mp);
16035   clib_memcpy (mp->name, name, vec_len (name));
16036   S (mp);
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_cop_interface_enable_disable (vat_main_t * vam)
16043 {
16044   unformat_input_t *line_input = vam->input;
16045   vl_api_cop_interface_enable_disable_t *mp;
16046   u32 sw_if_index = ~0;
16047   u8 enable_disable = 1;
16048   int ret;
16049
16050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16051     {
16052       if (unformat (line_input, "disable"))
16053         enable_disable = 0;
16054       if (unformat (line_input, "enable"))
16055         enable_disable = 1;
16056       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16057                          vam, &sw_if_index))
16058         ;
16059       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16060         ;
16061       else
16062         break;
16063     }
16064
16065   if (sw_if_index == ~0)
16066     {
16067       errmsg ("missing interface name or sw_if_index");
16068       return -99;
16069     }
16070
16071   /* Construct the API message */
16072   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16073   mp->sw_if_index = ntohl (sw_if_index);
16074   mp->enable_disable = enable_disable;
16075
16076   /* send it... */
16077   S (mp);
16078   /* Wait for the reply */
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_cop_whitelist_enable_disable (vat_main_t * vam)
16085 {
16086   unformat_input_t *line_input = vam->input;
16087   vl_api_cop_whitelist_enable_disable_t *mp;
16088   u32 sw_if_index = ~0;
16089   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16090   u32 fib_id = 0;
16091   int ret;
16092
16093   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (line_input, "ip4"))
16096         ip4 = 1;
16097       else if (unformat (line_input, "ip6"))
16098         ip6 = 1;
16099       else if (unformat (line_input, "default"))
16100         default_cop = 1;
16101       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16102                          vam, &sw_if_index))
16103         ;
16104       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16105         ;
16106       else if (unformat (line_input, "fib-id %d", &fib_id))
16107         ;
16108       else
16109         break;
16110     }
16111
16112   if (sw_if_index == ~0)
16113     {
16114       errmsg ("missing interface name or sw_if_index");
16115       return -99;
16116     }
16117
16118   /* Construct the API message */
16119   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16120   mp->sw_if_index = ntohl (sw_if_index);
16121   mp->fib_id = ntohl (fib_id);
16122   mp->ip4 = ip4;
16123   mp->ip6 = ip6;
16124   mp->default_cop = default_cop;
16125
16126   /* send it... */
16127   S (mp);
16128   /* Wait for the reply */
16129   W (ret);
16130   return ret;
16131 }
16132
16133 static int
16134 api_get_node_graph (vat_main_t * vam)
16135 {
16136   vl_api_get_node_graph_t *mp;
16137   int ret;
16138
16139   M (GET_NODE_GRAPH, mp);
16140
16141   /* send it... */
16142   S (mp);
16143   /* Wait for the reply */
16144   W (ret);
16145   return ret;
16146 }
16147
16148 /* *INDENT-OFF* */
16149 /** Used for parsing LISP eids */
16150 typedef CLIB_PACKED(struct{
16151   u8 addr[16];   /**< eid address */
16152   u32 len;       /**< prefix length if IP */
16153   u8 type;      /**< type of eid */
16154 }) lisp_eid_vat_t;
16155 /* *INDENT-ON* */
16156
16157 static uword
16158 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16159 {
16160   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16161
16162   memset (a, 0, sizeof (a[0]));
16163
16164   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16165     {
16166       a->type = 0;              /* ipv4 type */
16167     }
16168   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16169     {
16170       a->type = 1;              /* ipv6 type */
16171     }
16172   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16173     {
16174       a->type = 2;              /* mac type */
16175     }
16176   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16177     {
16178       a->type = 3;              /* NSH type */
16179       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16180       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16181     }
16182   else
16183     {
16184       return 0;
16185     }
16186
16187   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16188     {
16189       return 0;
16190     }
16191
16192   return 1;
16193 }
16194
16195 static int
16196 lisp_eid_size_vat (u8 type)
16197 {
16198   switch (type)
16199     {
16200     case 0:
16201       return 4;
16202     case 1:
16203       return 16;
16204     case 2:
16205       return 6;
16206     case 3:
16207       return 5;
16208     }
16209   return 0;
16210 }
16211
16212 static void
16213 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16214 {
16215   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16216 }
16217
16218 static int
16219 api_one_add_del_locator_set (vat_main_t * vam)
16220 {
16221   unformat_input_t *input = vam->input;
16222   vl_api_one_add_del_locator_set_t *mp;
16223   u8 is_add = 1;
16224   u8 *locator_set_name = NULL;
16225   u8 locator_set_name_set = 0;
16226   vl_api_local_locator_t locator, *locators = 0;
16227   u32 sw_if_index, priority, weight;
16228   u32 data_len = 0;
16229
16230   int ret;
16231   /* Parse args required to build the message */
16232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (input, "del"))
16235         {
16236           is_add = 0;
16237         }
16238       else if (unformat (input, "locator-set %s", &locator_set_name))
16239         {
16240           locator_set_name_set = 1;
16241         }
16242       else if (unformat (input, "sw_if_index %u p %u w %u",
16243                          &sw_if_index, &priority, &weight))
16244         {
16245           locator.sw_if_index = htonl (sw_if_index);
16246           locator.priority = priority;
16247           locator.weight = weight;
16248           vec_add1 (locators, locator);
16249         }
16250       else
16251         if (unformat
16252             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16253              &sw_if_index, &priority, &weight))
16254         {
16255           locator.sw_if_index = htonl (sw_if_index);
16256           locator.priority = priority;
16257           locator.weight = weight;
16258           vec_add1 (locators, locator);
16259         }
16260       else
16261         break;
16262     }
16263
16264   if (locator_set_name_set == 0)
16265     {
16266       errmsg ("missing locator-set name");
16267       vec_free (locators);
16268       return -99;
16269     }
16270
16271   if (vec_len (locator_set_name) > 64)
16272     {
16273       errmsg ("locator-set name too long");
16274       vec_free (locator_set_name);
16275       vec_free (locators);
16276       return -99;
16277     }
16278   vec_add1 (locator_set_name, 0);
16279
16280   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16281
16282   /* Construct the API message */
16283   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16284
16285   mp->is_add = is_add;
16286   clib_memcpy (mp->locator_set_name, locator_set_name,
16287                vec_len (locator_set_name));
16288   vec_free (locator_set_name);
16289
16290   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16291   if (locators)
16292     clib_memcpy (mp->locators, locators, data_len);
16293   vec_free (locators);
16294
16295   /* send it... */
16296   S (mp);
16297
16298   /* Wait for a reply... */
16299   W (ret);
16300   return ret;
16301 }
16302
16303 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16304
16305 static int
16306 api_one_add_del_locator (vat_main_t * vam)
16307 {
16308   unformat_input_t *input = vam->input;
16309   vl_api_one_add_del_locator_t *mp;
16310   u32 tmp_if_index = ~0;
16311   u32 sw_if_index = ~0;
16312   u8 sw_if_index_set = 0;
16313   u8 sw_if_index_if_name_set = 0;
16314   u32 priority = ~0;
16315   u8 priority_set = 0;
16316   u32 weight = ~0;
16317   u8 weight_set = 0;
16318   u8 is_add = 1;
16319   u8 *locator_set_name = NULL;
16320   u8 locator_set_name_set = 0;
16321   int ret;
16322
16323   /* Parse args required to build the message */
16324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16325     {
16326       if (unformat (input, "del"))
16327         {
16328           is_add = 0;
16329         }
16330       else if (unformat (input, "locator-set %s", &locator_set_name))
16331         {
16332           locator_set_name_set = 1;
16333         }
16334       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16335                          &tmp_if_index))
16336         {
16337           sw_if_index_if_name_set = 1;
16338           sw_if_index = tmp_if_index;
16339         }
16340       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16341         {
16342           sw_if_index_set = 1;
16343           sw_if_index = tmp_if_index;
16344         }
16345       else if (unformat (input, "p %d", &priority))
16346         {
16347           priority_set = 1;
16348         }
16349       else if (unformat (input, "w %d", &weight))
16350         {
16351           weight_set = 1;
16352         }
16353       else
16354         break;
16355     }
16356
16357   if (locator_set_name_set == 0)
16358     {
16359       errmsg ("missing locator-set name");
16360       return -99;
16361     }
16362
16363   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16364     {
16365       errmsg ("missing sw_if_index");
16366       vec_free (locator_set_name);
16367       return -99;
16368     }
16369
16370   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16371     {
16372       errmsg ("cannot use both params interface name and sw_if_index");
16373       vec_free (locator_set_name);
16374       return -99;
16375     }
16376
16377   if (priority_set == 0)
16378     {
16379       errmsg ("missing locator-set priority");
16380       vec_free (locator_set_name);
16381       return -99;
16382     }
16383
16384   if (weight_set == 0)
16385     {
16386       errmsg ("missing locator-set weight");
16387       vec_free (locator_set_name);
16388       return -99;
16389     }
16390
16391   if (vec_len (locator_set_name) > 64)
16392     {
16393       errmsg ("locator-set name too long");
16394       vec_free (locator_set_name);
16395       return -99;
16396     }
16397   vec_add1 (locator_set_name, 0);
16398
16399   /* Construct the API message */
16400   M (ONE_ADD_DEL_LOCATOR, mp);
16401
16402   mp->is_add = is_add;
16403   mp->sw_if_index = ntohl (sw_if_index);
16404   mp->priority = priority;
16405   mp->weight = weight;
16406   clib_memcpy (mp->locator_set_name, locator_set_name,
16407                vec_len (locator_set_name));
16408   vec_free (locator_set_name);
16409
16410   /* send it... */
16411   S (mp);
16412
16413   /* Wait for a reply... */
16414   W (ret);
16415   return ret;
16416 }
16417
16418 #define api_lisp_add_del_locator api_one_add_del_locator
16419
16420 uword
16421 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16422 {
16423   u32 *key_id = va_arg (*args, u32 *);
16424   u8 *s = 0;
16425
16426   if (unformat (input, "%s", &s))
16427     {
16428       if (!strcmp ((char *) s, "sha1"))
16429         key_id[0] = HMAC_SHA_1_96;
16430       else if (!strcmp ((char *) s, "sha256"))
16431         key_id[0] = HMAC_SHA_256_128;
16432       else
16433         {
16434           clib_warning ("invalid key_id: '%s'", s);
16435           key_id[0] = HMAC_NO_KEY;
16436         }
16437     }
16438   else
16439     return 0;
16440
16441   vec_free (s);
16442   return 1;
16443 }
16444
16445 static int
16446 api_one_add_del_local_eid (vat_main_t * vam)
16447 {
16448   unformat_input_t *input = vam->input;
16449   vl_api_one_add_del_local_eid_t *mp;
16450   u8 is_add = 1;
16451   u8 eid_set = 0;
16452   lisp_eid_vat_t _eid, *eid = &_eid;
16453   u8 *locator_set_name = 0;
16454   u8 locator_set_name_set = 0;
16455   u32 vni = 0;
16456   u16 key_id = 0;
16457   u8 *key = 0;
16458   int ret;
16459
16460   /* Parse args required to build the message */
16461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16462     {
16463       if (unformat (input, "del"))
16464         {
16465           is_add = 0;
16466         }
16467       else if (unformat (input, "vni %d", &vni))
16468         {
16469           ;
16470         }
16471       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16472         {
16473           eid_set = 1;
16474         }
16475       else if (unformat (input, "locator-set %s", &locator_set_name))
16476         {
16477           locator_set_name_set = 1;
16478         }
16479       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16480         ;
16481       else if (unformat (input, "secret-key %_%v%_", &key))
16482         ;
16483       else
16484         break;
16485     }
16486
16487   if (locator_set_name_set == 0)
16488     {
16489       errmsg ("missing locator-set name");
16490       return -99;
16491     }
16492
16493   if (0 == eid_set)
16494     {
16495       errmsg ("EID address not set!");
16496       vec_free (locator_set_name);
16497       return -99;
16498     }
16499
16500   if (key && (0 == key_id))
16501     {
16502       errmsg ("invalid key_id!");
16503       return -99;
16504     }
16505
16506   if (vec_len (key) > 64)
16507     {
16508       errmsg ("key too long");
16509       vec_free (key);
16510       return -99;
16511     }
16512
16513   if (vec_len (locator_set_name) > 64)
16514     {
16515       errmsg ("locator-set name too long");
16516       vec_free (locator_set_name);
16517       return -99;
16518     }
16519   vec_add1 (locator_set_name, 0);
16520
16521   /* Construct the API message */
16522   M (ONE_ADD_DEL_LOCAL_EID, mp);
16523
16524   mp->is_add = is_add;
16525   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16526   mp->eid_type = eid->type;
16527   mp->prefix_len = eid->len;
16528   mp->vni = clib_host_to_net_u32 (vni);
16529   mp->key_id = clib_host_to_net_u16 (key_id);
16530   clib_memcpy (mp->locator_set_name, locator_set_name,
16531                vec_len (locator_set_name));
16532   clib_memcpy (mp->key, key, vec_len (key));
16533
16534   vec_free (locator_set_name);
16535   vec_free (key);
16536
16537   /* send it... */
16538   S (mp);
16539
16540   /* Wait for a reply... */
16541   W (ret);
16542   return ret;
16543 }
16544
16545 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16546
16547 static int
16548 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16549 {
16550   u32 dp_table = 0, vni = 0;;
16551   unformat_input_t *input = vam->input;
16552   vl_api_gpe_add_del_fwd_entry_t *mp;
16553   u8 is_add = 1;
16554   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16555   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16556   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16557   u32 action = ~0, w;
16558   ip4_address_t rmt_rloc4, lcl_rloc4;
16559   ip6_address_t rmt_rloc6, lcl_rloc6;
16560   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16561   int ret;
16562
16563   memset (&rloc, 0, sizeof (rloc));
16564
16565   /* Parse args required to build the message */
16566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16567     {
16568       if (unformat (input, "del"))
16569         is_add = 0;
16570       else if (unformat (input, "add"))
16571         is_add = 1;
16572       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16573         {
16574           rmt_eid_set = 1;
16575         }
16576       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16577         {
16578           lcl_eid_set = 1;
16579         }
16580       else if (unformat (input, "vrf %d", &dp_table))
16581         ;
16582       else if (unformat (input, "bd %d", &dp_table))
16583         ;
16584       else if (unformat (input, "vni %d", &vni))
16585         ;
16586       else if (unformat (input, "w %d", &w))
16587         {
16588           if (!curr_rloc)
16589             {
16590               errmsg ("No RLOC configured for setting priority/weight!");
16591               return -99;
16592             }
16593           curr_rloc->weight = w;
16594         }
16595       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16596                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16597         {
16598           rloc.is_ip4 = 1;
16599
16600           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16601           rloc.weight = 0;
16602           vec_add1 (lcl_locs, rloc);
16603
16604           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16605           vec_add1 (rmt_locs, rloc);
16606           /* weight saved in rmt loc */
16607           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16608         }
16609       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16610                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16611         {
16612           rloc.is_ip4 = 0;
16613           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16614           rloc.weight = 0;
16615           vec_add1 (lcl_locs, rloc);
16616
16617           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16618           vec_add1 (rmt_locs, rloc);
16619           /* weight saved in rmt loc */
16620           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16621         }
16622       else if (unformat (input, "action %d", &action))
16623         {
16624           ;
16625         }
16626       else
16627         {
16628           clib_warning ("parse error '%U'", format_unformat_error, input);
16629           return -99;
16630         }
16631     }
16632
16633   if (!rmt_eid_set)
16634     {
16635       errmsg ("remote eid addresses not set");
16636       return -99;
16637     }
16638
16639   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16640     {
16641       errmsg ("eid types don't match");
16642       return -99;
16643     }
16644
16645   if (0 == rmt_locs && (u32) ~ 0 == action)
16646     {
16647       errmsg ("action not set for negative mapping");
16648       return -99;
16649     }
16650
16651   /* Construct the API message */
16652   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16653       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16654
16655   mp->is_add = is_add;
16656   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16657   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16658   mp->eid_type = rmt_eid->type;
16659   mp->dp_table = clib_host_to_net_u32 (dp_table);
16660   mp->vni = clib_host_to_net_u32 (vni);
16661   mp->rmt_len = rmt_eid->len;
16662   mp->lcl_len = lcl_eid->len;
16663   mp->action = action;
16664
16665   if (0 != rmt_locs && 0 != lcl_locs)
16666     {
16667       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16668       clib_memcpy (mp->locs, lcl_locs,
16669                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16670
16671       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16672       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16673                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16674     }
16675   vec_free (lcl_locs);
16676   vec_free (rmt_locs);
16677
16678   /* send it... */
16679   S (mp);
16680
16681   /* Wait for a reply... */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 static int
16687 api_one_add_del_map_server (vat_main_t * vam)
16688 {
16689   unformat_input_t *input = vam->input;
16690   vl_api_one_add_del_map_server_t *mp;
16691   u8 is_add = 1;
16692   u8 ipv4_set = 0;
16693   u8 ipv6_set = 0;
16694   ip4_address_t ipv4;
16695   ip6_address_t ipv6;
16696   int ret;
16697
16698   /* Parse args required to build the message */
16699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (input, "del"))
16702         {
16703           is_add = 0;
16704         }
16705       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16706         {
16707           ipv4_set = 1;
16708         }
16709       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16710         {
16711           ipv6_set = 1;
16712         }
16713       else
16714         break;
16715     }
16716
16717   if (ipv4_set && ipv6_set)
16718     {
16719       errmsg ("both eid v4 and v6 addresses set");
16720       return -99;
16721     }
16722
16723   if (!ipv4_set && !ipv6_set)
16724     {
16725       errmsg ("eid addresses not set");
16726       return -99;
16727     }
16728
16729   /* Construct the API message */
16730   M (ONE_ADD_DEL_MAP_SERVER, mp);
16731
16732   mp->is_add = is_add;
16733   if (ipv6_set)
16734     {
16735       mp->is_ipv6 = 1;
16736       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16737     }
16738   else
16739     {
16740       mp->is_ipv6 = 0;
16741       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16742     }
16743
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define api_lisp_add_del_map_server api_one_add_del_map_server
16753
16754 static int
16755 api_one_add_del_map_resolver (vat_main_t * vam)
16756 {
16757   unformat_input_t *input = vam->input;
16758   vl_api_one_add_del_map_resolver_t *mp;
16759   u8 is_add = 1;
16760   u8 ipv4_set = 0;
16761   u8 ipv6_set = 0;
16762   ip4_address_t ipv4;
16763   ip6_address_t ipv6;
16764   int ret;
16765
16766   /* Parse args required to build the message */
16767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16768     {
16769       if (unformat (input, "del"))
16770         {
16771           is_add = 0;
16772         }
16773       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16774         {
16775           ipv4_set = 1;
16776         }
16777       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16778         {
16779           ipv6_set = 1;
16780         }
16781       else
16782         break;
16783     }
16784
16785   if (ipv4_set && ipv6_set)
16786     {
16787       errmsg ("both eid v4 and v6 addresses set");
16788       return -99;
16789     }
16790
16791   if (!ipv4_set && !ipv6_set)
16792     {
16793       errmsg ("eid addresses not set");
16794       return -99;
16795     }
16796
16797   /* Construct the API message */
16798   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16799
16800   mp->is_add = is_add;
16801   if (ipv6_set)
16802     {
16803       mp->is_ipv6 = 1;
16804       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16805     }
16806   else
16807     {
16808       mp->is_ipv6 = 0;
16809       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16810     }
16811
16812   /* send it... */
16813   S (mp);
16814
16815   /* Wait for a reply... */
16816   W (ret);
16817   return ret;
16818 }
16819
16820 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16821
16822 static int
16823 api_lisp_gpe_enable_disable (vat_main_t * vam)
16824 {
16825   unformat_input_t *input = vam->input;
16826   vl_api_gpe_enable_disable_t *mp;
16827   u8 is_set = 0;
16828   u8 is_en = 1;
16829   int ret;
16830
16831   /* Parse args required to build the message */
16832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16833     {
16834       if (unformat (input, "enable"))
16835         {
16836           is_set = 1;
16837           is_en = 1;
16838         }
16839       else if (unformat (input, "disable"))
16840         {
16841           is_set = 1;
16842           is_en = 0;
16843         }
16844       else
16845         break;
16846     }
16847
16848   if (is_set == 0)
16849     {
16850       errmsg ("Value not set");
16851       return -99;
16852     }
16853
16854   /* Construct the API message */
16855   M (GPE_ENABLE_DISABLE, mp);
16856
16857   mp->is_en = is_en;
16858
16859   /* send it... */
16860   S (mp);
16861
16862   /* Wait for a reply... */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 static int
16868 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16869 {
16870   unformat_input_t *input = vam->input;
16871   vl_api_one_rloc_probe_enable_disable_t *mp;
16872   u8 is_set = 0;
16873   u8 is_en = 0;
16874   int ret;
16875
16876   /* Parse args required to build the message */
16877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16878     {
16879       if (unformat (input, "enable"))
16880         {
16881           is_set = 1;
16882           is_en = 1;
16883         }
16884       else if (unformat (input, "disable"))
16885         is_set = 1;
16886       else
16887         break;
16888     }
16889
16890   if (!is_set)
16891     {
16892       errmsg ("Value not set");
16893       return -99;
16894     }
16895
16896   /* Construct the API message */
16897   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16898
16899   mp->is_enabled = is_en;
16900
16901   /* send it... */
16902   S (mp);
16903
16904   /* Wait for a reply... */
16905   W (ret);
16906   return ret;
16907 }
16908
16909 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16910
16911 static int
16912 api_one_map_register_enable_disable (vat_main_t * vam)
16913 {
16914   unformat_input_t *input = vam->input;
16915   vl_api_one_map_register_enable_disable_t *mp;
16916   u8 is_set = 0;
16917   u8 is_en = 0;
16918   int ret;
16919
16920   /* Parse args required to build the message */
16921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16922     {
16923       if (unformat (input, "enable"))
16924         {
16925           is_set = 1;
16926           is_en = 1;
16927         }
16928       else if (unformat (input, "disable"))
16929         is_set = 1;
16930       else
16931         break;
16932     }
16933
16934   if (!is_set)
16935     {
16936       errmsg ("Value not set");
16937       return -99;
16938     }
16939
16940   /* Construct the API message */
16941   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16942
16943   mp->is_enabled = is_en;
16944
16945   /* send it... */
16946   S (mp);
16947
16948   /* Wait for a reply... */
16949   W (ret);
16950   return ret;
16951 }
16952
16953 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16954
16955 static int
16956 api_one_enable_disable (vat_main_t * vam)
16957 {
16958   unformat_input_t *input = vam->input;
16959   vl_api_one_enable_disable_t *mp;
16960   u8 is_set = 0;
16961   u8 is_en = 0;
16962   int ret;
16963
16964   /* Parse args required to build the message */
16965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16966     {
16967       if (unformat (input, "enable"))
16968         {
16969           is_set = 1;
16970           is_en = 1;
16971         }
16972       else if (unformat (input, "disable"))
16973         {
16974           is_set = 1;
16975         }
16976       else
16977         break;
16978     }
16979
16980   if (!is_set)
16981     {
16982       errmsg ("Value not set");
16983       return -99;
16984     }
16985
16986   /* Construct the API message */
16987   M (ONE_ENABLE_DISABLE, mp);
16988
16989   mp->is_en = is_en;
16990
16991   /* send it... */
16992   S (mp);
16993
16994   /* Wait for a reply... */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 #define api_lisp_enable_disable api_one_enable_disable
17000
17001 static int
17002 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17003 {
17004   unformat_input_t *input = vam->input;
17005   vl_api_one_enable_disable_xtr_mode_t *mp;
17006   u8 is_set = 0;
17007   u8 is_en = 0;
17008   int ret;
17009
17010   /* Parse args required to build the message */
17011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17012     {
17013       if (unformat (input, "enable"))
17014         {
17015           is_set = 1;
17016           is_en = 1;
17017         }
17018       else if (unformat (input, "disable"))
17019         {
17020           is_set = 1;
17021         }
17022       else
17023         break;
17024     }
17025
17026   if (!is_set)
17027     {
17028       errmsg ("Value not set");
17029       return -99;
17030     }
17031
17032   /* Construct the API message */
17033   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17034
17035   mp->is_en = is_en;
17036
17037   /* send it... */
17038   S (mp);
17039
17040   /* Wait for a reply... */
17041   W (ret);
17042   return ret;
17043 }
17044
17045 static int
17046 api_one_show_xtr_mode (vat_main_t * vam)
17047 {
17048   vl_api_one_show_xtr_mode_t *mp;
17049   int ret;
17050
17051   /* Construct the API message */
17052   M (ONE_SHOW_XTR_MODE, mp);
17053
17054   /* send it... */
17055   S (mp);
17056
17057   /* Wait for a reply... */
17058   W (ret);
17059   return ret;
17060 }
17061
17062 static int
17063 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17064 {
17065   unformat_input_t *input = vam->input;
17066   vl_api_one_enable_disable_pitr_mode_t *mp;
17067   u8 is_set = 0;
17068   u8 is_en = 0;
17069   int ret;
17070
17071   /* Parse args required to build the message */
17072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17073     {
17074       if (unformat (input, "enable"))
17075         {
17076           is_set = 1;
17077           is_en = 1;
17078         }
17079       else if (unformat (input, "disable"))
17080         {
17081           is_set = 1;
17082         }
17083       else
17084         break;
17085     }
17086
17087   if (!is_set)
17088     {
17089       errmsg ("Value not set");
17090       return -99;
17091     }
17092
17093   /* Construct the API message */
17094   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17095
17096   mp->is_en = is_en;
17097
17098   /* send it... */
17099   S (mp);
17100
17101   /* Wait for a reply... */
17102   W (ret);
17103   return ret;
17104 }
17105
17106 static int
17107 api_one_show_pitr_mode (vat_main_t * vam)
17108 {
17109   vl_api_one_show_pitr_mode_t *mp;
17110   int ret;
17111
17112   /* Construct the API message */
17113   M (ONE_SHOW_PITR_MODE, mp);
17114
17115   /* send it... */
17116   S (mp);
17117
17118   /* Wait for a reply... */
17119   W (ret);
17120   return ret;
17121 }
17122
17123 static int
17124 api_one_enable_disable_petr_mode (vat_main_t * vam)
17125 {
17126   unformat_input_t *input = vam->input;
17127   vl_api_one_enable_disable_petr_mode_t *mp;
17128   u8 is_set = 0;
17129   u8 is_en = 0;
17130   int ret;
17131
17132   /* Parse args required to build the message */
17133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17134     {
17135       if (unformat (input, "enable"))
17136         {
17137           is_set = 1;
17138           is_en = 1;
17139         }
17140       else if (unformat (input, "disable"))
17141         {
17142           is_set = 1;
17143         }
17144       else
17145         break;
17146     }
17147
17148   if (!is_set)
17149     {
17150       errmsg ("Value not set");
17151       return -99;
17152     }
17153
17154   /* Construct the API message */
17155   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17156
17157   mp->is_en = is_en;
17158
17159   /* send it... */
17160   S (mp);
17161
17162   /* Wait for a reply... */
17163   W (ret);
17164   return ret;
17165 }
17166
17167 static int
17168 api_one_show_petr_mode (vat_main_t * vam)
17169 {
17170   vl_api_one_show_petr_mode_t *mp;
17171   int ret;
17172
17173   /* Construct the API message */
17174   M (ONE_SHOW_PETR_MODE, mp);
17175
17176   /* send it... */
17177   S (mp);
17178
17179   /* Wait for a reply... */
17180   W (ret);
17181   return ret;
17182 }
17183
17184 static int
17185 api_show_one_map_register_state (vat_main_t * vam)
17186 {
17187   vl_api_show_one_map_register_state_t *mp;
17188   int ret;
17189
17190   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17191
17192   /* send */
17193   S (mp);
17194
17195   /* wait for reply */
17196   W (ret);
17197   return ret;
17198 }
17199
17200 #define api_show_lisp_map_register_state api_show_one_map_register_state
17201
17202 static int
17203 api_show_one_rloc_probe_state (vat_main_t * vam)
17204 {
17205   vl_api_show_one_rloc_probe_state_t *mp;
17206   int ret;
17207
17208   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17209
17210   /* send */
17211   S (mp);
17212
17213   /* wait for reply */
17214   W (ret);
17215   return ret;
17216 }
17217
17218 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17219
17220 static int
17221 api_one_add_del_ndp_entry (vat_main_t * vam)
17222 {
17223   vl_api_one_add_del_ndp_entry_t *mp;
17224   unformat_input_t *input = vam->input;
17225   u8 is_add = 1;
17226   u8 mac_set = 0;
17227   u8 bd_set = 0;
17228   u8 ip_set = 0;
17229   u8 mac[6] = { 0, };
17230   u8 ip6[16] = { 0, };
17231   u32 bd = ~0;
17232   int ret;
17233
17234   /* Parse args required to build the message */
17235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17236     {
17237       if (unformat (input, "del"))
17238         is_add = 0;
17239       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17240         mac_set = 1;
17241       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17242         ip_set = 1;
17243       else if (unformat (input, "bd %d", &bd))
17244         bd_set = 1;
17245       else
17246         {
17247           errmsg ("parse error '%U'", format_unformat_error, input);
17248           return -99;
17249         }
17250     }
17251
17252   if (!bd_set || !ip_set || (!mac_set && is_add))
17253     {
17254       errmsg ("Missing BD, IP or MAC!");
17255       return -99;
17256     }
17257
17258   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17259   mp->is_add = is_add;
17260   clib_memcpy (mp->mac, mac, 6);
17261   mp->bd = clib_host_to_net_u32 (bd);
17262   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17263
17264   /* send */
17265   S (mp);
17266
17267   /* wait for reply */
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17274 {
17275   vl_api_one_add_del_l2_arp_entry_t *mp;
17276   unformat_input_t *input = vam->input;
17277   u8 is_add = 1;
17278   u8 mac_set = 0;
17279   u8 bd_set = 0;
17280   u8 ip_set = 0;
17281   u8 mac[6] = { 0, };
17282   u32 ip4 = 0, bd = ~0;
17283   int ret;
17284
17285   /* Parse args required to build the message */
17286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17287     {
17288       if (unformat (input, "del"))
17289         is_add = 0;
17290       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17291         mac_set = 1;
17292       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17293         ip_set = 1;
17294       else if (unformat (input, "bd %d", &bd))
17295         bd_set = 1;
17296       else
17297         {
17298           errmsg ("parse error '%U'", format_unformat_error, input);
17299           return -99;
17300         }
17301     }
17302
17303   if (!bd_set || !ip_set || (!mac_set && is_add))
17304     {
17305       errmsg ("Missing BD, IP or MAC!");
17306       return -99;
17307     }
17308
17309   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17310   mp->is_add = is_add;
17311   clib_memcpy (mp->mac, mac, 6);
17312   mp->bd = clib_host_to_net_u32 (bd);
17313   mp->ip4 = ip4;
17314
17315   /* send */
17316   S (mp);
17317
17318   /* wait for reply */
17319   W (ret);
17320   return ret;
17321 }
17322
17323 static int
17324 api_one_ndp_bd_get (vat_main_t * vam)
17325 {
17326   vl_api_one_ndp_bd_get_t *mp;
17327   int ret;
17328
17329   M (ONE_NDP_BD_GET, mp);
17330
17331   /* send */
17332   S (mp);
17333
17334   /* wait for reply */
17335   W (ret);
17336   return ret;
17337 }
17338
17339 static int
17340 api_one_ndp_entries_get (vat_main_t * vam)
17341 {
17342   vl_api_one_ndp_entries_get_t *mp;
17343   unformat_input_t *input = vam->input;
17344   u8 bd_set = 0;
17345   u32 bd = ~0;
17346   int ret;
17347
17348   /* Parse args required to build the message */
17349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17350     {
17351       if (unformat (input, "bd %d", &bd))
17352         bd_set = 1;
17353       else
17354         {
17355           errmsg ("parse error '%U'", format_unformat_error, input);
17356           return -99;
17357         }
17358     }
17359
17360   if (!bd_set)
17361     {
17362       errmsg ("Expected bridge domain!");
17363       return -99;
17364     }
17365
17366   M (ONE_NDP_ENTRIES_GET, mp);
17367   mp->bd = clib_host_to_net_u32 (bd);
17368
17369   /* send */
17370   S (mp);
17371
17372   /* wait for reply */
17373   W (ret);
17374   return ret;
17375 }
17376
17377 static int
17378 api_one_l2_arp_bd_get (vat_main_t * vam)
17379 {
17380   vl_api_one_l2_arp_bd_get_t *mp;
17381   int ret;
17382
17383   M (ONE_L2_ARP_BD_GET, mp);
17384
17385   /* send */
17386   S (mp);
17387
17388   /* wait for reply */
17389   W (ret);
17390   return ret;
17391 }
17392
17393 static int
17394 api_one_l2_arp_entries_get (vat_main_t * vam)
17395 {
17396   vl_api_one_l2_arp_entries_get_t *mp;
17397   unformat_input_t *input = vam->input;
17398   u8 bd_set = 0;
17399   u32 bd = ~0;
17400   int ret;
17401
17402   /* Parse args required to build the message */
17403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (input, "bd %d", &bd))
17406         bd_set = 1;
17407       else
17408         {
17409           errmsg ("parse error '%U'", format_unformat_error, input);
17410           return -99;
17411         }
17412     }
17413
17414   if (!bd_set)
17415     {
17416       errmsg ("Expected bridge domain!");
17417       return -99;
17418     }
17419
17420   M (ONE_L2_ARP_ENTRIES_GET, mp);
17421   mp->bd = clib_host_to_net_u32 (bd);
17422
17423   /* send */
17424   S (mp);
17425
17426   /* wait for reply */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_one_stats_enable_disable (vat_main_t * vam)
17433 {
17434   vl_api_one_stats_enable_disable_t *mp;
17435   unformat_input_t *input = vam->input;
17436   u8 is_set = 0;
17437   u8 is_en = 0;
17438   int ret;
17439
17440   /* Parse args required to build the message */
17441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17442     {
17443       if (unformat (input, "enable"))
17444         {
17445           is_set = 1;
17446           is_en = 1;
17447         }
17448       else if (unformat (input, "disable"))
17449         {
17450           is_set = 1;
17451         }
17452       else
17453         break;
17454     }
17455
17456   if (!is_set)
17457     {
17458       errmsg ("Value not set");
17459       return -99;
17460     }
17461
17462   M (ONE_STATS_ENABLE_DISABLE, mp);
17463   mp->is_en = is_en;
17464
17465   /* send */
17466   S (mp);
17467
17468   /* wait for reply */
17469   W (ret);
17470   return ret;
17471 }
17472
17473 static int
17474 api_show_one_stats_enable_disable (vat_main_t * vam)
17475 {
17476   vl_api_show_one_stats_enable_disable_t *mp;
17477   int ret;
17478
17479   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17480
17481   /* send */
17482   S (mp);
17483
17484   /* wait for reply */
17485   W (ret);
17486   return ret;
17487 }
17488
17489 static int
17490 api_show_one_map_request_mode (vat_main_t * vam)
17491 {
17492   vl_api_show_one_map_request_mode_t *mp;
17493   int ret;
17494
17495   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17496
17497   /* send */
17498   S (mp);
17499
17500   /* wait for reply */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17506
17507 static int
17508 api_one_map_request_mode (vat_main_t * vam)
17509 {
17510   unformat_input_t *input = vam->input;
17511   vl_api_one_map_request_mode_t *mp;
17512   u8 mode = 0;
17513   int ret;
17514
17515   /* Parse args required to build the message */
17516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17517     {
17518       if (unformat (input, "dst-only"))
17519         mode = 0;
17520       else if (unformat (input, "src-dst"))
17521         mode = 1;
17522       else
17523         {
17524           errmsg ("parse error '%U'", format_unformat_error, input);
17525           return -99;
17526         }
17527     }
17528
17529   M (ONE_MAP_REQUEST_MODE, mp);
17530
17531   mp->mode = mode;
17532
17533   /* send */
17534   S (mp);
17535
17536   /* wait for reply */
17537   W (ret);
17538   return ret;
17539 }
17540
17541 #define api_lisp_map_request_mode api_one_map_request_mode
17542
17543 /**
17544  * Enable/disable ONE proxy ITR.
17545  *
17546  * @param vam vpp API test context
17547  * @return return code
17548  */
17549 static int
17550 api_one_pitr_set_locator_set (vat_main_t * vam)
17551 {
17552   u8 ls_name_set = 0;
17553   unformat_input_t *input = vam->input;
17554   vl_api_one_pitr_set_locator_set_t *mp;
17555   u8 is_add = 1;
17556   u8 *ls_name = 0;
17557   int ret;
17558
17559   /* Parse args required to build the message */
17560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17561     {
17562       if (unformat (input, "del"))
17563         is_add = 0;
17564       else if (unformat (input, "locator-set %s", &ls_name))
17565         ls_name_set = 1;
17566       else
17567         {
17568           errmsg ("parse error '%U'", format_unformat_error, input);
17569           return -99;
17570         }
17571     }
17572
17573   if (!ls_name_set)
17574     {
17575       errmsg ("locator-set name not set!");
17576       return -99;
17577     }
17578
17579   M (ONE_PITR_SET_LOCATOR_SET, mp);
17580
17581   mp->is_add = is_add;
17582   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17583   vec_free (ls_name);
17584
17585   /* send */
17586   S (mp);
17587
17588   /* wait for reply */
17589   W (ret);
17590   return ret;
17591 }
17592
17593 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17594
17595 static int
17596 api_one_nsh_set_locator_set (vat_main_t * vam)
17597 {
17598   u8 ls_name_set = 0;
17599   unformat_input_t *input = vam->input;
17600   vl_api_one_nsh_set_locator_set_t *mp;
17601   u8 is_add = 1;
17602   u8 *ls_name = 0;
17603   int ret;
17604
17605   /* Parse args required to build the message */
17606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17607     {
17608       if (unformat (input, "del"))
17609         is_add = 0;
17610       else if (unformat (input, "ls %s", &ls_name))
17611         ls_name_set = 1;
17612       else
17613         {
17614           errmsg ("parse error '%U'", format_unformat_error, input);
17615           return -99;
17616         }
17617     }
17618
17619   if (!ls_name_set && is_add)
17620     {
17621       errmsg ("locator-set name not set!");
17622       return -99;
17623     }
17624
17625   M (ONE_NSH_SET_LOCATOR_SET, mp);
17626
17627   mp->is_add = is_add;
17628   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17629   vec_free (ls_name);
17630
17631   /* send */
17632   S (mp);
17633
17634   /* wait for reply */
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static int
17640 api_show_one_pitr (vat_main_t * vam)
17641 {
17642   vl_api_show_one_pitr_t *mp;
17643   int ret;
17644
17645   if (!vam->json_output)
17646     {
17647       print (vam->ofp, "%=20s", "lisp status:");
17648     }
17649
17650   M (SHOW_ONE_PITR, mp);
17651   /* send it... */
17652   S (mp);
17653
17654   /* Wait for a reply... */
17655   W (ret);
17656   return ret;
17657 }
17658
17659 #define api_show_lisp_pitr api_show_one_pitr
17660
17661 static int
17662 api_one_use_petr (vat_main_t * vam)
17663 {
17664   unformat_input_t *input = vam->input;
17665   vl_api_one_use_petr_t *mp;
17666   u8 is_add = 0;
17667   ip_address_t ip;
17668   int ret;
17669
17670   memset (&ip, 0, sizeof (ip));
17671
17672   /* Parse args required to build the message */
17673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17674     {
17675       if (unformat (input, "disable"))
17676         is_add = 0;
17677       else
17678         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17679         {
17680           is_add = 1;
17681           ip_addr_version (&ip) = IP4;
17682         }
17683       else
17684         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17685         {
17686           is_add = 1;
17687           ip_addr_version (&ip) = IP6;
17688         }
17689       else
17690         {
17691           errmsg ("parse error '%U'", format_unformat_error, input);
17692           return -99;
17693         }
17694     }
17695
17696   M (ONE_USE_PETR, mp);
17697
17698   mp->is_add = is_add;
17699   if (is_add)
17700     {
17701       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17702       if (mp->is_ip4)
17703         clib_memcpy (mp->address, &ip, 4);
17704       else
17705         clib_memcpy (mp->address, &ip, 16);
17706     }
17707
17708   /* send */
17709   S (mp);
17710
17711   /* wait for reply */
17712   W (ret);
17713   return ret;
17714 }
17715
17716 #define api_lisp_use_petr api_one_use_petr
17717
17718 static int
17719 api_show_one_nsh_mapping (vat_main_t * vam)
17720 {
17721   vl_api_show_one_use_petr_t *mp;
17722   int ret;
17723
17724   if (!vam->json_output)
17725     {
17726       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17727     }
17728
17729   M (SHOW_ONE_NSH_MAPPING, mp);
17730   /* send it... */
17731   S (mp);
17732
17733   /* Wait for a reply... */
17734   W (ret);
17735   return ret;
17736 }
17737
17738 static int
17739 api_show_one_use_petr (vat_main_t * vam)
17740 {
17741   vl_api_show_one_use_petr_t *mp;
17742   int ret;
17743
17744   if (!vam->json_output)
17745     {
17746       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17747     }
17748
17749   M (SHOW_ONE_USE_PETR, mp);
17750   /* send it... */
17751   S (mp);
17752
17753   /* Wait for a reply... */
17754   W (ret);
17755   return ret;
17756 }
17757
17758 #define api_show_lisp_use_petr api_show_one_use_petr
17759
17760 /**
17761  * Add/delete mapping between vni and vrf
17762  */
17763 static int
17764 api_one_eid_table_add_del_map (vat_main_t * vam)
17765 {
17766   unformat_input_t *input = vam->input;
17767   vl_api_one_eid_table_add_del_map_t *mp;
17768   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17769   u32 vni, vrf, bd_index;
17770   int ret;
17771
17772   /* Parse args required to build the message */
17773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17774     {
17775       if (unformat (input, "del"))
17776         is_add = 0;
17777       else if (unformat (input, "vrf %d", &vrf))
17778         vrf_set = 1;
17779       else if (unformat (input, "bd_index %d", &bd_index))
17780         bd_index_set = 1;
17781       else if (unformat (input, "vni %d", &vni))
17782         vni_set = 1;
17783       else
17784         break;
17785     }
17786
17787   if (!vni_set || (!vrf_set && !bd_index_set))
17788     {
17789       errmsg ("missing arguments!");
17790       return -99;
17791     }
17792
17793   if (vrf_set && bd_index_set)
17794     {
17795       errmsg ("error: both vrf and bd entered!");
17796       return -99;
17797     }
17798
17799   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17800
17801   mp->is_add = is_add;
17802   mp->vni = htonl (vni);
17803   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17804   mp->is_l2 = bd_index_set;
17805
17806   /* send */
17807   S (mp);
17808
17809   /* wait for reply */
17810   W (ret);
17811   return ret;
17812 }
17813
17814 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17815
17816 uword
17817 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17818 {
17819   u32 *action = va_arg (*args, u32 *);
17820   u8 *s = 0;
17821
17822   if (unformat (input, "%s", &s))
17823     {
17824       if (!strcmp ((char *) s, "no-action"))
17825         action[0] = 0;
17826       else if (!strcmp ((char *) s, "natively-forward"))
17827         action[0] = 1;
17828       else if (!strcmp ((char *) s, "send-map-request"))
17829         action[0] = 2;
17830       else if (!strcmp ((char *) s, "drop"))
17831         action[0] = 3;
17832       else
17833         {
17834           clib_warning ("invalid action: '%s'", s);
17835           action[0] = 3;
17836         }
17837     }
17838   else
17839     return 0;
17840
17841   vec_free (s);
17842   return 1;
17843 }
17844
17845 /**
17846  * Add/del remote mapping to/from ONE control plane
17847  *
17848  * @param vam vpp API test context
17849  * @return return code
17850  */
17851 static int
17852 api_one_add_del_remote_mapping (vat_main_t * vam)
17853 {
17854   unformat_input_t *input = vam->input;
17855   vl_api_one_add_del_remote_mapping_t *mp;
17856   u32 vni = 0;
17857   lisp_eid_vat_t _eid, *eid = &_eid;
17858   lisp_eid_vat_t _seid, *seid = &_seid;
17859   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17860   u32 action = ~0, p, w, data_len;
17861   ip4_address_t rloc4;
17862   ip6_address_t rloc6;
17863   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17864   int ret;
17865
17866   memset (&rloc, 0, sizeof (rloc));
17867
17868   /* Parse args required to build the message */
17869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17870     {
17871       if (unformat (input, "del-all"))
17872         {
17873           del_all = 1;
17874         }
17875       else if (unformat (input, "del"))
17876         {
17877           is_add = 0;
17878         }
17879       else if (unformat (input, "add"))
17880         {
17881           is_add = 1;
17882         }
17883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17884         {
17885           eid_set = 1;
17886         }
17887       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17888         {
17889           seid_set = 1;
17890         }
17891       else if (unformat (input, "vni %d", &vni))
17892         {
17893           ;
17894         }
17895       else if (unformat (input, "p %d w %d", &p, &w))
17896         {
17897           if (!curr_rloc)
17898             {
17899               errmsg ("No RLOC configured for setting priority/weight!");
17900               return -99;
17901             }
17902           curr_rloc->priority = p;
17903           curr_rloc->weight = w;
17904         }
17905       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17906         {
17907           rloc.is_ip4 = 1;
17908           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17909           vec_add1 (rlocs, rloc);
17910           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17911         }
17912       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17913         {
17914           rloc.is_ip4 = 0;
17915           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17916           vec_add1 (rlocs, rloc);
17917           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17918         }
17919       else if (unformat (input, "action %U",
17920                          unformat_negative_mapping_action, &action))
17921         {
17922           ;
17923         }
17924       else
17925         {
17926           clib_warning ("parse error '%U'", format_unformat_error, input);
17927           return -99;
17928         }
17929     }
17930
17931   if (0 == eid_set)
17932     {
17933       errmsg ("missing params!");
17934       return -99;
17935     }
17936
17937   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17938     {
17939       errmsg ("no action set for negative map-reply!");
17940       return -99;
17941     }
17942
17943   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17944
17945   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17946   mp->is_add = is_add;
17947   mp->vni = htonl (vni);
17948   mp->action = (u8) action;
17949   mp->is_src_dst = seid_set;
17950   mp->eid_len = eid->len;
17951   mp->seid_len = seid->len;
17952   mp->del_all = del_all;
17953   mp->eid_type = eid->type;
17954   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17955   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17956
17957   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17958   clib_memcpy (mp->rlocs, rlocs, data_len);
17959   vec_free (rlocs);
17960
17961   /* send it... */
17962   S (mp);
17963
17964   /* Wait for a reply... */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17970
17971 /**
17972  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17973  * forwarding entries in data-plane accordingly.
17974  *
17975  * @param vam vpp API test context
17976  * @return return code
17977  */
17978 static int
17979 api_one_add_del_adjacency (vat_main_t * vam)
17980 {
17981   unformat_input_t *input = vam->input;
17982   vl_api_one_add_del_adjacency_t *mp;
17983   u32 vni = 0;
17984   ip4_address_t leid4, reid4;
17985   ip6_address_t leid6, reid6;
17986   u8 reid_mac[6] = { 0 };
17987   u8 leid_mac[6] = { 0 };
17988   u8 reid_type, leid_type;
17989   u32 leid_len = 0, reid_len = 0, len;
17990   u8 is_add = 1;
17991   int ret;
17992
17993   leid_type = reid_type = (u8) ~ 0;
17994
17995   /* Parse args required to build the message */
17996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17997     {
17998       if (unformat (input, "del"))
17999         {
18000           is_add = 0;
18001         }
18002       else if (unformat (input, "add"))
18003         {
18004           is_add = 1;
18005         }
18006       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18007                          &reid4, &len))
18008         {
18009           reid_type = 0;        /* ipv4 */
18010           reid_len = len;
18011         }
18012       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18013                          &reid6, &len))
18014         {
18015           reid_type = 1;        /* ipv6 */
18016           reid_len = len;
18017         }
18018       else if (unformat (input, "reid %U", unformat_ethernet_address,
18019                          reid_mac))
18020         {
18021           reid_type = 2;        /* mac */
18022         }
18023       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18024                          &leid4, &len))
18025         {
18026           leid_type = 0;        /* ipv4 */
18027           leid_len = len;
18028         }
18029       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18030                          &leid6, &len))
18031         {
18032           leid_type = 1;        /* ipv6 */
18033           leid_len = len;
18034         }
18035       else if (unformat (input, "leid %U", unformat_ethernet_address,
18036                          leid_mac))
18037         {
18038           leid_type = 2;        /* mac */
18039         }
18040       else if (unformat (input, "vni %d", &vni))
18041         {
18042           ;
18043         }
18044       else
18045         {
18046           errmsg ("parse error '%U'", format_unformat_error, input);
18047           return -99;
18048         }
18049     }
18050
18051   if ((u8) ~ 0 == reid_type)
18052     {
18053       errmsg ("missing params!");
18054       return -99;
18055     }
18056
18057   if (leid_type != reid_type)
18058     {
18059       errmsg ("remote and local EIDs are of different types!");
18060       return -99;
18061     }
18062
18063   M (ONE_ADD_DEL_ADJACENCY, mp);
18064   mp->is_add = is_add;
18065   mp->vni = htonl (vni);
18066   mp->leid_len = leid_len;
18067   mp->reid_len = reid_len;
18068   mp->eid_type = reid_type;
18069
18070   switch (mp->eid_type)
18071     {
18072     case 0:
18073       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18074       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18075       break;
18076     case 1:
18077       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18078       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18079       break;
18080     case 2:
18081       clib_memcpy (mp->leid, leid_mac, 6);
18082       clib_memcpy (mp->reid, reid_mac, 6);
18083       break;
18084     default:
18085       errmsg ("unknown EID type %d!", mp->eid_type);
18086       return 0;
18087     }
18088
18089   /* send it... */
18090   S (mp);
18091
18092   /* Wait for a reply... */
18093   W (ret);
18094   return ret;
18095 }
18096
18097 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18098
18099 uword
18100 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18101 {
18102   u32 *mode = va_arg (*args, u32 *);
18103
18104   if (unformat (input, "lisp"))
18105     *mode = 0;
18106   else if (unformat (input, "vxlan"))
18107     *mode = 1;
18108   else
18109     return 0;
18110
18111   return 1;
18112 }
18113
18114 static int
18115 api_gpe_get_encap_mode (vat_main_t * vam)
18116 {
18117   vl_api_gpe_get_encap_mode_t *mp;
18118   int ret;
18119
18120   /* Construct the API message */
18121   M (GPE_GET_ENCAP_MODE, mp);
18122
18123   /* send it... */
18124   S (mp);
18125
18126   /* Wait for a reply... */
18127   W (ret);
18128   return ret;
18129 }
18130
18131 static int
18132 api_gpe_set_encap_mode (vat_main_t * vam)
18133 {
18134   unformat_input_t *input = vam->input;
18135   vl_api_gpe_set_encap_mode_t *mp;
18136   int ret;
18137   u32 mode = 0;
18138
18139   /* Parse args required to build the message */
18140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18141     {
18142       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18143         ;
18144       else
18145         break;
18146     }
18147
18148   /* Construct the API message */
18149   M (GPE_SET_ENCAP_MODE, mp);
18150
18151   mp->mode = mode;
18152
18153   /* send it... */
18154   S (mp);
18155
18156   /* Wait for a reply... */
18157   W (ret);
18158   return ret;
18159 }
18160
18161 static int
18162 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18163 {
18164   unformat_input_t *input = vam->input;
18165   vl_api_gpe_add_del_iface_t *mp;
18166   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18167   u32 dp_table = 0, vni = 0;
18168   int ret;
18169
18170   /* Parse args required to build the message */
18171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18172     {
18173       if (unformat (input, "up"))
18174         {
18175           action_set = 1;
18176           is_add = 1;
18177         }
18178       else if (unformat (input, "down"))
18179         {
18180           action_set = 1;
18181           is_add = 0;
18182         }
18183       else if (unformat (input, "table_id %d", &dp_table))
18184         {
18185           dp_table_set = 1;
18186         }
18187       else if (unformat (input, "bd_id %d", &dp_table))
18188         {
18189           dp_table_set = 1;
18190           is_l2 = 1;
18191         }
18192       else if (unformat (input, "vni %d", &vni))
18193         {
18194           vni_set = 1;
18195         }
18196       else
18197         break;
18198     }
18199
18200   if (action_set == 0)
18201     {
18202       errmsg ("Action not set");
18203       return -99;
18204     }
18205   if (dp_table_set == 0 || vni_set == 0)
18206     {
18207       errmsg ("vni and dp_table must be set");
18208       return -99;
18209     }
18210
18211   /* Construct the API message */
18212   M (GPE_ADD_DEL_IFACE, mp);
18213
18214   mp->is_add = is_add;
18215   mp->dp_table = clib_host_to_net_u32 (dp_table);
18216   mp->is_l2 = is_l2;
18217   mp->vni = clib_host_to_net_u32 (vni);
18218
18219   /* send it... */
18220   S (mp);
18221
18222   /* Wait for a reply... */
18223   W (ret);
18224   return ret;
18225 }
18226
18227 static int
18228 api_one_map_register_fallback_threshold (vat_main_t * vam)
18229 {
18230   unformat_input_t *input = vam->input;
18231   vl_api_one_map_register_fallback_threshold_t *mp;
18232   u32 value = 0;
18233   u8 is_set = 0;
18234   int ret;
18235
18236   /* Parse args required to build the message */
18237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18238     {
18239       if (unformat (input, "%u", &value))
18240         is_set = 1;
18241       else
18242         {
18243           clib_warning ("parse error '%U'", format_unformat_error, input);
18244           return -99;
18245         }
18246     }
18247
18248   if (!is_set)
18249     {
18250       errmsg ("fallback threshold value is missing!");
18251       return -99;
18252     }
18253
18254   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18255   mp->value = clib_host_to_net_u32 (value);
18256
18257   /* send it... */
18258   S (mp);
18259
18260   /* Wait for a reply... */
18261   W (ret);
18262   return ret;
18263 }
18264
18265 static int
18266 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18267 {
18268   vl_api_show_one_map_register_fallback_threshold_t *mp;
18269   int ret;
18270
18271   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18272
18273   /* send it... */
18274   S (mp);
18275
18276   /* Wait for a reply... */
18277   W (ret);
18278   return ret;
18279 }
18280
18281 uword
18282 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18283 {
18284   u32 *proto = va_arg (*args, u32 *);
18285
18286   if (unformat (input, "udp"))
18287     *proto = 1;
18288   else if (unformat (input, "api"))
18289     *proto = 2;
18290   else
18291     return 0;
18292
18293   return 1;
18294 }
18295
18296 static int
18297 api_one_set_transport_protocol (vat_main_t * vam)
18298 {
18299   unformat_input_t *input = vam->input;
18300   vl_api_one_set_transport_protocol_t *mp;
18301   u8 is_set = 0;
18302   u32 protocol = 0;
18303   int ret;
18304
18305   /* Parse args required to build the message */
18306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18307     {
18308       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18309         is_set = 1;
18310       else
18311         {
18312           clib_warning ("parse error '%U'", format_unformat_error, input);
18313           return -99;
18314         }
18315     }
18316
18317   if (!is_set)
18318     {
18319       errmsg ("Transport protocol missing!");
18320       return -99;
18321     }
18322
18323   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18324   mp->protocol = (u8) protocol;
18325
18326   /* send it... */
18327   S (mp);
18328
18329   /* Wait for a reply... */
18330   W (ret);
18331   return ret;
18332 }
18333
18334 static int
18335 api_one_get_transport_protocol (vat_main_t * vam)
18336 {
18337   vl_api_one_get_transport_protocol_t *mp;
18338   int ret;
18339
18340   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18341
18342   /* send it... */
18343   S (mp);
18344
18345   /* Wait for a reply... */
18346   W (ret);
18347   return ret;
18348 }
18349
18350 static int
18351 api_one_map_register_set_ttl (vat_main_t * vam)
18352 {
18353   unformat_input_t *input = vam->input;
18354   vl_api_one_map_register_set_ttl_t *mp;
18355   u32 ttl = 0;
18356   u8 is_set = 0;
18357   int ret;
18358
18359   /* Parse args required to build the message */
18360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18361     {
18362       if (unformat (input, "%u", &ttl))
18363         is_set = 1;
18364       else
18365         {
18366           clib_warning ("parse error '%U'", format_unformat_error, input);
18367           return -99;
18368         }
18369     }
18370
18371   if (!is_set)
18372     {
18373       errmsg ("TTL value missing!");
18374       return -99;
18375     }
18376
18377   M (ONE_MAP_REGISTER_SET_TTL, mp);
18378   mp->ttl = clib_host_to_net_u32 (ttl);
18379
18380   /* send it... */
18381   S (mp);
18382
18383   /* Wait for a reply... */
18384   W (ret);
18385   return ret;
18386 }
18387
18388 static int
18389 api_show_one_map_register_ttl (vat_main_t * vam)
18390 {
18391   vl_api_show_one_map_register_ttl_t *mp;
18392   int ret;
18393
18394   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18395
18396   /* send it... */
18397   S (mp);
18398
18399   /* Wait for a reply... */
18400   W (ret);
18401   return ret;
18402 }
18403
18404 /**
18405  * Add/del map request itr rlocs from ONE control plane and updates
18406  *
18407  * @param vam vpp API test context
18408  * @return return code
18409  */
18410 static int
18411 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18412 {
18413   unformat_input_t *input = vam->input;
18414   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18415   u8 *locator_set_name = 0;
18416   u8 locator_set_name_set = 0;
18417   u8 is_add = 1;
18418   int ret;
18419
18420   /* Parse args required to build the message */
18421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18422     {
18423       if (unformat (input, "del"))
18424         {
18425           is_add = 0;
18426         }
18427       else if (unformat (input, "%_%v%_", &locator_set_name))
18428         {
18429           locator_set_name_set = 1;
18430         }
18431       else
18432         {
18433           clib_warning ("parse error '%U'", format_unformat_error, input);
18434           return -99;
18435         }
18436     }
18437
18438   if (is_add && !locator_set_name_set)
18439     {
18440       errmsg ("itr-rloc is not set!");
18441       return -99;
18442     }
18443
18444   if (is_add && vec_len (locator_set_name) > 64)
18445     {
18446       errmsg ("itr-rloc locator-set name too long");
18447       vec_free (locator_set_name);
18448       return -99;
18449     }
18450
18451   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18452   mp->is_add = is_add;
18453   if (is_add)
18454     {
18455       clib_memcpy (mp->locator_set_name, locator_set_name,
18456                    vec_len (locator_set_name));
18457     }
18458   else
18459     {
18460       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18461     }
18462   vec_free (locator_set_name);
18463
18464   /* send it... */
18465   S (mp);
18466
18467   /* Wait for a reply... */
18468   W (ret);
18469   return ret;
18470 }
18471
18472 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18473
18474 static int
18475 api_one_locator_dump (vat_main_t * vam)
18476 {
18477   unformat_input_t *input = vam->input;
18478   vl_api_one_locator_dump_t *mp;
18479   vl_api_control_ping_t *mp_ping;
18480   u8 is_index_set = 0, is_name_set = 0;
18481   u8 *ls_name = 0;
18482   u32 ls_index = ~0;
18483   int ret;
18484
18485   /* Parse args required to build the message */
18486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18487     {
18488       if (unformat (input, "ls_name %_%v%_", &ls_name))
18489         {
18490           is_name_set = 1;
18491         }
18492       else if (unformat (input, "ls_index %d", &ls_index))
18493         {
18494           is_index_set = 1;
18495         }
18496       else
18497         {
18498           errmsg ("parse error '%U'", format_unformat_error, input);
18499           return -99;
18500         }
18501     }
18502
18503   if (!is_index_set && !is_name_set)
18504     {
18505       errmsg ("error: expected one of index or name!");
18506       return -99;
18507     }
18508
18509   if (is_index_set && is_name_set)
18510     {
18511       errmsg ("error: only one param expected!");
18512       return -99;
18513     }
18514
18515   if (vec_len (ls_name) > 62)
18516     {
18517       errmsg ("error: locator set name too long!");
18518       return -99;
18519     }
18520
18521   if (!vam->json_output)
18522     {
18523       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18524     }
18525
18526   M (ONE_LOCATOR_DUMP, mp);
18527   mp->is_index_set = is_index_set;
18528
18529   if (is_index_set)
18530     mp->ls_index = clib_host_to_net_u32 (ls_index);
18531   else
18532     {
18533       vec_add1 (ls_name, 0);
18534       strncpy ((char *) mp->ls_name, (char *) ls_name,
18535                sizeof (mp->ls_name) - 1);
18536     }
18537
18538   /* send it... */
18539   S (mp);
18540
18541   /* Use a control ping for synchronization */
18542   MPING (CONTROL_PING, mp_ping);
18543   S (mp_ping);
18544
18545   /* Wait for a reply... */
18546   W (ret);
18547   return ret;
18548 }
18549
18550 #define api_lisp_locator_dump api_one_locator_dump
18551
18552 static int
18553 api_one_locator_set_dump (vat_main_t * vam)
18554 {
18555   vl_api_one_locator_set_dump_t *mp;
18556   vl_api_control_ping_t *mp_ping;
18557   unformat_input_t *input = vam->input;
18558   u8 filter = 0;
18559   int ret;
18560
18561   /* Parse args required to build the message */
18562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18563     {
18564       if (unformat (input, "local"))
18565         {
18566           filter = 1;
18567         }
18568       else if (unformat (input, "remote"))
18569         {
18570           filter = 2;
18571         }
18572       else
18573         {
18574           errmsg ("parse error '%U'", format_unformat_error, input);
18575           return -99;
18576         }
18577     }
18578
18579   if (!vam->json_output)
18580     {
18581       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18582     }
18583
18584   M (ONE_LOCATOR_SET_DUMP, mp);
18585
18586   mp->filter = filter;
18587
18588   /* send it... */
18589   S (mp);
18590
18591   /* Use a control ping for synchronization */
18592   MPING (CONTROL_PING, mp_ping);
18593   S (mp_ping);
18594
18595   /* Wait for a reply... */
18596   W (ret);
18597   return ret;
18598 }
18599
18600 #define api_lisp_locator_set_dump api_one_locator_set_dump
18601
18602 static int
18603 api_one_eid_table_map_dump (vat_main_t * vam)
18604 {
18605   u8 is_l2 = 0;
18606   u8 mode_set = 0;
18607   unformat_input_t *input = vam->input;
18608   vl_api_one_eid_table_map_dump_t *mp;
18609   vl_api_control_ping_t *mp_ping;
18610   int ret;
18611
18612   /* Parse args required to build the message */
18613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18614     {
18615       if (unformat (input, "l2"))
18616         {
18617           is_l2 = 1;
18618           mode_set = 1;
18619         }
18620       else if (unformat (input, "l3"))
18621         {
18622           is_l2 = 0;
18623           mode_set = 1;
18624         }
18625       else
18626         {
18627           errmsg ("parse error '%U'", format_unformat_error, input);
18628           return -99;
18629         }
18630     }
18631
18632   if (!mode_set)
18633     {
18634       errmsg ("expected one of 'l2' or 'l3' parameter!");
18635       return -99;
18636     }
18637
18638   if (!vam->json_output)
18639     {
18640       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18641     }
18642
18643   M (ONE_EID_TABLE_MAP_DUMP, mp);
18644   mp->is_l2 = is_l2;
18645
18646   /* send it... */
18647   S (mp);
18648
18649   /* Use a control ping for synchronization */
18650   MPING (CONTROL_PING, mp_ping);
18651   S (mp_ping);
18652
18653   /* Wait for a reply... */
18654   W (ret);
18655   return ret;
18656 }
18657
18658 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18659
18660 static int
18661 api_one_eid_table_vni_dump (vat_main_t * vam)
18662 {
18663   vl_api_one_eid_table_vni_dump_t *mp;
18664   vl_api_control_ping_t *mp_ping;
18665   int ret;
18666
18667   if (!vam->json_output)
18668     {
18669       print (vam->ofp, "VNI");
18670     }
18671
18672   M (ONE_EID_TABLE_VNI_DUMP, mp);
18673
18674   /* send it... */
18675   S (mp);
18676
18677   /* Use a control ping for synchronization */
18678   MPING (CONTROL_PING, mp_ping);
18679   S (mp_ping);
18680
18681   /* Wait for a reply... */
18682   W (ret);
18683   return ret;
18684 }
18685
18686 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18687
18688 static int
18689 api_one_eid_table_dump (vat_main_t * vam)
18690 {
18691   unformat_input_t *i = vam->input;
18692   vl_api_one_eid_table_dump_t *mp;
18693   vl_api_control_ping_t *mp_ping;
18694   struct in_addr ip4;
18695   struct in6_addr ip6;
18696   u8 mac[6];
18697   u8 eid_type = ~0, eid_set = 0;
18698   u32 prefix_length = ~0, t, vni = 0;
18699   u8 filter = 0;
18700   int ret;
18701   lisp_nsh_api_t nsh;
18702
18703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18704     {
18705       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18706         {
18707           eid_set = 1;
18708           eid_type = 0;
18709           prefix_length = t;
18710         }
18711       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18712         {
18713           eid_set = 1;
18714           eid_type = 1;
18715           prefix_length = t;
18716         }
18717       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18718         {
18719           eid_set = 1;
18720           eid_type = 2;
18721         }
18722       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18723         {
18724           eid_set = 1;
18725           eid_type = 3;
18726         }
18727       else if (unformat (i, "vni %d", &t))
18728         {
18729           vni = t;
18730         }
18731       else if (unformat (i, "local"))
18732         {
18733           filter = 1;
18734         }
18735       else if (unformat (i, "remote"))
18736         {
18737           filter = 2;
18738         }
18739       else
18740         {
18741           errmsg ("parse error '%U'", format_unformat_error, i);
18742           return -99;
18743         }
18744     }
18745
18746   if (!vam->json_output)
18747     {
18748       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18749              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18750     }
18751
18752   M (ONE_EID_TABLE_DUMP, mp);
18753
18754   mp->filter = filter;
18755   if (eid_set)
18756     {
18757       mp->eid_set = 1;
18758       mp->vni = htonl (vni);
18759       mp->eid_type = eid_type;
18760       switch (eid_type)
18761         {
18762         case 0:
18763           mp->prefix_length = prefix_length;
18764           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18765           break;
18766         case 1:
18767           mp->prefix_length = prefix_length;
18768           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18769           break;
18770         case 2:
18771           clib_memcpy (mp->eid, mac, sizeof (mac));
18772           break;
18773         case 3:
18774           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18775           break;
18776         default:
18777           errmsg ("unknown EID type %d!", eid_type);
18778           return -99;
18779         }
18780     }
18781
18782   /* send it... */
18783   S (mp);
18784
18785   /* Use a control ping for synchronization */
18786   MPING (CONTROL_PING, mp_ping);
18787   S (mp_ping);
18788
18789   /* Wait for a reply... */
18790   W (ret);
18791   return ret;
18792 }
18793
18794 #define api_lisp_eid_table_dump api_one_eid_table_dump
18795
18796 static int
18797 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18798 {
18799   unformat_input_t *i = vam->input;
18800   vl_api_gpe_fwd_entries_get_t *mp;
18801   u8 vni_set = 0;
18802   u32 vni = ~0;
18803   int ret;
18804
18805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18806     {
18807       if (unformat (i, "vni %d", &vni))
18808         {
18809           vni_set = 1;
18810         }
18811       else
18812         {
18813           errmsg ("parse error '%U'", format_unformat_error, i);
18814           return -99;
18815         }
18816     }
18817
18818   if (!vni_set)
18819     {
18820       errmsg ("vni not set!");
18821       return -99;
18822     }
18823
18824   if (!vam->json_output)
18825     {
18826       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18827              "leid", "reid");
18828     }
18829
18830   M (GPE_FWD_ENTRIES_GET, mp);
18831   mp->vni = clib_host_to_net_u32 (vni);
18832
18833   /* send it... */
18834   S (mp);
18835
18836   /* Wait for a reply... */
18837   W (ret);
18838   return ret;
18839 }
18840
18841 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18842 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18843 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18844 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18845 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18846 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18847 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18848 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18849
18850 static int
18851 api_one_adjacencies_get (vat_main_t * vam)
18852 {
18853   unformat_input_t *i = vam->input;
18854   vl_api_one_adjacencies_get_t *mp;
18855   u8 vni_set = 0;
18856   u32 vni = ~0;
18857   int ret;
18858
18859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18860     {
18861       if (unformat (i, "vni %d", &vni))
18862         {
18863           vni_set = 1;
18864         }
18865       else
18866         {
18867           errmsg ("parse error '%U'", format_unformat_error, i);
18868           return -99;
18869         }
18870     }
18871
18872   if (!vni_set)
18873     {
18874       errmsg ("vni not set!");
18875       return -99;
18876     }
18877
18878   if (!vam->json_output)
18879     {
18880       print (vam->ofp, "%s %40s", "leid", "reid");
18881     }
18882
18883   M (ONE_ADJACENCIES_GET, mp);
18884   mp->vni = clib_host_to_net_u32 (vni);
18885
18886   /* send it... */
18887   S (mp);
18888
18889   /* Wait for a reply... */
18890   W (ret);
18891   return ret;
18892 }
18893
18894 #define api_lisp_adjacencies_get api_one_adjacencies_get
18895
18896 static int
18897 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18898 {
18899   unformat_input_t *i = vam->input;
18900   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18901   int ret;
18902   u8 ip_family_set = 0, is_ip4 = 1;
18903
18904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18905     {
18906       if (unformat (i, "ip4"))
18907         {
18908           ip_family_set = 1;
18909           is_ip4 = 1;
18910         }
18911       else if (unformat (i, "ip6"))
18912         {
18913           ip_family_set = 1;
18914           is_ip4 = 0;
18915         }
18916       else
18917         {
18918           errmsg ("parse error '%U'", format_unformat_error, i);
18919           return -99;
18920         }
18921     }
18922
18923   if (!ip_family_set)
18924     {
18925       errmsg ("ip family not set!");
18926       return -99;
18927     }
18928
18929   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18930   mp->is_ip4 = is_ip4;
18931
18932   /* send it... */
18933   S (mp);
18934
18935   /* Wait for a reply... */
18936   W (ret);
18937   return ret;
18938 }
18939
18940 static int
18941 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18942 {
18943   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18944   int ret;
18945
18946   if (!vam->json_output)
18947     {
18948       print (vam->ofp, "VNIs");
18949     }
18950
18951   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18952
18953   /* send it... */
18954   S (mp);
18955
18956   /* Wait for a reply... */
18957   W (ret);
18958   return ret;
18959 }
18960
18961 static int
18962 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18963 {
18964   unformat_input_t *i = vam->input;
18965   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18966   int ret = 0;
18967   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18968   struct in_addr ip4;
18969   struct in6_addr ip6;
18970   u32 table_id = 0, nh_sw_if_index = ~0;
18971
18972   memset (&ip4, 0, sizeof (ip4));
18973   memset (&ip6, 0, sizeof (ip6));
18974
18975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18976     {
18977       if (unformat (i, "del"))
18978         is_add = 0;
18979       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18980                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18981         {
18982           ip_set = 1;
18983           is_ip4 = 1;
18984         }
18985       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18986                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18987         {
18988           ip_set = 1;
18989           is_ip4 = 0;
18990         }
18991       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18992         {
18993           ip_set = 1;
18994           is_ip4 = 1;
18995           nh_sw_if_index = ~0;
18996         }
18997       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18998         {
18999           ip_set = 1;
19000           is_ip4 = 0;
19001           nh_sw_if_index = ~0;
19002         }
19003       else if (unformat (i, "table %d", &table_id))
19004         ;
19005       else
19006         {
19007           errmsg ("parse error '%U'", format_unformat_error, i);
19008           return -99;
19009         }
19010     }
19011
19012   if (!ip_set)
19013     {
19014       errmsg ("nh addr not set!");
19015       return -99;
19016     }
19017
19018   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19019   mp->is_add = is_add;
19020   mp->table_id = clib_host_to_net_u32 (table_id);
19021   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19022   mp->is_ip4 = is_ip4;
19023   if (is_ip4)
19024     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19025   else
19026     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19027
19028   /* send it... */
19029   S (mp);
19030
19031   /* Wait for a reply... */
19032   W (ret);
19033   return ret;
19034 }
19035
19036 static int
19037 api_one_map_server_dump (vat_main_t * vam)
19038 {
19039   vl_api_one_map_server_dump_t *mp;
19040   vl_api_control_ping_t *mp_ping;
19041   int ret;
19042
19043   if (!vam->json_output)
19044     {
19045       print (vam->ofp, "%=20s", "Map server");
19046     }
19047
19048   M (ONE_MAP_SERVER_DUMP, mp);
19049   /* send it... */
19050   S (mp);
19051
19052   /* Use a control ping for synchronization */
19053   MPING (CONTROL_PING, mp_ping);
19054   S (mp_ping);
19055
19056   /* Wait for a reply... */
19057   W (ret);
19058   return ret;
19059 }
19060
19061 #define api_lisp_map_server_dump api_one_map_server_dump
19062
19063 static int
19064 api_one_map_resolver_dump (vat_main_t * vam)
19065 {
19066   vl_api_one_map_resolver_dump_t *mp;
19067   vl_api_control_ping_t *mp_ping;
19068   int ret;
19069
19070   if (!vam->json_output)
19071     {
19072       print (vam->ofp, "%=20s", "Map resolver");
19073     }
19074
19075   M (ONE_MAP_RESOLVER_DUMP, mp);
19076   /* send it... */
19077   S (mp);
19078
19079   /* Use a control ping for synchronization */
19080   MPING (CONTROL_PING, mp_ping);
19081   S (mp_ping);
19082
19083   /* Wait for a reply... */
19084   W (ret);
19085   return ret;
19086 }
19087
19088 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19089
19090 static int
19091 api_one_stats_flush (vat_main_t * vam)
19092 {
19093   vl_api_one_stats_flush_t *mp;
19094   int ret = 0;
19095
19096   M (ONE_STATS_FLUSH, mp);
19097   S (mp);
19098   W (ret);
19099   return ret;
19100 }
19101
19102 static int
19103 api_one_stats_dump (vat_main_t * vam)
19104 {
19105   vl_api_one_stats_dump_t *mp;
19106   vl_api_control_ping_t *mp_ping;
19107   int ret;
19108
19109   M (ONE_STATS_DUMP, mp);
19110   /* send it... */
19111   S (mp);
19112
19113   /* Use a control ping for synchronization */
19114   MPING (CONTROL_PING, mp_ping);
19115   S (mp_ping);
19116
19117   /* Wait for a reply... */
19118   W (ret);
19119   return ret;
19120 }
19121
19122 static int
19123 api_show_one_status (vat_main_t * vam)
19124 {
19125   vl_api_show_one_status_t *mp;
19126   int ret;
19127
19128   if (!vam->json_output)
19129     {
19130       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19131     }
19132
19133   M (SHOW_ONE_STATUS, mp);
19134   /* send it... */
19135   S (mp);
19136   /* Wait for a reply... */
19137   W (ret);
19138   return ret;
19139 }
19140
19141 #define api_show_lisp_status api_show_one_status
19142
19143 static int
19144 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19145 {
19146   vl_api_gpe_fwd_entry_path_dump_t *mp;
19147   vl_api_control_ping_t *mp_ping;
19148   unformat_input_t *i = vam->input;
19149   u32 fwd_entry_index = ~0;
19150   int ret;
19151
19152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19153     {
19154       if (unformat (i, "index %d", &fwd_entry_index))
19155         ;
19156       else
19157         break;
19158     }
19159
19160   if (~0 == fwd_entry_index)
19161     {
19162       errmsg ("no index specified!");
19163       return -99;
19164     }
19165
19166   if (!vam->json_output)
19167     {
19168       print (vam->ofp, "first line");
19169     }
19170
19171   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19172
19173   /* send it... */
19174   S (mp);
19175   /* Use a control ping for synchronization */
19176   MPING (CONTROL_PING, mp_ping);
19177   S (mp_ping);
19178
19179   /* Wait for a reply... */
19180   W (ret);
19181   return ret;
19182 }
19183
19184 static int
19185 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19186 {
19187   vl_api_one_get_map_request_itr_rlocs_t *mp;
19188   int ret;
19189
19190   if (!vam->json_output)
19191     {
19192       print (vam->ofp, "%=20s", "itr-rlocs:");
19193     }
19194
19195   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19196   /* send it... */
19197   S (mp);
19198   /* Wait for a reply... */
19199   W (ret);
19200   return ret;
19201 }
19202
19203 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19204
19205 static int
19206 api_af_packet_create (vat_main_t * vam)
19207 {
19208   unformat_input_t *i = vam->input;
19209   vl_api_af_packet_create_t *mp;
19210   u8 *host_if_name = 0;
19211   u8 hw_addr[6];
19212   u8 random_hw_addr = 1;
19213   int ret;
19214
19215   memset (hw_addr, 0, sizeof (hw_addr));
19216
19217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19218     {
19219       if (unformat (i, "name %s", &host_if_name))
19220         vec_add1 (host_if_name, 0);
19221       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19222         random_hw_addr = 0;
19223       else
19224         break;
19225     }
19226
19227   if (!vec_len (host_if_name))
19228     {
19229       errmsg ("host-interface name must be specified");
19230       return -99;
19231     }
19232
19233   if (vec_len (host_if_name) > 64)
19234     {
19235       errmsg ("host-interface name too long");
19236       return -99;
19237     }
19238
19239   M (AF_PACKET_CREATE, mp);
19240
19241   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19242   clib_memcpy (mp->hw_addr, hw_addr, 6);
19243   mp->use_random_hw_addr = random_hw_addr;
19244   vec_free (host_if_name);
19245
19246   S (mp);
19247
19248   /* *INDENT-OFF* */
19249   W2 (ret,
19250       ({
19251         if (ret == 0)
19252           fprintf (vam->ofp ? vam->ofp : stderr,
19253                    " new sw_if_index = %d\n", vam->sw_if_index);
19254       }));
19255   /* *INDENT-ON* */
19256   return ret;
19257 }
19258
19259 static int
19260 api_af_packet_delete (vat_main_t * vam)
19261 {
19262   unformat_input_t *i = vam->input;
19263   vl_api_af_packet_delete_t *mp;
19264   u8 *host_if_name = 0;
19265   int ret;
19266
19267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19268     {
19269       if (unformat (i, "name %s", &host_if_name))
19270         vec_add1 (host_if_name, 0);
19271       else
19272         break;
19273     }
19274
19275   if (!vec_len (host_if_name))
19276     {
19277       errmsg ("host-interface name must be specified");
19278       return -99;
19279     }
19280
19281   if (vec_len (host_if_name) > 64)
19282     {
19283       errmsg ("host-interface name too long");
19284       return -99;
19285     }
19286
19287   M (AF_PACKET_DELETE, mp);
19288
19289   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19290   vec_free (host_if_name);
19291
19292   S (mp);
19293   W (ret);
19294   return ret;
19295 }
19296
19297 static int
19298 api_policer_add_del (vat_main_t * vam)
19299 {
19300   unformat_input_t *i = vam->input;
19301   vl_api_policer_add_del_t *mp;
19302   u8 is_add = 1;
19303   u8 *name = 0;
19304   u32 cir = 0;
19305   u32 eir = 0;
19306   u64 cb = 0;
19307   u64 eb = 0;
19308   u8 rate_type = 0;
19309   u8 round_type = 0;
19310   u8 type = 0;
19311   u8 color_aware = 0;
19312   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19313   int ret;
19314
19315   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19316   conform_action.dscp = 0;
19317   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19318   exceed_action.dscp = 0;
19319   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19320   violate_action.dscp = 0;
19321
19322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19323     {
19324       if (unformat (i, "del"))
19325         is_add = 0;
19326       else if (unformat (i, "name %s", &name))
19327         vec_add1 (name, 0);
19328       else if (unformat (i, "cir %u", &cir))
19329         ;
19330       else if (unformat (i, "eir %u", &eir))
19331         ;
19332       else if (unformat (i, "cb %u", &cb))
19333         ;
19334       else if (unformat (i, "eb %u", &eb))
19335         ;
19336       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19337                          &rate_type))
19338         ;
19339       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19340                          &round_type))
19341         ;
19342       else if (unformat (i, "type %U", unformat_policer_type, &type))
19343         ;
19344       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19345                          &conform_action))
19346         ;
19347       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19348                          &exceed_action))
19349         ;
19350       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19351                          &violate_action))
19352         ;
19353       else if (unformat (i, "color-aware"))
19354         color_aware = 1;
19355       else
19356         break;
19357     }
19358
19359   if (!vec_len (name))
19360     {
19361       errmsg ("policer name must be specified");
19362       return -99;
19363     }
19364
19365   if (vec_len (name) > 64)
19366     {
19367       errmsg ("policer name too long");
19368       return -99;
19369     }
19370
19371   M (POLICER_ADD_DEL, mp);
19372
19373   clib_memcpy (mp->name, name, vec_len (name));
19374   vec_free (name);
19375   mp->is_add = is_add;
19376   mp->cir = ntohl (cir);
19377   mp->eir = ntohl (eir);
19378   mp->cb = clib_net_to_host_u64 (cb);
19379   mp->eb = clib_net_to_host_u64 (eb);
19380   mp->rate_type = rate_type;
19381   mp->round_type = round_type;
19382   mp->type = type;
19383   mp->conform_action_type = conform_action.action_type;
19384   mp->conform_dscp = conform_action.dscp;
19385   mp->exceed_action_type = exceed_action.action_type;
19386   mp->exceed_dscp = exceed_action.dscp;
19387   mp->violate_action_type = violate_action.action_type;
19388   mp->violate_dscp = violate_action.dscp;
19389   mp->color_aware = color_aware;
19390
19391   S (mp);
19392   W (ret);
19393   return ret;
19394 }
19395
19396 static int
19397 api_policer_dump (vat_main_t * vam)
19398 {
19399   unformat_input_t *i = vam->input;
19400   vl_api_policer_dump_t *mp;
19401   vl_api_control_ping_t *mp_ping;
19402   u8 *match_name = 0;
19403   u8 match_name_valid = 0;
19404   int ret;
19405
19406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19407     {
19408       if (unformat (i, "name %s", &match_name))
19409         {
19410           vec_add1 (match_name, 0);
19411           match_name_valid = 1;
19412         }
19413       else
19414         break;
19415     }
19416
19417   M (POLICER_DUMP, mp);
19418   mp->match_name_valid = match_name_valid;
19419   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19420   vec_free (match_name);
19421   /* send it... */
19422   S (mp);
19423
19424   /* Use a control ping for synchronization */
19425   MPING (CONTROL_PING, mp_ping);
19426   S (mp_ping);
19427
19428   /* Wait for a reply... */
19429   W (ret);
19430   return ret;
19431 }
19432
19433 static int
19434 api_policer_classify_set_interface (vat_main_t * vam)
19435 {
19436   unformat_input_t *i = vam->input;
19437   vl_api_policer_classify_set_interface_t *mp;
19438   u32 sw_if_index;
19439   int sw_if_index_set;
19440   u32 ip4_table_index = ~0;
19441   u32 ip6_table_index = ~0;
19442   u32 l2_table_index = ~0;
19443   u8 is_add = 1;
19444   int ret;
19445
19446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19447     {
19448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19449         sw_if_index_set = 1;
19450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19451         sw_if_index_set = 1;
19452       else if (unformat (i, "del"))
19453         is_add = 0;
19454       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19455         ;
19456       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19457         ;
19458       else if (unformat (i, "l2-table %d", &l2_table_index))
19459         ;
19460       else
19461         {
19462           clib_warning ("parse error '%U'", format_unformat_error, i);
19463           return -99;
19464         }
19465     }
19466
19467   if (sw_if_index_set == 0)
19468     {
19469       errmsg ("missing interface name or sw_if_index");
19470       return -99;
19471     }
19472
19473   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19474
19475   mp->sw_if_index = ntohl (sw_if_index);
19476   mp->ip4_table_index = ntohl (ip4_table_index);
19477   mp->ip6_table_index = ntohl (ip6_table_index);
19478   mp->l2_table_index = ntohl (l2_table_index);
19479   mp->is_add = is_add;
19480
19481   S (mp);
19482   W (ret);
19483   return ret;
19484 }
19485
19486 static int
19487 api_policer_classify_dump (vat_main_t * vam)
19488 {
19489   unformat_input_t *i = vam->input;
19490   vl_api_policer_classify_dump_t *mp;
19491   vl_api_control_ping_t *mp_ping;
19492   u8 type = POLICER_CLASSIFY_N_TABLES;
19493   int ret;
19494
19495   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19496     ;
19497   else
19498     {
19499       errmsg ("classify table type must be specified");
19500       return -99;
19501     }
19502
19503   if (!vam->json_output)
19504     {
19505       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19506     }
19507
19508   M (POLICER_CLASSIFY_DUMP, mp);
19509   mp->type = type;
19510   /* send it... */
19511   S (mp);
19512
19513   /* Use a control ping for synchronization */
19514   MPING (CONTROL_PING, mp_ping);
19515   S (mp_ping);
19516
19517   /* Wait for a reply... */
19518   W (ret);
19519   return ret;
19520 }
19521
19522 static int
19523 api_netmap_create (vat_main_t * vam)
19524 {
19525   unformat_input_t *i = vam->input;
19526   vl_api_netmap_create_t *mp;
19527   u8 *if_name = 0;
19528   u8 hw_addr[6];
19529   u8 random_hw_addr = 1;
19530   u8 is_pipe = 0;
19531   u8 is_master = 0;
19532   int ret;
19533
19534   memset (hw_addr, 0, sizeof (hw_addr));
19535
19536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19537     {
19538       if (unformat (i, "name %s", &if_name))
19539         vec_add1 (if_name, 0);
19540       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19541         random_hw_addr = 0;
19542       else if (unformat (i, "pipe"))
19543         is_pipe = 1;
19544       else if (unformat (i, "master"))
19545         is_master = 1;
19546       else if (unformat (i, "slave"))
19547         is_master = 0;
19548       else
19549         break;
19550     }
19551
19552   if (!vec_len (if_name))
19553     {
19554       errmsg ("interface name must be specified");
19555       return -99;
19556     }
19557
19558   if (vec_len (if_name) > 64)
19559     {
19560       errmsg ("interface name too long");
19561       return -99;
19562     }
19563
19564   M (NETMAP_CREATE, mp);
19565
19566   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19567   clib_memcpy (mp->hw_addr, hw_addr, 6);
19568   mp->use_random_hw_addr = random_hw_addr;
19569   mp->is_pipe = is_pipe;
19570   mp->is_master = is_master;
19571   vec_free (if_name);
19572
19573   S (mp);
19574   W (ret);
19575   return ret;
19576 }
19577
19578 static int
19579 api_netmap_delete (vat_main_t * vam)
19580 {
19581   unformat_input_t *i = vam->input;
19582   vl_api_netmap_delete_t *mp;
19583   u8 *if_name = 0;
19584   int ret;
19585
19586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19587     {
19588       if (unformat (i, "name %s", &if_name))
19589         vec_add1 (if_name, 0);
19590       else
19591         break;
19592     }
19593
19594   if (!vec_len (if_name))
19595     {
19596       errmsg ("interface name must be specified");
19597       return -99;
19598     }
19599
19600   if (vec_len (if_name) > 64)
19601     {
19602       errmsg ("interface name too long");
19603       return -99;
19604     }
19605
19606   M (NETMAP_DELETE, mp);
19607
19608   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19609   vec_free (if_name);
19610
19611   S (mp);
19612   W (ret);
19613   return ret;
19614 }
19615
19616 static void
19617 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19618 {
19619   if (fp->afi == IP46_TYPE_IP6)
19620     print (vam->ofp,
19621            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19622            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19623            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19624            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19625            format_ip6_address, fp->next_hop);
19626   else if (fp->afi == IP46_TYPE_IP4)
19627     print (vam->ofp,
19628            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19629            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19630            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19631            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19632            format_ip4_address, fp->next_hop);
19633 }
19634
19635 static void
19636 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19637                                  vl_api_fib_path2_t * fp)
19638 {
19639   struct in_addr ip4;
19640   struct in6_addr ip6;
19641
19642   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19643   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19644   vat_json_object_add_uint (node, "is_local", fp->is_local);
19645   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19646   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19647   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19648   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19649   if (fp->afi == IP46_TYPE_IP4)
19650     {
19651       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19652       vat_json_object_add_ip4 (node, "next_hop", ip4);
19653     }
19654   else if (fp->afi == IP46_TYPE_IP6)
19655     {
19656       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19657       vat_json_object_add_ip6 (node, "next_hop", ip6);
19658     }
19659 }
19660
19661 static void
19662 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19663 {
19664   vat_main_t *vam = &vat_main;
19665   int count = ntohl (mp->mt_count);
19666   vl_api_fib_path2_t *fp;
19667   i32 i;
19668
19669   print (vam->ofp, "[%d]: sw_if_index %d via:",
19670          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19671   fp = mp->mt_paths;
19672   for (i = 0; i < count; i++)
19673     {
19674       vl_api_mpls_fib_path_print (vam, fp);
19675       fp++;
19676     }
19677
19678   print (vam->ofp, "");
19679 }
19680
19681 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19682 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19683
19684 static void
19685 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19686 {
19687   vat_main_t *vam = &vat_main;
19688   vat_json_node_t *node = NULL;
19689   int count = ntohl (mp->mt_count);
19690   vl_api_fib_path2_t *fp;
19691   i32 i;
19692
19693   if (VAT_JSON_ARRAY != vam->json_tree.type)
19694     {
19695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19696       vat_json_init_array (&vam->json_tree);
19697     }
19698   node = vat_json_array_add (&vam->json_tree);
19699
19700   vat_json_init_object (node);
19701   vat_json_object_add_uint (node, "tunnel_index",
19702                             ntohl (mp->mt_tunnel_index));
19703   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19704
19705   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19706
19707   fp = mp->mt_paths;
19708   for (i = 0; i < count; i++)
19709     {
19710       vl_api_mpls_fib_path_json_print (node, fp);
19711       fp++;
19712     }
19713 }
19714
19715 static int
19716 api_mpls_tunnel_dump (vat_main_t * vam)
19717 {
19718   vl_api_mpls_tunnel_dump_t *mp;
19719   vl_api_control_ping_t *mp_ping;
19720   i32 index = -1;
19721   int ret;
19722
19723   /* Parse args required to build the message */
19724   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19725     {
19726       if (!unformat (vam->input, "tunnel_index %d", &index))
19727         {
19728           index = -1;
19729           break;
19730         }
19731     }
19732
19733   print (vam->ofp, "  tunnel_index %d", index);
19734
19735   M (MPLS_TUNNEL_DUMP, mp);
19736   mp->tunnel_index = htonl (index);
19737   S (mp);
19738
19739   /* Use a control ping for synchronization */
19740   MPING (CONTROL_PING, mp_ping);
19741   S (mp_ping);
19742
19743   W (ret);
19744   return ret;
19745 }
19746
19747 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19748 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19749
19750
19751 static void
19752 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19753 {
19754   vat_main_t *vam = &vat_main;
19755   int count = ntohl (mp->count);
19756   vl_api_fib_path2_t *fp;
19757   int i;
19758
19759   print (vam->ofp,
19760          "table-id %d, label %u, ess_bit %u",
19761          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19762   fp = mp->path;
19763   for (i = 0; i < count; i++)
19764     {
19765       vl_api_mpls_fib_path_print (vam, fp);
19766       fp++;
19767     }
19768 }
19769
19770 static void vl_api_mpls_fib_details_t_handler_json
19771   (vl_api_mpls_fib_details_t * mp)
19772 {
19773   vat_main_t *vam = &vat_main;
19774   int count = ntohl (mp->count);
19775   vat_json_node_t *node = NULL;
19776   vl_api_fib_path2_t *fp;
19777   int i;
19778
19779   if (VAT_JSON_ARRAY != vam->json_tree.type)
19780     {
19781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19782       vat_json_init_array (&vam->json_tree);
19783     }
19784   node = vat_json_array_add (&vam->json_tree);
19785
19786   vat_json_init_object (node);
19787   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19788   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19789   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19790   vat_json_object_add_uint (node, "path_count", count);
19791   fp = mp->path;
19792   for (i = 0; i < count; i++)
19793     {
19794       vl_api_mpls_fib_path_json_print (node, fp);
19795       fp++;
19796     }
19797 }
19798
19799 static int
19800 api_mpls_fib_dump (vat_main_t * vam)
19801 {
19802   vl_api_mpls_fib_dump_t *mp;
19803   vl_api_control_ping_t *mp_ping;
19804   int ret;
19805
19806   M (MPLS_FIB_DUMP, mp);
19807   S (mp);
19808
19809   /* Use a control ping for synchronization */
19810   MPING (CONTROL_PING, mp_ping);
19811   S (mp_ping);
19812
19813   W (ret);
19814   return ret;
19815 }
19816
19817 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19818 #define vl_api_ip_fib_details_t_print vl_noop_handler
19819
19820 static void
19821 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19822 {
19823   vat_main_t *vam = &vat_main;
19824   int count = ntohl (mp->count);
19825   vl_api_fib_path_t *fp;
19826   int i;
19827
19828   print (vam->ofp,
19829          "table-id %d, prefix %U/%d",
19830          ntohl (mp->table_id), format_ip4_address, mp->address,
19831          mp->address_length);
19832   fp = mp->path;
19833   for (i = 0; i < count; i++)
19834     {
19835       if (fp->afi == IP46_TYPE_IP6)
19836         print (vam->ofp,
19837                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19838                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19839                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19840                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19841                format_ip6_address, fp->next_hop);
19842       else if (fp->afi == IP46_TYPE_IP4)
19843         print (vam->ofp,
19844                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19845                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19846                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19847                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19848                format_ip4_address, fp->next_hop);
19849       fp++;
19850     }
19851 }
19852
19853 static void vl_api_ip_fib_details_t_handler_json
19854   (vl_api_ip_fib_details_t * mp)
19855 {
19856   vat_main_t *vam = &vat_main;
19857   int count = ntohl (mp->count);
19858   vat_json_node_t *node = NULL;
19859   struct in_addr ip4;
19860   struct in6_addr ip6;
19861   vl_api_fib_path_t *fp;
19862   int i;
19863
19864   if (VAT_JSON_ARRAY != vam->json_tree.type)
19865     {
19866       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19867       vat_json_init_array (&vam->json_tree);
19868     }
19869   node = vat_json_array_add (&vam->json_tree);
19870
19871   vat_json_init_object (node);
19872   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19873   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19874   vat_json_object_add_ip4 (node, "prefix", ip4);
19875   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19876   vat_json_object_add_uint (node, "path_count", count);
19877   fp = mp->path;
19878   for (i = 0; i < count; i++)
19879     {
19880       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19881       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19882       vat_json_object_add_uint (node, "is_local", fp->is_local);
19883       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19884       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19885       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19886       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19887       if (fp->afi == IP46_TYPE_IP4)
19888         {
19889           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19890           vat_json_object_add_ip4 (node, "next_hop", ip4);
19891         }
19892       else if (fp->afi == IP46_TYPE_IP6)
19893         {
19894           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19895           vat_json_object_add_ip6 (node, "next_hop", ip6);
19896         }
19897     }
19898 }
19899
19900 static int
19901 api_ip_fib_dump (vat_main_t * vam)
19902 {
19903   vl_api_ip_fib_dump_t *mp;
19904   vl_api_control_ping_t *mp_ping;
19905   int ret;
19906
19907   M (IP_FIB_DUMP, mp);
19908   S (mp);
19909
19910   /* Use a control ping for synchronization */
19911   MPING (CONTROL_PING, mp_ping);
19912   S (mp_ping);
19913
19914   W (ret);
19915   return ret;
19916 }
19917
19918 static int
19919 api_ip_mfib_dump (vat_main_t * vam)
19920 {
19921   vl_api_ip_mfib_dump_t *mp;
19922   vl_api_control_ping_t *mp_ping;
19923   int ret;
19924
19925   M (IP_MFIB_DUMP, mp);
19926   S (mp);
19927
19928   /* Use a control ping for synchronization */
19929   MPING (CONTROL_PING, mp_ping);
19930   S (mp_ping);
19931
19932   W (ret);
19933   return ret;
19934 }
19935
19936 static void vl_api_ip_neighbor_details_t_handler
19937   (vl_api_ip_neighbor_details_t * mp)
19938 {
19939   vat_main_t *vam = &vat_main;
19940
19941   print (vam->ofp, "%c %U %U",
19942          (mp->is_static) ? 'S' : 'D',
19943          format_ethernet_address, &mp->mac_address,
19944          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19945          &mp->ip_address);
19946 }
19947
19948 static void vl_api_ip_neighbor_details_t_handler_json
19949   (vl_api_ip_neighbor_details_t * mp)
19950 {
19951
19952   vat_main_t *vam = &vat_main;
19953   vat_json_node_t *node;
19954   struct in_addr ip4;
19955   struct in6_addr ip6;
19956
19957   if (VAT_JSON_ARRAY != vam->json_tree.type)
19958     {
19959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19960       vat_json_init_array (&vam->json_tree);
19961     }
19962   node = vat_json_array_add (&vam->json_tree);
19963
19964   vat_json_init_object (node);
19965   vat_json_object_add_string_copy (node, "flag",
19966                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19967                                    "dynamic");
19968
19969   vat_json_object_add_string_copy (node, "link_layer",
19970                                    format (0, "%U", format_ethernet_address,
19971                                            &mp->mac_address));
19972
19973   if (mp->is_ipv6)
19974     {
19975       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19976       vat_json_object_add_ip6 (node, "ip_address", ip6);
19977     }
19978   else
19979     {
19980       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19981       vat_json_object_add_ip4 (node, "ip_address", ip4);
19982     }
19983 }
19984
19985 static int
19986 api_ip_neighbor_dump (vat_main_t * vam)
19987 {
19988   unformat_input_t *i = vam->input;
19989   vl_api_ip_neighbor_dump_t *mp;
19990   vl_api_control_ping_t *mp_ping;
19991   u8 is_ipv6 = 0;
19992   u32 sw_if_index = ~0;
19993   int ret;
19994
19995   /* Parse args required to build the message */
19996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19997     {
19998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19999         ;
20000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20001         ;
20002       else if (unformat (i, "ip6"))
20003         is_ipv6 = 1;
20004       else
20005         break;
20006     }
20007
20008   if (sw_if_index == ~0)
20009     {
20010       errmsg ("missing interface name or sw_if_index");
20011       return -99;
20012     }
20013
20014   M (IP_NEIGHBOR_DUMP, mp);
20015   mp->is_ipv6 = (u8) is_ipv6;
20016   mp->sw_if_index = ntohl (sw_if_index);
20017   S (mp);
20018
20019   /* Use a control ping for synchronization */
20020   MPING (CONTROL_PING, mp_ping);
20021   S (mp_ping);
20022
20023   W (ret);
20024   return ret;
20025 }
20026
20027 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20028 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20029
20030 static void
20031 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20032 {
20033   vat_main_t *vam = &vat_main;
20034   int count = ntohl (mp->count);
20035   vl_api_fib_path_t *fp;
20036   int i;
20037
20038   print (vam->ofp,
20039          "table-id %d, prefix %U/%d",
20040          ntohl (mp->table_id), format_ip6_address, mp->address,
20041          mp->address_length);
20042   fp = mp->path;
20043   for (i = 0; i < count; i++)
20044     {
20045       if (fp->afi == IP46_TYPE_IP6)
20046         print (vam->ofp,
20047                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20048                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20049                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20050                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20051                format_ip6_address, fp->next_hop);
20052       else if (fp->afi == IP46_TYPE_IP4)
20053         print (vam->ofp,
20054                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20055                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20056                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20057                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20058                format_ip4_address, fp->next_hop);
20059       fp++;
20060     }
20061 }
20062
20063 static void vl_api_ip6_fib_details_t_handler_json
20064   (vl_api_ip6_fib_details_t * mp)
20065 {
20066   vat_main_t *vam = &vat_main;
20067   int count = ntohl (mp->count);
20068   vat_json_node_t *node = NULL;
20069   struct in_addr ip4;
20070   struct in6_addr ip6;
20071   vl_api_fib_path_t *fp;
20072   int i;
20073
20074   if (VAT_JSON_ARRAY != vam->json_tree.type)
20075     {
20076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20077       vat_json_init_array (&vam->json_tree);
20078     }
20079   node = vat_json_array_add (&vam->json_tree);
20080
20081   vat_json_init_object (node);
20082   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20083   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20084   vat_json_object_add_ip6 (node, "prefix", ip6);
20085   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20086   vat_json_object_add_uint (node, "path_count", count);
20087   fp = mp->path;
20088   for (i = 0; i < count; i++)
20089     {
20090       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20091       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20092       vat_json_object_add_uint (node, "is_local", fp->is_local);
20093       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20094       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20095       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20096       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20097       if (fp->afi == IP46_TYPE_IP4)
20098         {
20099           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20100           vat_json_object_add_ip4 (node, "next_hop", ip4);
20101         }
20102       else if (fp->afi == IP46_TYPE_IP6)
20103         {
20104           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20105           vat_json_object_add_ip6 (node, "next_hop", ip6);
20106         }
20107     }
20108 }
20109
20110 static int
20111 api_ip6_fib_dump (vat_main_t * vam)
20112 {
20113   vl_api_ip6_fib_dump_t *mp;
20114   vl_api_control_ping_t *mp_ping;
20115   int ret;
20116
20117   M (IP6_FIB_DUMP, mp);
20118   S (mp);
20119
20120   /* Use a control ping for synchronization */
20121   MPING (CONTROL_PING, mp_ping);
20122   S (mp_ping);
20123
20124   W (ret);
20125   return ret;
20126 }
20127
20128 static int
20129 api_ip6_mfib_dump (vat_main_t * vam)
20130 {
20131   vl_api_ip6_mfib_dump_t *mp;
20132   vl_api_control_ping_t *mp_ping;
20133   int ret;
20134
20135   M (IP6_MFIB_DUMP, mp);
20136   S (mp);
20137
20138   /* Use a control ping for synchronization */
20139   MPING (CONTROL_PING, mp_ping);
20140   S (mp_ping);
20141
20142   W (ret);
20143   return ret;
20144 }
20145
20146 int
20147 api_classify_table_ids (vat_main_t * vam)
20148 {
20149   vl_api_classify_table_ids_t *mp;
20150   int ret;
20151
20152   /* Construct the API message */
20153   M (CLASSIFY_TABLE_IDS, mp);
20154   mp->context = 0;
20155
20156   S (mp);
20157   W (ret);
20158   return ret;
20159 }
20160
20161 int
20162 api_classify_table_by_interface (vat_main_t * vam)
20163 {
20164   unformat_input_t *input = vam->input;
20165   vl_api_classify_table_by_interface_t *mp;
20166
20167   u32 sw_if_index = ~0;
20168   int ret;
20169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20170     {
20171       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20172         ;
20173       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20174         ;
20175       else
20176         break;
20177     }
20178   if (sw_if_index == ~0)
20179     {
20180       errmsg ("missing interface name or sw_if_index");
20181       return -99;
20182     }
20183
20184   /* Construct the API message */
20185   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20186   mp->context = 0;
20187   mp->sw_if_index = ntohl (sw_if_index);
20188
20189   S (mp);
20190   W (ret);
20191   return ret;
20192 }
20193
20194 int
20195 api_classify_table_info (vat_main_t * vam)
20196 {
20197   unformat_input_t *input = vam->input;
20198   vl_api_classify_table_info_t *mp;
20199
20200   u32 table_id = ~0;
20201   int ret;
20202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20203     {
20204       if (unformat (input, "table_id %d", &table_id))
20205         ;
20206       else
20207         break;
20208     }
20209   if (table_id == ~0)
20210     {
20211       errmsg ("missing table id");
20212       return -99;
20213     }
20214
20215   /* Construct the API message */
20216   M (CLASSIFY_TABLE_INFO, mp);
20217   mp->context = 0;
20218   mp->table_id = ntohl (table_id);
20219
20220   S (mp);
20221   W (ret);
20222   return ret;
20223 }
20224
20225 int
20226 api_classify_session_dump (vat_main_t * vam)
20227 {
20228   unformat_input_t *input = vam->input;
20229   vl_api_classify_session_dump_t *mp;
20230   vl_api_control_ping_t *mp_ping;
20231
20232   u32 table_id = ~0;
20233   int ret;
20234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20235     {
20236       if (unformat (input, "table_id %d", &table_id))
20237         ;
20238       else
20239         break;
20240     }
20241   if (table_id == ~0)
20242     {
20243       errmsg ("missing table id");
20244       return -99;
20245     }
20246
20247   /* Construct the API message */
20248   M (CLASSIFY_SESSION_DUMP, mp);
20249   mp->context = 0;
20250   mp->table_id = ntohl (table_id);
20251   S (mp);
20252
20253   /* Use a control ping for synchronization */
20254   MPING (CONTROL_PING, mp_ping);
20255   S (mp_ping);
20256
20257   W (ret);
20258   return ret;
20259 }
20260
20261 static void
20262 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20263 {
20264   vat_main_t *vam = &vat_main;
20265
20266   print (vam->ofp, "collector_address %U, collector_port %d, "
20267          "src_address %U, vrf_id %d, path_mtu %u, "
20268          "template_interval %u, udp_checksum %d",
20269          format_ip4_address, mp->collector_address,
20270          ntohs (mp->collector_port),
20271          format_ip4_address, mp->src_address,
20272          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20273          ntohl (mp->template_interval), mp->udp_checksum);
20274
20275   vam->retval = 0;
20276   vam->result_ready = 1;
20277 }
20278
20279 static void
20280   vl_api_ipfix_exporter_details_t_handler_json
20281   (vl_api_ipfix_exporter_details_t * mp)
20282 {
20283   vat_main_t *vam = &vat_main;
20284   vat_json_node_t node;
20285   struct in_addr collector_address;
20286   struct in_addr src_address;
20287
20288   vat_json_init_object (&node);
20289   clib_memcpy (&collector_address, &mp->collector_address,
20290                sizeof (collector_address));
20291   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20292   vat_json_object_add_uint (&node, "collector_port",
20293                             ntohs (mp->collector_port));
20294   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20295   vat_json_object_add_ip4 (&node, "src_address", src_address);
20296   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20297   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20298   vat_json_object_add_uint (&node, "template_interval",
20299                             ntohl (mp->template_interval));
20300   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20301
20302   vat_json_print (vam->ofp, &node);
20303   vat_json_free (&node);
20304   vam->retval = 0;
20305   vam->result_ready = 1;
20306 }
20307
20308 int
20309 api_ipfix_exporter_dump (vat_main_t * vam)
20310 {
20311   vl_api_ipfix_exporter_dump_t *mp;
20312   int ret;
20313
20314   /* Construct the API message */
20315   M (IPFIX_EXPORTER_DUMP, mp);
20316   mp->context = 0;
20317
20318   S (mp);
20319   W (ret);
20320   return ret;
20321 }
20322
20323 static int
20324 api_ipfix_classify_stream_dump (vat_main_t * vam)
20325 {
20326   vl_api_ipfix_classify_stream_dump_t *mp;
20327   int ret;
20328
20329   /* Construct the API message */
20330   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20331   mp->context = 0;
20332
20333   S (mp);
20334   W (ret);
20335   return ret;
20336   /* NOTREACHED */
20337   return 0;
20338 }
20339
20340 static void
20341   vl_api_ipfix_classify_stream_details_t_handler
20342   (vl_api_ipfix_classify_stream_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   print (vam->ofp, "domain_id %d, src_port %d",
20346          ntohl (mp->domain_id), ntohs (mp->src_port));
20347   vam->retval = 0;
20348   vam->result_ready = 1;
20349 }
20350
20351 static void
20352   vl_api_ipfix_classify_stream_details_t_handler_json
20353   (vl_api_ipfix_classify_stream_details_t * mp)
20354 {
20355   vat_main_t *vam = &vat_main;
20356   vat_json_node_t node;
20357
20358   vat_json_init_object (&node);
20359   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20360   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20361
20362   vat_json_print (vam->ofp, &node);
20363   vat_json_free (&node);
20364   vam->retval = 0;
20365   vam->result_ready = 1;
20366 }
20367
20368 static int
20369 api_ipfix_classify_table_dump (vat_main_t * vam)
20370 {
20371   vl_api_ipfix_classify_table_dump_t *mp;
20372   vl_api_control_ping_t *mp_ping;
20373   int ret;
20374
20375   if (!vam->json_output)
20376     {
20377       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20378              "transport_protocol");
20379     }
20380
20381   /* Construct the API message */
20382   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20383
20384   /* send it... */
20385   S (mp);
20386
20387   /* Use a control ping for synchronization */
20388   MPING (CONTROL_PING, mp_ping);
20389   S (mp_ping);
20390
20391   W (ret);
20392   return ret;
20393 }
20394
20395 static void
20396   vl_api_ipfix_classify_table_details_t_handler
20397   (vl_api_ipfix_classify_table_details_t * mp)
20398 {
20399   vat_main_t *vam = &vat_main;
20400   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20401          mp->transport_protocol);
20402 }
20403
20404 static void
20405   vl_api_ipfix_classify_table_details_t_handler_json
20406   (vl_api_ipfix_classify_table_details_t * mp)
20407 {
20408   vat_json_node_t *node = NULL;
20409   vat_main_t *vam = &vat_main;
20410
20411   if (VAT_JSON_ARRAY != vam->json_tree.type)
20412     {
20413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20414       vat_json_init_array (&vam->json_tree);
20415     }
20416
20417   node = vat_json_array_add (&vam->json_tree);
20418   vat_json_init_object (node);
20419
20420   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20421   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20422   vat_json_object_add_uint (node, "transport_protocol",
20423                             mp->transport_protocol);
20424 }
20425
20426 static int
20427 api_sw_interface_span_enable_disable (vat_main_t * vam)
20428 {
20429   unformat_input_t *i = vam->input;
20430   vl_api_sw_interface_span_enable_disable_t *mp;
20431   u32 src_sw_if_index = ~0;
20432   u32 dst_sw_if_index = ~0;
20433   u8 state = 3;
20434   int ret;
20435   u8 is_l2 = 0;
20436
20437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20438     {
20439       if (unformat
20440           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20441         ;
20442       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20443         ;
20444       else
20445         if (unformat
20446             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20447         ;
20448       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20449         ;
20450       else if (unformat (i, "disable"))
20451         state = 0;
20452       else if (unformat (i, "rx"))
20453         state = 1;
20454       else if (unformat (i, "tx"))
20455         state = 2;
20456       else if (unformat (i, "both"))
20457         state = 3;
20458       else if (unformat (i, "l2"))
20459         is_l2 = 1;
20460       else
20461         break;
20462     }
20463
20464   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20465
20466   mp->sw_if_index_from = htonl (src_sw_if_index);
20467   mp->sw_if_index_to = htonl (dst_sw_if_index);
20468   mp->state = state;
20469   mp->is_l2 = is_l2;
20470
20471   S (mp);
20472   W (ret);
20473   return ret;
20474 }
20475
20476 static void
20477 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20478                                             * mp)
20479 {
20480   vat_main_t *vam = &vat_main;
20481   u8 *sw_if_from_name = 0;
20482   u8 *sw_if_to_name = 0;
20483   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20484   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20485   char *states[] = { "none", "rx", "tx", "both" };
20486   hash_pair_t *p;
20487
20488   /* *INDENT-OFF* */
20489   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20490   ({
20491     if ((u32) p->value[0] == sw_if_index_from)
20492       {
20493         sw_if_from_name = (u8 *)(p->key);
20494         if (sw_if_to_name)
20495           break;
20496       }
20497     if ((u32) p->value[0] == sw_if_index_to)
20498       {
20499         sw_if_to_name = (u8 *)(p->key);
20500         if (sw_if_from_name)
20501           break;
20502       }
20503   }));
20504   /* *INDENT-ON* */
20505   print (vam->ofp, "%20s => %20s (%s)",
20506          sw_if_from_name, sw_if_to_name, states[mp->state]);
20507 }
20508
20509 static void
20510   vl_api_sw_interface_span_details_t_handler_json
20511   (vl_api_sw_interface_span_details_t * mp)
20512 {
20513   vat_main_t *vam = &vat_main;
20514   vat_json_node_t *node = NULL;
20515   u8 *sw_if_from_name = 0;
20516   u8 *sw_if_to_name = 0;
20517   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20518   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20519   hash_pair_t *p;
20520
20521   /* *INDENT-OFF* */
20522   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20523   ({
20524     if ((u32) p->value[0] == sw_if_index_from)
20525       {
20526         sw_if_from_name = (u8 *)(p->key);
20527         if (sw_if_to_name)
20528           break;
20529       }
20530     if ((u32) p->value[0] == sw_if_index_to)
20531       {
20532         sw_if_to_name = (u8 *)(p->key);
20533         if (sw_if_from_name)
20534           break;
20535       }
20536   }));
20537   /* *INDENT-ON* */
20538
20539   if (VAT_JSON_ARRAY != vam->json_tree.type)
20540     {
20541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20542       vat_json_init_array (&vam->json_tree);
20543     }
20544   node = vat_json_array_add (&vam->json_tree);
20545
20546   vat_json_init_object (node);
20547   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20548   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20549   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20550   if (0 != sw_if_to_name)
20551     {
20552       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20553     }
20554   vat_json_object_add_uint (node, "state", mp->state);
20555 }
20556
20557 static int
20558 api_sw_interface_span_dump (vat_main_t * vam)
20559 {
20560   unformat_input_t *input = vam->input;
20561   vl_api_sw_interface_span_dump_t *mp;
20562   vl_api_control_ping_t *mp_ping;
20563   u8 is_l2 = 0;
20564   int ret;
20565
20566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20567     {
20568       if (unformat (input, "l2"))
20569         is_l2 = 1;
20570       else
20571         break;
20572     }
20573
20574   M (SW_INTERFACE_SPAN_DUMP, mp);
20575   mp->is_l2 = is_l2;
20576   S (mp);
20577
20578   /* Use a control ping for synchronization */
20579   MPING (CONTROL_PING, mp_ping);
20580   S (mp_ping);
20581
20582   W (ret);
20583   return ret;
20584 }
20585
20586 int
20587 api_pg_create_interface (vat_main_t * vam)
20588 {
20589   unformat_input_t *input = vam->input;
20590   vl_api_pg_create_interface_t *mp;
20591
20592   u32 if_id = ~0;
20593   int ret;
20594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20595     {
20596       if (unformat (input, "if_id %d", &if_id))
20597         ;
20598       else
20599         break;
20600     }
20601   if (if_id == ~0)
20602     {
20603       errmsg ("missing pg interface index");
20604       return -99;
20605     }
20606
20607   /* Construct the API message */
20608   M (PG_CREATE_INTERFACE, mp);
20609   mp->context = 0;
20610   mp->interface_id = ntohl (if_id);
20611
20612   S (mp);
20613   W (ret);
20614   return ret;
20615 }
20616
20617 int
20618 api_pg_capture (vat_main_t * vam)
20619 {
20620   unformat_input_t *input = vam->input;
20621   vl_api_pg_capture_t *mp;
20622
20623   u32 if_id = ~0;
20624   u8 enable = 1;
20625   u32 count = 1;
20626   u8 pcap_file_set = 0;
20627   u8 *pcap_file = 0;
20628   int ret;
20629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20630     {
20631       if (unformat (input, "if_id %d", &if_id))
20632         ;
20633       else if (unformat (input, "pcap %s", &pcap_file))
20634         pcap_file_set = 1;
20635       else if (unformat (input, "count %d", &count))
20636         ;
20637       else if (unformat (input, "disable"))
20638         enable = 0;
20639       else
20640         break;
20641     }
20642   if (if_id == ~0)
20643     {
20644       errmsg ("missing pg interface index");
20645       return -99;
20646     }
20647   if (pcap_file_set > 0)
20648     {
20649       if (vec_len (pcap_file) > 255)
20650         {
20651           errmsg ("pcap file name is too long");
20652           return -99;
20653         }
20654     }
20655
20656   u32 name_len = vec_len (pcap_file);
20657   /* Construct the API message */
20658   M (PG_CAPTURE, mp);
20659   mp->context = 0;
20660   mp->interface_id = ntohl (if_id);
20661   mp->is_enabled = enable;
20662   mp->count = ntohl (count);
20663   mp->pcap_name_length = ntohl (name_len);
20664   if (pcap_file_set != 0)
20665     {
20666       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20667     }
20668   vec_free (pcap_file);
20669
20670   S (mp);
20671   W (ret);
20672   return ret;
20673 }
20674
20675 int
20676 api_pg_enable_disable (vat_main_t * vam)
20677 {
20678   unformat_input_t *input = vam->input;
20679   vl_api_pg_enable_disable_t *mp;
20680
20681   u8 enable = 1;
20682   u8 stream_name_set = 0;
20683   u8 *stream_name = 0;
20684   int ret;
20685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20686     {
20687       if (unformat (input, "stream %s", &stream_name))
20688         stream_name_set = 1;
20689       else if (unformat (input, "disable"))
20690         enable = 0;
20691       else
20692         break;
20693     }
20694
20695   if (stream_name_set > 0)
20696     {
20697       if (vec_len (stream_name) > 255)
20698         {
20699           errmsg ("stream name too long");
20700           return -99;
20701         }
20702     }
20703
20704   u32 name_len = vec_len (stream_name);
20705   /* Construct the API message */
20706   M (PG_ENABLE_DISABLE, mp);
20707   mp->context = 0;
20708   mp->is_enabled = enable;
20709   if (stream_name_set != 0)
20710     {
20711       mp->stream_name_length = ntohl (name_len);
20712       clib_memcpy (mp->stream_name, stream_name, name_len);
20713     }
20714   vec_free (stream_name);
20715
20716   S (mp);
20717   W (ret);
20718   return ret;
20719 }
20720
20721 int
20722 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20723 {
20724   unformat_input_t *input = vam->input;
20725   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20726
20727   u16 *low_ports = 0;
20728   u16 *high_ports = 0;
20729   u16 this_low;
20730   u16 this_hi;
20731   ip4_address_t ip4_addr;
20732   ip6_address_t ip6_addr;
20733   u32 length;
20734   u32 tmp, tmp2;
20735   u8 prefix_set = 0;
20736   u32 vrf_id = ~0;
20737   u8 is_add = 1;
20738   u8 is_ipv6 = 0;
20739   int ret;
20740
20741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20742     {
20743       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20744         {
20745           prefix_set = 1;
20746         }
20747       else
20748         if (unformat
20749             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20750         {
20751           prefix_set = 1;
20752           is_ipv6 = 1;
20753         }
20754       else if (unformat (input, "vrf %d", &vrf_id))
20755         ;
20756       else if (unformat (input, "del"))
20757         is_add = 0;
20758       else if (unformat (input, "port %d", &tmp))
20759         {
20760           if (tmp == 0 || tmp > 65535)
20761             {
20762               errmsg ("port %d out of range", tmp);
20763               return -99;
20764             }
20765           this_low = tmp;
20766           this_hi = this_low + 1;
20767           vec_add1 (low_ports, this_low);
20768           vec_add1 (high_ports, this_hi);
20769         }
20770       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20771         {
20772           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20773             {
20774               errmsg ("incorrect range parameters");
20775               return -99;
20776             }
20777           this_low = tmp;
20778           /* Note: in debug CLI +1 is added to high before
20779              passing to real fn that does "the work"
20780              (ip_source_and_port_range_check_add_del).
20781              This fn is a wrapper around the binary API fn a
20782              control plane will call, which expects this increment
20783              to have occurred. Hence letting the binary API control
20784              plane fn do the increment for consistency between VAT
20785              and other control planes.
20786            */
20787           this_hi = tmp2;
20788           vec_add1 (low_ports, this_low);
20789           vec_add1 (high_ports, this_hi);
20790         }
20791       else
20792         break;
20793     }
20794
20795   if (prefix_set == 0)
20796     {
20797       errmsg ("<address>/<mask> not specified");
20798       return -99;
20799     }
20800
20801   if (vrf_id == ~0)
20802     {
20803       errmsg ("VRF ID required, not specified");
20804       return -99;
20805     }
20806
20807   if (vrf_id == 0)
20808     {
20809       errmsg
20810         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20811       return -99;
20812     }
20813
20814   if (vec_len (low_ports) == 0)
20815     {
20816       errmsg ("At least one port or port range required");
20817       return -99;
20818     }
20819
20820   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20821
20822   mp->is_add = is_add;
20823
20824   if (is_ipv6)
20825     {
20826       mp->is_ipv6 = 1;
20827       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20828     }
20829   else
20830     {
20831       mp->is_ipv6 = 0;
20832       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20833     }
20834
20835   mp->mask_length = length;
20836   mp->number_of_ranges = vec_len (low_ports);
20837
20838   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20839   vec_free (low_ports);
20840
20841   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20842   vec_free (high_ports);
20843
20844   mp->vrf_id = ntohl (vrf_id);
20845
20846   S (mp);
20847   W (ret);
20848   return ret;
20849 }
20850
20851 int
20852 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20853 {
20854   unformat_input_t *input = vam->input;
20855   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20856   u32 sw_if_index = ~0;
20857   int vrf_set = 0;
20858   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20859   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20860   u8 is_add = 1;
20861   int ret;
20862
20863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20864     {
20865       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20866         ;
20867       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20868         ;
20869       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20870         vrf_set = 1;
20871       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20872         vrf_set = 1;
20873       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20874         vrf_set = 1;
20875       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20876         vrf_set = 1;
20877       else if (unformat (input, "del"))
20878         is_add = 0;
20879       else
20880         break;
20881     }
20882
20883   if (sw_if_index == ~0)
20884     {
20885       errmsg ("Interface required but not specified");
20886       return -99;
20887     }
20888
20889   if (vrf_set == 0)
20890     {
20891       errmsg ("VRF ID required but not specified");
20892       return -99;
20893     }
20894
20895   if (tcp_out_vrf_id == 0
20896       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20897     {
20898       errmsg
20899         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20900       return -99;
20901     }
20902
20903   /* Construct the API message */
20904   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20905
20906   mp->sw_if_index = ntohl (sw_if_index);
20907   mp->is_add = is_add;
20908   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20909   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20910   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20911   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20912
20913   /* send it... */
20914   S (mp);
20915
20916   /* Wait for a reply... */
20917   W (ret);
20918   return ret;
20919 }
20920
20921 static int
20922 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20923 {
20924   unformat_input_t *i = vam->input;
20925   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20926   u32 local_sa_id = 0;
20927   u32 remote_sa_id = 0;
20928   ip4_address_t src_address;
20929   ip4_address_t dst_address;
20930   u8 is_add = 1;
20931   int ret;
20932
20933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20934     {
20935       if (unformat (i, "local_sa %d", &local_sa_id))
20936         ;
20937       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20938         ;
20939       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20940         ;
20941       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20942         ;
20943       else if (unformat (i, "del"))
20944         is_add = 0;
20945       else
20946         {
20947           clib_warning ("parse error '%U'", format_unformat_error, i);
20948           return -99;
20949         }
20950     }
20951
20952   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20953
20954   mp->local_sa_id = ntohl (local_sa_id);
20955   mp->remote_sa_id = ntohl (remote_sa_id);
20956   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20957   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20958   mp->is_add = is_add;
20959
20960   S (mp);
20961   W (ret);
20962   return ret;
20963 }
20964
20965 static int
20966 api_punt (vat_main_t * vam)
20967 {
20968   unformat_input_t *i = vam->input;
20969   vl_api_punt_t *mp;
20970   u32 ipv = ~0;
20971   u32 protocol = ~0;
20972   u32 port = ~0;
20973   int is_add = 1;
20974   int ret;
20975
20976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20977     {
20978       if (unformat (i, "ip %d", &ipv))
20979         ;
20980       else if (unformat (i, "protocol %d", &protocol))
20981         ;
20982       else if (unformat (i, "port %d", &port))
20983         ;
20984       else if (unformat (i, "del"))
20985         is_add = 0;
20986       else
20987         {
20988           clib_warning ("parse error '%U'", format_unformat_error, i);
20989           return -99;
20990         }
20991     }
20992
20993   M (PUNT, mp);
20994
20995   mp->is_add = (u8) is_add;
20996   mp->ipv = (u8) ipv;
20997   mp->l4_protocol = (u8) protocol;
20998   mp->l4_port = htons ((u16) port);
20999
21000   S (mp);
21001   W (ret);
21002   return ret;
21003 }
21004
21005 static void vl_api_ipsec_gre_tunnel_details_t_handler
21006   (vl_api_ipsec_gre_tunnel_details_t * mp)
21007 {
21008   vat_main_t *vam = &vat_main;
21009
21010   print (vam->ofp, "%11d%15U%15U%14d%14d",
21011          ntohl (mp->sw_if_index),
21012          format_ip4_address, &mp->src_address,
21013          format_ip4_address, &mp->dst_address,
21014          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21015 }
21016
21017 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21018   (vl_api_ipsec_gre_tunnel_details_t * mp)
21019 {
21020   vat_main_t *vam = &vat_main;
21021   vat_json_node_t *node = NULL;
21022   struct in_addr ip4;
21023
21024   if (VAT_JSON_ARRAY != vam->json_tree.type)
21025     {
21026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21027       vat_json_init_array (&vam->json_tree);
21028     }
21029   node = vat_json_array_add (&vam->json_tree);
21030
21031   vat_json_init_object (node);
21032   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21033   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21034   vat_json_object_add_ip4 (node, "src_address", ip4);
21035   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21036   vat_json_object_add_ip4 (node, "dst_address", ip4);
21037   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21038   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21039 }
21040
21041 static int
21042 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21043 {
21044   unformat_input_t *i = vam->input;
21045   vl_api_ipsec_gre_tunnel_dump_t *mp;
21046   vl_api_control_ping_t *mp_ping;
21047   u32 sw_if_index;
21048   u8 sw_if_index_set = 0;
21049   int ret;
21050
21051   /* Parse args required to build the message */
21052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21053     {
21054       if (unformat (i, "sw_if_index %d", &sw_if_index))
21055         sw_if_index_set = 1;
21056       else
21057         break;
21058     }
21059
21060   if (sw_if_index_set == 0)
21061     {
21062       sw_if_index = ~0;
21063     }
21064
21065   if (!vam->json_output)
21066     {
21067       print (vam->ofp, "%11s%15s%15s%14s%14s",
21068              "sw_if_index", "src_address", "dst_address",
21069              "local_sa_id", "remote_sa_id");
21070     }
21071
21072   /* Get list of gre-tunnel interfaces */
21073   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21074
21075   mp->sw_if_index = htonl (sw_if_index);
21076
21077   S (mp);
21078
21079   /* Use a control ping for synchronization */
21080   MPING (CONTROL_PING, mp_ping);
21081   S (mp_ping);
21082
21083   W (ret);
21084   return ret;
21085 }
21086
21087 static int
21088 api_delete_subif (vat_main_t * vam)
21089 {
21090   unformat_input_t *i = vam->input;
21091   vl_api_delete_subif_t *mp;
21092   u32 sw_if_index = ~0;
21093   int ret;
21094
21095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21096     {
21097       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21098         ;
21099       if (unformat (i, "sw_if_index %d", &sw_if_index))
21100         ;
21101       else
21102         break;
21103     }
21104
21105   if (sw_if_index == ~0)
21106     {
21107       errmsg ("missing sw_if_index");
21108       return -99;
21109     }
21110
21111   /* Construct the API message */
21112   M (DELETE_SUBIF, mp);
21113   mp->sw_if_index = ntohl (sw_if_index);
21114
21115   S (mp);
21116   W (ret);
21117   return ret;
21118 }
21119
21120 #define foreach_pbb_vtr_op      \
21121 _("disable",  L2_VTR_DISABLED)  \
21122 _("pop",  L2_VTR_POP_2)         \
21123 _("push",  L2_VTR_PUSH_2)
21124
21125 static int
21126 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21127 {
21128   unformat_input_t *i = vam->input;
21129   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21130   u32 sw_if_index = ~0, vtr_op = ~0;
21131   u16 outer_tag = ~0;
21132   u8 dmac[6], smac[6];
21133   u8 dmac_set = 0, smac_set = 0;
21134   u16 vlanid = 0;
21135   u32 sid = ~0;
21136   u32 tmp;
21137   int ret;
21138
21139   /* Shut up coverity */
21140   memset (dmac, 0, sizeof (dmac));
21141   memset (smac, 0, sizeof (smac));
21142
21143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21144     {
21145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21146         ;
21147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21148         ;
21149       else if (unformat (i, "vtr_op %d", &vtr_op))
21150         ;
21151 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21152       foreach_pbb_vtr_op
21153 #undef _
21154         else if (unformat (i, "translate_pbb_stag"))
21155         {
21156           if (unformat (i, "%d", &tmp))
21157             {
21158               vtr_op = L2_VTR_TRANSLATE_2_1;
21159               outer_tag = tmp;
21160             }
21161           else
21162             {
21163               errmsg
21164                 ("translate_pbb_stag operation requires outer tag definition");
21165               return -99;
21166             }
21167         }
21168       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21169         dmac_set++;
21170       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21171         smac_set++;
21172       else if (unformat (i, "sid %d", &sid))
21173         ;
21174       else if (unformat (i, "vlanid %d", &tmp))
21175         vlanid = tmp;
21176       else
21177         {
21178           clib_warning ("parse error '%U'", format_unformat_error, i);
21179           return -99;
21180         }
21181     }
21182
21183   if ((sw_if_index == ~0) || (vtr_op == ~0))
21184     {
21185       errmsg ("missing sw_if_index or vtr operation");
21186       return -99;
21187     }
21188   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21189       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21190     {
21191       errmsg
21192         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21193       return -99;
21194     }
21195
21196   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21197   mp->sw_if_index = ntohl (sw_if_index);
21198   mp->vtr_op = ntohl (vtr_op);
21199   mp->outer_tag = ntohs (outer_tag);
21200   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21201   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21202   mp->b_vlanid = ntohs (vlanid);
21203   mp->i_sid = ntohl (sid);
21204
21205   S (mp);
21206   W (ret);
21207   return ret;
21208 }
21209
21210 static int
21211 api_flow_classify_set_interface (vat_main_t * vam)
21212 {
21213   unformat_input_t *i = vam->input;
21214   vl_api_flow_classify_set_interface_t *mp;
21215   u32 sw_if_index;
21216   int sw_if_index_set;
21217   u32 ip4_table_index = ~0;
21218   u32 ip6_table_index = ~0;
21219   u8 is_add = 1;
21220   int ret;
21221
21222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21223     {
21224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21225         sw_if_index_set = 1;
21226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21227         sw_if_index_set = 1;
21228       else if (unformat (i, "del"))
21229         is_add = 0;
21230       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21231         ;
21232       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21233         ;
21234       else
21235         {
21236           clib_warning ("parse error '%U'", format_unformat_error, i);
21237           return -99;
21238         }
21239     }
21240
21241   if (sw_if_index_set == 0)
21242     {
21243       errmsg ("missing interface name or sw_if_index");
21244       return -99;
21245     }
21246
21247   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21248
21249   mp->sw_if_index = ntohl (sw_if_index);
21250   mp->ip4_table_index = ntohl (ip4_table_index);
21251   mp->ip6_table_index = ntohl (ip6_table_index);
21252   mp->is_add = is_add;
21253
21254   S (mp);
21255   W (ret);
21256   return ret;
21257 }
21258
21259 static int
21260 api_flow_classify_dump (vat_main_t * vam)
21261 {
21262   unformat_input_t *i = vam->input;
21263   vl_api_flow_classify_dump_t *mp;
21264   vl_api_control_ping_t *mp_ping;
21265   u8 type = FLOW_CLASSIFY_N_TABLES;
21266   int ret;
21267
21268   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21269     ;
21270   else
21271     {
21272       errmsg ("classify table type must be specified");
21273       return -99;
21274     }
21275
21276   if (!vam->json_output)
21277     {
21278       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21279     }
21280
21281   M (FLOW_CLASSIFY_DUMP, mp);
21282   mp->type = type;
21283   /* send it... */
21284   S (mp);
21285
21286   /* Use a control ping for synchronization */
21287   MPING (CONTROL_PING, mp_ping);
21288   S (mp_ping);
21289
21290   /* Wait for a reply... */
21291   W (ret);
21292   return ret;
21293 }
21294
21295 static int
21296 api_feature_enable_disable (vat_main_t * vam)
21297 {
21298   unformat_input_t *i = vam->input;
21299   vl_api_feature_enable_disable_t *mp;
21300   u8 *arc_name = 0;
21301   u8 *feature_name = 0;
21302   u32 sw_if_index = ~0;
21303   u8 enable = 1;
21304   int ret;
21305
21306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21307     {
21308       if (unformat (i, "arc_name %s", &arc_name))
21309         ;
21310       else if (unformat (i, "feature_name %s", &feature_name))
21311         ;
21312       else
21313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21314         ;
21315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21316         ;
21317       else if (unformat (i, "disable"))
21318         enable = 0;
21319       else
21320         break;
21321     }
21322
21323   if (arc_name == 0)
21324     {
21325       errmsg ("missing arc name");
21326       return -99;
21327     }
21328   if (vec_len (arc_name) > 63)
21329     {
21330       errmsg ("arc name too long");
21331     }
21332
21333   if (feature_name == 0)
21334     {
21335       errmsg ("missing feature name");
21336       return -99;
21337     }
21338   if (vec_len (feature_name) > 63)
21339     {
21340       errmsg ("feature name too long");
21341     }
21342
21343   if (sw_if_index == ~0)
21344     {
21345       errmsg ("missing interface name or sw_if_index");
21346       return -99;
21347     }
21348
21349   /* Construct the API message */
21350   M (FEATURE_ENABLE_DISABLE, mp);
21351   mp->sw_if_index = ntohl (sw_if_index);
21352   mp->enable = enable;
21353   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21354   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21355   vec_free (arc_name);
21356   vec_free (feature_name);
21357
21358   S (mp);
21359   W (ret);
21360   return ret;
21361 }
21362
21363 static int
21364 api_sw_interface_tag_add_del (vat_main_t * vam)
21365 {
21366   unformat_input_t *i = vam->input;
21367   vl_api_sw_interface_tag_add_del_t *mp;
21368   u32 sw_if_index = ~0;
21369   u8 *tag = 0;
21370   u8 enable = 1;
21371   int ret;
21372
21373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21374     {
21375       if (unformat (i, "tag %s", &tag))
21376         ;
21377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21378         ;
21379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21380         ;
21381       else if (unformat (i, "del"))
21382         enable = 0;
21383       else
21384         break;
21385     }
21386
21387   if (sw_if_index == ~0)
21388     {
21389       errmsg ("missing interface name or sw_if_index");
21390       return -99;
21391     }
21392
21393   if (enable && (tag == 0))
21394     {
21395       errmsg ("no tag specified");
21396       return -99;
21397     }
21398
21399   /* Construct the API message */
21400   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21401   mp->sw_if_index = ntohl (sw_if_index);
21402   mp->is_add = enable;
21403   if (enable)
21404     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21405   vec_free (tag);
21406
21407   S (mp);
21408   W (ret);
21409   return ret;
21410 }
21411
21412 static void vl_api_l2_xconnect_details_t_handler
21413   (vl_api_l2_xconnect_details_t * mp)
21414 {
21415   vat_main_t *vam = &vat_main;
21416
21417   print (vam->ofp, "%15d%15d",
21418          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21419 }
21420
21421 static void vl_api_l2_xconnect_details_t_handler_json
21422   (vl_api_l2_xconnect_details_t * mp)
21423 {
21424   vat_main_t *vam = &vat_main;
21425   vat_json_node_t *node = NULL;
21426
21427   if (VAT_JSON_ARRAY != vam->json_tree.type)
21428     {
21429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21430       vat_json_init_array (&vam->json_tree);
21431     }
21432   node = vat_json_array_add (&vam->json_tree);
21433
21434   vat_json_init_object (node);
21435   vat_json_object_add_uint (node, "rx_sw_if_index",
21436                             ntohl (mp->rx_sw_if_index));
21437   vat_json_object_add_uint (node, "tx_sw_if_index",
21438                             ntohl (mp->tx_sw_if_index));
21439 }
21440
21441 static int
21442 api_l2_xconnect_dump (vat_main_t * vam)
21443 {
21444   vl_api_l2_xconnect_dump_t *mp;
21445   vl_api_control_ping_t *mp_ping;
21446   int ret;
21447
21448   if (!vam->json_output)
21449     {
21450       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21451     }
21452
21453   M (L2_XCONNECT_DUMP, mp);
21454
21455   S (mp);
21456
21457   /* Use a control ping for synchronization */
21458   MPING (CONTROL_PING, mp_ping);
21459   S (mp_ping);
21460
21461   W (ret);
21462   return ret;
21463 }
21464
21465 static int
21466 api_sw_interface_set_mtu (vat_main_t * vam)
21467 {
21468   unformat_input_t *i = vam->input;
21469   vl_api_sw_interface_set_mtu_t *mp;
21470   u32 sw_if_index = ~0;
21471   u32 mtu = 0;
21472   int ret;
21473
21474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21475     {
21476       if (unformat (i, "mtu %d", &mtu))
21477         ;
21478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21479         ;
21480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21481         ;
21482       else
21483         break;
21484     }
21485
21486   if (sw_if_index == ~0)
21487     {
21488       errmsg ("missing interface name or sw_if_index");
21489       return -99;
21490     }
21491
21492   if (mtu == 0)
21493     {
21494       errmsg ("no mtu specified");
21495       return -99;
21496     }
21497
21498   /* Construct the API message */
21499   M (SW_INTERFACE_SET_MTU, mp);
21500   mp->sw_if_index = ntohl (sw_if_index);
21501   mp->mtu = ntohs ((u16) mtu);
21502
21503   S (mp);
21504   W (ret);
21505   return ret;
21506 }
21507
21508 static int
21509 api_p2p_ethernet_add (vat_main_t * vam)
21510 {
21511   unformat_input_t *i = vam->input;
21512   vl_api_p2p_ethernet_add_t *mp;
21513   u32 parent_if_index = ~0;
21514   u32 sub_id = ~0;
21515   u8 remote_mac[6];
21516   u8 mac_set = 0;
21517   int ret;
21518
21519   memset (remote_mac, 0, sizeof (remote_mac));
21520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21521     {
21522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21523         ;
21524       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21525         ;
21526       else
21527         if (unformat
21528             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21529         mac_set++;
21530       else if (unformat (i, "sub_id %d", &sub_id))
21531         ;
21532       else
21533         {
21534           clib_warning ("parse error '%U'", format_unformat_error, i);
21535           return -99;
21536         }
21537     }
21538
21539   if (parent_if_index == ~0)
21540     {
21541       errmsg ("missing interface name or sw_if_index");
21542       return -99;
21543     }
21544   if (mac_set == 0)
21545     {
21546       errmsg ("missing remote mac address");
21547       return -99;
21548     }
21549   if (sub_id == ~0)
21550     {
21551       errmsg ("missing sub-interface id");
21552       return -99;
21553     }
21554
21555   M (P2P_ETHERNET_ADD, mp);
21556   mp->parent_if_index = ntohl (parent_if_index);
21557   mp->subif_id = ntohl (sub_id);
21558   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21559
21560   S (mp);
21561   W (ret);
21562   return ret;
21563 }
21564
21565 static int
21566 api_p2p_ethernet_del (vat_main_t * vam)
21567 {
21568   unformat_input_t *i = vam->input;
21569   vl_api_p2p_ethernet_del_t *mp;
21570   u32 parent_if_index = ~0;
21571   u8 remote_mac[6];
21572   u8 mac_set = 0;
21573   int ret;
21574
21575   memset (remote_mac, 0, sizeof (remote_mac));
21576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21577     {
21578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21579         ;
21580       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21581         ;
21582       else
21583         if (unformat
21584             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21585         mac_set++;
21586       else
21587         {
21588           clib_warning ("parse error '%U'", format_unformat_error, i);
21589           return -99;
21590         }
21591     }
21592
21593   if (parent_if_index == ~0)
21594     {
21595       errmsg ("missing interface name or sw_if_index");
21596       return -99;
21597     }
21598   if (mac_set == 0)
21599     {
21600       errmsg ("missing remote mac address");
21601       return -99;
21602     }
21603
21604   M (P2P_ETHERNET_DEL, mp);
21605   mp->parent_if_index = ntohl (parent_if_index);
21606   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21607
21608   S (mp);
21609   W (ret);
21610   return ret;
21611 }
21612
21613 static int
21614 api_lldp_config (vat_main_t * vam)
21615 {
21616   unformat_input_t *i = vam->input;
21617   vl_api_lldp_config_t *mp;
21618   int tx_hold = 0;
21619   int tx_interval = 0;
21620   u8 *sys_name = NULL;
21621   int ret;
21622
21623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21624     {
21625       if (unformat (i, "system-name %s", &sys_name))
21626         ;
21627       else if (unformat (i, "tx-hold %d", &tx_hold))
21628         ;
21629       else if (unformat (i, "tx-interval %d", &tx_interval))
21630         ;
21631       else
21632         {
21633           clib_warning ("parse error '%U'", format_unformat_error, i);
21634           return -99;
21635         }
21636     }
21637
21638   vec_add1 (sys_name, 0);
21639
21640   M (LLDP_CONFIG, mp);
21641   mp->tx_hold = htonl (tx_hold);
21642   mp->tx_interval = htonl (tx_interval);
21643   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21644   vec_free (sys_name);
21645
21646   S (mp);
21647   W (ret);
21648   return ret;
21649 }
21650
21651 static int
21652 api_sw_interface_set_lldp (vat_main_t * vam)
21653 {
21654   unformat_input_t *i = vam->input;
21655   vl_api_sw_interface_set_lldp_t *mp;
21656   u32 sw_if_index = ~0;
21657   u32 enable = 1;
21658   u8 *port_desc = NULL, *mgmt_oid = NULL;
21659   ip4_address_t ip4_addr;
21660   ip6_address_t ip6_addr;
21661   int ret;
21662
21663   memset (&ip4_addr, 0, sizeof (ip4_addr));
21664   memset (&ip6_addr, 0, sizeof (ip6_addr));
21665
21666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21667     {
21668       if (unformat (i, "disable"))
21669         enable = 0;
21670       else
21671         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21672         ;
21673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21674         ;
21675       else if (unformat (i, "port-desc %s", &port_desc))
21676         ;
21677       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21678         ;
21679       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21680         ;
21681       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21682         ;
21683       else
21684         break;
21685     }
21686
21687   if (sw_if_index == ~0)
21688     {
21689       errmsg ("missing interface name or sw_if_index");
21690       return -99;
21691     }
21692
21693   /* Construct the API message */
21694   vec_add1 (port_desc, 0);
21695   vec_add1 (mgmt_oid, 0);
21696   M (SW_INTERFACE_SET_LLDP, mp);
21697   mp->sw_if_index = ntohl (sw_if_index);
21698   mp->enable = enable;
21699   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21700   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21701   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21702   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21703   vec_free (port_desc);
21704   vec_free (mgmt_oid);
21705
21706   S (mp);
21707   W (ret);
21708   return ret;
21709 }
21710
21711 static int
21712 api_tcp_configure_src_addresses (vat_main_t * vam)
21713 {
21714   vl_api_tcp_configure_src_addresses_t *mp;
21715   unformat_input_t *i = vam->input;
21716   ip4_address_t v4first, v4last;
21717   ip6_address_t v6first, v6last;
21718   u8 range_set = 0;
21719   u32 vrf_id = 0;
21720   int ret;
21721
21722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21723     {
21724       if (unformat (i, "%U - %U",
21725                     unformat_ip4_address, &v4first,
21726                     unformat_ip4_address, &v4last))
21727         {
21728           if (range_set)
21729             {
21730               errmsg ("one range per message (range already set)");
21731               return -99;
21732             }
21733           range_set = 1;
21734         }
21735       else if (unformat (i, "%U - %U",
21736                          unformat_ip6_address, &v6first,
21737                          unformat_ip6_address, &v6last))
21738         {
21739           if (range_set)
21740             {
21741               errmsg ("one range per message (range already set)");
21742               return -99;
21743             }
21744           range_set = 2;
21745         }
21746       else if (unformat (i, "vrf %d", &vrf_id))
21747         ;
21748       else
21749         break;
21750     }
21751
21752   if (range_set == 0)
21753     {
21754       errmsg ("address range not set");
21755       return -99;
21756     }
21757
21758   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21759   mp->vrf_id = ntohl (vrf_id);
21760   /* ipv6? */
21761   if (range_set == 2)
21762     {
21763       mp->is_ipv6 = 1;
21764       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21765       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21766     }
21767   else
21768     {
21769       mp->is_ipv6 = 0;
21770       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21771       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21772     }
21773   S (mp);
21774   W (ret);
21775   return ret;
21776 }
21777
21778 static void vl_api_app_namespace_add_del_reply_t_handler
21779   (vl_api_app_namespace_add_del_reply_t * mp)
21780 {
21781   vat_main_t *vam = &vat_main;
21782   i32 retval = ntohl (mp->retval);
21783   if (vam->async_mode)
21784     {
21785       vam->async_errors += (retval < 0);
21786     }
21787   else
21788     {
21789       vam->retval = retval;
21790       if (retval == 0)
21791         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21792       vam->result_ready = 1;
21793     }
21794 }
21795
21796 static void vl_api_app_namespace_add_del_reply_t_handler_json
21797   (vl_api_app_namespace_add_del_reply_t * mp)
21798 {
21799   vat_main_t *vam = &vat_main;
21800   vat_json_node_t node;
21801
21802   vat_json_init_object (&node);
21803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21804   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21805
21806   vat_json_print (vam->ofp, &node);
21807   vat_json_free (&node);
21808
21809   vam->retval = ntohl (mp->retval);
21810   vam->result_ready = 1;
21811 }
21812
21813 static int
21814 api_app_namespace_add_del (vat_main_t * vam)
21815 {
21816   vl_api_app_namespace_add_del_t *mp;
21817   unformat_input_t *i = vam->input;
21818   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21819   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21820   u64 secret;
21821   int ret;
21822
21823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21824     {
21825       if (unformat (i, "id %_%v%_", &ns_id))
21826         ;
21827       else if (unformat (i, "secret %lu", &secret))
21828         secret_set = 1;
21829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21830         sw_if_index_set = 1;
21831       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21832         ;
21833       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21834         ;
21835       else
21836         break;
21837     }
21838   if (!ns_id || !secret_set || !sw_if_index_set)
21839     {
21840       errmsg ("namespace id, secret and sw_if_index must be set");
21841       return -99;
21842     }
21843   if (vec_len (ns_id) > 64)
21844     {
21845       errmsg ("namespace id too long");
21846       return -99;
21847     }
21848   M (APP_NAMESPACE_ADD_DEL, mp);
21849
21850   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21851   mp->namespace_id_len = vec_len (ns_id);
21852   mp->secret = clib_host_to_net_u64 (secret);
21853   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21854   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21855   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21856   vec_free (ns_id);
21857   S (mp);
21858   W (ret);
21859   return ret;
21860 }
21861
21862 static int
21863 api_memfd_segment_create (vat_main_t * vam)
21864 {
21865 #if VPP_API_TEST_BUILTIN == 0
21866   unformat_input_t *i = vam->input;
21867   vl_api_memfd_segment_create_t *mp;
21868   u64 size = 64 << 20;
21869   int ret;
21870
21871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21872     {
21873       if (unformat (i, "size %U", unformat_memory_size, &size))
21874         ;
21875       else
21876         break;
21877     }
21878
21879   M (MEMFD_SEGMENT_CREATE, mp);
21880   mp->requested_size = size;
21881   S (mp);
21882   W (ret);
21883   return ret;
21884
21885 #else
21886   errmsg ("memfd_segment_create (builtin) not supported");
21887   return -99;
21888 #endif
21889 }
21890
21891 static int
21892 api_sock_init_shm (vat_main_t * vam)
21893 {
21894 #if VPP_API_TEST_BUILTIN == 0
21895   unformat_input_t *i = vam->input;
21896   vl_api_shm_elem_config_t *config = 0;
21897   u64 size = 64 << 20;
21898   int rv;
21899
21900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21901     {
21902       if (unformat (i, "size %U", unformat_memory_size, &size))
21903         ;
21904       else
21905         break;
21906     }
21907
21908   /* Try customized config to see if it works */
21909   vec_validate (config, 3);
21910   config[0].type = VL_API_VLIB_RING;
21911   config[0].count = 256;
21912   config[0].size = 256;
21913   config[1].type = VL_API_CLIENT_RING;
21914   config[1].count = 256;
21915   config[1].size = 1024;
21916   config[2].type = VL_API_CLIENT_RING;
21917   config[2].count = 8;
21918   config[2].size = 4096;
21919   config[3].type = VL_API_QUEUE;
21920   config[3].count = 256;
21921   config[3].size = sizeof (uword);
21922   rv = vl_socket_client_init_shm (config);
21923   if (!rv)
21924     vam->client_index_invalid = 1;
21925   return rv;
21926 #else
21927   return -99;
21928 #endif
21929 }
21930
21931 static int
21932 api_dns_enable_disable (vat_main_t * vam)
21933 {
21934   unformat_input_t *line_input = vam->input;
21935   vl_api_dns_enable_disable_t *mp;
21936   u8 enable_disable = 1;
21937   int ret;
21938
21939   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21940     {
21941       if (unformat (line_input, "disable"))
21942         enable_disable = 0;
21943       if (unformat (line_input, "enable"))
21944         enable_disable = 1;
21945       else
21946         break;
21947     }
21948
21949   /* Construct the API message */
21950   M (DNS_ENABLE_DISABLE, mp);
21951   mp->enable = enable_disable;
21952
21953   /* send it... */
21954   S (mp);
21955   /* Wait for the reply */
21956   W (ret);
21957   return ret;
21958 }
21959
21960 static int
21961 api_dns_resolve_name (vat_main_t * vam)
21962 {
21963   unformat_input_t *line_input = vam->input;
21964   vl_api_dns_resolve_name_t *mp;
21965   u8 *name = 0;
21966   int ret;
21967
21968   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21969     {
21970       if (unformat (line_input, "%s", &name))
21971         ;
21972       else
21973         break;
21974     }
21975
21976   if (vec_len (name) > 127)
21977     {
21978       errmsg ("name too long");
21979       return -99;
21980     }
21981
21982   /* Construct the API message */
21983   M (DNS_RESOLVE_NAME, mp);
21984   memcpy (mp->name, name, vec_len (name));
21985   vec_free (name);
21986
21987   /* send it... */
21988   S (mp);
21989   /* Wait for the reply */
21990   W (ret);
21991   return ret;
21992 }
21993
21994 static int
21995 api_dns_resolve_ip (vat_main_t * vam)
21996 {
21997   unformat_input_t *line_input = vam->input;
21998   vl_api_dns_resolve_ip_t *mp;
21999   int is_ip6 = -1;
22000   ip4_address_t addr4;
22001   ip6_address_t addr6;
22002   int ret;
22003
22004   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22005     {
22006       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22007         is_ip6 = 1;
22008       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22009         is_ip6 = 0;
22010       else
22011         break;
22012     }
22013
22014   if (is_ip6 == -1)
22015     {
22016       errmsg ("missing address");
22017       return -99;
22018     }
22019
22020   /* Construct the API message */
22021   M (DNS_RESOLVE_IP, mp);
22022   mp->is_ip6 = is_ip6;
22023   if (is_ip6)
22024     memcpy (mp->address, &addr6, sizeof (addr6));
22025   else
22026     memcpy (mp->address, &addr4, sizeof (addr4));
22027
22028   /* send it... */
22029   S (mp);
22030   /* Wait for the reply */
22031   W (ret);
22032   return ret;
22033 }
22034
22035 static int
22036 api_dns_name_server_add_del (vat_main_t * vam)
22037 {
22038   unformat_input_t *i = vam->input;
22039   vl_api_dns_name_server_add_del_t *mp;
22040   u8 is_add = 1;
22041   ip6_address_t ip6_server;
22042   ip4_address_t ip4_server;
22043   int ip6_set = 0;
22044   int ip4_set = 0;
22045   int ret = 0;
22046
22047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22048     {
22049       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22050         ip6_set = 1;
22051       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22052         ip4_set = 1;
22053       else if (unformat (i, "del"))
22054         is_add = 0;
22055       else
22056         {
22057           clib_warning ("parse error '%U'", format_unformat_error, i);
22058           return -99;
22059         }
22060     }
22061
22062   if (ip4_set && ip6_set)
22063     {
22064       errmsg ("Only one server address allowed per message");
22065       return -99;
22066     }
22067   if ((ip4_set + ip6_set) == 0)
22068     {
22069       errmsg ("Server address required");
22070       return -99;
22071     }
22072
22073   /* Construct the API message */
22074   M (DNS_NAME_SERVER_ADD_DEL, mp);
22075
22076   if (ip6_set)
22077     {
22078       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22079       mp->is_ip6 = 1;
22080     }
22081   else
22082     {
22083       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22084       mp->is_ip6 = 0;
22085     }
22086
22087   mp->is_add = is_add;
22088
22089   /* send it... */
22090   S (mp);
22091
22092   /* Wait for a reply, return good/bad news  */
22093   W (ret);
22094   return ret;
22095 }
22096
22097 static void
22098 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22099 {
22100   vat_main_t *vam = &vat_main;
22101
22102   if (mp->is_ip4)
22103     {
22104       print (vam->ofp,
22105              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22106              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22107              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22108              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22109              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22110              clib_net_to_host_u32 (mp->action_index), mp->tag);
22111     }
22112   else
22113     {
22114       print (vam->ofp,
22115              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22116              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22117              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22118              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22119              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22120              clib_net_to_host_u32 (mp->action_index), mp->tag);
22121     }
22122 }
22123
22124 static void
22125 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22126                                              mp)
22127 {
22128   vat_main_t *vam = &vat_main;
22129   vat_json_node_t *node = NULL;
22130   struct in6_addr ip6;
22131   struct in_addr ip4;
22132
22133   if (VAT_JSON_ARRAY != vam->json_tree.type)
22134     {
22135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22136       vat_json_init_array (&vam->json_tree);
22137     }
22138   node = vat_json_array_add (&vam->json_tree);
22139   vat_json_init_object (node);
22140
22141   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22142   vat_json_object_add_uint (node, "appns_index",
22143                             clib_net_to_host_u32 (mp->appns_index));
22144   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22145   vat_json_object_add_uint (node, "scope", mp->scope);
22146   vat_json_object_add_uint (node, "action_index",
22147                             clib_net_to_host_u32 (mp->action_index));
22148   vat_json_object_add_uint (node, "lcl_port",
22149                             clib_net_to_host_u16 (mp->lcl_port));
22150   vat_json_object_add_uint (node, "rmt_port",
22151                             clib_net_to_host_u16 (mp->rmt_port));
22152   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22153   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22154   vat_json_object_add_string_copy (node, "tag", mp->tag);
22155   if (mp->is_ip4)
22156     {
22157       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22158       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22159       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22160       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22161     }
22162   else
22163     {
22164       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22165       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22166       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22167       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22168     }
22169 }
22170
22171 static int
22172 api_session_rule_add_del (vat_main_t * vam)
22173 {
22174   vl_api_session_rule_add_del_t *mp;
22175   unformat_input_t *i = vam->input;
22176   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22177   u32 appns_index = 0, scope = 0;
22178   ip4_address_t lcl_ip4, rmt_ip4;
22179   ip6_address_t lcl_ip6, rmt_ip6;
22180   u8 is_ip4 = 1, conn_set = 0;
22181   u8 is_add = 1, *tag = 0;
22182   int ret;
22183
22184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22185     {
22186       if (unformat (i, "del"))
22187         is_add = 0;
22188       else if (unformat (i, "add"))
22189         ;
22190       else if (unformat (i, "proto tcp"))
22191         proto = 0;
22192       else if (unformat (i, "proto udp"))
22193         proto = 1;
22194       else if (unformat (i, "appns %d", &appns_index))
22195         ;
22196       else if (unformat (i, "scope %d", &scope))
22197         ;
22198       else if (unformat (i, "tag %_%v%_", &tag))
22199         ;
22200       else
22201         if (unformat
22202             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22203              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22204              &rmt_port))
22205         {
22206           is_ip4 = 1;
22207           conn_set = 1;
22208         }
22209       else
22210         if (unformat
22211             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22212              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22213              &rmt_port))
22214         {
22215           is_ip4 = 0;
22216           conn_set = 1;
22217         }
22218       else if (unformat (i, "action %d", &action))
22219         ;
22220       else
22221         break;
22222     }
22223   if (proto == ~0 || !conn_set || action == ~0)
22224     {
22225       errmsg ("transport proto, connection and action must be set");
22226       return -99;
22227     }
22228
22229   if (scope > 3)
22230     {
22231       errmsg ("scope should be 0-3");
22232       return -99;
22233     }
22234
22235   M (SESSION_RULE_ADD_DEL, mp);
22236
22237   mp->is_ip4 = is_ip4;
22238   mp->transport_proto = proto;
22239   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22240   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22241   mp->lcl_plen = lcl_plen;
22242   mp->rmt_plen = rmt_plen;
22243   mp->action_index = clib_host_to_net_u32 (action);
22244   mp->appns_index = clib_host_to_net_u32 (appns_index);
22245   mp->scope = scope;
22246   mp->is_add = is_add;
22247   if (is_ip4)
22248     {
22249       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22250       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22251     }
22252   else
22253     {
22254       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22255       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22256     }
22257   if (tag)
22258     {
22259       clib_memcpy (mp->tag, tag, vec_len (tag));
22260       vec_free (tag);
22261     }
22262
22263   S (mp);
22264   W (ret);
22265   return ret;
22266 }
22267
22268 static int
22269 api_session_rules_dump (vat_main_t * vam)
22270 {
22271   vl_api_session_rules_dump_t *mp;
22272   vl_api_control_ping_t *mp_ping;
22273   int ret;
22274
22275   if (!vam->json_output)
22276     {
22277       print (vam->ofp, "%=20s", "Session Rules");
22278     }
22279
22280   M (SESSION_RULES_DUMP, mp);
22281   /* send it... */
22282   S (mp);
22283
22284   /* Use a control ping for synchronization */
22285   MPING (CONTROL_PING, mp_ping);
22286   S (mp_ping);
22287
22288   /* Wait for a reply... */
22289   W (ret);
22290   return ret;
22291 }
22292
22293 static int
22294 api_ip_container_proxy_add_del (vat_main_t * vam)
22295 {
22296   vl_api_ip_container_proxy_add_del_t *mp;
22297   unformat_input_t *i = vam->input;
22298   u32 plen = ~0, sw_if_index = ~0;
22299   ip4_address_t ip4;
22300   ip6_address_t ip6;
22301   u8 is_ip4 = 1;
22302   u8 is_add = 1;
22303   int ret;
22304
22305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22306     {
22307       if (unformat (i, "del"))
22308         is_add = 0;
22309       else if (unformat (i, "add"))
22310         ;
22311       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22312         {
22313           is_ip4 = 1;
22314           plen = 32;
22315         }
22316       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22317         {
22318           is_ip4 = 0;
22319           plen = 128;
22320         }
22321       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22322         ;
22323       else
22324         break;
22325     }
22326   if (sw_if_index == ~0 || plen == ~0)
22327     {
22328       errmsg ("address and sw_if_index must be set");
22329       return -99;
22330     }
22331
22332   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22333
22334   mp->is_ip4 = is_ip4;
22335   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22336   mp->plen = plen;
22337   mp->is_add = is_add;
22338   if (is_ip4)
22339     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22340   else
22341     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22342
22343   S (mp);
22344   W (ret);
22345   return ret;
22346 }
22347
22348 static int
22349 q_or_quit (vat_main_t * vam)
22350 {
22351 #if VPP_API_TEST_BUILTIN == 0
22352   longjmp (vam->jump_buf, 1);
22353 #endif
22354   return 0;                     /* not so much */
22355 }
22356
22357 static int
22358 q (vat_main_t * vam)
22359 {
22360   return q_or_quit (vam);
22361 }
22362
22363 static int
22364 quit (vat_main_t * vam)
22365 {
22366   return q_or_quit (vam);
22367 }
22368
22369 static int
22370 comment (vat_main_t * vam)
22371 {
22372   return 0;
22373 }
22374
22375 static int
22376 cmd_cmp (void *a1, void *a2)
22377 {
22378   u8 **c1 = a1;
22379   u8 **c2 = a2;
22380
22381   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22382 }
22383
22384 static int
22385 help (vat_main_t * vam)
22386 {
22387   u8 **cmds = 0;
22388   u8 *name = 0;
22389   hash_pair_t *p;
22390   unformat_input_t *i = vam->input;
22391   int j;
22392
22393   if (unformat (i, "%s", &name))
22394     {
22395       uword *hs;
22396
22397       vec_add1 (name, 0);
22398
22399       hs = hash_get_mem (vam->help_by_name, name);
22400       if (hs)
22401         print (vam->ofp, "usage: %s %s", name, hs[0]);
22402       else
22403         print (vam->ofp, "No such msg / command '%s'", name);
22404       vec_free (name);
22405       return 0;
22406     }
22407
22408   print (vam->ofp, "Help is available for the following:");
22409
22410     /* *INDENT-OFF* */
22411     hash_foreach_pair (p, vam->function_by_name,
22412     ({
22413       vec_add1 (cmds, (u8 *)(p->key));
22414     }));
22415     /* *INDENT-ON* */
22416
22417   vec_sort_with_function (cmds, cmd_cmp);
22418
22419   for (j = 0; j < vec_len (cmds); j++)
22420     print (vam->ofp, "%s", cmds[j]);
22421
22422   vec_free (cmds);
22423   return 0;
22424 }
22425
22426 static int
22427 set (vat_main_t * vam)
22428 {
22429   u8 *name = 0, *value = 0;
22430   unformat_input_t *i = vam->input;
22431
22432   if (unformat (i, "%s", &name))
22433     {
22434       /* The input buffer is a vector, not a string. */
22435       value = vec_dup (i->buffer);
22436       vec_delete (value, i->index, 0);
22437       /* Almost certainly has a trailing newline */
22438       if (value[vec_len (value) - 1] == '\n')
22439         value[vec_len (value) - 1] = 0;
22440       /* Make sure it's a proper string, one way or the other */
22441       vec_add1 (value, 0);
22442       (void) clib_macro_set_value (&vam->macro_main,
22443                                    (char *) name, (char *) value);
22444     }
22445   else
22446     errmsg ("usage: set <name> <value>");
22447
22448   vec_free (name);
22449   vec_free (value);
22450   return 0;
22451 }
22452
22453 static int
22454 unset (vat_main_t * vam)
22455 {
22456   u8 *name = 0;
22457
22458   if (unformat (vam->input, "%s", &name))
22459     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22460       errmsg ("unset: %s wasn't set", name);
22461   vec_free (name);
22462   return 0;
22463 }
22464
22465 typedef struct
22466 {
22467   u8 *name;
22468   u8 *value;
22469 } macro_sort_t;
22470
22471
22472 static int
22473 macro_sort_cmp (void *a1, void *a2)
22474 {
22475   macro_sort_t *s1 = a1;
22476   macro_sort_t *s2 = a2;
22477
22478   return strcmp ((char *) (s1->name), (char *) (s2->name));
22479 }
22480
22481 static int
22482 dump_macro_table (vat_main_t * vam)
22483 {
22484   macro_sort_t *sort_me = 0, *sm;
22485   int i;
22486   hash_pair_t *p;
22487
22488     /* *INDENT-OFF* */
22489     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22490     ({
22491       vec_add2 (sort_me, sm, 1);
22492       sm->name = (u8 *)(p->key);
22493       sm->value = (u8 *) (p->value[0]);
22494     }));
22495     /* *INDENT-ON* */
22496
22497   vec_sort_with_function (sort_me, macro_sort_cmp);
22498
22499   if (vec_len (sort_me))
22500     print (vam->ofp, "%-15s%s", "Name", "Value");
22501   else
22502     print (vam->ofp, "The macro table is empty...");
22503
22504   for (i = 0; i < vec_len (sort_me); i++)
22505     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22506   return 0;
22507 }
22508
22509 static int
22510 dump_node_table (vat_main_t * vam)
22511 {
22512   int i, j;
22513   vlib_node_t *node, *next_node;
22514
22515   if (vec_len (vam->graph_nodes) == 0)
22516     {
22517       print (vam->ofp, "Node table empty, issue get_node_graph...");
22518       return 0;
22519     }
22520
22521   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22522     {
22523       node = vam->graph_nodes[i];
22524       print (vam->ofp, "[%d] %s", i, node->name);
22525       for (j = 0; j < vec_len (node->next_nodes); j++)
22526         {
22527           if (node->next_nodes[j] != ~0)
22528             {
22529               next_node = vam->graph_nodes[node->next_nodes[j]];
22530               print (vam->ofp, "  [%d] %s", j, next_node->name);
22531             }
22532         }
22533     }
22534   return 0;
22535 }
22536
22537 static int
22538 value_sort_cmp (void *a1, void *a2)
22539 {
22540   name_sort_t *n1 = a1;
22541   name_sort_t *n2 = a2;
22542
22543   if (n1->value < n2->value)
22544     return -1;
22545   if (n1->value > n2->value)
22546     return 1;
22547   return 0;
22548 }
22549
22550
22551 static int
22552 dump_msg_api_table (vat_main_t * vam)
22553 {
22554   api_main_t *am = &api_main;
22555   name_sort_t *nses = 0, *ns;
22556   hash_pair_t *hp;
22557   int i;
22558
22559   /* *INDENT-OFF* */
22560   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22561   ({
22562     vec_add2 (nses, ns, 1);
22563     ns->name = (u8 *)(hp->key);
22564     ns->value = (u32) hp->value[0];
22565   }));
22566   /* *INDENT-ON* */
22567
22568   vec_sort_with_function (nses, value_sort_cmp);
22569
22570   for (i = 0; i < vec_len (nses); i++)
22571     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22572   vec_free (nses);
22573   return 0;
22574 }
22575
22576 static int
22577 get_msg_id (vat_main_t * vam)
22578 {
22579   u8 *name_and_crc;
22580   u32 message_index;
22581
22582   if (unformat (vam->input, "%s", &name_and_crc))
22583     {
22584       message_index = vl_msg_api_get_msg_index (name_and_crc);
22585       if (message_index == ~0)
22586         {
22587           print (vam->ofp, " '%s' not found", name_and_crc);
22588           return 0;
22589         }
22590       print (vam->ofp, " '%s' has message index %d",
22591              name_and_crc, message_index);
22592       return 0;
22593     }
22594   errmsg ("name_and_crc required...");
22595   return 0;
22596 }
22597
22598 static int
22599 search_node_table (vat_main_t * vam)
22600 {
22601   unformat_input_t *line_input = vam->input;
22602   u8 *node_to_find;
22603   int j;
22604   vlib_node_t *node, *next_node;
22605   uword *p;
22606
22607   if (vam->graph_node_index_by_name == 0)
22608     {
22609       print (vam->ofp, "Node table empty, issue get_node_graph...");
22610       return 0;
22611     }
22612
22613   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22614     {
22615       if (unformat (line_input, "%s", &node_to_find))
22616         {
22617           vec_add1 (node_to_find, 0);
22618           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22619           if (p == 0)
22620             {
22621               print (vam->ofp, "%s not found...", node_to_find);
22622               goto out;
22623             }
22624           node = vam->graph_nodes[p[0]];
22625           print (vam->ofp, "[%d] %s", p[0], node->name);
22626           for (j = 0; j < vec_len (node->next_nodes); j++)
22627             {
22628               if (node->next_nodes[j] != ~0)
22629                 {
22630                   next_node = vam->graph_nodes[node->next_nodes[j]];
22631                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22632                 }
22633             }
22634         }
22635
22636       else
22637         {
22638           clib_warning ("parse error '%U'", format_unformat_error,
22639                         line_input);
22640           return -99;
22641         }
22642
22643     out:
22644       vec_free (node_to_find);
22645
22646     }
22647
22648   return 0;
22649 }
22650
22651
22652 static int
22653 script (vat_main_t * vam)
22654 {
22655 #if (VPP_API_TEST_BUILTIN==0)
22656   u8 *s = 0;
22657   char *save_current_file;
22658   unformat_input_t save_input;
22659   jmp_buf save_jump_buf;
22660   u32 save_line_number;
22661
22662   FILE *new_fp, *save_ifp;
22663
22664   if (unformat (vam->input, "%s", &s))
22665     {
22666       new_fp = fopen ((char *) s, "r");
22667       if (new_fp == 0)
22668         {
22669           errmsg ("Couldn't open script file %s", s);
22670           vec_free (s);
22671           return -99;
22672         }
22673     }
22674   else
22675     {
22676       errmsg ("Missing script name");
22677       return -99;
22678     }
22679
22680   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22681   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22682   save_ifp = vam->ifp;
22683   save_line_number = vam->input_line_number;
22684   save_current_file = (char *) vam->current_file;
22685
22686   vam->input_line_number = 0;
22687   vam->ifp = new_fp;
22688   vam->current_file = s;
22689   do_one_file (vam);
22690
22691   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22692   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22693   vam->ifp = save_ifp;
22694   vam->input_line_number = save_line_number;
22695   vam->current_file = (u8 *) save_current_file;
22696   vec_free (s);
22697
22698   return 0;
22699 #else
22700   clib_warning ("use the exec command...");
22701   return -99;
22702 #endif
22703 }
22704
22705 static int
22706 echo (vat_main_t * vam)
22707 {
22708   print (vam->ofp, "%v", vam->input->buffer);
22709   return 0;
22710 }
22711
22712 /* List of API message constructors, CLI names map to api_xxx */
22713 #define foreach_vpe_api_msg                                             \
22714 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22715 _(sw_interface_dump,"")                                                 \
22716 _(sw_interface_set_flags,                                               \
22717   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22718 _(sw_interface_add_del_address,                                         \
22719   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22720 _(sw_interface_set_rx_mode,                                             \
22721   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22722 _(sw_interface_set_table,                                               \
22723   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22724 _(sw_interface_set_mpls_enable,                                         \
22725   "<intfc> | sw_if_index [disable | dis]")                              \
22726 _(sw_interface_set_vpath,                                               \
22727   "<intfc> | sw_if_index <id> enable | disable")                        \
22728 _(sw_interface_set_vxlan_bypass,                                        \
22729   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22730 _(sw_interface_set_geneve_bypass,                                       \
22731   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22732 _(sw_interface_set_l2_xconnect,                                         \
22733   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22734   "enable | disable")                                                   \
22735 _(sw_interface_set_l2_bridge,                                           \
22736   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22737   "[shg <split-horizon-group>] [bvi]\n"                                 \
22738   "enable | disable")                                                   \
22739 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22740 _(bridge_domain_add_del,                                                \
22741   "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") \
22742 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22743 _(l2fib_add_del,                                                        \
22744   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22745 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22746 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22747 _(l2_flags,                                                             \
22748   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22749 _(bridge_flags,                                                         \
22750   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22751 _(tap_connect,                                                          \
22752   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22753 _(tap_modify,                                                           \
22754   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22755 _(tap_delete,                                                           \
22756   "<vpp-if-name> | sw_if_index <id>")                                   \
22757 _(sw_interface_tap_dump, "")                                            \
22758 _(tap_create_v2,                                                        \
22759   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22760 _(tap_delete_v2,                                                        \
22761   "<vpp-if-name> | sw_if_index <id>")                                   \
22762 _(sw_interface_tap_v2_dump, "")                                         \
22763 _(ip_table_add_del,                                                     \
22764   "table-id <n> [ipv6]\n")                                              \
22765 _(ip_add_del_route,                                                     \
22766   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22767   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22768   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22769   "[multipath] [count <n>]")                                            \
22770 _(ip_mroute_add_del,                                                    \
22771   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22772   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22773 _(mpls_table_add_del,                                                   \
22774   "table-id <n>\n")                                                     \
22775 _(mpls_route_add_del,                                                   \
22776   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22777   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22778   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22779   "[multipath] [count <n>]")                                            \
22780 _(mpls_ip_bind_unbind,                                                  \
22781   "<label> <addr/len>")                                                 \
22782 _(mpls_tunnel_add_del,                                                  \
22783   " via <addr> [table-id <n>]\n"                                        \
22784   "sw_if_index <id>] [l2]  [del]")                                      \
22785 _(bier_table_add_del,                                                   \
22786   "<label> <sub-domain> <set> <bsl> [del]")                             \
22787 _(bier_route_add_del,                                                   \
22788   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22789   "[<intfc> | sw_if_index <id>]"                                        \
22790   "[weight <n>] [del] [multipath]")                                     \
22791 _(proxy_arp_add_del,                                                    \
22792   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22793 _(proxy_arp_intfc_enable_disable,                                       \
22794   "<intfc> | sw_if_index <id> enable | disable")                        \
22795 _(sw_interface_set_unnumbered,                                          \
22796   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22797 _(ip_neighbor_add_del,                                                  \
22798   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22799   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22800 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22801 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22802   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22803   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22804   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22805 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22806 _(reset_fib, "vrf <n> [ipv6]")                                          \
22807 _(dhcp_proxy_config,                                                    \
22808   "svr <v46-address> src <v46-address>\n"                               \
22809    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22810 _(dhcp_proxy_set_vss,                                                   \
22811   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22812 _(dhcp_proxy_dump, "ip6")                                               \
22813 _(dhcp_client_config,                                                   \
22814   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22815 _(set_ip_flow_hash,                                                     \
22816   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22817 _(sw_interface_ip6_enable_disable,                                      \
22818   "<intfc> | sw_if_index <id> enable | disable")                        \
22819 _(sw_interface_ip6_set_link_local_address,                              \
22820   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22821 _(ip6nd_proxy_add_del,                                                  \
22822   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22823 _(ip6nd_proxy_dump, "")                                                 \
22824 _(sw_interface_ip6nd_ra_prefix,                                         \
22825   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22826   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22827   "[nolink] [isno]")                                                    \
22828 _(sw_interface_ip6nd_ra_config,                                         \
22829   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22830   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22831   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22832 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22833 _(l2_patch_add_del,                                                     \
22834   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22835   "enable | disable")                                                   \
22836 _(sr_localsid_add_del,                                                  \
22837   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22838   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22839 _(classify_add_del_table,                                               \
22840   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22841   " [del] [del-chain] mask <mask-value>\n"                              \
22842   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22843   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22844 _(classify_add_del_session,                                             \
22845   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22846   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22847   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22848   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22849 _(classify_set_interface_ip_table,                                      \
22850   "<intfc> | sw_if_index <nn> table <nn>")                              \
22851 _(classify_set_interface_l2_tables,                                     \
22852   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22853   "  [other-table <nn>]")                                               \
22854 _(get_node_index, "node <node-name")                                    \
22855 _(add_node_next, "node <node-name> next <next-node-name>")              \
22856 _(l2tpv3_create_tunnel,                                                 \
22857   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22858   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22859   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22860 _(l2tpv3_set_tunnel_cookies,                                            \
22861   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22862   "[new_remote_cookie <nn>]\n")                                         \
22863 _(l2tpv3_interface_enable_disable,                                      \
22864   "<intfc> | sw_if_index <nn> enable | disable")                        \
22865 _(l2tpv3_set_lookup_key,                                                \
22866   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22867 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22868 _(vxlan_add_del_tunnel,                                                 \
22869   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22870   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22871   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22872 _(geneve_add_del_tunnel,                                                \
22873   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22874   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22875   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22876 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22877 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22878 _(gre_add_del_tunnel,                                                   \
22879   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22880 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22881 _(l2_fib_clear_table, "")                                               \
22882 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22883 _(l2_interface_vlan_tag_rewrite,                                        \
22884   "<intfc> | sw_if_index <nn> \n"                                       \
22885   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22886   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22887 _(create_vhost_user_if,                                                 \
22888         "socket <filename> [server] [renumber <dev_instance>] "         \
22889         "[mac <mac_address>]")                                          \
22890 _(modify_vhost_user_if,                                                 \
22891         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22892         "[server] [renumber <dev_instance>]")                           \
22893 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22894 _(sw_interface_vhost_user_dump, "")                                     \
22895 _(show_version, "")                                                     \
22896 _(vxlan_gpe_add_del_tunnel,                                             \
22897   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22898   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22899   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22900   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22901 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22902 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22903 _(interface_name_renumber,                                              \
22904   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22905 _(input_acl_set_interface,                                              \
22906   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22907   "  [l2-table <nn>] [del]")                                            \
22908 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22909 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22910 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22911 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22912 _(ip_dump, "ipv4 | ipv6")                                               \
22913 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22914 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22915   "  spid_id <n> ")                                                     \
22916 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22917   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22918   "  integ_alg <alg> integ_key <hex>")                                  \
22919 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22920   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22921   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22922   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22923 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22924 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22925   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22926   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22927   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22928 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22929 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22930   "  <alg> <hex>\n")                                                    \
22931 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22932 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22933 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22934   "(auth_data 0x<data> | auth_data <data>)")                            \
22935 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22936   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22937 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22938   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22939   "(local|remote)")                                                     \
22940 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22941 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22942 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22943 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22944 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22945 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22946 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22947 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22948 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22949 _(delete_loopback,"sw_if_index <nn>")                                   \
22950 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22951 _(map_add_domain,                                                       \
22952   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22953   "ip6-src <ip6addr> "                                                  \
22954   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22955 _(map_del_domain, "index <n>")                                          \
22956 _(map_add_del_rule,                                                     \
22957   "index <n> psid <n> dst <ip6addr> [del]")                             \
22958 _(map_domain_dump, "")                                                  \
22959 _(map_rule_dump, "index <map-domain>")                                  \
22960 _(want_interface_events,  "enable|disable")                             \
22961 _(want_stats,"enable|disable")                                          \
22962 _(get_first_msg_id, "client <name>")                                    \
22963 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22964 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22965   "fib-id <nn> [ip4][ip6][default]")                                    \
22966 _(get_node_graph, " ")                                                  \
22967 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22968 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22969 _(ioam_disable, "")                                                     \
22970 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22971                             " sw_if_index <sw_if_index> p <priority> "  \
22972                             "w <weight>] [del]")                        \
22973 _(one_add_del_locator, "locator-set <locator_name> "                    \
22974                         "iface <intf> | sw_if_index <sw_if_index> "     \
22975                         "p <priority> w <weight> [del]")                \
22976 _(one_add_del_local_eid,"vni <vni> eid "                                \
22977                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22978                          "locator-set <locator_name> [del]"             \
22979                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22980 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22981 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22982 _(one_enable_disable, "enable|disable")                                 \
22983 _(one_map_register_enable_disable, "enable|disable")                    \
22984 _(one_map_register_fallback_threshold, "<value>")                       \
22985 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22986 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22987                                "[seid <seid>] "                         \
22988                                "rloc <locator> p <prio> "               \
22989                                "w <weight> [rloc <loc> ... ] "          \
22990                                "action <action> [del-all]")             \
22991 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22992                           "<local-eid>")                                \
22993 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22994 _(one_use_petr, "ip-address> | disable")                                \
22995 _(one_map_request_mode, "src-dst|dst-only")                             \
22996 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22997 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22998 _(one_locator_set_dump, "[local | remote]")                             \
22999 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23000 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23001                        "[local] | [remote]")                            \
23002 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23003 _(one_ndp_bd_get, "")                                                   \
23004 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23005 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23006 _(one_l2_arp_bd_get, "")                                                \
23007 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23008 _(one_stats_enable_disable, "enable|disalbe")                           \
23009 _(show_one_stats_enable_disable, "")                                    \
23010 _(one_eid_table_vni_dump, "")                                           \
23011 _(one_eid_table_map_dump, "l2|l3")                                      \
23012 _(one_map_resolver_dump, "")                                            \
23013 _(one_map_server_dump, "")                                              \
23014 _(one_adjacencies_get, "vni <vni>")                                     \
23015 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23016 _(show_one_rloc_probe_state, "")                                        \
23017 _(show_one_map_register_state, "")                                      \
23018 _(show_one_status, "")                                                  \
23019 _(one_stats_dump, "")                                                   \
23020 _(one_stats_flush, "")                                                  \
23021 _(one_get_map_request_itr_rlocs, "")                                    \
23022 _(one_map_register_set_ttl, "<ttl>")                                    \
23023 _(one_set_transport_protocol, "udp|api")                                \
23024 _(one_get_transport_protocol, "")                                       \
23025 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23026 _(one_show_xtr_mode, "")                                                \
23027 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23028 _(one_show_pitr_mode, "")                                               \
23029 _(one_enable_disable_petr_mode, "enable|disable")                       \
23030 _(one_show_petr_mode, "")                                               \
23031 _(show_one_nsh_mapping, "")                                             \
23032 _(show_one_pitr, "")                                                    \
23033 _(show_one_use_petr, "")                                                \
23034 _(show_one_map_request_mode, "")                                        \
23035 _(show_one_map_register_ttl, "")                                        \
23036 _(show_one_map_register_fallback_threshold, "")                         \
23037 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23038                             " sw_if_index <sw_if_index> p <priority> "  \
23039                             "w <weight>] [del]")                        \
23040 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23041                         "iface <intf> | sw_if_index <sw_if_index> "     \
23042                         "p <priority> w <weight> [del]")                \
23043 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23044                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23045                          "locator-set <locator_name> [del]"             \
23046                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23047 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23048 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23049 _(lisp_enable_disable, "enable|disable")                                \
23050 _(lisp_map_register_enable_disable, "enable|disable")                   \
23051 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23052 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23053                                "[seid <seid>] "                         \
23054                                "rloc <locator> p <prio> "               \
23055                                "w <weight> [rloc <loc> ... ] "          \
23056                                "action <action> [del-all]")             \
23057 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23058                           "<local-eid>")                                \
23059 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23060 _(lisp_use_petr, "<ip-address> | disable")                              \
23061 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23062 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23063 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23064 _(lisp_locator_set_dump, "[local | remote]")                            \
23065 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23066 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23067                        "[local] | [remote]")                            \
23068 _(lisp_eid_table_vni_dump, "")                                          \
23069 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23070 _(lisp_map_resolver_dump, "")                                           \
23071 _(lisp_map_server_dump, "")                                             \
23072 _(lisp_adjacencies_get, "vni <vni>")                                    \
23073 _(gpe_fwd_entry_vnis_get, "")                                           \
23074 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23075 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23076                                 "[table <table-id>]")                   \
23077 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23078 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23079 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23080 _(gpe_get_encap_mode, "")                                               \
23081 _(lisp_gpe_add_del_iface, "up|down")                                    \
23082 _(lisp_gpe_enable_disable, "enable|disable")                            \
23083 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23084   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23085 _(show_lisp_rloc_probe_state, "")                                       \
23086 _(show_lisp_map_register_state, "")                                     \
23087 _(show_lisp_status, "")                                                 \
23088 _(lisp_get_map_request_itr_rlocs, "")                                   \
23089 _(show_lisp_pitr, "")                                                   \
23090 _(show_lisp_use_petr, "")                                               \
23091 _(show_lisp_map_request_mode, "")                                       \
23092 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23093 _(af_packet_delete, "name <host interface name>")                       \
23094 _(policer_add_del, "name <policer name> <params> [del]")                \
23095 _(policer_dump, "[name <policer name>]")                                \
23096 _(policer_classify_set_interface,                                       \
23097   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23098   "  [l2-table <nn>] [del]")                                            \
23099 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23100 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23101     "[master|slave]")                                                   \
23102 _(netmap_delete, "name <interface name>")                               \
23103 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23104 _(mpls_fib_dump, "")                                                    \
23105 _(classify_table_ids, "")                                               \
23106 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23107 _(classify_table_info, "table_id <nn>")                                 \
23108 _(classify_session_dump, "table_id <nn>")                               \
23109 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23110     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23111     "[template_interval <nn>] [udp_checksum]")                          \
23112 _(ipfix_exporter_dump, "")                                              \
23113 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23114 _(ipfix_classify_stream_dump, "")                                       \
23115 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23116 _(ipfix_classify_table_dump, "")                                        \
23117 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23118 _(sw_interface_span_dump, "[l2]")                                           \
23119 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23120 _(pg_create_interface, "if_id <nn>")                                    \
23121 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23122 _(pg_enable_disable, "[stream <id>] disable")                           \
23123 _(ip_source_and_port_range_check_add_del,                               \
23124   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23125 _(ip_source_and_port_range_check_interface_add_del,                     \
23126   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23127   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23128 _(ipsec_gre_add_del_tunnel,                                             \
23129   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23130 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23131 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23132 _(l2_interface_pbb_tag_rewrite,                                         \
23133   "<intfc> | sw_if_index <nn> \n"                                       \
23134   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23135   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23136 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23137 _(flow_classify_set_interface,                                          \
23138   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23139 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23140 _(ip_fib_dump, "")                                                      \
23141 _(ip_mfib_dump, "")                                                     \
23142 _(ip6_fib_dump, "")                                                     \
23143 _(ip6_mfib_dump, "")                                                    \
23144 _(feature_enable_disable, "arc_name <arc_name> "                        \
23145   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23146 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23147 "[disable]")                                                            \
23148 _(l2_xconnect_dump, "")                                                 \
23149 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23150 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23151 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23152 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23153 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23154 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23155 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23156   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23157 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23158 _(memfd_segment_create,"size <nnn>")                                    \
23159 _(sock_init_shm, "size <nnn>")                                          \
23160 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23161 _(dns_enable_disable, "[enable][disable]")                              \
23162 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23163 _(dns_resolve_name, "<hostname>")                                       \
23164 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23165 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23166 _(dns_resolve_name, "<hostname>")                                       \
23167 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23168   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23169 _(session_rules_dump, "")                                               \
23170 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23171 _(output_acl_set_interface,                                             \
23172   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23173   "  [l2-table <nn>] [del]")                                            \
23174
23175 /* List of command functions, CLI names map directly to functions */
23176 #define foreach_cli_function                                    \
23177 _(comment, "usage: comment <ignore-rest-of-line>")              \
23178 _(dump_interface_table, "usage: dump_interface_table")          \
23179 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23180 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23181 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23182 _(dump_stats_table, "usage: dump_stats_table")                  \
23183 _(dump_macro_table, "usage: dump_macro_table ")                 \
23184 _(dump_node_table, "usage: dump_node_table")                    \
23185 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23186 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23187 _(echo, "usage: echo <message>")                                \
23188 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23189 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23190 _(help, "usage: help")                                          \
23191 _(q, "usage: quit")                                             \
23192 _(quit, "usage: quit")                                          \
23193 _(search_node_table, "usage: search_node_table <name>...")      \
23194 _(set, "usage: set <variable-name> <value>")                    \
23195 _(script, "usage: script <file-name>")                          \
23196 _(unset, "usage: unset <variable-name>")
23197 #define _(N,n)                                  \
23198     static void vl_api_##n##_t_handler_uni      \
23199     (vl_api_##n##_t * mp)                       \
23200     {                                           \
23201         vat_main_t * vam = &vat_main;           \
23202         if (vam->json_output) {                 \
23203             vl_api_##n##_t_handler_json(mp);    \
23204         } else {                                \
23205             vl_api_##n##_t_handler(mp);         \
23206         }                                       \
23207     }
23208 foreach_vpe_api_reply_msg;
23209 #if VPP_API_TEST_BUILTIN == 0
23210 foreach_standalone_reply_msg;
23211 #endif
23212 #undef _
23213
23214 void
23215 vat_api_hookup (vat_main_t * vam)
23216 {
23217 #define _(N,n)                                                  \
23218     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23219                            vl_api_##n##_t_handler_uni,          \
23220                            vl_noop_handler,                     \
23221                            vl_api_##n##_t_endian,               \
23222                            vl_api_##n##_t_print,                \
23223                            sizeof(vl_api_##n##_t), 1);
23224   foreach_vpe_api_reply_msg;
23225 #if VPP_API_TEST_BUILTIN == 0
23226   foreach_standalone_reply_msg;
23227 #endif
23228 #undef _
23229
23230 #if (VPP_API_TEST_BUILTIN==0)
23231   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23232
23233   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23234
23235   vam->function_by_name = hash_create_string (0, sizeof (uword));
23236
23237   vam->help_by_name = hash_create_string (0, sizeof (uword));
23238 #endif
23239
23240   /* API messages we can send */
23241 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23242   foreach_vpe_api_msg;
23243 #undef _
23244
23245   /* Help strings */
23246 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23247   foreach_vpe_api_msg;
23248 #undef _
23249
23250   /* CLI functions */
23251 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23252   foreach_cli_function;
23253 #undef _
23254
23255   /* Help strings */
23256 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23257   foreach_cli_function;
23258 #undef _
23259 }
23260
23261 #if VPP_API_TEST_BUILTIN
23262 static clib_error_t *
23263 vat_api_hookup_shim (vlib_main_t * vm)
23264 {
23265   vat_api_hookup (&vat_main);
23266   return 0;
23267 }
23268
23269 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23270 #endif
23271
23272 /*
23273  * fd.io coding-style-patch-verification: ON
23274  *
23275  * Local Variables:
23276  * eval: (c-set-style "gnu")
23277  * End:
23278  */