Improve l2_macs_events API to provide MAC move information
[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  action %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->action);
1354       if (i == 1000)
1355         break;
1356     }
1357 }
1358
1359 static void
1360 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1361 {
1362   /* JSON output not supported */
1363 }
1364
1365 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1366 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1367
1368 /*
1369  * Special-case: build the bridge domain table, maintain
1370  * the next bd id vbl.
1371  */
1372 static void vl_api_bridge_domain_details_t_handler
1373   (vl_api_bridge_domain_details_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1377   int i;
1378
1379   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1380          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1381
1382   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1383          ntohl (mp->bd_id), mp->learn, mp->forward,
1384          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1385
1386   if (n_sw_ifs)
1387     {
1388       vl_api_bridge_domain_sw_if_t *sw_ifs;
1389       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1390              "Interface Name");
1391
1392       sw_ifs = mp->sw_if_details;
1393       for (i = 0; i < n_sw_ifs; i++)
1394         {
1395           u8 *sw_if_name = 0;
1396           u32 sw_if_index;
1397           hash_pair_t *p;
1398
1399           sw_if_index = ntohl (sw_ifs->sw_if_index);
1400
1401           /* *INDENT-OFF* */
1402           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1403                              ({
1404                                if ((u32) p->value[0] == sw_if_index)
1405                                  {
1406                                    sw_if_name = (u8 *)(p->key);
1407                                    break;
1408                                  }
1409                              }));
1410           /* *INDENT-ON* */
1411           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1412                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1413                  "sw_if_index not found!");
1414
1415           sw_ifs++;
1416         }
1417     }
1418 }
1419
1420 static void vl_api_bridge_domain_details_t_handler_json
1421   (vl_api_bridge_domain_details_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   vat_json_node_t *node, *array = NULL;
1425   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1426
1427   if (VAT_JSON_ARRAY != vam->json_tree.type)
1428     {
1429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1430       vat_json_init_array (&vam->json_tree);
1431     }
1432   node = vat_json_array_add (&vam->json_tree);
1433
1434   vat_json_init_object (node);
1435   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1436   vat_json_object_add_uint (node, "flood", mp->flood);
1437   vat_json_object_add_uint (node, "forward", mp->forward);
1438   vat_json_object_add_uint (node, "learn", mp->learn);
1439   vat_json_object_add_uint (node, "bvi_sw_if_index",
1440                             ntohl (mp->bvi_sw_if_index));
1441   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1442   array = vat_json_object_add (node, "sw_if");
1443   vat_json_init_array (array);
1444
1445
1446
1447   if (n_sw_ifs)
1448     {
1449       vl_api_bridge_domain_sw_if_t *sw_ifs;
1450       int i;
1451
1452       sw_ifs = mp->sw_if_details;
1453       for (i = 0; i < n_sw_ifs; i++)
1454         {
1455           node = vat_json_array_add (array);
1456           vat_json_init_object (node);
1457           vat_json_object_add_uint (node, "sw_if_index",
1458                                     ntohl (sw_ifs->sw_if_index));
1459           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1460           sw_ifs++;
1461         }
1462     }
1463 }
1464
1465 static void vl_api_control_ping_reply_t_handler
1466   (vl_api_control_ping_reply_t * mp)
1467 {
1468   vat_main_t *vam = &vat_main;
1469   i32 retval = ntohl (mp->retval);
1470   if (vam->async_mode)
1471     {
1472       vam->async_errors += (retval < 0);
1473     }
1474   else
1475     {
1476       vam->retval = retval;
1477       vam->result_ready = 1;
1478     }
1479   if (vam->socket_client_main)
1480     vam->socket_client_main->control_pings_outstanding--;
1481 }
1482
1483 static void vl_api_control_ping_reply_t_handler_json
1484   (vl_api_control_ping_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488
1489   if (VAT_JSON_NONE != vam->json_tree.type)
1490     {
1491       vat_json_print (vam->ofp, &vam->json_tree);
1492       vat_json_free (&vam->json_tree);
1493       vam->json_tree.type = VAT_JSON_NONE;
1494     }
1495   else
1496     {
1497       /* just print [] */
1498       vat_json_init_array (&vam->json_tree);
1499       vat_json_print (vam->ofp, &vam->json_tree);
1500       vam->json_tree.type = VAT_JSON_NONE;
1501     }
1502
1503   vam->retval = retval;
1504   vam->result_ready = 1;
1505 }
1506
1507 static void
1508   vl_api_bridge_domain_set_mac_age_reply_t_handler
1509   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1525   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void
1541 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2_flags_reply_t_handler_json
1557   (vl_api_l2_flags_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1565                             ntohl (mp->resulting_feature_bitmap));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_bridge_flags_reply_t_handler
1575   (vl_api_bridge_flags_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_bridge_flags_reply_t_handler_json
1591   (vl_api_bridge_flags_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1599                             ntohl (mp->resulting_feature_bitmap));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_tap_connect_reply_t_handler
1609   (vl_api_tap_connect_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623
1624 }
1625
1626 static void vl_api_tap_connect_reply_t_handler_json
1627   (vl_api_tap_connect_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641
1642 }
1643
1644 static void
1645 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_tap_modify_reply_t_handler_json
1662   (vl_api_tap_modify_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void
1679 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   i32 retval = ntohl (mp->retval);
1683   if (vam->async_mode)
1684     {
1685       vam->async_errors += (retval < 0);
1686     }
1687   else
1688     {
1689       vam->retval = retval;
1690       vam->result_ready = 1;
1691     }
1692 }
1693
1694 static void vl_api_tap_delete_reply_t_handler_json
1695   (vl_api_tap_delete_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   vat_json_node_t node;
1699
1700   vat_json_init_object (&node);
1701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void
1711 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   i32 retval = ntohl (mp->retval);
1715   if (vam->async_mode)
1716     {
1717       vam->async_errors += (retval < 0);
1718     }
1719   else
1720     {
1721       vam->retval = retval;
1722       vam->sw_if_index = ntohl (mp->sw_if_index);
1723       vam->result_ready = 1;
1724     }
1725
1726 }
1727
1728 static void vl_api_tap_create_v2_reply_t_handler_json
1729   (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   vat_json_node_t node;
1733
1734   vat_json_init_object (&node);
1735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1736   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1737
1738   vat_json_print (vam->ofp, &node);
1739   vat_json_free (&node);
1740
1741   vam->retval = ntohl (mp->retval);
1742   vam->result_ready = 1;
1743
1744 }
1745
1746 static void
1747 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   i32 retval = ntohl (mp->retval);
1751   if (vam->async_mode)
1752     {
1753       vam->async_errors += (retval < 0);
1754     }
1755   else
1756     {
1757       vam->retval = retval;
1758       vam->result_ready = 1;
1759     }
1760 }
1761
1762 static void vl_api_tap_delete_v2_reply_t_handler_json
1763   (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   vat_json_node_t node;
1767
1768   vat_json_init_object (&node);
1769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1770
1771   vat_json_print (vam->ofp, &node);
1772   vat_json_free (&node);
1773
1774   vam->retval = ntohl (mp->retval);
1775   vam->result_ready = 1;
1776 }
1777
1778 static void 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   u32 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 %u", &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 = ntohl (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 = ntohs (rx_ring_sz);
7884   mp->tx_ring_sz = ntohs (tx_ring_sz);
7885
7886   if (random_mac == 0)
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_path_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].label = ntohl (next_hop_out_label);
8885   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8886
8887   if (next_hop_proto_is_ip4)
8888     {
8889       clib_memcpy (mp->br_paths[0].next_hop,
8890                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8891     }
8892   else
8893     {
8894       clib_memcpy (mp->br_paths[0].next_hop,
8895                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8896     }
8897
8898   /* send it... */
8899   S (mp);
8900
8901   /* Wait for a reply... */
8902   W (ret);
8903
8904   return (ret);
8905 }
8906
8907 static int
8908 api_proxy_arp_add_del (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_proxy_arp_add_del_t *mp;
8912   u32 vrf_id = 0;
8913   u8 is_add = 1;
8914   ip4_address_t lo, hi;
8915   u8 range_set = 0;
8916   int ret;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "vrf %d", &vrf_id))
8921         ;
8922       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8923                          unformat_ip4_address, &hi))
8924         range_set = 1;
8925       else if (unformat (i, "del"))
8926         is_add = 0;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (range_set == 0)
8935     {
8936       errmsg ("address range not set");
8937       return -99;
8938     }
8939
8940   M (PROXY_ARP_ADD_DEL, mp);
8941
8942   mp->vrf_id = ntohl (vrf_id);
8943   mp->is_add = is_add;
8944   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8945   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8946
8947   S (mp);
8948   W (ret);
8949   return ret;
8950 }
8951
8952 static int
8953 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8957   u32 sw_if_index;
8958   u8 enable = 1;
8959   u8 sw_if_index_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "enable"))
8969         enable = 1;
8970       else if (unformat (i, "disable"))
8971         enable = 0;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index_set == 0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984
8985   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->enable_disable = enable;
8989
8990   S (mp);
8991   W (ret);
8992   return ret;
8993 }
8994
8995 static int
8996 api_mpls_tunnel_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_mpls_tunnel_add_del_t *mp;
9000
9001   u8 is_add = 1;
9002   u8 l2_only = 0;
9003   u32 sw_if_index = ~0;
9004   u32 next_hop_sw_if_index = ~0;
9005   u32 next_hop_proto_is_ip4 = 1;
9006
9007   u32 next_hop_table_id = 0;
9008   ip4_address_t v4_next_hop_address = {
9009     .as_u32 = 0,
9010   };
9011   ip6_address_t v6_next_hop_address = { {0} };
9012   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9013   int ret;
9014
9015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9016     {
9017       if (unformat (i, "add"))
9018         is_add = 1;
9019       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9020         is_add = 0;
9021       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9022         ;
9023       else if (unformat (i, "via %U",
9024                          unformat_ip4_address, &v4_next_hop_address))
9025         {
9026           next_hop_proto_is_ip4 = 1;
9027         }
9028       else if (unformat (i, "via %U",
9029                          unformat_ip6_address, &v6_next_hop_address))
9030         {
9031           next_hop_proto_is_ip4 = 0;
9032         }
9033       else if (unformat (i, "l2-only"))
9034         l2_only = 1;
9035       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9036         ;
9037       else if (unformat (i, "out-label %d", &next_hop_out_label))
9038         vec_add1 (labels, ntohl (next_hop_out_label));
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9047
9048   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9049   mp->mt_sw_if_index = ntohl (sw_if_index);
9050   mp->mt_is_add = is_add;
9051   mp->mt_l2_only = l2_only;
9052   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9053   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9054
9055   mp->mt_next_hop_n_out_labels = vec_len (labels);
9056
9057   if (0 != mp->mt_next_hop_n_out_labels)
9058     {
9059       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9060                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9061       vec_free (labels);
9062     }
9063
9064   if (next_hop_proto_is_ip4)
9065     {
9066       clib_memcpy (mp->mt_next_hop,
9067                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9068     }
9069   else
9070     {
9071       clib_memcpy (mp->mt_next_hop,
9072                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9073     }
9074
9075   S (mp);
9076   W (ret);
9077   return ret;
9078 }
9079
9080 static int
9081 api_sw_interface_set_unnumbered (vat_main_t * vam)
9082 {
9083   unformat_input_t *i = vam->input;
9084   vl_api_sw_interface_set_unnumbered_t *mp;
9085   u32 sw_if_index;
9086   u32 unnum_sw_index = ~0;
9087   u8 is_add = 1;
9088   u8 sw_if_index_set = 0;
9089   int ret;
9090
9091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9094         sw_if_index_set = 1;
9095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9096         sw_if_index_set = 1;
9097       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9098         ;
9099       else if (unformat (i, "del"))
9100         is_add = 0;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (sw_if_index_set == 0)
9109     {
9110       errmsg ("missing interface name or sw_if_index");
9111       return -99;
9112     }
9113
9114   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9115
9116   mp->sw_if_index = ntohl (sw_if_index);
9117   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9118   mp->is_add = is_add;
9119
9120   S (mp);
9121   W (ret);
9122   return ret;
9123 }
9124
9125 static int
9126 api_ip_neighbor_add_del (vat_main_t * vam)
9127 {
9128   unformat_input_t *i = vam->input;
9129   vl_api_ip_neighbor_add_del_t *mp;
9130   u32 sw_if_index;
9131   u8 sw_if_index_set = 0;
9132   u8 is_add = 1;
9133   u8 is_static = 0;
9134   u8 is_no_fib_entry = 0;
9135   u8 mac_address[6];
9136   u8 mac_set = 0;
9137   u8 v4_address_set = 0;
9138   u8 v6_address_set = 0;
9139   ip4_address_t v4address;
9140   ip6_address_t v6address;
9141   int ret;
9142
9143   memset (mac_address, 0, sizeof (mac_address));
9144
9145   /* Parse args required to build the message */
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9149         {
9150           mac_set = 1;
9151         }
9152       else if (unformat (i, "del"))
9153         is_add = 0;
9154       else
9155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "is_static"))
9160         is_static = 1;
9161       else if (unformat (i, "no-fib-entry"))
9162         is_no_fib_entry = 1;
9163       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9164         v4_address_set = 1;
9165       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9166         v6_address_set = 1;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179   if (v4_address_set && v6_address_set)
9180     {
9181       errmsg ("both v4 and v6 addresses set");
9182       return -99;
9183     }
9184   if (!v4_address_set && !v6_address_set)
9185     {
9186       errmsg ("no address set");
9187       return -99;
9188     }
9189
9190   /* Construct the API message */
9191   M (IP_NEIGHBOR_ADD_DEL, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->is_add = is_add;
9195   mp->is_static = is_static;
9196   mp->is_no_adj_fib = is_no_fib_entry;
9197   if (mac_set)
9198     clib_memcpy (mp->mac_address, mac_address, 6);
9199   if (v6_address_set)
9200     {
9201       mp->is_ipv6 = 1;
9202       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9203     }
9204   else
9205     {
9206       /* mp->is_ipv6 = 0; via memset in M macro above */
9207       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9208     }
9209
9210   /* send it... */
9211   S (mp);
9212
9213   /* Wait for a reply, return good/bad news  */
9214   W (ret);
9215   return ret;
9216 }
9217
9218 static int
9219 api_create_vlan_subif (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_create_vlan_subif_t *mp;
9223   u32 sw_if_index;
9224   u8 sw_if_index_set = 0;
9225   u32 vlan_id;
9226   u8 vlan_id_set = 0;
9227   int ret;
9228
9229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9230     {
9231       if (unformat (i, "sw_if_index %d", &sw_if_index))
9232         sw_if_index_set = 1;
9233       else
9234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9235         sw_if_index_set = 1;
9236       else if (unformat (i, "vlan %d", &vlan_id))
9237         vlan_id_set = 1;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (sw_if_index_set == 0)
9246     {
9247       errmsg ("missing interface name or sw_if_index");
9248       return -99;
9249     }
9250
9251   if (vlan_id_set == 0)
9252     {
9253       errmsg ("missing vlan_id");
9254       return -99;
9255     }
9256   M (CREATE_VLAN_SUBIF, mp);
9257
9258   mp->sw_if_index = ntohl (sw_if_index);
9259   mp->vlan_id = ntohl (vlan_id);
9260
9261   S (mp);
9262   W (ret);
9263   return ret;
9264 }
9265
9266 #define foreach_create_subif_bit                \
9267 _(no_tags)                                      \
9268 _(one_tag)                                      \
9269 _(two_tags)                                     \
9270 _(dot1ad)                                       \
9271 _(exact_match)                                  \
9272 _(default_sub)                                  \
9273 _(outer_vlan_id_any)                            \
9274 _(inner_vlan_id_any)
9275
9276 static int
9277 api_create_subif (vat_main_t * vam)
9278 {
9279   unformat_input_t *i = vam->input;
9280   vl_api_create_subif_t *mp;
9281   u32 sw_if_index;
9282   u8 sw_if_index_set = 0;
9283   u32 sub_id;
9284   u8 sub_id_set = 0;
9285   u32 no_tags = 0;
9286   u32 one_tag = 0;
9287   u32 two_tags = 0;
9288   u32 dot1ad = 0;
9289   u32 exact_match = 0;
9290   u32 default_sub = 0;
9291   u32 outer_vlan_id_any = 0;
9292   u32 inner_vlan_id_any = 0;
9293   u32 tmp;
9294   u16 outer_vlan_id = 0;
9295   u16 inner_vlan_id = 0;
9296   int ret;
9297
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "sw_if_index %d", &sw_if_index))
9301         sw_if_index_set = 1;
9302       else
9303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "sub_id %d", &sub_id))
9306         sub_id_set = 1;
9307       else if (unformat (i, "outer_vlan_id %d", &tmp))
9308         outer_vlan_id = tmp;
9309       else if (unformat (i, "inner_vlan_id %d", &tmp))
9310         inner_vlan_id = tmp;
9311
9312 #define _(a) else if (unformat (i, #a)) a = 1 ;
9313       foreach_create_subif_bit
9314 #undef _
9315         else
9316         {
9317           clib_warning ("parse error '%U'", format_unformat_error, i);
9318           return -99;
9319         }
9320     }
9321
9322   if (sw_if_index_set == 0)
9323     {
9324       errmsg ("missing interface name or sw_if_index");
9325       return -99;
9326     }
9327
9328   if (sub_id_set == 0)
9329     {
9330       errmsg ("missing sub_id");
9331       return -99;
9332     }
9333   M (CREATE_SUBIF, mp);
9334
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->sub_id = ntohl (sub_id);
9337
9338 #define _(a) mp->a = a;
9339   foreach_create_subif_bit;
9340 #undef _
9341
9342   mp->outer_vlan_id = ntohs (outer_vlan_id);
9343   mp->inner_vlan_id = ntohs (inner_vlan_id);
9344
9345   S (mp);
9346   W (ret);
9347   return ret;
9348 }
9349
9350 static int
9351 api_oam_add_del (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_oam_add_del_t *mp;
9355   u32 vrf_id = 0;
9356   u8 is_add = 1;
9357   ip4_address_t src, dst;
9358   u8 src_set = 0;
9359   u8 dst_set = 0;
9360   int ret;
9361
9362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (i, "vrf %d", &vrf_id))
9365         ;
9366       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9367         src_set = 1;
9368       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9369         dst_set = 1;
9370       else if (unformat (i, "del"))
9371         is_add = 0;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (src_set == 0)
9380     {
9381       errmsg ("missing src addr");
9382       return -99;
9383     }
9384
9385   if (dst_set == 0)
9386     {
9387       errmsg ("missing dst addr");
9388       return -99;
9389     }
9390
9391   M (OAM_ADD_DEL, mp);
9392
9393   mp->vrf_id = ntohl (vrf_id);
9394   mp->is_add = is_add;
9395   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9396   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_reset_fib (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_reset_fib_t *mp;
9408   u32 vrf_id = 0;
9409   u8 is_ipv6 = 0;
9410   u8 vrf_id_set = 0;
9411
9412   int ret;
9413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (i, "vrf %d", &vrf_id))
9416         vrf_id_set = 1;
9417       else if (unformat (i, "ipv6"))
9418         is_ipv6 = 1;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (vrf_id_set == 0)
9427     {
9428       errmsg ("missing vrf id");
9429       return -99;
9430     }
9431
9432   M (RESET_FIB, mp);
9433
9434   mp->vrf_id = ntohl (vrf_id);
9435   mp->is_ipv6 = is_ipv6;
9436
9437   S (mp);
9438   W (ret);
9439   return ret;
9440 }
9441
9442 static int
9443 api_dhcp_proxy_config (vat_main_t * vam)
9444 {
9445   unformat_input_t *i = vam->input;
9446   vl_api_dhcp_proxy_config_t *mp;
9447   u32 rx_vrf_id = 0;
9448   u32 server_vrf_id = 0;
9449   u8 is_add = 1;
9450   u8 v4_address_set = 0;
9451   u8 v6_address_set = 0;
9452   ip4_address_t v4address;
9453   ip6_address_t v6address;
9454   u8 v4_src_address_set = 0;
9455   u8 v6_src_address_set = 0;
9456   ip4_address_t v4srcaddress;
9457   ip6_address_t v6srcaddress;
9458   int ret;
9459
9460   /* Parse args required to build the message */
9461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (i, "del"))
9464         is_add = 0;
9465       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9466         ;
9467       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9468         ;
9469       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9470         v4_address_set = 1;
9471       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9472         v6_address_set = 1;
9473       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9474         v4_src_address_set = 1;
9475       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9476         v6_src_address_set = 1;
9477       else
9478         break;
9479     }
9480
9481   if (v4_address_set && v6_address_set)
9482     {
9483       errmsg ("both v4 and v6 server addresses set");
9484       return -99;
9485     }
9486   if (!v4_address_set && !v6_address_set)
9487     {
9488       errmsg ("no server addresses set");
9489       return -99;
9490     }
9491
9492   if (v4_src_address_set && v6_src_address_set)
9493     {
9494       errmsg ("both v4 and v6  src addresses set");
9495       return -99;
9496     }
9497   if (!v4_src_address_set && !v6_src_address_set)
9498     {
9499       errmsg ("no src addresses set");
9500       return -99;
9501     }
9502
9503   if (!(v4_src_address_set && v4_address_set) &&
9504       !(v6_src_address_set && v6_address_set))
9505     {
9506       errmsg ("no matching server and src addresses set");
9507       return -99;
9508     }
9509
9510   /* Construct the API message */
9511   M (DHCP_PROXY_CONFIG, mp);
9512
9513   mp->is_add = is_add;
9514   mp->rx_vrf_id = ntohl (rx_vrf_id);
9515   mp->server_vrf_id = ntohl (server_vrf_id);
9516   if (v6_address_set)
9517     {
9518       mp->is_ipv6 = 1;
9519       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9520       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9521     }
9522   else
9523     {
9524       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9525       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9526     }
9527
9528   /* send it... */
9529   S (mp);
9530
9531   /* Wait for a reply, return good/bad news  */
9532   W (ret);
9533   return ret;
9534 }
9535
9536 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9537 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9538
9539 static void
9540 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9541 {
9542   vat_main_t *vam = &vat_main;
9543   u32 i, count = mp->count;
9544   vl_api_dhcp_server_t *s;
9545
9546   if (mp->is_ipv6)
9547     print (vam->ofp,
9548            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9549            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9550            ntohl (mp->rx_vrf_id),
9551            format_ip6_address, mp->dhcp_src_address,
9552            mp->vss_type, mp->vss_vpn_ascii_id,
9553            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9554   else
9555     print (vam->ofp,
9556            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9557            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9558            ntohl (mp->rx_vrf_id),
9559            format_ip4_address, mp->dhcp_src_address,
9560            mp->vss_type, mp->vss_vpn_ascii_id,
9561            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9562
9563   for (i = 0; i < count; i++)
9564     {
9565       s = &mp->servers[i];
9566
9567       if (mp->is_ipv6)
9568         print (vam->ofp,
9569                " Server Table-ID %d, Server Address %U",
9570                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9571       else
9572         print (vam->ofp,
9573                " Server Table-ID %d, Server Address %U",
9574                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9575     }
9576 }
9577
9578 static void vl_api_dhcp_proxy_details_t_handler_json
9579   (vl_api_dhcp_proxy_details_t * mp)
9580 {
9581   vat_main_t *vam = &vat_main;
9582   vat_json_node_t *node = NULL;
9583   u32 i, count = mp->count;
9584   struct in_addr ip4;
9585   struct in6_addr ip6;
9586   vl_api_dhcp_server_t *s;
9587
9588   if (VAT_JSON_ARRAY != vam->json_tree.type)
9589     {
9590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9591       vat_json_init_array (&vam->json_tree);
9592     }
9593   node = vat_json_array_add (&vam->json_tree);
9594
9595   vat_json_init_object (node);
9596   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9597   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9598                              sizeof (mp->vss_type));
9599   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9600                                    mp->vss_vpn_ascii_id);
9601   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9602   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9603
9604   if (mp->is_ipv6)
9605     {
9606       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9607       vat_json_object_add_ip6 (node, "src_address", ip6);
9608     }
9609   else
9610     {
9611       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9612       vat_json_object_add_ip4 (node, "src_address", ip4);
9613     }
9614
9615   for (i = 0; i < count; i++)
9616     {
9617       s = &mp->servers[i];
9618
9619       vat_json_object_add_uint (node, "server-table-id",
9620                                 ntohl (s->server_vrf_id));
9621
9622       if (mp->is_ipv6)
9623         {
9624           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9625           vat_json_object_add_ip4 (node, "src_address", ip4);
9626         }
9627       else
9628         {
9629           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9630           vat_json_object_add_ip6 (node, "server_address", ip6);
9631         }
9632     }
9633 }
9634
9635 static int
9636 api_dhcp_proxy_dump (vat_main_t * vam)
9637 {
9638   unformat_input_t *i = vam->input;
9639   vl_api_control_ping_t *mp_ping;
9640   vl_api_dhcp_proxy_dump_t *mp;
9641   u8 is_ipv6 = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "ipv6"))
9647         is_ipv6 = 1;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   M (DHCP_PROXY_DUMP, mp);
9656
9657   mp->is_ip6 = is_ipv6;
9658   S (mp);
9659
9660   /* Use a control ping for synchronization */
9661   MPING (CONTROL_PING, mp_ping);
9662   S (mp_ping);
9663
9664   W (ret);
9665   return ret;
9666 }
9667
9668 static int
9669 api_dhcp_proxy_set_vss (vat_main_t * vam)
9670 {
9671   unformat_input_t *i = vam->input;
9672   vl_api_dhcp_proxy_set_vss_t *mp;
9673   u8 is_ipv6 = 0;
9674   u8 is_add = 1;
9675   u32 tbl_id = ~0;
9676   u8 vss_type = VSS_TYPE_DEFAULT;
9677   u8 *vpn_ascii_id = 0;
9678   u32 oui = 0;
9679   u32 fib_id = 0;
9680   int ret;
9681
9682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (i, "tbl_id %d", &tbl_id))
9685         ;
9686       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9687         vss_type = VSS_TYPE_ASCII;
9688       else if (unformat (i, "fib_id %d", &fib_id))
9689         vss_type = VSS_TYPE_VPN_ID;
9690       else if (unformat (i, "oui %d", &oui))
9691         vss_type = VSS_TYPE_VPN_ID;
9692       else if (unformat (i, "ipv6"))
9693         is_ipv6 = 1;
9694       else if (unformat (i, "del"))
9695         is_add = 0;
9696       else
9697         break;
9698     }
9699
9700   if (tbl_id == ~0)
9701     {
9702       errmsg ("missing tbl_id ");
9703       vec_free (vpn_ascii_id);
9704       return -99;
9705     }
9706
9707   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9708     {
9709       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9710       vec_free (vpn_ascii_id);
9711       return -99;
9712     }
9713
9714   M (DHCP_PROXY_SET_VSS, mp);
9715   mp->tbl_id = ntohl (tbl_id);
9716   mp->vss_type = vss_type;
9717   if (vpn_ascii_id)
9718     {
9719       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9720       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9721     }
9722   mp->vpn_index = ntohl (fib_id);
9723   mp->oui = ntohl (oui);
9724   mp->is_ipv6 = is_ipv6;
9725   mp->is_add = is_add;
9726
9727   S (mp);
9728   W (ret);
9729
9730   vec_free (vpn_ascii_id);
9731   return ret;
9732 }
9733
9734 static int
9735 api_dhcp_client_config (vat_main_t * vam)
9736 {
9737   unformat_input_t *i = vam->input;
9738   vl_api_dhcp_client_config_t *mp;
9739   u32 sw_if_index;
9740   u8 sw_if_index_set = 0;
9741   u8 is_add = 1;
9742   u8 *hostname = 0;
9743   u8 disable_event = 0;
9744   int ret;
9745
9746   /* Parse args required to build the message */
9747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (i, "del"))
9750         is_add = 0;
9751       else
9752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9753         sw_if_index_set = 1;
9754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9755         sw_if_index_set = 1;
9756       else if (unformat (i, "hostname %s", &hostname))
9757         ;
9758       else if (unformat (i, "disable_event"))
9759         disable_event = 1;
9760       else
9761         break;
9762     }
9763
9764   if (sw_if_index_set == 0)
9765     {
9766       errmsg ("missing interface name or sw_if_index");
9767       return -99;
9768     }
9769
9770   if (vec_len (hostname) > 63)
9771     {
9772       errmsg ("hostname too long");
9773     }
9774   vec_add1 (hostname, 0);
9775
9776   /* Construct the API message */
9777   M (DHCP_CLIENT_CONFIG, mp);
9778
9779   mp->sw_if_index = htonl (sw_if_index);
9780   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9781   vec_free (hostname);
9782   mp->is_add = is_add;
9783   mp->want_dhcp_event = disable_event ? 0 : 1;
9784   mp->pid = htonl (getpid ());
9785
9786   /* send it... */
9787   S (mp);
9788
9789   /* Wait for a reply, return good/bad news  */
9790   W (ret);
9791   return ret;
9792 }
9793
9794 static int
9795 api_set_ip_flow_hash (vat_main_t * vam)
9796 {
9797   unformat_input_t *i = vam->input;
9798   vl_api_set_ip_flow_hash_t *mp;
9799   u32 vrf_id = 0;
9800   u8 is_ipv6 = 0;
9801   u8 vrf_id_set = 0;
9802   u8 src = 0;
9803   u8 dst = 0;
9804   u8 sport = 0;
9805   u8 dport = 0;
9806   u8 proto = 0;
9807   u8 reverse = 0;
9808   int ret;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "vrf %d", &vrf_id))
9813         vrf_id_set = 1;
9814       else if (unformat (i, "ipv6"))
9815         is_ipv6 = 1;
9816       else if (unformat (i, "src"))
9817         src = 1;
9818       else if (unformat (i, "dst"))
9819         dst = 1;
9820       else if (unformat (i, "sport"))
9821         sport = 1;
9822       else if (unformat (i, "dport"))
9823         dport = 1;
9824       else if (unformat (i, "proto"))
9825         proto = 1;
9826       else if (unformat (i, "reverse"))
9827         reverse = 1;
9828
9829       else
9830         {
9831           clib_warning ("parse error '%U'", format_unformat_error, i);
9832           return -99;
9833         }
9834     }
9835
9836   if (vrf_id_set == 0)
9837     {
9838       errmsg ("missing vrf id");
9839       return -99;
9840     }
9841
9842   M (SET_IP_FLOW_HASH, mp);
9843   mp->src = src;
9844   mp->dst = dst;
9845   mp->sport = sport;
9846   mp->dport = dport;
9847   mp->proto = proto;
9848   mp->reverse = reverse;
9849   mp->vrf_id = ntohl (vrf_id);
9850   mp->is_ipv6 = is_ipv6;
9851
9852   S (mp);
9853   W (ret);
9854   return ret;
9855 }
9856
9857 static int
9858 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_sw_interface_ip6_enable_disable_t *mp;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable = 0;
9865   int ret;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable = 1;
9875       else if (unformat (i, "disable"))
9876         enable = 0;
9877       else
9878         {
9879           clib_warning ("parse error '%U'", format_unformat_error, i);
9880           return -99;
9881         }
9882     }
9883
9884   if (sw_if_index_set == 0)
9885     {
9886       errmsg ("missing interface name or sw_if_index");
9887       return -99;
9888     }
9889
9890   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9891
9892   mp->sw_if_index = ntohl (sw_if_index);
9893   mp->enable = enable;
9894
9895   S (mp);
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u8 v6_address_set = 0;
9908   ip6_address_t v6address;
9909   int ret;
9910
9911   /* Parse args required to build the message */
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9919         v6_address_set = 1;
9920       else
9921         break;
9922     }
9923
9924   if (sw_if_index_set == 0)
9925     {
9926       errmsg ("missing interface name or sw_if_index");
9927       return -99;
9928     }
9929   if (!v6_address_set)
9930     {
9931       errmsg ("no address set");
9932       return -99;
9933     }
9934
9935   /* Construct the API message */
9936   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9937
9938   mp->sw_if_index = ntohl (sw_if_index);
9939   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9940
9941   /* send it... */
9942   S (mp);
9943
9944   /* Wait for a reply, return good/bad news  */
9945   W (ret);
9946   return ret;
9947 }
9948
9949 static int
9950 api_ip6nd_proxy_add_del (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_ip6nd_proxy_add_del_t *mp;
9954   u32 sw_if_index = ~0;
9955   u8 v6_address_set = 0;
9956   ip6_address_t v6address;
9957   u8 is_del = 0;
9958   int ret;
9959
9960   /* Parse args required to build the message */
9961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9962     {
9963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9964         ;
9965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9966         ;
9967       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9968         v6_address_set = 1;
9969       if (unformat (i, "del"))
9970         is_del = 1;
9971       else
9972         {
9973           clib_warning ("parse error '%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   if (sw_if_index == ~0)
9979     {
9980       errmsg ("missing interface name or sw_if_index");
9981       return -99;
9982     }
9983   if (!v6_address_set)
9984     {
9985       errmsg ("no address set");
9986       return -99;
9987     }
9988
9989   /* Construct the API message */
9990   M (IP6ND_PROXY_ADD_DEL, mp);
9991
9992   mp->is_del = is_del;
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9995
9996   /* send it... */
9997   S (mp);
9998
9999   /* Wait for a reply, return good/bad news  */
10000   W (ret);
10001   return ret;
10002 }
10003
10004 static int
10005 api_ip6nd_proxy_dump (vat_main_t * vam)
10006 {
10007   vl_api_ip6nd_proxy_dump_t *mp;
10008   vl_api_control_ping_t *mp_ping;
10009   int ret;
10010
10011   M (IP6ND_PROXY_DUMP, mp);
10012
10013   S (mp);
10014
10015   /* Use a control ping for synchronization */
10016   MPING (CONTROL_PING, mp_ping);
10017   S (mp_ping);
10018
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static void vl_api_ip6nd_proxy_details_t_handler
10024   (vl_api_ip6nd_proxy_details_t * mp)
10025 {
10026   vat_main_t *vam = &vat_main;
10027
10028   print (vam->ofp, "host %U sw_if_index %d",
10029          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10030 }
10031
10032 static void vl_api_ip6nd_proxy_details_t_handler_json
10033   (vl_api_ip6nd_proxy_details_t * mp)
10034 {
10035   vat_main_t *vam = &vat_main;
10036   struct in6_addr ip6;
10037   vat_json_node_t *node = NULL;
10038
10039   if (VAT_JSON_ARRAY != vam->json_tree.type)
10040     {
10041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10042       vat_json_init_array (&vam->json_tree);
10043     }
10044   node = vat_json_array_add (&vam->json_tree);
10045
10046   vat_json_init_object (node);
10047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10048
10049   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10050   vat_json_object_add_ip6 (node, "host", ip6);
10051 }
10052
10053 static int
10054 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10058   u32 sw_if_index;
10059   u8 sw_if_index_set = 0;
10060   u32 address_length = 0;
10061   u8 v6_address_set = 0;
10062   ip6_address_t v6address;
10063   u8 use_default = 0;
10064   u8 no_advertise = 0;
10065   u8 off_link = 0;
10066   u8 no_autoconfig = 0;
10067   u8 no_onlink = 0;
10068   u8 is_no = 0;
10069   u32 val_lifetime = 0;
10070   u32 pref_lifetime = 0;
10071   int ret;
10072
10073   /* Parse args required to build the message */
10074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10075     {
10076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10077         sw_if_index_set = 1;
10078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10079         sw_if_index_set = 1;
10080       else if (unformat (i, "%U/%d",
10081                          unformat_ip6_address, &v6address, &address_length))
10082         v6_address_set = 1;
10083       else if (unformat (i, "val_life %d", &val_lifetime))
10084         ;
10085       else if (unformat (i, "pref_life %d", &pref_lifetime))
10086         ;
10087       else if (unformat (i, "def"))
10088         use_default = 1;
10089       else if (unformat (i, "noadv"))
10090         no_advertise = 1;
10091       else if (unformat (i, "offl"))
10092         off_link = 1;
10093       else if (unformat (i, "noauto"))
10094         no_autoconfig = 1;
10095       else if (unformat (i, "nolink"))
10096         no_onlink = 1;
10097       else if (unformat (i, "isno"))
10098         is_no = 1;
10099       else
10100         {
10101           clib_warning ("parse error '%U'", format_unformat_error, i);
10102           return -99;
10103         }
10104     }
10105
10106   if (sw_if_index_set == 0)
10107     {
10108       errmsg ("missing interface name or sw_if_index");
10109       return -99;
10110     }
10111   if (!v6_address_set)
10112     {
10113       errmsg ("no address set");
10114       return -99;
10115     }
10116
10117   /* Construct the API message */
10118   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10122   mp->address_length = address_length;
10123   mp->use_default = use_default;
10124   mp->no_advertise = no_advertise;
10125   mp->off_link = off_link;
10126   mp->no_autoconfig = no_autoconfig;
10127   mp->no_onlink = no_onlink;
10128   mp->is_no = is_no;
10129   mp->val_lifetime = ntohl (val_lifetime);
10130   mp->pref_lifetime = ntohl (pref_lifetime);
10131
10132   /* send it... */
10133   S (mp);
10134
10135   /* Wait for a reply, return good/bad news  */
10136   W (ret);
10137   return ret;
10138 }
10139
10140 static int
10141 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10145   u32 sw_if_index;
10146   u8 sw_if_index_set = 0;
10147   u8 suppress = 0;
10148   u8 managed = 0;
10149   u8 other = 0;
10150   u8 ll_option = 0;
10151   u8 send_unicast = 0;
10152   u8 cease = 0;
10153   u8 is_no = 0;
10154   u8 default_router = 0;
10155   u32 max_interval = 0;
10156   u32 min_interval = 0;
10157   u32 lifetime = 0;
10158   u32 initial_count = 0;
10159   u32 initial_interval = 0;
10160   int ret;
10161
10162
10163   /* Parse args required to build the message */
10164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169         sw_if_index_set = 1;
10170       else if (unformat (i, "maxint %d", &max_interval))
10171         ;
10172       else if (unformat (i, "minint %d", &min_interval))
10173         ;
10174       else if (unformat (i, "life %d", &lifetime))
10175         ;
10176       else if (unformat (i, "count %d", &initial_count))
10177         ;
10178       else if (unformat (i, "interval %d", &initial_interval))
10179         ;
10180       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10181         suppress = 1;
10182       else if (unformat (i, "managed"))
10183         managed = 1;
10184       else if (unformat (i, "other"))
10185         other = 1;
10186       else if (unformat (i, "ll"))
10187         ll_option = 1;
10188       else if (unformat (i, "send"))
10189         send_unicast = 1;
10190       else if (unformat (i, "cease"))
10191         cease = 1;
10192       else if (unformat (i, "isno"))
10193         is_no = 1;
10194       else if (unformat (i, "def"))
10195         default_router = 1;
10196       else
10197         {
10198           clib_warning ("parse error '%U'", format_unformat_error, i);
10199           return -99;
10200         }
10201     }
10202
10203   if (sw_if_index_set == 0)
10204     {
10205       errmsg ("missing interface name or sw_if_index");
10206       return -99;
10207     }
10208
10209   /* Construct the API message */
10210   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10211
10212   mp->sw_if_index = ntohl (sw_if_index);
10213   mp->max_interval = ntohl (max_interval);
10214   mp->min_interval = ntohl (min_interval);
10215   mp->lifetime = ntohl (lifetime);
10216   mp->initial_count = ntohl (initial_count);
10217   mp->initial_interval = ntohl (initial_interval);
10218   mp->suppress = suppress;
10219   mp->managed = managed;
10220   mp->other = other;
10221   mp->ll_option = ll_option;
10222   mp->send_unicast = send_unicast;
10223   mp->cease = cease;
10224   mp->is_no = is_no;
10225   mp->default_router = default_router;
10226
10227   /* send it... */
10228   S (mp);
10229
10230   /* Wait for a reply, return good/bad news  */
10231   W (ret);
10232   return ret;
10233 }
10234
10235 static int
10236 api_set_arp_neighbor_limit (vat_main_t * vam)
10237 {
10238   unformat_input_t *i = vam->input;
10239   vl_api_set_arp_neighbor_limit_t *mp;
10240   u32 arp_nbr_limit;
10241   u8 limit_set = 0;
10242   u8 is_ipv6 = 0;
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10248         limit_set = 1;
10249       else if (unformat (i, "ipv6"))
10250         is_ipv6 = 1;
10251       else
10252         {
10253           clib_warning ("parse error '%U'", format_unformat_error, i);
10254           return -99;
10255         }
10256     }
10257
10258   if (limit_set == 0)
10259     {
10260       errmsg ("missing limit value");
10261       return -99;
10262     }
10263
10264   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10265
10266   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10267   mp->is_ipv6 = is_ipv6;
10268
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_l2_patch_add_del (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_l2_patch_add_del_t *mp;
10279   u32 rx_sw_if_index;
10280   u8 rx_sw_if_index_set = 0;
10281   u32 tx_sw_if_index;
10282   u8 tx_sw_if_index_set = 0;
10283   u8 is_add = 1;
10284   int ret;
10285
10286   /* Parse args required to build the message */
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10290         rx_sw_if_index_set = 1;
10291       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10292         tx_sw_if_index_set = 1;
10293       else if (unformat (i, "rx"))
10294         {
10295           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10296             {
10297               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10298                             &rx_sw_if_index))
10299                 rx_sw_if_index_set = 1;
10300             }
10301           else
10302             break;
10303         }
10304       else if (unformat (i, "tx"))
10305         {
10306           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307             {
10308               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10309                             &tx_sw_if_index))
10310                 tx_sw_if_index_set = 1;
10311             }
10312           else
10313             break;
10314         }
10315       else if (unformat (i, "del"))
10316         is_add = 0;
10317       else
10318         break;
10319     }
10320
10321   if (rx_sw_if_index_set == 0)
10322     {
10323       errmsg ("missing rx interface name or rx_sw_if_index");
10324       return -99;
10325     }
10326
10327   if (tx_sw_if_index_set == 0)
10328     {
10329       errmsg ("missing tx interface name or tx_sw_if_index");
10330       return -99;
10331     }
10332
10333   M (L2_PATCH_ADD_DEL, mp);
10334
10335   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10336   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10337   mp->is_add = is_add;
10338
10339   S (mp);
10340   W (ret);
10341   return ret;
10342 }
10343
10344 u8 is_del;
10345 u8 localsid_addr[16];
10346 u8 end_psp;
10347 u8 behavior;
10348 u32 sw_if_index;
10349 u32 vlan_index;
10350 u32 fib_table;
10351 u8 nh_addr[16];
10352
10353 static int
10354 api_sr_localsid_add_del (vat_main_t * vam)
10355 {
10356   unformat_input_t *i = vam->input;
10357   vl_api_sr_localsid_add_del_t *mp;
10358
10359   u8 is_del;
10360   ip6_address_t localsid;
10361   u8 end_psp = 0;
10362   u8 behavior = ~0;
10363   u32 sw_if_index;
10364   u32 fib_table = ~(u32) 0;
10365   ip6_address_t next_hop;
10366
10367   bool nexthop_set = 0;
10368
10369   int ret;
10370
10371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (i, "del"))
10374         is_del = 1;
10375       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10376       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10377         nexthop_set = 1;
10378       else if (unformat (i, "behavior %u", &behavior));
10379       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10380       else if (unformat (i, "fib-table %u", &fib_table));
10381       else if (unformat (i, "end.psp %u", &behavior));
10382       else
10383         break;
10384     }
10385
10386   M (SR_LOCALSID_ADD_DEL, mp);
10387
10388   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10389   if (nexthop_set)
10390     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10391   mp->behavior = behavior;
10392   mp->sw_if_index = ntohl (sw_if_index);
10393   mp->fib_table = ntohl (fib_table);
10394   mp->end_psp = end_psp;
10395   mp->is_del = is_del;
10396
10397   S (mp);
10398   W (ret);
10399   return ret;
10400 }
10401
10402 static int
10403 api_ioam_enable (vat_main_t * vam)
10404 {
10405   unformat_input_t *input = vam->input;
10406   vl_api_ioam_enable_t *mp;
10407   u32 id = 0;
10408   int has_trace_option = 0;
10409   int has_pot_option = 0;
10410   int has_seqno_option = 0;
10411   int has_analyse_option = 0;
10412   int ret;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "trace"))
10417         has_trace_option = 1;
10418       else if (unformat (input, "pot"))
10419         has_pot_option = 1;
10420       else if (unformat (input, "seqno"))
10421         has_seqno_option = 1;
10422       else if (unformat (input, "analyse"))
10423         has_analyse_option = 1;
10424       else
10425         break;
10426     }
10427   M (IOAM_ENABLE, mp);
10428   mp->id = htons (id);
10429   mp->seqno = has_seqno_option;
10430   mp->analyse = has_analyse_option;
10431   mp->pot_enable = has_pot_option;
10432   mp->trace_enable = has_trace_option;
10433
10434   S (mp);
10435   W (ret);
10436   return ret;
10437 }
10438
10439
10440 static int
10441 api_ioam_disable (vat_main_t * vam)
10442 {
10443   vl_api_ioam_disable_t *mp;
10444   int ret;
10445
10446   M (IOAM_DISABLE, mp);
10447   S (mp);
10448   W (ret);
10449   return ret;
10450 }
10451
10452 #define foreach_tcp_proto_field                 \
10453 _(src_port)                                     \
10454 _(dst_port)
10455
10456 #define foreach_udp_proto_field                 \
10457 _(src_port)                                     \
10458 _(dst_port)
10459
10460 #define foreach_ip4_proto_field                 \
10461 _(src_address)                                  \
10462 _(dst_address)                                  \
10463 _(tos)                                          \
10464 _(length)                                       \
10465 _(fragment_id)                                  \
10466 _(ttl)                                          \
10467 _(protocol)                                     \
10468 _(checksum)
10469
10470 typedef struct
10471 {
10472   u16 src_port, dst_port;
10473 } tcpudp_header_t;
10474
10475 #if VPP_API_TEST_BUILTIN == 0
10476 uword
10477 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10478 {
10479   u8 **maskp = va_arg (*args, u8 **);
10480   u8 *mask = 0;
10481   u8 found_something = 0;
10482   tcp_header_t *tcp;
10483
10484 #define _(a) u8 a=0;
10485   foreach_tcp_proto_field;
10486 #undef _
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (0);
10491 #define _(a) else if (unformat (input, #a)) a=1;
10492       foreach_tcp_proto_field
10493 #undef _
10494         else
10495         break;
10496     }
10497
10498 #define _(a) found_something += a;
10499   foreach_tcp_proto_field;
10500 #undef _
10501
10502   if (found_something == 0)
10503     return 0;
10504
10505   vec_validate (mask, sizeof (*tcp) - 1);
10506
10507   tcp = (tcp_header_t *) mask;
10508
10509 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10510   foreach_tcp_proto_field;
10511 #undef _
10512
10513   *maskp = mask;
10514   return 1;
10515 }
10516
10517 uword
10518 unformat_udp_mask (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **maskp = va_arg (*args, u8 **);
10521   u8 *mask = 0;
10522   u8 found_something = 0;
10523   udp_header_t *udp;
10524
10525 #define _(a) u8 a=0;
10526   foreach_udp_proto_field;
10527 #undef _
10528
10529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10530     {
10531       if (0);
10532 #define _(a) else if (unformat (input, #a)) a=1;
10533       foreach_udp_proto_field
10534 #undef _
10535         else
10536         break;
10537     }
10538
10539 #define _(a) found_something += a;
10540   foreach_udp_proto_field;
10541 #undef _
10542
10543   if (found_something == 0)
10544     return 0;
10545
10546   vec_validate (mask, sizeof (*udp) - 1);
10547
10548   udp = (udp_header_t *) mask;
10549
10550 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10551   foreach_udp_proto_field;
10552 #undef _
10553
10554   *maskp = mask;
10555   return 1;
10556 }
10557
10558 uword
10559 unformat_l4_mask (unformat_input_t * input, va_list * args)
10560 {
10561   u8 **maskp = va_arg (*args, u8 **);
10562   u16 src_port = 0, dst_port = 0;
10563   tcpudp_header_t *tcpudp;
10564
10565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10568         return 1;
10569       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10570         return 1;
10571       else if (unformat (input, "src_port"))
10572         src_port = 0xFFFF;
10573       else if (unformat (input, "dst_port"))
10574         dst_port = 0xFFFF;
10575       else
10576         return 0;
10577     }
10578
10579   if (!src_port && !dst_port)
10580     return 0;
10581
10582   u8 *mask = 0;
10583   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10584
10585   tcpudp = (tcpudp_header_t *) mask;
10586   tcpudp->src_port = src_port;
10587   tcpudp->dst_port = dst_port;
10588
10589   *maskp = mask;
10590
10591   return 1;
10592 }
10593
10594 uword
10595 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10596 {
10597   u8 **maskp = va_arg (*args, u8 **);
10598   u8 *mask = 0;
10599   u8 found_something = 0;
10600   ip4_header_t *ip;
10601
10602 #define _(a) u8 a=0;
10603   foreach_ip4_proto_field;
10604 #undef _
10605   u8 version = 0;
10606   u8 hdr_length = 0;
10607
10608
10609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (input, "version"))
10612         version = 1;
10613       else if (unformat (input, "hdr_length"))
10614         hdr_length = 1;
10615       else if (unformat (input, "src"))
10616         src_address = 1;
10617       else if (unformat (input, "dst"))
10618         dst_address = 1;
10619       else if (unformat (input, "proto"))
10620         protocol = 1;
10621
10622 #define _(a) else if (unformat (input, #a)) a=1;
10623       foreach_ip4_proto_field
10624 #undef _
10625         else
10626         break;
10627     }
10628
10629 #define _(a) found_something += a;
10630   foreach_ip4_proto_field;
10631 #undef _
10632
10633   if (found_something == 0)
10634     return 0;
10635
10636   vec_validate (mask, sizeof (*ip) - 1);
10637
10638   ip = (ip4_header_t *) mask;
10639
10640 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10641   foreach_ip4_proto_field;
10642 #undef _
10643
10644   ip->ip_version_and_header_length = 0;
10645
10646   if (version)
10647     ip->ip_version_and_header_length |= 0xF0;
10648
10649   if (hdr_length)
10650     ip->ip_version_and_header_length |= 0x0F;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 #define foreach_ip6_proto_field                 \
10657 _(src_address)                                  \
10658 _(dst_address)                                  \
10659 _(payload_length)                               \
10660 _(hop_limit)                                    \
10661 _(protocol)
10662
10663 uword
10664 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10665 {
10666   u8 **maskp = va_arg (*args, u8 **);
10667   u8 *mask = 0;
10668   u8 found_something = 0;
10669   ip6_header_t *ip;
10670   u32 ip_version_traffic_class_and_flow_label;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip6_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 traffic_class = 0;
10677   u8 flow_label = 0;
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "traffic-class"))
10684         traffic_class = 1;
10685       else if (unformat (input, "flow-label"))
10686         flow_label = 1;
10687       else if (unformat (input, "src"))
10688         src_address = 1;
10689       else if (unformat (input, "dst"))
10690         dst_address = 1;
10691       else if (unformat (input, "proto"))
10692         protocol = 1;
10693
10694 #define _(a) else if (unformat (input, #a)) a=1;
10695       foreach_ip6_proto_field
10696 #undef _
10697         else
10698         break;
10699     }
10700
10701 #define _(a) found_something += a;
10702   foreach_ip6_proto_field;
10703 #undef _
10704
10705   if (found_something == 0)
10706     return 0;
10707
10708   vec_validate (mask, sizeof (*ip) - 1);
10709
10710   ip = (ip6_header_t *) mask;
10711
10712 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10713   foreach_ip6_proto_field;
10714 #undef _
10715
10716   ip_version_traffic_class_and_flow_label = 0;
10717
10718   if (version)
10719     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10720
10721   if (traffic_class)
10722     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10723
10724   if (flow_label)
10725     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10726
10727   ip->ip_version_traffic_class_and_flow_label =
10728     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10729
10730   *maskp = mask;
10731   return 1;
10732 }
10733
10734 uword
10735 unformat_l3_mask (unformat_input_t * input, va_list * args)
10736 {
10737   u8 **maskp = va_arg (*args, u8 **);
10738
10739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10742         return 1;
10743       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10744         return 1;
10745       else
10746         break;
10747     }
10748   return 0;
10749 }
10750
10751 uword
10752 unformat_l2_mask (unformat_input_t * input, va_list * args)
10753 {
10754   u8 **maskp = va_arg (*args, u8 **);
10755   u8 *mask = 0;
10756   u8 src = 0;
10757   u8 dst = 0;
10758   u8 proto = 0;
10759   u8 tag1 = 0;
10760   u8 tag2 = 0;
10761   u8 ignore_tag1 = 0;
10762   u8 ignore_tag2 = 0;
10763   u8 cos1 = 0;
10764   u8 cos2 = 0;
10765   u8 dot1q = 0;
10766   u8 dot1ad = 0;
10767   int len = 14;
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "src"))
10772         src = 1;
10773       else if (unformat (input, "dst"))
10774         dst = 1;
10775       else if (unformat (input, "proto"))
10776         proto = 1;
10777       else if (unformat (input, "tag1"))
10778         tag1 = 1;
10779       else if (unformat (input, "tag2"))
10780         tag2 = 1;
10781       else if (unformat (input, "ignore-tag1"))
10782         ignore_tag1 = 1;
10783       else if (unformat (input, "ignore-tag2"))
10784         ignore_tag2 = 1;
10785       else if (unformat (input, "cos1"))
10786         cos1 = 1;
10787       else if (unformat (input, "cos2"))
10788         cos2 = 1;
10789       else if (unformat (input, "dot1q"))
10790         dot1q = 1;
10791       else if (unformat (input, "dot1ad"))
10792         dot1ad = 1;
10793       else
10794         break;
10795     }
10796   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10797        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10798     return 0;
10799
10800   if (tag1 || ignore_tag1 || cos1 || dot1q)
10801     len = 18;
10802   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10803     len = 22;
10804
10805   vec_validate (mask, len - 1);
10806
10807   if (dst)
10808     memset (mask, 0xff, 6);
10809
10810   if (src)
10811     memset (mask + 6, 0xff, 6);
10812
10813   if (tag2 || dot1ad)
10814     {
10815       /* inner vlan tag */
10816       if (tag2)
10817         {
10818           mask[19] = 0xff;
10819           mask[18] = 0x0f;
10820         }
10821       if (cos2)
10822         mask[18] |= 0xe0;
10823       if (proto)
10824         mask[21] = mask[20] = 0xff;
10825       if (tag1)
10826         {
10827           mask[15] = 0xff;
10828           mask[14] = 0x0f;
10829         }
10830       if (cos1)
10831         mask[14] |= 0xe0;
10832       *maskp = mask;
10833       return 1;
10834     }
10835   if (tag1 | dot1q)
10836     {
10837       if (tag1)
10838         {
10839           mask[15] = 0xff;
10840           mask[14] = 0x0f;
10841         }
10842       if (cos1)
10843         mask[14] |= 0xe0;
10844       if (proto)
10845         mask[16] = mask[17] = 0xff;
10846
10847       *maskp = mask;
10848       return 1;
10849     }
10850   if (cos2)
10851     mask[18] |= 0xe0;
10852   if (cos1)
10853     mask[14] |= 0xe0;
10854   if (proto)
10855     mask[12] = mask[13] = 0xff;
10856
10857   *maskp = mask;
10858   return 1;
10859 }
10860
10861 uword
10862 unformat_classify_mask (unformat_input_t * input, va_list * args)
10863 {
10864   u8 **maskp = va_arg (*args, u8 **);
10865   u32 *skipp = va_arg (*args, u32 *);
10866   u32 *matchp = va_arg (*args, u32 *);
10867   u32 match;
10868   u8 *mask = 0;
10869   u8 *l2 = 0;
10870   u8 *l3 = 0;
10871   u8 *l4 = 0;
10872   int i;
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10877         ;
10878       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10879         ;
10880       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10881         ;
10882       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10883         ;
10884       else
10885         break;
10886     }
10887
10888   if (l4 && !l3)
10889     {
10890       vec_free (mask);
10891       vec_free (l2);
10892       vec_free (l4);
10893       return 0;
10894     }
10895
10896   if (mask || l2 || l3 || l4)
10897     {
10898       if (l2 || l3 || l4)
10899         {
10900           /* "With a free Ethernet header in every package" */
10901           if (l2 == 0)
10902             vec_validate (l2, 13);
10903           mask = l2;
10904           if (vec_len (l3))
10905             {
10906               vec_append (mask, l3);
10907               vec_free (l3);
10908             }
10909           if (vec_len (l4))
10910             {
10911               vec_append (mask, l4);
10912               vec_free (l4);
10913             }
10914         }
10915
10916       /* Scan forward looking for the first significant mask octet */
10917       for (i = 0; i < vec_len (mask); i++)
10918         if (mask[i])
10919           break;
10920
10921       /* compute (skip, match) params */
10922       *skipp = i / sizeof (u32x4);
10923       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10924
10925       /* Pad mask to an even multiple of the vector size */
10926       while (vec_len (mask) % sizeof (u32x4))
10927         vec_add1 (mask, 0);
10928
10929       match = vec_len (mask) / sizeof (u32x4);
10930
10931       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10932         {
10933           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10934           if (*tmp || *(tmp + 1))
10935             break;
10936           match--;
10937         }
10938       if (match == 0)
10939         clib_warning ("BUG: match 0");
10940
10941       _vec_len (mask) = match * sizeof (u32x4);
10942
10943       *matchp = match;
10944       *maskp = mask;
10945
10946       return 1;
10947     }
10948
10949   return 0;
10950 }
10951 #endif /* VPP_API_TEST_BUILTIN */
10952
10953 #define foreach_l2_next                         \
10954 _(drop, DROP)                                   \
10955 _(ethernet, ETHERNET_INPUT)                     \
10956 _(ip4, IP4_INPUT)                               \
10957 _(ip6, IP6_INPUT)
10958
10959 uword
10960 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10961 {
10962   u32 *miss_next_indexp = va_arg (*args, u32 *);
10963   u32 next_index = 0;
10964   u32 tmp;
10965
10966 #define _(n,N) \
10967   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10968   foreach_l2_next;
10969 #undef _
10970
10971   if (unformat (input, "%d", &tmp))
10972     {
10973       next_index = tmp;
10974       goto out;
10975     }
10976
10977   return 0;
10978
10979 out:
10980   *miss_next_indexp = next_index;
10981   return 1;
10982 }
10983
10984 #define foreach_ip_next                         \
10985 _(drop, DROP)                                   \
10986 _(local, LOCAL)                                 \
10987 _(rewrite, REWRITE)
10988
10989 uword
10990 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10991 {
10992   u32 *miss_next_indexp = va_arg (*args, u32 *);
10993   u32 next_index = 0;
10994   u32 tmp;
10995
10996 #define _(n,N) \
10997   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10998   foreach_ip_next;
10999 #undef _
11000
11001   if (unformat (input, "%d", &tmp))
11002     {
11003       next_index = tmp;
11004       goto out;
11005     }
11006
11007   return 0;
11008
11009 out:
11010   *miss_next_indexp = next_index;
11011   return 1;
11012 }
11013
11014 #define foreach_acl_next                        \
11015 _(deny, DENY)
11016
11017 uword
11018 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11019 {
11020   u32 *miss_next_indexp = va_arg (*args, u32 *);
11021   u32 next_index = 0;
11022   u32 tmp;
11023
11024 #define _(n,N) \
11025   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11026   foreach_acl_next;
11027 #undef _
11028
11029   if (unformat (input, "permit"))
11030     {
11031       next_index = ~0;
11032       goto out;
11033     }
11034   else if (unformat (input, "%d", &tmp))
11035     {
11036       next_index = tmp;
11037       goto out;
11038     }
11039
11040   return 0;
11041
11042 out:
11043   *miss_next_indexp = next_index;
11044   return 1;
11045 }
11046
11047 uword
11048 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11049 {
11050   u32 *r = va_arg (*args, u32 *);
11051
11052   if (unformat (input, "conform-color"))
11053     *r = POLICE_CONFORM;
11054   else if (unformat (input, "exceed-color"))
11055     *r = POLICE_EXCEED;
11056   else
11057     return 0;
11058
11059   return 1;
11060 }
11061
11062 static int
11063 api_classify_add_del_table (vat_main_t * vam)
11064 {
11065   unformat_input_t *i = vam->input;
11066   vl_api_classify_add_del_table_t *mp;
11067
11068   u32 nbuckets = 2;
11069   u32 skip = ~0;
11070   u32 match = ~0;
11071   int is_add = 1;
11072   int del_chain = 0;
11073   u32 table_index = ~0;
11074   u32 next_table_index = ~0;
11075   u32 miss_next_index = ~0;
11076   u32 memory_size = 32 << 20;
11077   u8 *mask = 0;
11078   u32 current_data_flag = 0;
11079   int current_data_offset = 0;
11080   int ret;
11081
11082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11083     {
11084       if (unformat (i, "del"))
11085         is_add = 0;
11086       else if (unformat (i, "del-chain"))
11087         {
11088           is_add = 0;
11089           del_chain = 1;
11090         }
11091       else if (unformat (i, "buckets %d", &nbuckets))
11092         ;
11093       else if (unformat (i, "memory_size %d", &memory_size))
11094         ;
11095       else if (unformat (i, "skip %d", &skip))
11096         ;
11097       else if (unformat (i, "match %d", &match))
11098         ;
11099       else if (unformat (i, "table %d", &table_index))
11100         ;
11101       else if (unformat (i, "mask %U", unformat_classify_mask,
11102                          &mask, &skip, &match))
11103         ;
11104       else if (unformat (i, "next-table %d", &next_table_index))
11105         ;
11106       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11107                          &miss_next_index))
11108         ;
11109       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11110                          &miss_next_index))
11111         ;
11112       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11113                          &miss_next_index))
11114         ;
11115       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11116         ;
11117       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11118         ;
11119       else
11120         break;
11121     }
11122
11123   if (is_add && mask == 0)
11124     {
11125       errmsg ("Mask required");
11126       return -99;
11127     }
11128
11129   if (is_add && skip == ~0)
11130     {
11131       errmsg ("skip count required");
11132       return -99;
11133     }
11134
11135   if (is_add && match == ~0)
11136     {
11137       errmsg ("match count required");
11138       return -99;
11139     }
11140
11141   if (!is_add && table_index == ~0)
11142     {
11143       errmsg ("table index required for delete");
11144       return -99;
11145     }
11146
11147   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11148
11149   mp->is_add = is_add;
11150   mp->del_chain = del_chain;
11151   mp->table_index = ntohl (table_index);
11152   mp->nbuckets = ntohl (nbuckets);
11153   mp->memory_size = ntohl (memory_size);
11154   mp->skip_n_vectors = ntohl (skip);
11155   mp->match_n_vectors = ntohl (match);
11156   mp->next_table_index = ntohl (next_table_index);
11157   mp->miss_next_index = ntohl (miss_next_index);
11158   mp->current_data_flag = ntohl (current_data_flag);
11159   mp->current_data_offset = ntohl (current_data_offset);
11160   clib_memcpy (mp->mask, mask, vec_len (mask));
11161
11162   vec_free (mask);
11163
11164   S (mp);
11165   W (ret);
11166   return ret;
11167 }
11168
11169 #if VPP_API_TEST_BUILTIN == 0
11170 uword
11171 unformat_l4_match (unformat_input_t * input, va_list * args)
11172 {
11173   u8 **matchp = va_arg (*args, u8 **);
11174
11175   u8 *proto_header = 0;
11176   int src_port = 0;
11177   int dst_port = 0;
11178
11179   tcpudp_header_t h;
11180
11181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (input, "src_port %d", &src_port))
11184         ;
11185       else if (unformat (input, "dst_port %d", &dst_port))
11186         ;
11187       else
11188         return 0;
11189     }
11190
11191   h.src_port = clib_host_to_net_u16 (src_port);
11192   h.dst_port = clib_host_to_net_u16 (dst_port);
11193   vec_validate (proto_header, sizeof (h) - 1);
11194   memcpy (proto_header, &h, sizeof (h));
11195
11196   *matchp = proto_header;
11197
11198   return 1;
11199 }
11200
11201 uword
11202 unformat_ip4_match (unformat_input_t * input, va_list * args)
11203 {
11204   u8 **matchp = va_arg (*args, u8 **);
11205   u8 *match = 0;
11206   ip4_header_t *ip;
11207   int version = 0;
11208   u32 version_val;
11209   int hdr_length = 0;
11210   u32 hdr_length_val;
11211   int src = 0, dst = 0;
11212   ip4_address_t src_val, dst_val;
11213   int proto = 0;
11214   u32 proto_val;
11215   int tos = 0;
11216   u32 tos_val;
11217   int length = 0;
11218   u32 length_val;
11219   int fragment_id = 0;
11220   u32 fragment_id_val;
11221   int ttl = 0;
11222   int ttl_val;
11223   int checksum = 0;
11224   u32 checksum_val;
11225
11226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11227     {
11228       if (unformat (input, "version %d", &version_val))
11229         version = 1;
11230       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11231         hdr_length = 1;
11232       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11233         src = 1;
11234       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11235         dst = 1;
11236       else if (unformat (input, "proto %d", &proto_val))
11237         proto = 1;
11238       else if (unformat (input, "tos %d", &tos_val))
11239         tos = 1;
11240       else if (unformat (input, "length %d", &length_val))
11241         length = 1;
11242       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11243         fragment_id = 1;
11244       else if (unformat (input, "ttl %d", &ttl_val))
11245         ttl = 1;
11246       else if (unformat (input, "checksum %d", &checksum_val))
11247         checksum = 1;
11248       else
11249         break;
11250     }
11251
11252   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11253       + ttl + checksum == 0)
11254     return 0;
11255
11256   /*
11257    * Aligned because we use the real comparison functions
11258    */
11259   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11260
11261   ip = (ip4_header_t *) match;
11262
11263   /* These are realistically matched in practice */
11264   if (src)
11265     ip->src_address.as_u32 = src_val.as_u32;
11266
11267   if (dst)
11268     ip->dst_address.as_u32 = dst_val.as_u32;
11269
11270   if (proto)
11271     ip->protocol = proto_val;
11272
11273
11274   /* These are not, but they're included for completeness */
11275   if (version)
11276     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11277
11278   if (hdr_length)
11279     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11280
11281   if (tos)
11282     ip->tos = tos_val;
11283
11284   if (length)
11285     ip->length = clib_host_to_net_u16 (length_val);
11286
11287   if (ttl)
11288     ip->ttl = ttl_val;
11289
11290   if (checksum)
11291     ip->checksum = clib_host_to_net_u16 (checksum_val);
11292
11293   *matchp = match;
11294   return 1;
11295 }
11296
11297 uword
11298 unformat_ip6_match (unformat_input_t * input, va_list * args)
11299 {
11300   u8 **matchp = va_arg (*args, u8 **);
11301   u8 *match = 0;
11302   ip6_header_t *ip;
11303   int version = 0;
11304   u32 version_val;
11305   u8 traffic_class = 0;
11306   u32 traffic_class_val = 0;
11307   u8 flow_label = 0;
11308   u8 flow_label_val;
11309   int src = 0, dst = 0;
11310   ip6_address_t src_val, dst_val;
11311   int proto = 0;
11312   u32 proto_val;
11313   int payload_length = 0;
11314   u32 payload_length_val;
11315   int hop_limit = 0;
11316   int hop_limit_val;
11317   u32 ip_version_traffic_class_and_flow_label;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "version %d", &version_val))
11322         version = 1;
11323       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11324         traffic_class = 1;
11325       else if (unformat (input, "flow_label %d", &flow_label_val))
11326         flow_label = 1;
11327       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11328         src = 1;
11329       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11330         dst = 1;
11331       else if (unformat (input, "proto %d", &proto_val))
11332         proto = 1;
11333       else if (unformat (input, "payload_length %d", &payload_length_val))
11334         payload_length = 1;
11335       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11336         hop_limit = 1;
11337       else
11338         break;
11339     }
11340
11341   if (version + traffic_class + flow_label + src + dst + proto +
11342       payload_length + hop_limit == 0)
11343     return 0;
11344
11345   /*
11346    * Aligned because we use the real comparison functions
11347    */
11348   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11349
11350   ip = (ip6_header_t *) match;
11351
11352   if (src)
11353     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11354
11355   if (dst)
11356     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11357
11358   if (proto)
11359     ip->protocol = proto_val;
11360
11361   ip_version_traffic_class_and_flow_label = 0;
11362
11363   if (version)
11364     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11365
11366   if (traffic_class)
11367     ip_version_traffic_class_and_flow_label |=
11368       (traffic_class_val & 0xFF) << 20;
11369
11370   if (flow_label)
11371     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11372
11373   ip->ip_version_traffic_class_and_flow_label =
11374     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11375
11376   if (payload_length)
11377     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11378
11379   if (hop_limit)
11380     ip->hop_limit = hop_limit_val;
11381
11382   *matchp = match;
11383   return 1;
11384 }
11385
11386 uword
11387 unformat_l3_match (unformat_input_t * input, va_list * args)
11388 {
11389   u8 **matchp = va_arg (*args, u8 **);
11390
11391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11394         return 1;
11395       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11396         return 1;
11397       else
11398         break;
11399     }
11400   return 0;
11401 }
11402
11403 uword
11404 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11405 {
11406   u8 *tagp = va_arg (*args, u8 *);
11407   u32 tag;
11408
11409   if (unformat (input, "%d", &tag))
11410     {
11411       tagp[0] = (tag >> 8) & 0x0F;
11412       tagp[1] = tag & 0xFF;
11413       return 1;
11414     }
11415
11416   return 0;
11417 }
11418
11419 uword
11420 unformat_l2_match (unformat_input_t * input, va_list * args)
11421 {
11422   u8 **matchp = va_arg (*args, u8 **);
11423   u8 *match = 0;
11424   u8 src = 0;
11425   u8 src_val[6];
11426   u8 dst = 0;
11427   u8 dst_val[6];
11428   u8 proto = 0;
11429   u16 proto_val;
11430   u8 tag1 = 0;
11431   u8 tag1_val[2];
11432   u8 tag2 = 0;
11433   u8 tag2_val[2];
11434   int len = 14;
11435   u8 ignore_tag1 = 0;
11436   u8 ignore_tag2 = 0;
11437   u8 cos1 = 0;
11438   u8 cos2 = 0;
11439   u32 cos1_val = 0;
11440   u32 cos2_val = 0;
11441
11442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11445         src = 1;
11446       else
11447         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11448         dst = 1;
11449       else if (unformat (input, "proto %U",
11450                          unformat_ethernet_type_host_byte_order, &proto_val))
11451         proto = 1;
11452       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11453         tag1 = 1;
11454       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11455         tag2 = 1;
11456       else if (unformat (input, "ignore-tag1"))
11457         ignore_tag1 = 1;
11458       else if (unformat (input, "ignore-tag2"))
11459         ignore_tag2 = 1;
11460       else if (unformat (input, "cos1 %d", &cos1_val))
11461         cos1 = 1;
11462       else if (unformat (input, "cos2 %d", &cos2_val))
11463         cos2 = 1;
11464       else
11465         break;
11466     }
11467   if ((src + dst + proto + tag1 + tag2 +
11468        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11469     return 0;
11470
11471   if (tag1 || ignore_tag1 || cos1)
11472     len = 18;
11473   if (tag2 || ignore_tag2 || cos2)
11474     len = 22;
11475
11476   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11477
11478   if (dst)
11479     clib_memcpy (match, dst_val, 6);
11480
11481   if (src)
11482     clib_memcpy (match + 6, src_val, 6);
11483
11484   if (tag2)
11485     {
11486       /* inner vlan tag */
11487       match[19] = tag2_val[1];
11488       match[18] = tag2_val[0];
11489       if (cos2)
11490         match[18] |= (cos2_val & 0x7) << 5;
11491       if (proto)
11492         {
11493           match[21] = proto_val & 0xff;
11494           match[20] = proto_val >> 8;
11495         }
11496       if (tag1)
11497         {
11498           match[15] = tag1_val[1];
11499           match[14] = tag1_val[0];
11500         }
11501       if (cos1)
11502         match[14] |= (cos1_val & 0x7) << 5;
11503       *matchp = match;
11504       return 1;
11505     }
11506   if (tag1)
11507     {
11508       match[15] = tag1_val[1];
11509       match[14] = tag1_val[0];
11510       if (proto)
11511         {
11512           match[17] = proto_val & 0xff;
11513           match[16] = proto_val >> 8;
11514         }
11515       if (cos1)
11516         match[14] |= (cos1_val & 0x7) << 5;
11517
11518       *matchp = match;
11519       return 1;
11520     }
11521   if (cos2)
11522     match[18] |= (cos2_val & 0x7) << 5;
11523   if (cos1)
11524     match[14] |= (cos1_val & 0x7) << 5;
11525   if (proto)
11526     {
11527       match[13] = proto_val & 0xff;
11528       match[12] = proto_val >> 8;
11529     }
11530
11531   *matchp = match;
11532   return 1;
11533 }
11534 #endif
11535
11536 uword
11537 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11538 {
11539   u8 **matchp = va_arg (*args, u8 **);
11540   u32 skip_n_vectors = va_arg (*args, u32);
11541   u32 match_n_vectors = va_arg (*args, u32);
11542
11543   u8 *match = 0;
11544   u8 *l2 = 0;
11545   u8 *l3 = 0;
11546   u8 *l4 = 0;
11547
11548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (input, "hex %U", unformat_hex_string, &match))
11551         ;
11552       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11553         ;
11554       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11555         ;
11556       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11557         ;
11558       else
11559         break;
11560     }
11561
11562   if (l4 && !l3)
11563     {
11564       vec_free (match);
11565       vec_free (l2);
11566       vec_free (l4);
11567       return 0;
11568     }
11569
11570   if (match || l2 || l3 || l4)
11571     {
11572       if (l2 || l3 || l4)
11573         {
11574           /* "Win a free Ethernet header in every packet" */
11575           if (l2 == 0)
11576             vec_validate_aligned (l2, 13, sizeof (u32x4));
11577           match = l2;
11578           if (vec_len (l3))
11579             {
11580               vec_append_aligned (match, l3, sizeof (u32x4));
11581               vec_free (l3);
11582             }
11583           if (vec_len (l4))
11584             {
11585               vec_append_aligned (match, l4, sizeof (u32x4));
11586               vec_free (l4);
11587             }
11588         }
11589
11590       /* Make sure the vector is big enough even if key is all 0's */
11591       vec_validate_aligned
11592         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11593          sizeof (u32x4));
11594
11595       /* Set size, include skipped vectors */
11596       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11597
11598       *matchp = match;
11599
11600       return 1;
11601     }
11602
11603   return 0;
11604 }
11605
11606 static int
11607 api_classify_add_del_session (vat_main_t * vam)
11608 {
11609   unformat_input_t *i = vam->input;
11610   vl_api_classify_add_del_session_t *mp;
11611   int is_add = 1;
11612   u32 table_index = ~0;
11613   u32 hit_next_index = ~0;
11614   u32 opaque_index = ~0;
11615   u8 *match = 0;
11616   i32 advance = 0;
11617   u32 skip_n_vectors = 0;
11618   u32 match_n_vectors = 0;
11619   u32 action = 0;
11620   u32 metadata = 0;
11621   int ret;
11622
11623   /*
11624    * Warning: you have to supply skip_n and match_n
11625    * because the API client cant simply look at the classify
11626    * table object.
11627    */
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "del"))
11632         is_add = 0;
11633       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11634                          &hit_next_index))
11635         ;
11636       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11637                          &hit_next_index))
11638         ;
11639       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11640                          &hit_next_index))
11641         ;
11642       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11643         ;
11644       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11645         ;
11646       else if (unformat (i, "opaque-index %d", &opaque_index))
11647         ;
11648       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11649         ;
11650       else if (unformat (i, "match_n %d", &match_n_vectors))
11651         ;
11652       else if (unformat (i, "match %U", api_unformat_classify_match,
11653                          &match, skip_n_vectors, match_n_vectors))
11654         ;
11655       else if (unformat (i, "advance %d", &advance))
11656         ;
11657       else if (unformat (i, "table-index %d", &table_index))
11658         ;
11659       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11660         action = 1;
11661       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11662         action = 2;
11663       else if (unformat (i, "action %d", &action))
11664         ;
11665       else if (unformat (i, "metadata %d", &metadata))
11666         ;
11667       else
11668         break;
11669     }
11670
11671   if (table_index == ~0)
11672     {
11673       errmsg ("Table index required");
11674       return -99;
11675     }
11676
11677   if (is_add && match == 0)
11678     {
11679       errmsg ("Match value required");
11680       return -99;
11681     }
11682
11683   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11684
11685   mp->is_add = is_add;
11686   mp->table_index = ntohl (table_index);
11687   mp->hit_next_index = ntohl (hit_next_index);
11688   mp->opaque_index = ntohl (opaque_index);
11689   mp->advance = ntohl (advance);
11690   mp->action = action;
11691   mp->metadata = ntohl (metadata);
11692   clib_memcpy (mp->match, match, vec_len (match));
11693   vec_free (match);
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_classify_set_interface_ip_table (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_classify_set_interface_ip_table_t *mp;
11705   u32 sw_if_index;
11706   int sw_if_index_set;
11707   u32 table_index = ~0;
11708   u8 is_ipv6 = 0;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "table %d", &table_index))
11718         ;
11719       else
11720         {
11721           clib_warning ("parse error '%U'", format_unformat_error, i);
11722           return -99;
11723         }
11724     }
11725
11726   if (sw_if_index_set == 0)
11727     {
11728       errmsg ("missing interface name or sw_if_index");
11729       return -99;
11730     }
11731
11732
11733   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11734
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->table_index = ntohl (table_index);
11737   mp->is_ipv6 = is_ipv6;
11738
11739   S (mp);
11740   W (ret);
11741   return ret;
11742 }
11743
11744 static int
11745 api_classify_set_interface_l2_tables (vat_main_t * vam)
11746 {
11747   unformat_input_t *i = vam->input;
11748   vl_api_classify_set_interface_l2_tables_t *mp;
11749   u32 sw_if_index;
11750   int sw_if_index_set;
11751   u32 ip4_table_index = ~0;
11752   u32 ip6_table_index = ~0;
11753   u32 other_table_index = ~0;
11754   u32 is_input = 1;
11755   int ret;
11756
11757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11758     {
11759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11762         sw_if_index_set = 1;
11763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11764         ;
11765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11766         ;
11767       else if (unformat (i, "other-table %d", &other_table_index))
11768         ;
11769       else if (unformat (i, "is-input %d", &is_input))
11770         ;
11771       else
11772         {
11773           clib_warning ("parse error '%U'", format_unformat_error, i);
11774           return -99;
11775         }
11776     }
11777
11778   if (sw_if_index_set == 0)
11779     {
11780       errmsg ("missing interface name or sw_if_index");
11781       return -99;
11782     }
11783
11784
11785   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11786
11787   mp->sw_if_index = ntohl (sw_if_index);
11788   mp->ip4_table_index = ntohl (ip4_table_index);
11789   mp->ip6_table_index = ntohl (ip6_table_index);
11790   mp->other_table_index = ntohl (other_table_index);
11791   mp->is_input = (u8) is_input;
11792
11793   S (mp);
11794   W (ret);
11795   return ret;
11796 }
11797
11798 static int
11799 api_set_ipfix_exporter (vat_main_t * vam)
11800 {
11801   unformat_input_t *i = vam->input;
11802   vl_api_set_ipfix_exporter_t *mp;
11803   ip4_address_t collector_address;
11804   u8 collector_address_set = 0;
11805   u32 collector_port = ~0;
11806   ip4_address_t src_address;
11807   u8 src_address_set = 0;
11808   u32 vrf_id = ~0;
11809   u32 path_mtu = ~0;
11810   u32 template_interval = ~0;
11811   u8 udp_checksum = 0;
11812   int ret;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "collector_address %U", unformat_ip4_address,
11817                     &collector_address))
11818         collector_address_set = 1;
11819       else if (unformat (i, "collector_port %d", &collector_port))
11820         ;
11821       else if (unformat (i, "src_address %U", unformat_ip4_address,
11822                          &src_address))
11823         src_address_set = 1;
11824       else if (unformat (i, "vrf_id %d", &vrf_id))
11825         ;
11826       else if (unformat (i, "path_mtu %d", &path_mtu))
11827         ;
11828       else if (unformat (i, "template_interval %d", &template_interval))
11829         ;
11830       else if (unformat (i, "udp_checksum"))
11831         udp_checksum = 1;
11832       else
11833         break;
11834     }
11835
11836   if (collector_address_set == 0)
11837     {
11838       errmsg ("collector_address required");
11839       return -99;
11840     }
11841
11842   if (src_address_set == 0)
11843     {
11844       errmsg ("src_address required");
11845       return -99;
11846     }
11847
11848   M (SET_IPFIX_EXPORTER, mp);
11849
11850   memcpy (mp->collector_address, collector_address.data,
11851           sizeof (collector_address.data));
11852   mp->collector_port = htons ((u16) collector_port);
11853   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11854   mp->vrf_id = htonl (vrf_id);
11855   mp->path_mtu = htonl (path_mtu);
11856   mp->template_interval = htonl (template_interval);
11857   mp->udp_checksum = udp_checksum;
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_set_ipfix_classify_stream (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_set_ipfix_classify_stream_t *mp;
11869   u32 domain_id = 0;
11870   u32 src_port = UDP_DST_PORT_ipfix;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "domain %d", &domain_id))
11876         ;
11877       else if (unformat (i, "src_port %d", &src_port))
11878         ;
11879       else
11880         {
11881           errmsg ("unknown input `%U'", format_unformat_error, i);
11882           return -99;
11883         }
11884     }
11885
11886   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11887
11888   mp->domain_id = htonl (domain_id);
11889   mp->src_port = htons ((u16) src_port);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_ipfix_classify_table_add_del (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_ipfix_classify_table_add_del_t *mp;
11901   int is_add = -1;
11902   u32 classify_table_index = ~0;
11903   u8 ip_version = 0;
11904   u8 transport_protocol = 255;
11905   int ret;
11906
11907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11908     {
11909       if (unformat (i, "add"))
11910         is_add = 1;
11911       else if (unformat (i, "del"))
11912         is_add = 0;
11913       else if (unformat (i, "table %d", &classify_table_index))
11914         ;
11915       else if (unformat (i, "ip4"))
11916         ip_version = 4;
11917       else if (unformat (i, "ip6"))
11918         ip_version = 6;
11919       else if (unformat (i, "tcp"))
11920         transport_protocol = 6;
11921       else if (unformat (i, "udp"))
11922         transport_protocol = 17;
11923       else
11924         {
11925           errmsg ("unknown input `%U'", format_unformat_error, i);
11926           return -99;
11927         }
11928     }
11929
11930   if (is_add == -1)
11931     {
11932       errmsg ("expecting: add|del");
11933       return -99;
11934     }
11935   if (classify_table_index == ~0)
11936     {
11937       errmsg ("classifier table not specified");
11938       return -99;
11939     }
11940   if (ip_version == 0)
11941     {
11942       errmsg ("IP version not specified");
11943       return -99;
11944     }
11945
11946   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11947
11948   mp->is_add = is_add;
11949   mp->table_id = htonl (classify_table_index);
11950   mp->ip_version = ip_version;
11951   mp->transport_protocol = transport_protocol;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_get_node_index (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_get_node_index_t *mp;
11963   u8 *name = 0;
11964   int ret;
11965
11966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (i, "node %s", &name))
11969         ;
11970       else
11971         break;
11972     }
11973   if (name == 0)
11974     {
11975       errmsg ("node name required");
11976       return -99;
11977     }
11978   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11979     {
11980       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11981       return -99;
11982     }
11983
11984   M (GET_NODE_INDEX, mp);
11985   clib_memcpy (mp->node_name, name, vec_len (name));
11986   vec_free (name);
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993 static int
11994 api_get_next_index (vat_main_t * vam)
11995 {
11996   unformat_input_t *i = vam->input;
11997   vl_api_get_next_index_t *mp;
11998   u8 *node_name = 0, *next_node_name = 0;
11999   int ret;
12000
12001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (i, "node-name %s", &node_name))
12004         ;
12005       else if (unformat (i, "next-node-name %s", &next_node_name))
12006         break;
12007     }
12008
12009   if (node_name == 0)
12010     {
12011       errmsg ("node name required");
12012       return -99;
12013     }
12014   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12015     {
12016       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12017       return -99;
12018     }
12019
12020   if (next_node_name == 0)
12021     {
12022       errmsg ("next node name required");
12023       return -99;
12024     }
12025   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12026     {
12027       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12028       return -99;
12029     }
12030
12031   M (GET_NEXT_INDEX, mp);
12032   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12033   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12034   vec_free (node_name);
12035   vec_free (next_node_name);
12036
12037   S (mp);
12038   W (ret);
12039   return ret;
12040 }
12041
12042 static int
12043 api_add_node_next (vat_main_t * vam)
12044 {
12045   unformat_input_t *i = vam->input;
12046   vl_api_add_node_next_t *mp;
12047   u8 *name = 0;
12048   u8 *next = 0;
12049   int ret;
12050
12051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (i, "node %s", &name))
12054         ;
12055       else if (unformat (i, "next %s", &next))
12056         ;
12057       else
12058         break;
12059     }
12060   if (name == 0)
12061     {
12062       errmsg ("node name required");
12063       return -99;
12064     }
12065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12066     {
12067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12068       return -99;
12069     }
12070   if (next == 0)
12071     {
12072       errmsg ("next node required");
12073       return -99;
12074     }
12075   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12076     {
12077       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12078       return -99;
12079     }
12080
12081   M (ADD_NODE_NEXT, mp);
12082   clib_memcpy (mp->node_name, name, vec_len (name));
12083   clib_memcpy (mp->next_name, next, vec_len (next));
12084   vec_free (name);
12085   vec_free (next);
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_l2tpv3_create_tunnel (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   ip6_address_t client_address, our_address;
12097   int client_address_set = 0;
12098   int our_address_set = 0;
12099   u32 local_session_id = 0;
12100   u32 remote_session_id = 0;
12101   u64 local_cookie = 0;
12102   u64 remote_cookie = 0;
12103   u8 l2_sublayer_present = 0;
12104   vl_api_l2tpv3_create_tunnel_t *mp;
12105   int ret;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "client_address %U", unformat_ip6_address,
12110                     &client_address))
12111         client_address_set = 1;
12112       else if (unformat (i, "our_address %U", unformat_ip6_address,
12113                          &our_address))
12114         our_address_set = 1;
12115       else if (unformat (i, "local_session_id %d", &local_session_id))
12116         ;
12117       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12118         ;
12119       else if (unformat (i, "local_cookie %lld", &local_cookie))
12120         ;
12121       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12122         ;
12123       else if (unformat (i, "l2-sublayer-present"))
12124         l2_sublayer_present = 1;
12125       else
12126         break;
12127     }
12128
12129   if (client_address_set == 0)
12130     {
12131       errmsg ("client_address required");
12132       return -99;
12133     }
12134
12135   if (our_address_set == 0)
12136     {
12137       errmsg ("our_address required");
12138       return -99;
12139     }
12140
12141   M (L2TPV3_CREATE_TUNNEL, mp);
12142
12143   clib_memcpy (mp->client_address, client_address.as_u8,
12144                sizeof (mp->client_address));
12145
12146   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12147
12148   mp->local_session_id = ntohl (local_session_id);
12149   mp->remote_session_id = ntohl (remote_session_id);
12150   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12151   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12152   mp->l2_sublayer_present = l2_sublayer_present;
12153   mp->is_ipv6 = 1;
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   u32 sw_if_index;
12165   u8 sw_if_index_set = 0;
12166   u64 new_local_cookie = 0;
12167   u64 new_remote_cookie = 0;
12168   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12174         sw_if_index_set = 1;
12175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12176         sw_if_index_set = 1;
12177       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12178         ;
12179       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12180         ;
12181       else
12182         break;
12183     }
12184
12185   if (sw_if_index_set == 0)
12186     {
12187       errmsg ("missing interface name or sw_if_index");
12188       return -99;
12189     }
12190
12191   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12192
12193   mp->sw_if_index = ntohl (sw_if_index);
12194   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12195   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_l2tpv3_interface_enable_disable_t *mp;
12207   u32 sw_if_index;
12208   u8 sw_if_index_set = 0;
12209   u8 enable_disable = 1;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12215         sw_if_index_set = 1;
12216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "enable"))
12219         enable_disable = 1;
12220       else if (unformat (i, "disable"))
12221         enable_disable = 0;
12222       else
12223         break;
12224     }
12225
12226   if (sw_if_index_set == 0)
12227     {
12228       errmsg ("missing interface name or sw_if_index");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12233
12234   mp->sw_if_index = ntohl (sw_if_index);
12235   mp->enable_disable = enable_disable;
12236
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 static int
12243 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12244 {
12245   unformat_input_t *i = vam->input;
12246   vl_api_l2tpv3_set_lookup_key_t *mp;
12247   u8 key = ~0;
12248   int ret;
12249
12250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12251     {
12252       if (unformat (i, "lookup_v6_src"))
12253         key = L2T_LOOKUP_SRC_ADDRESS;
12254       else if (unformat (i, "lookup_v6_dst"))
12255         key = L2T_LOOKUP_DST_ADDRESS;
12256       else if (unformat (i, "lookup_session_id"))
12257         key = L2T_LOOKUP_SESSION_ID;
12258       else
12259         break;
12260     }
12261
12262   if (key == (u8) ~ 0)
12263     {
12264       errmsg ("l2tp session lookup key unset");
12265       return -99;
12266     }
12267
12268   M (L2TPV3_SET_LOOKUP_KEY, mp);
12269
12270   mp->key = key;
12271
12272   S (mp);
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12278   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281
12282   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12283          format_ip6_address, mp->our_address,
12284          format_ip6_address, mp->client_address,
12285          clib_net_to_host_u32 (mp->sw_if_index));
12286
12287   print (vam->ofp,
12288          "   local cookies %016llx %016llx remote cookie %016llx",
12289          clib_net_to_host_u64 (mp->local_cookie[0]),
12290          clib_net_to_host_u64 (mp->local_cookie[1]),
12291          clib_net_to_host_u64 (mp->remote_cookie));
12292
12293   print (vam->ofp, "   local session-id %d remote session-id %d",
12294          clib_net_to_host_u32 (mp->local_session_id),
12295          clib_net_to_host_u32 (mp->remote_session_id));
12296
12297   print (vam->ofp, "   l2 specific sublayer %s\n",
12298          mp->l2_sublayer_present ? "preset" : "absent");
12299
12300 }
12301
12302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12303   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12304 {
12305   vat_main_t *vam = &vat_main;
12306   vat_json_node_t *node = NULL;
12307   struct in6_addr addr;
12308
12309   if (VAT_JSON_ARRAY != vam->json_tree.type)
12310     {
12311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12312       vat_json_init_array (&vam->json_tree);
12313     }
12314   node = vat_json_array_add (&vam->json_tree);
12315
12316   vat_json_init_object (node);
12317
12318   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12319   vat_json_object_add_ip6 (node, "our_address", addr);
12320   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12321   vat_json_object_add_ip6 (node, "client_address", addr);
12322
12323   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12324   vat_json_init_array (lc);
12325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12327   vat_json_object_add_uint (node, "remote_cookie",
12328                             clib_net_to_host_u64 (mp->remote_cookie));
12329
12330   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12331   vat_json_object_add_uint (node, "local_session_id",
12332                             clib_net_to_host_u32 (mp->local_session_id));
12333   vat_json_object_add_uint (node, "remote_session_id",
12334                             clib_net_to_host_u32 (mp->remote_session_id));
12335   vat_json_object_add_string_copy (node, "l2_sublayer",
12336                                    mp->l2_sublayer_present ? (u8 *) "present"
12337                                    : (u8 *) "absent");
12338 }
12339
12340 static int
12341 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12342 {
12343   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12344   vl_api_control_ping_t *mp_ping;
12345   int ret;
12346
12347   /* Get list of l2tpv3-tunnel interfaces */
12348   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12349   S (mp);
12350
12351   /* Use a control ping for synchronization */
12352   MPING (CONTROL_PING, mp_ping);
12353   S (mp_ping);
12354
12355   W (ret);
12356   return ret;
12357 }
12358
12359
12360 static void vl_api_sw_interface_tap_details_t_handler
12361   (vl_api_sw_interface_tap_details_t * mp)
12362 {
12363   vat_main_t *vam = &vat_main;
12364
12365   print (vam->ofp, "%-16s %d",
12366          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12367 }
12368
12369 static void vl_api_sw_interface_tap_details_t_handler_json
12370   (vl_api_sw_interface_tap_details_t * mp)
12371 {
12372   vat_main_t *vam = &vat_main;
12373   vat_json_node_t *node = NULL;
12374
12375   if (VAT_JSON_ARRAY != vam->json_tree.type)
12376     {
12377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12378       vat_json_init_array (&vam->json_tree);
12379     }
12380   node = vat_json_array_add (&vam->json_tree);
12381
12382   vat_json_init_object (node);
12383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12384   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12385 }
12386
12387 static int
12388 api_sw_interface_tap_dump (vat_main_t * vam)
12389 {
12390   vl_api_sw_interface_tap_dump_t *mp;
12391   vl_api_control_ping_t *mp_ping;
12392   int ret;
12393
12394   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12395   /* Get list of tap interfaces */
12396   M (SW_INTERFACE_TAP_DUMP, mp);
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   MPING (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static void vl_api_sw_interface_tap_v2_details_t_handler
12408   (vl_api_sw_interface_tap_v2_details_t * mp)
12409 {
12410   vat_main_t *vam = &vat_main;
12411
12412   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12413                     mp->host_ip4_prefix_len);
12414   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12415                     mp->host_ip6_prefix_len);
12416
12417   print (vam->ofp,
12418          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12419          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12420          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12421          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12422          mp->host_bridge, ip4, ip6);
12423
12424   vec_free (ip4);
12425   vec_free (ip6);
12426 }
12427
12428 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12429   (vl_api_sw_interface_tap_v2_details_t * mp)
12430 {
12431   vat_main_t *vam = &vat_main;
12432   vat_json_node_t *node = NULL;
12433
12434   if (VAT_JSON_ARRAY != vam->json_tree.type)
12435     {
12436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12437       vat_json_init_array (&vam->json_tree);
12438     }
12439   node = vat_json_array_add (&vam->json_tree);
12440
12441   vat_json_init_object (node);
12442   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12443   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12444   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12445   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12446   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12447   vat_json_object_add_string_copy (node, "host_mac_addr",
12448                                    format (0, "%U", format_ethernet_address,
12449                                            &mp->host_mac_addr));
12450   vat_json_object_add_string_copy (node, "host_namespace",
12451                                    mp->host_namespace);
12452   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12453   vat_json_object_add_string_copy (node, "host_ip4_addr",
12454                                    format (0, "%U/%d", format_ip4_address,
12455                                            mp->host_ip4_addr,
12456                                            mp->host_ip4_prefix_len));
12457   vat_json_object_add_string_copy (node, "host_ip6_addr",
12458                                    format (0, "%U/%d", format_ip6_address,
12459                                            mp->host_ip6_addr,
12460                                            mp->host_ip6_prefix_len));
12461
12462 }
12463
12464 static int
12465 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12466 {
12467   vl_api_sw_interface_tap_v2_dump_t *mp;
12468   vl_api_control_ping_t *mp_ping;
12469   int ret;
12470
12471   print (vam->ofp,
12472          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12473          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12474          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12475          "host_ip6_addr");
12476
12477   /* Get list of tap interfaces */
12478   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12479   S (mp);
12480
12481   /* Use a control ping for synchronization */
12482   MPING (CONTROL_PING, mp_ping);
12483   S (mp_ping);
12484
12485   W (ret);
12486   return ret;
12487 }
12488
12489 static uword unformat_vxlan_decap_next
12490   (unformat_input_t * input, va_list * args)
12491 {
12492   u32 *result = va_arg (*args, u32 *);
12493   u32 tmp;
12494
12495   if (unformat (input, "l2"))
12496     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12497   else if (unformat (input, "%d", &tmp))
12498     *result = tmp;
12499   else
12500     return 0;
12501   return 1;
12502 }
12503
12504 static int
12505 api_vxlan_add_del_tunnel (vat_main_t * vam)
12506 {
12507   unformat_input_t *line_input = vam->input;
12508   vl_api_vxlan_add_del_tunnel_t *mp;
12509   ip46_address_t src, dst;
12510   u8 is_add = 1;
12511   u8 ipv4_set = 0, ipv6_set = 0;
12512   u8 src_set = 0;
12513   u8 dst_set = 0;
12514   u8 grp_set = 0;
12515   u32 instance = ~0;
12516   u32 mcast_sw_if_index = ~0;
12517   u32 encap_vrf_id = 0;
12518   u32 decap_next_index = ~0;
12519   u32 vni = 0;
12520   int ret;
12521
12522   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12523   memset (&src, 0, sizeof src);
12524   memset (&dst, 0, sizeof dst);
12525
12526   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12527     {
12528       if (unformat (line_input, "del"))
12529         is_add = 0;
12530       else if (unformat (line_input, "instance %d", &instance))
12531         ;
12532       else
12533         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12534         {
12535           ipv4_set = 1;
12536           src_set = 1;
12537         }
12538       else
12539         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12540         {
12541           ipv4_set = 1;
12542           dst_set = 1;
12543         }
12544       else
12545         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12546         {
12547           ipv6_set = 1;
12548           src_set = 1;
12549         }
12550       else
12551         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12552         {
12553           ipv6_set = 1;
12554           dst_set = 1;
12555         }
12556       else if (unformat (line_input, "group %U %U",
12557                          unformat_ip4_address, &dst.ip4,
12558                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12559         {
12560           grp_set = dst_set = 1;
12561           ipv4_set = 1;
12562         }
12563       else if (unformat (line_input, "group %U",
12564                          unformat_ip4_address, &dst.ip4))
12565         {
12566           grp_set = dst_set = 1;
12567           ipv4_set = 1;
12568         }
12569       else if (unformat (line_input, "group %U %U",
12570                          unformat_ip6_address, &dst.ip6,
12571                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12572         {
12573           grp_set = dst_set = 1;
12574           ipv6_set = 1;
12575         }
12576       else if (unformat (line_input, "group %U",
12577                          unformat_ip6_address, &dst.ip6))
12578         {
12579           grp_set = dst_set = 1;
12580           ipv6_set = 1;
12581         }
12582       else
12583         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12584         ;
12585       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12586         ;
12587       else if (unformat (line_input, "decap-next %U",
12588                          unformat_vxlan_decap_next, &decap_next_index))
12589         ;
12590       else if (unformat (line_input, "vni %d", &vni))
12591         ;
12592       else
12593         {
12594           errmsg ("parse error '%U'", format_unformat_error, line_input);
12595           return -99;
12596         }
12597     }
12598
12599   if (src_set == 0)
12600     {
12601       errmsg ("tunnel src address not specified");
12602       return -99;
12603     }
12604   if (dst_set == 0)
12605     {
12606       errmsg ("tunnel dst address not specified");
12607       return -99;
12608     }
12609
12610   if (grp_set && !ip46_address_is_multicast (&dst))
12611     {
12612       errmsg ("tunnel group address not multicast");
12613       return -99;
12614     }
12615   if (grp_set && mcast_sw_if_index == ~0)
12616     {
12617       errmsg ("tunnel nonexistent multicast device");
12618       return -99;
12619     }
12620   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12621     {
12622       errmsg ("tunnel dst address must be unicast");
12623       return -99;
12624     }
12625
12626
12627   if (ipv4_set && ipv6_set)
12628     {
12629       errmsg ("both IPv4 and IPv6 addresses specified");
12630       return -99;
12631     }
12632
12633   if ((vni == 0) || (vni >> 24))
12634     {
12635       errmsg ("vni not specified or out of range");
12636       return -99;
12637     }
12638
12639   M (VXLAN_ADD_DEL_TUNNEL, mp);
12640
12641   if (ipv6_set)
12642     {
12643       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12644       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12645     }
12646   else
12647     {
12648       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12649       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12650     }
12651
12652   mp->instance = htonl (instance);
12653   mp->encap_vrf_id = ntohl (encap_vrf_id);
12654   mp->decap_next_index = ntohl (decap_next_index);
12655   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12656   mp->vni = ntohl (vni);
12657   mp->is_add = is_add;
12658   mp->is_ipv6 = ipv6_set;
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static void vl_api_vxlan_tunnel_details_t_handler
12666   (vl_api_vxlan_tunnel_details_t * mp)
12667 {
12668   vat_main_t *vam = &vat_main;
12669   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12670   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12671
12672   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12673          ntohl (mp->sw_if_index),
12674          ntohl (mp->instance),
12675          format_ip46_address, &src, IP46_TYPE_ANY,
12676          format_ip46_address, &dst, IP46_TYPE_ANY,
12677          ntohl (mp->encap_vrf_id),
12678          ntohl (mp->decap_next_index), ntohl (mp->vni),
12679          ntohl (mp->mcast_sw_if_index));
12680 }
12681
12682 static void vl_api_vxlan_tunnel_details_t_handler_json
12683   (vl_api_vxlan_tunnel_details_t * mp)
12684 {
12685   vat_main_t *vam = &vat_main;
12686   vat_json_node_t *node = NULL;
12687
12688   if (VAT_JSON_ARRAY != vam->json_tree.type)
12689     {
12690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12691       vat_json_init_array (&vam->json_tree);
12692     }
12693   node = vat_json_array_add (&vam->json_tree);
12694
12695   vat_json_init_object (node);
12696   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12697
12698   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12699
12700   if (mp->is_ipv6)
12701     {
12702       struct in6_addr ip6;
12703
12704       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12705       vat_json_object_add_ip6 (node, "src_address", ip6);
12706       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12707       vat_json_object_add_ip6 (node, "dst_address", ip6);
12708     }
12709   else
12710     {
12711       struct in_addr ip4;
12712
12713       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12714       vat_json_object_add_ip4 (node, "src_address", ip4);
12715       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12716       vat_json_object_add_ip4 (node, "dst_address", ip4);
12717     }
12718   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12719   vat_json_object_add_uint (node, "decap_next_index",
12720                             ntohl (mp->decap_next_index));
12721   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12722   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12723   vat_json_object_add_uint (node, "mcast_sw_if_index",
12724                             ntohl (mp->mcast_sw_if_index));
12725 }
12726
12727 static int
12728 api_vxlan_tunnel_dump (vat_main_t * vam)
12729 {
12730   unformat_input_t *i = vam->input;
12731   vl_api_vxlan_tunnel_dump_t *mp;
12732   vl_api_control_ping_t *mp_ping;
12733   u32 sw_if_index;
12734   u8 sw_if_index_set = 0;
12735   int ret;
12736
12737   /* Parse args required to build the message */
12738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat (i, "sw_if_index %d", &sw_if_index))
12741         sw_if_index_set = 1;
12742       else
12743         break;
12744     }
12745
12746   if (sw_if_index_set == 0)
12747     {
12748       sw_if_index = ~0;
12749     }
12750
12751   if (!vam->json_output)
12752     {
12753       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12754              "sw_if_index", "instance", "src_address", "dst_address",
12755              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12756     }
12757
12758   /* Get list of vxlan-tunnel interfaces */
12759   M (VXLAN_TUNNEL_DUMP, mp);
12760
12761   mp->sw_if_index = htonl (sw_if_index);
12762
12763   S (mp);
12764
12765   /* Use a control ping for synchronization */
12766   MPING (CONTROL_PING, mp_ping);
12767   S (mp_ping);
12768
12769   W (ret);
12770   return ret;
12771 }
12772
12773 static uword unformat_geneve_decap_next
12774   (unformat_input_t * input, va_list * args)
12775 {
12776   u32 *result = va_arg (*args, u32 *);
12777   u32 tmp;
12778
12779   if (unformat (input, "l2"))
12780     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12781   else if (unformat (input, "%d", &tmp))
12782     *result = tmp;
12783   else
12784     return 0;
12785   return 1;
12786 }
12787
12788 static int
12789 api_geneve_add_del_tunnel (vat_main_t * vam)
12790 {
12791   unformat_input_t *line_input = vam->input;
12792   vl_api_geneve_add_del_tunnel_t *mp;
12793   ip46_address_t src, dst;
12794   u8 is_add = 1;
12795   u8 ipv4_set = 0, ipv6_set = 0;
12796   u8 src_set = 0;
12797   u8 dst_set = 0;
12798   u8 grp_set = 0;
12799   u32 mcast_sw_if_index = ~0;
12800   u32 encap_vrf_id = 0;
12801   u32 decap_next_index = ~0;
12802   u32 vni = 0;
12803   int ret;
12804
12805   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12806   memset (&src, 0, sizeof src);
12807   memset (&dst, 0, sizeof dst);
12808
12809   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (line_input, "del"))
12812         is_add = 0;
12813       else
12814         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12815         {
12816           ipv4_set = 1;
12817           src_set = 1;
12818         }
12819       else
12820         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12821         {
12822           ipv4_set = 1;
12823           dst_set = 1;
12824         }
12825       else
12826         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12827         {
12828           ipv6_set = 1;
12829           src_set = 1;
12830         }
12831       else
12832         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12833         {
12834           ipv6_set = 1;
12835           dst_set = 1;
12836         }
12837       else if (unformat (line_input, "group %U %U",
12838                          unformat_ip4_address, &dst.ip4,
12839                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12840         {
12841           grp_set = dst_set = 1;
12842           ipv4_set = 1;
12843         }
12844       else if (unformat (line_input, "group %U",
12845                          unformat_ip4_address, &dst.ip4))
12846         {
12847           grp_set = dst_set = 1;
12848           ipv4_set = 1;
12849         }
12850       else if (unformat (line_input, "group %U %U",
12851                          unformat_ip6_address, &dst.ip6,
12852                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12853         {
12854           grp_set = dst_set = 1;
12855           ipv6_set = 1;
12856         }
12857       else if (unformat (line_input, "group %U",
12858                          unformat_ip6_address, &dst.ip6))
12859         {
12860           grp_set = dst_set = 1;
12861           ipv6_set = 1;
12862         }
12863       else
12864         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12865         ;
12866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12867         ;
12868       else if (unformat (line_input, "decap-next %U",
12869                          unformat_geneve_decap_next, &decap_next_index))
12870         ;
12871       else if (unformat (line_input, "vni %d", &vni))
12872         ;
12873       else
12874         {
12875           errmsg ("parse error '%U'", format_unformat_error, line_input);
12876           return -99;
12877         }
12878     }
12879
12880   if (src_set == 0)
12881     {
12882       errmsg ("tunnel src address not specified");
12883       return -99;
12884     }
12885   if (dst_set == 0)
12886     {
12887       errmsg ("tunnel dst address not specified");
12888       return -99;
12889     }
12890
12891   if (grp_set && !ip46_address_is_multicast (&dst))
12892     {
12893       errmsg ("tunnel group address not multicast");
12894       return -99;
12895     }
12896   if (grp_set && mcast_sw_if_index == ~0)
12897     {
12898       errmsg ("tunnel nonexistent multicast device");
12899       return -99;
12900     }
12901   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12902     {
12903       errmsg ("tunnel dst address must be unicast");
12904       return -99;
12905     }
12906
12907
12908   if (ipv4_set && ipv6_set)
12909     {
12910       errmsg ("both IPv4 and IPv6 addresses specified");
12911       return -99;
12912     }
12913
12914   if ((vni == 0) || (vni >> 24))
12915     {
12916       errmsg ("vni not specified or out of range");
12917       return -99;
12918     }
12919
12920   M (GENEVE_ADD_DEL_TUNNEL, mp);
12921
12922   if (ipv6_set)
12923     {
12924       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12925       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12926     }
12927   else
12928     {
12929       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12930       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12931     }
12932   mp->encap_vrf_id = ntohl (encap_vrf_id);
12933   mp->decap_next_index = ntohl (decap_next_index);
12934   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12935   mp->vni = ntohl (vni);
12936   mp->is_add = is_add;
12937   mp->is_ipv6 = ipv6_set;
12938
12939   S (mp);
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static void vl_api_geneve_tunnel_details_t_handler
12945   (vl_api_geneve_tunnel_details_t * mp)
12946 {
12947   vat_main_t *vam = &vat_main;
12948   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12949   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12950
12951   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12952          ntohl (mp->sw_if_index),
12953          format_ip46_address, &src, IP46_TYPE_ANY,
12954          format_ip46_address, &dst, IP46_TYPE_ANY,
12955          ntohl (mp->encap_vrf_id),
12956          ntohl (mp->decap_next_index), ntohl (mp->vni),
12957          ntohl (mp->mcast_sw_if_index));
12958 }
12959
12960 static void vl_api_geneve_tunnel_details_t_handler_json
12961   (vl_api_geneve_tunnel_details_t * mp)
12962 {
12963   vat_main_t *vam = &vat_main;
12964   vat_json_node_t *node = NULL;
12965
12966   if (VAT_JSON_ARRAY != vam->json_tree.type)
12967     {
12968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12969       vat_json_init_array (&vam->json_tree);
12970     }
12971   node = vat_json_array_add (&vam->json_tree);
12972
12973   vat_json_init_object (node);
12974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12975   if (mp->is_ipv6)
12976     {
12977       struct in6_addr ip6;
12978
12979       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12980       vat_json_object_add_ip6 (node, "src_address", ip6);
12981       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12982       vat_json_object_add_ip6 (node, "dst_address", ip6);
12983     }
12984   else
12985     {
12986       struct in_addr ip4;
12987
12988       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12989       vat_json_object_add_ip4 (node, "src_address", ip4);
12990       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12991       vat_json_object_add_ip4 (node, "dst_address", ip4);
12992     }
12993   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12994   vat_json_object_add_uint (node, "decap_next_index",
12995                             ntohl (mp->decap_next_index));
12996   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12997   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12998   vat_json_object_add_uint (node, "mcast_sw_if_index",
12999                             ntohl (mp->mcast_sw_if_index));
13000 }
13001
13002 static int
13003 api_geneve_tunnel_dump (vat_main_t * vam)
13004 {
13005   unformat_input_t *i = vam->input;
13006   vl_api_geneve_tunnel_dump_t *mp;
13007   vl_api_control_ping_t *mp_ping;
13008   u32 sw_if_index;
13009   u8 sw_if_index_set = 0;
13010   int ret;
13011
13012   /* Parse args required to build the message */
13013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13014     {
13015       if (unformat (i, "sw_if_index %d", &sw_if_index))
13016         sw_if_index_set = 1;
13017       else
13018         break;
13019     }
13020
13021   if (sw_if_index_set == 0)
13022     {
13023       sw_if_index = ~0;
13024     }
13025
13026   if (!vam->json_output)
13027     {
13028       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13029              "sw_if_index", "local_address", "remote_address",
13030              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13031     }
13032
13033   /* Get list of geneve-tunnel interfaces */
13034   M (GENEVE_TUNNEL_DUMP, mp);
13035
13036   mp->sw_if_index = htonl (sw_if_index);
13037
13038   S (mp);
13039
13040   /* Use a control ping for synchronization */
13041   M (CONTROL_PING, mp_ping);
13042   S (mp_ping);
13043
13044   W (ret);
13045   return ret;
13046 }
13047
13048 static int
13049 api_gre_add_del_tunnel (vat_main_t * vam)
13050 {
13051   unformat_input_t *line_input = vam->input;
13052   vl_api_gre_add_del_tunnel_t *mp;
13053   ip4_address_t src4, dst4;
13054   ip6_address_t src6, dst6;
13055   u8 is_add = 1;
13056   u8 ipv4_set = 0;
13057   u8 ipv6_set = 0;
13058   u8 t_type = GRE_TUNNEL_TYPE_L3;
13059   u8 src_set = 0;
13060   u8 dst_set = 0;
13061   u32 outer_fib_id = 0;
13062   u32 session_id = 0;
13063   u32 instance = ~0;
13064   int ret;
13065
13066   memset (&src4, 0, sizeof src4);
13067   memset (&dst4, 0, sizeof dst4);
13068   memset (&src6, 0, sizeof src6);
13069   memset (&dst6, 0, sizeof dst6);
13070
13071   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13072     {
13073       if (unformat (line_input, "del"))
13074         is_add = 0;
13075       else if (unformat (line_input, "instance %d", &instance))
13076         ;
13077       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13078         {
13079           src_set = 1;
13080           ipv4_set = 1;
13081         }
13082       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13083         {
13084           dst_set = 1;
13085           ipv4_set = 1;
13086         }
13087       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13088         {
13089           src_set = 1;
13090           ipv6_set = 1;
13091         }
13092       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13093         {
13094           dst_set = 1;
13095           ipv6_set = 1;
13096         }
13097       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13098         ;
13099       else if (unformat (line_input, "teb"))
13100         t_type = GRE_TUNNEL_TYPE_TEB;
13101       else if (unformat (line_input, "erspan %d", &session_id))
13102         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13103       else
13104         {
13105           errmsg ("parse error '%U'", format_unformat_error, line_input);
13106           return -99;
13107         }
13108     }
13109
13110   if (src_set == 0)
13111     {
13112       errmsg ("tunnel src address not specified");
13113       return -99;
13114     }
13115   if (dst_set == 0)
13116     {
13117       errmsg ("tunnel dst address not specified");
13118       return -99;
13119     }
13120   if (ipv4_set && ipv6_set)
13121     {
13122       errmsg ("both IPv4 and IPv6 addresses specified");
13123       return -99;
13124     }
13125
13126
13127   M (GRE_ADD_DEL_TUNNEL, mp);
13128
13129   if (ipv4_set)
13130     {
13131       clib_memcpy (&mp->src_address, &src4, 4);
13132       clib_memcpy (&mp->dst_address, &dst4, 4);
13133     }
13134   else
13135     {
13136       clib_memcpy (&mp->src_address, &src6, 16);
13137       clib_memcpy (&mp->dst_address, &dst6, 16);
13138     }
13139   mp->instance = htonl (instance);
13140   mp->outer_fib_id = htonl (outer_fib_id);
13141   mp->is_add = is_add;
13142   mp->session_id = htons ((u16) session_id);
13143   mp->tunnel_type = t_type;
13144   mp->is_ipv6 = ipv6_set;
13145
13146   S (mp);
13147   W (ret);
13148   return ret;
13149 }
13150
13151 static void vl_api_gre_tunnel_details_t_handler
13152   (vl_api_gre_tunnel_details_t * mp)
13153 {
13154   vat_main_t *vam = &vat_main;
13155   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13156   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13157
13158   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13159          ntohl (mp->sw_if_index),
13160          ntohl (mp->instance),
13161          format_ip46_address, &src, IP46_TYPE_ANY,
13162          format_ip46_address, &dst, IP46_TYPE_ANY,
13163          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13164 }
13165
13166 static void vl_api_gre_tunnel_details_t_handler_json
13167   (vl_api_gre_tunnel_details_t * mp)
13168 {
13169   vat_main_t *vam = &vat_main;
13170   vat_json_node_t *node = NULL;
13171   struct in_addr ip4;
13172   struct in6_addr ip6;
13173
13174   if (VAT_JSON_ARRAY != vam->json_tree.type)
13175     {
13176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13177       vat_json_init_array (&vam->json_tree);
13178     }
13179   node = vat_json_array_add (&vam->json_tree);
13180
13181   vat_json_init_object (node);
13182   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13183   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13184   if (!mp->is_ipv6)
13185     {
13186       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13187       vat_json_object_add_ip4 (node, "src_address", ip4);
13188       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13189       vat_json_object_add_ip4 (node, "dst_address", ip4);
13190     }
13191   else
13192     {
13193       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13194       vat_json_object_add_ip6 (node, "src_address", ip6);
13195       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13196       vat_json_object_add_ip6 (node, "dst_address", ip6);
13197     }
13198   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13199   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13200   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13201   vat_json_object_add_uint (node, "session_id", mp->session_id);
13202 }
13203
13204 static int
13205 api_gre_tunnel_dump (vat_main_t * vam)
13206 {
13207   unformat_input_t *i = vam->input;
13208   vl_api_gre_tunnel_dump_t *mp;
13209   vl_api_control_ping_t *mp_ping;
13210   u32 sw_if_index;
13211   u8 sw_if_index_set = 0;
13212   int ret;
13213
13214   /* Parse args required to build the message */
13215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13216     {
13217       if (unformat (i, "sw_if_index %d", &sw_if_index))
13218         sw_if_index_set = 1;
13219       else
13220         break;
13221     }
13222
13223   if (sw_if_index_set == 0)
13224     {
13225       sw_if_index = ~0;
13226     }
13227
13228   if (!vam->json_output)
13229     {
13230       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13231              "sw_if_index", "instance", "src_address", "dst_address",
13232              "tunnel_type", "outer_fib_id", "session_id");
13233     }
13234
13235   /* Get list of gre-tunnel interfaces */
13236   M (GRE_TUNNEL_DUMP, mp);
13237
13238   mp->sw_if_index = htonl (sw_if_index);
13239
13240   S (mp);
13241
13242   /* Use a control ping for synchronization */
13243   MPING (CONTROL_PING, mp_ping);
13244   S (mp_ping);
13245
13246   W (ret);
13247   return ret;
13248 }
13249
13250 static int
13251 api_l2_fib_clear_table (vat_main_t * vam)
13252 {
13253 //  unformat_input_t * i = vam->input;
13254   vl_api_l2_fib_clear_table_t *mp;
13255   int ret;
13256
13257   M (L2_FIB_CLEAR_TABLE, mp);
13258
13259   S (mp);
13260   W (ret);
13261   return ret;
13262 }
13263
13264 static int
13265 api_l2_interface_efp_filter (vat_main_t * vam)
13266 {
13267   unformat_input_t *i = vam->input;
13268   vl_api_l2_interface_efp_filter_t *mp;
13269   u32 sw_if_index;
13270   u8 enable = 1;
13271   u8 sw_if_index_set = 0;
13272   int ret;
13273
13274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13275     {
13276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13277         sw_if_index_set = 1;
13278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13279         sw_if_index_set = 1;
13280       else if (unformat (i, "enable"))
13281         enable = 1;
13282       else if (unformat (i, "disable"))
13283         enable = 0;
13284       else
13285         {
13286           clib_warning ("parse error '%U'", format_unformat_error, i);
13287           return -99;
13288         }
13289     }
13290
13291   if (sw_if_index_set == 0)
13292     {
13293       errmsg ("missing sw_if_index");
13294       return -99;
13295     }
13296
13297   M (L2_INTERFACE_EFP_FILTER, mp);
13298
13299   mp->sw_if_index = ntohl (sw_if_index);
13300   mp->enable_disable = enable;
13301
13302   S (mp);
13303   W (ret);
13304   return ret;
13305 }
13306
13307 #define foreach_vtr_op                          \
13308 _("disable",  L2_VTR_DISABLED)                  \
13309 _("push-1",  L2_VTR_PUSH_1)                     \
13310 _("push-2",  L2_VTR_PUSH_2)                     \
13311 _("pop-1",  L2_VTR_POP_1)                       \
13312 _("pop-2",  L2_VTR_POP_2)                       \
13313 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13314 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13315 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13316 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13317
13318 static int
13319 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13320 {
13321   unformat_input_t *i = vam->input;
13322   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13323   u32 sw_if_index;
13324   u8 sw_if_index_set = 0;
13325   u8 vtr_op_set = 0;
13326   u32 vtr_op = 0;
13327   u32 push_dot1q = 1;
13328   u32 tag1 = ~0;
13329   u32 tag2 = ~0;
13330   int ret;
13331
13332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13333     {
13334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13335         sw_if_index_set = 1;
13336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13337         sw_if_index_set = 1;
13338       else if (unformat (i, "vtr_op %d", &vtr_op))
13339         vtr_op_set = 1;
13340 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13341       foreach_vtr_op
13342 #undef _
13343         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13344         ;
13345       else if (unformat (i, "tag1 %d", &tag1))
13346         ;
13347       else if (unformat (i, "tag2 %d", &tag2))
13348         ;
13349       else
13350         {
13351           clib_warning ("parse error '%U'", format_unformat_error, i);
13352           return -99;
13353         }
13354     }
13355
13356   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13357     {
13358       errmsg ("missing vtr operation or sw_if_index");
13359       return -99;
13360     }
13361
13362   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13363   mp->sw_if_index = ntohl (sw_if_index);
13364   mp->vtr_op = ntohl (vtr_op);
13365   mp->push_dot1q = ntohl (push_dot1q);
13366   mp->tag1 = ntohl (tag1);
13367   mp->tag2 = ntohl (tag2);
13368
13369   S (mp);
13370   W (ret);
13371   return ret;
13372 }
13373
13374 static int
13375 api_create_vhost_user_if (vat_main_t * vam)
13376 {
13377   unformat_input_t *i = vam->input;
13378   vl_api_create_vhost_user_if_t *mp;
13379   u8 *file_name;
13380   u8 is_server = 0;
13381   u8 file_name_set = 0;
13382   u32 custom_dev_instance = ~0;
13383   u8 hwaddr[6];
13384   u8 use_custom_mac = 0;
13385   u8 *tag = 0;
13386   int ret;
13387
13388   /* Shut up coverity */
13389   memset (hwaddr, 0, sizeof (hwaddr));
13390
13391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13392     {
13393       if (unformat (i, "socket %s", &file_name))
13394         {
13395           file_name_set = 1;
13396         }
13397       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13398         ;
13399       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13400         use_custom_mac = 1;
13401       else if (unformat (i, "server"))
13402         is_server = 1;
13403       else if (unformat (i, "tag %s", &tag))
13404         ;
13405       else
13406         break;
13407     }
13408
13409   if (file_name_set == 0)
13410     {
13411       errmsg ("missing socket file name");
13412       return -99;
13413     }
13414
13415   if (vec_len (file_name) > 255)
13416     {
13417       errmsg ("socket file name too long");
13418       return -99;
13419     }
13420   vec_add1 (file_name, 0);
13421
13422   M (CREATE_VHOST_USER_IF, mp);
13423
13424   mp->is_server = is_server;
13425   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13426   vec_free (file_name);
13427   if (custom_dev_instance != ~0)
13428     {
13429       mp->renumber = 1;
13430       mp->custom_dev_instance = ntohl (custom_dev_instance);
13431     }
13432   mp->use_custom_mac = use_custom_mac;
13433   clib_memcpy (mp->mac_address, hwaddr, 6);
13434   if (tag)
13435     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13436   vec_free (tag);
13437
13438   S (mp);
13439   W (ret);
13440   return ret;
13441 }
13442
13443 static int
13444 api_modify_vhost_user_if (vat_main_t * vam)
13445 {
13446   unformat_input_t *i = vam->input;
13447   vl_api_modify_vhost_user_if_t *mp;
13448   u8 *file_name;
13449   u8 is_server = 0;
13450   u8 file_name_set = 0;
13451   u32 custom_dev_instance = ~0;
13452   u8 sw_if_index_set = 0;
13453   u32 sw_if_index = (u32) ~ 0;
13454   int ret;
13455
13456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13457     {
13458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13459         sw_if_index_set = 1;
13460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13461         sw_if_index_set = 1;
13462       else if (unformat (i, "socket %s", &file_name))
13463         {
13464           file_name_set = 1;
13465         }
13466       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13467         ;
13468       else if (unformat (i, "server"))
13469         is_server = 1;
13470       else
13471         break;
13472     }
13473
13474   if (sw_if_index_set == 0)
13475     {
13476       errmsg ("missing sw_if_index or interface name");
13477       return -99;
13478     }
13479
13480   if (file_name_set == 0)
13481     {
13482       errmsg ("missing socket file name");
13483       return -99;
13484     }
13485
13486   if (vec_len (file_name) > 255)
13487     {
13488       errmsg ("socket file name too long");
13489       return -99;
13490     }
13491   vec_add1 (file_name, 0);
13492
13493   M (MODIFY_VHOST_USER_IF, mp);
13494
13495   mp->sw_if_index = ntohl (sw_if_index);
13496   mp->is_server = is_server;
13497   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13498   vec_free (file_name);
13499   if (custom_dev_instance != ~0)
13500     {
13501       mp->renumber = 1;
13502       mp->custom_dev_instance = ntohl (custom_dev_instance);
13503     }
13504
13505   S (mp);
13506   W (ret);
13507   return ret;
13508 }
13509
13510 static int
13511 api_delete_vhost_user_if (vat_main_t * vam)
13512 {
13513   unformat_input_t *i = vam->input;
13514   vl_api_delete_vhost_user_if_t *mp;
13515   u32 sw_if_index = ~0;
13516   u8 sw_if_index_set = 0;
13517   int ret;
13518
13519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13520     {
13521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13522         sw_if_index_set = 1;
13523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13524         sw_if_index_set = 1;
13525       else
13526         break;
13527     }
13528
13529   if (sw_if_index_set == 0)
13530     {
13531       errmsg ("missing sw_if_index or interface name");
13532       return -99;
13533     }
13534
13535
13536   M (DELETE_VHOST_USER_IF, mp);
13537
13538   mp->sw_if_index = ntohl (sw_if_index);
13539
13540   S (mp);
13541   W (ret);
13542   return ret;
13543 }
13544
13545 static void vl_api_sw_interface_vhost_user_details_t_handler
13546   (vl_api_sw_interface_vhost_user_details_t * mp)
13547 {
13548   vat_main_t *vam = &vat_main;
13549
13550   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13551          (char *) mp->interface_name,
13552          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13553          clib_net_to_host_u64 (mp->features), mp->is_server,
13554          ntohl (mp->num_regions), (char *) mp->sock_filename);
13555   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13556 }
13557
13558 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13559   (vl_api_sw_interface_vhost_user_details_t * mp)
13560 {
13561   vat_main_t *vam = &vat_main;
13562   vat_json_node_t *node = NULL;
13563
13564   if (VAT_JSON_ARRAY != vam->json_tree.type)
13565     {
13566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13567       vat_json_init_array (&vam->json_tree);
13568     }
13569   node = vat_json_array_add (&vam->json_tree);
13570
13571   vat_json_init_object (node);
13572   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13573   vat_json_object_add_string_copy (node, "interface_name",
13574                                    mp->interface_name);
13575   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13576                             ntohl (mp->virtio_net_hdr_sz));
13577   vat_json_object_add_uint (node, "features",
13578                             clib_net_to_host_u64 (mp->features));
13579   vat_json_object_add_uint (node, "is_server", mp->is_server);
13580   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13581   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13582   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13583 }
13584
13585 static int
13586 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13587 {
13588   vl_api_sw_interface_vhost_user_dump_t *mp;
13589   vl_api_control_ping_t *mp_ping;
13590   int ret;
13591   print (vam->ofp,
13592          "Interface name            idx hdr_sz features server regions filename");
13593
13594   /* Get list of vhost-user interfaces */
13595   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13596   S (mp);
13597
13598   /* Use a control ping for synchronization */
13599   MPING (CONTROL_PING, mp_ping);
13600   S (mp_ping);
13601
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_show_version (vat_main_t * vam)
13608 {
13609   vl_api_show_version_t *mp;
13610   int ret;
13611
13612   M (SHOW_VERSION, mp);
13613
13614   S (mp);
13615   W (ret);
13616   return ret;
13617 }
13618
13619
13620 static int
13621 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13622 {
13623   unformat_input_t *line_input = vam->input;
13624   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13625   ip4_address_t local4, remote4;
13626   ip6_address_t local6, remote6;
13627   u8 is_add = 1;
13628   u8 ipv4_set = 0, ipv6_set = 0;
13629   u8 local_set = 0;
13630   u8 remote_set = 0;
13631   u8 grp_set = 0;
13632   u32 mcast_sw_if_index = ~0;
13633   u32 encap_vrf_id = 0;
13634   u32 decap_vrf_id = 0;
13635   u8 protocol = ~0;
13636   u32 vni;
13637   u8 vni_set = 0;
13638   int ret;
13639
13640   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13641   memset (&local4, 0, sizeof local4);
13642   memset (&remote4, 0, sizeof remote4);
13643   memset (&local6, 0, sizeof local6);
13644   memset (&remote6, 0, sizeof remote6);
13645
13646   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13647     {
13648       if (unformat (line_input, "del"))
13649         is_add = 0;
13650       else if (unformat (line_input, "local %U",
13651                          unformat_ip4_address, &local4))
13652         {
13653           local_set = 1;
13654           ipv4_set = 1;
13655         }
13656       else if (unformat (line_input, "remote %U",
13657                          unformat_ip4_address, &remote4))
13658         {
13659           remote_set = 1;
13660           ipv4_set = 1;
13661         }
13662       else if (unformat (line_input, "local %U",
13663                          unformat_ip6_address, &local6))
13664         {
13665           local_set = 1;
13666           ipv6_set = 1;
13667         }
13668       else if (unformat (line_input, "remote %U",
13669                          unformat_ip6_address, &remote6))
13670         {
13671           remote_set = 1;
13672           ipv6_set = 1;
13673         }
13674       else if (unformat (line_input, "group %U %U",
13675                          unformat_ip4_address, &remote4,
13676                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13677         {
13678           grp_set = remote_set = 1;
13679           ipv4_set = 1;
13680         }
13681       else if (unformat (line_input, "group %U",
13682                          unformat_ip4_address, &remote4))
13683         {
13684           grp_set = remote_set = 1;
13685           ipv4_set = 1;
13686         }
13687       else if (unformat (line_input, "group %U %U",
13688                          unformat_ip6_address, &remote6,
13689                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13690         {
13691           grp_set = remote_set = 1;
13692           ipv6_set = 1;
13693         }
13694       else if (unformat (line_input, "group %U",
13695                          unformat_ip6_address, &remote6))
13696         {
13697           grp_set = remote_set = 1;
13698           ipv6_set = 1;
13699         }
13700       else
13701         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13702         ;
13703       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13704         ;
13705       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13706         ;
13707       else if (unformat (line_input, "vni %d", &vni))
13708         vni_set = 1;
13709       else if (unformat (line_input, "next-ip4"))
13710         protocol = 1;
13711       else if (unformat (line_input, "next-ip6"))
13712         protocol = 2;
13713       else if (unformat (line_input, "next-ethernet"))
13714         protocol = 3;
13715       else if (unformat (line_input, "next-nsh"))
13716         protocol = 4;
13717       else
13718         {
13719           errmsg ("parse error '%U'", format_unformat_error, line_input);
13720           return -99;
13721         }
13722     }
13723
13724   if (local_set == 0)
13725     {
13726       errmsg ("tunnel local address not specified");
13727       return -99;
13728     }
13729   if (remote_set == 0)
13730     {
13731       errmsg ("tunnel remote address not specified");
13732       return -99;
13733     }
13734   if (grp_set && mcast_sw_if_index == ~0)
13735     {
13736       errmsg ("tunnel nonexistent multicast device");
13737       return -99;
13738     }
13739   if (ipv4_set && ipv6_set)
13740     {
13741       errmsg ("both IPv4 and IPv6 addresses specified");
13742       return -99;
13743     }
13744
13745   if (vni_set == 0)
13746     {
13747       errmsg ("vni not specified");
13748       return -99;
13749     }
13750
13751   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13752
13753
13754   if (ipv6_set)
13755     {
13756       clib_memcpy (&mp->local, &local6, sizeof (local6));
13757       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13758     }
13759   else
13760     {
13761       clib_memcpy (&mp->local, &local4, sizeof (local4));
13762       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13763     }
13764
13765   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13766   mp->encap_vrf_id = ntohl (encap_vrf_id);
13767   mp->decap_vrf_id = ntohl (decap_vrf_id);
13768   mp->protocol = protocol;
13769   mp->vni = ntohl (vni);
13770   mp->is_add = is_add;
13771   mp->is_ipv6 = ipv6_set;
13772
13773   S (mp);
13774   W (ret);
13775   return ret;
13776 }
13777
13778 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13779   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13780 {
13781   vat_main_t *vam = &vat_main;
13782   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13783   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13784
13785   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13786          ntohl (mp->sw_if_index),
13787          format_ip46_address, &local, IP46_TYPE_ANY,
13788          format_ip46_address, &remote, IP46_TYPE_ANY,
13789          ntohl (mp->vni), mp->protocol,
13790          ntohl (mp->mcast_sw_if_index),
13791          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13792 }
13793
13794
13795 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13796   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13797 {
13798   vat_main_t *vam = &vat_main;
13799   vat_json_node_t *node = NULL;
13800   struct in_addr ip4;
13801   struct in6_addr ip6;
13802
13803   if (VAT_JSON_ARRAY != vam->json_tree.type)
13804     {
13805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13806       vat_json_init_array (&vam->json_tree);
13807     }
13808   node = vat_json_array_add (&vam->json_tree);
13809
13810   vat_json_init_object (node);
13811   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13812   if (mp->is_ipv6)
13813     {
13814       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13815       vat_json_object_add_ip6 (node, "local", ip6);
13816       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13817       vat_json_object_add_ip6 (node, "remote", ip6);
13818     }
13819   else
13820     {
13821       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13822       vat_json_object_add_ip4 (node, "local", ip4);
13823       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13824       vat_json_object_add_ip4 (node, "remote", ip4);
13825     }
13826   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13827   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13828   vat_json_object_add_uint (node, "mcast_sw_if_index",
13829                             ntohl (mp->mcast_sw_if_index));
13830   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13831   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13832   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13833 }
13834
13835 static int
13836 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13837 {
13838   unformat_input_t *i = vam->input;
13839   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13840   vl_api_control_ping_t *mp_ping;
13841   u32 sw_if_index;
13842   u8 sw_if_index_set = 0;
13843   int ret;
13844
13845   /* Parse args required to build the message */
13846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13847     {
13848       if (unformat (i, "sw_if_index %d", &sw_if_index))
13849         sw_if_index_set = 1;
13850       else
13851         break;
13852     }
13853
13854   if (sw_if_index_set == 0)
13855     {
13856       sw_if_index = ~0;
13857     }
13858
13859   if (!vam->json_output)
13860     {
13861       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13862              "sw_if_index", "local", "remote", "vni",
13863              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13864     }
13865
13866   /* Get list of vxlan-tunnel interfaces */
13867   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13868
13869   mp->sw_if_index = htonl (sw_if_index);
13870
13871   S (mp);
13872
13873   /* Use a control ping for synchronization */
13874   MPING (CONTROL_PING, mp_ping);
13875   S (mp_ping);
13876
13877   W (ret);
13878   return ret;
13879 }
13880
13881 static void vl_api_l2_fib_table_details_t_handler
13882   (vl_api_l2_fib_table_details_t * mp)
13883 {
13884   vat_main_t *vam = &vat_main;
13885
13886   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13887          "       %d       %d     %d",
13888          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13889          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13890          mp->bvi_mac);
13891 }
13892
13893 static void vl_api_l2_fib_table_details_t_handler_json
13894   (vl_api_l2_fib_table_details_t * mp)
13895 {
13896   vat_main_t *vam = &vat_main;
13897   vat_json_node_t *node = NULL;
13898
13899   if (VAT_JSON_ARRAY != vam->json_tree.type)
13900     {
13901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13902       vat_json_init_array (&vam->json_tree);
13903     }
13904   node = vat_json_array_add (&vam->json_tree);
13905
13906   vat_json_init_object (node);
13907   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13908   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13909   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13910   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13911   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13912   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13913 }
13914
13915 static int
13916 api_l2_fib_table_dump (vat_main_t * vam)
13917 {
13918   unformat_input_t *i = vam->input;
13919   vl_api_l2_fib_table_dump_t *mp;
13920   vl_api_control_ping_t *mp_ping;
13921   u32 bd_id;
13922   u8 bd_id_set = 0;
13923   int ret;
13924
13925   /* Parse args required to build the message */
13926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13927     {
13928       if (unformat (i, "bd_id %d", &bd_id))
13929         bd_id_set = 1;
13930       else
13931         break;
13932     }
13933
13934   if (bd_id_set == 0)
13935     {
13936       errmsg ("missing bridge domain");
13937       return -99;
13938     }
13939
13940   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13941
13942   /* Get list of l2 fib entries */
13943   M (L2_FIB_TABLE_DUMP, mp);
13944
13945   mp->bd_id = ntohl (bd_id);
13946   S (mp);
13947
13948   /* Use a control ping for synchronization */
13949   MPING (CONTROL_PING, mp_ping);
13950   S (mp_ping);
13951
13952   W (ret);
13953   return ret;
13954 }
13955
13956
13957 static int
13958 api_interface_name_renumber (vat_main_t * vam)
13959 {
13960   unformat_input_t *line_input = vam->input;
13961   vl_api_interface_name_renumber_t *mp;
13962   u32 sw_if_index = ~0;
13963   u32 new_show_dev_instance = ~0;
13964   int ret;
13965
13966   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13967     {
13968       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13969                     &sw_if_index))
13970         ;
13971       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13972         ;
13973       else if (unformat (line_input, "new_show_dev_instance %d",
13974                          &new_show_dev_instance))
13975         ;
13976       else
13977         break;
13978     }
13979
13980   if (sw_if_index == ~0)
13981     {
13982       errmsg ("missing interface name or sw_if_index");
13983       return -99;
13984     }
13985
13986   if (new_show_dev_instance == ~0)
13987     {
13988       errmsg ("missing new_show_dev_instance");
13989       return -99;
13990     }
13991
13992   M (INTERFACE_NAME_RENUMBER, mp);
13993
13994   mp->sw_if_index = ntohl (sw_if_index);
13995   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13996
13997   S (mp);
13998   W (ret);
13999   return ret;
14000 }
14001
14002 static int
14003 api_want_ip4_arp_events (vat_main_t * vam)
14004 {
14005   unformat_input_t *line_input = vam->input;
14006   vl_api_want_ip4_arp_events_t *mp;
14007   ip4_address_t address;
14008   int address_set = 0;
14009   u32 enable_disable = 1;
14010   int ret;
14011
14012   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14013     {
14014       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14015         address_set = 1;
14016       else if (unformat (line_input, "del"))
14017         enable_disable = 0;
14018       else
14019         break;
14020     }
14021
14022   if (address_set == 0)
14023     {
14024       errmsg ("missing addresses");
14025       return -99;
14026     }
14027
14028   M (WANT_IP4_ARP_EVENTS, mp);
14029   mp->enable_disable = enable_disable;
14030   mp->pid = htonl (getpid ());
14031   mp->address = address.as_u32;
14032
14033   S (mp);
14034   W (ret);
14035   return ret;
14036 }
14037
14038 static int
14039 api_want_ip6_nd_events (vat_main_t * vam)
14040 {
14041   unformat_input_t *line_input = vam->input;
14042   vl_api_want_ip6_nd_events_t *mp;
14043   ip6_address_t address;
14044   int address_set = 0;
14045   u32 enable_disable = 1;
14046   int ret;
14047
14048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14051         address_set = 1;
14052       else if (unformat (line_input, "del"))
14053         enable_disable = 0;
14054       else
14055         break;
14056     }
14057
14058   if (address_set == 0)
14059     {
14060       errmsg ("missing addresses");
14061       return -99;
14062     }
14063
14064   M (WANT_IP6_ND_EVENTS, mp);
14065   mp->enable_disable = enable_disable;
14066   mp->pid = htonl (getpid ());
14067   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14068
14069   S (mp);
14070   W (ret);
14071   return ret;
14072 }
14073
14074 static int
14075 api_want_l2_macs_events (vat_main_t * vam)
14076 {
14077   unformat_input_t *line_input = vam->input;
14078   vl_api_want_l2_macs_events_t *mp;
14079   u8 enable_disable = 1;
14080   u32 scan_delay = 0;
14081   u32 max_macs_in_event = 0;
14082   u32 learn_limit = 0;
14083   int ret;
14084
14085   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14086     {
14087       if (unformat (line_input, "learn-limit %d", &learn_limit))
14088         ;
14089       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14090         ;
14091       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14092         ;
14093       else if (unformat (line_input, "disable"))
14094         enable_disable = 0;
14095       else
14096         break;
14097     }
14098
14099   M (WANT_L2_MACS_EVENTS, mp);
14100   mp->enable_disable = enable_disable;
14101   mp->pid = htonl (getpid ());
14102   mp->learn_limit = htonl (learn_limit);
14103   mp->scan_delay = (u8) scan_delay;
14104   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14105   S (mp);
14106   W (ret);
14107   return ret;
14108 }
14109
14110 static int
14111 api_input_acl_set_interface (vat_main_t * vam)
14112 {
14113   unformat_input_t *i = vam->input;
14114   vl_api_input_acl_set_interface_t *mp;
14115   u32 sw_if_index;
14116   int sw_if_index_set;
14117   u32 ip4_table_index = ~0;
14118   u32 ip6_table_index = ~0;
14119   u32 l2_table_index = ~0;
14120   u8 is_add = 1;
14121   int ret;
14122
14123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14124     {
14125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14126         sw_if_index_set = 1;
14127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14128         sw_if_index_set = 1;
14129       else if (unformat (i, "del"))
14130         is_add = 0;
14131       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14132         ;
14133       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14134         ;
14135       else if (unformat (i, "l2-table %d", &l2_table_index))
14136         ;
14137       else
14138         {
14139           clib_warning ("parse error '%U'", format_unformat_error, i);
14140           return -99;
14141         }
14142     }
14143
14144   if (sw_if_index_set == 0)
14145     {
14146       errmsg ("missing interface name or sw_if_index");
14147       return -99;
14148     }
14149
14150   M (INPUT_ACL_SET_INTERFACE, mp);
14151
14152   mp->sw_if_index = ntohl (sw_if_index);
14153   mp->ip4_table_index = ntohl (ip4_table_index);
14154   mp->ip6_table_index = ntohl (ip6_table_index);
14155   mp->l2_table_index = ntohl (l2_table_index);
14156   mp->is_add = is_add;
14157
14158   S (mp);
14159   W (ret);
14160   return ret;
14161 }
14162
14163 static int
14164 api_output_acl_set_interface (vat_main_t * vam)
14165 {
14166   unformat_input_t *i = vam->input;
14167   vl_api_output_acl_set_interface_t *mp;
14168   u32 sw_if_index;
14169   int sw_if_index_set;
14170   u32 ip4_table_index = ~0;
14171   u32 ip6_table_index = ~0;
14172   u32 l2_table_index = ~0;
14173   u8 is_add = 1;
14174   int ret;
14175
14176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14177     {
14178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14179         sw_if_index_set = 1;
14180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14181         sw_if_index_set = 1;
14182       else if (unformat (i, "del"))
14183         is_add = 0;
14184       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14185         ;
14186       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14187         ;
14188       else if (unformat (i, "l2-table %d", &l2_table_index))
14189         ;
14190       else
14191         {
14192           clib_warning ("parse error '%U'", format_unformat_error, i);
14193           return -99;
14194         }
14195     }
14196
14197   if (sw_if_index_set == 0)
14198     {
14199       errmsg ("missing interface name or sw_if_index");
14200       return -99;
14201     }
14202
14203   M (OUTPUT_ACL_SET_INTERFACE, mp);
14204
14205   mp->sw_if_index = ntohl (sw_if_index);
14206   mp->ip4_table_index = ntohl (ip4_table_index);
14207   mp->ip6_table_index = ntohl (ip6_table_index);
14208   mp->l2_table_index = ntohl (l2_table_index);
14209   mp->is_add = is_add;
14210
14211   S (mp);
14212   W (ret);
14213   return ret;
14214 }
14215
14216 static int
14217 api_ip_address_dump (vat_main_t * vam)
14218 {
14219   unformat_input_t *i = vam->input;
14220   vl_api_ip_address_dump_t *mp;
14221   vl_api_control_ping_t *mp_ping;
14222   u32 sw_if_index = ~0;
14223   u8 sw_if_index_set = 0;
14224   u8 ipv4_set = 0;
14225   u8 ipv6_set = 0;
14226   int ret;
14227
14228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14229     {
14230       if (unformat (i, "sw_if_index %d", &sw_if_index))
14231         sw_if_index_set = 1;
14232       else
14233         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14234         sw_if_index_set = 1;
14235       else if (unformat (i, "ipv4"))
14236         ipv4_set = 1;
14237       else if (unformat (i, "ipv6"))
14238         ipv6_set = 1;
14239       else
14240         break;
14241     }
14242
14243   if (ipv4_set && ipv6_set)
14244     {
14245       errmsg ("ipv4 and ipv6 flags cannot be both set");
14246       return -99;
14247     }
14248
14249   if ((!ipv4_set) && (!ipv6_set))
14250     {
14251       errmsg ("no ipv4 nor ipv6 flag set");
14252       return -99;
14253     }
14254
14255   if (sw_if_index_set == 0)
14256     {
14257       errmsg ("missing interface name or sw_if_index");
14258       return -99;
14259     }
14260
14261   vam->current_sw_if_index = sw_if_index;
14262   vam->is_ipv6 = ipv6_set;
14263
14264   M (IP_ADDRESS_DUMP, mp);
14265   mp->sw_if_index = ntohl (sw_if_index);
14266   mp->is_ipv6 = ipv6_set;
14267   S (mp);
14268
14269   /* Use a control ping for synchronization */
14270   MPING (CONTROL_PING, mp_ping);
14271   S (mp_ping);
14272
14273   W (ret);
14274   return ret;
14275 }
14276
14277 static int
14278 api_ip_dump (vat_main_t * vam)
14279 {
14280   vl_api_ip_dump_t *mp;
14281   vl_api_control_ping_t *mp_ping;
14282   unformat_input_t *in = vam->input;
14283   int ipv4_set = 0;
14284   int ipv6_set = 0;
14285   int is_ipv6;
14286   int i;
14287   int ret;
14288
14289   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14290     {
14291       if (unformat (in, "ipv4"))
14292         ipv4_set = 1;
14293       else if (unformat (in, "ipv6"))
14294         ipv6_set = 1;
14295       else
14296         break;
14297     }
14298
14299   if (ipv4_set && ipv6_set)
14300     {
14301       errmsg ("ipv4 and ipv6 flags cannot be both set");
14302       return -99;
14303     }
14304
14305   if ((!ipv4_set) && (!ipv6_set))
14306     {
14307       errmsg ("no ipv4 nor ipv6 flag set");
14308       return -99;
14309     }
14310
14311   is_ipv6 = ipv6_set;
14312   vam->is_ipv6 = is_ipv6;
14313
14314   /* free old data */
14315   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14316     {
14317       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14318     }
14319   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14320
14321   M (IP_DUMP, mp);
14322   mp->is_ipv6 = ipv6_set;
14323   S (mp);
14324
14325   /* Use a control ping for synchronization */
14326   MPING (CONTROL_PING, mp_ping);
14327   S (mp_ping);
14328
14329   W (ret);
14330   return ret;
14331 }
14332
14333 static int
14334 api_ipsec_spd_add_del (vat_main_t * vam)
14335 {
14336   unformat_input_t *i = vam->input;
14337   vl_api_ipsec_spd_add_del_t *mp;
14338   u32 spd_id = ~0;
14339   u8 is_add = 1;
14340   int ret;
14341
14342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14343     {
14344       if (unformat (i, "spd_id %d", &spd_id))
14345         ;
14346       else if (unformat (i, "del"))
14347         is_add = 0;
14348       else
14349         {
14350           clib_warning ("parse error '%U'", format_unformat_error, i);
14351           return -99;
14352         }
14353     }
14354   if (spd_id == ~0)
14355     {
14356       errmsg ("spd_id must be set");
14357       return -99;
14358     }
14359
14360   M (IPSEC_SPD_ADD_DEL, mp);
14361
14362   mp->spd_id = ntohl (spd_id);
14363   mp->is_add = is_add;
14364
14365   S (mp);
14366   W (ret);
14367   return ret;
14368 }
14369
14370 static int
14371 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14372 {
14373   unformat_input_t *i = vam->input;
14374   vl_api_ipsec_interface_add_del_spd_t *mp;
14375   u32 sw_if_index;
14376   u8 sw_if_index_set = 0;
14377   u32 spd_id = (u32) ~ 0;
14378   u8 is_add = 1;
14379   int ret;
14380
14381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14382     {
14383       if (unformat (i, "del"))
14384         is_add = 0;
14385       else if (unformat (i, "spd_id %d", &spd_id))
14386         ;
14387       else
14388         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14389         sw_if_index_set = 1;
14390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14391         sw_if_index_set = 1;
14392       else
14393         {
14394           clib_warning ("parse error '%U'", format_unformat_error, i);
14395           return -99;
14396         }
14397
14398     }
14399
14400   if (spd_id == (u32) ~ 0)
14401     {
14402       errmsg ("spd_id must be set");
14403       return -99;
14404     }
14405
14406   if (sw_if_index_set == 0)
14407     {
14408       errmsg ("missing interface name or sw_if_index");
14409       return -99;
14410     }
14411
14412   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14413
14414   mp->spd_id = ntohl (spd_id);
14415   mp->sw_if_index = ntohl (sw_if_index);
14416   mp->is_add = is_add;
14417
14418   S (mp);
14419   W (ret);
14420   return ret;
14421 }
14422
14423 static int
14424 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14425 {
14426   unformat_input_t *i = vam->input;
14427   vl_api_ipsec_spd_add_del_entry_t *mp;
14428   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14429   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14430   i32 priority = 0;
14431   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14432   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14433   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14434   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14435   int ret;
14436
14437   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14438   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14439   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14440   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14441   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14442   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14443
14444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14445     {
14446       if (unformat (i, "del"))
14447         is_add = 0;
14448       if (unformat (i, "outbound"))
14449         is_outbound = 1;
14450       if (unformat (i, "inbound"))
14451         is_outbound = 0;
14452       else if (unformat (i, "spd_id %d", &spd_id))
14453         ;
14454       else if (unformat (i, "sa_id %d", &sa_id))
14455         ;
14456       else if (unformat (i, "priority %d", &priority))
14457         ;
14458       else if (unformat (i, "protocol %d", &protocol))
14459         ;
14460       else if (unformat (i, "lport_start %d", &lport_start))
14461         ;
14462       else if (unformat (i, "lport_stop %d", &lport_stop))
14463         ;
14464       else if (unformat (i, "rport_start %d", &rport_start))
14465         ;
14466       else if (unformat (i, "rport_stop %d", &rport_stop))
14467         ;
14468       else
14469         if (unformat
14470             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14471         {
14472           is_ipv6 = 0;
14473           is_ip_any = 0;
14474         }
14475       else
14476         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14477         {
14478           is_ipv6 = 0;
14479           is_ip_any = 0;
14480         }
14481       else
14482         if (unformat
14483             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14484         {
14485           is_ipv6 = 0;
14486           is_ip_any = 0;
14487         }
14488       else
14489         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14490         {
14491           is_ipv6 = 0;
14492           is_ip_any = 0;
14493         }
14494       else
14495         if (unformat
14496             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14497         {
14498           is_ipv6 = 1;
14499           is_ip_any = 0;
14500         }
14501       else
14502         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14503         {
14504           is_ipv6 = 1;
14505           is_ip_any = 0;
14506         }
14507       else
14508         if (unformat
14509             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14510         {
14511           is_ipv6 = 1;
14512           is_ip_any = 0;
14513         }
14514       else
14515         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14516         {
14517           is_ipv6 = 1;
14518           is_ip_any = 0;
14519         }
14520       else
14521         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14522         {
14523           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14524             {
14525               clib_warning ("unsupported action: 'resolve'");
14526               return -99;
14527             }
14528         }
14529       else
14530         {
14531           clib_warning ("parse error '%U'", format_unformat_error, i);
14532           return -99;
14533         }
14534
14535     }
14536
14537   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14538
14539   mp->spd_id = ntohl (spd_id);
14540   mp->priority = ntohl (priority);
14541   mp->is_outbound = is_outbound;
14542
14543   mp->is_ipv6 = is_ipv6;
14544   if (is_ipv6 || is_ip_any)
14545     {
14546       clib_memcpy (mp->remote_address_start, &raddr6_start,
14547                    sizeof (ip6_address_t));
14548       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14549                    sizeof (ip6_address_t));
14550       clib_memcpy (mp->local_address_start, &laddr6_start,
14551                    sizeof (ip6_address_t));
14552       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14553                    sizeof (ip6_address_t));
14554     }
14555   else
14556     {
14557       clib_memcpy (mp->remote_address_start, &raddr4_start,
14558                    sizeof (ip4_address_t));
14559       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14560                    sizeof (ip4_address_t));
14561       clib_memcpy (mp->local_address_start, &laddr4_start,
14562                    sizeof (ip4_address_t));
14563       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14564                    sizeof (ip4_address_t));
14565     }
14566   mp->protocol = (u8) protocol;
14567   mp->local_port_start = ntohs ((u16) lport_start);
14568   mp->local_port_stop = ntohs ((u16) lport_stop);
14569   mp->remote_port_start = ntohs ((u16) rport_start);
14570   mp->remote_port_stop = ntohs ((u16) rport_stop);
14571   mp->policy = (u8) policy;
14572   mp->sa_id = ntohl (sa_id);
14573   mp->is_add = is_add;
14574   mp->is_ip_any = is_ip_any;
14575   S (mp);
14576   W (ret);
14577   return ret;
14578 }
14579
14580 static int
14581 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14582 {
14583   unformat_input_t *i = vam->input;
14584   vl_api_ipsec_sad_add_del_entry_t *mp;
14585   u32 sad_id = 0, spi = 0;
14586   u8 *ck = 0, *ik = 0;
14587   u8 is_add = 1;
14588
14589   u8 protocol = IPSEC_PROTOCOL_AH;
14590   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14591   u32 crypto_alg = 0, integ_alg = 0;
14592   ip4_address_t tun_src4;
14593   ip4_address_t tun_dst4;
14594   ip6_address_t tun_src6;
14595   ip6_address_t tun_dst6;
14596   int ret;
14597
14598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14599     {
14600       if (unformat (i, "del"))
14601         is_add = 0;
14602       else if (unformat (i, "sad_id %d", &sad_id))
14603         ;
14604       else if (unformat (i, "spi %d", &spi))
14605         ;
14606       else if (unformat (i, "esp"))
14607         protocol = IPSEC_PROTOCOL_ESP;
14608       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14609         {
14610           is_tunnel = 1;
14611           is_tunnel_ipv6 = 0;
14612         }
14613       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14614         {
14615           is_tunnel = 1;
14616           is_tunnel_ipv6 = 0;
14617         }
14618       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14619         {
14620           is_tunnel = 1;
14621           is_tunnel_ipv6 = 1;
14622         }
14623       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14624         {
14625           is_tunnel = 1;
14626           is_tunnel_ipv6 = 1;
14627         }
14628       else
14629         if (unformat
14630             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14631         {
14632           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14633               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14634             {
14635               clib_warning ("unsupported crypto-alg: '%U'",
14636                             format_ipsec_crypto_alg, crypto_alg);
14637               return -99;
14638             }
14639         }
14640       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14641         ;
14642       else
14643         if (unformat
14644             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14645         {
14646           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14647               integ_alg >= IPSEC_INTEG_N_ALG)
14648             {
14649               clib_warning ("unsupported integ-alg: '%U'",
14650                             format_ipsec_integ_alg, integ_alg);
14651               return -99;
14652             }
14653         }
14654       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14655         ;
14656       else
14657         {
14658           clib_warning ("parse error '%U'", format_unformat_error, i);
14659           return -99;
14660         }
14661
14662     }
14663
14664   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14665
14666   mp->sad_id = ntohl (sad_id);
14667   mp->is_add = is_add;
14668   mp->protocol = protocol;
14669   mp->spi = ntohl (spi);
14670   mp->is_tunnel = is_tunnel;
14671   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14672   mp->crypto_algorithm = crypto_alg;
14673   mp->integrity_algorithm = integ_alg;
14674   mp->crypto_key_length = vec_len (ck);
14675   mp->integrity_key_length = vec_len (ik);
14676
14677   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14678     mp->crypto_key_length = sizeof (mp->crypto_key);
14679
14680   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14681     mp->integrity_key_length = sizeof (mp->integrity_key);
14682
14683   if (ck)
14684     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14685   if (ik)
14686     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14687
14688   if (is_tunnel)
14689     {
14690       if (is_tunnel_ipv6)
14691         {
14692           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14693                        sizeof (ip6_address_t));
14694           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14695                        sizeof (ip6_address_t));
14696         }
14697       else
14698         {
14699           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14700                        sizeof (ip4_address_t));
14701           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14702                        sizeof (ip4_address_t));
14703         }
14704     }
14705
14706   S (mp);
14707   W (ret);
14708   return ret;
14709 }
14710
14711 static int
14712 api_ipsec_sa_set_key (vat_main_t * vam)
14713 {
14714   unformat_input_t *i = vam->input;
14715   vl_api_ipsec_sa_set_key_t *mp;
14716   u32 sa_id;
14717   u8 *ck = 0, *ik = 0;
14718   int ret;
14719
14720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14721     {
14722       if (unformat (i, "sa_id %d", &sa_id))
14723         ;
14724       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14725         ;
14726       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14727         ;
14728       else
14729         {
14730           clib_warning ("parse error '%U'", format_unformat_error, i);
14731           return -99;
14732         }
14733     }
14734
14735   M (IPSEC_SA_SET_KEY, mp);
14736
14737   mp->sa_id = ntohl (sa_id);
14738   mp->crypto_key_length = vec_len (ck);
14739   mp->integrity_key_length = vec_len (ik);
14740
14741   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14742     mp->crypto_key_length = sizeof (mp->crypto_key);
14743
14744   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14745     mp->integrity_key_length = sizeof (mp->integrity_key);
14746
14747   if (ck)
14748     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14749   if (ik)
14750     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14751
14752   S (mp);
14753   W (ret);
14754   return ret;
14755 }
14756
14757 static int
14758 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14759 {
14760   unformat_input_t *i = vam->input;
14761   vl_api_ipsec_tunnel_if_add_del_t *mp;
14762   u32 local_spi = 0, remote_spi = 0;
14763   u32 crypto_alg = 0, integ_alg = 0;
14764   u8 *lck = NULL, *rck = NULL;
14765   u8 *lik = NULL, *rik = NULL;
14766   ip4_address_t local_ip = { {0} };
14767   ip4_address_t remote_ip = { {0} };
14768   u8 is_add = 1;
14769   u8 esn = 0;
14770   u8 anti_replay = 0;
14771   int ret;
14772
14773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14774     {
14775       if (unformat (i, "del"))
14776         is_add = 0;
14777       else if (unformat (i, "esn"))
14778         esn = 1;
14779       else if (unformat (i, "anti_replay"))
14780         anti_replay = 1;
14781       else if (unformat (i, "local_spi %d", &local_spi))
14782         ;
14783       else if (unformat (i, "remote_spi %d", &remote_spi))
14784         ;
14785       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14786         ;
14787       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14788         ;
14789       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14790         ;
14791       else
14792         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14793         ;
14794       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14795         ;
14796       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14797         ;
14798       else
14799         if (unformat
14800             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14801         {
14802           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14803               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14804             {
14805               errmsg ("unsupported crypto-alg: '%U'\n",
14806                       format_ipsec_crypto_alg, crypto_alg);
14807               return -99;
14808             }
14809         }
14810       else
14811         if (unformat
14812             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14813         {
14814           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14815               integ_alg >= IPSEC_INTEG_N_ALG)
14816             {
14817               errmsg ("unsupported integ-alg: '%U'\n",
14818                       format_ipsec_integ_alg, integ_alg);
14819               return -99;
14820             }
14821         }
14822       else
14823         {
14824           errmsg ("parse error '%U'\n", format_unformat_error, i);
14825           return -99;
14826         }
14827     }
14828
14829   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14830
14831   mp->is_add = is_add;
14832   mp->esn = esn;
14833   mp->anti_replay = anti_replay;
14834
14835   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14836   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14837
14838   mp->local_spi = htonl (local_spi);
14839   mp->remote_spi = htonl (remote_spi);
14840   mp->crypto_alg = (u8) crypto_alg;
14841
14842   mp->local_crypto_key_len = 0;
14843   if (lck)
14844     {
14845       mp->local_crypto_key_len = vec_len (lck);
14846       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14847         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14848       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14849     }
14850
14851   mp->remote_crypto_key_len = 0;
14852   if (rck)
14853     {
14854       mp->remote_crypto_key_len = vec_len (rck);
14855       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14856         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14857       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14858     }
14859
14860   mp->integ_alg = (u8) integ_alg;
14861
14862   mp->local_integ_key_len = 0;
14863   if (lik)
14864     {
14865       mp->local_integ_key_len = vec_len (lik);
14866       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14867         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14868       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14869     }
14870
14871   mp->remote_integ_key_len = 0;
14872   if (rik)
14873     {
14874       mp->remote_integ_key_len = vec_len (rik);
14875       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14876         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14877       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14878     }
14879
14880   S (mp);
14881   W (ret);
14882   return ret;
14883 }
14884
14885 static void
14886 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14887 {
14888   vat_main_t *vam = &vat_main;
14889
14890   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14891          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14892          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14893          "tunnel_src_addr %U tunnel_dst_addr %U "
14894          "salt %u seq_outbound %lu last_seq_inbound %lu "
14895          "replay_window %lu total_data_size %lu\n",
14896          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14897          mp->protocol,
14898          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14899          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14900          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14901          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14902          mp->tunnel_src_addr,
14903          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14904          mp->tunnel_dst_addr,
14905          ntohl (mp->salt),
14906          clib_net_to_host_u64 (mp->seq_outbound),
14907          clib_net_to_host_u64 (mp->last_seq_inbound),
14908          clib_net_to_host_u64 (mp->replay_window),
14909          clib_net_to_host_u64 (mp->total_data_size));
14910 }
14911
14912 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14913 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14914
14915 static void vl_api_ipsec_sa_details_t_handler_json
14916   (vl_api_ipsec_sa_details_t * mp)
14917 {
14918   vat_main_t *vam = &vat_main;
14919   vat_json_node_t *node = NULL;
14920   struct in_addr src_ip4, dst_ip4;
14921   struct in6_addr src_ip6, dst_ip6;
14922
14923   if (VAT_JSON_ARRAY != vam->json_tree.type)
14924     {
14925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14926       vat_json_init_array (&vam->json_tree);
14927     }
14928   node = vat_json_array_add (&vam->json_tree);
14929
14930   vat_json_init_object (node);
14931   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14933   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14934   vat_json_object_add_uint (node, "proto", mp->protocol);
14935   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14936   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14937   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14938   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14939   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14940   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14941   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14942                              mp->crypto_key_len);
14943   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14944                              mp->integ_key_len);
14945   if (mp->is_tunnel_ip6)
14946     {
14947       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14948       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14949       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14950       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14951     }
14952   else
14953     {
14954       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14955       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14956       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14957       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14958     }
14959   vat_json_object_add_uint (node, "replay_window",
14960                             clib_net_to_host_u64 (mp->replay_window));
14961   vat_json_object_add_uint (node, "total_data_size",
14962                             clib_net_to_host_u64 (mp->total_data_size));
14963
14964 }
14965
14966 static int
14967 api_ipsec_sa_dump (vat_main_t * vam)
14968 {
14969   unformat_input_t *i = vam->input;
14970   vl_api_ipsec_sa_dump_t *mp;
14971   vl_api_control_ping_t *mp_ping;
14972   u32 sa_id = ~0;
14973   int ret;
14974
14975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (i, "sa_id %d", &sa_id))
14978         ;
14979       else
14980         {
14981           clib_warning ("parse error '%U'", format_unformat_error, i);
14982           return -99;
14983         }
14984     }
14985
14986   M (IPSEC_SA_DUMP, mp);
14987
14988   mp->sa_id = ntohl (sa_id);
14989
14990   S (mp);
14991
14992   /* Use a control ping for synchronization */
14993   M (CONTROL_PING, mp_ping);
14994   S (mp_ping);
14995
14996   W (ret);
14997   return ret;
14998 }
14999
15000 static int
15001 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15002 {
15003   unformat_input_t *i = vam->input;
15004   vl_api_ipsec_tunnel_if_set_key_t *mp;
15005   u32 sw_if_index = ~0;
15006   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15007   u8 *key = 0;
15008   u32 alg = ~0;
15009   int ret;
15010
15011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15012     {
15013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15014         ;
15015       else
15016         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15017         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15018       else
15019         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15020         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15021       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15022         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15023       else
15024         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15025         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15026       else if (unformat (i, "%U", unformat_hex_string, &key))
15027         ;
15028       else
15029         {
15030           clib_warning ("parse error '%U'", format_unformat_error, i);
15031           return -99;
15032         }
15033     }
15034
15035   if (sw_if_index == ~0)
15036     {
15037       errmsg ("interface must be specified");
15038       return -99;
15039     }
15040
15041   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15042     {
15043       errmsg ("key type must be specified");
15044       return -99;
15045     }
15046
15047   if (alg == ~0)
15048     {
15049       errmsg ("algorithm must be specified");
15050       return -99;
15051     }
15052
15053   if (vec_len (key) == 0)
15054     {
15055       errmsg ("key must be specified");
15056       return -99;
15057     }
15058
15059   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15060
15061   mp->sw_if_index = htonl (sw_if_index);
15062   mp->alg = alg;
15063   mp->key_type = key_type;
15064   mp->key_len = vec_len (key);
15065   clib_memcpy (mp->key, key, vec_len (key));
15066
15067   S (mp);
15068   W (ret);
15069
15070   return ret;
15071 }
15072
15073 static int
15074 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15075 {
15076   unformat_input_t *i = vam->input;
15077   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15078   u32 sw_if_index = ~0;
15079   u32 sa_id = ~0;
15080   u8 is_outbound = (u8) ~ 0;
15081   int ret;
15082
15083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15086         ;
15087       else if (unformat (i, "sa_id %d", &sa_id))
15088         ;
15089       else if (unformat (i, "outbound"))
15090         is_outbound = 1;
15091       else if (unformat (i, "inbound"))
15092         is_outbound = 0;
15093       else
15094         {
15095           clib_warning ("parse error '%U'", format_unformat_error, i);
15096           return -99;
15097         }
15098     }
15099
15100   if (sw_if_index == ~0)
15101     {
15102       errmsg ("interface must be specified");
15103       return -99;
15104     }
15105
15106   if (sa_id == ~0)
15107     {
15108       errmsg ("SA ID must be specified");
15109       return -99;
15110     }
15111
15112   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15113
15114   mp->sw_if_index = htonl (sw_if_index);
15115   mp->sa_id = htonl (sa_id);
15116   mp->is_outbound = is_outbound;
15117
15118   S (mp);
15119   W (ret);
15120
15121   return ret;
15122 }
15123
15124 static int
15125 api_ikev2_profile_add_del (vat_main_t * vam)
15126 {
15127   unformat_input_t *i = vam->input;
15128   vl_api_ikev2_profile_add_del_t *mp;
15129   u8 is_add = 1;
15130   u8 *name = 0;
15131   int ret;
15132
15133   const char *valid_chars = "a-zA-Z0-9_";
15134
15135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (i, "del"))
15138         is_add = 0;
15139       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15140         vec_add1 (name, 0);
15141       else
15142         {
15143           errmsg ("parse error '%U'", format_unformat_error, i);
15144           return -99;
15145         }
15146     }
15147
15148   if (!vec_len (name))
15149     {
15150       errmsg ("profile name must be specified");
15151       return -99;
15152     }
15153
15154   if (vec_len (name) > 64)
15155     {
15156       errmsg ("profile name too long");
15157       return -99;
15158     }
15159
15160   M (IKEV2_PROFILE_ADD_DEL, mp);
15161
15162   clib_memcpy (mp->name, name, vec_len (name));
15163   mp->is_add = is_add;
15164   vec_free (name);
15165
15166   S (mp);
15167   W (ret);
15168   return ret;
15169 }
15170
15171 static int
15172 api_ikev2_profile_set_auth (vat_main_t * vam)
15173 {
15174   unformat_input_t *i = vam->input;
15175   vl_api_ikev2_profile_set_auth_t *mp;
15176   u8 *name = 0;
15177   u8 *data = 0;
15178   u32 auth_method = 0;
15179   u8 is_hex = 0;
15180   int ret;
15181
15182   const char *valid_chars = "a-zA-Z0-9_";
15183
15184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15185     {
15186       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15187         vec_add1 (name, 0);
15188       else if (unformat (i, "auth_method %U",
15189                          unformat_ikev2_auth_method, &auth_method))
15190         ;
15191       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15192         is_hex = 1;
15193       else if (unformat (i, "auth_data %v", &data))
15194         ;
15195       else
15196         {
15197           errmsg ("parse error '%U'", format_unformat_error, i);
15198           return -99;
15199         }
15200     }
15201
15202   if (!vec_len (name))
15203     {
15204       errmsg ("profile name must be specified");
15205       return -99;
15206     }
15207
15208   if (vec_len (name) > 64)
15209     {
15210       errmsg ("profile name too long");
15211       return -99;
15212     }
15213
15214   if (!vec_len (data))
15215     {
15216       errmsg ("auth_data must be specified");
15217       return -99;
15218     }
15219
15220   if (!auth_method)
15221     {
15222       errmsg ("auth_method must be specified");
15223       return -99;
15224     }
15225
15226   M (IKEV2_PROFILE_SET_AUTH, mp);
15227
15228   mp->is_hex = is_hex;
15229   mp->auth_method = (u8) auth_method;
15230   mp->data_len = vec_len (data);
15231   clib_memcpy (mp->name, name, vec_len (name));
15232   clib_memcpy (mp->data, data, vec_len (data));
15233   vec_free (name);
15234   vec_free (data);
15235
15236   S (mp);
15237   W (ret);
15238   return ret;
15239 }
15240
15241 static int
15242 api_ikev2_profile_set_id (vat_main_t * vam)
15243 {
15244   unformat_input_t *i = vam->input;
15245   vl_api_ikev2_profile_set_id_t *mp;
15246   u8 *name = 0;
15247   u8 *data = 0;
15248   u8 is_local = 0;
15249   u32 id_type = 0;
15250   ip4_address_t ip4;
15251   int ret;
15252
15253   const char *valid_chars = "a-zA-Z0-9_";
15254
15255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15256     {
15257       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15258         vec_add1 (name, 0);
15259       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15260         ;
15261       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15262         {
15263           data = vec_new (u8, 4);
15264           clib_memcpy (data, ip4.as_u8, 4);
15265         }
15266       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15267         ;
15268       else if (unformat (i, "id_data %v", &data))
15269         ;
15270       else if (unformat (i, "local"))
15271         is_local = 1;
15272       else if (unformat (i, "remote"))
15273         is_local = 0;
15274       else
15275         {
15276           errmsg ("parse error '%U'", format_unformat_error, i);
15277           return -99;
15278         }
15279     }
15280
15281   if (!vec_len (name))
15282     {
15283       errmsg ("profile name must be specified");
15284       return -99;
15285     }
15286
15287   if (vec_len (name) > 64)
15288     {
15289       errmsg ("profile name too long");
15290       return -99;
15291     }
15292
15293   if (!vec_len (data))
15294     {
15295       errmsg ("id_data must be specified");
15296       return -99;
15297     }
15298
15299   if (!id_type)
15300     {
15301       errmsg ("id_type must be specified");
15302       return -99;
15303     }
15304
15305   M (IKEV2_PROFILE_SET_ID, mp);
15306
15307   mp->is_local = is_local;
15308   mp->id_type = (u8) id_type;
15309   mp->data_len = vec_len (data);
15310   clib_memcpy (mp->name, name, vec_len (name));
15311   clib_memcpy (mp->data, data, vec_len (data));
15312   vec_free (name);
15313   vec_free (data);
15314
15315   S (mp);
15316   W (ret);
15317   return ret;
15318 }
15319
15320 static int
15321 api_ikev2_profile_set_ts (vat_main_t * vam)
15322 {
15323   unformat_input_t *i = vam->input;
15324   vl_api_ikev2_profile_set_ts_t *mp;
15325   u8 *name = 0;
15326   u8 is_local = 0;
15327   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15328   ip4_address_t start_addr, end_addr;
15329
15330   const char *valid_chars = "a-zA-Z0-9_";
15331   int ret;
15332
15333   start_addr.as_u32 = 0;
15334   end_addr.as_u32 = (u32) ~ 0;
15335
15336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15337     {
15338       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15339         vec_add1 (name, 0);
15340       else if (unformat (i, "protocol %d", &proto))
15341         ;
15342       else if (unformat (i, "start_port %d", &start_port))
15343         ;
15344       else if (unformat (i, "end_port %d", &end_port))
15345         ;
15346       else
15347         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15348         ;
15349       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15350         ;
15351       else if (unformat (i, "local"))
15352         is_local = 1;
15353       else if (unformat (i, "remote"))
15354         is_local = 0;
15355       else
15356         {
15357           errmsg ("parse error '%U'", format_unformat_error, i);
15358           return -99;
15359         }
15360     }
15361
15362   if (!vec_len (name))
15363     {
15364       errmsg ("profile name must be specified");
15365       return -99;
15366     }
15367
15368   if (vec_len (name) > 64)
15369     {
15370       errmsg ("profile name too long");
15371       return -99;
15372     }
15373
15374   M (IKEV2_PROFILE_SET_TS, mp);
15375
15376   mp->is_local = is_local;
15377   mp->proto = (u8) proto;
15378   mp->start_port = (u16) start_port;
15379   mp->end_port = (u16) end_port;
15380   mp->start_addr = start_addr.as_u32;
15381   mp->end_addr = end_addr.as_u32;
15382   clib_memcpy (mp->name, name, vec_len (name));
15383   vec_free (name);
15384
15385   S (mp);
15386   W (ret);
15387   return ret;
15388 }
15389
15390 static int
15391 api_ikev2_set_local_key (vat_main_t * vam)
15392 {
15393   unformat_input_t *i = vam->input;
15394   vl_api_ikev2_set_local_key_t *mp;
15395   u8 *file = 0;
15396   int ret;
15397
15398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15399     {
15400       if (unformat (i, "file %v", &file))
15401         vec_add1 (file, 0);
15402       else
15403         {
15404           errmsg ("parse error '%U'", format_unformat_error, i);
15405           return -99;
15406         }
15407     }
15408
15409   if (!vec_len (file))
15410     {
15411       errmsg ("RSA key file must be specified");
15412       return -99;
15413     }
15414
15415   if (vec_len (file) > 256)
15416     {
15417       errmsg ("file name too long");
15418       return -99;
15419     }
15420
15421   M (IKEV2_SET_LOCAL_KEY, mp);
15422
15423   clib_memcpy (mp->key_file, file, vec_len (file));
15424   vec_free (file);
15425
15426   S (mp);
15427   W (ret);
15428   return ret;
15429 }
15430
15431 static int
15432 api_ikev2_set_responder (vat_main_t * vam)
15433 {
15434   unformat_input_t *i = vam->input;
15435   vl_api_ikev2_set_responder_t *mp;
15436   int ret;
15437   u8 *name = 0;
15438   u32 sw_if_index = ~0;
15439   ip4_address_t address;
15440
15441   const char *valid_chars = "a-zA-Z0-9_";
15442
15443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15444     {
15445       if (unformat
15446           (i, "%U interface %d address %U", unformat_token, valid_chars,
15447            &name, &sw_if_index, unformat_ip4_address, &address))
15448         vec_add1 (name, 0);
15449       else
15450         {
15451           errmsg ("parse error '%U'", format_unformat_error, i);
15452           return -99;
15453         }
15454     }
15455
15456   if (!vec_len (name))
15457     {
15458       errmsg ("profile name must be specified");
15459       return -99;
15460     }
15461
15462   if (vec_len (name) > 64)
15463     {
15464       errmsg ("profile name too long");
15465       return -99;
15466     }
15467
15468   M (IKEV2_SET_RESPONDER, mp);
15469
15470   clib_memcpy (mp->name, name, vec_len (name));
15471   vec_free (name);
15472
15473   mp->sw_if_index = sw_if_index;
15474   clib_memcpy (mp->address, &address, sizeof (address));
15475
15476   S (mp);
15477   W (ret);
15478   return ret;
15479 }
15480
15481 static int
15482 api_ikev2_set_ike_transforms (vat_main_t * vam)
15483 {
15484   unformat_input_t *i = vam->input;
15485   vl_api_ikev2_set_ike_transforms_t *mp;
15486   int ret;
15487   u8 *name = 0;
15488   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15489
15490   const char *valid_chars = "a-zA-Z0-9_";
15491
15492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15495                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15496         vec_add1 (name, 0);
15497       else
15498         {
15499           errmsg ("parse error '%U'", format_unformat_error, i);
15500           return -99;
15501         }
15502     }
15503
15504   if (!vec_len (name))
15505     {
15506       errmsg ("profile name must be specified");
15507       return -99;
15508     }
15509
15510   if (vec_len (name) > 64)
15511     {
15512       errmsg ("profile name too long");
15513       return -99;
15514     }
15515
15516   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15517
15518   clib_memcpy (mp->name, name, vec_len (name));
15519   vec_free (name);
15520   mp->crypto_alg = crypto_alg;
15521   mp->crypto_key_size = crypto_key_size;
15522   mp->integ_alg = integ_alg;
15523   mp->dh_group = dh_group;
15524
15525   S (mp);
15526   W (ret);
15527   return ret;
15528 }
15529
15530
15531 static int
15532 api_ikev2_set_esp_transforms (vat_main_t * vam)
15533 {
15534   unformat_input_t *i = vam->input;
15535   vl_api_ikev2_set_esp_transforms_t *mp;
15536   int ret;
15537   u8 *name = 0;
15538   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15539
15540   const char *valid_chars = "a-zA-Z0-9_";
15541
15542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15543     {
15544       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15545                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15546         vec_add1 (name, 0);
15547       else
15548         {
15549           errmsg ("parse error '%U'", format_unformat_error, i);
15550           return -99;
15551         }
15552     }
15553
15554   if (!vec_len (name))
15555     {
15556       errmsg ("profile name must be specified");
15557       return -99;
15558     }
15559
15560   if (vec_len (name) > 64)
15561     {
15562       errmsg ("profile name too long");
15563       return -99;
15564     }
15565
15566   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15567
15568   clib_memcpy (mp->name, name, vec_len (name));
15569   vec_free (name);
15570   mp->crypto_alg = crypto_alg;
15571   mp->crypto_key_size = crypto_key_size;
15572   mp->integ_alg = integ_alg;
15573   mp->dh_group = dh_group;
15574
15575   S (mp);
15576   W (ret);
15577   return ret;
15578 }
15579
15580 static int
15581 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15582 {
15583   unformat_input_t *i = vam->input;
15584   vl_api_ikev2_set_sa_lifetime_t *mp;
15585   int ret;
15586   u8 *name = 0;
15587   u64 lifetime, lifetime_maxdata;
15588   u32 lifetime_jitter, handover;
15589
15590   const char *valid_chars = "a-zA-Z0-9_";
15591
15592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15593     {
15594       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15595                     &lifetime, &lifetime_jitter, &handover,
15596                     &lifetime_maxdata))
15597         vec_add1 (name, 0);
15598       else
15599         {
15600           errmsg ("parse error '%U'", format_unformat_error, i);
15601           return -99;
15602         }
15603     }
15604
15605   if (!vec_len (name))
15606     {
15607       errmsg ("profile name must be specified");
15608       return -99;
15609     }
15610
15611   if (vec_len (name) > 64)
15612     {
15613       errmsg ("profile name too long");
15614       return -99;
15615     }
15616
15617   M (IKEV2_SET_SA_LIFETIME, mp);
15618
15619   clib_memcpy (mp->name, name, vec_len (name));
15620   vec_free (name);
15621   mp->lifetime = lifetime;
15622   mp->lifetime_jitter = lifetime_jitter;
15623   mp->handover = handover;
15624   mp->lifetime_maxdata = lifetime_maxdata;
15625
15626   S (mp);
15627   W (ret);
15628   return ret;
15629 }
15630
15631 static int
15632 api_ikev2_initiate_sa_init (vat_main_t * vam)
15633 {
15634   unformat_input_t *i = vam->input;
15635   vl_api_ikev2_initiate_sa_init_t *mp;
15636   int ret;
15637   u8 *name = 0;
15638
15639   const char *valid_chars = "a-zA-Z0-9_";
15640
15641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15642     {
15643       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15644         vec_add1 (name, 0);
15645       else
15646         {
15647           errmsg ("parse error '%U'", format_unformat_error, i);
15648           return -99;
15649         }
15650     }
15651
15652   if (!vec_len (name))
15653     {
15654       errmsg ("profile name must be specified");
15655       return -99;
15656     }
15657
15658   if (vec_len (name) > 64)
15659     {
15660       errmsg ("profile name too long");
15661       return -99;
15662     }
15663
15664   M (IKEV2_INITIATE_SA_INIT, mp);
15665
15666   clib_memcpy (mp->name, name, vec_len (name));
15667   vec_free (name);
15668
15669   S (mp);
15670   W (ret);
15671   return ret;
15672 }
15673
15674 static int
15675 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15676 {
15677   unformat_input_t *i = vam->input;
15678   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15679   int ret;
15680   u64 ispi;
15681
15682
15683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15684     {
15685       if (unformat (i, "%lx", &ispi))
15686         ;
15687       else
15688         {
15689           errmsg ("parse error '%U'", format_unformat_error, i);
15690           return -99;
15691         }
15692     }
15693
15694   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15695
15696   mp->ispi = ispi;
15697
15698   S (mp);
15699   W (ret);
15700   return ret;
15701 }
15702
15703 static int
15704 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15705 {
15706   unformat_input_t *i = vam->input;
15707   vl_api_ikev2_initiate_del_child_sa_t *mp;
15708   int ret;
15709   u32 ispi;
15710
15711
15712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15713     {
15714       if (unformat (i, "%x", &ispi))
15715         ;
15716       else
15717         {
15718           errmsg ("parse error '%U'", format_unformat_error, i);
15719           return -99;
15720         }
15721     }
15722
15723   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15724
15725   mp->ispi = ispi;
15726
15727   S (mp);
15728   W (ret);
15729   return ret;
15730 }
15731
15732 static int
15733 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15734 {
15735   unformat_input_t *i = vam->input;
15736   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15737   int ret;
15738   u32 ispi;
15739
15740
15741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15742     {
15743       if (unformat (i, "%x", &ispi))
15744         ;
15745       else
15746         {
15747           errmsg ("parse error '%U'", format_unformat_error, i);
15748           return -99;
15749         }
15750     }
15751
15752   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15753
15754   mp->ispi = ispi;
15755
15756   S (mp);
15757   W (ret);
15758   return ret;
15759 }
15760
15761 /*
15762  * MAP
15763  */
15764 static int
15765 api_map_add_domain (vat_main_t * vam)
15766 {
15767   unformat_input_t *i = vam->input;
15768   vl_api_map_add_domain_t *mp;
15769
15770   ip4_address_t ip4_prefix;
15771   ip6_address_t ip6_prefix;
15772   ip6_address_t ip6_src;
15773   u32 num_m_args = 0;
15774   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15775     0, psid_length = 0;
15776   u8 is_translation = 0;
15777   u32 mtu = 0;
15778   u32 ip6_src_len = 128;
15779   int ret;
15780
15781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15782     {
15783       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15784                     &ip4_prefix, &ip4_prefix_len))
15785         num_m_args++;
15786       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15787                          &ip6_prefix, &ip6_prefix_len))
15788         num_m_args++;
15789       else
15790         if (unformat
15791             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15792              &ip6_src_len))
15793         num_m_args++;
15794       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15795         num_m_args++;
15796       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15797         num_m_args++;
15798       else if (unformat (i, "psid-offset %d", &psid_offset))
15799         num_m_args++;
15800       else if (unformat (i, "psid-len %d", &psid_length))
15801         num_m_args++;
15802       else if (unformat (i, "mtu %d", &mtu))
15803         num_m_args++;
15804       else if (unformat (i, "map-t"))
15805         is_translation = 1;
15806       else
15807         {
15808           clib_warning ("parse error '%U'", format_unformat_error, i);
15809           return -99;
15810         }
15811     }
15812
15813   if (num_m_args < 3)
15814     {
15815       errmsg ("mandatory argument(s) missing");
15816       return -99;
15817     }
15818
15819   /* Construct the API message */
15820   M (MAP_ADD_DOMAIN, mp);
15821
15822   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15823   mp->ip4_prefix_len = ip4_prefix_len;
15824
15825   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15826   mp->ip6_prefix_len = ip6_prefix_len;
15827
15828   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15829   mp->ip6_src_prefix_len = ip6_src_len;
15830
15831   mp->ea_bits_len = ea_bits_len;
15832   mp->psid_offset = psid_offset;
15833   mp->psid_length = psid_length;
15834   mp->is_translation = is_translation;
15835   mp->mtu = htons (mtu);
15836
15837   /* send it... */
15838   S (mp);
15839
15840   /* Wait for a reply, return good/bad news  */
15841   W (ret);
15842   return ret;
15843 }
15844
15845 static int
15846 api_map_del_domain (vat_main_t * vam)
15847 {
15848   unformat_input_t *i = vam->input;
15849   vl_api_map_del_domain_t *mp;
15850
15851   u32 num_m_args = 0;
15852   u32 index;
15853   int ret;
15854
15855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15856     {
15857       if (unformat (i, "index %d", &index))
15858         num_m_args++;
15859       else
15860         {
15861           clib_warning ("parse error '%U'", format_unformat_error, i);
15862           return -99;
15863         }
15864     }
15865
15866   if (num_m_args != 1)
15867     {
15868       errmsg ("mandatory argument(s) missing");
15869       return -99;
15870     }
15871
15872   /* Construct the API message */
15873   M (MAP_DEL_DOMAIN, mp);
15874
15875   mp->index = ntohl (index);
15876
15877   /* send it... */
15878   S (mp);
15879
15880   /* Wait for a reply, return good/bad news  */
15881   W (ret);
15882   return ret;
15883 }
15884
15885 static int
15886 api_map_add_del_rule (vat_main_t * vam)
15887 {
15888   unformat_input_t *i = vam->input;
15889   vl_api_map_add_del_rule_t *mp;
15890   u8 is_add = 1;
15891   ip6_address_t ip6_dst;
15892   u32 num_m_args = 0, index, psid = 0;
15893   int ret;
15894
15895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15896     {
15897       if (unformat (i, "index %d", &index))
15898         num_m_args++;
15899       else if (unformat (i, "psid %d", &psid))
15900         num_m_args++;
15901       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15902         num_m_args++;
15903       else if (unformat (i, "del"))
15904         {
15905           is_add = 0;
15906         }
15907       else
15908         {
15909           clib_warning ("parse error '%U'", format_unformat_error, i);
15910           return -99;
15911         }
15912     }
15913
15914   /* Construct the API message */
15915   M (MAP_ADD_DEL_RULE, mp);
15916
15917   mp->index = ntohl (index);
15918   mp->is_add = is_add;
15919   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15920   mp->psid = ntohs (psid);
15921
15922   /* send it... */
15923   S (mp);
15924
15925   /* Wait for a reply, return good/bad news  */
15926   W (ret);
15927   return ret;
15928 }
15929
15930 static int
15931 api_map_domain_dump (vat_main_t * vam)
15932 {
15933   vl_api_map_domain_dump_t *mp;
15934   vl_api_control_ping_t *mp_ping;
15935   int ret;
15936
15937   /* Construct the API message */
15938   M (MAP_DOMAIN_DUMP, mp);
15939
15940   /* send it... */
15941   S (mp);
15942
15943   /* Use a control ping for synchronization */
15944   MPING (CONTROL_PING, mp_ping);
15945   S (mp_ping);
15946
15947   W (ret);
15948   return ret;
15949 }
15950
15951 static int
15952 api_map_rule_dump (vat_main_t * vam)
15953 {
15954   unformat_input_t *i = vam->input;
15955   vl_api_map_rule_dump_t *mp;
15956   vl_api_control_ping_t *mp_ping;
15957   u32 domain_index = ~0;
15958   int ret;
15959
15960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15961     {
15962       if (unformat (i, "index %u", &domain_index))
15963         ;
15964       else
15965         break;
15966     }
15967
15968   if (domain_index == ~0)
15969     {
15970       clib_warning ("parse error: domain index expected");
15971       return -99;
15972     }
15973
15974   /* Construct the API message */
15975   M (MAP_RULE_DUMP, mp);
15976
15977   mp->domain_index = htonl (domain_index);
15978
15979   /* send it... */
15980   S (mp);
15981
15982   /* Use a control ping for synchronization */
15983   MPING (CONTROL_PING, mp_ping);
15984   S (mp_ping);
15985
15986   W (ret);
15987   return ret;
15988 }
15989
15990 static void vl_api_map_add_domain_reply_t_handler
15991   (vl_api_map_add_domain_reply_t * mp)
15992 {
15993   vat_main_t *vam = &vat_main;
15994   i32 retval = ntohl (mp->retval);
15995
15996   if (vam->async_mode)
15997     {
15998       vam->async_errors += (retval < 0);
15999     }
16000   else
16001     {
16002       vam->retval = retval;
16003       vam->result_ready = 1;
16004     }
16005 }
16006
16007 static void vl_api_map_add_domain_reply_t_handler_json
16008   (vl_api_map_add_domain_reply_t * mp)
16009 {
16010   vat_main_t *vam = &vat_main;
16011   vat_json_node_t node;
16012
16013   vat_json_init_object (&node);
16014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16015   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16016
16017   vat_json_print (vam->ofp, &node);
16018   vat_json_free (&node);
16019
16020   vam->retval = ntohl (mp->retval);
16021   vam->result_ready = 1;
16022 }
16023
16024 static int
16025 api_get_first_msg_id (vat_main_t * vam)
16026 {
16027   vl_api_get_first_msg_id_t *mp;
16028   unformat_input_t *i = vam->input;
16029   u8 *name;
16030   u8 name_set = 0;
16031   int ret;
16032
16033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16034     {
16035       if (unformat (i, "client %s", &name))
16036         name_set = 1;
16037       else
16038         break;
16039     }
16040
16041   if (name_set == 0)
16042     {
16043       errmsg ("missing client name");
16044       return -99;
16045     }
16046   vec_add1 (name, 0);
16047
16048   if (vec_len (name) > 63)
16049     {
16050       errmsg ("client name too long");
16051       return -99;
16052     }
16053
16054   M (GET_FIRST_MSG_ID, mp);
16055   clib_memcpy (mp->name, name, vec_len (name));
16056   S (mp);
16057   W (ret);
16058   return ret;
16059 }
16060
16061 static int
16062 api_cop_interface_enable_disable (vat_main_t * vam)
16063 {
16064   unformat_input_t *line_input = vam->input;
16065   vl_api_cop_interface_enable_disable_t *mp;
16066   u32 sw_if_index = ~0;
16067   u8 enable_disable = 1;
16068   int ret;
16069
16070   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16071     {
16072       if (unformat (line_input, "disable"))
16073         enable_disable = 0;
16074       if (unformat (line_input, "enable"))
16075         enable_disable = 1;
16076       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16077                          vam, &sw_if_index))
16078         ;
16079       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16080         ;
16081       else
16082         break;
16083     }
16084
16085   if (sw_if_index == ~0)
16086     {
16087       errmsg ("missing interface name or sw_if_index");
16088       return -99;
16089     }
16090
16091   /* Construct the API message */
16092   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16093   mp->sw_if_index = ntohl (sw_if_index);
16094   mp->enable_disable = enable_disable;
16095
16096   /* send it... */
16097   S (mp);
16098   /* Wait for the reply */
16099   W (ret);
16100   return ret;
16101 }
16102
16103 static int
16104 api_cop_whitelist_enable_disable (vat_main_t * vam)
16105 {
16106   unformat_input_t *line_input = vam->input;
16107   vl_api_cop_whitelist_enable_disable_t *mp;
16108   u32 sw_if_index = ~0;
16109   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16110   u32 fib_id = 0;
16111   int ret;
16112
16113   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16114     {
16115       if (unformat (line_input, "ip4"))
16116         ip4 = 1;
16117       else if (unformat (line_input, "ip6"))
16118         ip6 = 1;
16119       else if (unformat (line_input, "default"))
16120         default_cop = 1;
16121       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16122                          vam, &sw_if_index))
16123         ;
16124       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16125         ;
16126       else if (unformat (line_input, "fib-id %d", &fib_id))
16127         ;
16128       else
16129         break;
16130     }
16131
16132   if (sw_if_index == ~0)
16133     {
16134       errmsg ("missing interface name or sw_if_index");
16135       return -99;
16136     }
16137
16138   /* Construct the API message */
16139   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16140   mp->sw_if_index = ntohl (sw_if_index);
16141   mp->fib_id = ntohl (fib_id);
16142   mp->ip4 = ip4;
16143   mp->ip6 = ip6;
16144   mp->default_cop = default_cop;
16145
16146   /* send it... */
16147   S (mp);
16148   /* Wait for the reply */
16149   W (ret);
16150   return ret;
16151 }
16152
16153 static int
16154 api_get_node_graph (vat_main_t * vam)
16155 {
16156   vl_api_get_node_graph_t *mp;
16157   int ret;
16158
16159   M (GET_NODE_GRAPH, mp);
16160
16161   /* send it... */
16162   S (mp);
16163   /* Wait for the reply */
16164   W (ret);
16165   return ret;
16166 }
16167
16168 /* *INDENT-OFF* */
16169 /** Used for parsing LISP eids */
16170 typedef CLIB_PACKED(struct{
16171   u8 addr[16];   /**< eid address */
16172   u32 len;       /**< prefix length if IP */
16173   u8 type;      /**< type of eid */
16174 }) lisp_eid_vat_t;
16175 /* *INDENT-ON* */
16176
16177 static uword
16178 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16179 {
16180   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16181
16182   memset (a, 0, sizeof (a[0]));
16183
16184   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16185     {
16186       a->type = 0;              /* ipv4 type */
16187     }
16188   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16189     {
16190       a->type = 1;              /* ipv6 type */
16191     }
16192   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16193     {
16194       a->type = 2;              /* mac type */
16195     }
16196   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16197     {
16198       a->type = 3;              /* NSH type */
16199       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16200       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16201     }
16202   else
16203     {
16204       return 0;
16205     }
16206
16207   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16208     {
16209       return 0;
16210     }
16211
16212   return 1;
16213 }
16214
16215 static int
16216 lisp_eid_size_vat (u8 type)
16217 {
16218   switch (type)
16219     {
16220     case 0:
16221       return 4;
16222     case 1:
16223       return 16;
16224     case 2:
16225       return 6;
16226     case 3:
16227       return 5;
16228     }
16229   return 0;
16230 }
16231
16232 static void
16233 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16234 {
16235   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16236 }
16237
16238 static int
16239 api_one_add_del_locator_set (vat_main_t * vam)
16240 {
16241   unformat_input_t *input = vam->input;
16242   vl_api_one_add_del_locator_set_t *mp;
16243   u8 is_add = 1;
16244   u8 *locator_set_name = NULL;
16245   u8 locator_set_name_set = 0;
16246   vl_api_local_locator_t locator, *locators = 0;
16247   u32 sw_if_index, priority, weight;
16248   u32 data_len = 0;
16249
16250   int ret;
16251   /* Parse args required to build the message */
16252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16253     {
16254       if (unformat (input, "del"))
16255         {
16256           is_add = 0;
16257         }
16258       else if (unformat (input, "locator-set %s", &locator_set_name))
16259         {
16260           locator_set_name_set = 1;
16261         }
16262       else if (unformat (input, "sw_if_index %u p %u w %u",
16263                          &sw_if_index, &priority, &weight))
16264         {
16265           locator.sw_if_index = htonl (sw_if_index);
16266           locator.priority = priority;
16267           locator.weight = weight;
16268           vec_add1 (locators, locator);
16269         }
16270       else
16271         if (unformat
16272             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16273              &sw_if_index, &priority, &weight))
16274         {
16275           locator.sw_if_index = htonl (sw_if_index);
16276           locator.priority = priority;
16277           locator.weight = weight;
16278           vec_add1 (locators, locator);
16279         }
16280       else
16281         break;
16282     }
16283
16284   if (locator_set_name_set == 0)
16285     {
16286       errmsg ("missing locator-set name");
16287       vec_free (locators);
16288       return -99;
16289     }
16290
16291   if (vec_len (locator_set_name) > 64)
16292     {
16293       errmsg ("locator-set name too long");
16294       vec_free (locator_set_name);
16295       vec_free (locators);
16296       return -99;
16297     }
16298   vec_add1 (locator_set_name, 0);
16299
16300   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16301
16302   /* Construct the API message */
16303   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16304
16305   mp->is_add = is_add;
16306   clib_memcpy (mp->locator_set_name, locator_set_name,
16307                vec_len (locator_set_name));
16308   vec_free (locator_set_name);
16309
16310   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16311   if (locators)
16312     clib_memcpy (mp->locators, locators, data_len);
16313   vec_free (locators);
16314
16315   /* send it... */
16316   S (mp);
16317
16318   /* Wait for a reply... */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16324
16325 static int
16326 api_one_add_del_locator (vat_main_t * vam)
16327 {
16328   unformat_input_t *input = vam->input;
16329   vl_api_one_add_del_locator_t *mp;
16330   u32 tmp_if_index = ~0;
16331   u32 sw_if_index = ~0;
16332   u8 sw_if_index_set = 0;
16333   u8 sw_if_index_if_name_set = 0;
16334   u32 priority = ~0;
16335   u8 priority_set = 0;
16336   u32 weight = ~0;
16337   u8 weight_set = 0;
16338   u8 is_add = 1;
16339   u8 *locator_set_name = NULL;
16340   u8 locator_set_name_set = 0;
16341   int ret;
16342
16343   /* Parse args required to build the message */
16344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16345     {
16346       if (unformat (input, "del"))
16347         {
16348           is_add = 0;
16349         }
16350       else if (unformat (input, "locator-set %s", &locator_set_name))
16351         {
16352           locator_set_name_set = 1;
16353         }
16354       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16355                          &tmp_if_index))
16356         {
16357           sw_if_index_if_name_set = 1;
16358           sw_if_index = tmp_if_index;
16359         }
16360       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16361         {
16362           sw_if_index_set = 1;
16363           sw_if_index = tmp_if_index;
16364         }
16365       else if (unformat (input, "p %d", &priority))
16366         {
16367           priority_set = 1;
16368         }
16369       else if (unformat (input, "w %d", &weight))
16370         {
16371           weight_set = 1;
16372         }
16373       else
16374         break;
16375     }
16376
16377   if (locator_set_name_set == 0)
16378     {
16379       errmsg ("missing locator-set name");
16380       return -99;
16381     }
16382
16383   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16384     {
16385       errmsg ("missing sw_if_index");
16386       vec_free (locator_set_name);
16387       return -99;
16388     }
16389
16390   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16391     {
16392       errmsg ("cannot use both params interface name and sw_if_index");
16393       vec_free (locator_set_name);
16394       return -99;
16395     }
16396
16397   if (priority_set == 0)
16398     {
16399       errmsg ("missing locator-set priority");
16400       vec_free (locator_set_name);
16401       return -99;
16402     }
16403
16404   if (weight_set == 0)
16405     {
16406       errmsg ("missing locator-set weight");
16407       vec_free (locator_set_name);
16408       return -99;
16409     }
16410
16411   if (vec_len (locator_set_name) > 64)
16412     {
16413       errmsg ("locator-set name too long");
16414       vec_free (locator_set_name);
16415       return -99;
16416     }
16417   vec_add1 (locator_set_name, 0);
16418
16419   /* Construct the API message */
16420   M (ONE_ADD_DEL_LOCATOR, mp);
16421
16422   mp->is_add = is_add;
16423   mp->sw_if_index = ntohl (sw_if_index);
16424   mp->priority = priority;
16425   mp->weight = weight;
16426   clib_memcpy (mp->locator_set_name, locator_set_name,
16427                vec_len (locator_set_name));
16428   vec_free (locator_set_name);
16429
16430   /* send it... */
16431   S (mp);
16432
16433   /* Wait for a reply... */
16434   W (ret);
16435   return ret;
16436 }
16437
16438 #define api_lisp_add_del_locator api_one_add_del_locator
16439
16440 uword
16441 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16442 {
16443   u32 *key_id = va_arg (*args, u32 *);
16444   u8 *s = 0;
16445
16446   if (unformat (input, "%s", &s))
16447     {
16448       if (!strcmp ((char *) s, "sha1"))
16449         key_id[0] = HMAC_SHA_1_96;
16450       else if (!strcmp ((char *) s, "sha256"))
16451         key_id[0] = HMAC_SHA_256_128;
16452       else
16453         {
16454           clib_warning ("invalid key_id: '%s'", s);
16455           key_id[0] = HMAC_NO_KEY;
16456         }
16457     }
16458   else
16459     return 0;
16460
16461   vec_free (s);
16462   return 1;
16463 }
16464
16465 static int
16466 api_one_add_del_local_eid (vat_main_t * vam)
16467 {
16468   unformat_input_t *input = vam->input;
16469   vl_api_one_add_del_local_eid_t *mp;
16470   u8 is_add = 1;
16471   u8 eid_set = 0;
16472   lisp_eid_vat_t _eid, *eid = &_eid;
16473   u8 *locator_set_name = 0;
16474   u8 locator_set_name_set = 0;
16475   u32 vni = 0;
16476   u16 key_id = 0;
16477   u8 *key = 0;
16478   int ret;
16479
16480   /* Parse args required to build the message */
16481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16482     {
16483       if (unformat (input, "del"))
16484         {
16485           is_add = 0;
16486         }
16487       else if (unformat (input, "vni %d", &vni))
16488         {
16489           ;
16490         }
16491       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16492         {
16493           eid_set = 1;
16494         }
16495       else if (unformat (input, "locator-set %s", &locator_set_name))
16496         {
16497           locator_set_name_set = 1;
16498         }
16499       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16500         ;
16501       else if (unformat (input, "secret-key %_%v%_", &key))
16502         ;
16503       else
16504         break;
16505     }
16506
16507   if (locator_set_name_set == 0)
16508     {
16509       errmsg ("missing locator-set name");
16510       return -99;
16511     }
16512
16513   if (0 == eid_set)
16514     {
16515       errmsg ("EID address not set!");
16516       vec_free (locator_set_name);
16517       return -99;
16518     }
16519
16520   if (key && (0 == key_id))
16521     {
16522       errmsg ("invalid key_id!");
16523       return -99;
16524     }
16525
16526   if (vec_len (key) > 64)
16527     {
16528       errmsg ("key too long");
16529       vec_free (key);
16530       return -99;
16531     }
16532
16533   if (vec_len (locator_set_name) > 64)
16534     {
16535       errmsg ("locator-set name too long");
16536       vec_free (locator_set_name);
16537       return -99;
16538     }
16539   vec_add1 (locator_set_name, 0);
16540
16541   /* Construct the API message */
16542   M (ONE_ADD_DEL_LOCAL_EID, mp);
16543
16544   mp->is_add = is_add;
16545   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16546   mp->eid_type = eid->type;
16547   mp->prefix_len = eid->len;
16548   mp->vni = clib_host_to_net_u32 (vni);
16549   mp->key_id = clib_host_to_net_u16 (key_id);
16550   clib_memcpy (mp->locator_set_name, locator_set_name,
16551                vec_len (locator_set_name));
16552   clib_memcpy (mp->key, key, vec_len (key));
16553
16554   vec_free (locator_set_name);
16555   vec_free (key);
16556
16557   /* send it... */
16558   S (mp);
16559
16560   /* Wait for a reply... */
16561   W (ret);
16562   return ret;
16563 }
16564
16565 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16566
16567 static int
16568 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16569 {
16570   u32 dp_table = 0, vni = 0;;
16571   unformat_input_t *input = vam->input;
16572   vl_api_gpe_add_del_fwd_entry_t *mp;
16573   u8 is_add = 1;
16574   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16575   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16576   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16577   u32 action = ~0, w;
16578   ip4_address_t rmt_rloc4, lcl_rloc4;
16579   ip6_address_t rmt_rloc6, lcl_rloc6;
16580   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16581   int ret;
16582
16583   memset (&rloc, 0, sizeof (rloc));
16584
16585   /* Parse args required to build the message */
16586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16587     {
16588       if (unformat (input, "del"))
16589         is_add = 0;
16590       else if (unformat (input, "add"))
16591         is_add = 1;
16592       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16593         {
16594           rmt_eid_set = 1;
16595         }
16596       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16597         {
16598           lcl_eid_set = 1;
16599         }
16600       else if (unformat (input, "vrf %d", &dp_table))
16601         ;
16602       else if (unformat (input, "bd %d", &dp_table))
16603         ;
16604       else if (unformat (input, "vni %d", &vni))
16605         ;
16606       else if (unformat (input, "w %d", &w))
16607         {
16608           if (!curr_rloc)
16609             {
16610               errmsg ("No RLOC configured for setting priority/weight!");
16611               return -99;
16612             }
16613           curr_rloc->weight = w;
16614         }
16615       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16616                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16617         {
16618           rloc.is_ip4 = 1;
16619
16620           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16621           rloc.weight = 0;
16622           vec_add1 (lcl_locs, rloc);
16623
16624           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16625           vec_add1 (rmt_locs, rloc);
16626           /* weight saved in rmt loc */
16627           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16628         }
16629       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16630                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16631         {
16632           rloc.is_ip4 = 0;
16633           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16634           rloc.weight = 0;
16635           vec_add1 (lcl_locs, rloc);
16636
16637           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16638           vec_add1 (rmt_locs, rloc);
16639           /* weight saved in rmt loc */
16640           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16641         }
16642       else if (unformat (input, "action %d", &action))
16643         {
16644           ;
16645         }
16646       else
16647         {
16648           clib_warning ("parse error '%U'", format_unformat_error, input);
16649           return -99;
16650         }
16651     }
16652
16653   if (!rmt_eid_set)
16654     {
16655       errmsg ("remote eid addresses not set");
16656       return -99;
16657     }
16658
16659   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16660     {
16661       errmsg ("eid types don't match");
16662       return -99;
16663     }
16664
16665   if (0 == rmt_locs && (u32) ~ 0 == action)
16666     {
16667       errmsg ("action not set for negative mapping");
16668       return -99;
16669     }
16670
16671   /* Construct the API message */
16672   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16673       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16674
16675   mp->is_add = is_add;
16676   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16677   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16678   mp->eid_type = rmt_eid->type;
16679   mp->dp_table = clib_host_to_net_u32 (dp_table);
16680   mp->vni = clib_host_to_net_u32 (vni);
16681   mp->rmt_len = rmt_eid->len;
16682   mp->lcl_len = lcl_eid->len;
16683   mp->action = action;
16684
16685   if (0 != rmt_locs && 0 != lcl_locs)
16686     {
16687       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16688       clib_memcpy (mp->locs, lcl_locs,
16689                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16690
16691       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16692       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16693                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16694     }
16695   vec_free (lcl_locs);
16696   vec_free (rmt_locs);
16697
16698   /* send it... */
16699   S (mp);
16700
16701   /* Wait for a reply... */
16702   W (ret);
16703   return ret;
16704 }
16705
16706 static int
16707 api_one_add_del_map_server (vat_main_t * vam)
16708 {
16709   unformat_input_t *input = vam->input;
16710   vl_api_one_add_del_map_server_t *mp;
16711   u8 is_add = 1;
16712   u8 ipv4_set = 0;
16713   u8 ipv6_set = 0;
16714   ip4_address_t ipv4;
16715   ip6_address_t ipv6;
16716   int ret;
16717
16718   /* Parse args required to build the message */
16719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16720     {
16721       if (unformat (input, "del"))
16722         {
16723           is_add = 0;
16724         }
16725       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16726         {
16727           ipv4_set = 1;
16728         }
16729       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16730         {
16731           ipv6_set = 1;
16732         }
16733       else
16734         break;
16735     }
16736
16737   if (ipv4_set && ipv6_set)
16738     {
16739       errmsg ("both eid v4 and v6 addresses set");
16740       return -99;
16741     }
16742
16743   if (!ipv4_set && !ipv6_set)
16744     {
16745       errmsg ("eid addresses not set");
16746       return -99;
16747     }
16748
16749   /* Construct the API message */
16750   M (ONE_ADD_DEL_MAP_SERVER, mp);
16751
16752   mp->is_add = is_add;
16753   if (ipv6_set)
16754     {
16755       mp->is_ipv6 = 1;
16756       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16757     }
16758   else
16759     {
16760       mp->is_ipv6 = 0;
16761       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16762     }
16763
16764   /* send it... */
16765   S (mp);
16766
16767   /* Wait for a reply... */
16768   W (ret);
16769   return ret;
16770 }
16771
16772 #define api_lisp_add_del_map_server api_one_add_del_map_server
16773
16774 static int
16775 api_one_add_del_map_resolver (vat_main_t * vam)
16776 {
16777   unformat_input_t *input = vam->input;
16778   vl_api_one_add_del_map_resolver_t *mp;
16779   u8 is_add = 1;
16780   u8 ipv4_set = 0;
16781   u8 ipv6_set = 0;
16782   ip4_address_t ipv4;
16783   ip6_address_t ipv6;
16784   int ret;
16785
16786   /* Parse args required to build the message */
16787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16788     {
16789       if (unformat (input, "del"))
16790         {
16791           is_add = 0;
16792         }
16793       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16794         {
16795           ipv4_set = 1;
16796         }
16797       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16798         {
16799           ipv6_set = 1;
16800         }
16801       else
16802         break;
16803     }
16804
16805   if (ipv4_set && ipv6_set)
16806     {
16807       errmsg ("both eid v4 and v6 addresses set");
16808       return -99;
16809     }
16810
16811   if (!ipv4_set && !ipv6_set)
16812     {
16813       errmsg ("eid addresses not set");
16814       return -99;
16815     }
16816
16817   /* Construct the API message */
16818   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16819
16820   mp->is_add = is_add;
16821   if (ipv6_set)
16822     {
16823       mp->is_ipv6 = 1;
16824       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16825     }
16826   else
16827     {
16828       mp->is_ipv6 = 0;
16829       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16830     }
16831
16832   /* send it... */
16833   S (mp);
16834
16835   /* Wait for a reply... */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16841
16842 static int
16843 api_lisp_gpe_enable_disable (vat_main_t * vam)
16844 {
16845   unformat_input_t *input = vam->input;
16846   vl_api_gpe_enable_disable_t *mp;
16847   u8 is_set = 0;
16848   u8 is_en = 1;
16849   int ret;
16850
16851   /* Parse args required to build the message */
16852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16853     {
16854       if (unformat (input, "enable"))
16855         {
16856           is_set = 1;
16857           is_en = 1;
16858         }
16859       else if (unformat (input, "disable"))
16860         {
16861           is_set = 1;
16862           is_en = 0;
16863         }
16864       else
16865         break;
16866     }
16867
16868   if (is_set == 0)
16869     {
16870       errmsg ("Value not set");
16871       return -99;
16872     }
16873
16874   /* Construct the API message */
16875   M (GPE_ENABLE_DISABLE, mp);
16876
16877   mp->is_en = is_en;
16878
16879   /* send it... */
16880   S (mp);
16881
16882   /* Wait for a reply... */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 static int
16888 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16889 {
16890   unformat_input_t *input = vam->input;
16891   vl_api_one_rloc_probe_enable_disable_t *mp;
16892   u8 is_set = 0;
16893   u8 is_en = 0;
16894   int ret;
16895
16896   /* Parse args required to build the message */
16897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16898     {
16899       if (unformat (input, "enable"))
16900         {
16901           is_set = 1;
16902           is_en = 1;
16903         }
16904       else if (unformat (input, "disable"))
16905         is_set = 1;
16906       else
16907         break;
16908     }
16909
16910   if (!is_set)
16911     {
16912       errmsg ("Value not set");
16913       return -99;
16914     }
16915
16916   /* Construct the API message */
16917   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16918
16919   mp->is_enabled = is_en;
16920
16921   /* send it... */
16922   S (mp);
16923
16924   /* Wait for a reply... */
16925   W (ret);
16926   return ret;
16927 }
16928
16929 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16930
16931 static int
16932 api_one_map_register_enable_disable (vat_main_t * vam)
16933 {
16934   unformat_input_t *input = vam->input;
16935   vl_api_one_map_register_enable_disable_t *mp;
16936   u8 is_set = 0;
16937   u8 is_en = 0;
16938   int ret;
16939
16940   /* Parse args required to build the message */
16941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16942     {
16943       if (unformat (input, "enable"))
16944         {
16945           is_set = 1;
16946           is_en = 1;
16947         }
16948       else if (unformat (input, "disable"))
16949         is_set = 1;
16950       else
16951         break;
16952     }
16953
16954   if (!is_set)
16955     {
16956       errmsg ("Value not set");
16957       return -99;
16958     }
16959
16960   /* Construct the API message */
16961   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16962
16963   mp->is_enabled = is_en;
16964
16965   /* send it... */
16966   S (mp);
16967
16968   /* Wait for a reply... */
16969   W (ret);
16970   return ret;
16971 }
16972
16973 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16974
16975 static int
16976 api_one_enable_disable (vat_main_t * vam)
16977 {
16978   unformat_input_t *input = vam->input;
16979   vl_api_one_enable_disable_t *mp;
16980   u8 is_set = 0;
16981   u8 is_en = 0;
16982   int ret;
16983
16984   /* Parse args required to build the message */
16985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16986     {
16987       if (unformat (input, "enable"))
16988         {
16989           is_set = 1;
16990           is_en = 1;
16991         }
16992       else if (unformat (input, "disable"))
16993         {
16994           is_set = 1;
16995         }
16996       else
16997         break;
16998     }
16999
17000   if (!is_set)
17001     {
17002       errmsg ("Value not set");
17003       return -99;
17004     }
17005
17006   /* Construct the API message */
17007   M (ONE_ENABLE_DISABLE, mp);
17008
17009   mp->is_en = is_en;
17010
17011   /* send it... */
17012   S (mp);
17013
17014   /* Wait for a reply... */
17015   W (ret);
17016   return ret;
17017 }
17018
17019 #define api_lisp_enable_disable api_one_enable_disable
17020
17021 static int
17022 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17023 {
17024   unformat_input_t *input = vam->input;
17025   vl_api_one_enable_disable_xtr_mode_t *mp;
17026   u8 is_set = 0;
17027   u8 is_en = 0;
17028   int ret;
17029
17030   /* Parse args required to build the message */
17031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17032     {
17033       if (unformat (input, "enable"))
17034         {
17035           is_set = 1;
17036           is_en = 1;
17037         }
17038       else if (unformat (input, "disable"))
17039         {
17040           is_set = 1;
17041         }
17042       else
17043         break;
17044     }
17045
17046   if (!is_set)
17047     {
17048       errmsg ("Value not set");
17049       return -99;
17050     }
17051
17052   /* Construct the API message */
17053   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17054
17055   mp->is_en = is_en;
17056
17057   /* send it... */
17058   S (mp);
17059
17060   /* Wait for a reply... */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_one_show_xtr_mode (vat_main_t * vam)
17067 {
17068   vl_api_one_show_xtr_mode_t *mp;
17069   int ret;
17070
17071   /* Construct the API message */
17072   M (ONE_SHOW_XTR_MODE, mp);
17073
17074   /* send it... */
17075   S (mp);
17076
17077   /* Wait for a reply... */
17078   W (ret);
17079   return ret;
17080 }
17081
17082 static int
17083 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17084 {
17085   unformat_input_t *input = vam->input;
17086   vl_api_one_enable_disable_pitr_mode_t *mp;
17087   u8 is_set = 0;
17088   u8 is_en = 0;
17089   int ret;
17090
17091   /* Parse args required to build the message */
17092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17093     {
17094       if (unformat (input, "enable"))
17095         {
17096           is_set = 1;
17097           is_en = 1;
17098         }
17099       else if (unformat (input, "disable"))
17100         {
17101           is_set = 1;
17102         }
17103       else
17104         break;
17105     }
17106
17107   if (!is_set)
17108     {
17109       errmsg ("Value not set");
17110       return -99;
17111     }
17112
17113   /* Construct the API message */
17114   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17115
17116   mp->is_en = is_en;
17117
17118   /* send it... */
17119   S (mp);
17120
17121   /* Wait for a reply... */
17122   W (ret);
17123   return ret;
17124 }
17125
17126 static int
17127 api_one_show_pitr_mode (vat_main_t * vam)
17128 {
17129   vl_api_one_show_pitr_mode_t *mp;
17130   int ret;
17131
17132   /* Construct the API message */
17133   M (ONE_SHOW_PITR_MODE, mp);
17134
17135   /* send it... */
17136   S (mp);
17137
17138   /* Wait for a reply... */
17139   W (ret);
17140   return ret;
17141 }
17142
17143 static int
17144 api_one_enable_disable_petr_mode (vat_main_t * vam)
17145 {
17146   unformat_input_t *input = vam->input;
17147   vl_api_one_enable_disable_petr_mode_t *mp;
17148   u8 is_set = 0;
17149   u8 is_en = 0;
17150   int ret;
17151
17152   /* Parse args required to build the message */
17153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17154     {
17155       if (unformat (input, "enable"))
17156         {
17157           is_set = 1;
17158           is_en = 1;
17159         }
17160       else if (unformat (input, "disable"))
17161         {
17162           is_set = 1;
17163         }
17164       else
17165         break;
17166     }
17167
17168   if (!is_set)
17169     {
17170       errmsg ("Value not set");
17171       return -99;
17172     }
17173
17174   /* Construct the API message */
17175   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17176
17177   mp->is_en = is_en;
17178
17179   /* send it... */
17180   S (mp);
17181
17182   /* Wait for a reply... */
17183   W (ret);
17184   return ret;
17185 }
17186
17187 static int
17188 api_one_show_petr_mode (vat_main_t * vam)
17189 {
17190   vl_api_one_show_petr_mode_t *mp;
17191   int ret;
17192
17193   /* Construct the API message */
17194   M (ONE_SHOW_PETR_MODE, mp);
17195
17196   /* send it... */
17197   S (mp);
17198
17199   /* Wait for a reply... */
17200   W (ret);
17201   return ret;
17202 }
17203
17204 static int
17205 api_show_one_map_register_state (vat_main_t * vam)
17206 {
17207   vl_api_show_one_map_register_state_t *mp;
17208   int ret;
17209
17210   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17211
17212   /* send */
17213   S (mp);
17214
17215   /* wait for reply */
17216   W (ret);
17217   return ret;
17218 }
17219
17220 #define api_show_lisp_map_register_state api_show_one_map_register_state
17221
17222 static int
17223 api_show_one_rloc_probe_state (vat_main_t * vam)
17224 {
17225   vl_api_show_one_rloc_probe_state_t *mp;
17226   int ret;
17227
17228   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17229
17230   /* send */
17231   S (mp);
17232
17233   /* wait for reply */
17234   W (ret);
17235   return ret;
17236 }
17237
17238 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17239
17240 static int
17241 api_one_add_del_ndp_entry (vat_main_t * vam)
17242 {
17243   vl_api_one_add_del_ndp_entry_t *mp;
17244   unformat_input_t *input = vam->input;
17245   u8 is_add = 1;
17246   u8 mac_set = 0;
17247   u8 bd_set = 0;
17248   u8 ip_set = 0;
17249   u8 mac[6] = { 0, };
17250   u8 ip6[16] = { 0, };
17251   u32 bd = ~0;
17252   int ret;
17253
17254   /* Parse args required to build the message */
17255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17256     {
17257       if (unformat (input, "del"))
17258         is_add = 0;
17259       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17260         mac_set = 1;
17261       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17262         ip_set = 1;
17263       else if (unformat (input, "bd %d", &bd))
17264         bd_set = 1;
17265       else
17266         {
17267           errmsg ("parse error '%U'", format_unformat_error, input);
17268           return -99;
17269         }
17270     }
17271
17272   if (!bd_set || !ip_set || (!mac_set && is_add))
17273     {
17274       errmsg ("Missing BD, IP or MAC!");
17275       return -99;
17276     }
17277
17278   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17279   mp->is_add = is_add;
17280   clib_memcpy (mp->mac, mac, 6);
17281   mp->bd = clib_host_to_net_u32 (bd);
17282   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17283
17284   /* send */
17285   S (mp);
17286
17287   /* wait for reply */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 static int
17293 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17294 {
17295   vl_api_one_add_del_l2_arp_entry_t *mp;
17296   unformat_input_t *input = vam->input;
17297   u8 is_add = 1;
17298   u8 mac_set = 0;
17299   u8 bd_set = 0;
17300   u8 ip_set = 0;
17301   u8 mac[6] = { 0, };
17302   u32 ip4 = 0, bd = ~0;
17303   int ret;
17304
17305   /* Parse args required to build the message */
17306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17307     {
17308       if (unformat (input, "del"))
17309         is_add = 0;
17310       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17311         mac_set = 1;
17312       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17313         ip_set = 1;
17314       else if (unformat (input, "bd %d", &bd))
17315         bd_set = 1;
17316       else
17317         {
17318           errmsg ("parse error '%U'", format_unformat_error, input);
17319           return -99;
17320         }
17321     }
17322
17323   if (!bd_set || !ip_set || (!mac_set && is_add))
17324     {
17325       errmsg ("Missing BD, IP or MAC!");
17326       return -99;
17327     }
17328
17329   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17330   mp->is_add = is_add;
17331   clib_memcpy (mp->mac, mac, 6);
17332   mp->bd = clib_host_to_net_u32 (bd);
17333   mp->ip4 = ip4;
17334
17335   /* send */
17336   S (mp);
17337
17338   /* wait for reply */
17339   W (ret);
17340   return ret;
17341 }
17342
17343 static int
17344 api_one_ndp_bd_get (vat_main_t * vam)
17345 {
17346   vl_api_one_ndp_bd_get_t *mp;
17347   int ret;
17348
17349   M (ONE_NDP_BD_GET, mp);
17350
17351   /* send */
17352   S (mp);
17353
17354   /* wait for reply */
17355   W (ret);
17356   return ret;
17357 }
17358
17359 static int
17360 api_one_ndp_entries_get (vat_main_t * vam)
17361 {
17362   vl_api_one_ndp_entries_get_t *mp;
17363   unformat_input_t *input = vam->input;
17364   u8 bd_set = 0;
17365   u32 bd = ~0;
17366   int ret;
17367
17368   /* Parse args required to build the message */
17369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17370     {
17371       if (unformat (input, "bd %d", &bd))
17372         bd_set = 1;
17373       else
17374         {
17375           errmsg ("parse error '%U'", format_unformat_error, input);
17376           return -99;
17377         }
17378     }
17379
17380   if (!bd_set)
17381     {
17382       errmsg ("Expected bridge domain!");
17383       return -99;
17384     }
17385
17386   M (ONE_NDP_ENTRIES_GET, mp);
17387   mp->bd = clib_host_to_net_u32 (bd);
17388
17389   /* send */
17390   S (mp);
17391
17392   /* wait for reply */
17393   W (ret);
17394   return ret;
17395 }
17396
17397 static int
17398 api_one_l2_arp_bd_get (vat_main_t * vam)
17399 {
17400   vl_api_one_l2_arp_bd_get_t *mp;
17401   int ret;
17402
17403   M (ONE_L2_ARP_BD_GET, mp);
17404
17405   /* send */
17406   S (mp);
17407
17408   /* wait for reply */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 static int
17414 api_one_l2_arp_entries_get (vat_main_t * vam)
17415 {
17416   vl_api_one_l2_arp_entries_get_t *mp;
17417   unformat_input_t *input = vam->input;
17418   u8 bd_set = 0;
17419   u32 bd = ~0;
17420   int ret;
17421
17422   /* Parse args required to build the message */
17423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17424     {
17425       if (unformat (input, "bd %d", &bd))
17426         bd_set = 1;
17427       else
17428         {
17429           errmsg ("parse error '%U'", format_unformat_error, input);
17430           return -99;
17431         }
17432     }
17433
17434   if (!bd_set)
17435     {
17436       errmsg ("Expected bridge domain!");
17437       return -99;
17438     }
17439
17440   M (ONE_L2_ARP_ENTRIES_GET, mp);
17441   mp->bd = clib_host_to_net_u32 (bd);
17442
17443   /* send */
17444   S (mp);
17445
17446   /* wait for reply */
17447   W (ret);
17448   return ret;
17449 }
17450
17451 static int
17452 api_one_stats_enable_disable (vat_main_t * vam)
17453 {
17454   vl_api_one_stats_enable_disable_t *mp;
17455   unformat_input_t *input = vam->input;
17456   u8 is_set = 0;
17457   u8 is_en = 0;
17458   int ret;
17459
17460   /* Parse args required to build the message */
17461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17462     {
17463       if (unformat (input, "enable"))
17464         {
17465           is_set = 1;
17466           is_en = 1;
17467         }
17468       else if (unformat (input, "disable"))
17469         {
17470           is_set = 1;
17471         }
17472       else
17473         break;
17474     }
17475
17476   if (!is_set)
17477     {
17478       errmsg ("Value not set");
17479       return -99;
17480     }
17481
17482   M (ONE_STATS_ENABLE_DISABLE, mp);
17483   mp->is_en = is_en;
17484
17485   /* send */
17486   S (mp);
17487
17488   /* wait for reply */
17489   W (ret);
17490   return ret;
17491 }
17492
17493 static int
17494 api_show_one_stats_enable_disable (vat_main_t * vam)
17495 {
17496   vl_api_show_one_stats_enable_disable_t *mp;
17497   int ret;
17498
17499   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17500
17501   /* send */
17502   S (mp);
17503
17504   /* wait for reply */
17505   W (ret);
17506   return ret;
17507 }
17508
17509 static int
17510 api_show_one_map_request_mode (vat_main_t * vam)
17511 {
17512   vl_api_show_one_map_request_mode_t *mp;
17513   int ret;
17514
17515   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17516
17517   /* send */
17518   S (mp);
17519
17520   /* wait for reply */
17521   W (ret);
17522   return ret;
17523 }
17524
17525 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17526
17527 static int
17528 api_one_map_request_mode (vat_main_t * vam)
17529 {
17530   unformat_input_t *input = vam->input;
17531   vl_api_one_map_request_mode_t *mp;
17532   u8 mode = 0;
17533   int ret;
17534
17535   /* Parse args required to build the message */
17536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17537     {
17538       if (unformat (input, "dst-only"))
17539         mode = 0;
17540       else if (unformat (input, "src-dst"))
17541         mode = 1;
17542       else
17543         {
17544           errmsg ("parse error '%U'", format_unformat_error, input);
17545           return -99;
17546         }
17547     }
17548
17549   M (ONE_MAP_REQUEST_MODE, mp);
17550
17551   mp->mode = mode;
17552
17553   /* send */
17554   S (mp);
17555
17556   /* wait for reply */
17557   W (ret);
17558   return ret;
17559 }
17560
17561 #define api_lisp_map_request_mode api_one_map_request_mode
17562
17563 /**
17564  * Enable/disable ONE proxy ITR.
17565  *
17566  * @param vam vpp API test context
17567  * @return return code
17568  */
17569 static int
17570 api_one_pitr_set_locator_set (vat_main_t * vam)
17571 {
17572   u8 ls_name_set = 0;
17573   unformat_input_t *input = vam->input;
17574   vl_api_one_pitr_set_locator_set_t *mp;
17575   u8 is_add = 1;
17576   u8 *ls_name = 0;
17577   int ret;
17578
17579   /* Parse args required to build the message */
17580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17581     {
17582       if (unformat (input, "del"))
17583         is_add = 0;
17584       else if (unformat (input, "locator-set %s", &ls_name))
17585         ls_name_set = 1;
17586       else
17587         {
17588           errmsg ("parse error '%U'", format_unformat_error, input);
17589           return -99;
17590         }
17591     }
17592
17593   if (!ls_name_set)
17594     {
17595       errmsg ("locator-set name not set!");
17596       return -99;
17597     }
17598
17599   M (ONE_PITR_SET_LOCATOR_SET, mp);
17600
17601   mp->is_add = is_add;
17602   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17603   vec_free (ls_name);
17604
17605   /* send */
17606   S (mp);
17607
17608   /* wait for reply */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17614
17615 static int
17616 api_one_nsh_set_locator_set (vat_main_t * vam)
17617 {
17618   u8 ls_name_set = 0;
17619   unformat_input_t *input = vam->input;
17620   vl_api_one_nsh_set_locator_set_t *mp;
17621   u8 is_add = 1;
17622   u8 *ls_name = 0;
17623   int ret;
17624
17625   /* Parse args required to build the message */
17626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17627     {
17628       if (unformat (input, "del"))
17629         is_add = 0;
17630       else if (unformat (input, "ls %s", &ls_name))
17631         ls_name_set = 1;
17632       else
17633         {
17634           errmsg ("parse error '%U'", format_unformat_error, input);
17635           return -99;
17636         }
17637     }
17638
17639   if (!ls_name_set && is_add)
17640     {
17641       errmsg ("locator-set name not set!");
17642       return -99;
17643     }
17644
17645   M (ONE_NSH_SET_LOCATOR_SET, mp);
17646
17647   mp->is_add = is_add;
17648   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17649   vec_free (ls_name);
17650
17651   /* send */
17652   S (mp);
17653
17654   /* wait for reply */
17655   W (ret);
17656   return ret;
17657 }
17658
17659 static int
17660 api_show_one_pitr (vat_main_t * vam)
17661 {
17662   vl_api_show_one_pitr_t *mp;
17663   int ret;
17664
17665   if (!vam->json_output)
17666     {
17667       print (vam->ofp, "%=20s", "lisp status:");
17668     }
17669
17670   M (SHOW_ONE_PITR, mp);
17671   /* send it... */
17672   S (mp);
17673
17674   /* Wait for a reply... */
17675   W (ret);
17676   return ret;
17677 }
17678
17679 #define api_show_lisp_pitr api_show_one_pitr
17680
17681 static int
17682 api_one_use_petr (vat_main_t * vam)
17683 {
17684   unformat_input_t *input = vam->input;
17685   vl_api_one_use_petr_t *mp;
17686   u8 is_add = 0;
17687   ip_address_t ip;
17688   int ret;
17689
17690   memset (&ip, 0, sizeof (ip));
17691
17692   /* Parse args required to build the message */
17693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17694     {
17695       if (unformat (input, "disable"))
17696         is_add = 0;
17697       else
17698         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17699         {
17700           is_add = 1;
17701           ip_addr_version (&ip) = IP4;
17702         }
17703       else
17704         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17705         {
17706           is_add = 1;
17707           ip_addr_version (&ip) = IP6;
17708         }
17709       else
17710         {
17711           errmsg ("parse error '%U'", format_unformat_error, input);
17712           return -99;
17713         }
17714     }
17715
17716   M (ONE_USE_PETR, mp);
17717
17718   mp->is_add = is_add;
17719   if (is_add)
17720     {
17721       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17722       if (mp->is_ip4)
17723         clib_memcpy (mp->address, &ip, 4);
17724       else
17725         clib_memcpy (mp->address, &ip, 16);
17726     }
17727
17728   /* send */
17729   S (mp);
17730
17731   /* wait for reply */
17732   W (ret);
17733   return ret;
17734 }
17735
17736 #define api_lisp_use_petr api_one_use_petr
17737
17738 static int
17739 api_show_one_nsh_mapping (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", "local ONE NSH mapping:");
17747     }
17748
17749   M (SHOW_ONE_NSH_MAPPING, mp);
17750   /* send it... */
17751   S (mp);
17752
17753   /* Wait for a reply... */
17754   W (ret);
17755   return ret;
17756 }
17757
17758 static int
17759 api_show_one_use_petr (vat_main_t * vam)
17760 {
17761   vl_api_show_one_use_petr_t *mp;
17762   int ret;
17763
17764   if (!vam->json_output)
17765     {
17766       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17767     }
17768
17769   M (SHOW_ONE_USE_PETR, mp);
17770   /* send it... */
17771   S (mp);
17772
17773   /* Wait for a reply... */
17774   W (ret);
17775   return ret;
17776 }
17777
17778 #define api_show_lisp_use_petr api_show_one_use_petr
17779
17780 /**
17781  * Add/delete mapping between vni and vrf
17782  */
17783 static int
17784 api_one_eid_table_add_del_map (vat_main_t * vam)
17785 {
17786   unformat_input_t *input = vam->input;
17787   vl_api_one_eid_table_add_del_map_t *mp;
17788   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17789   u32 vni, vrf, bd_index;
17790   int ret;
17791
17792   /* Parse args required to build the message */
17793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17794     {
17795       if (unformat (input, "del"))
17796         is_add = 0;
17797       else if (unformat (input, "vrf %d", &vrf))
17798         vrf_set = 1;
17799       else if (unformat (input, "bd_index %d", &bd_index))
17800         bd_index_set = 1;
17801       else if (unformat (input, "vni %d", &vni))
17802         vni_set = 1;
17803       else
17804         break;
17805     }
17806
17807   if (!vni_set || (!vrf_set && !bd_index_set))
17808     {
17809       errmsg ("missing arguments!");
17810       return -99;
17811     }
17812
17813   if (vrf_set && bd_index_set)
17814     {
17815       errmsg ("error: both vrf and bd entered!");
17816       return -99;
17817     }
17818
17819   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17820
17821   mp->is_add = is_add;
17822   mp->vni = htonl (vni);
17823   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17824   mp->is_l2 = bd_index_set;
17825
17826   /* send */
17827   S (mp);
17828
17829   /* wait for reply */
17830   W (ret);
17831   return ret;
17832 }
17833
17834 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17835
17836 uword
17837 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17838 {
17839   u32 *action = va_arg (*args, u32 *);
17840   u8 *s = 0;
17841
17842   if (unformat (input, "%s", &s))
17843     {
17844       if (!strcmp ((char *) s, "no-action"))
17845         action[0] = 0;
17846       else if (!strcmp ((char *) s, "natively-forward"))
17847         action[0] = 1;
17848       else if (!strcmp ((char *) s, "send-map-request"))
17849         action[0] = 2;
17850       else if (!strcmp ((char *) s, "drop"))
17851         action[0] = 3;
17852       else
17853         {
17854           clib_warning ("invalid action: '%s'", s);
17855           action[0] = 3;
17856         }
17857     }
17858   else
17859     return 0;
17860
17861   vec_free (s);
17862   return 1;
17863 }
17864
17865 /**
17866  * Add/del remote mapping to/from ONE control plane
17867  *
17868  * @param vam vpp API test context
17869  * @return return code
17870  */
17871 static int
17872 api_one_add_del_remote_mapping (vat_main_t * vam)
17873 {
17874   unformat_input_t *input = vam->input;
17875   vl_api_one_add_del_remote_mapping_t *mp;
17876   u32 vni = 0;
17877   lisp_eid_vat_t _eid, *eid = &_eid;
17878   lisp_eid_vat_t _seid, *seid = &_seid;
17879   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17880   u32 action = ~0, p, w, data_len;
17881   ip4_address_t rloc4;
17882   ip6_address_t rloc6;
17883   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17884   int ret;
17885
17886   memset (&rloc, 0, sizeof (rloc));
17887
17888   /* Parse args required to build the message */
17889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17890     {
17891       if (unformat (input, "del-all"))
17892         {
17893           del_all = 1;
17894         }
17895       else if (unformat (input, "del"))
17896         {
17897           is_add = 0;
17898         }
17899       else if (unformat (input, "add"))
17900         {
17901           is_add = 1;
17902         }
17903       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17904         {
17905           eid_set = 1;
17906         }
17907       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17908         {
17909           seid_set = 1;
17910         }
17911       else if (unformat (input, "vni %d", &vni))
17912         {
17913           ;
17914         }
17915       else if (unformat (input, "p %d w %d", &p, &w))
17916         {
17917           if (!curr_rloc)
17918             {
17919               errmsg ("No RLOC configured for setting priority/weight!");
17920               return -99;
17921             }
17922           curr_rloc->priority = p;
17923           curr_rloc->weight = w;
17924         }
17925       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17926         {
17927           rloc.is_ip4 = 1;
17928           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17929           vec_add1 (rlocs, rloc);
17930           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17931         }
17932       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17933         {
17934           rloc.is_ip4 = 0;
17935           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17936           vec_add1 (rlocs, rloc);
17937           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17938         }
17939       else if (unformat (input, "action %U",
17940                          unformat_negative_mapping_action, &action))
17941         {
17942           ;
17943         }
17944       else
17945         {
17946           clib_warning ("parse error '%U'", format_unformat_error, input);
17947           return -99;
17948         }
17949     }
17950
17951   if (0 == eid_set)
17952     {
17953       errmsg ("missing params!");
17954       return -99;
17955     }
17956
17957   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17958     {
17959       errmsg ("no action set for negative map-reply!");
17960       return -99;
17961     }
17962
17963   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17964
17965   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17966   mp->is_add = is_add;
17967   mp->vni = htonl (vni);
17968   mp->action = (u8) action;
17969   mp->is_src_dst = seid_set;
17970   mp->eid_len = eid->len;
17971   mp->seid_len = seid->len;
17972   mp->del_all = del_all;
17973   mp->eid_type = eid->type;
17974   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17975   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17976
17977   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17978   clib_memcpy (mp->rlocs, rlocs, data_len);
17979   vec_free (rlocs);
17980
17981   /* send it... */
17982   S (mp);
17983
17984   /* Wait for a reply... */
17985   W (ret);
17986   return ret;
17987 }
17988
17989 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17990
17991 /**
17992  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17993  * forwarding entries in data-plane accordingly.
17994  *
17995  * @param vam vpp API test context
17996  * @return return code
17997  */
17998 static int
17999 api_one_add_del_adjacency (vat_main_t * vam)
18000 {
18001   unformat_input_t *input = vam->input;
18002   vl_api_one_add_del_adjacency_t *mp;
18003   u32 vni = 0;
18004   ip4_address_t leid4, reid4;
18005   ip6_address_t leid6, reid6;
18006   u8 reid_mac[6] = { 0 };
18007   u8 leid_mac[6] = { 0 };
18008   u8 reid_type, leid_type;
18009   u32 leid_len = 0, reid_len = 0, len;
18010   u8 is_add = 1;
18011   int ret;
18012
18013   leid_type = reid_type = (u8) ~ 0;
18014
18015   /* Parse args required to build the message */
18016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18017     {
18018       if (unformat (input, "del"))
18019         {
18020           is_add = 0;
18021         }
18022       else if (unformat (input, "add"))
18023         {
18024           is_add = 1;
18025         }
18026       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18027                          &reid4, &len))
18028         {
18029           reid_type = 0;        /* ipv4 */
18030           reid_len = len;
18031         }
18032       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18033                          &reid6, &len))
18034         {
18035           reid_type = 1;        /* ipv6 */
18036           reid_len = len;
18037         }
18038       else if (unformat (input, "reid %U", unformat_ethernet_address,
18039                          reid_mac))
18040         {
18041           reid_type = 2;        /* mac */
18042         }
18043       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18044                          &leid4, &len))
18045         {
18046           leid_type = 0;        /* ipv4 */
18047           leid_len = len;
18048         }
18049       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18050                          &leid6, &len))
18051         {
18052           leid_type = 1;        /* ipv6 */
18053           leid_len = len;
18054         }
18055       else if (unformat (input, "leid %U", unformat_ethernet_address,
18056                          leid_mac))
18057         {
18058           leid_type = 2;        /* mac */
18059         }
18060       else if (unformat (input, "vni %d", &vni))
18061         {
18062           ;
18063         }
18064       else
18065         {
18066           errmsg ("parse error '%U'", format_unformat_error, input);
18067           return -99;
18068         }
18069     }
18070
18071   if ((u8) ~ 0 == reid_type)
18072     {
18073       errmsg ("missing params!");
18074       return -99;
18075     }
18076
18077   if (leid_type != reid_type)
18078     {
18079       errmsg ("remote and local EIDs are of different types!");
18080       return -99;
18081     }
18082
18083   M (ONE_ADD_DEL_ADJACENCY, mp);
18084   mp->is_add = is_add;
18085   mp->vni = htonl (vni);
18086   mp->leid_len = leid_len;
18087   mp->reid_len = reid_len;
18088   mp->eid_type = reid_type;
18089
18090   switch (mp->eid_type)
18091     {
18092     case 0:
18093       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18094       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18095       break;
18096     case 1:
18097       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18098       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18099       break;
18100     case 2:
18101       clib_memcpy (mp->leid, leid_mac, 6);
18102       clib_memcpy (mp->reid, reid_mac, 6);
18103       break;
18104     default:
18105       errmsg ("unknown EID type %d!", mp->eid_type);
18106       return 0;
18107     }
18108
18109   /* send it... */
18110   S (mp);
18111
18112   /* Wait for a reply... */
18113   W (ret);
18114   return ret;
18115 }
18116
18117 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18118
18119 uword
18120 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18121 {
18122   u32 *mode = va_arg (*args, u32 *);
18123
18124   if (unformat (input, "lisp"))
18125     *mode = 0;
18126   else if (unformat (input, "vxlan"))
18127     *mode = 1;
18128   else
18129     return 0;
18130
18131   return 1;
18132 }
18133
18134 static int
18135 api_gpe_get_encap_mode (vat_main_t * vam)
18136 {
18137   vl_api_gpe_get_encap_mode_t *mp;
18138   int ret;
18139
18140   /* Construct the API message */
18141   M (GPE_GET_ENCAP_MODE, mp);
18142
18143   /* send it... */
18144   S (mp);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 static int
18152 api_gpe_set_encap_mode (vat_main_t * vam)
18153 {
18154   unformat_input_t *input = vam->input;
18155   vl_api_gpe_set_encap_mode_t *mp;
18156   int ret;
18157   u32 mode = 0;
18158
18159   /* Parse args required to build the message */
18160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18161     {
18162       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18163         ;
18164       else
18165         break;
18166     }
18167
18168   /* Construct the API message */
18169   M (GPE_SET_ENCAP_MODE, mp);
18170
18171   mp->mode = mode;
18172
18173   /* send it... */
18174   S (mp);
18175
18176   /* Wait for a reply... */
18177   W (ret);
18178   return ret;
18179 }
18180
18181 static int
18182 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18183 {
18184   unformat_input_t *input = vam->input;
18185   vl_api_gpe_add_del_iface_t *mp;
18186   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18187   u32 dp_table = 0, vni = 0;
18188   int ret;
18189
18190   /* Parse args required to build the message */
18191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18192     {
18193       if (unformat (input, "up"))
18194         {
18195           action_set = 1;
18196           is_add = 1;
18197         }
18198       else if (unformat (input, "down"))
18199         {
18200           action_set = 1;
18201           is_add = 0;
18202         }
18203       else if (unformat (input, "table_id %d", &dp_table))
18204         {
18205           dp_table_set = 1;
18206         }
18207       else if (unformat (input, "bd_id %d", &dp_table))
18208         {
18209           dp_table_set = 1;
18210           is_l2 = 1;
18211         }
18212       else if (unformat (input, "vni %d", &vni))
18213         {
18214           vni_set = 1;
18215         }
18216       else
18217         break;
18218     }
18219
18220   if (action_set == 0)
18221     {
18222       errmsg ("Action not set");
18223       return -99;
18224     }
18225   if (dp_table_set == 0 || vni_set == 0)
18226     {
18227       errmsg ("vni and dp_table must be set");
18228       return -99;
18229     }
18230
18231   /* Construct the API message */
18232   M (GPE_ADD_DEL_IFACE, mp);
18233
18234   mp->is_add = is_add;
18235   mp->dp_table = clib_host_to_net_u32 (dp_table);
18236   mp->is_l2 = is_l2;
18237   mp->vni = clib_host_to_net_u32 (vni);
18238
18239   /* send it... */
18240   S (mp);
18241
18242   /* Wait for a reply... */
18243   W (ret);
18244   return ret;
18245 }
18246
18247 static int
18248 api_one_map_register_fallback_threshold (vat_main_t * vam)
18249 {
18250   unformat_input_t *input = vam->input;
18251   vl_api_one_map_register_fallback_threshold_t *mp;
18252   u32 value = 0;
18253   u8 is_set = 0;
18254   int ret;
18255
18256   /* Parse args required to build the message */
18257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18258     {
18259       if (unformat (input, "%u", &value))
18260         is_set = 1;
18261       else
18262         {
18263           clib_warning ("parse error '%U'", format_unformat_error, input);
18264           return -99;
18265         }
18266     }
18267
18268   if (!is_set)
18269     {
18270       errmsg ("fallback threshold value is missing!");
18271       return -99;
18272     }
18273
18274   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18275   mp->value = clib_host_to_net_u32 (value);
18276
18277   /* send it... */
18278   S (mp);
18279
18280   /* Wait for a reply... */
18281   W (ret);
18282   return ret;
18283 }
18284
18285 static int
18286 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18287 {
18288   vl_api_show_one_map_register_fallback_threshold_t *mp;
18289   int ret;
18290
18291   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18292
18293   /* send it... */
18294   S (mp);
18295
18296   /* Wait for a reply... */
18297   W (ret);
18298   return ret;
18299 }
18300
18301 uword
18302 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18303 {
18304   u32 *proto = va_arg (*args, u32 *);
18305
18306   if (unformat (input, "udp"))
18307     *proto = 1;
18308   else if (unformat (input, "api"))
18309     *proto = 2;
18310   else
18311     return 0;
18312
18313   return 1;
18314 }
18315
18316 static int
18317 api_one_set_transport_protocol (vat_main_t * vam)
18318 {
18319   unformat_input_t *input = vam->input;
18320   vl_api_one_set_transport_protocol_t *mp;
18321   u8 is_set = 0;
18322   u32 protocol = 0;
18323   int ret;
18324
18325   /* Parse args required to build the message */
18326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18327     {
18328       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18329         is_set = 1;
18330       else
18331         {
18332           clib_warning ("parse error '%U'", format_unformat_error, input);
18333           return -99;
18334         }
18335     }
18336
18337   if (!is_set)
18338     {
18339       errmsg ("Transport protocol missing!");
18340       return -99;
18341     }
18342
18343   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18344   mp->protocol = (u8) protocol;
18345
18346   /* send it... */
18347   S (mp);
18348
18349   /* Wait for a reply... */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_one_get_transport_protocol (vat_main_t * vam)
18356 {
18357   vl_api_one_get_transport_protocol_t *mp;
18358   int ret;
18359
18360   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18361
18362   /* send it... */
18363   S (mp);
18364
18365   /* Wait for a reply... */
18366   W (ret);
18367   return ret;
18368 }
18369
18370 static int
18371 api_one_map_register_set_ttl (vat_main_t * vam)
18372 {
18373   unformat_input_t *input = vam->input;
18374   vl_api_one_map_register_set_ttl_t *mp;
18375   u32 ttl = 0;
18376   u8 is_set = 0;
18377   int ret;
18378
18379   /* Parse args required to build the message */
18380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18381     {
18382       if (unformat (input, "%u", &ttl))
18383         is_set = 1;
18384       else
18385         {
18386           clib_warning ("parse error '%U'", format_unformat_error, input);
18387           return -99;
18388         }
18389     }
18390
18391   if (!is_set)
18392     {
18393       errmsg ("TTL value missing!");
18394       return -99;
18395     }
18396
18397   M (ONE_MAP_REGISTER_SET_TTL, mp);
18398   mp->ttl = clib_host_to_net_u32 (ttl);
18399
18400   /* send it... */
18401   S (mp);
18402
18403   /* Wait for a reply... */
18404   W (ret);
18405   return ret;
18406 }
18407
18408 static int
18409 api_show_one_map_register_ttl (vat_main_t * vam)
18410 {
18411   vl_api_show_one_map_register_ttl_t *mp;
18412   int ret;
18413
18414   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18415
18416   /* send it... */
18417   S (mp);
18418
18419   /* Wait for a reply... */
18420   W (ret);
18421   return ret;
18422 }
18423
18424 /**
18425  * Add/del map request itr rlocs from ONE control plane and updates
18426  *
18427  * @param vam vpp API test context
18428  * @return return code
18429  */
18430 static int
18431 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18432 {
18433   unformat_input_t *input = vam->input;
18434   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18435   u8 *locator_set_name = 0;
18436   u8 locator_set_name_set = 0;
18437   u8 is_add = 1;
18438   int ret;
18439
18440   /* Parse args required to build the message */
18441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18442     {
18443       if (unformat (input, "del"))
18444         {
18445           is_add = 0;
18446         }
18447       else if (unformat (input, "%_%v%_", &locator_set_name))
18448         {
18449           locator_set_name_set = 1;
18450         }
18451       else
18452         {
18453           clib_warning ("parse error '%U'", format_unformat_error, input);
18454           return -99;
18455         }
18456     }
18457
18458   if (is_add && !locator_set_name_set)
18459     {
18460       errmsg ("itr-rloc is not set!");
18461       return -99;
18462     }
18463
18464   if (is_add && vec_len (locator_set_name) > 64)
18465     {
18466       errmsg ("itr-rloc locator-set name too long");
18467       vec_free (locator_set_name);
18468       return -99;
18469     }
18470
18471   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18472   mp->is_add = is_add;
18473   if (is_add)
18474     {
18475       clib_memcpy (mp->locator_set_name, locator_set_name,
18476                    vec_len (locator_set_name));
18477     }
18478   else
18479     {
18480       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18481     }
18482   vec_free (locator_set_name);
18483
18484   /* send it... */
18485   S (mp);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18493
18494 static int
18495 api_one_locator_dump (vat_main_t * vam)
18496 {
18497   unformat_input_t *input = vam->input;
18498   vl_api_one_locator_dump_t *mp;
18499   vl_api_control_ping_t *mp_ping;
18500   u8 is_index_set = 0, is_name_set = 0;
18501   u8 *ls_name = 0;
18502   u32 ls_index = ~0;
18503   int ret;
18504
18505   /* Parse args required to build the message */
18506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18507     {
18508       if (unformat (input, "ls_name %_%v%_", &ls_name))
18509         {
18510           is_name_set = 1;
18511         }
18512       else if (unformat (input, "ls_index %d", &ls_index))
18513         {
18514           is_index_set = 1;
18515         }
18516       else
18517         {
18518           errmsg ("parse error '%U'", format_unformat_error, input);
18519           return -99;
18520         }
18521     }
18522
18523   if (!is_index_set && !is_name_set)
18524     {
18525       errmsg ("error: expected one of index or name!");
18526       return -99;
18527     }
18528
18529   if (is_index_set && is_name_set)
18530     {
18531       errmsg ("error: only one param expected!");
18532       return -99;
18533     }
18534
18535   if (vec_len (ls_name) > 62)
18536     {
18537       errmsg ("error: locator set name too long!");
18538       return -99;
18539     }
18540
18541   if (!vam->json_output)
18542     {
18543       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18544     }
18545
18546   M (ONE_LOCATOR_DUMP, mp);
18547   mp->is_index_set = is_index_set;
18548
18549   if (is_index_set)
18550     mp->ls_index = clib_host_to_net_u32 (ls_index);
18551   else
18552     {
18553       vec_add1 (ls_name, 0);
18554       strncpy ((char *) mp->ls_name, (char *) ls_name,
18555                sizeof (mp->ls_name) - 1);
18556     }
18557
18558   /* send it... */
18559   S (mp);
18560
18561   /* Use a control ping for synchronization */
18562   MPING (CONTROL_PING, mp_ping);
18563   S (mp_ping);
18564
18565   /* Wait for a reply... */
18566   W (ret);
18567   return ret;
18568 }
18569
18570 #define api_lisp_locator_dump api_one_locator_dump
18571
18572 static int
18573 api_one_locator_set_dump (vat_main_t * vam)
18574 {
18575   vl_api_one_locator_set_dump_t *mp;
18576   vl_api_control_ping_t *mp_ping;
18577   unformat_input_t *input = vam->input;
18578   u8 filter = 0;
18579   int ret;
18580
18581   /* Parse args required to build the message */
18582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18583     {
18584       if (unformat (input, "local"))
18585         {
18586           filter = 1;
18587         }
18588       else if (unformat (input, "remote"))
18589         {
18590           filter = 2;
18591         }
18592       else
18593         {
18594           errmsg ("parse error '%U'", format_unformat_error, input);
18595           return -99;
18596         }
18597     }
18598
18599   if (!vam->json_output)
18600     {
18601       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18602     }
18603
18604   M (ONE_LOCATOR_SET_DUMP, mp);
18605
18606   mp->filter = filter;
18607
18608   /* send it... */
18609   S (mp);
18610
18611   /* Use a control ping for synchronization */
18612   MPING (CONTROL_PING, mp_ping);
18613   S (mp_ping);
18614
18615   /* Wait for a reply... */
18616   W (ret);
18617   return ret;
18618 }
18619
18620 #define api_lisp_locator_set_dump api_one_locator_set_dump
18621
18622 static int
18623 api_one_eid_table_map_dump (vat_main_t * vam)
18624 {
18625   u8 is_l2 = 0;
18626   u8 mode_set = 0;
18627   unformat_input_t *input = vam->input;
18628   vl_api_one_eid_table_map_dump_t *mp;
18629   vl_api_control_ping_t *mp_ping;
18630   int ret;
18631
18632   /* Parse args required to build the message */
18633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18634     {
18635       if (unformat (input, "l2"))
18636         {
18637           is_l2 = 1;
18638           mode_set = 1;
18639         }
18640       else if (unformat (input, "l3"))
18641         {
18642           is_l2 = 0;
18643           mode_set = 1;
18644         }
18645       else
18646         {
18647           errmsg ("parse error '%U'", format_unformat_error, input);
18648           return -99;
18649         }
18650     }
18651
18652   if (!mode_set)
18653     {
18654       errmsg ("expected one of 'l2' or 'l3' parameter!");
18655       return -99;
18656     }
18657
18658   if (!vam->json_output)
18659     {
18660       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18661     }
18662
18663   M (ONE_EID_TABLE_MAP_DUMP, mp);
18664   mp->is_l2 = is_l2;
18665
18666   /* send it... */
18667   S (mp);
18668
18669   /* Use a control ping for synchronization */
18670   MPING (CONTROL_PING, mp_ping);
18671   S (mp_ping);
18672
18673   /* Wait for a reply... */
18674   W (ret);
18675   return ret;
18676 }
18677
18678 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18679
18680 static int
18681 api_one_eid_table_vni_dump (vat_main_t * vam)
18682 {
18683   vl_api_one_eid_table_vni_dump_t *mp;
18684   vl_api_control_ping_t *mp_ping;
18685   int ret;
18686
18687   if (!vam->json_output)
18688     {
18689       print (vam->ofp, "VNI");
18690     }
18691
18692   M (ONE_EID_TABLE_VNI_DUMP, mp);
18693
18694   /* send it... */
18695   S (mp);
18696
18697   /* Use a control ping for synchronization */
18698   MPING (CONTROL_PING, mp_ping);
18699   S (mp_ping);
18700
18701   /* Wait for a reply... */
18702   W (ret);
18703   return ret;
18704 }
18705
18706 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18707
18708 static int
18709 api_one_eid_table_dump (vat_main_t * vam)
18710 {
18711   unformat_input_t *i = vam->input;
18712   vl_api_one_eid_table_dump_t *mp;
18713   vl_api_control_ping_t *mp_ping;
18714   struct in_addr ip4;
18715   struct in6_addr ip6;
18716   u8 mac[6];
18717   u8 eid_type = ~0, eid_set = 0;
18718   u32 prefix_length = ~0, t, vni = 0;
18719   u8 filter = 0;
18720   int ret;
18721   lisp_nsh_api_t nsh;
18722
18723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18724     {
18725       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18726         {
18727           eid_set = 1;
18728           eid_type = 0;
18729           prefix_length = t;
18730         }
18731       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18732         {
18733           eid_set = 1;
18734           eid_type = 1;
18735           prefix_length = t;
18736         }
18737       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18738         {
18739           eid_set = 1;
18740           eid_type = 2;
18741         }
18742       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18743         {
18744           eid_set = 1;
18745           eid_type = 3;
18746         }
18747       else if (unformat (i, "vni %d", &t))
18748         {
18749           vni = t;
18750         }
18751       else if (unformat (i, "local"))
18752         {
18753           filter = 1;
18754         }
18755       else if (unformat (i, "remote"))
18756         {
18757           filter = 2;
18758         }
18759       else
18760         {
18761           errmsg ("parse error '%U'", format_unformat_error, i);
18762           return -99;
18763         }
18764     }
18765
18766   if (!vam->json_output)
18767     {
18768       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18769              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18770     }
18771
18772   M (ONE_EID_TABLE_DUMP, mp);
18773
18774   mp->filter = filter;
18775   if (eid_set)
18776     {
18777       mp->eid_set = 1;
18778       mp->vni = htonl (vni);
18779       mp->eid_type = eid_type;
18780       switch (eid_type)
18781         {
18782         case 0:
18783           mp->prefix_length = prefix_length;
18784           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18785           break;
18786         case 1:
18787           mp->prefix_length = prefix_length;
18788           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18789           break;
18790         case 2:
18791           clib_memcpy (mp->eid, mac, sizeof (mac));
18792           break;
18793         case 3:
18794           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18795           break;
18796         default:
18797           errmsg ("unknown EID type %d!", eid_type);
18798           return -99;
18799         }
18800     }
18801
18802   /* send it... */
18803   S (mp);
18804
18805   /* Use a control ping for synchronization */
18806   MPING (CONTROL_PING, mp_ping);
18807   S (mp_ping);
18808
18809   /* Wait for a reply... */
18810   W (ret);
18811   return ret;
18812 }
18813
18814 #define api_lisp_eid_table_dump api_one_eid_table_dump
18815
18816 static int
18817 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18818 {
18819   unformat_input_t *i = vam->input;
18820   vl_api_gpe_fwd_entries_get_t *mp;
18821   u8 vni_set = 0;
18822   u32 vni = ~0;
18823   int ret;
18824
18825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18826     {
18827       if (unformat (i, "vni %d", &vni))
18828         {
18829           vni_set = 1;
18830         }
18831       else
18832         {
18833           errmsg ("parse error '%U'", format_unformat_error, i);
18834           return -99;
18835         }
18836     }
18837
18838   if (!vni_set)
18839     {
18840       errmsg ("vni not set!");
18841       return -99;
18842     }
18843
18844   if (!vam->json_output)
18845     {
18846       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18847              "leid", "reid");
18848     }
18849
18850   M (GPE_FWD_ENTRIES_GET, mp);
18851   mp->vni = clib_host_to_net_u32 (vni);
18852
18853   /* send it... */
18854   S (mp);
18855
18856   /* Wait for a reply... */
18857   W (ret);
18858   return ret;
18859 }
18860
18861 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18862 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18863 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18864 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18865 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18866 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18867 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18868 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18869
18870 static int
18871 api_one_adjacencies_get (vat_main_t * vam)
18872 {
18873   unformat_input_t *i = vam->input;
18874   vl_api_one_adjacencies_get_t *mp;
18875   u8 vni_set = 0;
18876   u32 vni = ~0;
18877   int ret;
18878
18879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18880     {
18881       if (unformat (i, "vni %d", &vni))
18882         {
18883           vni_set = 1;
18884         }
18885       else
18886         {
18887           errmsg ("parse error '%U'", format_unformat_error, i);
18888           return -99;
18889         }
18890     }
18891
18892   if (!vni_set)
18893     {
18894       errmsg ("vni not set!");
18895       return -99;
18896     }
18897
18898   if (!vam->json_output)
18899     {
18900       print (vam->ofp, "%s %40s", "leid", "reid");
18901     }
18902
18903   M (ONE_ADJACENCIES_GET, mp);
18904   mp->vni = clib_host_to_net_u32 (vni);
18905
18906   /* send it... */
18907   S (mp);
18908
18909   /* Wait for a reply... */
18910   W (ret);
18911   return ret;
18912 }
18913
18914 #define api_lisp_adjacencies_get api_one_adjacencies_get
18915
18916 static int
18917 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18918 {
18919   unformat_input_t *i = vam->input;
18920   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18921   int ret;
18922   u8 ip_family_set = 0, is_ip4 = 1;
18923
18924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18925     {
18926       if (unformat (i, "ip4"))
18927         {
18928           ip_family_set = 1;
18929           is_ip4 = 1;
18930         }
18931       else if (unformat (i, "ip6"))
18932         {
18933           ip_family_set = 1;
18934           is_ip4 = 0;
18935         }
18936       else
18937         {
18938           errmsg ("parse error '%U'", format_unformat_error, i);
18939           return -99;
18940         }
18941     }
18942
18943   if (!ip_family_set)
18944     {
18945       errmsg ("ip family not set!");
18946       return -99;
18947     }
18948
18949   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18950   mp->is_ip4 = is_ip4;
18951
18952   /* send it... */
18953   S (mp);
18954
18955   /* Wait for a reply... */
18956   W (ret);
18957   return ret;
18958 }
18959
18960 static int
18961 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18962 {
18963   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18964   int ret;
18965
18966   if (!vam->json_output)
18967     {
18968       print (vam->ofp, "VNIs");
18969     }
18970
18971   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18972
18973   /* send it... */
18974   S (mp);
18975
18976   /* Wait for a reply... */
18977   W (ret);
18978   return ret;
18979 }
18980
18981 static int
18982 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18983 {
18984   unformat_input_t *i = vam->input;
18985   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18986   int ret = 0;
18987   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18988   struct in_addr ip4;
18989   struct in6_addr ip6;
18990   u32 table_id = 0, nh_sw_if_index = ~0;
18991
18992   memset (&ip4, 0, sizeof (ip4));
18993   memset (&ip6, 0, sizeof (ip6));
18994
18995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18996     {
18997       if (unformat (i, "del"))
18998         is_add = 0;
18999       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19000                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19001         {
19002           ip_set = 1;
19003           is_ip4 = 1;
19004         }
19005       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19006                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19007         {
19008           ip_set = 1;
19009           is_ip4 = 0;
19010         }
19011       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19012         {
19013           ip_set = 1;
19014           is_ip4 = 1;
19015           nh_sw_if_index = ~0;
19016         }
19017       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19018         {
19019           ip_set = 1;
19020           is_ip4 = 0;
19021           nh_sw_if_index = ~0;
19022         }
19023       else if (unformat (i, "table %d", &table_id))
19024         ;
19025       else
19026         {
19027           errmsg ("parse error '%U'", format_unformat_error, i);
19028           return -99;
19029         }
19030     }
19031
19032   if (!ip_set)
19033     {
19034       errmsg ("nh addr not set!");
19035       return -99;
19036     }
19037
19038   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19039   mp->is_add = is_add;
19040   mp->table_id = clib_host_to_net_u32 (table_id);
19041   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19042   mp->is_ip4 = is_ip4;
19043   if (is_ip4)
19044     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19045   else
19046     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19047
19048   /* send it... */
19049   S (mp);
19050
19051   /* Wait for a reply... */
19052   W (ret);
19053   return ret;
19054 }
19055
19056 static int
19057 api_one_map_server_dump (vat_main_t * vam)
19058 {
19059   vl_api_one_map_server_dump_t *mp;
19060   vl_api_control_ping_t *mp_ping;
19061   int ret;
19062
19063   if (!vam->json_output)
19064     {
19065       print (vam->ofp, "%=20s", "Map server");
19066     }
19067
19068   M (ONE_MAP_SERVER_DUMP, mp);
19069   /* send it... */
19070   S (mp);
19071
19072   /* Use a control ping for synchronization */
19073   MPING (CONTROL_PING, mp_ping);
19074   S (mp_ping);
19075
19076   /* Wait for a reply... */
19077   W (ret);
19078   return ret;
19079 }
19080
19081 #define api_lisp_map_server_dump api_one_map_server_dump
19082
19083 static int
19084 api_one_map_resolver_dump (vat_main_t * vam)
19085 {
19086   vl_api_one_map_resolver_dump_t *mp;
19087   vl_api_control_ping_t *mp_ping;
19088   int ret;
19089
19090   if (!vam->json_output)
19091     {
19092       print (vam->ofp, "%=20s", "Map resolver");
19093     }
19094
19095   M (ONE_MAP_RESOLVER_DUMP, mp);
19096   /* send it... */
19097   S (mp);
19098
19099   /* Use a control ping for synchronization */
19100   MPING (CONTROL_PING, mp_ping);
19101   S (mp_ping);
19102
19103   /* Wait for a reply... */
19104   W (ret);
19105   return ret;
19106 }
19107
19108 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19109
19110 static int
19111 api_one_stats_flush (vat_main_t * vam)
19112 {
19113   vl_api_one_stats_flush_t *mp;
19114   int ret = 0;
19115
19116   M (ONE_STATS_FLUSH, mp);
19117   S (mp);
19118   W (ret);
19119   return ret;
19120 }
19121
19122 static int
19123 api_one_stats_dump (vat_main_t * vam)
19124 {
19125   vl_api_one_stats_dump_t *mp;
19126   vl_api_control_ping_t *mp_ping;
19127   int ret;
19128
19129   M (ONE_STATS_DUMP, mp);
19130   /* send it... */
19131   S (mp);
19132
19133   /* Use a control ping for synchronization */
19134   MPING (CONTROL_PING, mp_ping);
19135   S (mp_ping);
19136
19137   /* Wait for a reply... */
19138   W (ret);
19139   return ret;
19140 }
19141
19142 static int
19143 api_show_one_status (vat_main_t * vam)
19144 {
19145   vl_api_show_one_status_t *mp;
19146   int ret;
19147
19148   if (!vam->json_output)
19149     {
19150       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19151     }
19152
19153   M (SHOW_ONE_STATUS, mp);
19154   /* send it... */
19155   S (mp);
19156   /* Wait for a reply... */
19157   W (ret);
19158   return ret;
19159 }
19160
19161 #define api_show_lisp_status api_show_one_status
19162
19163 static int
19164 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19165 {
19166   vl_api_gpe_fwd_entry_path_dump_t *mp;
19167   vl_api_control_ping_t *mp_ping;
19168   unformat_input_t *i = vam->input;
19169   u32 fwd_entry_index = ~0;
19170   int ret;
19171
19172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19173     {
19174       if (unformat (i, "index %d", &fwd_entry_index))
19175         ;
19176       else
19177         break;
19178     }
19179
19180   if (~0 == fwd_entry_index)
19181     {
19182       errmsg ("no index specified!");
19183       return -99;
19184     }
19185
19186   if (!vam->json_output)
19187     {
19188       print (vam->ofp, "first line");
19189     }
19190
19191   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19192
19193   /* send it... */
19194   S (mp);
19195   /* Use a control ping for synchronization */
19196   MPING (CONTROL_PING, mp_ping);
19197   S (mp_ping);
19198
19199   /* Wait for a reply... */
19200   W (ret);
19201   return ret;
19202 }
19203
19204 static int
19205 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19206 {
19207   vl_api_one_get_map_request_itr_rlocs_t *mp;
19208   int ret;
19209
19210   if (!vam->json_output)
19211     {
19212       print (vam->ofp, "%=20s", "itr-rlocs:");
19213     }
19214
19215   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19216   /* send it... */
19217   S (mp);
19218   /* Wait for a reply... */
19219   W (ret);
19220   return ret;
19221 }
19222
19223 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19224
19225 static int
19226 api_af_packet_create (vat_main_t * vam)
19227 {
19228   unformat_input_t *i = vam->input;
19229   vl_api_af_packet_create_t *mp;
19230   u8 *host_if_name = 0;
19231   u8 hw_addr[6];
19232   u8 random_hw_addr = 1;
19233   int ret;
19234
19235   memset (hw_addr, 0, sizeof (hw_addr));
19236
19237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19238     {
19239       if (unformat (i, "name %s", &host_if_name))
19240         vec_add1 (host_if_name, 0);
19241       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19242         random_hw_addr = 0;
19243       else
19244         break;
19245     }
19246
19247   if (!vec_len (host_if_name))
19248     {
19249       errmsg ("host-interface name must be specified");
19250       return -99;
19251     }
19252
19253   if (vec_len (host_if_name) > 64)
19254     {
19255       errmsg ("host-interface name too long");
19256       return -99;
19257     }
19258
19259   M (AF_PACKET_CREATE, mp);
19260
19261   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19262   clib_memcpy (mp->hw_addr, hw_addr, 6);
19263   mp->use_random_hw_addr = random_hw_addr;
19264   vec_free (host_if_name);
19265
19266   S (mp);
19267
19268   /* *INDENT-OFF* */
19269   W2 (ret,
19270       ({
19271         if (ret == 0)
19272           fprintf (vam->ofp ? vam->ofp : stderr,
19273                    " new sw_if_index = %d\n", vam->sw_if_index);
19274       }));
19275   /* *INDENT-ON* */
19276   return ret;
19277 }
19278
19279 static int
19280 api_af_packet_delete (vat_main_t * vam)
19281 {
19282   unformat_input_t *i = vam->input;
19283   vl_api_af_packet_delete_t *mp;
19284   u8 *host_if_name = 0;
19285   int ret;
19286
19287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19288     {
19289       if (unformat (i, "name %s", &host_if_name))
19290         vec_add1 (host_if_name, 0);
19291       else
19292         break;
19293     }
19294
19295   if (!vec_len (host_if_name))
19296     {
19297       errmsg ("host-interface name must be specified");
19298       return -99;
19299     }
19300
19301   if (vec_len (host_if_name) > 64)
19302     {
19303       errmsg ("host-interface name too long");
19304       return -99;
19305     }
19306
19307   M (AF_PACKET_DELETE, mp);
19308
19309   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19310   vec_free (host_if_name);
19311
19312   S (mp);
19313   W (ret);
19314   return ret;
19315 }
19316
19317 static int
19318 api_policer_add_del (vat_main_t * vam)
19319 {
19320   unformat_input_t *i = vam->input;
19321   vl_api_policer_add_del_t *mp;
19322   u8 is_add = 1;
19323   u8 *name = 0;
19324   u32 cir = 0;
19325   u32 eir = 0;
19326   u64 cb = 0;
19327   u64 eb = 0;
19328   u8 rate_type = 0;
19329   u8 round_type = 0;
19330   u8 type = 0;
19331   u8 color_aware = 0;
19332   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19333   int ret;
19334
19335   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19336   conform_action.dscp = 0;
19337   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19338   exceed_action.dscp = 0;
19339   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19340   violate_action.dscp = 0;
19341
19342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19343     {
19344       if (unformat (i, "del"))
19345         is_add = 0;
19346       else if (unformat (i, "name %s", &name))
19347         vec_add1 (name, 0);
19348       else if (unformat (i, "cir %u", &cir))
19349         ;
19350       else if (unformat (i, "eir %u", &eir))
19351         ;
19352       else if (unformat (i, "cb %u", &cb))
19353         ;
19354       else if (unformat (i, "eb %u", &eb))
19355         ;
19356       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19357                          &rate_type))
19358         ;
19359       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19360                          &round_type))
19361         ;
19362       else if (unformat (i, "type %U", unformat_policer_type, &type))
19363         ;
19364       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19365                          &conform_action))
19366         ;
19367       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19368                          &exceed_action))
19369         ;
19370       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19371                          &violate_action))
19372         ;
19373       else if (unformat (i, "color-aware"))
19374         color_aware = 1;
19375       else
19376         break;
19377     }
19378
19379   if (!vec_len (name))
19380     {
19381       errmsg ("policer name must be specified");
19382       return -99;
19383     }
19384
19385   if (vec_len (name) > 64)
19386     {
19387       errmsg ("policer name too long");
19388       return -99;
19389     }
19390
19391   M (POLICER_ADD_DEL, mp);
19392
19393   clib_memcpy (mp->name, name, vec_len (name));
19394   vec_free (name);
19395   mp->is_add = is_add;
19396   mp->cir = ntohl (cir);
19397   mp->eir = ntohl (eir);
19398   mp->cb = clib_net_to_host_u64 (cb);
19399   mp->eb = clib_net_to_host_u64 (eb);
19400   mp->rate_type = rate_type;
19401   mp->round_type = round_type;
19402   mp->type = type;
19403   mp->conform_action_type = conform_action.action_type;
19404   mp->conform_dscp = conform_action.dscp;
19405   mp->exceed_action_type = exceed_action.action_type;
19406   mp->exceed_dscp = exceed_action.dscp;
19407   mp->violate_action_type = violate_action.action_type;
19408   mp->violate_dscp = violate_action.dscp;
19409   mp->color_aware = color_aware;
19410
19411   S (mp);
19412   W (ret);
19413   return ret;
19414 }
19415
19416 static int
19417 api_policer_dump (vat_main_t * vam)
19418 {
19419   unformat_input_t *i = vam->input;
19420   vl_api_policer_dump_t *mp;
19421   vl_api_control_ping_t *mp_ping;
19422   u8 *match_name = 0;
19423   u8 match_name_valid = 0;
19424   int ret;
19425
19426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (i, "name %s", &match_name))
19429         {
19430           vec_add1 (match_name, 0);
19431           match_name_valid = 1;
19432         }
19433       else
19434         break;
19435     }
19436
19437   M (POLICER_DUMP, mp);
19438   mp->match_name_valid = match_name_valid;
19439   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19440   vec_free (match_name);
19441   /* send it... */
19442   S (mp);
19443
19444   /* Use a control ping for synchronization */
19445   MPING (CONTROL_PING, mp_ping);
19446   S (mp_ping);
19447
19448   /* Wait for a reply... */
19449   W (ret);
19450   return ret;
19451 }
19452
19453 static int
19454 api_policer_classify_set_interface (vat_main_t * vam)
19455 {
19456   unformat_input_t *i = vam->input;
19457   vl_api_policer_classify_set_interface_t *mp;
19458   u32 sw_if_index;
19459   int sw_if_index_set;
19460   u32 ip4_table_index = ~0;
19461   u32 ip6_table_index = ~0;
19462   u32 l2_table_index = ~0;
19463   u8 is_add = 1;
19464   int ret;
19465
19466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19467     {
19468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19469         sw_if_index_set = 1;
19470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19471         sw_if_index_set = 1;
19472       else if (unformat (i, "del"))
19473         is_add = 0;
19474       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19475         ;
19476       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19477         ;
19478       else if (unformat (i, "l2-table %d", &l2_table_index))
19479         ;
19480       else
19481         {
19482           clib_warning ("parse error '%U'", format_unformat_error, i);
19483           return -99;
19484         }
19485     }
19486
19487   if (sw_if_index_set == 0)
19488     {
19489       errmsg ("missing interface name or sw_if_index");
19490       return -99;
19491     }
19492
19493   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19494
19495   mp->sw_if_index = ntohl (sw_if_index);
19496   mp->ip4_table_index = ntohl (ip4_table_index);
19497   mp->ip6_table_index = ntohl (ip6_table_index);
19498   mp->l2_table_index = ntohl (l2_table_index);
19499   mp->is_add = is_add;
19500
19501   S (mp);
19502   W (ret);
19503   return ret;
19504 }
19505
19506 static int
19507 api_policer_classify_dump (vat_main_t * vam)
19508 {
19509   unformat_input_t *i = vam->input;
19510   vl_api_policer_classify_dump_t *mp;
19511   vl_api_control_ping_t *mp_ping;
19512   u8 type = POLICER_CLASSIFY_N_TABLES;
19513   int ret;
19514
19515   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19516     ;
19517   else
19518     {
19519       errmsg ("classify table type must be specified");
19520       return -99;
19521     }
19522
19523   if (!vam->json_output)
19524     {
19525       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19526     }
19527
19528   M (POLICER_CLASSIFY_DUMP, mp);
19529   mp->type = type;
19530   /* send it... */
19531   S (mp);
19532
19533   /* Use a control ping for synchronization */
19534   MPING (CONTROL_PING, mp_ping);
19535   S (mp_ping);
19536
19537   /* Wait for a reply... */
19538   W (ret);
19539   return ret;
19540 }
19541
19542 static int
19543 api_netmap_create (vat_main_t * vam)
19544 {
19545   unformat_input_t *i = vam->input;
19546   vl_api_netmap_create_t *mp;
19547   u8 *if_name = 0;
19548   u8 hw_addr[6];
19549   u8 random_hw_addr = 1;
19550   u8 is_pipe = 0;
19551   u8 is_master = 0;
19552   int ret;
19553
19554   memset (hw_addr, 0, sizeof (hw_addr));
19555
19556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19557     {
19558       if (unformat (i, "name %s", &if_name))
19559         vec_add1 (if_name, 0);
19560       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19561         random_hw_addr = 0;
19562       else if (unformat (i, "pipe"))
19563         is_pipe = 1;
19564       else if (unformat (i, "master"))
19565         is_master = 1;
19566       else if (unformat (i, "slave"))
19567         is_master = 0;
19568       else
19569         break;
19570     }
19571
19572   if (!vec_len (if_name))
19573     {
19574       errmsg ("interface name must be specified");
19575       return -99;
19576     }
19577
19578   if (vec_len (if_name) > 64)
19579     {
19580       errmsg ("interface name too long");
19581       return -99;
19582     }
19583
19584   M (NETMAP_CREATE, mp);
19585
19586   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19587   clib_memcpy (mp->hw_addr, hw_addr, 6);
19588   mp->use_random_hw_addr = random_hw_addr;
19589   mp->is_pipe = is_pipe;
19590   mp->is_master = is_master;
19591   vec_free (if_name);
19592
19593   S (mp);
19594   W (ret);
19595   return ret;
19596 }
19597
19598 static int
19599 api_netmap_delete (vat_main_t * vam)
19600 {
19601   unformat_input_t *i = vam->input;
19602   vl_api_netmap_delete_t *mp;
19603   u8 *if_name = 0;
19604   int ret;
19605
19606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19607     {
19608       if (unformat (i, "name %s", &if_name))
19609         vec_add1 (if_name, 0);
19610       else
19611         break;
19612     }
19613
19614   if (!vec_len (if_name))
19615     {
19616       errmsg ("interface name must be specified");
19617       return -99;
19618     }
19619
19620   if (vec_len (if_name) > 64)
19621     {
19622       errmsg ("interface name too long");
19623       return -99;
19624     }
19625
19626   M (NETMAP_DELETE, mp);
19627
19628   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19629   vec_free (if_name);
19630
19631   S (mp);
19632   W (ret);
19633   return ret;
19634 }
19635
19636 static void
19637 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19638 {
19639   if (fp->afi == IP46_TYPE_IP6)
19640     print (vam->ofp,
19641            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19642            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19643            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19644            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19645            format_ip6_address, fp->next_hop);
19646   else if (fp->afi == IP46_TYPE_IP4)
19647     print (vam->ofp,
19648            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19649            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19650            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19651            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19652            format_ip4_address, fp->next_hop);
19653 }
19654
19655 static void
19656 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19657                                  vl_api_fib_path_t * fp)
19658 {
19659   struct in_addr ip4;
19660   struct in6_addr ip6;
19661
19662   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19663   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19664   vat_json_object_add_uint (node, "is_local", fp->is_local);
19665   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19666   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19667   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19668   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19669   if (fp->afi == IP46_TYPE_IP4)
19670     {
19671       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19672       vat_json_object_add_ip4 (node, "next_hop", ip4);
19673     }
19674   else if (fp->afi == IP46_TYPE_IP6)
19675     {
19676       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19677       vat_json_object_add_ip6 (node, "next_hop", ip6);
19678     }
19679 }
19680
19681 static void
19682 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19683 {
19684   vat_main_t *vam = &vat_main;
19685   int count = ntohl (mp->mt_count);
19686   vl_api_fib_path_t *fp;
19687   i32 i;
19688
19689   print (vam->ofp, "[%d]: sw_if_index %d via:",
19690          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19691   fp = mp->mt_paths;
19692   for (i = 0; i < count; i++)
19693     {
19694       vl_api_mpls_fib_path_print (vam, fp);
19695       fp++;
19696     }
19697
19698   print (vam->ofp, "");
19699 }
19700
19701 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19702 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19703
19704 static void
19705 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19706 {
19707   vat_main_t *vam = &vat_main;
19708   vat_json_node_t *node = NULL;
19709   int count = ntohl (mp->mt_count);
19710   vl_api_fib_path_t *fp;
19711   i32 i;
19712
19713   if (VAT_JSON_ARRAY != vam->json_tree.type)
19714     {
19715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19716       vat_json_init_array (&vam->json_tree);
19717     }
19718   node = vat_json_array_add (&vam->json_tree);
19719
19720   vat_json_init_object (node);
19721   vat_json_object_add_uint (node, "tunnel_index",
19722                             ntohl (mp->mt_tunnel_index));
19723   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19724
19725   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19726
19727   fp = mp->mt_paths;
19728   for (i = 0; i < count; i++)
19729     {
19730       vl_api_mpls_fib_path_json_print (node, fp);
19731       fp++;
19732     }
19733 }
19734
19735 static int
19736 api_mpls_tunnel_dump (vat_main_t * vam)
19737 {
19738   vl_api_mpls_tunnel_dump_t *mp;
19739   vl_api_control_ping_t *mp_ping;
19740   i32 index = -1;
19741   int ret;
19742
19743   /* Parse args required to build the message */
19744   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19745     {
19746       if (!unformat (vam->input, "tunnel_index %d", &index))
19747         {
19748           index = -1;
19749           break;
19750         }
19751     }
19752
19753   print (vam->ofp, "  tunnel_index %d", index);
19754
19755   M (MPLS_TUNNEL_DUMP, mp);
19756   mp->tunnel_index = htonl (index);
19757   S (mp);
19758
19759   /* Use a control ping for synchronization */
19760   MPING (CONTROL_PING, mp_ping);
19761   S (mp_ping);
19762
19763   W (ret);
19764   return ret;
19765 }
19766
19767 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19768 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19769
19770
19771 static void
19772 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19773 {
19774   vat_main_t *vam = &vat_main;
19775   int count = ntohl (mp->count);
19776   vl_api_fib_path_t *fp;
19777   int i;
19778
19779   print (vam->ofp,
19780          "table-id %d, label %u, ess_bit %u",
19781          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19782   fp = mp->path;
19783   for (i = 0; i < count; i++)
19784     {
19785       vl_api_mpls_fib_path_print (vam, fp);
19786       fp++;
19787     }
19788 }
19789
19790 static void vl_api_mpls_fib_details_t_handler_json
19791   (vl_api_mpls_fib_details_t * mp)
19792 {
19793   vat_main_t *vam = &vat_main;
19794   int count = ntohl (mp->count);
19795   vat_json_node_t *node = NULL;
19796   vl_api_fib_path_t *fp;
19797   int i;
19798
19799   if (VAT_JSON_ARRAY != vam->json_tree.type)
19800     {
19801       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19802       vat_json_init_array (&vam->json_tree);
19803     }
19804   node = vat_json_array_add (&vam->json_tree);
19805
19806   vat_json_init_object (node);
19807   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19808   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19809   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19810   vat_json_object_add_uint (node, "path_count", count);
19811   fp = mp->path;
19812   for (i = 0; i < count; i++)
19813     {
19814       vl_api_mpls_fib_path_json_print (node, fp);
19815       fp++;
19816     }
19817 }
19818
19819 static int
19820 api_mpls_fib_dump (vat_main_t * vam)
19821 {
19822   vl_api_mpls_fib_dump_t *mp;
19823   vl_api_control_ping_t *mp_ping;
19824   int ret;
19825
19826   M (MPLS_FIB_DUMP, mp);
19827   S (mp);
19828
19829   /* Use a control ping for synchronization */
19830   MPING (CONTROL_PING, mp_ping);
19831   S (mp_ping);
19832
19833   W (ret);
19834   return ret;
19835 }
19836
19837 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19838 #define vl_api_ip_fib_details_t_print vl_noop_handler
19839
19840 static void
19841 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19842 {
19843   vat_main_t *vam = &vat_main;
19844   int count = ntohl (mp->count);
19845   vl_api_fib_path_t *fp;
19846   int i;
19847
19848   print (vam->ofp,
19849          "table-id %d, prefix %U/%d",
19850          ntohl (mp->table_id), format_ip4_address, mp->address,
19851          mp->address_length);
19852   fp = mp->path;
19853   for (i = 0; i < count; i++)
19854     {
19855       if (fp->afi == IP46_TYPE_IP6)
19856         print (vam->ofp,
19857                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19858                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19859                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19860                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19861                format_ip6_address, fp->next_hop);
19862       else if (fp->afi == IP46_TYPE_IP4)
19863         print (vam->ofp,
19864                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19865                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19866                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19867                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19868                format_ip4_address, fp->next_hop);
19869       fp++;
19870     }
19871 }
19872
19873 static void vl_api_ip_fib_details_t_handler_json
19874   (vl_api_ip_fib_details_t * mp)
19875 {
19876   vat_main_t *vam = &vat_main;
19877   int count = ntohl (mp->count);
19878   vat_json_node_t *node = NULL;
19879   struct in_addr ip4;
19880   struct in6_addr ip6;
19881   vl_api_fib_path_t *fp;
19882   int i;
19883
19884   if (VAT_JSON_ARRAY != vam->json_tree.type)
19885     {
19886       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19887       vat_json_init_array (&vam->json_tree);
19888     }
19889   node = vat_json_array_add (&vam->json_tree);
19890
19891   vat_json_init_object (node);
19892   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19893   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19894   vat_json_object_add_ip4 (node, "prefix", ip4);
19895   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19896   vat_json_object_add_uint (node, "path_count", count);
19897   fp = mp->path;
19898   for (i = 0; i < count; i++)
19899     {
19900       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19901       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19902       vat_json_object_add_uint (node, "is_local", fp->is_local);
19903       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19904       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19905       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19906       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19907       if (fp->afi == IP46_TYPE_IP4)
19908         {
19909           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19910           vat_json_object_add_ip4 (node, "next_hop", ip4);
19911         }
19912       else if (fp->afi == IP46_TYPE_IP6)
19913         {
19914           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19915           vat_json_object_add_ip6 (node, "next_hop", ip6);
19916         }
19917     }
19918 }
19919
19920 static int
19921 api_ip_fib_dump (vat_main_t * vam)
19922 {
19923   vl_api_ip_fib_dump_t *mp;
19924   vl_api_control_ping_t *mp_ping;
19925   int ret;
19926
19927   M (IP_FIB_DUMP, mp);
19928   S (mp);
19929
19930   /* Use a control ping for synchronization */
19931   MPING (CONTROL_PING, mp_ping);
19932   S (mp_ping);
19933
19934   W (ret);
19935   return ret;
19936 }
19937
19938 static int
19939 api_ip_mfib_dump (vat_main_t * vam)
19940 {
19941   vl_api_ip_mfib_dump_t *mp;
19942   vl_api_control_ping_t *mp_ping;
19943   int ret;
19944
19945   M (IP_MFIB_DUMP, mp);
19946   S (mp);
19947
19948   /* Use a control ping for synchronization */
19949   MPING (CONTROL_PING, mp_ping);
19950   S (mp_ping);
19951
19952   W (ret);
19953   return ret;
19954 }
19955
19956 static void vl_api_ip_neighbor_details_t_handler
19957   (vl_api_ip_neighbor_details_t * mp)
19958 {
19959   vat_main_t *vam = &vat_main;
19960
19961   print (vam->ofp, "%c %U %U",
19962          (mp->is_static) ? 'S' : 'D',
19963          format_ethernet_address, &mp->mac_address,
19964          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19965          &mp->ip_address);
19966 }
19967
19968 static void vl_api_ip_neighbor_details_t_handler_json
19969   (vl_api_ip_neighbor_details_t * mp)
19970 {
19971
19972   vat_main_t *vam = &vat_main;
19973   vat_json_node_t *node;
19974   struct in_addr ip4;
19975   struct in6_addr ip6;
19976
19977   if (VAT_JSON_ARRAY != vam->json_tree.type)
19978     {
19979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19980       vat_json_init_array (&vam->json_tree);
19981     }
19982   node = vat_json_array_add (&vam->json_tree);
19983
19984   vat_json_init_object (node);
19985   vat_json_object_add_string_copy (node, "flag",
19986                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19987                                    "dynamic");
19988
19989   vat_json_object_add_string_copy (node, "link_layer",
19990                                    format (0, "%U", format_ethernet_address,
19991                                            &mp->mac_address));
19992
19993   if (mp->is_ipv6)
19994     {
19995       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19996       vat_json_object_add_ip6 (node, "ip_address", ip6);
19997     }
19998   else
19999     {
20000       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20001       vat_json_object_add_ip4 (node, "ip_address", ip4);
20002     }
20003 }
20004
20005 static int
20006 api_ip_neighbor_dump (vat_main_t * vam)
20007 {
20008   unformat_input_t *i = vam->input;
20009   vl_api_ip_neighbor_dump_t *mp;
20010   vl_api_control_ping_t *mp_ping;
20011   u8 is_ipv6 = 0;
20012   u32 sw_if_index = ~0;
20013   int ret;
20014
20015   /* Parse args required to build the message */
20016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20017     {
20018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20019         ;
20020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20021         ;
20022       else if (unformat (i, "ip6"))
20023         is_ipv6 = 1;
20024       else
20025         break;
20026     }
20027
20028   if (sw_if_index == ~0)
20029     {
20030       errmsg ("missing interface name or sw_if_index");
20031       return -99;
20032     }
20033
20034   M (IP_NEIGHBOR_DUMP, mp);
20035   mp->is_ipv6 = (u8) is_ipv6;
20036   mp->sw_if_index = ntohl (sw_if_index);
20037   S (mp);
20038
20039   /* Use a control ping for synchronization */
20040   MPING (CONTROL_PING, mp_ping);
20041   S (mp_ping);
20042
20043   W (ret);
20044   return ret;
20045 }
20046
20047 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20048 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20049
20050 static void
20051 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20052 {
20053   vat_main_t *vam = &vat_main;
20054   int count = ntohl (mp->count);
20055   vl_api_fib_path_t *fp;
20056   int i;
20057
20058   print (vam->ofp,
20059          "table-id %d, prefix %U/%d",
20060          ntohl (mp->table_id), format_ip6_address, mp->address,
20061          mp->address_length);
20062   fp = mp->path;
20063   for (i = 0; i < count; i++)
20064     {
20065       if (fp->afi == IP46_TYPE_IP6)
20066         print (vam->ofp,
20067                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20068                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20069                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20070                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20071                format_ip6_address, fp->next_hop);
20072       else if (fp->afi == IP46_TYPE_IP4)
20073         print (vam->ofp,
20074                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20075                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20076                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20077                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20078                format_ip4_address, fp->next_hop);
20079       fp++;
20080     }
20081 }
20082
20083 static void vl_api_ip6_fib_details_t_handler_json
20084   (vl_api_ip6_fib_details_t * mp)
20085 {
20086   vat_main_t *vam = &vat_main;
20087   int count = ntohl (mp->count);
20088   vat_json_node_t *node = NULL;
20089   struct in_addr ip4;
20090   struct in6_addr ip6;
20091   vl_api_fib_path_t *fp;
20092   int i;
20093
20094   if (VAT_JSON_ARRAY != vam->json_tree.type)
20095     {
20096       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20097       vat_json_init_array (&vam->json_tree);
20098     }
20099   node = vat_json_array_add (&vam->json_tree);
20100
20101   vat_json_init_object (node);
20102   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20103   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20104   vat_json_object_add_ip6 (node, "prefix", ip6);
20105   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20106   vat_json_object_add_uint (node, "path_count", count);
20107   fp = mp->path;
20108   for (i = 0; i < count; i++)
20109     {
20110       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20111       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20112       vat_json_object_add_uint (node, "is_local", fp->is_local);
20113       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20114       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20115       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20116       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20117       if (fp->afi == IP46_TYPE_IP4)
20118         {
20119           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20120           vat_json_object_add_ip4 (node, "next_hop", ip4);
20121         }
20122       else if (fp->afi == IP46_TYPE_IP6)
20123         {
20124           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20125           vat_json_object_add_ip6 (node, "next_hop", ip6);
20126         }
20127     }
20128 }
20129
20130 static int
20131 api_ip6_fib_dump (vat_main_t * vam)
20132 {
20133   vl_api_ip6_fib_dump_t *mp;
20134   vl_api_control_ping_t *mp_ping;
20135   int ret;
20136
20137   M (IP6_FIB_DUMP, mp);
20138   S (mp);
20139
20140   /* Use a control ping for synchronization */
20141   MPING (CONTROL_PING, mp_ping);
20142   S (mp_ping);
20143
20144   W (ret);
20145   return ret;
20146 }
20147
20148 static int
20149 api_ip6_mfib_dump (vat_main_t * vam)
20150 {
20151   vl_api_ip6_mfib_dump_t *mp;
20152   vl_api_control_ping_t *mp_ping;
20153   int ret;
20154
20155   M (IP6_MFIB_DUMP, mp);
20156   S (mp);
20157
20158   /* Use a control ping for synchronization */
20159   MPING (CONTROL_PING, mp_ping);
20160   S (mp_ping);
20161
20162   W (ret);
20163   return ret;
20164 }
20165
20166 int
20167 api_classify_table_ids (vat_main_t * vam)
20168 {
20169   vl_api_classify_table_ids_t *mp;
20170   int ret;
20171
20172   /* Construct the API message */
20173   M (CLASSIFY_TABLE_IDS, mp);
20174   mp->context = 0;
20175
20176   S (mp);
20177   W (ret);
20178   return ret;
20179 }
20180
20181 int
20182 api_classify_table_by_interface (vat_main_t * vam)
20183 {
20184   unformat_input_t *input = vam->input;
20185   vl_api_classify_table_by_interface_t *mp;
20186
20187   u32 sw_if_index = ~0;
20188   int ret;
20189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20190     {
20191       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20192         ;
20193       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20194         ;
20195       else
20196         break;
20197     }
20198   if (sw_if_index == ~0)
20199     {
20200       errmsg ("missing interface name or sw_if_index");
20201       return -99;
20202     }
20203
20204   /* Construct the API message */
20205   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20206   mp->context = 0;
20207   mp->sw_if_index = ntohl (sw_if_index);
20208
20209   S (mp);
20210   W (ret);
20211   return ret;
20212 }
20213
20214 int
20215 api_classify_table_info (vat_main_t * vam)
20216 {
20217   unformat_input_t *input = vam->input;
20218   vl_api_classify_table_info_t *mp;
20219
20220   u32 table_id = ~0;
20221   int ret;
20222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20223     {
20224       if (unformat (input, "table_id %d", &table_id))
20225         ;
20226       else
20227         break;
20228     }
20229   if (table_id == ~0)
20230     {
20231       errmsg ("missing table id");
20232       return -99;
20233     }
20234
20235   /* Construct the API message */
20236   M (CLASSIFY_TABLE_INFO, mp);
20237   mp->context = 0;
20238   mp->table_id = ntohl (table_id);
20239
20240   S (mp);
20241   W (ret);
20242   return ret;
20243 }
20244
20245 int
20246 api_classify_session_dump (vat_main_t * vam)
20247 {
20248   unformat_input_t *input = vam->input;
20249   vl_api_classify_session_dump_t *mp;
20250   vl_api_control_ping_t *mp_ping;
20251
20252   u32 table_id = ~0;
20253   int ret;
20254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20255     {
20256       if (unformat (input, "table_id %d", &table_id))
20257         ;
20258       else
20259         break;
20260     }
20261   if (table_id == ~0)
20262     {
20263       errmsg ("missing table id");
20264       return -99;
20265     }
20266
20267   /* Construct the API message */
20268   M (CLASSIFY_SESSION_DUMP, mp);
20269   mp->context = 0;
20270   mp->table_id = ntohl (table_id);
20271   S (mp);
20272
20273   /* Use a control ping for synchronization */
20274   MPING (CONTROL_PING, mp_ping);
20275   S (mp_ping);
20276
20277   W (ret);
20278   return ret;
20279 }
20280
20281 static void
20282 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20283 {
20284   vat_main_t *vam = &vat_main;
20285
20286   print (vam->ofp, "collector_address %U, collector_port %d, "
20287          "src_address %U, vrf_id %d, path_mtu %u, "
20288          "template_interval %u, udp_checksum %d",
20289          format_ip4_address, mp->collector_address,
20290          ntohs (mp->collector_port),
20291          format_ip4_address, mp->src_address,
20292          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20293          ntohl (mp->template_interval), mp->udp_checksum);
20294
20295   vam->retval = 0;
20296   vam->result_ready = 1;
20297 }
20298
20299 static void
20300   vl_api_ipfix_exporter_details_t_handler_json
20301   (vl_api_ipfix_exporter_details_t * mp)
20302 {
20303   vat_main_t *vam = &vat_main;
20304   vat_json_node_t node;
20305   struct in_addr collector_address;
20306   struct in_addr src_address;
20307
20308   vat_json_init_object (&node);
20309   clib_memcpy (&collector_address, &mp->collector_address,
20310                sizeof (collector_address));
20311   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20312   vat_json_object_add_uint (&node, "collector_port",
20313                             ntohs (mp->collector_port));
20314   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20315   vat_json_object_add_ip4 (&node, "src_address", src_address);
20316   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20317   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20318   vat_json_object_add_uint (&node, "template_interval",
20319                             ntohl (mp->template_interval));
20320   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20321
20322   vat_json_print (vam->ofp, &node);
20323   vat_json_free (&node);
20324   vam->retval = 0;
20325   vam->result_ready = 1;
20326 }
20327
20328 int
20329 api_ipfix_exporter_dump (vat_main_t * vam)
20330 {
20331   vl_api_ipfix_exporter_dump_t *mp;
20332   int ret;
20333
20334   /* Construct the API message */
20335   M (IPFIX_EXPORTER_DUMP, mp);
20336   mp->context = 0;
20337
20338   S (mp);
20339   W (ret);
20340   return ret;
20341 }
20342
20343 static int
20344 api_ipfix_classify_stream_dump (vat_main_t * vam)
20345 {
20346   vl_api_ipfix_classify_stream_dump_t *mp;
20347   int ret;
20348
20349   /* Construct the API message */
20350   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20351   mp->context = 0;
20352
20353   S (mp);
20354   W (ret);
20355   return ret;
20356   /* NOTREACHED */
20357   return 0;
20358 }
20359
20360 static void
20361   vl_api_ipfix_classify_stream_details_t_handler
20362   (vl_api_ipfix_classify_stream_details_t * mp)
20363 {
20364   vat_main_t *vam = &vat_main;
20365   print (vam->ofp, "domain_id %d, src_port %d",
20366          ntohl (mp->domain_id), ntohs (mp->src_port));
20367   vam->retval = 0;
20368   vam->result_ready = 1;
20369 }
20370
20371 static void
20372   vl_api_ipfix_classify_stream_details_t_handler_json
20373   (vl_api_ipfix_classify_stream_details_t * mp)
20374 {
20375   vat_main_t *vam = &vat_main;
20376   vat_json_node_t node;
20377
20378   vat_json_init_object (&node);
20379   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20380   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20381
20382   vat_json_print (vam->ofp, &node);
20383   vat_json_free (&node);
20384   vam->retval = 0;
20385   vam->result_ready = 1;
20386 }
20387
20388 static int
20389 api_ipfix_classify_table_dump (vat_main_t * vam)
20390 {
20391   vl_api_ipfix_classify_table_dump_t *mp;
20392   vl_api_control_ping_t *mp_ping;
20393   int ret;
20394
20395   if (!vam->json_output)
20396     {
20397       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20398              "transport_protocol");
20399     }
20400
20401   /* Construct the API message */
20402   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20403
20404   /* send it... */
20405   S (mp);
20406
20407   /* Use a control ping for synchronization */
20408   MPING (CONTROL_PING, mp_ping);
20409   S (mp_ping);
20410
20411   W (ret);
20412   return ret;
20413 }
20414
20415 static void
20416   vl_api_ipfix_classify_table_details_t_handler
20417   (vl_api_ipfix_classify_table_details_t * mp)
20418 {
20419   vat_main_t *vam = &vat_main;
20420   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20421          mp->transport_protocol);
20422 }
20423
20424 static void
20425   vl_api_ipfix_classify_table_details_t_handler_json
20426   (vl_api_ipfix_classify_table_details_t * mp)
20427 {
20428   vat_json_node_t *node = NULL;
20429   vat_main_t *vam = &vat_main;
20430
20431   if (VAT_JSON_ARRAY != vam->json_tree.type)
20432     {
20433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20434       vat_json_init_array (&vam->json_tree);
20435     }
20436
20437   node = vat_json_array_add (&vam->json_tree);
20438   vat_json_init_object (node);
20439
20440   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20441   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20442   vat_json_object_add_uint (node, "transport_protocol",
20443                             mp->transport_protocol);
20444 }
20445
20446 static int
20447 api_sw_interface_span_enable_disable (vat_main_t * vam)
20448 {
20449   unformat_input_t *i = vam->input;
20450   vl_api_sw_interface_span_enable_disable_t *mp;
20451   u32 src_sw_if_index = ~0;
20452   u32 dst_sw_if_index = ~0;
20453   u8 state = 3;
20454   int ret;
20455   u8 is_l2 = 0;
20456
20457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20458     {
20459       if (unformat
20460           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20461         ;
20462       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20463         ;
20464       else
20465         if (unformat
20466             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20467         ;
20468       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20469         ;
20470       else if (unformat (i, "disable"))
20471         state = 0;
20472       else if (unformat (i, "rx"))
20473         state = 1;
20474       else if (unformat (i, "tx"))
20475         state = 2;
20476       else if (unformat (i, "both"))
20477         state = 3;
20478       else if (unformat (i, "l2"))
20479         is_l2 = 1;
20480       else
20481         break;
20482     }
20483
20484   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20485
20486   mp->sw_if_index_from = htonl (src_sw_if_index);
20487   mp->sw_if_index_to = htonl (dst_sw_if_index);
20488   mp->state = state;
20489   mp->is_l2 = is_l2;
20490
20491   S (mp);
20492   W (ret);
20493   return ret;
20494 }
20495
20496 static void
20497 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20498                                             * mp)
20499 {
20500   vat_main_t *vam = &vat_main;
20501   u8 *sw_if_from_name = 0;
20502   u8 *sw_if_to_name = 0;
20503   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20504   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20505   char *states[] = { "none", "rx", "tx", "both" };
20506   hash_pair_t *p;
20507
20508   /* *INDENT-OFF* */
20509   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20510   ({
20511     if ((u32) p->value[0] == sw_if_index_from)
20512       {
20513         sw_if_from_name = (u8 *)(p->key);
20514         if (sw_if_to_name)
20515           break;
20516       }
20517     if ((u32) p->value[0] == sw_if_index_to)
20518       {
20519         sw_if_to_name = (u8 *)(p->key);
20520         if (sw_if_from_name)
20521           break;
20522       }
20523   }));
20524   /* *INDENT-ON* */
20525   print (vam->ofp, "%20s => %20s (%s) %s",
20526          sw_if_from_name, sw_if_to_name, states[mp->state],
20527          mp->is_l2 ? "l2" : "device");
20528 }
20529
20530 static void
20531   vl_api_sw_interface_span_details_t_handler_json
20532   (vl_api_sw_interface_span_details_t * mp)
20533 {
20534   vat_main_t *vam = &vat_main;
20535   vat_json_node_t *node = NULL;
20536   u8 *sw_if_from_name = 0;
20537   u8 *sw_if_to_name = 0;
20538   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20539   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20540   hash_pair_t *p;
20541
20542   /* *INDENT-OFF* */
20543   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20544   ({
20545     if ((u32) p->value[0] == sw_if_index_from)
20546       {
20547         sw_if_from_name = (u8 *)(p->key);
20548         if (sw_if_to_name)
20549           break;
20550       }
20551     if ((u32) p->value[0] == sw_if_index_to)
20552       {
20553         sw_if_to_name = (u8 *)(p->key);
20554         if (sw_if_from_name)
20555           break;
20556       }
20557   }));
20558   /* *INDENT-ON* */
20559
20560   if (VAT_JSON_ARRAY != vam->json_tree.type)
20561     {
20562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20563       vat_json_init_array (&vam->json_tree);
20564     }
20565   node = vat_json_array_add (&vam->json_tree);
20566
20567   vat_json_init_object (node);
20568   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20569   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20570   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20571   if (0 != sw_if_to_name)
20572     {
20573       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20574     }
20575   vat_json_object_add_uint (node, "state", mp->state);
20576   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20577 }
20578
20579 static int
20580 api_sw_interface_span_dump (vat_main_t * vam)
20581 {
20582   unformat_input_t *input = vam->input;
20583   vl_api_sw_interface_span_dump_t *mp;
20584   vl_api_control_ping_t *mp_ping;
20585   u8 is_l2 = 0;
20586   int ret;
20587
20588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20589     {
20590       if (unformat (input, "l2"))
20591         is_l2 = 1;
20592       else
20593         break;
20594     }
20595
20596   M (SW_INTERFACE_SPAN_DUMP, mp);
20597   mp->is_l2 = is_l2;
20598   S (mp);
20599
20600   /* Use a control ping for synchronization */
20601   MPING (CONTROL_PING, mp_ping);
20602   S (mp_ping);
20603
20604   W (ret);
20605   return ret;
20606 }
20607
20608 int
20609 api_pg_create_interface (vat_main_t * vam)
20610 {
20611   unformat_input_t *input = vam->input;
20612   vl_api_pg_create_interface_t *mp;
20613
20614   u32 if_id = ~0;
20615   int ret;
20616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20617     {
20618       if (unformat (input, "if_id %d", &if_id))
20619         ;
20620       else
20621         break;
20622     }
20623   if (if_id == ~0)
20624     {
20625       errmsg ("missing pg interface index");
20626       return -99;
20627     }
20628
20629   /* Construct the API message */
20630   M (PG_CREATE_INTERFACE, mp);
20631   mp->context = 0;
20632   mp->interface_id = ntohl (if_id);
20633
20634   S (mp);
20635   W (ret);
20636   return ret;
20637 }
20638
20639 int
20640 api_pg_capture (vat_main_t * vam)
20641 {
20642   unformat_input_t *input = vam->input;
20643   vl_api_pg_capture_t *mp;
20644
20645   u32 if_id = ~0;
20646   u8 enable = 1;
20647   u32 count = 1;
20648   u8 pcap_file_set = 0;
20649   u8 *pcap_file = 0;
20650   int ret;
20651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20652     {
20653       if (unformat (input, "if_id %d", &if_id))
20654         ;
20655       else if (unformat (input, "pcap %s", &pcap_file))
20656         pcap_file_set = 1;
20657       else if (unformat (input, "count %d", &count))
20658         ;
20659       else if (unformat (input, "disable"))
20660         enable = 0;
20661       else
20662         break;
20663     }
20664   if (if_id == ~0)
20665     {
20666       errmsg ("missing pg interface index");
20667       return -99;
20668     }
20669   if (pcap_file_set > 0)
20670     {
20671       if (vec_len (pcap_file) > 255)
20672         {
20673           errmsg ("pcap file name is too long");
20674           return -99;
20675         }
20676     }
20677
20678   u32 name_len = vec_len (pcap_file);
20679   /* Construct the API message */
20680   M (PG_CAPTURE, mp);
20681   mp->context = 0;
20682   mp->interface_id = ntohl (if_id);
20683   mp->is_enabled = enable;
20684   mp->count = ntohl (count);
20685   mp->pcap_name_length = ntohl (name_len);
20686   if (pcap_file_set != 0)
20687     {
20688       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20689     }
20690   vec_free (pcap_file);
20691
20692   S (mp);
20693   W (ret);
20694   return ret;
20695 }
20696
20697 int
20698 api_pg_enable_disable (vat_main_t * vam)
20699 {
20700   unformat_input_t *input = vam->input;
20701   vl_api_pg_enable_disable_t *mp;
20702
20703   u8 enable = 1;
20704   u8 stream_name_set = 0;
20705   u8 *stream_name = 0;
20706   int ret;
20707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20708     {
20709       if (unformat (input, "stream %s", &stream_name))
20710         stream_name_set = 1;
20711       else if (unformat (input, "disable"))
20712         enable = 0;
20713       else
20714         break;
20715     }
20716
20717   if (stream_name_set > 0)
20718     {
20719       if (vec_len (stream_name) > 255)
20720         {
20721           errmsg ("stream name too long");
20722           return -99;
20723         }
20724     }
20725
20726   u32 name_len = vec_len (stream_name);
20727   /* Construct the API message */
20728   M (PG_ENABLE_DISABLE, mp);
20729   mp->context = 0;
20730   mp->is_enabled = enable;
20731   if (stream_name_set != 0)
20732     {
20733       mp->stream_name_length = ntohl (name_len);
20734       clib_memcpy (mp->stream_name, stream_name, name_len);
20735     }
20736   vec_free (stream_name);
20737
20738   S (mp);
20739   W (ret);
20740   return ret;
20741 }
20742
20743 int
20744 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20745 {
20746   unformat_input_t *input = vam->input;
20747   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20748
20749   u16 *low_ports = 0;
20750   u16 *high_ports = 0;
20751   u16 this_low;
20752   u16 this_hi;
20753   ip4_address_t ip4_addr;
20754   ip6_address_t ip6_addr;
20755   u32 length;
20756   u32 tmp, tmp2;
20757   u8 prefix_set = 0;
20758   u32 vrf_id = ~0;
20759   u8 is_add = 1;
20760   u8 is_ipv6 = 0;
20761   int ret;
20762
20763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20764     {
20765       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20766         {
20767           prefix_set = 1;
20768         }
20769       else
20770         if (unformat
20771             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20772         {
20773           prefix_set = 1;
20774           is_ipv6 = 1;
20775         }
20776       else if (unformat (input, "vrf %d", &vrf_id))
20777         ;
20778       else if (unformat (input, "del"))
20779         is_add = 0;
20780       else if (unformat (input, "port %d", &tmp))
20781         {
20782           if (tmp == 0 || tmp > 65535)
20783             {
20784               errmsg ("port %d out of range", tmp);
20785               return -99;
20786             }
20787           this_low = tmp;
20788           this_hi = this_low + 1;
20789           vec_add1 (low_ports, this_low);
20790           vec_add1 (high_ports, this_hi);
20791         }
20792       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20793         {
20794           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20795             {
20796               errmsg ("incorrect range parameters");
20797               return -99;
20798             }
20799           this_low = tmp;
20800           /* Note: in debug CLI +1 is added to high before
20801              passing to real fn that does "the work"
20802              (ip_source_and_port_range_check_add_del).
20803              This fn is a wrapper around the binary API fn a
20804              control plane will call, which expects this increment
20805              to have occurred. Hence letting the binary API control
20806              plane fn do the increment for consistency between VAT
20807              and other control planes.
20808            */
20809           this_hi = tmp2;
20810           vec_add1 (low_ports, this_low);
20811           vec_add1 (high_ports, this_hi);
20812         }
20813       else
20814         break;
20815     }
20816
20817   if (prefix_set == 0)
20818     {
20819       errmsg ("<address>/<mask> not specified");
20820       return -99;
20821     }
20822
20823   if (vrf_id == ~0)
20824     {
20825       errmsg ("VRF ID required, not specified");
20826       return -99;
20827     }
20828
20829   if (vrf_id == 0)
20830     {
20831       errmsg
20832         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20833       return -99;
20834     }
20835
20836   if (vec_len (low_ports) == 0)
20837     {
20838       errmsg ("At least one port or port range required");
20839       return -99;
20840     }
20841
20842   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20843
20844   mp->is_add = is_add;
20845
20846   if (is_ipv6)
20847     {
20848       mp->is_ipv6 = 1;
20849       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20850     }
20851   else
20852     {
20853       mp->is_ipv6 = 0;
20854       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20855     }
20856
20857   mp->mask_length = length;
20858   mp->number_of_ranges = vec_len (low_ports);
20859
20860   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20861   vec_free (low_ports);
20862
20863   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20864   vec_free (high_ports);
20865
20866   mp->vrf_id = ntohl (vrf_id);
20867
20868   S (mp);
20869   W (ret);
20870   return ret;
20871 }
20872
20873 int
20874 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20875 {
20876   unformat_input_t *input = vam->input;
20877   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20878   u32 sw_if_index = ~0;
20879   int vrf_set = 0;
20880   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20881   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20882   u8 is_add = 1;
20883   int ret;
20884
20885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20886     {
20887       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20888         ;
20889       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20890         ;
20891       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20892         vrf_set = 1;
20893       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20894         vrf_set = 1;
20895       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20896         vrf_set = 1;
20897       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20898         vrf_set = 1;
20899       else if (unformat (input, "del"))
20900         is_add = 0;
20901       else
20902         break;
20903     }
20904
20905   if (sw_if_index == ~0)
20906     {
20907       errmsg ("Interface required but not specified");
20908       return -99;
20909     }
20910
20911   if (vrf_set == 0)
20912     {
20913       errmsg ("VRF ID required but not specified");
20914       return -99;
20915     }
20916
20917   if (tcp_out_vrf_id == 0
20918       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20919     {
20920       errmsg
20921         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20922       return -99;
20923     }
20924
20925   /* Construct the API message */
20926   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20927
20928   mp->sw_if_index = ntohl (sw_if_index);
20929   mp->is_add = is_add;
20930   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20931   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20932   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20933   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20934
20935   /* send it... */
20936   S (mp);
20937
20938   /* Wait for a reply... */
20939   W (ret);
20940   return ret;
20941 }
20942
20943 static int
20944 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20945 {
20946   unformat_input_t *i = vam->input;
20947   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20948   u32 local_sa_id = 0;
20949   u32 remote_sa_id = 0;
20950   ip4_address_t src_address;
20951   ip4_address_t dst_address;
20952   u8 is_add = 1;
20953   int ret;
20954
20955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20956     {
20957       if (unformat (i, "local_sa %d", &local_sa_id))
20958         ;
20959       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20960         ;
20961       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20962         ;
20963       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20964         ;
20965       else if (unformat (i, "del"))
20966         is_add = 0;
20967       else
20968         {
20969           clib_warning ("parse error '%U'", format_unformat_error, i);
20970           return -99;
20971         }
20972     }
20973
20974   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20975
20976   mp->local_sa_id = ntohl (local_sa_id);
20977   mp->remote_sa_id = ntohl (remote_sa_id);
20978   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20979   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20980   mp->is_add = is_add;
20981
20982   S (mp);
20983   W (ret);
20984   return ret;
20985 }
20986
20987 static int
20988 api_punt (vat_main_t * vam)
20989 {
20990   unformat_input_t *i = vam->input;
20991   vl_api_punt_t *mp;
20992   u32 ipv = ~0;
20993   u32 protocol = ~0;
20994   u32 port = ~0;
20995   int is_add = 1;
20996   int ret;
20997
20998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20999     {
21000       if (unformat (i, "ip %d", &ipv))
21001         ;
21002       else if (unformat (i, "protocol %d", &protocol))
21003         ;
21004       else if (unformat (i, "port %d", &port))
21005         ;
21006       else if (unformat (i, "del"))
21007         is_add = 0;
21008       else
21009         {
21010           clib_warning ("parse error '%U'", format_unformat_error, i);
21011           return -99;
21012         }
21013     }
21014
21015   M (PUNT, mp);
21016
21017   mp->is_add = (u8) is_add;
21018   mp->ipv = (u8) ipv;
21019   mp->l4_protocol = (u8) protocol;
21020   mp->l4_port = htons ((u16) port);
21021
21022   S (mp);
21023   W (ret);
21024   return ret;
21025 }
21026
21027 static void vl_api_ipsec_gre_tunnel_details_t_handler
21028   (vl_api_ipsec_gre_tunnel_details_t * mp)
21029 {
21030   vat_main_t *vam = &vat_main;
21031
21032   print (vam->ofp, "%11d%15U%15U%14d%14d",
21033          ntohl (mp->sw_if_index),
21034          format_ip4_address, &mp->src_address,
21035          format_ip4_address, &mp->dst_address,
21036          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21037 }
21038
21039 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21040   (vl_api_ipsec_gre_tunnel_details_t * mp)
21041 {
21042   vat_main_t *vam = &vat_main;
21043   vat_json_node_t *node = NULL;
21044   struct in_addr ip4;
21045
21046   if (VAT_JSON_ARRAY != vam->json_tree.type)
21047     {
21048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21049       vat_json_init_array (&vam->json_tree);
21050     }
21051   node = vat_json_array_add (&vam->json_tree);
21052
21053   vat_json_init_object (node);
21054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21055   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21056   vat_json_object_add_ip4 (node, "src_address", ip4);
21057   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21058   vat_json_object_add_ip4 (node, "dst_address", ip4);
21059   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21060   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21061 }
21062
21063 static int
21064 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21065 {
21066   unformat_input_t *i = vam->input;
21067   vl_api_ipsec_gre_tunnel_dump_t *mp;
21068   vl_api_control_ping_t *mp_ping;
21069   u32 sw_if_index;
21070   u8 sw_if_index_set = 0;
21071   int ret;
21072
21073   /* Parse args required to build the message */
21074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21075     {
21076       if (unformat (i, "sw_if_index %d", &sw_if_index))
21077         sw_if_index_set = 1;
21078       else
21079         break;
21080     }
21081
21082   if (sw_if_index_set == 0)
21083     {
21084       sw_if_index = ~0;
21085     }
21086
21087   if (!vam->json_output)
21088     {
21089       print (vam->ofp, "%11s%15s%15s%14s%14s",
21090              "sw_if_index", "src_address", "dst_address",
21091              "local_sa_id", "remote_sa_id");
21092     }
21093
21094   /* Get list of gre-tunnel interfaces */
21095   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21096
21097   mp->sw_if_index = htonl (sw_if_index);
21098
21099   S (mp);
21100
21101   /* Use a control ping for synchronization */
21102   MPING (CONTROL_PING, mp_ping);
21103   S (mp_ping);
21104
21105   W (ret);
21106   return ret;
21107 }
21108
21109 static int
21110 api_delete_subif (vat_main_t * vam)
21111 {
21112   unformat_input_t *i = vam->input;
21113   vl_api_delete_subif_t *mp;
21114   u32 sw_if_index = ~0;
21115   int ret;
21116
21117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21118     {
21119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21120         ;
21121       if (unformat (i, "sw_if_index %d", &sw_if_index))
21122         ;
21123       else
21124         break;
21125     }
21126
21127   if (sw_if_index == ~0)
21128     {
21129       errmsg ("missing sw_if_index");
21130       return -99;
21131     }
21132
21133   /* Construct the API message */
21134   M (DELETE_SUBIF, mp);
21135   mp->sw_if_index = ntohl (sw_if_index);
21136
21137   S (mp);
21138   W (ret);
21139   return ret;
21140 }
21141
21142 #define foreach_pbb_vtr_op      \
21143 _("disable",  L2_VTR_DISABLED)  \
21144 _("pop",  L2_VTR_POP_2)         \
21145 _("push",  L2_VTR_PUSH_2)
21146
21147 static int
21148 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21149 {
21150   unformat_input_t *i = vam->input;
21151   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21152   u32 sw_if_index = ~0, vtr_op = ~0;
21153   u16 outer_tag = ~0;
21154   u8 dmac[6], smac[6];
21155   u8 dmac_set = 0, smac_set = 0;
21156   u16 vlanid = 0;
21157   u32 sid = ~0;
21158   u32 tmp;
21159   int ret;
21160
21161   /* Shut up coverity */
21162   memset (dmac, 0, sizeof (dmac));
21163   memset (smac, 0, sizeof (smac));
21164
21165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21166     {
21167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21168         ;
21169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21170         ;
21171       else if (unformat (i, "vtr_op %d", &vtr_op))
21172         ;
21173 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21174       foreach_pbb_vtr_op
21175 #undef _
21176         else if (unformat (i, "translate_pbb_stag"))
21177         {
21178           if (unformat (i, "%d", &tmp))
21179             {
21180               vtr_op = L2_VTR_TRANSLATE_2_1;
21181               outer_tag = tmp;
21182             }
21183           else
21184             {
21185               errmsg
21186                 ("translate_pbb_stag operation requires outer tag definition");
21187               return -99;
21188             }
21189         }
21190       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21191         dmac_set++;
21192       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21193         smac_set++;
21194       else if (unformat (i, "sid %d", &sid))
21195         ;
21196       else if (unformat (i, "vlanid %d", &tmp))
21197         vlanid = tmp;
21198       else
21199         {
21200           clib_warning ("parse error '%U'", format_unformat_error, i);
21201           return -99;
21202         }
21203     }
21204
21205   if ((sw_if_index == ~0) || (vtr_op == ~0))
21206     {
21207       errmsg ("missing sw_if_index or vtr operation");
21208       return -99;
21209     }
21210   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21211       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21212     {
21213       errmsg
21214         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21215       return -99;
21216     }
21217
21218   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21219   mp->sw_if_index = ntohl (sw_if_index);
21220   mp->vtr_op = ntohl (vtr_op);
21221   mp->outer_tag = ntohs (outer_tag);
21222   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21223   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21224   mp->b_vlanid = ntohs (vlanid);
21225   mp->i_sid = ntohl (sid);
21226
21227   S (mp);
21228   W (ret);
21229   return ret;
21230 }
21231
21232 static int
21233 api_flow_classify_set_interface (vat_main_t * vam)
21234 {
21235   unformat_input_t *i = vam->input;
21236   vl_api_flow_classify_set_interface_t *mp;
21237   u32 sw_if_index;
21238   int sw_if_index_set;
21239   u32 ip4_table_index = ~0;
21240   u32 ip6_table_index = ~0;
21241   u8 is_add = 1;
21242   int ret;
21243
21244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21245     {
21246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21247         sw_if_index_set = 1;
21248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21249         sw_if_index_set = 1;
21250       else if (unformat (i, "del"))
21251         is_add = 0;
21252       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21253         ;
21254       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21255         ;
21256       else
21257         {
21258           clib_warning ("parse error '%U'", format_unformat_error, i);
21259           return -99;
21260         }
21261     }
21262
21263   if (sw_if_index_set == 0)
21264     {
21265       errmsg ("missing interface name or sw_if_index");
21266       return -99;
21267     }
21268
21269   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21270
21271   mp->sw_if_index = ntohl (sw_if_index);
21272   mp->ip4_table_index = ntohl (ip4_table_index);
21273   mp->ip6_table_index = ntohl (ip6_table_index);
21274   mp->is_add = is_add;
21275
21276   S (mp);
21277   W (ret);
21278   return ret;
21279 }
21280
21281 static int
21282 api_flow_classify_dump (vat_main_t * vam)
21283 {
21284   unformat_input_t *i = vam->input;
21285   vl_api_flow_classify_dump_t *mp;
21286   vl_api_control_ping_t *mp_ping;
21287   u8 type = FLOW_CLASSIFY_N_TABLES;
21288   int ret;
21289
21290   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21291     ;
21292   else
21293     {
21294       errmsg ("classify table type must be specified");
21295       return -99;
21296     }
21297
21298   if (!vam->json_output)
21299     {
21300       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21301     }
21302
21303   M (FLOW_CLASSIFY_DUMP, mp);
21304   mp->type = type;
21305   /* send it... */
21306   S (mp);
21307
21308   /* Use a control ping for synchronization */
21309   MPING (CONTROL_PING, mp_ping);
21310   S (mp_ping);
21311
21312   /* Wait for a reply... */
21313   W (ret);
21314   return ret;
21315 }
21316
21317 static int
21318 api_feature_enable_disable (vat_main_t * vam)
21319 {
21320   unformat_input_t *i = vam->input;
21321   vl_api_feature_enable_disable_t *mp;
21322   u8 *arc_name = 0;
21323   u8 *feature_name = 0;
21324   u32 sw_if_index = ~0;
21325   u8 enable = 1;
21326   int ret;
21327
21328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21329     {
21330       if (unformat (i, "arc_name %s", &arc_name))
21331         ;
21332       else if (unformat (i, "feature_name %s", &feature_name))
21333         ;
21334       else
21335         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21336         ;
21337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21338         ;
21339       else if (unformat (i, "disable"))
21340         enable = 0;
21341       else
21342         break;
21343     }
21344
21345   if (arc_name == 0)
21346     {
21347       errmsg ("missing arc name");
21348       return -99;
21349     }
21350   if (vec_len (arc_name) > 63)
21351     {
21352       errmsg ("arc name too long");
21353     }
21354
21355   if (feature_name == 0)
21356     {
21357       errmsg ("missing feature name");
21358       return -99;
21359     }
21360   if (vec_len (feature_name) > 63)
21361     {
21362       errmsg ("feature name too long");
21363     }
21364
21365   if (sw_if_index == ~0)
21366     {
21367       errmsg ("missing interface name or sw_if_index");
21368       return -99;
21369     }
21370
21371   /* Construct the API message */
21372   M (FEATURE_ENABLE_DISABLE, mp);
21373   mp->sw_if_index = ntohl (sw_if_index);
21374   mp->enable = enable;
21375   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21376   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21377   vec_free (arc_name);
21378   vec_free (feature_name);
21379
21380   S (mp);
21381   W (ret);
21382   return ret;
21383 }
21384
21385 static int
21386 api_sw_interface_tag_add_del (vat_main_t * vam)
21387 {
21388   unformat_input_t *i = vam->input;
21389   vl_api_sw_interface_tag_add_del_t *mp;
21390   u32 sw_if_index = ~0;
21391   u8 *tag = 0;
21392   u8 enable = 1;
21393   int ret;
21394
21395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21396     {
21397       if (unformat (i, "tag %s", &tag))
21398         ;
21399       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21400         ;
21401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21402         ;
21403       else if (unformat (i, "del"))
21404         enable = 0;
21405       else
21406         break;
21407     }
21408
21409   if (sw_if_index == ~0)
21410     {
21411       errmsg ("missing interface name or sw_if_index");
21412       return -99;
21413     }
21414
21415   if (enable && (tag == 0))
21416     {
21417       errmsg ("no tag specified");
21418       return -99;
21419     }
21420
21421   /* Construct the API message */
21422   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21423   mp->sw_if_index = ntohl (sw_if_index);
21424   mp->is_add = enable;
21425   if (enable)
21426     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21427   vec_free (tag);
21428
21429   S (mp);
21430   W (ret);
21431   return ret;
21432 }
21433
21434 static void vl_api_l2_xconnect_details_t_handler
21435   (vl_api_l2_xconnect_details_t * mp)
21436 {
21437   vat_main_t *vam = &vat_main;
21438
21439   print (vam->ofp, "%15d%15d",
21440          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21441 }
21442
21443 static void vl_api_l2_xconnect_details_t_handler_json
21444   (vl_api_l2_xconnect_details_t * mp)
21445 {
21446   vat_main_t *vam = &vat_main;
21447   vat_json_node_t *node = NULL;
21448
21449   if (VAT_JSON_ARRAY != vam->json_tree.type)
21450     {
21451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21452       vat_json_init_array (&vam->json_tree);
21453     }
21454   node = vat_json_array_add (&vam->json_tree);
21455
21456   vat_json_init_object (node);
21457   vat_json_object_add_uint (node, "rx_sw_if_index",
21458                             ntohl (mp->rx_sw_if_index));
21459   vat_json_object_add_uint (node, "tx_sw_if_index",
21460                             ntohl (mp->tx_sw_if_index));
21461 }
21462
21463 static int
21464 api_l2_xconnect_dump (vat_main_t * vam)
21465 {
21466   vl_api_l2_xconnect_dump_t *mp;
21467   vl_api_control_ping_t *mp_ping;
21468   int ret;
21469
21470   if (!vam->json_output)
21471     {
21472       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21473     }
21474
21475   M (L2_XCONNECT_DUMP, mp);
21476
21477   S (mp);
21478
21479   /* Use a control ping for synchronization */
21480   MPING (CONTROL_PING, mp_ping);
21481   S (mp_ping);
21482
21483   W (ret);
21484   return ret;
21485 }
21486
21487 static int
21488 api_sw_interface_set_mtu (vat_main_t * vam)
21489 {
21490   unformat_input_t *i = vam->input;
21491   vl_api_sw_interface_set_mtu_t *mp;
21492   u32 sw_if_index = ~0;
21493   u32 mtu = 0;
21494   int ret;
21495
21496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21497     {
21498       if (unformat (i, "mtu %d", &mtu))
21499         ;
21500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21501         ;
21502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21503         ;
21504       else
21505         break;
21506     }
21507
21508   if (sw_if_index == ~0)
21509     {
21510       errmsg ("missing interface name or sw_if_index");
21511       return -99;
21512     }
21513
21514   if (mtu == 0)
21515     {
21516       errmsg ("no mtu specified");
21517       return -99;
21518     }
21519
21520   /* Construct the API message */
21521   M (SW_INTERFACE_SET_MTU, mp);
21522   mp->sw_if_index = ntohl (sw_if_index);
21523   mp->mtu = ntohs ((u16) mtu);
21524
21525   S (mp);
21526   W (ret);
21527   return ret;
21528 }
21529
21530 static int
21531 api_p2p_ethernet_add (vat_main_t * vam)
21532 {
21533   unformat_input_t *i = vam->input;
21534   vl_api_p2p_ethernet_add_t *mp;
21535   u32 parent_if_index = ~0;
21536   u32 sub_id = ~0;
21537   u8 remote_mac[6];
21538   u8 mac_set = 0;
21539   int ret;
21540
21541   memset (remote_mac, 0, sizeof (remote_mac));
21542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21543     {
21544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21545         ;
21546       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21547         ;
21548       else
21549         if (unformat
21550             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21551         mac_set++;
21552       else if (unformat (i, "sub_id %d", &sub_id))
21553         ;
21554       else
21555         {
21556           clib_warning ("parse error '%U'", format_unformat_error, i);
21557           return -99;
21558         }
21559     }
21560
21561   if (parent_if_index == ~0)
21562     {
21563       errmsg ("missing interface name or sw_if_index");
21564       return -99;
21565     }
21566   if (mac_set == 0)
21567     {
21568       errmsg ("missing remote mac address");
21569       return -99;
21570     }
21571   if (sub_id == ~0)
21572     {
21573       errmsg ("missing sub-interface id");
21574       return -99;
21575     }
21576
21577   M (P2P_ETHERNET_ADD, mp);
21578   mp->parent_if_index = ntohl (parent_if_index);
21579   mp->subif_id = ntohl (sub_id);
21580   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21581
21582   S (mp);
21583   W (ret);
21584   return ret;
21585 }
21586
21587 static int
21588 api_p2p_ethernet_del (vat_main_t * vam)
21589 {
21590   unformat_input_t *i = vam->input;
21591   vl_api_p2p_ethernet_del_t *mp;
21592   u32 parent_if_index = ~0;
21593   u8 remote_mac[6];
21594   u8 mac_set = 0;
21595   int ret;
21596
21597   memset (remote_mac, 0, sizeof (remote_mac));
21598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21599     {
21600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21601         ;
21602       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21603         ;
21604       else
21605         if (unformat
21606             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21607         mac_set++;
21608       else
21609         {
21610           clib_warning ("parse error '%U'", format_unformat_error, i);
21611           return -99;
21612         }
21613     }
21614
21615   if (parent_if_index == ~0)
21616     {
21617       errmsg ("missing interface name or sw_if_index");
21618       return -99;
21619     }
21620   if (mac_set == 0)
21621     {
21622       errmsg ("missing remote mac address");
21623       return -99;
21624     }
21625
21626   M (P2P_ETHERNET_DEL, mp);
21627   mp->parent_if_index = ntohl (parent_if_index);
21628   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21629
21630   S (mp);
21631   W (ret);
21632   return ret;
21633 }
21634
21635 static int
21636 api_lldp_config (vat_main_t * vam)
21637 {
21638   unformat_input_t *i = vam->input;
21639   vl_api_lldp_config_t *mp;
21640   int tx_hold = 0;
21641   int tx_interval = 0;
21642   u8 *sys_name = NULL;
21643   int ret;
21644
21645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21646     {
21647       if (unformat (i, "system-name %s", &sys_name))
21648         ;
21649       else if (unformat (i, "tx-hold %d", &tx_hold))
21650         ;
21651       else if (unformat (i, "tx-interval %d", &tx_interval))
21652         ;
21653       else
21654         {
21655           clib_warning ("parse error '%U'", format_unformat_error, i);
21656           return -99;
21657         }
21658     }
21659
21660   vec_add1 (sys_name, 0);
21661
21662   M (LLDP_CONFIG, mp);
21663   mp->tx_hold = htonl (tx_hold);
21664   mp->tx_interval = htonl (tx_interval);
21665   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21666   vec_free (sys_name);
21667
21668   S (mp);
21669   W (ret);
21670   return ret;
21671 }
21672
21673 static int
21674 api_sw_interface_set_lldp (vat_main_t * vam)
21675 {
21676   unformat_input_t *i = vam->input;
21677   vl_api_sw_interface_set_lldp_t *mp;
21678   u32 sw_if_index = ~0;
21679   u32 enable = 1;
21680   u8 *port_desc = NULL, *mgmt_oid = NULL;
21681   ip4_address_t ip4_addr;
21682   ip6_address_t ip6_addr;
21683   int ret;
21684
21685   memset (&ip4_addr, 0, sizeof (ip4_addr));
21686   memset (&ip6_addr, 0, sizeof (ip6_addr));
21687
21688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21689     {
21690       if (unformat (i, "disable"))
21691         enable = 0;
21692       else
21693         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21694         ;
21695       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21696         ;
21697       else if (unformat (i, "port-desc %s", &port_desc))
21698         ;
21699       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21700         ;
21701       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21702         ;
21703       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21704         ;
21705       else
21706         break;
21707     }
21708
21709   if (sw_if_index == ~0)
21710     {
21711       errmsg ("missing interface name or sw_if_index");
21712       return -99;
21713     }
21714
21715   /* Construct the API message */
21716   vec_add1 (port_desc, 0);
21717   vec_add1 (mgmt_oid, 0);
21718   M (SW_INTERFACE_SET_LLDP, mp);
21719   mp->sw_if_index = ntohl (sw_if_index);
21720   mp->enable = enable;
21721   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21722   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21723   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21724   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21725   vec_free (port_desc);
21726   vec_free (mgmt_oid);
21727
21728   S (mp);
21729   W (ret);
21730   return ret;
21731 }
21732
21733 static int
21734 api_tcp_configure_src_addresses (vat_main_t * vam)
21735 {
21736   vl_api_tcp_configure_src_addresses_t *mp;
21737   unformat_input_t *i = vam->input;
21738   ip4_address_t v4first, v4last;
21739   ip6_address_t v6first, v6last;
21740   u8 range_set = 0;
21741   u32 vrf_id = 0;
21742   int ret;
21743
21744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21745     {
21746       if (unformat (i, "%U - %U",
21747                     unformat_ip4_address, &v4first,
21748                     unformat_ip4_address, &v4last))
21749         {
21750           if (range_set)
21751             {
21752               errmsg ("one range per message (range already set)");
21753               return -99;
21754             }
21755           range_set = 1;
21756         }
21757       else if (unformat (i, "%U - %U",
21758                          unformat_ip6_address, &v6first,
21759                          unformat_ip6_address, &v6last))
21760         {
21761           if (range_set)
21762             {
21763               errmsg ("one range per message (range already set)");
21764               return -99;
21765             }
21766           range_set = 2;
21767         }
21768       else if (unformat (i, "vrf %d", &vrf_id))
21769         ;
21770       else
21771         break;
21772     }
21773
21774   if (range_set == 0)
21775     {
21776       errmsg ("address range not set");
21777       return -99;
21778     }
21779
21780   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21781   mp->vrf_id = ntohl (vrf_id);
21782   /* ipv6? */
21783   if (range_set == 2)
21784     {
21785       mp->is_ipv6 = 1;
21786       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21787       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21788     }
21789   else
21790     {
21791       mp->is_ipv6 = 0;
21792       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21793       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21794     }
21795   S (mp);
21796   W (ret);
21797   return ret;
21798 }
21799
21800 static void vl_api_app_namespace_add_del_reply_t_handler
21801   (vl_api_app_namespace_add_del_reply_t * mp)
21802 {
21803   vat_main_t *vam = &vat_main;
21804   i32 retval = ntohl (mp->retval);
21805   if (vam->async_mode)
21806     {
21807       vam->async_errors += (retval < 0);
21808     }
21809   else
21810     {
21811       vam->retval = retval;
21812       if (retval == 0)
21813         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21814       vam->result_ready = 1;
21815     }
21816 }
21817
21818 static void vl_api_app_namespace_add_del_reply_t_handler_json
21819   (vl_api_app_namespace_add_del_reply_t * mp)
21820 {
21821   vat_main_t *vam = &vat_main;
21822   vat_json_node_t node;
21823
21824   vat_json_init_object (&node);
21825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21826   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21827
21828   vat_json_print (vam->ofp, &node);
21829   vat_json_free (&node);
21830
21831   vam->retval = ntohl (mp->retval);
21832   vam->result_ready = 1;
21833 }
21834
21835 static int
21836 api_app_namespace_add_del (vat_main_t * vam)
21837 {
21838   vl_api_app_namespace_add_del_t *mp;
21839   unformat_input_t *i = vam->input;
21840   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21841   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21842   u64 secret;
21843   int ret;
21844
21845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21846     {
21847       if (unformat (i, "id %_%v%_", &ns_id))
21848         ;
21849       else if (unformat (i, "secret %lu", &secret))
21850         secret_set = 1;
21851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21852         sw_if_index_set = 1;
21853       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21854         ;
21855       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21856         ;
21857       else
21858         break;
21859     }
21860   if (!ns_id || !secret_set || !sw_if_index_set)
21861     {
21862       errmsg ("namespace id, secret and sw_if_index must be set");
21863       return -99;
21864     }
21865   if (vec_len (ns_id) > 64)
21866     {
21867       errmsg ("namespace id too long");
21868       return -99;
21869     }
21870   M (APP_NAMESPACE_ADD_DEL, mp);
21871
21872   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21873   mp->namespace_id_len = vec_len (ns_id);
21874   mp->secret = clib_host_to_net_u64 (secret);
21875   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21876   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21877   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21878   vec_free (ns_id);
21879   S (mp);
21880   W (ret);
21881   return ret;
21882 }
21883
21884 static int
21885 api_memfd_segment_create (vat_main_t * vam)
21886 {
21887 #if VPP_API_TEST_BUILTIN == 0
21888   unformat_input_t *i = vam->input;
21889   vl_api_memfd_segment_create_t *mp;
21890   u64 size = 64 << 20;
21891   int ret;
21892
21893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21894     {
21895       if (unformat (i, "size %U", unformat_memory_size, &size))
21896         ;
21897       else
21898         break;
21899     }
21900
21901   M (MEMFD_SEGMENT_CREATE, mp);
21902   mp->requested_size = size;
21903   S (mp);
21904   W (ret);
21905   return ret;
21906
21907 #else
21908   errmsg ("memfd_segment_create (builtin) not supported");
21909   return -99;
21910 #endif
21911 }
21912
21913 static int
21914 api_sock_init_shm (vat_main_t * vam)
21915 {
21916 #if VPP_API_TEST_BUILTIN == 0
21917   unformat_input_t *i = vam->input;
21918   vl_api_shm_elem_config_t *config = 0;
21919   u64 size = 64 << 20;
21920   int rv;
21921
21922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21923     {
21924       if (unformat (i, "size %U", unformat_memory_size, &size))
21925         ;
21926       else
21927         break;
21928     }
21929
21930   /* Try customized config to see if it works */
21931   vec_validate (config, 3);
21932   config[0].type = VL_API_VLIB_RING;
21933   config[0].count = 256;
21934   config[0].size = 256;
21935   config[1].type = VL_API_CLIENT_RING;
21936   config[1].count = 256;
21937   config[1].size = 1024;
21938   config[2].type = VL_API_CLIENT_RING;
21939   config[2].count = 8;
21940   config[2].size = 4096;
21941   config[3].type = VL_API_QUEUE;
21942   config[3].count = 256;
21943   config[3].size = sizeof (uword);
21944   rv = vl_socket_client_init_shm (config);
21945   if (!rv)
21946     vam->client_index_invalid = 1;
21947   return rv;
21948 #else
21949   return -99;
21950 #endif
21951 }
21952
21953 static int
21954 api_dns_enable_disable (vat_main_t * vam)
21955 {
21956   unformat_input_t *line_input = vam->input;
21957   vl_api_dns_enable_disable_t *mp;
21958   u8 enable_disable = 1;
21959   int ret;
21960
21961   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21962     {
21963       if (unformat (line_input, "disable"))
21964         enable_disable = 0;
21965       if (unformat (line_input, "enable"))
21966         enable_disable = 1;
21967       else
21968         break;
21969     }
21970
21971   /* Construct the API message */
21972   M (DNS_ENABLE_DISABLE, mp);
21973   mp->enable = enable_disable;
21974
21975   /* send it... */
21976   S (mp);
21977   /* Wait for the reply */
21978   W (ret);
21979   return ret;
21980 }
21981
21982 static int
21983 api_dns_resolve_name (vat_main_t * vam)
21984 {
21985   unformat_input_t *line_input = vam->input;
21986   vl_api_dns_resolve_name_t *mp;
21987   u8 *name = 0;
21988   int ret;
21989
21990   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21991     {
21992       if (unformat (line_input, "%s", &name))
21993         ;
21994       else
21995         break;
21996     }
21997
21998   if (vec_len (name) > 127)
21999     {
22000       errmsg ("name too long");
22001       return -99;
22002     }
22003
22004   /* Construct the API message */
22005   M (DNS_RESOLVE_NAME, mp);
22006   memcpy (mp->name, name, vec_len (name));
22007   vec_free (name);
22008
22009   /* send it... */
22010   S (mp);
22011   /* Wait for the reply */
22012   W (ret);
22013   return ret;
22014 }
22015
22016 static int
22017 api_dns_resolve_ip (vat_main_t * vam)
22018 {
22019   unformat_input_t *line_input = vam->input;
22020   vl_api_dns_resolve_ip_t *mp;
22021   int is_ip6 = -1;
22022   ip4_address_t addr4;
22023   ip6_address_t addr6;
22024   int ret;
22025
22026   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22027     {
22028       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22029         is_ip6 = 1;
22030       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22031         is_ip6 = 0;
22032       else
22033         break;
22034     }
22035
22036   if (is_ip6 == -1)
22037     {
22038       errmsg ("missing address");
22039       return -99;
22040     }
22041
22042   /* Construct the API message */
22043   M (DNS_RESOLVE_IP, mp);
22044   mp->is_ip6 = is_ip6;
22045   if (is_ip6)
22046     memcpy (mp->address, &addr6, sizeof (addr6));
22047   else
22048     memcpy (mp->address, &addr4, sizeof (addr4));
22049
22050   /* send it... */
22051   S (mp);
22052   /* Wait for the reply */
22053   W (ret);
22054   return ret;
22055 }
22056
22057 static int
22058 api_dns_name_server_add_del (vat_main_t * vam)
22059 {
22060   unformat_input_t *i = vam->input;
22061   vl_api_dns_name_server_add_del_t *mp;
22062   u8 is_add = 1;
22063   ip6_address_t ip6_server;
22064   ip4_address_t ip4_server;
22065   int ip6_set = 0;
22066   int ip4_set = 0;
22067   int ret = 0;
22068
22069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22070     {
22071       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22072         ip6_set = 1;
22073       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22074         ip4_set = 1;
22075       else if (unformat (i, "del"))
22076         is_add = 0;
22077       else
22078         {
22079           clib_warning ("parse error '%U'", format_unformat_error, i);
22080           return -99;
22081         }
22082     }
22083
22084   if (ip4_set && ip6_set)
22085     {
22086       errmsg ("Only one server address allowed per message");
22087       return -99;
22088     }
22089   if ((ip4_set + ip6_set) == 0)
22090     {
22091       errmsg ("Server address required");
22092       return -99;
22093     }
22094
22095   /* Construct the API message */
22096   M (DNS_NAME_SERVER_ADD_DEL, mp);
22097
22098   if (ip6_set)
22099     {
22100       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22101       mp->is_ip6 = 1;
22102     }
22103   else
22104     {
22105       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22106       mp->is_ip6 = 0;
22107     }
22108
22109   mp->is_add = is_add;
22110
22111   /* send it... */
22112   S (mp);
22113
22114   /* Wait for a reply, return good/bad news  */
22115   W (ret);
22116   return ret;
22117 }
22118
22119 static void
22120 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22121 {
22122   vat_main_t *vam = &vat_main;
22123
22124   if (mp->is_ip4)
22125     {
22126       print (vam->ofp,
22127              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22128              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22129              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22130              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22131              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22132              clib_net_to_host_u32 (mp->action_index), mp->tag);
22133     }
22134   else
22135     {
22136       print (vam->ofp,
22137              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22138              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22139              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22140              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22141              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22142              clib_net_to_host_u32 (mp->action_index), mp->tag);
22143     }
22144 }
22145
22146 static void
22147 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22148                                              mp)
22149 {
22150   vat_main_t *vam = &vat_main;
22151   vat_json_node_t *node = NULL;
22152   struct in6_addr ip6;
22153   struct in_addr ip4;
22154
22155   if (VAT_JSON_ARRAY != vam->json_tree.type)
22156     {
22157       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22158       vat_json_init_array (&vam->json_tree);
22159     }
22160   node = vat_json_array_add (&vam->json_tree);
22161   vat_json_init_object (node);
22162
22163   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22164   vat_json_object_add_uint (node, "appns_index",
22165                             clib_net_to_host_u32 (mp->appns_index));
22166   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22167   vat_json_object_add_uint (node, "scope", mp->scope);
22168   vat_json_object_add_uint (node, "action_index",
22169                             clib_net_to_host_u32 (mp->action_index));
22170   vat_json_object_add_uint (node, "lcl_port",
22171                             clib_net_to_host_u16 (mp->lcl_port));
22172   vat_json_object_add_uint (node, "rmt_port",
22173                             clib_net_to_host_u16 (mp->rmt_port));
22174   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22175   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22176   vat_json_object_add_string_copy (node, "tag", mp->tag);
22177   if (mp->is_ip4)
22178     {
22179       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22180       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22181       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22182       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22183     }
22184   else
22185     {
22186       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22187       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22188       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22189       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22190     }
22191 }
22192
22193 static int
22194 api_session_rule_add_del (vat_main_t * vam)
22195 {
22196   vl_api_session_rule_add_del_t *mp;
22197   unformat_input_t *i = vam->input;
22198   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22199   u32 appns_index = 0, scope = 0;
22200   ip4_address_t lcl_ip4, rmt_ip4;
22201   ip6_address_t lcl_ip6, rmt_ip6;
22202   u8 is_ip4 = 1, conn_set = 0;
22203   u8 is_add = 1, *tag = 0;
22204   int ret;
22205
22206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22207     {
22208       if (unformat (i, "del"))
22209         is_add = 0;
22210       else if (unformat (i, "add"))
22211         ;
22212       else if (unformat (i, "proto tcp"))
22213         proto = 0;
22214       else if (unformat (i, "proto udp"))
22215         proto = 1;
22216       else if (unformat (i, "appns %d", &appns_index))
22217         ;
22218       else if (unformat (i, "scope %d", &scope))
22219         ;
22220       else if (unformat (i, "tag %_%v%_", &tag))
22221         ;
22222       else
22223         if (unformat
22224             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22225              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22226              &rmt_port))
22227         {
22228           is_ip4 = 1;
22229           conn_set = 1;
22230         }
22231       else
22232         if (unformat
22233             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22234              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22235              &rmt_port))
22236         {
22237           is_ip4 = 0;
22238           conn_set = 1;
22239         }
22240       else if (unformat (i, "action %d", &action))
22241         ;
22242       else
22243         break;
22244     }
22245   if (proto == ~0 || !conn_set || action == ~0)
22246     {
22247       errmsg ("transport proto, connection and action must be set");
22248       return -99;
22249     }
22250
22251   if (scope > 3)
22252     {
22253       errmsg ("scope should be 0-3");
22254       return -99;
22255     }
22256
22257   M (SESSION_RULE_ADD_DEL, mp);
22258
22259   mp->is_ip4 = is_ip4;
22260   mp->transport_proto = proto;
22261   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22262   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22263   mp->lcl_plen = lcl_plen;
22264   mp->rmt_plen = rmt_plen;
22265   mp->action_index = clib_host_to_net_u32 (action);
22266   mp->appns_index = clib_host_to_net_u32 (appns_index);
22267   mp->scope = scope;
22268   mp->is_add = is_add;
22269   if (is_ip4)
22270     {
22271       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22272       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22273     }
22274   else
22275     {
22276       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22277       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22278     }
22279   if (tag)
22280     {
22281       clib_memcpy (mp->tag, tag, vec_len (tag));
22282       vec_free (tag);
22283     }
22284
22285   S (mp);
22286   W (ret);
22287   return ret;
22288 }
22289
22290 static int
22291 api_session_rules_dump (vat_main_t * vam)
22292 {
22293   vl_api_session_rules_dump_t *mp;
22294   vl_api_control_ping_t *mp_ping;
22295   int ret;
22296
22297   if (!vam->json_output)
22298     {
22299       print (vam->ofp, "%=20s", "Session Rules");
22300     }
22301
22302   M (SESSION_RULES_DUMP, mp);
22303   /* send it... */
22304   S (mp);
22305
22306   /* Use a control ping for synchronization */
22307   MPING (CONTROL_PING, mp_ping);
22308   S (mp_ping);
22309
22310   /* Wait for a reply... */
22311   W (ret);
22312   return ret;
22313 }
22314
22315 static int
22316 api_ip_container_proxy_add_del (vat_main_t * vam)
22317 {
22318   vl_api_ip_container_proxy_add_del_t *mp;
22319   unformat_input_t *i = vam->input;
22320   u32 plen = ~0, sw_if_index = ~0;
22321   ip4_address_t ip4;
22322   ip6_address_t ip6;
22323   u8 is_ip4 = 1;
22324   u8 is_add = 1;
22325   int ret;
22326
22327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22328     {
22329       if (unformat (i, "del"))
22330         is_add = 0;
22331       else if (unformat (i, "add"))
22332         ;
22333       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22334         {
22335           is_ip4 = 1;
22336           plen = 32;
22337         }
22338       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22339         {
22340           is_ip4 = 0;
22341           plen = 128;
22342         }
22343       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22344         ;
22345       else
22346         break;
22347     }
22348   if (sw_if_index == ~0 || plen == ~0)
22349     {
22350       errmsg ("address and sw_if_index must be set");
22351       return -99;
22352     }
22353
22354   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22355
22356   mp->is_ip4 = is_ip4;
22357   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22358   mp->plen = plen;
22359   mp->is_add = is_add;
22360   if (is_ip4)
22361     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22362   else
22363     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22364
22365   S (mp);
22366   W (ret);
22367   return ret;
22368 }
22369
22370 static int
22371 q_or_quit (vat_main_t * vam)
22372 {
22373 #if VPP_API_TEST_BUILTIN == 0
22374   longjmp (vam->jump_buf, 1);
22375 #endif
22376   return 0;                     /* not so much */
22377 }
22378
22379 static int
22380 q (vat_main_t * vam)
22381 {
22382   return q_or_quit (vam);
22383 }
22384
22385 static int
22386 quit (vat_main_t * vam)
22387 {
22388   return q_or_quit (vam);
22389 }
22390
22391 static int
22392 comment (vat_main_t * vam)
22393 {
22394   return 0;
22395 }
22396
22397 static int
22398 cmd_cmp (void *a1, void *a2)
22399 {
22400   u8 **c1 = a1;
22401   u8 **c2 = a2;
22402
22403   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22404 }
22405
22406 static int
22407 help (vat_main_t * vam)
22408 {
22409   u8 **cmds = 0;
22410   u8 *name = 0;
22411   hash_pair_t *p;
22412   unformat_input_t *i = vam->input;
22413   int j;
22414
22415   if (unformat (i, "%s", &name))
22416     {
22417       uword *hs;
22418
22419       vec_add1 (name, 0);
22420
22421       hs = hash_get_mem (vam->help_by_name, name);
22422       if (hs)
22423         print (vam->ofp, "usage: %s %s", name, hs[0]);
22424       else
22425         print (vam->ofp, "No such msg / command '%s'", name);
22426       vec_free (name);
22427       return 0;
22428     }
22429
22430   print (vam->ofp, "Help is available for the following:");
22431
22432     /* *INDENT-OFF* */
22433     hash_foreach_pair (p, vam->function_by_name,
22434     ({
22435       vec_add1 (cmds, (u8 *)(p->key));
22436     }));
22437     /* *INDENT-ON* */
22438
22439   vec_sort_with_function (cmds, cmd_cmp);
22440
22441   for (j = 0; j < vec_len (cmds); j++)
22442     print (vam->ofp, "%s", cmds[j]);
22443
22444   vec_free (cmds);
22445   return 0;
22446 }
22447
22448 static int
22449 set (vat_main_t * vam)
22450 {
22451   u8 *name = 0, *value = 0;
22452   unformat_input_t *i = vam->input;
22453
22454   if (unformat (i, "%s", &name))
22455     {
22456       /* The input buffer is a vector, not a string. */
22457       value = vec_dup (i->buffer);
22458       vec_delete (value, i->index, 0);
22459       /* Almost certainly has a trailing newline */
22460       if (value[vec_len (value) - 1] == '\n')
22461         value[vec_len (value) - 1] = 0;
22462       /* Make sure it's a proper string, one way or the other */
22463       vec_add1 (value, 0);
22464       (void) clib_macro_set_value (&vam->macro_main,
22465                                    (char *) name, (char *) value);
22466     }
22467   else
22468     errmsg ("usage: set <name> <value>");
22469
22470   vec_free (name);
22471   vec_free (value);
22472   return 0;
22473 }
22474
22475 static int
22476 unset (vat_main_t * vam)
22477 {
22478   u8 *name = 0;
22479
22480   if (unformat (vam->input, "%s", &name))
22481     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22482       errmsg ("unset: %s wasn't set", name);
22483   vec_free (name);
22484   return 0;
22485 }
22486
22487 typedef struct
22488 {
22489   u8 *name;
22490   u8 *value;
22491 } macro_sort_t;
22492
22493
22494 static int
22495 macro_sort_cmp (void *a1, void *a2)
22496 {
22497   macro_sort_t *s1 = a1;
22498   macro_sort_t *s2 = a2;
22499
22500   return strcmp ((char *) (s1->name), (char *) (s2->name));
22501 }
22502
22503 static int
22504 dump_macro_table (vat_main_t * vam)
22505 {
22506   macro_sort_t *sort_me = 0, *sm;
22507   int i;
22508   hash_pair_t *p;
22509
22510     /* *INDENT-OFF* */
22511     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22512     ({
22513       vec_add2 (sort_me, sm, 1);
22514       sm->name = (u8 *)(p->key);
22515       sm->value = (u8 *) (p->value[0]);
22516     }));
22517     /* *INDENT-ON* */
22518
22519   vec_sort_with_function (sort_me, macro_sort_cmp);
22520
22521   if (vec_len (sort_me))
22522     print (vam->ofp, "%-15s%s", "Name", "Value");
22523   else
22524     print (vam->ofp, "The macro table is empty...");
22525
22526   for (i = 0; i < vec_len (sort_me); i++)
22527     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22528   return 0;
22529 }
22530
22531 static int
22532 dump_node_table (vat_main_t * vam)
22533 {
22534   int i, j;
22535   vlib_node_t *node, *next_node;
22536
22537   if (vec_len (vam->graph_nodes) == 0)
22538     {
22539       print (vam->ofp, "Node table empty, issue get_node_graph...");
22540       return 0;
22541     }
22542
22543   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22544     {
22545       node = vam->graph_nodes[i];
22546       print (vam->ofp, "[%d] %s", i, node->name);
22547       for (j = 0; j < vec_len (node->next_nodes); j++)
22548         {
22549           if (node->next_nodes[j] != ~0)
22550             {
22551               next_node = vam->graph_nodes[node->next_nodes[j]];
22552               print (vam->ofp, "  [%d] %s", j, next_node->name);
22553             }
22554         }
22555     }
22556   return 0;
22557 }
22558
22559 static int
22560 value_sort_cmp (void *a1, void *a2)
22561 {
22562   name_sort_t *n1 = a1;
22563   name_sort_t *n2 = a2;
22564
22565   if (n1->value < n2->value)
22566     return -1;
22567   if (n1->value > n2->value)
22568     return 1;
22569   return 0;
22570 }
22571
22572
22573 static int
22574 dump_msg_api_table (vat_main_t * vam)
22575 {
22576   api_main_t *am = &api_main;
22577   name_sort_t *nses = 0, *ns;
22578   hash_pair_t *hp;
22579   int i;
22580
22581   /* *INDENT-OFF* */
22582   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22583   ({
22584     vec_add2 (nses, ns, 1);
22585     ns->name = (u8 *)(hp->key);
22586     ns->value = (u32) hp->value[0];
22587   }));
22588   /* *INDENT-ON* */
22589
22590   vec_sort_with_function (nses, value_sort_cmp);
22591
22592   for (i = 0; i < vec_len (nses); i++)
22593     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22594   vec_free (nses);
22595   return 0;
22596 }
22597
22598 static int
22599 get_msg_id (vat_main_t * vam)
22600 {
22601   u8 *name_and_crc;
22602   u32 message_index;
22603
22604   if (unformat (vam->input, "%s", &name_and_crc))
22605     {
22606       message_index = vl_msg_api_get_msg_index (name_and_crc);
22607       if (message_index == ~0)
22608         {
22609           print (vam->ofp, " '%s' not found", name_and_crc);
22610           return 0;
22611         }
22612       print (vam->ofp, " '%s' has message index %d",
22613              name_and_crc, message_index);
22614       return 0;
22615     }
22616   errmsg ("name_and_crc required...");
22617   return 0;
22618 }
22619
22620 static int
22621 search_node_table (vat_main_t * vam)
22622 {
22623   unformat_input_t *line_input = vam->input;
22624   u8 *node_to_find;
22625   int j;
22626   vlib_node_t *node, *next_node;
22627   uword *p;
22628
22629   if (vam->graph_node_index_by_name == 0)
22630     {
22631       print (vam->ofp, "Node table empty, issue get_node_graph...");
22632       return 0;
22633     }
22634
22635   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22636     {
22637       if (unformat (line_input, "%s", &node_to_find))
22638         {
22639           vec_add1 (node_to_find, 0);
22640           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22641           if (p == 0)
22642             {
22643               print (vam->ofp, "%s not found...", node_to_find);
22644               goto out;
22645             }
22646           node = vam->graph_nodes[p[0]];
22647           print (vam->ofp, "[%d] %s", p[0], node->name);
22648           for (j = 0; j < vec_len (node->next_nodes); j++)
22649             {
22650               if (node->next_nodes[j] != ~0)
22651                 {
22652                   next_node = vam->graph_nodes[node->next_nodes[j]];
22653                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22654                 }
22655             }
22656         }
22657
22658       else
22659         {
22660           clib_warning ("parse error '%U'", format_unformat_error,
22661                         line_input);
22662           return -99;
22663         }
22664
22665     out:
22666       vec_free (node_to_find);
22667
22668     }
22669
22670   return 0;
22671 }
22672
22673
22674 static int
22675 script (vat_main_t * vam)
22676 {
22677 #if (VPP_API_TEST_BUILTIN==0)
22678   u8 *s = 0;
22679   char *save_current_file;
22680   unformat_input_t save_input;
22681   jmp_buf save_jump_buf;
22682   u32 save_line_number;
22683
22684   FILE *new_fp, *save_ifp;
22685
22686   if (unformat (vam->input, "%s", &s))
22687     {
22688       new_fp = fopen ((char *) s, "r");
22689       if (new_fp == 0)
22690         {
22691           errmsg ("Couldn't open script file %s", s);
22692           vec_free (s);
22693           return -99;
22694         }
22695     }
22696   else
22697     {
22698       errmsg ("Missing script name");
22699       return -99;
22700     }
22701
22702   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22703   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22704   save_ifp = vam->ifp;
22705   save_line_number = vam->input_line_number;
22706   save_current_file = (char *) vam->current_file;
22707
22708   vam->input_line_number = 0;
22709   vam->ifp = new_fp;
22710   vam->current_file = s;
22711   do_one_file (vam);
22712
22713   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22714   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22715   vam->ifp = save_ifp;
22716   vam->input_line_number = save_line_number;
22717   vam->current_file = (u8 *) save_current_file;
22718   vec_free (s);
22719
22720   return 0;
22721 #else
22722   clib_warning ("use the exec command...");
22723   return -99;
22724 #endif
22725 }
22726
22727 static int
22728 echo (vat_main_t * vam)
22729 {
22730   print (vam->ofp, "%v", vam->input->buffer);
22731   return 0;
22732 }
22733
22734 /* List of API message constructors, CLI names map to api_xxx */
22735 #define foreach_vpe_api_msg                                             \
22736 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22737 _(sw_interface_dump,"")                                                 \
22738 _(sw_interface_set_flags,                                               \
22739   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22740 _(sw_interface_add_del_address,                                         \
22741   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22742 _(sw_interface_set_rx_mode,                                             \
22743   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22744 _(sw_interface_set_table,                                               \
22745   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22746 _(sw_interface_set_mpls_enable,                                         \
22747   "<intfc> | sw_if_index [disable | dis]")                              \
22748 _(sw_interface_set_vpath,                                               \
22749   "<intfc> | sw_if_index <id> enable | disable")                        \
22750 _(sw_interface_set_vxlan_bypass,                                        \
22751   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22752 _(sw_interface_set_geneve_bypass,                                       \
22753   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22754 _(sw_interface_set_l2_xconnect,                                         \
22755   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22756   "enable | disable")                                                   \
22757 _(sw_interface_set_l2_bridge,                                           \
22758   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22759   "[shg <split-horizon-group>] [bvi]\n"                                 \
22760   "enable | disable")                                                   \
22761 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22762 _(bridge_domain_add_del,                                                \
22763   "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") \
22764 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22765 _(l2fib_add_del,                                                        \
22766   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22767 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22768 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22769 _(l2_flags,                                                             \
22770   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22771 _(bridge_flags,                                                         \
22772   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22773 _(tap_connect,                                                          \
22774   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22775 _(tap_modify,                                                           \
22776   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22777 _(tap_delete,                                                           \
22778   "<vpp-if-name> | sw_if_index <id>")                                   \
22779 _(sw_interface_tap_dump, "")                                            \
22780 _(tap_create_v2,                                                        \
22781   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22782 _(tap_delete_v2,                                                        \
22783   "<vpp-if-name> | sw_if_index <id>")                                   \
22784 _(sw_interface_tap_v2_dump, "")                                         \
22785 _(ip_table_add_del,                                                     \
22786   "table-id <n> [ipv6]\n")                                              \
22787 _(ip_add_del_route,                                                     \
22788   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22789   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22790   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22791   "[multipath] [count <n>]")                                            \
22792 _(ip_mroute_add_del,                                                    \
22793   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22794   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22795 _(mpls_table_add_del,                                                   \
22796   "table-id <n>\n")                                                     \
22797 _(mpls_route_add_del,                                                   \
22798   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22799   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22800   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22801   "[multipath] [count <n>]")                                            \
22802 _(mpls_ip_bind_unbind,                                                  \
22803   "<label> <addr/len>")                                                 \
22804 _(mpls_tunnel_add_del,                                                  \
22805   " via <addr> [table-id <n>]\n"                                        \
22806   "sw_if_index <id>] [l2]  [del]")                                      \
22807 _(bier_table_add_del,                                                   \
22808   "<label> <sub-domain> <set> <bsl> [del]")                             \
22809 _(bier_route_add_del,                                                   \
22810   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22811   "[<intfc> | sw_if_index <id>]"                                        \
22812   "[weight <n>] [del] [multipath]")                                     \
22813 _(proxy_arp_add_del,                                                    \
22814   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22815 _(proxy_arp_intfc_enable_disable,                                       \
22816   "<intfc> | sw_if_index <id> enable | disable")                        \
22817 _(sw_interface_set_unnumbered,                                          \
22818   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22819 _(ip_neighbor_add_del,                                                  \
22820   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22821   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22822 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22823 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22824   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22825   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22826   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22827 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22828 _(reset_fib, "vrf <n> [ipv6]")                                          \
22829 _(dhcp_proxy_config,                                                    \
22830   "svr <v46-address> src <v46-address>\n"                               \
22831    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22832 _(dhcp_proxy_set_vss,                                                   \
22833   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22834 _(dhcp_proxy_dump, "ip6")                                               \
22835 _(dhcp_client_config,                                                   \
22836   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22837 _(set_ip_flow_hash,                                                     \
22838   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22839 _(sw_interface_ip6_enable_disable,                                      \
22840   "<intfc> | sw_if_index <id> enable | disable")                        \
22841 _(sw_interface_ip6_set_link_local_address,                              \
22842   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22843 _(ip6nd_proxy_add_del,                                                  \
22844   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22845 _(ip6nd_proxy_dump, "")                                                 \
22846 _(sw_interface_ip6nd_ra_prefix,                                         \
22847   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22848   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22849   "[nolink] [isno]")                                                    \
22850 _(sw_interface_ip6nd_ra_config,                                         \
22851   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22852   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22853   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22854 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22855 _(l2_patch_add_del,                                                     \
22856   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22857   "enable | disable")                                                   \
22858 _(sr_localsid_add_del,                                                  \
22859   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22860   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22861 _(classify_add_del_table,                                               \
22862   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22863   " [del] [del-chain] mask <mask-value>\n"                              \
22864   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22865   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22866 _(classify_add_del_session,                                             \
22867   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22868   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22869   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22870   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22871 _(classify_set_interface_ip_table,                                      \
22872   "<intfc> | sw_if_index <nn> table <nn>")                              \
22873 _(classify_set_interface_l2_tables,                                     \
22874   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22875   "  [other-table <nn>]")                                               \
22876 _(get_node_index, "node <node-name")                                    \
22877 _(add_node_next, "node <node-name> next <next-node-name>")              \
22878 _(l2tpv3_create_tunnel,                                                 \
22879   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22880   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22881   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22882 _(l2tpv3_set_tunnel_cookies,                                            \
22883   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22884   "[new_remote_cookie <nn>]\n")                                         \
22885 _(l2tpv3_interface_enable_disable,                                      \
22886   "<intfc> | sw_if_index <nn> enable | disable")                        \
22887 _(l2tpv3_set_lookup_key,                                                \
22888   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22889 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22890 _(vxlan_add_del_tunnel,                                                 \
22891   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22892   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22893   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22894 _(geneve_add_del_tunnel,                                                \
22895   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22896   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22897   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22898 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22899 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22900 _(gre_add_del_tunnel,                                                   \
22901   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22902   "[teb | erspan <session-id>] [del]")                                  \
22903 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22904 _(l2_fib_clear_table, "")                                               \
22905 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22906 _(l2_interface_vlan_tag_rewrite,                                        \
22907   "<intfc> | sw_if_index <nn> \n"                                       \
22908   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22909   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22910 _(create_vhost_user_if,                                                 \
22911         "socket <filename> [server] [renumber <dev_instance>] "         \
22912         "[mac <mac_address>]")                                          \
22913 _(modify_vhost_user_if,                                                 \
22914         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22915         "[server] [renumber <dev_instance>]")                           \
22916 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22917 _(sw_interface_vhost_user_dump, "")                                     \
22918 _(show_version, "")                                                     \
22919 _(vxlan_gpe_add_del_tunnel,                                             \
22920   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22921   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22922   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22923   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22924 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22925 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22926 _(interface_name_renumber,                                              \
22927   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22928 _(input_acl_set_interface,                                              \
22929   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22930   "  [l2-table <nn>] [del]")                                            \
22931 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22932 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22933 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22934 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22935 _(ip_dump, "ipv4 | ipv6")                                               \
22936 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22937 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22938   "  spid_id <n> ")                                                     \
22939 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22940   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22941   "  integ_alg <alg> integ_key <hex>")                                  \
22942 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22943   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22944   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22945   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22946 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22947 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22948   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22949   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22950   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22951 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22952 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22953   "  <alg> <hex>\n")                                                    \
22954 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22955 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22956 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22957   "(auth_data 0x<data> | auth_data <data>)")                            \
22958 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22959   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22960 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22961   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22962   "(local|remote)")                                                     \
22963 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22964 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22965 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22966 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22967 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22968 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22969 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22970 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22971 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22972 _(delete_loopback,"sw_if_index <nn>")                                   \
22973 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22974 _(map_add_domain,                                                       \
22975   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22976   "ip6-src <ip6addr> "                                                  \
22977   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22978 _(map_del_domain, "index <n>")                                          \
22979 _(map_add_del_rule,                                                     \
22980   "index <n> psid <n> dst <ip6addr> [del]")                             \
22981 _(map_domain_dump, "")                                                  \
22982 _(map_rule_dump, "index <map-domain>")                                  \
22983 _(want_interface_events,  "enable|disable")                             \
22984 _(want_stats,"enable|disable")                                          \
22985 _(get_first_msg_id, "client <name>")                                    \
22986 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22987 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22988   "fib-id <nn> [ip4][ip6][default]")                                    \
22989 _(get_node_graph, " ")                                                  \
22990 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22991 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22992 _(ioam_disable, "")                                                     \
22993 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22994                             " sw_if_index <sw_if_index> p <priority> "  \
22995                             "w <weight>] [del]")                        \
22996 _(one_add_del_locator, "locator-set <locator_name> "                    \
22997                         "iface <intf> | sw_if_index <sw_if_index> "     \
22998                         "p <priority> w <weight> [del]")                \
22999 _(one_add_del_local_eid,"vni <vni> eid "                                \
23000                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23001                          "locator-set <locator_name> [del]"             \
23002                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23003 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23004 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23005 _(one_enable_disable, "enable|disable")                                 \
23006 _(one_map_register_enable_disable, "enable|disable")                    \
23007 _(one_map_register_fallback_threshold, "<value>")                       \
23008 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23009 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23010                                "[seid <seid>] "                         \
23011                                "rloc <locator> p <prio> "               \
23012                                "w <weight> [rloc <loc> ... ] "          \
23013                                "action <action> [del-all]")             \
23014 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23015                           "<local-eid>")                                \
23016 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23017 _(one_use_petr, "ip-address> | disable")                                \
23018 _(one_map_request_mode, "src-dst|dst-only")                             \
23019 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23020 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23021 _(one_locator_set_dump, "[local | remote]")                             \
23022 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23023 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23024                        "[local] | [remote]")                            \
23025 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23026 _(one_ndp_bd_get, "")                                                   \
23027 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23028 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23029 _(one_l2_arp_bd_get, "")                                                \
23030 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23031 _(one_stats_enable_disable, "enable|disalbe")                           \
23032 _(show_one_stats_enable_disable, "")                                    \
23033 _(one_eid_table_vni_dump, "")                                           \
23034 _(one_eid_table_map_dump, "l2|l3")                                      \
23035 _(one_map_resolver_dump, "")                                            \
23036 _(one_map_server_dump, "")                                              \
23037 _(one_adjacencies_get, "vni <vni>")                                     \
23038 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23039 _(show_one_rloc_probe_state, "")                                        \
23040 _(show_one_map_register_state, "")                                      \
23041 _(show_one_status, "")                                                  \
23042 _(one_stats_dump, "")                                                   \
23043 _(one_stats_flush, "")                                                  \
23044 _(one_get_map_request_itr_rlocs, "")                                    \
23045 _(one_map_register_set_ttl, "<ttl>")                                    \
23046 _(one_set_transport_protocol, "udp|api")                                \
23047 _(one_get_transport_protocol, "")                                       \
23048 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23049 _(one_show_xtr_mode, "")                                                \
23050 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23051 _(one_show_pitr_mode, "")                                               \
23052 _(one_enable_disable_petr_mode, "enable|disable")                       \
23053 _(one_show_petr_mode, "")                                               \
23054 _(show_one_nsh_mapping, "")                                             \
23055 _(show_one_pitr, "")                                                    \
23056 _(show_one_use_petr, "")                                                \
23057 _(show_one_map_request_mode, "")                                        \
23058 _(show_one_map_register_ttl, "")                                        \
23059 _(show_one_map_register_fallback_threshold, "")                         \
23060 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23061                             " sw_if_index <sw_if_index> p <priority> "  \
23062                             "w <weight>] [del]")                        \
23063 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23064                         "iface <intf> | sw_if_index <sw_if_index> "     \
23065                         "p <priority> w <weight> [del]")                \
23066 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23067                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23068                          "locator-set <locator_name> [del]"             \
23069                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23070 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23071 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23072 _(lisp_enable_disable, "enable|disable")                                \
23073 _(lisp_map_register_enable_disable, "enable|disable")                   \
23074 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23075 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23076                                "[seid <seid>] "                         \
23077                                "rloc <locator> p <prio> "               \
23078                                "w <weight> [rloc <loc> ... ] "          \
23079                                "action <action> [del-all]")             \
23080 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23081                           "<local-eid>")                                \
23082 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23083 _(lisp_use_petr, "<ip-address> | disable")                              \
23084 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23085 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23086 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23087 _(lisp_locator_set_dump, "[local | remote]")                            \
23088 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23089 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23090                        "[local] | [remote]")                            \
23091 _(lisp_eid_table_vni_dump, "")                                          \
23092 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23093 _(lisp_map_resolver_dump, "")                                           \
23094 _(lisp_map_server_dump, "")                                             \
23095 _(lisp_adjacencies_get, "vni <vni>")                                    \
23096 _(gpe_fwd_entry_vnis_get, "")                                           \
23097 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23098 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23099                                 "[table <table-id>]")                   \
23100 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23101 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23102 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23103 _(gpe_get_encap_mode, "")                                               \
23104 _(lisp_gpe_add_del_iface, "up|down")                                    \
23105 _(lisp_gpe_enable_disable, "enable|disable")                            \
23106 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23107   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23108 _(show_lisp_rloc_probe_state, "")                                       \
23109 _(show_lisp_map_register_state, "")                                     \
23110 _(show_lisp_status, "")                                                 \
23111 _(lisp_get_map_request_itr_rlocs, "")                                   \
23112 _(show_lisp_pitr, "")                                                   \
23113 _(show_lisp_use_petr, "")                                               \
23114 _(show_lisp_map_request_mode, "")                                       \
23115 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23116 _(af_packet_delete, "name <host interface name>")                       \
23117 _(policer_add_del, "name <policer name> <params> [del]")                \
23118 _(policer_dump, "[name <policer name>]")                                \
23119 _(policer_classify_set_interface,                                       \
23120   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23121   "  [l2-table <nn>] [del]")                                            \
23122 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23123 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23124     "[master|slave]")                                                   \
23125 _(netmap_delete, "name <interface name>")                               \
23126 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23127 _(mpls_fib_dump, "")                                                    \
23128 _(classify_table_ids, "")                                               \
23129 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23130 _(classify_table_info, "table_id <nn>")                                 \
23131 _(classify_session_dump, "table_id <nn>")                               \
23132 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23133     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23134     "[template_interval <nn>] [udp_checksum]")                          \
23135 _(ipfix_exporter_dump, "")                                              \
23136 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23137 _(ipfix_classify_stream_dump, "")                                       \
23138 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23139 _(ipfix_classify_table_dump, "")                                        \
23140 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23141 _(sw_interface_span_dump, "[l2]")                                           \
23142 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23143 _(pg_create_interface, "if_id <nn>")                                    \
23144 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23145 _(pg_enable_disable, "[stream <id>] disable")                           \
23146 _(ip_source_and_port_range_check_add_del,                               \
23147   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23148 _(ip_source_and_port_range_check_interface_add_del,                     \
23149   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23150   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23151 _(ipsec_gre_add_del_tunnel,                                             \
23152   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23153 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23154 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23155 _(l2_interface_pbb_tag_rewrite,                                         \
23156   "<intfc> | sw_if_index <nn> \n"                                       \
23157   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23158   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23159 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23160 _(flow_classify_set_interface,                                          \
23161   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23162 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23163 _(ip_fib_dump, "")                                                      \
23164 _(ip_mfib_dump, "")                                                     \
23165 _(ip6_fib_dump, "")                                                     \
23166 _(ip6_mfib_dump, "")                                                    \
23167 _(feature_enable_disable, "arc_name <arc_name> "                        \
23168   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23169 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23170 "[disable]")                                                            \
23171 _(l2_xconnect_dump, "")                                                 \
23172 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23173 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23174 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23175 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23176 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23177 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23178 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23179   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23180 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23181 _(memfd_segment_create,"size <nnn>")                                    \
23182 _(sock_init_shm, "size <nnn>")                                          \
23183 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23184 _(dns_enable_disable, "[enable][disable]")                              \
23185 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23186 _(dns_resolve_name, "<hostname>")                                       \
23187 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23188 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23189 _(dns_resolve_name, "<hostname>")                                       \
23190 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23191   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23192 _(session_rules_dump, "")                                               \
23193 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23194 _(output_acl_set_interface,                                             \
23195   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23196   "  [l2-table <nn>] [del]")                                            \
23197
23198 /* List of command functions, CLI names map directly to functions */
23199 #define foreach_cli_function                                    \
23200 _(comment, "usage: comment <ignore-rest-of-line>")              \
23201 _(dump_interface_table, "usage: dump_interface_table")          \
23202 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23203 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23204 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23205 _(dump_stats_table, "usage: dump_stats_table")                  \
23206 _(dump_macro_table, "usage: dump_macro_table ")                 \
23207 _(dump_node_table, "usage: dump_node_table")                    \
23208 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23209 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23210 _(echo, "usage: echo <message>")                                \
23211 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23212 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23213 _(help, "usage: help")                                          \
23214 _(q, "usage: quit")                                             \
23215 _(quit, "usage: quit")                                          \
23216 _(search_node_table, "usage: search_node_table <name>...")      \
23217 _(set, "usage: set <variable-name> <value>")                    \
23218 _(script, "usage: script <file-name>")                          \
23219 _(unset, "usage: unset <variable-name>")
23220 #define _(N,n)                                  \
23221     static void vl_api_##n##_t_handler_uni      \
23222     (vl_api_##n##_t * mp)                       \
23223     {                                           \
23224         vat_main_t * vam = &vat_main;           \
23225         if (vam->json_output) {                 \
23226             vl_api_##n##_t_handler_json(mp);    \
23227         } else {                                \
23228             vl_api_##n##_t_handler(mp);         \
23229         }                                       \
23230     }
23231 foreach_vpe_api_reply_msg;
23232 #if VPP_API_TEST_BUILTIN == 0
23233 foreach_standalone_reply_msg;
23234 #endif
23235 #undef _
23236
23237 void
23238 vat_api_hookup (vat_main_t * vam)
23239 {
23240 #define _(N,n)                                                  \
23241     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23242                            vl_api_##n##_t_handler_uni,          \
23243                            vl_noop_handler,                     \
23244                            vl_api_##n##_t_endian,               \
23245                            vl_api_##n##_t_print,                \
23246                            sizeof(vl_api_##n##_t), 1);
23247   foreach_vpe_api_reply_msg;
23248 #if VPP_API_TEST_BUILTIN == 0
23249   foreach_standalone_reply_msg;
23250 #endif
23251 #undef _
23252
23253 #if (VPP_API_TEST_BUILTIN==0)
23254   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23255
23256   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23257
23258   vam->function_by_name = hash_create_string (0, sizeof (uword));
23259
23260   vam->help_by_name = hash_create_string (0, sizeof (uword));
23261 #endif
23262
23263   /* API messages we can send */
23264 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23265   foreach_vpe_api_msg;
23266 #undef _
23267
23268   /* Help strings */
23269 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23270   foreach_vpe_api_msg;
23271 #undef _
23272
23273   /* CLI functions */
23274 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23275   foreach_cli_function;
23276 #undef _
23277
23278   /* Help strings */
23279 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23280   foreach_cli_function;
23281 #undef _
23282 }
23283
23284 #if VPP_API_TEST_BUILTIN
23285 static clib_error_t *
23286 vat_api_hookup_shim (vlib_main_t * vm)
23287 {
23288   vat_api_hookup (&vat_main);
23289   return 0;
23290 }
23291
23292 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23293 #endif
23294
23295 /*
23296  * fd.io coding-style-patch-verification: ON
23297  *
23298  * Local Variables:
23299  * eval: (c-set-style "gnu")
23300  * End:
23301  */