svm: refactor memfd and remove ssvm_eth
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   vam->socket_client_main = &socket_client_main;
91   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
92                                    0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 int
102 vl_socket_client_read (int wait)
103 {
104   return -1;
105 };
106
107 int
108 vl_socket_client_write ()
109 {
110   return -1;
111 };
112
113 void *
114 vl_socket_client_msg_alloc (int nbytes)
115 {
116   return 0;
117 }
118 #endif
119
120
121 f64
122 vat_time_now (vat_main_t * vam)
123 {
124 #if VPP_API_TEST_BUILTIN
125   return vlib_time_now (vam->vlib_main);
126 #else
127   return clib_time_now (&vam->clib_time);
128 #endif
129 }
130
131 void
132 errmsg (char *fmt, ...)
133 {
134   vat_main_t *vam = &vat_main;
135   va_list va;
136   u8 *s;
137
138   va_start (va, fmt);
139   s = va_format (0, fmt, &va);
140   va_end (va);
141
142   vec_add1 (s, 0);
143
144 #if VPP_API_TEST_BUILTIN
145   vlib_cli_output (vam->vlib_main, (char *) s);
146 #else
147   {
148     if (vam->ifp != stdin)
149       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
150                vam->input_line_number);
151     fformat (vam->ofp, (char *) s);
152     fflush (vam->ofp);
153   }
154 #endif
155
156   vec_free (s);
157 }
158
159 #if VPP_API_TEST_BUILTIN == 0
160 static uword
161 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
162 {
163   vat_main_t *vam = va_arg (*args, vat_main_t *);
164   u32 *result = va_arg (*args, u32 *);
165   u8 *if_name;
166   uword *p;
167
168   if (!unformat (input, "%s", &if_name))
169     return 0;
170
171   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
172   if (p == 0)
173     return 0;
174   *result = p[0];
175   return 1;
176 }
177
178 /* Parse an IP4 address %d.%d.%d.%d. */
179 uword
180 unformat_ip4_address (unformat_input_t * input, va_list * args)
181 {
182   u8 *result = va_arg (*args, u8 *);
183   unsigned a[4];
184
185   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
186     return 0;
187
188   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
189     return 0;
190
191   result[0] = a[0];
192   result[1] = a[1];
193   result[2] = a[2];
194   result[3] = a[3];
195
196   return 1;
197 }
198
199 uword
200 unformat_ethernet_address (unformat_input_t * input, va_list * args)
201 {
202   u8 *result = va_arg (*args, u8 *);
203   u32 i, a[6];
204
205   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
206                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
207     return 0;
208
209   /* Check range. */
210   for (i = 0; i < 6; i++)
211     if (a[i] >= (1 << 8))
212       return 0;
213
214   for (i = 0; i < 6; i++)
215     result[i] = a[i];
216
217   return 1;
218 }
219
220 /* Returns ethernet type as an int in host byte order. */
221 uword
222 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
223                                         va_list * args)
224 {
225   u16 *result = va_arg (*args, u16 *);
226   int type;
227
228   /* Numeric type. */
229   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
230     {
231       if (type >= (1 << 16))
232         return 0;
233       *result = type;
234       return 1;
235     }
236   return 0;
237 }
238
239 /* Parse an IP6 address. */
240 uword
241 unformat_ip6_address (unformat_input_t * input, va_list * args)
242 {
243   ip6_address_t *result = va_arg (*args, ip6_address_t *);
244   u16 hex_quads[8];
245   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
246   uword c, n_colon, double_colon_index;
247
248   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
249   double_colon_index = ARRAY_LEN (hex_quads);
250   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
251     {
252       hex_digit = 16;
253       if (c >= '0' && c <= '9')
254         hex_digit = c - '0';
255       else if (c >= 'a' && c <= 'f')
256         hex_digit = c + 10 - 'a';
257       else if (c >= 'A' && c <= 'F')
258         hex_digit = c + 10 - 'A';
259       else if (c == ':' && n_colon < 2)
260         n_colon++;
261       else
262         {
263           unformat_put_input (input);
264           break;
265         }
266
267       /* Too many hex quads. */
268       if (n_hex_quads >= ARRAY_LEN (hex_quads))
269         return 0;
270
271       if (hex_digit < 16)
272         {
273           hex_quad = (hex_quad << 4) | hex_digit;
274
275           /* Hex quad must fit in 16 bits. */
276           if (n_hex_digits >= 4)
277             return 0;
278
279           n_colon = 0;
280           n_hex_digits++;
281         }
282
283       /* Save position of :: */
284       if (n_colon == 2)
285         {
286           /* More than one :: ? */
287           if (double_colon_index < ARRAY_LEN (hex_quads))
288             return 0;
289           double_colon_index = n_hex_quads;
290         }
291
292       if (n_colon > 0 && n_hex_digits > 0)
293         {
294           hex_quads[n_hex_quads++] = hex_quad;
295           hex_quad = 0;
296           n_hex_digits = 0;
297         }
298     }
299
300   if (n_hex_digits > 0)
301     hex_quads[n_hex_quads++] = hex_quad;
302
303   {
304     word i;
305
306     /* Expand :: to appropriate number of zero hex quads. */
307     if (double_colon_index < ARRAY_LEN (hex_quads))
308       {
309         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
310
311         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
312           hex_quads[n_zero + i] = hex_quads[i];
313
314         for (i = 0; i < n_zero; i++)
315           hex_quads[double_colon_index + i] = 0;
316
317         n_hex_quads = ARRAY_LEN (hex_quads);
318       }
319
320     /* Too few hex quads given. */
321     if (n_hex_quads < ARRAY_LEN (hex_quads))
322       return 0;
323
324     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
325       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
326
327     return 1;
328   }
329 }
330
331 uword
332 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
338   foreach_ipsec_policy_action
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 uword
346 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
347 {
348   u32 *r = va_arg (*args, u32 *);
349
350   if (0);
351 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
352   foreach_ipsec_crypto_alg
353 #undef _
354     else
355     return 0;
356   return 1;
357 }
358
359 u8 *
360 format_ipsec_crypto_alg (u8 * s, va_list * args)
361 {
362   u32 i = va_arg (*args, u32);
363   u8 *t = 0;
364
365   switch (i)
366     {
367 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
368       foreach_ipsec_crypto_alg
369 #undef _
370     default:
371       return format (s, "unknown");
372     }
373   return format (s, "%s", t);
374 }
375
376 uword
377 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
383   foreach_ipsec_integ_alg
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 uword
408 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
409 {
410   u32 *r = va_arg (*args, u32 *);
411
412   if (0);
413 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
414   foreach_ikev2_auth_method
415 #undef _
416     else
417     return 0;
418   return 1;
419 }
420
421 uword
422 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
423 {
424   u32 *r = va_arg (*args, u32 *);
425
426   if (0);
427 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
428   foreach_ikev2_id_type
429 #undef _
430     else
431     return 0;
432   return 1;
433 }
434 #else /* VPP_API_TEST_BUILTIN == 1 */
435 static uword
436 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
437 {
438   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
439   vnet_main_t *vnm = vnet_get_main ();
440   u32 *result = va_arg (*args, u32 *);
441   u32 sw_if_index;
442
443   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
444     return 0;
445
446   *result = sw_if_index;
447   return 1;
448 }
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 static uword
452 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
453 {
454   u8 *r = va_arg (*args, u8 *);
455
456   if (unformat (input, "kbps"))
457     *r = SSE2_QOS_RATE_KBPS;
458   else if (unformat (input, "pps"))
459     *r = SSE2_QOS_RATE_PPS;
460   else
461     return 0;
462   return 1;
463 }
464
465 static uword
466 unformat_policer_round_type (unformat_input_t * input, va_list * args)
467 {
468   u8 *r = va_arg (*args, u8 *);
469
470   if (unformat (input, "closest"))
471     *r = SSE2_QOS_ROUND_TO_CLOSEST;
472   else if (unformat (input, "up"))
473     *r = SSE2_QOS_ROUND_TO_UP;
474   else if (unformat (input, "down"))
475     *r = SSE2_QOS_ROUND_TO_DOWN;
476   else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "1r2c"))
487     *r = SSE2_QOS_POLICER_TYPE_1R2C;
488   else if (unformat (input, "1r3c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
490   else if (unformat (input, "2r3c-2698"))
491     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
492   else if (unformat (input, "2r3c-4115"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
494   else if (unformat (input, "2r3c-mef5cf1"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
496   else
497     return 0;
498   return 1;
499 }
500
501 static uword
502 unformat_dscp (unformat_input_t * input, va_list * va)
503 {
504   u8 *r = va_arg (*va, u8 *);
505
506   if (0);
507 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
508   foreach_vnet_dscp
509 #undef _
510     else
511     return 0;
512   return 1;
513 }
514
515 static uword
516 unformat_policer_action_type (unformat_input_t * input, va_list * va)
517 {
518   sse2_qos_pol_action_params_st *a
519     = va_arg (*va, sse2_qos_pol_action_params_st *);
520
521   if (unformat (input, "drop"))
522     a->action_type = SSE2_QOS_ACTION_DROP;
523   else if (unformat (input, "transmit"))
524     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
525   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
526     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
527   else
528     return 0;
529   return 1;
530 }
531
532 static uword
533 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
534 {
535   u32 *r = va_arg (*va, u32 *);
536   u32 tid;
537
538   if (unformat (input, "ip4"))
539     tid = POLICER_CLASSIFY_TABLE_IP4;
540   else if (unformat (input, "ip6"))
541     tid = POLICER_CLASSIFY_TABLE_IP6;
542   else if (unformat (input, "l2"))
543     tid = POLICER_CLASSIFY_TABLE_L2;
544   else
545     return 0;
546
547   *r = tid;
548   return 1;
549 }
550
551 static uword
552 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
553 {
554   u32 *r = va_arg (*va, u32 *);
555   u32 tid;
556
557   if (unformat (input, "ip4"))
558     tid = FLOW_CLASSIFY_TABLE_IP4;
559   else if (unformat (input, "ip6"))
560     tid = FLOW_CLASSIFY_TABLE_IP6;
561   else
562     return 0;
563
564   *r = tid;
565   return 1;
566 }
567
568 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
569 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
570 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
571 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
572
573 #if (VPP_API_TEST_BUILTIN==0)
574 uword
575 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
576 {
577   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
578   mfib_itf_attribute_t attr;
579
580   old = *iflags;
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_long_names[attr]))
584       *iflags |= (1 << attr);
585   }
586   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
587   {
588     if (unformat (input, mfib_itf_flag_names[attr]))
589       *iflags |= (1 << attr);
590   }
591
592   return (old == *iflags ? 0 : 1);
593 }
594
595 uword
596 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
597 {
598   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
599   mfib_entry_attribute_t attr;
600
601   old = *eflags;
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_long_names[attr]))
605       *eflags |= (1 << attr);
606   }
607   FOR_EACH_MFIB_ATTRIBUTE (attr)
608   {
609     if (unformat (input, mfib_flag_names[attr]))
610       *eflags |= (1 << attr);
611   }
612
613   return (old == *eflags ? 0 : 1);
614 }
615
616 u8 *
617 format_ip4_address (u8 * s, va_list * args)
618 {
619   u8 *a = va_arg (*args, u8 *);
620   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
621 }
622
623 u8 *
624 format_ip6_address (u8 * s, va_list * args)
625 {
626   ip6_address_t *a = va_arg (*args, ip6_address_t *);
627   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
628
629   i_max_n_zero = ARRAY_LEN (a->as_u16);
630   max_n_zeros = 0;
631   i_first_zero = i_max_n_zero;
632   n_zeros = 0;
633   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
634     {
635       u32 is_zero = a->as_u16[i] == 0;
636       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
637         {
638           i_first_zero = i;
639           n_zeros = 0;
640         }
641       n_zeros += is_zero;
642       if ((!is_zero && n_zeros > max_n_zeros)
643           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
644         {
645           i_max_n_zero = i_first_zero;
646           max_n_zeros = n_zeros;
647           i_first_zero = ARRAY_LEN (a->as_u16);
648           n_zeros = 0;
649         }
650     }
651
652   last_double_colon = 0;
653   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
654     {
655       if (i == i_max_n_zero && max_n_zeros > 1)
656         {
657           s = format (s, "::");
658           i += max_n_zeros - 1;
659           last_double_colon = 1;
660         }
661       else
662         {
663           s = format (s, "%s%x",
664                       (last_double_colon || i == 0) ? "" : ":",
665                       clib_net_to_host_u16 (a->as_u16[i]));
666           last_double_colon = 0;
667         }
668     }
669
670   return s;
671 }
672
673 /* Format an IP46 address. */
674 u8 *
675 format_ip46_address (u8 * s, va_list * args)
676 {
677   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
678   ip46_type_t type = va_arg (*args, ip46_type_t);
679   int is_ip4 = 1;
680
681   switch (type)
682     {
683     case IP46_TYPE_ANY:
684       is_ip4 = ip46_address_is_ip4 (ip46);
685       break;
686     case IP46_TYPE_IP4:
687       is_ip4 = 1;
688       break;
689     case IP46_TYPE_IP6:
690       is_ip4 = 0;
691       break;
692     }
693
694   return is_ip4 ?
695     format (s, "%U", format_ip4_address, &ip46->ip4) :
696     format (s, "%U", format_ip6_address, &ip46->ip6);
697 }
698
699 u8 *
700 format_ethernet_address (u8 * s, va_list * args)
701 {
702   u8 *a = va_arg (*args, u8 *);
703
704   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
705                  a[0], a[1], a[2], a[3], a[4], a[5]);
706 }
707 #endif
708
709 static void
710 increment_v4_address (ip4_address_t * a)
711 {
712   u32 v;
713
714   v = ntohl (a->as_u32) + 1;
715   a->as_u32 = ntohl (v);
716 }
717
718 static void
719 increment_v6_address (ip6_address_t * a)
720 {
721   u64 v0, v1;
722
723   v0 = clib_net_to_host_u64 (a->as_u64[0]);
724   v1 = clib_net_to_host_u64 (a->as_u64[1]);
725
726   v1 += 1;
727   if (v1 == 0)
728     v0 += 1;
729   a->as_u64[0] = clib_net_to_host_u64 (v0);
730   a->as_u64[1] = clib_net_to_host_u64 (v1);
731 }
732
733 static void
734 increment_mac_address (u8 * mac)
735 {
736   u64 tmp = *((u64 *) mac);
737   tmp = clib_net_to_host_u64 (tmp);
738   tmp += 1 << 16;               /* skip unused (least significant) octets */
739   tmp = clib_host_to_net_u64 (tmp);
740
741   clib_memcpy (mac, &tmp, 6);
742 }
743
744 static void vl_api_create_loopback_reply_t_handler
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   i32 retval = ntohl (mp->retval);
749
750   vam->retval = retval;
751   vam->regenerate_interface_table = 1;
752   vam->sw_if_index = ntohl (mp->sw_if_index);
753   vam->result_ready = 1;
754 }
755
756 static void vl_api_create_loopback_reply_t_handler_json
757   (vl_api_create_loopback_reply_t * mp)
758 {
759   vat_main_t *vam = &vat_main;
760   vat_json_node_t node;
761
762   vat_json_init_object (&node);
763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
765
766   vat_json_print (vam->ofp, &node);
767   vat_json_free (&node);
768   vam->retval = ntohl (mp->retval);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   i32 retval = ntohl (mp->retval);
777
778   vam->retval = retval;
779   vam->regenerate_interface_table = 1;
780   vam->sw_if_index = ntohl (mp->sw_if_index);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_loopback_instance_reply_t_handler_json
785   (vl_api_create_loopback_instance_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   vat_json_node_t node;
789
790   vat_json_init_object (&node);
791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
792   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
793
794   vat_json_print (vam->ofp, &node);
795   vat_json_free (&node);
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler
801   (vl_api_af_packet_create_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->sw_if_index = ntohl (mp->sw_if_index);
809   vam->result_ready = 1;
810 }
811
812 static void vl_api_af_packet_create_reply_t_handler_json
813   (vl_api_af_packet_create_reply_t * mp)
814 {
815   vat_main_t *vam = &vat_main;
816   vat_json_node_t node;
817
818   vat_json_init_object (&node);
819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
821
822   vat_json_print (vam->ofp, &node);
823   vat_json_free (&node);
824
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_vlan_subif_reply_t_handler_json
842   (vl_api_create_vlan_subif_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_subif_reply_t_handler_json
871   (vl_api_create_subif_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_interface_name_renumber_reply_t_handler
888   (vl_api_interface_name_renumber_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_interface_name_renumber_reply_t_handler_json
899   (vl_api_interface_name_renumber_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 /*
915  * Special-case: build the interface table, maintain
916  * the next loopback sw_if_index vbl.
917  */
918 static void vl_api_sw_interface_details_t_handler
919   (vl_api_sw_interface_details_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   u8 *s = format (0, "%s%c", mp->interface_name, 0);
923
924   hash_set_mem (vam->sw_if_index_by_interface_name, s,
925                 ntohl (mp->sw_if_index));
926
927   /* In sub interface case, fill the sub interface table entry */
928   if (mp->sw_if_index != mp->sup_sw_if_index)
929     {
930       sw_interface_subif_t *sub = NULL;
931
932       vec_add2 (vam->sw_if_subif_table, sub, 1);
933
934       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
935       strncpy ((char *) sub->interface_name, (char *) s,
936                vec_len (sub->interface_name));
937       sub->sw_if_index = ntohl (mp->sw_if_index);
938       sub->sub_id = ntohl (mp->sub_id);
939
940       sub->sub_dot1ad = mp->sub_dot1ad;
941       sub->sub_number_of_tags = mp->sub_number_of_tags;
942       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
943       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
944       sub->sub_exact_match = mp->sub_exact_match;
945       sub->sub_default = mp->sub_default;
946       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
947       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
948
949       /* vlan tag rewrite */
950       sub->vtr_op = ntohl (mp->vtr_op);
951       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
952       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
953       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
954     }
955 }
956
957 static void vl_api_sw_interface_details_t_handler_json
958   (vl_api_sw_interface_details_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   vat_json_node_t *node = NULL;
962
963   if (VAT_JSON_ARRAY != vam->json_tree.type)
964     {
965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
966       vat_json_init_array (&vam->json_tree);
967     }
968   node = vat_json_array_add (&vam->json_tree);
969
970   vat_json_init_object (node);
971   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
972   vat_json_object_add_uint (node, "sup_sw_if_index",
973                             ntohl (mp->sup_sw_if_index));
974   vat_json_object_add_uint (node, "l2_address_length",
975                             ntohl (mp->l2_address_length));
976   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
977                              sizeof (mp->l2_address));
978   vat_json_object_add_string_copy (node, "interface_name",
979                                    mp->interface_name);
980   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
981   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
982   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
983   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
984   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
985   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
986   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
987   vat_json_object_add_uint (node, "sub_number_of_tags",
988                             mp->sub_number_of_tags);
989   vat_json_object_add_uint (node, "sub_outer_vlan_id",
990                             ntohs (mp->sub_outer_vlan_id));
991   vat_json_object_add_uint (node, "sub_inner_vlan_id",
992                             ntohs (mp->sub_inner_vlan_id));
993   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
994   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
995   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
996                             mp->sub_outer_vlan_id_any);
997   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
998                             mp->sub_inner_vlan_id_any);
999   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1000   vat_json_object_add_uint (node, "vtr_push_dot1q",
1001                             ntohl (mp->vtr_push_dot1q));
1002   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1003   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1004   if (mp->sub_dot1ah)
1005     {
1006       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1007                                        format (0, "%U",
1008                                                format_ethernet_address,
1009                                                &mp->b_dmac));
1010       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1011                                        format (0, "%U",
1012                                                format_ethernet_address,
1013                                                &mp->b_smac));
1014       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1015       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1016     }
1017 }
1018
1019 #if VPP_API_TEST_BUILTIN == 0
1020 static void vl_api_sw_interface_event_t_handler
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   if (vam->interface_event_display)
1025     errmsg ("interface flags: sw_if_index %d %s %s",
1026             ntohl (mp->sw_if_index),
1027             mp->admin_up_down ? "admin-up" : "admin-down",
1028             mp->link_up_down ? "link-up" : "link-down");
1029 }
1030 #endif
1031
1032 static void vl_api_sw_interface_event_t_handler_json
1033   (vl_api_sw_interface_event_t * mp)
1034 {
1035   /* JSON output not supported */
1036 }
1037
1038 static void
1039 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1040 {
1041   vat_main_t *vam = &vat_main;
1042   i32 retval = ntohl (mp->retval);
1043
1044   vam->retval = retval;
1045   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1046   vam->result_ready = 1;
1047 }
1048
1049 static void
1050 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1051 {
1052   vat_main_t *vam = &vat_main;
1053   vat_json_node_t node;
1054   api_main_t *am = &api_main;
1055   void *oldheap;
1056   u8 *reply;
1057
1058   vat_json_init_object (&node);
1059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1060   vat_json_object_add_uint (&node, "reply_in_shmem",
1061                             ntohl (mp->reply_in_shmem));
1062   /* Toss the shared-memory original... */
1063   pthread_mutex_lock (&am->vlib_rp->mutex);
1064   oldheap = svm_push_data_heap (am->vlib_rp);
1065
1066   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1067   vec_free (reply);
1068
1069   svm_pop_heap (oldheap);
1070   pthread_mutex_unlock (&am->vlib_rp->mutex);
1071
1072   vat_json_print (vam->ofp, &node);
1073   vat_json_free (&node);
1074
1075   vam->retval = ntohl (mp->retval);
1076   vam->result_ready = 1;
1077 }
1078
1079 static void
1080 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   i32 retval = ntohl (mp->retval);
1084   u32 length = ntohl (mp->length);
1085
1086   vec_reset_length (vam->cmd_reply);
1087
1088   vam->retval = retval;
1089   if (retval == 0)
1090     {
1091       vec_validate (vam->cmd_reply, length);
1092       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1093       vam->cmd_reply[length] = 0;
1094     }
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103
1104   vec_reset_length (vam->cmd_reply);
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_classify_add_del_table_reply_t_handler
1118   (vl_api_classify_add_del_table_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0 &&
1130           ((mp->new_table_index != 0xFFFFFFFF) ||
1131            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1132            (mp->match_n_vectors != 0xFFFFFFFF)))
1133         /*
1134          * Note: this is just barely thread-safe, depends on
1135          * the main thread spinning waiting for an answer...
1136          */
1137         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1138                 ntohl (mp->new_table_index),
1139                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1140       vam->result_ready = 1;
1141     }
1142 }
1143
1144 static void vl_api_classify_add_del_table_reply_t_handler_json
1145   (vl_api_classify_add_del_table_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vat_json_init_object (&node);
1151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1152   vat_json_object_add_uint (&node, "new_table_index",
1153                             ntohl (mp->new_table_index));
1154   vat_json_object_add_uint (&node, "skip_n_vectors",
1155                             ntohl (mp->skip_n_vectors));
1156   vat_json_object_add_uint (&node, "match_n_vectors",
1157                             ntohl (mp->match_n_vectors));
1158
1159   vat_json_print (vam->ofp, &node);
1160   vat_json_free (&node);
1161
1162   vam->retval = ntohl (mp->retval);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void vl_api_get_node_index_reply_t_handler
1167   (vl_api_get_node_index_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   i32 retval = ntohl (mp->retval);
1171   if (vam->async_mode)
1172     {
1173       vam->async_errors += (retval < 0);
1174     }
1175   else
1176     {
1177       vam->retval = retval;
1178       if (retval == 0)
1179         errmsg ("node index %d", ntohl (mp->node_index));
1180       vam->result_ready = 1;
1181     }
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler_json
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   vat_json_node_t node;
1189
1190   vat_json_init_object (&node);
1191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1192   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1193
1194   vat_json_print (vam->ofp, &node);
1195   vat_json_free (&node);
1196
1197   vam->retval = ntohl (mp->retval);
1198   vam->result_ready = 1;
1199 }
1200
1201 static void vl_api_get_next_index_reply_t_handler
1202   (vl_api_get_next_index_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   i32 retval = ntohl (mp->retval);
1206   if (vam->async_mode)
1207     {
1208       vam->async_errors += (retval < 0);
1209     }
1210   else
1211     {
1212       vam->retval = retval;
1213       if (retval == 0)
1214         errmsg ("next node index %d", ntohl (mp->next_index));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler_json
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1228
1229   vat_json_print (vam->ofp, &node);
1230   vat_json_free (&node);
1231
1232   vam->retval = ntohl (mp->retval);
1233   vam->result_ready = 1;
1234 }
1235
1236 static void vl_api_add_node_next_reply_t_handler
1237   (vl_api_add_node_next_reply_t * mp)
1238 {
1239   vat_main_t *vam = &vat_main;
1240   i32 retval = ntohl (mp->retval);
1241   if (vam->async_mode)
1242     {
1243       vam->async_errors += (retval < 0);
1244     }
1245   else
1246     {
1247       vam->retval = retval;
1248       if (retval == 0)
1249         errmsg ("next index %d", ntohl (mp->next_index));
1250       vam->result_ready = 1;
1251     }
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler_json
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   vat_json_node_t node;
1259
1260   vat_json_init_object (&node);
1261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1262   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1263
1264   vat_json_print (vam->ofp, &node);
1265   vat_json_free (&node);
1266
1267   vam->retval = ntohl (mp->retval);
1268   vam->result_ready = 1;
1269 }
1270
1271 static void vl_api_show_version_reply_t_handler
1272   (vl_api_show_version_reply_t * mp)
1273 {
1274   vat_main_t *vam = &vat_main;
1275   i32 retval = ntohl (mp->retval);
1276
1277   if (retval >= 0)
1278     {
1279       errmsg ("        program: %s", mp->program);
1280       errmsg ("        version: %s", mp->version);
1281       errmsg ("     build date: %s", mp->build_date);
1282       errmsg ("build directory: %s", mp->build_directory);
1283     }
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_show_version_reply_t_handler_json
1289   (vl_api_show_version_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   vat_json_node_t node;
1293
1294   vat_json_init_object (&node);
1295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1296   vat_json_object_add_string_copy (&node, "program", mp->program);
1297   vat_json_object_add_string_copy (&node, "version", mp->version);
1298   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1299   vat_json_object_add_string_copy (&node, "build_directory",
1300                                    mp->build_directory);
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void
1310 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1311 {
1312   u32 sw_if_index = ntohl (mp->sw_if_index);
1313   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1314           mp->mac_ip ? "mac/ip binding" : "address resolution",
1315           ntohl (mp->pid), format_ip4_address, &mp->address,
1316           format_ethernet_address, mp->new_mac, sw_if_index);
1317 }
1318
1319 static void
1320 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1321 {
1322   /* JSON output not supported */
1323 }
1324
1325 static void
1326 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1327 {
1328   u32 sw_if_index = ntohl (mp->sw_if_index);
1329   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1330           mp->mac_ip ? "mac/ip binding" : "address resolution",
1331           ntohl (mp->pid), format_ip6_address, mp->address,
1332           format_ethernet_address, mp->new_mac, sw_if_index);
1333 }
1334
1335 static void
1336 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1337 {
1338   /* JSON output not supported */
1339 }
1340
1341 static void
1342 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1343 {
1344   u32 n_macs = ntohl (mp->n_macs);
1345   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1346           ntohl (mp->pid), mp->client_index, n_macs);
1347   int i;
1348   for (i = 0; i < n_macs; i++)
1349     {
1350       vl_api_mac_entry_t *mac = &mp->mac[i];
1351       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->is_del);
1354       if (i == 1000)
1355         break;
1356     }
1357 }
1358
1359 static void
1360 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1361 {
1362   /* JSON output not supported */
1363 }
1364
1365 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1366 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1367
1368 /*
1369  * Special-case: build the bridge domain table, maintain
1370  * the next bd id vbl.
1371  */
1372 static void vl_api_bridge_domain_details_t_handler
1373   (vl_api_bridge_domain_details_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1377   int i;
1378
1379   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1380          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1381
1382   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1383          ntohl (mp->bd_id), mp->learn, mp->forward,
1384          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1385
1386   if (n_sw_ifs)
1387     {
1388       vl_api_bridge_domain_sw_if_t *sw_ifs;
1389       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1390              "Interface Name");
1391
1392       sw_ifs = mp->sw_if_details;
1393       for (i = 0; i < n_sw_ifs; i++)
1394         {
1395           u8 *sw_if_name = 0;
1396           u32 sw_if_index;
1397           hash_pair_t *p;
1398
1399           sw_if_index = ntohl (sw_ifs->sw_if_index);
1400
1401           /* *INDENT-OFF* */
1402           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1403                              ({
1404                                if ((u32) p->value[0] == sw_if_index)
1405                                  {
1406                                    sw_if_name = (u8 *)(p->key);
1407                                    break;
1408                                  }
1409                              }));
1410           /* *INDENT-ON* */
1411           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1412                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1413                  "sw_if_index not found!");
1414
1415           sw_ifs++;
1416         }
1417     }
1418 }
1419
1420 static void vl_api_bridge_domain_details_t_handler_json
1421   (vl_api_bridge_domain_details_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   vat_json_node_t *node, *array = NULL;
1425   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1426
1427   if (VAT_JSON_ARRAY != vam->json_tree.type)
1428     {
1429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1430       vat_json_init_array (&vam->json_tree);
1431     }
1432   node = vat_json_array_add (&vam->json_tree);
1433
1434   vat_json_init_object (node);
1435   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1436   vat_json_object_add_uint (node, "flood", mp->flood);
1437   vat_json_object_add_uint (node, "forward", mp->forward);
1438   vat_json_object_add_uint (node, "learn", mp->learn);
1439   vat_json_object_add_uint (node, "bvi_sw_if_index",
1440                             ntohl (mp->bvi_sw_if_index));
1441   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1442   array = vat_json_object_add (node, "sw_if");
1443   vat_json_init_array (array);
1444
1445
1446
1447   if (n_sw_ifs)
1448     {
1449       vl_api_bridge_domain_sw_if_t *sw_ifs;
1450       int i;
1451
1452       sw_ifs = mp->sw_if_details;
1453       for (i = 0; i < n_sw_ifs; i++)
1454         {
1455           node = vat_json_array_add (array);
1456           vat_json_init_object (node);
1457           vat_json_object_add_uint (node, "sw_if_index",
1458                                     ntohl (sw_ifs->sw_if_index));
1459           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1460           sw_ifs++;
1461         }
1462     }
1463 }
1464
1465 static void vl_api_control_ping_reply_t_handler
1466   (vl_api_control_ping_reply_t * mp)
1467 {
1468   vat_main_t *vam = &vat_main;
1469   i32 retval = ntohl (mp->retval);
1470   if (vam->async_mode)
1471     {
1472       vam->async_errors += (retval < 0);
1473     }
1474   else
1475     {
1476       vam->retval = retval;
1477       vam->result_ready = 1;
1478     }
1479   if (vam->socket_client_main)
1480     vam->socket_client_main->control_pings_outstanding--;
1481 }
1482
1483 static void vl_api_control_ping_reply_t_handler_json
1484   (vl_api_control_ping_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488
1489   if (VAT_JSON_NONE != vam->json_tree.type)
1490     {
1491       vat_json_print (vam->ofp, &vam->json_tree);
1492       vat_json_free (&vam->json_tree);
1493       vam->json_tree.type = VAT_JSON_NONE;
1494     }
1495   else
1496     {
1497       /* just print [] */
1498       vat_json_init_array (&vam->json_tree);
1499       vat_json_print (vam->ofp, &vam->json_tree);
1500       vam->json_tree.type = VAT_JSON_NONE;
1501     }
1502
1503   vam->retval = retval;
1504   vam->result_ready = 1;
1505 }
1506
1507 static void
1508   vl_api_bridge_domain_set_mac_age_reply_t_handler
1509   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1525   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void
1541 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2_flags_reply_t_handler_json
1557   (vl_api_l2_flags_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1565                             ntohl (mp->resulting_feature_bitmap));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_bridge_flags_reply_t_handler
1575   (vl_api_bridge_flags_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_bridge_flags_reply_t_handler_json
1591   (vl_api_bridge_flags_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1599                             ntohl (mp->resulting_feature_bitmap));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_tap_connect_reply_t_handler
1609   (vl_api_tap_connect_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623
1624 }
1625
1626 static void vl_api_tap_connect_reply_t_handler_json
1627   (vl_api_tap_connect_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641
1642 }
1643
1644 static void
1645 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_tap_modify_reply_t_handler_json
1662   (vl_api_tap_modify_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void
1679 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   i32 retval = ntohl (mp->retval);
1683   if (vam->async_mode)
1684     {
1685       vam->async_errors += (retval < 0);
1686     }
1687   else
1688     {
1689       vam->retval = retval;
1690       vam->result_ready = 1;
1691     }
1692 }
1693
1694 static void vl_api_tap_delete_reply_t_handler_json
1695   (vl_api_tap_delete_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   vat_json_node_t node;
1699
1700   vat_json_init_object (&node);
1701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void
1711 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   i32 retval = ntohl (mp->retval);
1715   if (vam->async_mode)
1716     {
1717       vam->async_errors += (retval < 0);
1718     }
1719   else
1720     {
1721       vam->retval = retval;
1722       vam->sw_if_index = ntohl (mp->sw_if_index);
1723       vam->result_ready = 1;
1724     }
1725
1726 }
1727
1728 static void vl_api_tap_create_v2_reply_t_handler_json
1729   (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   vat_json_node_t node;
1733
1734   vat_json_init_object (&node);
1735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1736   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1737
1738   vat_json_print (vam->ofp, &node);
1739   vat_json_free (&node);
1740
1741   vam->retval = ntohl (mp->retval);
1742   vam->result_ready = 1;
1743
1744 }
1745
1746 static void
1747 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   i32 retval = ntohl (mp->retval);
1751   if (vam->async_mode)
1752     {
1753       vam->async_errors += (retval < 0);
1754     }
1755   else
1756     {
1757       vam->retval = retval;
1758       vam->result_ready = 1;
1759     }
1760 }
1761
1762 static void vl_api_tap_delete_v2_reply_t_handler_json
1763   (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   vat_json_node_t node;
1767
1768   vat_json_init_object (&node);
1769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1770
1771   vat_json_print (vam->ofp, &node);
1772   vat_json_free (&node);
1773
1774   vam->retval = ntohl (mp->retval);
1775   vam->result_ready = 1;
1776 }
1777
1778 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1779   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   i32 retval = ntohl (mp->retval);
1783   if (vam->async_mode)
1784     {
1785       vam->async_errors += (retval < 0);
1786     }
1787   else
1788     {
1789       vam->retval = retval;
1790       vam->result_ready = 1;
1791     }
1792 }
1793
1794 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1795   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   vat_json_node_t node;
1799
1800   vat_json_init_object (&node);
1801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1802   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1803                             ntohl (mp->sw_if_index));
1804
1805   vat_json_print (vam->ofp, &node);
1806   vat_json_free (&node);
1807
1808   vam->retval = ntohl (mp->retval);
1809   vam->result_ready = 1;
1810 }
1811
1812 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1813   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   i32 retval = ntohl (mp->retval);
1817   if (vam->async_mode)
1818     {
1819       vam->async_errors += (retval < 0);
1820     }
1821   else
1822     {
1823       vam->retval = retval;
1824       vam->sw_if_index = ntohl (mp->sw_if_index);
1825       vam->result_ready = 1;
1826     }
1827 }
1828
1829 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1830   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   vat_json_node_t node;
1834
1835   vat_json_init_object (&node);
1836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1838
1839   vat_json_print (vam->ofp, &node);
1840   vat_json_free (&node);
1841
1842   vam->retval = ntohl (mp->retval);
1843   vam->result_ready = 1;
1844 }
1845
1846 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1847   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1863   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870   vat_json_object_add_uint (&node, "fwd_entry_index",
1871                             clib_net_to_host_u32 (mp->fwd_entry_index));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 u8 *
1881 format_lisp_transport_protocol (u8 * s, va_list * args)
1882 {
1883   u32 proto = va_arg (*args, u32);
1884
1885   switch (proto)
1886     {
1887     case 1:
1888       return format (s, "udp");
1889     case 2:
1890       return format (s, "api");
1891     default:
1892       return 0;
1893     }
1894   return 0;
1895 }
1896
1897 static void vl_api_one_get_transport_protocol_reply_t_handler
1898   (vl_api_one_get_transport_protocol_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       u32 proto = mp->protocol;
1909       print (vam->ofp, "Transport protocol: %U",
1910              format_lisp_transport_protocol, proto);
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1917   (vl_api_one_get_transport_protocol_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921   u8 *s;
1922
1923   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1924   vec_add1 (s, 0);
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1929
1930   vec_free (s);
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void vl_api_one_add_del_locator_set_reply_t_handler
1939   (vl_api_one_add_del_locator_set_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1955   (vl_api_one_add_del_locator_set_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1972   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->sw_if_index = ntohl (mp->sw_if_index);
1984       vam->result_ready = 1;
1985     }
1986   vam->regenerate_interface_table = 1;
1987 }
1988
1989 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1990   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2007   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   i32 retval = ntohl (mp->retval);
2011   if (vam->async_mode)
2012     {
2013       vam->async_errors += (retval < 0);
2014     }
2015   else
2016     {
2017       vam->retval = retval;
2018       vam->sw_if_index = ntohl (mp->sw_if_index);
2019       vam->result_ready = 1;
2020     }
2021 }
2022
2023 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2024   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t node;
2028
2029   vat_json_init_object (&node);
2030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2031   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2032
2033   vat_json_print (vam->ofp, &node);
2034   vat_json_free (&node);
2035
2036   vam->retval = ntohl (mp->retval);
2037   vam->result_ready = 1;
2038 }
2039
2040 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2041   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044   i32 retval = ntohl (mp->retval);
2045   if (vam->async_mode)
2046     {
2047       vam->async_errors += (retval < 0);
2048     }
2049   else
2050     {
2051       vam->retval = retval;
2052       vam->sw_if_index = ntohl (mp->sw_if_index);
2053       vam->result_ready = 1;
2054     }
2055   vam->regenerate_interface_table = 1;
2056 }
2057
2058 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2059   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2060 {
2061   vat_main_t *vam = &vat_main;
2062   vat_json_node_t node;
2063
2064   vat_json_init_object (&node);
2065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2066   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2067
2068   vat_json_print (vam->ofp, &node);
2069   vat_json_free (&node);
2070
2071   vam->retval = ntohl (mp->retval);
2072   vam->result_ready = 1;
2073 }
2074
2075 static void vl_api_gre_add_del_tunnel_reply_t_handler
2076   (vl_api_gre_add_del_tunnel_reply_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   i32 retval = ntohl (mp->retval);
2080   if (vam->async_mode)
2081     {
2082       vam->async_errors += (retval < 0);
2083     }
2084   else
2085     {
2086       vam->retval = retval;
2087       vam->sw_if_index = ntohl (mp->sw_if_index);
2088       vam->result_ready = 1;
2089     }
2090 }
2091
2092 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2093   (vl_api_gre_add_del_tunnel_reply_t * mp)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   vat_json_node_t node;
2097
2098   vat_json_init_object (&node);
2099   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2100   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2101
2102   vat_json_print (vam->ofp, &node);
2103   vat_json_free (&node);
2104
2105   vam->retval = ntohl (mp->retval);
2106   vam->result_ready = 1;
2107 }
2108
2109 static void vl_api_create_vhost_user_if_reply_t_handler
2110   (vl_api_create_vhost_user_if_reply_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113   i32 retval = ntohl (mp->retval);
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->sw_if_index = ntohl (mp->sw_if_index);
2122       vam->result_ready = 1;
2123     }
2124   vam->regenerate_interface_table = 1;
2125 }
2126
2127 static void vl_api_create_vhost_user_if_reply_t_handler_json
2128   (vl_api_create_vhost_user_if_reply_t * mp)
2129 {
2130   vat_main_t *vam = &vat_main;
2131   vat_json_node_t node;
2132
2133   vat_json_init_object (&node);
2134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2135   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2136
2137   vat_json_print (vam->ofp, &node);
2138   vat_json_free (&node);
2139
2140   vam->retval = ntohl (mp->retval);
2141   vam->result_ready = 1;
2142 }
2143
2144 static clib_error_t *
2145 receive_fd_msg (int socket_fd, int *my_fd)
2146 {
2147   char msgbuf[16];
2148   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2149   struct msghdr mh = { 0 };
2150   struct iovec iov[1];
2151   ssize_t size;
2152   struct ucred *cr = 0;
2153   struct cmsghdr *cmsg;
2154   pid_t pid __attribute__ ((unused));
2155   uid_t uid __attribute__ ((unused));
2156   gid_t gid __attribute__ ((unused));
2157
2158   iov[0].iov_base = msgbuf;
2159   iov[0].iov_len = 5;
2160   mh.msg_iov = iov;
2161   mh.msg_iovlen = 1;
2162   mh.msg_control = ctl;
2163   mh.msg_controllen = sizeof (ctl);
2164
2165   memset (ctl, 0, sizeof (ctl));
2166
2167   /* receive the incoming message */
2168   size = recvmsg (socket_fd, &mh, 0);
2169   if (size != 5)
2170     {
2171       return (size == 0) ? clib_error_return (0, "disconnected") :
2172         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2173                                 socket_fd);
2174     }
2175
2176   cmsg = CMSG_FIRSTHDR (&mh);
2177   while (cmsg)
2178     {
2179       if (cmsg->cmsg_level == SOL_SOCKET)
2180         {
2181           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2182             {
2183               cr = (struct ucred *) CMSG_DATA (cmsg);
2184               uid = cr->uid;
2185               gid = cr->gid;
2186               pid = cr->pid;
2187             }
2188           else if (cmsg->cmsg_type == SCM_RIGHTS)
2189             {
2190               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2191             }
2192         }
2193       cmsg = CMSG_NXTHDR (&mh, cmsg);
2194     }
2195   return 0;
2196 }
2197
2198 static void vl_api_memfd_segment_create_reply_t_handler
2199   (vl_api_memfd_segment_create_reply_t * mp)
2200 {
2201   /* Dont bother in the builtin version */
2202 #if VPP_API_TEST_BUILTIN == 0
2203   vat_main_t *vam = &vat_main;
2204   api_main_t *am = &api_main;
2205   socket_client_main_t *scm = vam->socket_client_main;
2206   int my_fd = -1;
2207   clib_error_t *error;
2208   ssvm_private_t memfd;
2209   i32 retval = ntohl (mp->retval);
2210
2211   if (retval == 0)
2212     {
2213       error = receive_fd_msg (scm->socket_fd, &my_fd);
2214       if (error)
2215         {
2216           retval = -99;
2217           goto out;
2218         }
2219
2220       memset (&memfd, 0, sizeof (memfd));
2221       memfd.fd = my_fd;
2222
2223       vam->client_index_invalid = 1;
2224
2225       /* Note: this closes memfd.fd */
2226       retval = ssvm_slave_init_memfd (&memfd);
2227       if (retval)
2228         clib_warning ("WARNING: segment map returned %d", retval);
2229
2230       /* Pivot to the memory client segment that vpp just created */
2231
2232       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2233
2234       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2235
2236       vl_client_install_client_message_handlers ();
2237
2238       vl_client_connect_to_vlib_no_map ("pvt",
2239                                         "vpp_api_test(p)",
2240                                         32 /* input_queue_length */ );
2241       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2242
2243       vl_socket_client_enable_disable (0 /* disable socket */ );
2244     }
2245
2246 out:
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->result_ready = 1;
2255     }
2256 #endif
2257 }
2258
2259 static void vl_api_memfd_segment_create_reply_t_handler_json
2260   (vl_api_memfd_segment_create_reply_t * mp)
2261 {
2262   clib_warning ("no");
2263 }
2264
2265 static void vl_api_dns_resolve_name_reply_t_handler
2266   (vl_api_dns_resolve_name_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   i32 retval = ntohl (mp->retval);
2270   if (vam->async_mode)
2271     {
2272       vam->async_errors += (retval < 0);
2273     }
2274   else
2275     {
2276       vam->retval = retval;
2277       vam->result_ready = 1;
2278
2279       if (retval == 0)
2280         {
2281           if (mp->ip4_set)
2282             clib_warning ("ip4 address %U", format_ip4_address,
2283                           (ip4_address_t *) mp->ip4_address);
2284           if (mp->ip6_set)
2285             clib_warning ("ip6 address %U", format_ip6_address,
2286                           (ip6_address_t *) mp->ip6_address);
2287         }
2288       else
2289         clib_warning ("retval %d", retval);
2290     }
2291 }
2292
2293 static void vl_api_dns_resolve_name_reply_t_handler_json
2294   (vl_api_dns_resolve_name_reply_t * mp)
2295 {
2296   clib_warning ("not implemented");
2297 }
2298
2299 static void vl_api_dns_resolve_ip_reply_t_handler
2300   (vl_api_dns_resolve_ip_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312
2313       if (retval == 0)
2314         {
2315           clib_warning ("canonical name %s", mp->name);
2316         }
2317       else
2318         clib_warning ("retval %d", retval);
2319     }
2320 }
2321
2322 static void vl_api_dns_resolve_ip_reply_t_handler_json
2323   (vl_api_dns_resolve_ip_reply_t * mp)
2324 {
2325   clib_warning ("not implemented");
2326 }
2327
2328
2329 static void vl_api_ip_address_details_t_handler
2330   (vl_api_ip_address_details_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   static ip_address_details_t empty_ip_address_details = { {0} };
2334   ip_address_details_t *address = NULL;
2335   ip_details_t *current_ip_details = NULL;
2336   ip_details_t *details = NULL;
2337
2338   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2339
2340   if (!details || vam->current_sw_if_index >= vec_len (details)
2341       || !details[vam->current_sw_if_index].present)
2342     {
2343       errmsg ("ip address details arrived but not stored");
2344       errmsg ("ip_dump should be called first");
2345       return;
2346     }
2347
2348   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2349
2350 #define addresses (current_ip_details->addr)
2351
2352   vec_validate_init_empty (addresses, vec_len (addresses),
2353                            empty_ip_address_details);
2354
2355   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2356
2357   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2358   address->prefix_length = mp->prefix_length;
2359 #undef addresses
2360 }
2361
2362 static void vl_api_ip_address_details_t_handler_json
2363   (vl_api_ip_address_details_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t *node = NULL;
2367   struct in6_addr ip6;
2368   struct in_addr ip4;
2369
2370   if (VAT_JSON_ARRAY != vam->json_tree.type)
2371     {
2372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2373       vat_json_init_array (&vam->json_tree);
2374     }
2375   node = vat_json_array_add (&vam->json_tree);
2376
2377   vat_json_init_object (node);
2378   if (vam->is_ipv6)
2379     {
2380       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2381       vat_json_object_add_ip6 (node, "ip", ip6);
2382     }
2383   else
2384     {
2385       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2386       vat_json_object_add_ip4 (node, "ip", ip4);
2387     }
2388   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2389 }
2390
2391 static void
2392 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   static ip_details_t empty_ip_details = { 0 };
2396   ip_details_t *ip = NULL;
2397   u32 sw_if_index = ~0;
2398
2399   sw_if_index = ntohl (mp->sw_if_index);
2400
2401   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2402                            sw_if_index, empty_ip_details);
2403
2404   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2405                          sw_if_index);
2406
2407   ip->present = 1;
2408 }
2409
2410 static void
2411 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2412 {
2413   vat_main_t *vam = &vat_main;
2414
2415   if (VAT_JSON_ARRAY != vam->json_tree.type)
2416     {
2417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418       vat_json_init_array (&vam->json_tree);
2419     }
2420   vat_json_array_add_uint (&vam->json_tree,
2421                            clib_net_to_host_u32 (mp->sw_if_index));
2422 }
2423
2424 static void vl_api_map_domain_details_t_handler_json
2425   (vl_api_map_domain_details_t * mp)
2426 {
2427   vat_json_node_t *node = NULL;
2428   vat_main_t *vam = &vat_main;
2429   struct in6_addr ip6;
2430   struct in_addr ip4;
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437
2438   node = vat_json_array_add (&vam->json_tree);
2439   vat_json_init_object (node);
2440
2441   vat_json_object_add_uint (node, "domain_index",
2442                             clib_net_to_host_u32 (mp->domain_index));
2443   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2444   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2445   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2446   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2447   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2448   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2449   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2450   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2451   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2452   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2453   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2454   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2455   vat_json_object_add_uint (node, "flags", mp->flags);
2456   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2457   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2458 }
2459
2460 static void vl_api_map_domain_details_t_handler
2461   (vl_api_map_domain_details_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464
2465   if (mp->is_translation)
2466     {
2467       print (vam->ofp,
2468              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2469              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2470              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2471              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2472              clib_net_to_host_u32 (mp->domain_index));
2473     }
2474   else
2475     {
2476       print (vam->ofp,
2477              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2478              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2479              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2480              format_ip6_address, mp->ip6_src,
2481              clib_net_to_host_u32 (mp->domain_index));
2482     }
2483   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2484          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2485          mp->is_translation ? "map-t" : "");
2486 }
2487
2488 static void vl_api_map_rule_details_t_handler_json
2489   (vl_api_map_rule_details_t * mp)
2490 {
2491   struct in6_addr ip6;
2492   vat_json_node_t *node = NULL;
2493   vat_main_t *vam = &vat_main;
2494
2495   if (VAT_JSON_ARRAY != vam->json_tree.type)
2496     {
2497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2498       vat_json_init_array (&vam->json_tree);
2499     }
2500
2501   node = vat_json_array_add (&vam->json_tree);
2502   vat_json_init_object (node);
2503
2504   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2505   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2506   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2507 }
2508
2509 static void
2510 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2514          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2515 }
2516
2517 static void
2518 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2519 {
2520   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2521           "router_addr %U host_mac %U",
2522           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2523           format_ip4_address, &mp->host_address,
2524           format_ip4_address, &mp->router_address,
2525           format_ethernet_address, mp->host_mac);
2526 }
2527
2528 static void vl_api_dhcp_compl_event_t_handler_json
2529   (vl_api_dhcp_compl_event_t * mp)
2530 {
2531   /* JSON output not supported */
2532 }
2533
2534 static void
2535 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2536                               u32 counter)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   static u64 default_counter = 0;
2540
2541   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2542                            NULL);
2543   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2544                            sw_if_index, default_counter);
2545   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2546 }
2547
2548 static void
2549 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2550                                 interface_counter_t counter)
2551 {
2552   vat_main_t *vam = &vat_main;
2553   static interface_counter_t default_counter = { 0, };
2554
2555   vec_validate_init_empty (vam->combined_interface_counters,
2556                            vnet_counter_type, NULL);
2557   vec_validate_init_empty (vam->combined_interface_counters
2558                            [vnet_counter_type], sw_if_index, default_counter);
2559   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2560 }
2561
2562 static void vl_api_vnet_interface_simple_counters_t_handler
2563   (vl_api_vnet_interface_simple_counters_t * mp)
2564 {
2565   /* not supported */
2566 }
2567
2568 static void vl_api_vnet_interface_combined_counters_t_handler
2569   (vl_api_vnet_interface_combined_counters_t * mp)
2570 {
2571   /* not supported */
2572 }
2573
2574 static void vl_api_vnet_interface_simple_counters_t_handler_json
2575   (vl_api_vnet_interface_simple_counters_t * mp)
2576 {
2577   u64 *v_packets;
2578   u64 packets;
2579   u32 count;
2580   u32 first_sw_if_index;
2581   int i;
2582
2583   count = ntohl (mp->count);
2584   first_sw_if_index = ntohl (mp->first_sw_if_index);
2585
2586   v_packets = (u64 *) & mp->data;
2587   for (i = 0; i < count; i++)
2588     {
2589       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2590       set_simple_interface_counter (mp->vnet_counter_type,
2591                                     first_sw_if_index + i, packets);
2592       v_packets++;
2593     }
2594 }
2595
2596 static void vl_api_vnet_interface_combined_counters_t_handler_json
2597   (vl_api_vnet_interface_combined_counters_t * mp)
2598 {
2599   interface_counter_t counter;
2600   vlib_counter_t *v;
2601   u32 first_sw_if_index;
2602   int i;
2603   u32 count;
2604
2605   count = ntohl (mp->count);
2606   first_sw_if_index = ntohl (mp->first_sw_if_index);
2607
2608   v = (vlib_counter_t *) & mp->data;
2609   for (i = 0; i < count; i++)
2610     {
2611       counter.packets =
2612         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2613       counter.bytes =
2614         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2615       set_combined_interface_counter (mp->vnet_counter_type,
2616                                       first_sw_if_index + i, counter);
2617       v++;
2618     }
2619 }
2620
2621 static u32
2622 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2623 {
2624   vat_main_t *vam = &vat_main;
2625   u32 i;
2626
2627   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2628     {
2629       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2630         {
2631           return i;
2632         }
2633     }
2634   return ~0;
2635 }
2636
2637 static u32
2638 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   u32 i;
2642
2643   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2644     {
2645       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2646         {
2647           return i;
2648         }
2649     }
2650   return ~0;
2651 }
2652
2653 static void vl_api_vnet_ip4_fib_counters_t_handler
2654   (vl_api_vnet_ip4_fib_counters_t * mp)
2655 {
2656   /* not supported */
2657 }
2658
2659 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2660   (vl_api_vnet_ip4_fib_counters_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   vl_api_ip4_fib_counter_t *v;
2664   ip4_fib_counter_t *counter;
2665   struct in_addr ip4;
2666   u32 vrf_id;
2667   u32 vrf_index;
2668   u32 count;
2669   int i;
2670
2671   vrf_id = ntohl (mp->vrf_id);
2672   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2673   if (~0 == vrf_index)
2674     {
2675       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2676       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2677       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2678       vec_validate (vam->ip4_fib_counters, vrf_index);
2679       vam->ip4_fib_counters[vrf_index] = NULL;
2680     }
2681
2682   vec_free (vam->ip4_fib_counters[vrf_index]);
2683   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2684   count = ntohl (mp->count);
2685   for (i = 0; i < count; i++)
2686     {
2687       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2688       counter = &vam->ip4_fib_counters[vrf_index][i];
2689       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2690       counter->address = ip4;
2691       counter->address_length = v->address_length;
2692       counter->packets = clib_net_to_host_u64 (v->packets);
2693       counter->bytes = clib_net_to_host_u64 (v->bytes);
2694       v++;
2695     }
2696 }
2697
2698 static void vl_api_vnet_ip4_nbr_counters_t_handler
2699   (vl_api_vnet_ip4_nbr_counters_t * mp)
2700 {
2701   /* not supported */
2702 }
2703
2704 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2705   (vl_api_vnet_ip4_nbr_counters_t * mp)
2706 {
2707   vat_main_t *vam = &vat_main;
2708   vl_api_ip4_nbr_counter_t *v;
2709   ip4_nbr_counter_t *counter;
2710   u32 sw_if_index;
2711   u32 count;
2712   int i;
2713
2714   sw_if_index = ntohl (mp->sw_if_index);
2715   count = ntohl (mp->count);
2716   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2717
2718   if (mp->begin)
2719     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2720
2721   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2722   for (i = 0; i < count; i++)
2723     {
2724       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2725       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2726       counter->address.s_addr = v->address;
2727       counter->packets = clib_net_to_host_u64 (v->packets);
2728       counter->bytes = clib_net_to_host_u64 (v->bytes);
2729       counter->linkt = v->link_type;
2730       v++;
2731     }
2732 }
2733
2734 static void vl_api_vnet_ip6_fib_counters_t_handler
2735   (vl_api_vnet_ip6_fib_counters_t * mp)
2736 {
2737   /* not supported */
2738 }
2739
2740 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2741   (vl_api_vnet_ip6_fib_counters_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744   vl_api_ip6_fib_counter_t *v;
2745   ip6_fib_counter_t *counter;
2746   struct in6_addr ip6;
2747   u32 vrf_id;
2748   u32 vrf_index;
2749   u32 count;
2750   int i;
2751
2752   vrf_id = ntohl (mp->vrf_id);
2753   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2754   if (~0 == vrf_index)
2755     {
2756       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2757       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2758       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2759       vec_validate (vam->ip6_fib_counters, vrf_index);
2760       vam->ip6_fib_counters[vrf_index] = NULL;
2761     }
2762
2763   vec_free (vam->ip6_fib_counters[vrf_index]);
2764   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2765   count = ntohl (mp->count);
2766   for (i = 0; i < count; i++)
2767     {
2768       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2769       counter = &vam->ip6_fib_counters[vrf_index][i];
2770       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2771       counter->address = ip6;
2772       counter->address_length = v->address_length;
2773       counter->packets = clib_net_to_host_u64 (v->packets);
2774       counter->bytes = clib_net_to_host_u64 (v->bytes);
2775       v++;
2776     }
2777 }
2778
2779 static void vl_api_vnet_ip6_nbr_counters_t_handler
2780   (vl_api_vnet_ip6_nbr_counters_t * mp)
2781 {
2782   /* not supported */
2783 }
2784
2785 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2786   (vl_api_vnet_ip6_nbr_counters_t * mp)
2787 {
2788   vat_main_t *vam = &vat_main;
2789   vl_api_ip6_nbr_counter_t *v;
2790   ip6_nbr_counter_t *counter;
2791   struct in6_addr ip6;
2792   u32 sw_if_index;
2793   u32 count;
2794   int i;
2795
2796   sw_if_index = ntohl (mp->sw_if_index);
2797   count = ntohl (mp->count);
2798   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2799
2800   if (mp->begin)
2801     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2802
2803   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2804   for (i = 0; i < count; i++)
2805     {
2806       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2807       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2808       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2809       counter->address = ip6;
2810       counter->packets = clib_net_to_host_u64 (v->packets);
2811       counter->bytes = clib_net_to_host_u64 (v->bytes);
2812       v++;
2813     }
2814 }
2815
2816 static void vl_api_get_first_msg_id_reply_t_handler
2817   (vl_api_get_first_msg_id_reply_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   i32 retval = ntohl (mp->retval);
2821
2822   if (vam->async_mode)
2823     {
2824       vam->async_errors += (retval < 0);
2825     }
2826   else
2827     {
2828       vam->retval = retval;
2829       vam->result_ready = 1;
2830     }
2831   if (retval >= 0)
2832     {
2833       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2834     }
2835 }
2836
2837 static void vl_api_get_first_msg_id_reply_t_handler_json
2838   (vl_api_get_first_msg_id_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t node;
2842
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "first_msg_id",
2846                             (uint) ntohs (mp->first_msg_id));
2847
2848   vat_json_print (vam->ofp, &node);
2849   vat_json_free (&node);
2850
2851   vam->retval = ntohl (mp->retval);
2852   vam->result_ready = 1;
2853 }
2854
2855 static void vl_api_get_node_graph_reply_t_handler
2856   (vl_api_get_node_graph_reply_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   api_main_t *am = &api_main;
2860   i32 retval = ntohl (mp->retval);
2861   u8 *pvt_copy, *reply;
2862   void *oldheap;
2863   vlib_node_t *node;
2864   int i;
2865
2866   if (vam->async_mode)
2867     {
2868       vam->async_errors += (retval < 0);
2869     }
2870   else
2871     {
2872       vam->retval = retval;
2873       vam->result_ready = 1;
2874     }
2875
2876   /* "Should never happen..." */
2877   if (retval != 0)
2878     return;
2879
2880   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2881   pvt_copy = vec_dup (reply);
2882
2883   /* Toss the shared-memory original... */
2884   pthread_mutex_lock (&am->vlib_rp->mutex);
2885   oldheap = svm_push_data_heap (am->vlib_rp);
2886
2887   vec_free (reply);
2888
2889   svm_pop_heap (oldheap);
2890   pthread_mutex_unlock (&am->vlib_rp->mutex);
2891
2892   if (vam->graph_nodes)
2893     {
2894       hash_free (vam->graph_node_index_by_name);
2895
2896       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2897         {
2898           node = vam->graph_nodes[i];
2899           vec_free (node->name);
2900           vec_free (node->next_nodes);
2901           vec_free (node);
2902         }
2903       vec_free (vam->graph_nodes);
2904     }
2905
2906   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2907   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2908   vec_free (pvt_copy);
2909
2910   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2911     {
2912       node = vam->graph_nodes[i];
2913       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2914     }
2915 }
2916
2917 static void vl_api_get_node_graph_reply_t_handler_json
2918   (vl_api_get_node_graph_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   api_main_t *am = &api_main;
2922   void *oldheap;
2923   vat_json_node_t node;
2924   u8 *reply;
2925
2926   /* $$$$ make this real? */
2927   vat_json_init_object (&node);
2928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2929   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2930
2931   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2932
2933   /* Toss the shared-memory original... */
2934   pthread_mutex_lock (&am->vlib_rp->mutex);
2935   oldheap = svm_push_data_heap (am->vlib_rp);
2936
2937   vec_free (reply);
2938
2939   svm_pop_heap (oldheap);
2940   pthread_mutex_unlock (&am->vlib_rp->mutex);
2941
2942   vat_json_print (vam->ofp, &node);
2943   vat_json_free (&node);
2944
2945   vam->retval = ntohl (mp->retval);
2946   vam->result_ready = 1;
2947 }
2948
2949 static void
2950 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0;
2954
2955   if (mp->local)
2956     {
2957       s = format (s, "%=16d%=16d%=16d",
2958                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2959     }
2960   else
2961     {
2962       s = format (s, "%=16U%=16d%=16d",
2963                   mp->is_ipv6 ? format_ip6_address :
2964                   format_ip4_address,
2965                   mp->ip_address, mp->priority, mp->weight);
2966     }
2967
2968   print (vam->ofp, "%v", s);
2969   vec_free (s);
2970 }
2971
2972 static void
2973 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2974 {
2975   vat_main_t *vam = &vat_main;
2976   vat_json_node_t *node = NULL;
2977   struct in6_addr ip6;
2978   struct in_addr ip4;
2979
2980   if (VAT_JSON_ARRAY != vam->json_tree.type)
2981     {
2982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2983       vat_json_init_array (&vam->json_tree);
2984     }
2985   node = vat_json_array_add (&vam->json_tree);
2986   vat_json_init_object (node);
2987
2988   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2989   vat_json_object_add_uint (node, "priority", mp->priority);
2990   vat_json_object_add_uint (node, "weight", mp->weight);
2991
2992   if (mp->local)
2993     vat_json_object_add_uint (node, "sw_if_index",
2994                               clib_net_to_host_u32 (mp->sw_if_index));
2995   else
2996     {
2997       if (mp->is_ipv6)
2998         {
2999           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3000           vat_json_object_add_ip6 (node, "address", ip6);
3001         }
3002       else
3003         {
3004           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3005           vat_json_object_add_ip4 (node, "address", ip4);
3006         }
3007     }
3008 }
3009
3010 static void
3011 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3012                                           mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   u8 *ls_name = 0;
3016
3017   ls_name = format (0, "%s", mp->ls_name);
3018
3019   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3020          ls_name);
3021   vec_free (ls_name);
3022 }
3023
3024 static void
3025   vl_api_one_locator_set_details_t_handler_json
3026   (vl_api_one_locator_set_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = 0;
3030   u8 *ls_name = 0;
3031
3032   ls_name = format (0, "%s", mp->ls_name);
3033   vec_add1 (ls_name, 0);
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3044   vat_json_object_add_uint (node, "ls_index",
3045                             clib_net_to_host_u32 (mp->ls_index));
3046   vec_free (ls_name);
3047 }
3048
3049 typedef struct
3050 {
3051   u32 spi;
3052   u8 si;
3053 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3054
3055 uword
3056 unformat_nsh_address (unformat_input_t * input, va_list * args)
3057 {
3058   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3059   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3060 }
3061
3062 u8 *
3063 format_nsh_address_vat (u8 * s, va_list * args)
3064 {
3065   nsh_t *a = va_arg (*args, nsh_t *);
3066   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3067 }
3068
3069 static u8 *
3070 format_lisp_flat_eid (u8 * s, va_list * args)
3071 {
3072   u32 type = va_arg (*args, u32);
3073   u8 *eid = va_arg (*args, u8 *);
3074   u32 eid_len = va_arg (*args, u32);
3075
3076   switch (type)
3077     {
3078     case 0:
3079       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3080     case 1:
3081       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3082     case 2:
3083       return format (s, "%U", format_ethernet_address, eid);
3084     case 3:
3085       return format (s, "%U", format_nsh_address_vat, eid);
3086     }
3087   return 0;
3088 }
3089
3090 static u8 *
3091 format_lisp_eid_vat (u8 * s, va_list * args)
3092 {
3093   u32 type = va_arg (*args, u32);
3094   u8 *eid = va_arg (*args, u8 *);
3095   u32 eid_len = va_arg (*args, u32);
3096   u8 *seid = va_arg (*args, u8 *);
3097   u32 seid_len = va_arg (*args, u32);
3098   u32 is_src_dst = va_arg (*args, u32);
3099
3100   if (is_src_dst)
3101     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3102
3103   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3104
3105   return s;
3106 }
3107
3108 static void
3109 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *s = 0, *eid = 0;
3113
3114   if (~0 == mp->locator_set_index)
3115     s = format (0, "action: %d", mp->action);
3116   else
3117     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3118
3119   eid = format (0, "%U", format_lisp_eid_vat,
3120                 mp->eid_type,
3121                 mp->eid,
3122                 mp->eid_prefix_len,
3123                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3124   vec_add1 (eid, 0);
3125
3126   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3127          clib_net_to_host_u32 (mp->vni),
3128          eid,
3129          mp->is_local ? "local" : "remote",
3130          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3131          clib_net_to_host_u16 (mp->key_id), mp->key);
3132
3133   vec_free (s);
3134   vec_free (eid);
3135 }
3136
3137 static void
3138 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3139                                              * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = 0;
3143   u8 *eid = 0;
3144
3145   if (VAT_JSON_ARRAY != vam->json_tree.type)
3146     {
3147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3148       vat_json_init_array (&vam->json_tree);
3149     }
3150   node = vat_json_array_add (&vam->json_tree);
3151
3152   vat_json_init_object (node);
3153   if (~0 == mp->locator_set_index)
3154     vat_json_object_add_uint (node, "action", mp->action);
3155   else
3156     vat_json_object_add_uint (node, "locator_set_index",
3157                               clib_net_to_host_u32 (mp->locator_set_index));
3158
3159   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3160   if (mp->eid_type == 3)
3161     {
3162       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3163       vat_json_init_object (nsh_json);
3164       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3165       vat_json_object_add_uint (nsh_json, "spi",
3166                                 clib_net_to_host_u32 (nsh->spi));
3167       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3168     }
3169   else
3170     {
3171       eid = format (0, "%U", format_lisp_eid_vat,
3172                     mp->eid_type,
3173                     mp->eid,
3174                     mp->eid_prefix_len,
3175                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3176       vec_add1 (eid, 0);
3177       vat_json_object_add_string_copy (node, "eid", eid);
3178       vec_free (eid);
3179     }
3180   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3181   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3182   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3183
3184   if (mp->key_id)
3185     {
3186       vat_json_object_add_uint (node, "key_id",
3187                                 clib_net_to_host_u16 (mp->key_id));
3188       vat_json_object_add_string_copy (node, "key", mp->key);
3189     }
3190 }
3191
3192 static void
3193 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   u8 *seid = 0, *deid = 0;
3197   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3198
3199   deid = format (0, "%U", format_lisp_eid_vat,
3200                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3201
3202   seid = format (0, "%U", format_lisp_eid_vat,
3203                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3204
3205   vec_add1 (deid, 0);
3206   vec_add1 (seid, 0);
3207
3208   if (mp->is_ip4)
3209     format_ip_address_fcn = format_ip4_address;
3210   else
3211     format_ip_address_fcn = format_ip6_address;
3212
3213
3214   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3215          clib_net_to_host_u32 (mp->vni),
3216          seid, deid,
3217          format_ip_address_fcn, mp->lloc,
3218          format_ip_address_fcn, mp->rloc,
3219          clib_net_to_host_u32 (mp->pkt_count),
3220          clib_net_to_host_u32 (mp->bytes));
3221
3222   vec_free (deid);
3223   vec_free (seid);
3224 }
3225
3226 static void
3227 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3228 {
3229   struct in6_addr ip6;
3230   struct in_addr ip4;
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t *node = 0;
3233   u8 *deid = 0, *seid = 0;
3234
3235   if (VAT_JSON_ARRAY != vam->json_tree.type)
3236     {
3237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3238       vat_json_init_array (&vam->json_tree);
3239     }
3240   node = vat_json_array_add (&vam->json_tree);
3241
3242   vat_json_init_object (node);
3243   deid = format (0, "%U", format_lisp_eid_vat,
3244                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3245
3246   seid = format (0, "%U", format_lisp_eid_vat,
3247                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3248
3249   vec_add1 (deid, 0);
3250   vec_add1 (seid, 0);
3251
3252   vat_json_object_add_string_copy (node, "seid", seid);
3253   vat_json_object_add_string_copy (node, "deid", deid);
3254   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3255
3256   if (mp->is_ip4)
3257     {
3258       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3259       vat_json_object_add_ip4 (node, "lloc", ip4);
3260       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3261       vat_json_object_add_ip4 (node, "rloc", ip4);
3262     }
3263   else
3264     {
3265       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3266       vat_json_object_add_ip6 (node, "lloc", ip6);
3267       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3268       vat_json_object_add_ip6 (node, "rloc", ip6);
3269     }
3270   vat_json_object_add_uint (node, "pkt_count",
3271                             clib_net_to_host_u32 (mp->pkt_count));
3272   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3273
3274   vec_free (deid);
3275   vec_free (seid);
3276 }
3277
3278 static void
3279   vl_api_one_eid_table_map_details_t_handler
3280   (vl_api_one_eid_table_map_details_t * mp)
3281 {
3282   vat_main_t *vam = &vat_main;
3283
3284   u8 *line = format (0, "%=10d%=10d",
3285                      clib_net_to_host_u32 (mp->vni),
3286                      clib_net_to_host_u32 (mp->dp_table));
3287   print (vam->ofp, "%v", line);
3288   vec_free (line);
3289 }
3290
3291 static void
3292   vl_api_one_eid_table_map_details_t_handler_json
3293   (vl_api_one_eid_table_map_details_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t *node = NULL;
3297
3298   if (VAT_JSON_ARRAY != vam->json_tree.type)
3299     {
3300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3301       vat_json_init_array (&vam->json_tree);
3302     }
3303   node = vat_json_array_add (&vam->json_tree);
3304   vat_json_init_object (node);
3305   vat_json_object_add_uint (node, "dp_table",
3306                             clib_net_to_host_u32 (mp->dp_table));
3307   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3308 }
3309
3310 static void
3311   vl_api_one_eid_table_vni_details_t_handler
3312   (vl_api_one_eid_table_vni_details_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315
3316   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3317   print (vam->ofp, "%v", line);
3318   vec_free (line);
3319 }
3320
3321 static void
3322   vl_api_one_eid_table_vni_details_t_handler_json
3323   (vl_api_one_eid_table_vni_details_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t *node = NULL;
3327
3328   if (VAT_JSON_ARRAY != vam->json_tree.type)
3329     {
3330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3331       vat_json_init_array (&vam->json_tree);
3332     }
3333   node = vat_json_array_add (&vam->json_tree);
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3336 }
3337
3338 static void
3339   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3340   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3346   print (vam->ofp, "fallback threshold value: %d", mp->value);
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3354   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t _node, *node = &_node;
3358   int retval = clib_net_to_host_u32 (mp->retval);
3359
3360   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "value", mp->value);
3363
3364   vat_json_print (vam->ofp, node);
3365   vat_json_free (node);
3366
3367   vam->retval = retval;
3368   vam->result_ready = 1;
3369 }
3370
3371 static void
3372   vl_api_show_one_map_register_state_reply_t_handler
3373   (vl_api_show_one_map_register_state_reply_t * mp)
3374 {
3375   vat_main_t *vam = &vat_main;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3379
3380   vam->retval = retval;
3381   vam->result_ready = 1;
3382 }
3383
3384 static void
3385   vl_api_show_one_map_register_state_reply_t_handler_json
3386   (vl_api_show_one_map_register_state_reply_t * mp)
3387 {
3388   vat_main_t *vam = &vat_main;
3389   vat_json_node_t _node, *node = &_node;
3390   int retval = clib_net_to_host_u32 (mp->retval);
3391
3392   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3393
3394   vat_json_init_object (node);
3395   vat_json_object_add_string_copy (node, "state", s);
3396
3397   vat_json_print (vam->ofp, node);
3398   vat_json_free (node);
3399
3400   vam->retval = retval;
3401   vam->result_ready = 1;
3402   vec_free (s);
3403 }
3404
3405 static void
3406   vl_api_show_one_rloc_probe_state_reply_t_handler
3407   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   int retval = clib_net_to_host_u32 (mp->retval);
3411
3412   if (retval)
3413     goto end;
3414
3415   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3416 end:
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3423   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   vat_json_node_t _node, *node = &_node;
3427   int retval = clib_net_to_host_u32 (mp->retval);
3428
3429   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3430   vat_json_init_object (node);
3431   vat_json_object_add_string_copy (node, "state", s);
3432
3433   vat_json_print (vam->ofp, node);
3434   vat_json_free (node);
3435
3436   vam->retval = retval;
3437   vam->result_ready = 1;
3438   vec_free (s);
3439 }
3440
3441 static void
3442   vl_api_show_one_stats_enable_disable_reply_t_handler
3443   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   int retval = clib_net_to_host_u32 (mp->retval);
3447
3448   if (retval)
3449     goto end;
3450
3451   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3452 end:
3453   vam->retval = retval;
3454   vam->result_ready = 1;
3455 }
3456
3457 static void
3458   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3459   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   vat_json_node_t _node, *node = &_node;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464
3465   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3466   vat_json_init_object (node);
3467   vat_json_object_add_string_copy (node, "state", s);
3468
3469   vat_json_print (vam->ofp, node);
3470   vat_json_free (node);
3471
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474   vec_free (s);
3475 }
3476
3477 static void
3478 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3479 {
3480   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3481   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3482   e->vni = clib_net_to_host_u32 (e->vni);
3483 }
3484
3485 static void
3486   gpe_fwd_entries_get_reply_t_net_to_host
3487   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3488 {
3489   u32 i;
3490
3491   mp->count = clib_net_to_host_u32 (mp->count);
3492   for (i = 0; i < mp->count; i++)
3493     {
3494       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3495     }
3496 }
3497
3498 static u8 *
3499 format_gpe_encap_mode (u8 * s, va_list * args)
3500 {
3501   u32 mode = va_arg (*args, u32);
3502
3503   switch (mode)
3504     {
3505     case 0:
3506       return format (s, "lisp");
3507     case 1:
3508       return format (s, "vxlan");
3509     }
3510   return 0;
3511 }
3512
3513 static void
3514   vl_api_gpe_get_encap_mode_reply_t_handler
3515   (vl_api_gpe_get_encap_mode_reply_t * mp)
3516 {
3517   vat_main_t *vam = &vat_main;
3518
3519   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3520   vam->retval = ntohl (mp->retval);
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_get_encap_mode_reply_t_handler_json
3526   (vl_api_gpe_get_encap_mode_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t node;
3530
3531   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3532   vec_add1 (encap_mode, 0);
3533
3534   vat_json_init_object (&node);
3535   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3536
3537   vec_free (encap_mode);
3538   vat_json_print (vam->ofp, &node);
3539   vat_json_free (&node);
3540
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_gpe_fwd_entry_path_details_t_handler
3547   (vl_api_gpe_fwd_entry_path_details_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3551
3552   if (mp->lcl_loc.is_ip4)
3553     format_ip_address_fcn = format_ip4_address;
3554   else
3555     format_ip_address_fcn = format_ip6_address;
3556
3557   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3558          format_ip_address_fcn, &mp->lcl_loc,
3559          format_ip_address_fcn, &mp->rmt_loc);
3560 }
3561
3562 static void
3563 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3564 {
3565   struct in6_addr ip6;
3566   struct in_addr ip4;
3567
3568   if (loc->is_ip4)
3569     {
3570       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3571       vat_json_object_add_ip4 (n, "address", ip4);
3572     }
3573   else
3574     {
3575       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3576       vat_json_object_add_ip6 (n, "address", ip6);
3577     }
3578   vat_json_object_add_uint (n, "weight", loc->weight);
3579 }
3580
3581 static void
3582   vl_api_gpe_fwd_entry_path_details_t_handler_json
3583   (vl_api_gpe_fwd_entry_path_details_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586   vat_json_node_t *node = NULL;
3587   vat_json_node_t *loc_node;
3588
3589   if (VAT_JSON_ARRAY != vam->json_tree.type)
3590     {
3591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3592       vat_json_init_array (&vam->json_tree);
3593     }
3594   node = vat_json_array_add (&vam->json_tree);
3595   vat_json_init_object (node);
3596
3597   loc_node = vat_json_object_add (node, "local_locator");
3598   vat_json_init_object (loc_node);
3599   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3600
3601   loc_node = vat_json_object_add (node, "remote_locator");
3602   vat_json_init_object (loc_node);
3603   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3604 }
3605
3606 static void
3607   vl_api_gpe_fwd_entries_get_reply_t_handler
3608   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   u32 i;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613   vl_api_gpe_fwd_entry_t *e;
3614
3615   if (retval)
3616     goto end;
3617
3618   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3619
3620   for (i = 0; i < mp->count; i++)
3621     {
3622       e = &mp->entries[i];
3623       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3624              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3625              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3626     }
3627
3628 end:
3629   vam->retval = retval;
3630   vam->result_ready = 1;
3631 }
3632
3633 static void
3634   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3635   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3636 {
3637   u8 *s = 0;
3638   vat_main_t *vam = &vat_main;
3639   vat_json_node_t *e = 0, root;
3640   u32 i;
3641   int retval = clib_net_to_host_u32 (mp->retval);
3642   vl_api_gpe_fwd_entry_t *fwd;
3643
3644   if (retval)
3645     goto end;
3646
3647   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3648   vat_json_init_array (&root);
3649
3650   for (i = 0; i < mp->count; i++)
3651     {
3652       e = vat_json_array_add (&root);
3653       fwd = &mp->entries[i];
3654
3655       vat_json_init_object (e);
3656       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3657       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3658       vat_json_object_add_int (e, "vni", fwd->vni);
3659       vat_json_object_add_int (e, "action", fwd->action);
3660
3661       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3662                   fwd->leid_prefix_len);
3663       vec_add1 (s, 0);
3664       vat_json_object_add_string_copy (e, "leid", s);
3665       vec_free (s);
3666
3667       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3668                   fwd->reid_prefix_len);
3669       vec_add1 (s, 0);
3670       vat_json_object_add_string_copy (e, "reid", s);
3671       vec_free (s);
3672     }
3673
3674   vat_json_print (vam->ofp, &root);
3675   vat_json_free (&root);
3676
3677 end:
3678   vam->retval = retval;
3679   vam->result_ready = 1;
3680 }
3681
3682 static void
3683   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3684   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3685 {
3686   vat_main_t *vam = &vat_main;
3687   u32 i, n;
3688   int retval = clib_net_to_host_u32 (mp->retval);
3689   vl_api_gpe_native_fwd_rpath_t *r;
3690
3691   if (retval)
3692     goto end;
3693
3694   n = clib_net_to_host_u32 (mp->count);
3695
3696   for (i = 0; i < n; i++)
3697     {
3698       r = &mp->entries[i];
3699       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3700              clib_net_to_host_u32 (r->fib_index),
3701              clib_net_to_host_u32 (r->nh_sw_if_index),
3702              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3703     }
3704
3705 end:
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3712   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   vat_json_node_t root, *e;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718   vl_api_gpe_native_fwd_rpath_t *r;
3719   u8 *s;
3720
3721   if (retval)
3722     goto end;
3723
3724   n = clib_net_to_host_u32 (mp->count);
3725   vat_json_init_array (&root);
3726
3727   for (i = 0; i < n; i++)
3728     {
3729       e = vat_json_array_add (&root);
3730       vat_json_init_object (e);
3731       r = &mp->entries[i];
3732       s =
3733         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3734                 r->nh_addr);
3735       vec_add1 (s, 0);
3736       vat_json_object_add_string_copy (e, "ip4", s);
3737       vec_free (s);
3738
3739       vat_json_object_add_uint (e, "fib_index",
3740                                 clib_net_to_host_u32 (r->fib_index));
3741       vat_json_object_add_uint (e, "nh_sw_if_index",
3742                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3743     }
3744
3745   vat_json_print (vam->ofp, &root);
3746   vat_json_free (&root);
3747
3748 end:
3749   vam->retval = retval;
3750   vam->result_ready = 1;
3751 }
3752
3753 static void
3754   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3755   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3756 {
3757   vat_main_t *vam = &vat_main;
3758   u32 i, n;
3759   int retval = clib_net_to_host_u32 (mp->retval);
3760
3761   if (retval)
3762     goto end;
3763
3764   n = clib_net_to_host_u32 (mp->count);
3765
3766   for (i = 0; i < n; i++)
3767     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3776   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3777 {
3778   vat_main_t *vam = &vat_main;
3779   vat_json_node_t root;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787   vat_json_init_array (&root);
3788
3789   for (i = 0; i < n; i++)
3790     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3791
3792   vat_json_print (vam->ofp, &root);
3793   vat_json_free (&root);
3794
3795 end:
3796   vam->retval = retval;
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_one_ndp_entries_get_reply_t_handler
3802   (vl_api_one_ndp_entries_get_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 i, n;
3806   int retval = clib_net_to_host_u32 (mp->retval);
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812
3813   for (i = 0; i < n; i++)
3814     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3815            format_ethernet_address, mp->entries[i].mac);
3816
3817 end:
3818   vam->retval = retval;
3819   vam->result_ready = 1;
3820 }
3821
3822 static void
3823   vl_api_one_ndp_entries_get_reply_t_handler_json
3824   (vl_api_one_ndp_entries_get_reply_t * mp)
3825 {
3826   u8 *s = 0;
3827   vat_main_t *vam = &vat_main;
3828   vat_json_node_t *e = 0, root;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831   vl_api_one_ndp_entry_t *arp_entry;
3832
3833   if (retval)
3834     goto end;
3835
3836   n = clib_net_to_host_u32 (mp->count);
3837   vat_json_init_array (&root);
3838
3839   for (i = 0; i < n; i++)
3840     {
3841       e = vat_json_array_add (&root);
3842       arp_entry = &mp->entries[i];
3843
3844       vat_json_init_object (e);
3845       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3846       vec_add1 (s, 0);
3847
3848       vat_json_object_add_string_copy (e, "mac", s);
3849       vec_free (s);
3850
3851       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3852       vec_add1 (s, 0);
3853       vat_json_object_add_string_copy (e, "ip6", s);
3854       vec_free (s);
3855     }
3856
3857   vat_json_print (vam->ofp, &root);
3858   vat_json_free (&root);
3859
3860 end:
3861   vam->retval = retval;
3862   vam->result_ready = 1;
3863 }
3864
3865 static void
3866   vl_api_one_l2_arp_entries_get_reply_t_handler
3867   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3868 {
3869   vat_main_t *vam = &vat_main;
3870   u32 i, n;
3871   int retval = clib_net_to_host_u32 (mp->retval);
3872
3873   if (retval)
3874     goto end;
3875
3876   n = clib_net_to_host_u32 (mp->count);
3877
3878   for (i = 0; i < n; i++)
3879     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3880            format_ethernet_address, mp->entries[i].mac);
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3889   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3890 {
3891   u8 *s = 0;
3892   vat_main_t *vam = &vat_main;
3893   vat_json_node_t *e = 0, root;
3894   u32 i, n;
3895   int retval = clib_net_to_host_u32 (mp->retval);
3896   vl_api_one_l2_arp_entry_t *arp_entry;
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       e = vat_json_array_add (&root);
3907       arp_entry = &mp->entries[i];
3908
3909       vat_json_init_object (e);
3910       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3911       vec_add1 (s, 0);
3912
3913       vat_json_object_add_string_copy (e, "mac", s);
3914       vec_free (s);
3915
3916       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3917       vec_add1 (s, 0);
3918       vat_json_object_add_string_copy (e, "ip4", s);
3919       vec_free (s);
3920     }
3921
3922   vat_json_print (vam->ofp, &root);
3923   vat_json_free (&root);
3924
3925 end:
3926   vam->retval = retval;
3927   vam->result_ready = 1;
3928 }
3929
3930 static void
3931 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3932 {
3933   vat_main_t *vam = &vat_main;
3934   u32 i, n;
3935   int retval = clib_net_to_host_u32 (mp->retval);
3936
3937   if (retval)
3938     goto end;
3939
3940   n = clib_net_to_host_u32 (mp->count);
3941
3942   for (i = 0; i < n; i++)
3943     {
3944       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3945     }
3946
3947 end:
3948   vam->retval = retval;
3949   vam->result_ready = 1;
3950 }
3951
3952 static void
3953   vl_api_one_ndp_bd_get_reply_t_handler_json
3954   (vl_api_one_ndp_bd_get_reply_t * mp)
3955 {
3956   vat_main_t *vam = &vat_main;
3957   vat_json_node_t root;
3958   u32 i, n;
3959   int retval = clib_net_to_host_u32 (mp->retval);
3960
3961   if (retval)
3962     goto end;
3963
3964   n = clib_net_to_host_u32 (mp->count);
3965   vat_json_init_array (&root);
3966
3967   for (i = 0; i < n; i++)
3968     {
3969       vat_json_array_add_uint (&root,
3970                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3971     }
3972
3973   vat_json_print (vam->ofp, &root);
3974   vat_json_free (&root);
3975
3976 end:
3977   vam->retval = retval;
3978   vam->result_ready = 1;
3979 }
3980
3981 static void
3982   vl_api_one_l2_arp_bd_get_reply_t_handler
3983   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3984 {
3985   vat_main_t *vam = &vat_main;
3986   u32 i, n;
3987   int retval = clib_net_to_host_u32 (mp->retval);
3988
3989   if (retval)
3990     goto end;
3991
3992   n = clib_net_to_host_u32 (mp->count);
3993
3994   for (i = 0; i < n; i++)
3995     {
3996       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3997     }
3998
3999 end:
4000   vam->retval = retval;
4001   vam->result_ready = 1;
4002 }
4003
4004 static void
4005   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4006   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4007 {
4008   vat_main_t *vam = &vat_main;
4009   vat_json_node_t root;
4010   u32 i, n;
4011   int retval = clib_net_to_host_u32 (mp->retval);
4012
4013   if (retval)
4014     goto end;
4015
4016   n = clib_net_to_host_u32 (mp->count);
4017   vat_json_init_array (&root);
4018
4019   for (i = 0; i < n; i++)
4020     {
4021       vat_json_array_add_uint (&root,
4022                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4023     }
4024
4025   vat_json_print (vam->ofp, &root);
4026   vat_json_free (&root);
4027
4028 end:
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_one_adjacencies_get_reply_t_handler
4035   (vl_api_one_adjacencies_get_reply_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   u32 i, n;
4039   int retval = clib_net_to_host_u32 (mp->retval);
4040   vl_api_one_adjacency_t *a;
4041
4042   if (retval)
4043     goto end;
4044
4045   n = clib_net_to_host_u32 (mp->count);
4046
4047   for (i = 0; i < n; i++)
4048     {
4049       a = &mp->adjacencies[i];
4050       print (vam->ofp, "%U %40U",
4051              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4052              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4053     }
4054
4055 end:
4056   vam->retval = retval;
4057   vam->result_ready = 1;
4058 }
4059
4060 static void
4061   vl_api_one_adjacencies_get_reply_t_handler_json
4062   (vl_api_one_adjacencies_get_reply_t * mp)
4063 {
4064   u8 *s = 0;
4065   vat_main_t *vam = &vat_main;
4066   vat_json_node_t *e = 0, root;
4067   u32 i, n;
4068   int retval = clib_net_to_host_u32 (mp->retval);
4069   vl_api_one_adjacency_t *a;
4070
4071   if (retval)
4072     goto end;
4073
4074   n = clib_net_to_host_u32 (mp->count);
4075   vat_json_init_array (&root);
4076
4077   for (i = 0; i < n; i++)
4078     {
4079       e = vat_json_array_add (&root);
4080       a = &mp->adjacencies[i];
4081
4082       vat_json_init_object (e);
4083       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4084                   a->leid_prefix_len);
4085       vec_add1 (s, 0);
4086       vat_json_object_add_string_copy (e, "leid", s);
4087       vec_free (s);
4088
4089       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4090                   a->reid_prefix_len);
4091       vec_add1 (s, 0);
4092       vat_json_object_add_string_copy (e, "reid", s);
4093       vec_free (s);
4094     }
4095
4096   vat_json_print (vam->ofp, &root);
4097   vat_json_free (&root);
4098
4099 end:
4100   vam->retval = retval;
4101   vam->result_ready = 1;
4102 }
4103
4104 static void
4105 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108
4109   print (vam->ofp, "%=20U",
4110          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4111          mp->ip_address);
4112 }
4113
4114 static void
4115   vl_api_one_map_server_details_t_handler_json
4116   (vl_api_one_map_server_details_t * mp)
4117 {
4118   vat_main_t *vam = &vat_main;
4119   vat_json_node_t *node = NULL;
4120   struct in6_addr ip6;
4121   struct in_addr ip4;
4122
4123   if (VAT_JSON_ARRAY != vam->json_tree.type)
4124     {
4125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4126       vat_json_init_array (&vam->json_tree);
4127     }
4128   node = vat_json_array_add (&vam->json_tree);
4129
4130   vat_json_init_object (node);
4131   if (mp->is_ipv6)
4132     {
4133       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4134       vat_json_object_add_ip6 (node, "map-server", ip6);
4135     }
4136   else
4137     {
4138       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4139       vat_json_object_add_ip4 (node, "map-server", ip4);
4140     }
4141 }
4142
4143 static void
4144 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4145                                            * mp)
4146 {
4147   vat_main_t *vam = &vat_main;
4148
4149   print (vam->ofp, "%=20U",
4150          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4151          mp->ip_address);
4152 }
4153
4154 static void
4155   vl_api_one_map_resolver_details_t_handler_json
4156   (vl_api_one_map_resolver_details_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t *node = NULL;
4160   struct in6_addr ip6;
4161   struct in_addr ip4;
4162
4163   if (VAT_JSON_ARRAY != vam->json_tree.type)
4164     {
4165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4166       vat_json_init_array (&vam->json_tree);
4167     }
4168   node = vat_json_array_add (&vam->json_tree);
4169
4170   vat_json_init_object (node);
4171   if (mp->is_ipv6)
4172     {
4173       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4174       vat_json_object_add_ip6 (node, "map resolver", ip6);
4175     }
4176   else
4177     {
4178       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4179       vat_json_object_add_ip4 (node, "map resolver", ip4);
4180     }
4181 }
4182
4183 static void
4184 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   i32 retval = ntohl (mp->retval);
4188
4189   if (0 <= retval)
4190     {
4191       print (vam->ofp, "feature: %s\ngpe: %s",
4192              mp->feature_status ? "enabled" : "disabled",
4193              mp->gpe_status ? "enabled" : "disabled");
4194     }
4195
4196   vam->retval = retval;
4197   vam->result_ready = 1;
4198 }
4199
4200 static void
4201   vl_api_show_one_status_reply_t_handler_json
4202   (vl_api_show_one_status_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   vat_json_node_t node;
4206   u8 *gpe_status = NULL;
4207   u8 *feature_status = NULL;
4208
4209   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4210   feature_status = format (0, "%s",
4211                            mp->feature_status ? "enabled" : "disabled");
4212   vec_add1 (gpe_status, 0);
4213   vec_add1 (feature_status, 0);
4214
4215   vat_json_init_object (&node);
4216   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4217   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4218
4219   vec_free (gpe_status);
4220   vec_free (feature_status);
4221
4222   vat_json_print (vam->ofp, &node);
4223   vat_json_free (&node);
4224
4225   vam->retval = ntohl (mp->retval);
4226   vam->result_ready = 1;
4227 }
4228
4229 static void
4230   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4231   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4232 {
4233   vat_main_t *vam = &vat_main;
4234   i32 retval = ntohl (mp->retval);
4235
4236   if (retval >= 0)
4237     {
4238       print (vam->ofp, "%=20s", mp->locator_set_name);
4239     }
4240
4241   vam->retval = retval;
4242   vam->result_ready = 1;
4243 }
4244
4245 static void
4246   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4247   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   vat_json_node_t *node = NULL;
4251
4252   if (VAT_JSON_ARRAY != vam->json_tree.type)
4253     {
4254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4255       vat_json_init_array (&vam->json_tree);
4256     }
4257   node = vat_json_array_add (&vam->json_tree);
4258
4259   vat_json_init_object (node);
4260   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4261
4262   vat_json_print (vam->ofp, node);
4263   vat_json_free (node);
4264
4265   vam->retval = ntohl (mp->retval);
4266   vam->result_ready = 1;
4267 }
4268
4269 static u8 *
4270 format_lisp_map_request_mode (u8 * s, va_list * args)
4271 {
4272   u32 mode = va_arg (*args, u32);
4273
4274   switch (mode)
4275     {
4276     case 0:
4277       return format (0, "dst-only");
4278     case 1:
4279       return format (0, "src-dst");
4280     }
4281   return 0;
4282 }
4283
4284 static void
4285   vl_api_show_one_map_request_mode_reply_t_handler
4286   (vl_api_show_one_map_request_mode_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       u32 mode = mp->mode;
4294       print (vam->ofp, "map_request_mode: %U",
4295              format_lisp_map_request_mode, mode);
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_map_request_mode_reply_t_handler_json
4304   (vl_api_show_one_map_request_mode_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *s = 0;
4309   u32 mode;
4310
4311   mode = mp->mode;
4312   s = format (0, "%U", format_lisp_map_request_mode, mode);
4313   vec_add1 (s, 0);
4314
4315   vat_json_init_object (&node);
4316   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vec_free (s);
4321   vam->retval = ntohl (mp->retval);
4322   vam->result_ready = 1;
4323 }
4324
4325 static void
4326   vl_api_one_show_xtr_mode_reply_t_handler
4327   (vl_api_one_show_xtr_mode_reply_t * mp)
4328 {
4329   vat_main_t *vam = &vat_main;
4330   i32 retval = ntohl (mp->retval);
4331
4332   if (0 <= retval)
4333     {
4334       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4335     }
4336
4337   vam->retval = retval;
4338   vam->result_ready = 1;
4339 }
4340
4341 static void
4342   vl_api_one_show_xtr_mode_reply_t_handler_json
4343   (vl_api_one_show_xtr_mode_reply_t * mp)
4344 {
4345   vat_main_t *vam = &vat_main;
4346   vat_json_node_t node;
4347   u8 *status = 0;
4348
4349   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4350   vec_add1 (status, 0);
4351
4352   vat_json_init_object (&node);
4353   vat_json_object_add_string_copy (&node, "status", status);
4354
4355   vec_free (status);
4356
4357   vat_json_print (vam->ofp, &node);
4358   vat_json_free (&node);
4359
4360   vam->retval = ntohl (mp->retval);
4361   vam->result_ready = 1;
4362 }
4363
4364 static void
4365   vl_api_one_show_pitr_mode_reply_t_handler
4366   (vl_api_one_show_pitr_mode_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369   i32 retval = ntohl (mp->retval);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_one_show_pitr_mode_reply_t_handler_json
4382   (vl_api_one_show_pitr_mode_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386   u8 *status = 0;
4387
4388   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4389   vec_add1 (status, 0);
4390
4391   vat_json_init_object (&node);
4392   vat_json_object_add_string_copy (&node, "status", status);
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_one_show_petr_mode_reply_t_handler
4405   (vl_api_one_show_petr_mode_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   if (0 <= retval)
4411     {
4412       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4413     }
4414
4415   vam->retval = retval;
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_one_show_petr_mode_reply_t_handler_json
4421   (vl_api_one_show_petr_mode_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   vat_json_node_t node;
4425   u8 *status = 0;
4426
4427   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4428   vec_add1 (status, 0);
4429
4430   vat_json_init_object (&node);
4431   vat_json_object_add_string_copy (&node, "status", status);
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static void
4443   vl_api_show_one_use_petr_reply_t_handler
4444   (vl_api_show_one_use_petr_reply_t * mp)
4445 {
4446   vat_main_t *vam = &vat_main;
4447   i32 retval = ntohl (mp->retval);
4448
4449   if (0 <= retval)
4450     {
4451       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4452       if (mp->status)
4453         {
4454           print (vam->ofp, "Proxy-ETR address; %U",
4455                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4456                  mp->address);
4457         }
4458     }
4459
4460   vam->retval = retval;
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465   vl_api_show_one_use_petr_reply_t_handler_json
4466   (vl_api_show_one_use_petr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   vat_json_node_t node;
4470   u8 *status = 0;
4471   struct in_addr ip4;
4472   struct in6_addr ip6;
4473
4474   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4475   vec_add1 (status, 0);
4476
4477   vat_json_init_object (&node);
4478   vat_json_object_add_string_copy (&node, "status", status);
4479   if (mp->status)
4480     {
4481       if (mp->is_ip4)
4482         {
4483           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4484           vat_json_object_add_ip6 (&node, "address", ip6);
4485         }
4486       else
4487         {
4488           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4489           vat_json_object_add_ip4 (&node, "address", ip4);
4490         }
4491     }
4492
4493   vec_free (status);
4494
4495   vat_json_print (vam->ofp, &node);
4496   vat_json_free (&node);
4497
4498   vam->retval = ntohl (mp->retval);
4499   vam->result_ready = 1;
4500 }
4501
4502 static void
4503   vl_api_show_one_nsh_mapping_reply_t_handler
4504   (vl_api_show_one_nsh_mapping_reply_t * mp)
4505 {
4506   vat_main_t *vam = &vat_main;
4507   i32 retval = ntohl (mp->retval);
4508
4509   if (0 <= retval)
4510     {
4511       print (vam->ofp, "%-20s%-16s",
4512              mp->is_set ? "set" : "not-set",
4513              mp->is_set ? (char *) mp->locator_set_name : "");
4514     }
4515
4516   vam->retval = retval;
4517   vam->result_ready = 1;
4518 }
4519
4520 static void
4521   vl_api_show_one_nsh_mapping_reply_t_handler_json
4522   (vl_api_show_one_nsh_mapping_reply_t * mp)
4523 {
4524   vat_main_t *vam = &vat_main;
4525   vat_json_node_t node;
4526   u8 *status = 0;
4527
4528   status = format (0, "%s", mp->is_set ? "yes" : "no");
4529   vec_add1 (status, 0);
4530
4531   vat_json_init_object (&node);
4532   vat_json_object_add_string_copy (&node, "is_set", status);
4533   if (mp->is_set)
4534     {
4535       vat_json_object_add_string_copy (&node, "locator_set",
4536                                        mp->locator_set_name);
4537     }
4538
4539   vec_free (status);
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void
4549   vl_api_show_one_map_register_ttl_reply_t_handler
4550   (vl_api_show_one_map_register_ttl_reply_t * mp)
4551 {
4552   vat_main_t *vam = &vat_main;
4553   i32 retval = ntohl (mp->retval);
4554
4555   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4556
4557   if (0 <= retval)
4558     {
4559       print (vam->ofp, "ttl: %u", mp->ttl);
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_map_register_ttl_reply_t_handler_json
4568   (vl_api_show_one_map_register_ttl_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572
4573   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4574   vat_json_init_object (&node);
4575   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4576
4577   vat_json_print (vam->ofp, &node);
4578   vat_json_free (&node);
4579
4580   vam->retval = ntohl (mp->retval);
4581   vam->result_ready = 1;
4582 }
4583
4584 static void
4585 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4586 {
4587   vat_main_t *vam = &vat_main;
4588   i32 retval = ntohl (mp->retval);
4589
4590   if (0 <= retval)
4591     {
4592       print (vam->ofp, "%-20s%-16s",
4593              mp->status ? "enabled" : "disabled",
4594              mp->status ? (char *) mp->locator_set_name : "");
4595     }
4596
4597   vam->retval = retval;
4598   vam->result_ready = 1;
4599 }
4600
4601 static void
4602 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4603 {
4604   vat_main_t *vam = &vat_main;
4605   vat_json_node_t node;
4606   u8 *status = 0;
4607
4608   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4609   vec_add1 (status, 0);
4610
4611   vat_json_init_object (&node);
4612   vat_json_object_add_string_copy (&node, "status", status);
4613   if (mp->status)
4614     {
4615       vat_json_object_add_string_copy (&node, "locator_set",
4616                                        mp->locator_set_name);
4617     }
4618
4619   vec_free (status);
4620
4621   vat_json_print (vam->ofp, &node);
4622   vat_json_free (&node);
4623
4624   vam->retval = ntohl (mp->retval);
4625   vam->result_ready = 1;
4626 }
4627
4628 static u8 *
4629 format_policer_type (u8 * s, va_list * va)
4630 {
4631   u32 i = va_arg (*va, u32);
4632
4633   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4634     s = format (s, "1r2c");
4635   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4636     s = format (s, "1r3c");
4637   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4638     s = format (s, "2r3c-2698");
4639   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4640     s = format (s, "2r3c-4115");
4641   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4642     s = format (s, "2r3c-mef5cf1");
4643   else
4644     s = format (s, "ILLEGAL");
4645   return s;
4646 }
4647
4648 static u8 *
4649 format_policer_rate_type (u8 * s, va_list * va)
4650 {
4651   u32 i = va_arg (*va, u32);
4652
4653   if (i == SSE2_QOS_RATE_KBPS)
4654     s = format (s, "kbps");
4655   else if (i == SSE2_QOS_RATE_PPS)
4656     s = format (s, "pps");
4657   else
4658     s = format (s, "ILLEGAL");
4659   return s;
4660 }
4661
4662 static u8 *
4663 format_policer_round_type (u8 * s, va_list * va)
4664 {
4665   u32 i = va_arg (*va, u32);
4666
4667   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4668     s = format (s, "closest");
4669   else if (i == SSE2_QOS_ROUND_TO_UP)
4670     s = format (s, "up");
4671   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4672     s = format (s, "down");
4673   else
4674     s = format (s, "ILLEGAL");
4675   return s;
4676 }
4677
4678 static u8 *
4679 format_policer_action_type (u8 * s, va_list * va)
4680 {
4681   u32 i = va_arg (*va, u32);
4682
4683   if (i == SSE2_QOS_ACTION_DROP)
4684     s = format (s, "drop");
4685   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4686     s = format (s, "transmit");
4687   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4688     s = format (s, "mark-and-transmit");
4689   else
4690     s = format (s, "ILLEGAL");
4691   return s;
4692 }
4693
4694 static u8 *
4695 format_dscp (u8 * s, va_list * va)
4696 {
4697   u32 i = va_arg (*va, u32);
4698   char *t = 0;
4699
4700   switch (i)
4701     {
4702 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4703       foreach_vnet_dscp
4704 #undef _
4705     default:
4706       return format (s, "ILLEGAL");
4707     }
4708   s = format (s, "%s", t);
4709   return s;
4710 }
4711
4712 static void
4713 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4714 {
4715   vat_main_t *vam = &vat_main;
4716   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4717
4718   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4719     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4720   else
4721     conform_dscp_str = format (0, "");
4722
4723   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4724     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4725   else
4726     exceed_dscp_str = format (0, "");
4727
4728   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4729     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4730   else
4731     violate_dscp_str = format (0, "");
4732
4733   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4734          "rate type %U, round type %U, %s rate, %s color-aware, "
4735          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4736          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4737          "conform action %U%s, exceed action %U%s, violate action %U%s",
4738          mp->name,
4739          format_policer_type, mp->type,
4740          ntohl (mp->cir),
4741          ntohl (mp->eir),
4742          clib_net_to_host_u64 (mp->cb),
4743          clib_net_to_host_u64 (mp->eb),
4744          format_policer_rate_type, mp->rate_type,
4745          format_policer_round_type, mp->round_type,
4746          mp->single_rate ? "single" : "dual",
4747          mp->color_aware ? "is" : "not",
4748          ntohl (mp->cir_tokens_per_period),
4749          ntohl (mp->pir_tokens_per_period),
4750          ntohl (mp->scale),
4751          ntohl (mp->current_limit),
4752          ntohl (mp->current_bucket),
4753          ntohl (mp->extended_limit),
4754          ntohl (mp->extended_bucket),
4755          clib_net_to_host_u64 (mp->last_update_time),
4756          format_policer_action_type, mp->conform_action_type,
4757          conform_dscp_str,
4758          format_policer_action_type, mp->exceed_action_type,
4759          exceed_dscp_str,
4760          format_policer_action_type, mp->violate_action_type,
4761          violate_dscp_str);
4762
4763   vec_free (conform_dscp_str);
4764   vec_free (exceed_dscp_str);
4765   vec_free (violate_dscp_str);
4766 }
4767
4768 static void vl_api_policer_details_t_handler_json
4769   (vl_api_policer_details_t * mp)
4770 {
4771   vat_main_t *vam = &vat_main;
4772   vat_json_node_t *node;
4773   u8 *rate_type_str, *round_type_str, *type_str;
4774   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4775
4776   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4777   round_type_str =
4778     format (0, "%U", format_policer_round_type, mp->round_type);
4779   type_str = format (0, "%U", format_policer_type, mp->type);
4780   conform_action_str = format (0, "%U", format_policer_action_type,
4781                                mp->conform_action_type);
4782   exceed_action_str = format (0, "%U", format_policer_action_type,
4783                               mp->exceed_action_type);
4784   violate_action_str = format (0, "%U", format_policer_action_type,
4785                                mp->violate_action_type);
4786
4787   if (VAT_JSON_ARRAY != vam->json_tree.type)
4788     {
4789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4790       vat_json_init_array (&vam->json_tree);
4791     }
4792   node = vat_json_array_add (&vam->json_tree);
4793
4794   vat_json_init_object (node);
4795   vat_json_object_add_string_copy (node, "name", mp->name);
4796   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4797   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4798   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4799   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4800   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4801   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4802   vat_json_object_add_string_copy (node, "type", type_str);
4803   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4804   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4805   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4806   vat_json_object_add_uint (node, "cir_tokens_per_period",
4807                             ntohl (mp->cir_tokens_per_period));
4808   vat_json_object_add_uint (node, "eir_tokens_per_period",
4809                             ntohl (mp->pir_tokens_per_period));
4810   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4811   vat_json_object_add_uint (node, "current_bucket",
4812                             ntohl (mp->current_bucket));
4813   vat_json_object_add_uint (node, "extended_limit",
4814                             ntohl (mp->extended_limit));
4815   vat_json_object_add_uint (node, "extended_bucket",
4816                             ntohl (mp->extended_bucket));
4817   vat_json_object_add_uint (node, "last_update_time",
4818                             ntohl (mp->last_update_time));
4819   vat_json_object_add_string_copy (node, "conform_action",
4820                                    conform_action_str);
4821   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     {
4823       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4824       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4825       vec_free (dscp_str);
4826     }
4827   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4828   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4829     {
4830       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4831       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4832       vec_free (dscp_str);
4833     }
4834   vat_json_object_add_string_copy (node, "violate_action",
4835                                    violate_action_str);
4836   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4837     {
4838       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4839       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4840       vec_free (dscp_str);
4841     }
4842
4843   vec_free (rate_type_str);
4844   vec_free (round_type_str);
4845   vec_free (type_str);
4846   vec_free (conform_action_str);
4847   vec_free (exceed_action_str);
4848   vec_free (violate_action_str);
4849 }
4850
4851 static void
4852 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4853                                            mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   int i, count = ntohl (mp->count);
4857
4858   if (count > 0)
4859     print (vam->ofp, "classify table ids (%d) : ", count);
4860   for (i = 0; i < count; i++)
4861     {
4862       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4863       print (vam->ofp, (i < count - 1) ? "," : "");
4864     }
4865   vam->retval = ntohl (mp->retval);
4866   vam->result_ready = 1;
4867 }
4868
4869 static void
4870   vl_api_classify_table_ids_reply_t_handler_json
4871   (vl_api_classify_table_ids_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   int i, count = ntohl (mp->count);
4875
4876   if (count > 0)
4877     {
4878       vat_json_node_t node;
4879
4880       vat_json_init_object (&node);
4881       for (i = 0; i < count; i++)
4882         {
4883           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4884         }
4885       vat_json_print (vam->ofp, &node);
4886       vat_json_free (&node);
4887     }
4888   vam->retval = ntohl (mp->retval);
4889   vam->result_ready = 1;
4890 }
4891
4892 static void
4893   vl_api_classify_table_by_interface_reply_t_handler
4894   (vl_api_classify_table_by_interface_reply_t * mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897   u32 table_id;
4898
4899   table_id = ntohl (mp->l2_table_id);
4900   if (table_id != ~0)
4901     print (vam->ofp, "l2 table id : %d", table_id);
4902   else
4903     print (vam->ofp, "l2 table id : No input ACL tables configured");
4904   table_id = ntohl (mp->ip4_table_id);
4905   if (table_id != ~0)
4906     print (vam->ofp, "ip4 table id : %d", table_id);
4907   else
4908     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4909   table_id = ntohl (mp->ip6_table_id);
4910   if (table_id != ~0)
4911     print (vam->ofp, "ip6 table id : %d", table_id);
4912   else
4913     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4914   vam->retval = ntohl (mp->retval);
4915   vam->result_ready = 1;
4916 }
4917
4918 static void
4919   vl_api_classify_table_by_interface_reply_t_handler_json
4920   (vl_api_classify_table_by_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   vat_json_init_object (&node);
4926
4927   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4928   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4929   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4930
4931   vat_json_print (vam->ofp, &node);
4932   vat_json_free (&node);
4933
4934   vam->retval = ntohl (mp->retval);
4935   vam->result_ready = 1;
4936 }
4937
4938 static void vl_api_policer_add_del_reply_t_handler
4939   (vl_api_policer_add_del_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   i32 retval = ntohl (mp->retval);
4943   if (vam->async_mode)
4944     {
4945       vam->async_errors += (retval < 0);
4946     }
4947   else
4948     {
4949       vam->retval = retval;
4950       vam->result_ready = 1;
4951       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4952         /*
4953          * Note: this is just barely thread-safe, depends on
4954          * the main thread spinning waiting for an answer...
4955          */
4956         errmsg ("policer index %d", ntohl (mp->policer_index));
4957     }
4958 }
4959
4960 static void vl_api_policer_add_del_reply_t_handler_json
4961   (vl_api_policer_add_del_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   vat_json_init_object (&node);
4967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4968   vat_json_object_add_uint (&node, "policer_index",
4969                             ntohl (mp->policer_index));
4970
4971   vat_json_print (vam->ofp, &node);
4972   vat_json_free (&node);
4973
4974   vam->retval = ntohl (mp->retval);
4975   vam->result_ready = 1;
4976 }
4977
4978 /* Format hex dump. */
4979 u8 *
4980 format_hex_bytes (u8 * s, va_list * va)
4981 {
4982   u8 *bytes = va_arg (*va, u8 *);
4983   int n_bytes = va_arg (*va, int);
4984   uword i;
4985
4986   /* Print short or long form depending on byte count. */
4987   uword short_form = n_bytes <= 32;
4988   u32 indent = format_get_indent (s);
4989
4990   if (n_bytes == 0)
4991     return s;
4992
4993   for (i = 0; i < n_bytes; i++)
4994     {
4995       if (!short_form && (i % 32) == 0)
4996         s = format (s, "%08x: ", i);
4997       s = format (s, "%02x", bytes[i]);
4998       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4999         s = format (s, "\n%U", format_white_space, indent);
5000     }
5001
5002   return s;
5003 }
5004
5005 static void
5006 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5007                                             * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010   i32 retval = ntohl (mp->retval);
5011   if (retval == 0)
5012     {
5013       print (vam->ofp, "classify table info :");
5014       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5015              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5016              ntohl (mp->miss_next_index));
5017       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5018              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5019              ntohl (mp->match_n_vectors));
5020       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5021              ntohl (mp->mask_length));
5022     }
5023   vam->retval = retval;
5024   vam->result_ready = 1;
5025 }
5026
5027 static void
5028   vl_api_classify_table_info_reply_t_handler_json
5029   (vl_api_classify_table_info_reply_t * mp)
5030 {
5031   vat_main_t *vam = &vat_main;
5032   vat_json_node_t node;
5033
5034   i32 retval = ntohl (mp->retval);
5035   if (retval == 0)
5036     {
5037       vat_json_init_object (&node);
5038
5039       vat_json_object_add_int (&node, "sessions",
5040                                ntohl (mp->active_sessions));
5041       vat_json_object_add_int (&node, "nexttbl",
5042                                ntohl (mp->next_table_index));
5043       vat_json_object_add_int (&node, "nextnode",
5044                                ntohl (mp->miss_next_index));
5045       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5046       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5047       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5048       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5049                       ntohl (mp->mask_length), 0);
5050       vat_json_object_add_string_copy (&node, "mask", s);
5051
5052       vat_json_print (vam->ofp, &node);
5053       vat_json_free (&node);
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void
5060 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5061                                            mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064
5065   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5066          ntohl (mp->hit_next_index), ntohl (mp->advance),
5067          ntohl (mp->opaque_index));
5068   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5069          ntohl (mp->match_length));
5070 }
5071
5072 static void
5073   vl_api_classify_session_details_t_handler_json
5074   (vl_api_classify_session_details_t * mp)
5075 {
5076   vat_main_t *vam = &vat_main;
5077   vat_json_node_t *node = NULL;
5078
5079   if (VAT_JSON_ARRAY != vam->json_tree.type)
5080     {
5081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5082       vat_json_init_array (&vam->json_tree);
5083     }
5084   node = vat_json_array_add (&vam->json_tree);
5085
5086   vat_json_init_object (node);
5087   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5088   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5089   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5090   u8 *s =
5091     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5092             0);
5093   vat_json_object_add_string_copy (node, "match", s);
5094 }
5095
5096 static void vl_api_pg_create_interface_reply_t_handler
5097   (vl_api_pg_create_interface_reply_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100
5101   vam->retval = ntohl (mp->retval);
5102   vam->result_ready = 1;
5103 }
5104
5105 static void vl_api_pg_create_interface_reply_t_handler_json
5106   (vl_api_pg_create_interface_reply_t * mp)
5107 {
5108   vat_main_t *vam = &vat_main;
5109   vat_json_node_t node;
5110
5111   i32 retval = ntohl (mp->retval);
5112   if (retval == 0)
5113     {
5114       vat_json_init_object (&node);
5115
5116       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5117
5118       vat_json_print (vam->ofp, &node);
5119       vat_json_free (&node);
5120     }
5121   vam->retval = ntohl (mp->retval);
5122   vam->result_ready = 1;
5123 }
5124
5125 static void vl_api_policer_classify_details_t_handler
5126   (vl_api_policer_classify_details_t * mp)
5127 {
5128   vat_main_t *vam = &vat_main;
5129
5130   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5131          ntohl (mp->table_index));
5132 }
5133
5134 static void vl_api_policer_classify_details_t_handler_json
5135   (vl_api_policer_classify_details_t * mp)
5136 {
5137   vat_main_t *vam = &vat_main;
5138   vat_json_node_t *node;
5139
5140   if (VAT_JSON_ARRAY != vam->json_tree.type)
5141     {
5142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5143       vat_json_init_array (&vam->json_tree);
5144     }
5145   node = vat_json_array_add (&vam->json_tree);
5146
5147   vat_json_init_object (node);
5148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5149   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5150 }
5151
5152 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5153   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5154 {
5155   vat_main_t *vam = &vat_main;
5156   i32 retval = ntohl (mp->retval);
5157   if (vam->async_mode)
5158     {
5159       vam->async_errors += (retval < 0);
5160     }
5161   else
5162     {
5163       vam->retval = retval;
5164       vam->sw_if_index = ntohl (mp->sw_if_index);
5165       vam->result_ready = 1;
5166     }
5167   vam->regenerate_interface_table = 1;
5168 }
5169
5170 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5171   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5172 {
5173   vat_main_t *vam = &vat_main;
5174   vat_json_node_t node;
5175
5176   vat_json_init_object (&node);
5177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5178   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5179
5180   vat_json_print (vam->ofp, &node);
5181   vat_json_free (&node);
5182
5183   vam->retval = ntohl (mp->retval);
5184   vam->result_ready = 1;
5185 }
5186
5187 static void vl_api_flow_classify_details_t_handler
5188   (vl_api_flow_classify_details_t * mp)
5189 {
5190   vat_main_t *vam = &vat_main;
5191
5192   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5193          ntohl (mp->table_index));
5194 }
5195
5196 static void vl_api_flow_classify_details_t_handler_json
5197   (vl_api_flow_classify_details_t * mp)
5198 {
5199   vat_main_t *vam = &vat_main;
5200   vat_json_node_t *node;
5201
5202   if (VAT_JSON_ARRAY != vam->json_tree.type)
5203     {
5204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5205       vat_json_init_array (&vam->json_tree);
5206     }
5207   node = vat_json_array_add (&vam->json_tree);
5208
5209   vat_json_init_object (node);
5210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5211   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5212 }
5213
5214 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5215 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5216 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5217 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5218 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5219 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5220 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5221 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5222 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5223 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5224 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5225 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5226 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5227 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5228 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5229 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5230 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5232 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5233 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5234 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5235 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5236
5237 /*
5238  * Generate boilerplate reply handlers, which
5239  * dig the return value out of the xxx_reply_t API message,
5240  * stick it into vam->retval, and set vam->result_ready
5241  *
5242  * Could also do this by pointing N message decode slots at
5243  * a single function, but that could break in subtle ways.
5244  */
5245
5246 #define foreach_standard_reply_retval_handler           \
5247 _(sw_interface_set_flags_reply)                         \
5248 _(sw_interface_add_del_address_reply)                   \
5249 _(sw_interface_set_rx_mode_reply)                       \
5250 _(sw_interface_set_table_reply)                         \
5251 _(sw_interface_set_mpls_enable_reply)                   \
5252 _(sw_interface_set_vpath_reply)                         \
5253 _(sw_interface_set_vxlan_bypass_reply)                  \
5254 _(sw_interface_set_geneve_bypass_reply)                 \
5255 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5256 _(sw_interface_set_l2_bridge_reply)                     \
5257 _(bridge_domain_add_del_reply)                          \
5258 _(sw_interface_set_l2_xconnect_reply)                   \
5259 _(l2fib_add_del_reply)                                  \
5260 _(l2fib_flush_int_reply)                                \
5261 _(l2fib_flush_bd_reply)                                 \
5262 _(ip_add_del_route_reply)                               \
5263 _(ip_table_add_del_reply)                               \
5264 _(ip_mroute_add_del_reply)                              \
5265 _(mpls_route_add_del_reply)                             \
5266 _(mpls_table_add_del_reply)                             \
5267 _(mpls_ip_bind_unbind_reply)                            \
5268 _(bier_route_add_del_reply)                             \
5269 _(bier_table_add_del_reply)                             \
5270 _(proxy_arp_add_del_reply)                              \
5271 _(proxy_arp_intfc_enable_disable_reply)                 \
5272 _(sw_interface_set_unnumbered_reply)                    \
5273 _(ip_neighbor_add_del_reply)                            \
5274 _(oam_add_del_reply)                                    \
5275 _(reset_fib_reply)                                      \
5276 _(dhcp_proxy_config_reply)                              \
5277 _(dhcp_proxy_set_vss_reply)                             \
5278 _(dhcp_client_config_reply)                             \
5279 _(set_ip_flow_hash_reply)                               \
5280 _(sw_interface_ip6_enable_disable_reply)                \
5281 _(sw_interface_ip6_set_link_local_address_reply)        \
5282 _(ip6nd_proxy_add_del_reply)                            \
5283 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5284 _(sw_interface_ip6nd_ra_config_reply)                   \
5285 _(set_arp_neighbor_limit_reply)                         \
5286 _(l2_patch_add_del_reply)                               \
5287 _(sr_policy_add_reply)                                  \
5288 _(sr_policy_mod_reply)                                  \
5289 _(sr_policy_del_reply)                                  \
5290 _(sr_localsid_add_del_reply)                            \
5291 _(sr_steering_add_del_reply)                            \
5292 _(classify_add_del_session_reply)                       \
5293 _(classify_set_interface_ip_table_reply)                \
5294 _(classify_set_interface_l2_tables_reply)               \
5295 _(l2tpv3_set_tunnel_cookies_reply)                      \
5296 _(l2tpv3_interface_enable_disable_reply)                \
5297 _(l2tpv3_set_lookup_key_reply)                          \
5298 _(l2_fib_clear_table_reply)                             \
5299 _(l2_interface_efp_filter_reply)                        \
5300 _(l2_interface_vlan_tag_rewrite_reply)                  \
5301 _(modify_vhost_user_if_reply)                           \
5302 _(delete_vhost_user_if_reply)                           \
5303 _(want_ip4_arp_events_reply)                            \
5304 _(want_ip6_nd_events_reply)                             \
5305 _(want_l2_macs_events_reply)                            \
5306 _(input_acl_set_interface_reply)                        \
5307 _(ipsec_spd_add_del_reply)                              \
5308 _(ipsec_interface_add_del_spd_reply)                    \
5309 _(ipsec_spd_add_del_entry_reply)                        \
5310 _(ipsec_sad_add_del_entry_reply)                        \
5311 _(ipsec_sa_set_key_reply)                               \
5312 _(ipsec_tunnel_if_add_del_reply)                        \
5313 _(ipsec_tunnel_if_set_key_reply)                        \
5314 _(ipsec_tunnel_if_set_sa_reply)                         \
5315 _(ikev2_profile_add_del_reply)                          \
5316 _(ikev2_profile_set_auth_reply)                         \
5317 _(ikev2_profile_set_id_reply)                           \
5318 _(ikev2_profile_set_ts_reply)                           \
5319 _(ikev2_set_local_key_reply)                            \
5320 _(ikev2_set_responder_reply)                            \
5321 _(ikev2_set_ike_transforms_reply)                       \
5322 _(ikev2_set_esp_transforms_reply)                       \
5323 _(ikev2_set_sa_lifetime_reply)                          \
5324 _(ikev2_initiate_sa_init_reply)                         \
5325 _(ikev2_initiate_del_ike_sa_reply)                      \
5326 _(ikev2_initiate_del_child_sa_reply)                    \
5327 _(ikev2_initiate_rekey_child_sa_reply)                  \
5328 _(delete_loopback_reply)                                \
5329 _(bd_ip_mac_add_del_reply)                              \
5330 _(map_del_domain_reply)                                 \
5331 _(map_add_del_rule_reply)                               \
5332 _(want_interface_events_reply)                          \
5333 _(want_stats_reply)                                     \
5334 _(cop_interface_enable_disable_reply)                   \
5335 _(cop_whitelist_enable_disable_reply)                   \
5336 _(sw_interface_clear_stats_reply)                       \
5337 _(ioam_enable_reply)                                    \
5338 _(ioam_disable_reply)                                   \
5339 _(one_add_del_locator_reply)                            \
5340 _(one_add_del_local_eid_reply)                          \
5341 _(one_add_del_remote_mapping_reply)                     \
5342 _(one_add_del_adjacency_reply)                          \
5343 _(one_add_del_map_resolver_reply)                       \
5344 _(one_add_del_map_server_reply)                         \
5345 _(one_enable_disable_reply)                             \
5346 _(one_rloc_probe_enable_disable_reply)                  \
5347 _(one_map_register_enable_disable_reply)                \
5348 _(one_map_register_set_ttl_reply)                       \
5349 _(one_set_transport_protocol_reply)                     \
5350 _(one_map_register_fallback_threshold_reply)            \
5351 _(one_pitr_set_locator_set_reply)                       \
5352 _(one_map_request_mode_reply)                           \
5353 _(one_add_del_map_request_itr_rlocs_reply)              \
5354 _(one_eid_table_add_del_map_reply)                      \
5355 _(one_use_petr_reply)                                   \
5356 _(one_stats_enable_disable_reply)                       \
5357 _(one_add_del_l2_arp_entry_reply)                       \
5358 _(one_add_del_ndp_entry_reply)                          \
5359 _(one_stats_flush_reply)                                \
5360 _(one_enable_disable_xtr_mode_reply)                    \
5361 _(one_enable_disable_pitr_mode_reply)                   \
5362 _(one_enable_disable_petr_mode_reply)                   \
5363 _(gpe_enable_disable_reply)                             \
5364 _(gpe_set_encap_mode_reply)                             \
5365 _(gpe_add_del_iface_reply)                              \
5366 _(gpe_add_del_native_fwd_rpath_reply)                   \
5367 _(af_packet_delete_reply)                               \
5368 _(policer_classify_set_interface_reply)                 \
5369 _(netmap_create_reply)                                  \
5370 _(netmap_delete_reply)                                  \
5371 _(set_ipfix_exporter_reply)                             \
5372 _(set_ipfix_classify_stream_reply)                      \
5373 _(ipfix_classify_table_add_del_reply)                   \
5374 _(flow_classify_set_interface_reply)                    \
5375 _(sw_interface_span_enable_disable_reply)               \
5376 _(pg_capture_reply)                                     \
5377 _(pg_enable_disable_reply)                              \
5378 _(ip_source_and_port_range_check_add_del_reply)         \
5379 _(ip_source_and_port_range_check_interface_add_del_reply)\
5380 _(delete_subif_reply)                                   \
5381 _(l2_interface_pbb_tag_rewrite_reply)                   \
5382 _(punt_reply)                                           \
5383 _(feature_enable_disable_reply)                         \
5384 _(sw_interface_tag_add_del_reply)                       \
5385 _(sw_interface_set_mtu_reply)                           \
5386 _(p2p_ethernet_add_reply)                               \
5387 _(p2p_ethernet_del_reply)                               \
5388 _(lldp_config_reply)                                    \
5389 _(sw_interface_set_lldp_reply)                          \
5390 _(tcp_configure_src_addresses_reply)                    \
5391 _(dns_enable_disable_reply)                             \
5392 _(dns_name_server_add_del_reply)                        \
5393 _(session_rule_add_del_reply)                           \
5394 _(ip_container_proxy_add_del_reply)
5395
5396 #define _(n)                                    \
5397     static void vl_api_##n##_t_handler          \
5398     (vl_api_##n##_t * mp)                       \
5399     {                                           \
5400         vat_main_t * vam = &vat_main;           \
5401         i32 retval = ntohl(mp->retval);         \
5402         if (vam->async_mode) {                  \
5403             vam->async_errors += (retval < 0);  \
5404         } else {                                \
5405             vam->retval = retval;               \
5406             vam->result_ready = 1;              \
5407         }                                       \
5408     }
5409 foreach_standard_reply_retval_handler;
5410 #undef _
5411
5412 #define _(n)                                    \
5413     static void vl_api_##n##_t_handler_json     \
5414     (vl_api_##n##_t * mp)                       \
5415     {                                           \
5416         vat_main_t * vam = &vat_main;           \
5417         vat_json_node_t node;                   \
5418         vat_json_init_object(&node);            \
5419         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5420         vat_json_print(vam->ofp, &node);        \
5421         vam->retval = ntohl(mp->retval);        \
5422         vam->result_ready = 1;                  \
5423     }
5424 foreach_standard_reply_retval_handler;
5425 #undef _
5426
5427 /*
5428  * Table of message reply handlers, must include boilerplate handlers
5429  * we just generated
5430  */
5431
5432 #define foreach_vpe_api_reply_msg                                       \
5433 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5434 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5435 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5436 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5437 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5438 _(CLI_REPLY, cli_reply)                                                 \
5439 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5440 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5441   sw_interface_add_del_address_reply)                                   \
5442 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5443 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5444 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5445 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5446 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5447 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5448 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5449 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5450   sw_interface_set_l2_xconnect_reply)                                   \
5451 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5452   sw_interface_set_l2_bridge_reply)                                     \
5453 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5454 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5455 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5456 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5457 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5458 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5459 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5460 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5461 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5462 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5463 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5464 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5465 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5466 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5467 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5468 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5469 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5470 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5471 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5472 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5473 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5474 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5475 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5476 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5477 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5478   proxy_arp_intfc_enable_disable_reply)                                 \
5479 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5480 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5481   sw_interface_set_unnumbered_reply)                                    \
5482 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5483 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5484 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5485 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5486 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5487 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5488 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5489 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5490 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5491 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5492 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5493   sw_interface_ip6_enable_disable_reply)                                \
5494 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5495   sw_interface_ip6_set_link_local_address_reply)                        \
5496 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5497 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5498 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5499   sw_interface_ip6nd_ra_prefix_reply)                                   \
5500 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5501   sw_interface_ip6nd_ra_config_reply)                                   \
5502 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5503 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5504 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5505 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5506 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5507 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5508 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5509 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5510 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5511 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5512 classify_set_interface_ip_table_reply)                                  \
5513 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5514   classify_set_interface_l2_tables_reply)                               \
5515 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5516 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5517 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5518 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5519 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5520   l2tpv3_interface_enable_disable_reply)                                \
5521 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5522 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5523 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5524 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5525 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5526 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5527 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5528 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5529 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5530 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5531 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5532 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5533 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5534 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5535 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5536 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5537 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5538 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5539 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5540 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5541 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5542 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5543 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5544 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5545 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5546 _(L2_MACS_EVENT, l2_macs_event)                                         \
5547 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5548 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5549 _(IP_DETAILS, ip_details)                                               \
5550 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5551 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5552 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5553 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5554 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5555 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5556 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5557 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5558 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5559 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5560 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5561 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5562 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5563 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5564 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5565 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5566 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5567 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5568 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5569 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5570 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5571 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5572 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5573 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5574 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5575 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5576 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5577 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5578 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5579 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5580 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5581 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5582 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5583 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5584 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5585 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5586 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5587 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5588 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5589 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5590 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5591 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5592 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5593 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5594 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5595 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5596 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5597 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5598   one_map_register_enable_disable_reply)                                \
5599 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5600 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5601 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5602 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5603   one_map_register_fallback_threshold_reply)                            \
5604 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5605   one_rloc_probe_enable_disable_reply)                                  \
5606 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5607 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5608 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5609 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5610 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5611 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5612 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5613 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5614 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5615 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5616 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5617 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5618 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5619 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5620 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5621 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5622   show_one_stats_enable_disable_reply)                                  \
5623 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5624 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5625 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5626 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5627 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5628 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5629 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5630 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5631   one_enable_disable_pitr_mode_reply)                                   \
5632 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5633   one_enable_disable_petr_mode_reply)                                   \
5634 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5635 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5636 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5637 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5638 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5639 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5640 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5641 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5642 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5643 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5644 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5645 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5646   gpe_add_del_native_fwd_rpath_reply)                                   \
5647 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5648   gpe_fwd_entry_path_details)                                           \
5649 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5650 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5651   one_add_del_map_request_itr_rlocs_reply)                              \
5652 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5653   one_get_map_request_itr_rlocs_reply)                                  \
5654 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5655 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5656 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5657 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5658 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5659 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5660   show_one_map_register_state_reply)                                    \
5661 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5662 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5663   show_one_map_register_fallback_threshold_reply)                       \
5664 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5665 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5666 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5667 _(POLICER_DETAILS, policer_details)                                     \
5668 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5669 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5670 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5671 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5672 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5673 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5674 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5675 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5676 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5677 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5678 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5679 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5680 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5681 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5682 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5683 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5684 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5685 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5686 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5687 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5688 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5689 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5690 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5691 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5692 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5693  ip_source_and_port_range_check_add_del_reply)                          \
5694 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5695  ip_source_and_port_range_check_interface_add_del_reply)                \
5696 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5697 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5698 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5699 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5700 _(PUNT_REPLY, punt_reply)                                               \
5701 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5702 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5703 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5704 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5705 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5706 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5707 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5708 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5709 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5710 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5711 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5712 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5713 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5714 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5715 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5716 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5717 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5718 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5719 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5720 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5721 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5722
5723 #define foreach_standalone_reply_msg                                    \
5724 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5725 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5726 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5727 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5728 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5729 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5730 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5731 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5732
5733 typedef struct
5734 {
5735   u8 *name;
5736   u32 value;
5737 } name_sort_t;
5738
5739
5740 #define STR_VTR_OP_CASE(op)     \
5741     case L2_VTR_ ## op:         \
5742         return "" # op;
5743
5744 static const char *
5745 str_vtr_op (u32 vtr_op)
5746 {
5747   switch (vtr_op)
5748     {
5749       STR_VTR_OP_CASE (DISABLED);
5750       STR_VTR_OP_CASE (PUSH_1);
5751       STR_VTR_OP_CASE (PUSH_2);
5752       STR_VTR_OP_CASE (POP_1);
5753       STR_VTR_OP_CASE (POP_2);
5754       STR_VTR_OP_CASE (TRANSLATE_1_1);
5755       STR_VTR_OP_CASE (TRANSLATE_1_2);
5756       STR_VTR_OP_CASE (TRANSLATE_2_1);
5757       STR_VTR_OP_CASE (TRANSLATE_2_2);
5758     }
5759
5760   return "UNKNOWN";
5761 }
5762
5763 static int
5764 dump_sub_interface_table (vat_main_t * vam)
5765 {
5766   const sw_interface_subif_t *sub = NULL;
5767
5768   if (vam->json_output)
5769     {
5770       clib_warning
5771         ("JSON output supported only for VPE API calls and dump_stats_table");
5772       return -99;
5773     }
5774
5775   print (vam->ofp,
5776          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5777          "Interface", "sw_if_index",
5778          "sub id", "dot1ad", "tags", "outer id",
5779          "inner id", "exact", "default", "outer any", "inner any");
5780
5781   vec_foreach (sub, vam->sw_if_subif_table)
5782   {
5783     print (vam->ofp,
5784            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5785            sub->interface_name,
5786            sub->sw_if_index,
5787            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5788            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5789            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5790            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5791     if (sub->vtr_op != L2_VTR_DISABLED)
5792       {
5793         print (vam->ofp,
5794                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5795                "tag1: %d tag2: %d ]",
5796                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5797                sub->vtr_tag1, sub->vtr_tag2);
5798       }
5799   }
5800
5801   return 0;
5802 }
5803
5804 static int
5805 name_sort_cmp (void *a1, void *a2)
5806 {
5807   name_sort_t *n1 = a1;
5808   name_sort_t *n2 = a2;
5809
5810   return strcmp ((char *) n1->name, (char *) n2->name);
5811 }
5812
5813 static int
5814 dump_interface_table (vat_main_t * vam)
5815 {
5816   hash_pair_t *p;
5817   name_sort_t *nses = 0, *ns;
5818
5819   if (vam->json_output)
5820     {
5821       clib_warning
5822         ("JSON output supported only for VPE API calls and dump_stats_table");
5823       return -99;
5824     }
5825
5826   /* *INDENT-OFF* */
5827   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5828   ({
5829     vec_add2 (nses, ns, 1);
5830     ns->name = (u8 *)(p->key);
5831     ns->value = (u32) p->value[0];
5832   }));
5833   /* *INDENT-ON* */
5834
5835   vec_sort_with_function (nses, name_sort_cmp);
5836
5837   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5838   vec_foreach (ns, nses)
5839   {
5840     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5841   }
5842   vec_free (nses);
5843   return 0;
5844 }
5845
5846 static int
5847 dump_ip_table (vat_main_t * vam, int is_ipv6)
5848 {
5849   const ip_details_t *det = NULL;
5850   const ip_address_details_t *address = NULL;
5851   u32 i = ~0;
5852
5853   print (vam->ofp, "%-12s", "sw_if_index");
5854
5855   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5856   {
5857     i++;
5858     if (!det->present)
5859       {
5860         continue;
5861       }
5862     print (vam->ofp, "%-12d", i);
5863     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5864     if (!det->addr)
5865       {
5866         continue;
5867       }
5868     vec_foreach (address, det->addr)
5869     {
5870       print (vam->ofp,
5871              "            %-30U%-13d",
5872              is_ipv6 ? format_ip6_address : format_ip4_address,
5873              address->ip, address->prefix_length);
5874     }
5875   }
5876
5877   return 0;
5878 }
5879
5880 static int
5881 dump_ipv4_table (vat_main_t * vam)
5882 {
5883   if (vam->json_output)
5884     {
5885       clib_warning
5886         ("JSON output supported only for VPE API calls and dump_stats_table");
5887       return -99;
5888     }
5889
5890   return dump_ip_table (vam, 0);
5891 }
5892
5893 static int
5894 dump_ipv6_table (vat_main_t * vam)
5895 {
5896   if (vam->json_output)
5897     {
5898       clib_warning
5899         ("JSON output supported only for VPE API calls and dump_stats_table");
5900       return -99;
5901     }
5902
5903   return dump_ip_table (vam, 1);
5904 }
5905
5906 static char *
5907 counter_type_to_str (u8 counter_type, u8 is_combined)
5908 {
5909   if (!is_combined)
5910     {
5911       switch (counter_type)
5912         {
5913         case VNET_INTERFACE_COUNTER_DROP:
5914           return "drop";
5915         case VNET_INTERFACE_COUNTER_PUNT:
5916           return "punt";
5917         case VNET_INTERFACE_COUNTER_IP4:
5918           return "ip4";
5919         case VNET_INTERFACE_COUNTER_IP6:
5920           return "ip6";
5921         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5922           return "rx-no-buf";
5923         case VNET_INTERFACE_COUNTER_RX_MISS:
5924           return "rx-miss";
5925         case VNET_INTERFACE_COUNTER_RX_ERROR:
5926           return "rx-error";
5927         case VNET_INTERFACE_COUNTER_TX_ERROR:
5928           return "tx-error";
5929         default:
5930           return "INVALID-COUNTER-TYPE";
5931         }
5932     }
5933   else
5934     {
5935       switch (counter_type)
5936         {
5937         case VNET_INTERFACE_COUNTER_RX:
5938           return "rx";
5939         case VNET_INTERFACE_COUNTER_TX:
5940           return "tx";
5941         default:
5942           return "INVALID-COUNTER-TYPE";
5943         }
5944     }
5945 }
5946
5947 static int
5948 dump_stats_table (vat_main_t * vam)
5949 {
5950   vat_json_node_t node;
5951   vat_json_node_t *msg_array;
5952   vat_json_node_t *msg;
5953   vat_json_node_t *counter_array;
5954   vat_json_node_t *counter;
5955   interface_counter_t c;
5956   u64 packets;
5957   ip4_fib_counter_t *c4;
5958   ip6_fib_counter_t *c6;
5959   ip4_nbr_counter_t *n4;
5960   ip6_nbr_counter_t *n6;
5961   int i, j;
5962
5963   if (!vam->json_output)
5964     {
5965       clib_warning ("dump_stats_table supported only in JSON format");
5966       return -99;
5967     }
5968
5969   vat_json_init_object (&node);
5970
5971   /* interface counters */
5972   msg_array = vat_json_object_add (&node, "interface_counters");
5973   vat_json_init_array (msg_array);
5974   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5975     {
5976       msg = vat_json_array_add (msg_array);
5977       vat_json_init_object (msg);
5978       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5979                                        (u8 *) counter_type_to_str (i, 0));
5980       vat_json_object_add_int (msg, "is_combined", 0);
5981       counter_array = vat_json_object_add (msg, "data");
5982       vat_json_init_array (counter_array);
5983       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5984         {
5985           packets = vam->simple_interface_counters[i][j];
5986           vat_json_array_add_uint (counter_array, packets);
5987         }
5988     }
5989   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5990     {
5991       msg = vat_json_array_add (msg_array);
5992       vat_json_init_object (msg);
5993       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5994                                        (u8 *) counter_type_to_str (i, 1));
5995       vat_json_object_add_int (msg, "is_combined", 1);
5996       counter_array = vat_json_object_add (msg, "data");
5997       vat_json_init_array (counter_array);
5998       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5999         {
6000           c = vam->combined_interface_counters[i][j];
6001           counter = vat_json_array_add (counter_array);
6002           vat_json_init_object (counter);
6003           vat_json_object_add_uint (counter, "packets", c.packets);
6004           vat_json_object_add_uint (counter, "bytes", c.bytes);
6005         }
6006     }
6007
6008   /* ip4 fib counters */
6009   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6010   vat_json_init_array (msg_array);
6011   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6012     {
6013       msg = vat_json_array_add (msg_array);
6014       vat_json_init_object (msg);
6015       vat_json_object_add_uint (msg, "vrf_id",
6016                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6017       counter_array = vat_json_object_add (msg, "c");
6018       vat_json_init_array (counter_array);
6019       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6020         {
6021           counter = vat_json_array_add (counter_array);
6022           vat_json_init_object (counter);
6023           c4 = &vam->ip4_fib_counters[i][j];
6024           vat_json_object_add_ip4 (counter, "address", c4->address);
6025           vat_json_object_add_uint (counter, "address_length",
6026                                     c4->address_length);
6027           vat_json_object_add_uint (counter, "packets", c4->packets);
6028           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6029         }
6030     }
6031
6032   /* ip6 fib counters */
6033   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6034   vat_json_init_array (msg_array);
6035   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6036     {
6037       msg = vat_json_array_add (msg_array);
6038       vat_json_init_object (msg);
6039       vat_json_object_add_uint (msg, "vrf_id",
6040                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6041       counter_array = vat_json_object_add (msg, "c");
6042       vat_json_init_array (counter_array);
6043       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6044         {
6045           counter = vat_json_array_add (counter_array);
6046           vat_json_init_object (counter);
6047           c6 = &vam->ip6_fib_counters[i][j];
6048           vat_json_object_add_ip6 (counter, "address", c6->address);
6049           vat_json_object_add_uint (counter, "address_length",
6050                                     c6->address_length);
6051           vat_json_object_add_uint (counter, "packets", c6->packets);
6052           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6053         }
6054     }
6055
6056   /* ip4 nbr counters */
6057   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6058   vat_json_init_array (msg_array);
6059   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6060     {
6061       msg = vat_json_array_add (msg_array);
6062       vat_json_init_object (msg);
6063       vat_json_object_add_uint (msg, "sw_if_index", i);
6064       counter_array = vat_json_object_add (msg, "c");
6065       vat_json_init_array (counter_array);
6066       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6067         {
6068           counter = vat_json_array_add (counter_array);
6069           vat_json_init_object (counter);
6070           n4 = &vam->ip4_nbr_counters[i][j];
6071           vat_json_object_add_ip4 (counter, "address", n4->address);
6072           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6073           vat_json_object_add_uint (counter, "packets", n4->packets);
6074           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6075         }
6076     }
6077
6078   /* ip6 nbr counters */
6079   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6080   vat_json_init_array (msg_array);
6081   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6082     {
6083       msg = vat_json_array_add (msg_array);
6084       vat_json_init_object (msg);
6085       vat_json_object_add_uint (msg, "sw_if_index", i);
6086       counter_array = vat_json_object_add (msg, "c");
6087       vat_json_init_array (counter_array);
6088       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6089         {
6090           counter = vat_json_array_add (counter_array);
6091           vat_json_init_object (counter);
6092           n6 = &vam->ip6_nbr_counters[i][j];
6093           vat_json_object_add_ip6 (counter, "address", n6->address);
6094           vat_json_object_add_uint (counter, "packets", n6->packets);
6095           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6096         }
6097     }
6098
6099   vat_json_print (vam->ofp, &node);
6100   vat_json_free (&node);
6101
6102   return 0;
6103 }
6104
6105 /*
6106  * Pass CLI buffers directly in the CLI_INBAND API message,
6107  * instead of an additional shared memory area.
6108  */
6109 static int
6110 exec_inband (vat_main_t * vam)
6111 {
6112   vl_api_cli_inband_t *mp;
6113   unformat_input_t *i = vam->input;
6114   int ret;
6115
6116   if (vec_len (i->buffer) == 0)
6117     return -1;
6118
6119   if (vam->exec_mode == 0 && unformat (i, "mode"))
6120     {
6121       vam->exec_mode = 1;
6122       return 0;
6123     }
6124   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6125     {
6126       vam->exec_mode = 0;
6127       return 0;
6128     }
6129
6130   /*
6131    * In order for the CLI command to work, it
6132    * must be a vector ending in \n, not a C-string ending
6133    * in \n\0.
6134    */
6135   u32 len = vec_len (vam->input->buffer);
6136   M2 (CLI_INBAND, mp, len);
6137   clib_memcpy (mp->cmd, vam->input->buffer, len);
6138   mp->length = htonl (len);
6139
6140   S (mp);
6141   W (ret);
6142   /* json responses may or may not include a useful reply... */
6143   if (vec_len (vam->cmd_reply))
6144     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6145   return ret;
6146 }
6147
6148 int
6149 exec (vat_main_t * vam)
6150 {
6151   return exec_inband (vam);
6152 }
6153
6154 static int
6155 api_create_loopback (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_create_loopback_t *mp;
6159   vl_api_create_loopback_instance_t *mp_lbi;
6160   u8 mac_address[6];
6161   u8 mac_set = 0;
6162   u8 is_specified = 0;
6163   u32 user_instance = 0;
6164   int ret;
6165
6166   memset (mac_address, 0, sizeof (mac_address));
6167
6168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6169     {
6170       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6171         mac_set = 1;
6172       if (unformat (i, "instance %d", &user_instance))
6173         is_specified = 1;
6174       else
6175         break;
6176     }
6177
6178   if (is_specified)
6179     {
6180       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6181       mp_lbi->is_specified = is_specified;
6182       if (is_specified)
6183         mp_lbi->user_instance = htonl (user_instance);
6184       if (mac_set)
6185         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6186       S (mp_lbi);
6187     }
6188   else
6189     {
6190       /* Construct the API message */
6191       M (CREATE_LOOPBACK, mp);
6192       if (mac_set)
6193         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6194       S (mp);
6195     }
6196
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static int
6202 api_delete_loopback (vat_main_t * vam)
6203 {
6204   unformat_input_t *i = vam->input;
6205   vl_api_delete_loopback_t *mp;
6206   u32 sw_if_index = ~0;
6207   int ret;
6208
6209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6210     {
6211       if (unformat (i, "sw_if_index %d", &sw_if_index))
6212         ;
6213       else
6214         break;
6215     }
6216
6217   if (sw_if_index == ~0)
6218     {
6219       errmsg ("missing sw_if_index");
6220       return -99;
6221     }
6222
6223   /* Construct the API message */
6224   M (DELETE_LOOPBACK, mp);
6225   mp->sw_if_index = ntohl (sw_if_index);
6226
6227   S (mp);
6228   W (ret);
6229   return ret;
6230 }
6231
6232 static int
6233 api_want_stats (vat_main_t * vam)
6234 {
6235   unformat_input_t *i = vam->input;
6236   vl_api_want_stats_t *mp;
6237   int enable = -1;
6238   int ret;
6239
6240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6241     {
6242       if (unformat (i, "enable"))
6243         enable = 1;
6244       else if (unformat (i, "disable"))
6245         enable = 0;
6246       else
6247         break;
6248     }
6249
6250   if (enable == -1)
6251     {
6252       errmsg ("missing enable|disable");
6253       return -99;
6254     }
6255
6256   M (WANT_STATS, mp);
6257   mp->enable_disable = enable;
6258
6259   S (mp);
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static int
6265 api_want_interface_events (vat_main_t * vam)
6266 {
6267   unformat_input_t *i = vam->input;
6268   vl_api_want_interface_events_t *mp;
6269   int enable = -1;
6270   int ret;
6271
6272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6273     {
6274       if (unformat (i, "enable"))
6275         enable = 1;
6276       else if (unformat (i, "disable"))
6277         enable = 0;
6278       else
6279         break;
6280     }
6281
6282   if (enable == -1)
6283     {
6284       errmsg ("missing enable|disable");
6285       return -99;
6286     }
6287
6288   M (WANT_INTERFACE_EVENTS, mp);
6289   mp->enable_disable = enable;
6290
6291   vam->interface_event_display = enable;
6292
6293   S (mp);
6294   W (ret);
6295   return ret;
6296 }
6297
6298
6299 /* Note: non-static, called once to set up the initial intfc table */
6300 int
6301 api_sw_interface_dump (vat_main_t * vam)
6302 {
6303   vl_api_sw_interface_dump_t *mp;
6304   vl_api_control_ping_t *mp_ping;
6305   hash_pair_t *p;
6306   name_sort_t *nses = 0, *ns;
6307   sw_interface_subif_t *sub = NULL;
6308   int ret;
6309
6310   /* Toss the old name table */
6311   /* *INDENT-OFF* */
6312   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6313   ({
6314     vec_add2 (nses, ns, 1);
6315     ns->name = (u8 *)(p->key);
6316     ns->value = (u32) p->value[0];
6317   }));
6318   /* *INDENT-ON* */
6319
6320   hash_free (vam->sw_if_index_by_interface_name);
6321
6322   vec_foreach (ns, nses) vec_free (ns->name);
6323
6324   vec_free (nses);
6325
6326   vec_foreach (sub, vam->sw_if_subif_table)
6327   {
6328     vec_free (sub->interface_name);
6329   }
6330   vec_free (vam->sw_if_subif_table);
6331
6332   /* recreate the interface name hash table */
6333   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6334
6335   /*
6336    * Ask for all interface names. Otherwise, the epic catalog of
6337    * name filters becomes ridiculously long, and vat ends up needing
6338    * to be taught about new interface types.
6339    */
6340   M (SW_INTERFACE_DUMP, mp);
6341   S (mp);
6342
6343   /* Use a control ping for synchronization */
6344   MPING (CONTROL_PING, mp_ping);
6345   S (mp_ping);
6346
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_sw_interface_set_flags (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_sw_interface_set_flags_t *mp;
6356   u32 sw_if_index;
6357   u8 sw_if_index_set = 0;
6358   u8 admin_up = 0;
6359   int ret;
6360
6361   /* Parse args required to build the message */
6362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6363     {
6364       if (unformat (i, "admin-up"))
6365         admin_up = 1;
6366       else if (unformat (i, "admin-down"))
6367         admin_up = 0;
6368       else
6369         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6372         sw_if_index_set = 1;
6373       else
6374         break;
6375     }
6376
6377   if (sw_if_index_set == 0)
6378     {
6379       errmsg ("missing interface name or sw_if_index");
6380       return -99;
6381     }
6382
6383   /* Construct the API message */
6384   M (SW_INTERFACE_SET_FLAGS, mp);
6385   mp->sw_if_index = ntohl (sw_if_index);
6386   mp->admin_up_down = admin_up;
6387
6388   /* send it... */
6389   S (mp);
6390
6391   /* Wait for a reply, return the good/bad news... */
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_rx_mode (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_rx_mode_t *mp;
6401   u32 sw_if_index;
6402   u8 sw_if_index_set = 0;
6403   int ret;
6404   u8 queue_id_valid = 0;
6405   u32 queue_id;
6406   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6407
6408   /* Parse args required to build the message */
6409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410     {
6411       if (unformat (i, "queue %d", &queue_id))
6412         queue_id_valid = 1;
6413       else if (unformat (i, "polling"))
6414         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6415       else if (unformat (i, "interrupt"))
6416         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6417       else if (unformat (i, "adaptive"))
6418         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6419       else
6420         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6421         sw_if_index_set = 1;
6422       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6423         sw_if_index_set = 1;
6424       else
6425         break;
6426     }
6427
6428   if (sw_if_index_set == 0)
6429     {
6430       errmsg ("missing interface name or sw_if_index");
6431       return -99;
6432     }
6433   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6434     {
6435       errmsg ("missing rx-mode");
6436       return -99;
6437     }
6438
6439   /* Construct the API message */
6440   M (SW_INTERFACE_SET_RX_MODE, mp);
6441   mp->sw_if_index = ntohl (sw_if_index);
6442   mp->mode = mode;
6443   mp->queue_id_valid = queue_id_valid;
6444   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply, return the good/bad news... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_clear_stats (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_clear_stats_t *mp;
6459   u32 sw_if_index;
6460   u8 sw_if_index_set = 0;
6461   int ret;
6462
6463   /* Parse args required to build the message */
6464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6465     {
6466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6469         sw_if_index_set = 1;
6470       else
6471         break;
6472     }
6473
6474   /* Construct the API message */
6475   M (SW_INTERFACE_CLEAR_STATS, mp);
6476
6477   if (sw_if_index_set == 1)
6478     mp->sw_if_index = ntohl (sw_if_index);
6479   else
6480     mp->sw_if_index = ~0;
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply, return the good/bad news... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static int
6491 api_sw_interface_add_del_address (vat_main_t * vam)
6492 {
6493   unformat_input_t *i = vam->input;
6494   vl_api_sw_interface_add_del_address_t *mp;
6495   u32 sw_if_index;
6496   u8 sw_if_index_set = 0;
6497   u8 is_add = 1, del_all = 0;
6498   u32 address_length = 0;
6499   u8 v4_address_set = 0;
6500   u8 v6_address_set = 0;
6501   ip4_address_t v4address;
6502   ip6_address_t v6address;
6503   int ret;
6504
6505   /* Parse args required to build the message */
6506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6507     {
6508       if (unformat (i, "del-all"))
6509         del_all = 1;
6510       else if (unformat (i, "del"))
6511         is_add = 0;
6512       else
6513         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6514         sw_if_index_set = 1;
6515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "%U/%d",
6518                          unformat_ip4_address, &v4address, &address_length))
6519         v4_address_set = 1;
6520       else if (unformat (i, "%U/%d",
6521                          unformat_ip6_address, &v6address, &address_length))
6522         v6_address_set = 1;
6523       else
6524         break;
6525     }
6526
6527   if (sw_if_index_set == 0)
6528     {
6529       errmsg ("missing interface name or sw_if_index");
6530       return -99;
6531     }
6532   if (v4_address_set && v6_address_set)
6533     {
6534       errmsg ("both v4 and v6 addresses set");
6535       return -99;
6536     }
6537   if (!v4_address_set && !v6_address_set && !del_all)
6538     {
6539       errmsg ("no addresses set");
6540       return -99;
6541     }
6542
6543   /* Construct the API message */
6544   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6545
6546   mp->sw_if_index = ntohl (sw_if_index);
6547   mp->is_add = is_add;
6548   mp->del_all = del_all;
6549   if (v6_address_set)
6550     {
6551       mp->is_ipv6 = 1;
6552       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6553     }
6554   else
6555     {
6556       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6557     }
6558   mp->address_length = address_length;
6559
6560   /* send it... */
6561   S (mp);
6562
6563   /* Wait for a reply, return good/bad news  */
6564   W (ret);
6565   return ret;
6566 }
6567
6568 static int
6569 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6570 {
6571   unformat_input_t *i = vam->input;
6572   vl_api_sw_interface_set_mpls_enable_t *mp;
6573   u32 sw_if_index;
6574   u8 sw_if_index_set = 0;
6575   u8 enable = 1;
6576   int ret;
6577
6578   /* Parse args required to build the message */
6579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580     {
6581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "disable"))
6586         enable = 0;
6587       else if (unformat (i, "dis"))
6588         enable = 0;
6589       else
6590         break;
6591     }
6592
6593   if (sw_if_index_set == 0)
6594     {
6595       errmsg ("missing interface name or sw_if_index");
6596       return -99;
6597     }
6598
6599   /* Construct the API message */
6600   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6601
6602   mp->sw_if_index = ntohl (sw_if_index);
6603   mp->enable = enable;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply... */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_table (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_table_t *mp;
6618   u32 sw_if_index, vrf_id = 0;
6619   u8 sw_if_index_set = 0;
6620   u8 is_ipv6 = 0;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "vrf %d", &vrf_id))
6631         ;
6632       else if (unformat (i, "ipv6"))
6633         is_ipv6 = 1;
6634       else
6635         break;
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   /* Construct the API message */
6645   M (SW_INTERFACE_SET_TABLE, mp);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->is_ipv6 = is_ipv6;
6649   mp->vrf_id = ntohl (vrf_id);
6650
6651   /* send it... */
6652   S (mp);
6653
6654   /* Wait for a reply... */
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static void vl_api_sw_interface_get_table_reply_t_handler
6660   (vl_api_sw_interface_get_table_reply_t * mp)
6661 {
6662   vat_main_t *vam = &vat_main;
6663
6664   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6665
6666   vam->retval = ntohl (mp->retval);
6667   vam->result_ready = 1;
6668
6669 }
6670
6671 static void vl_api_sw_interface_get_table_reply_t_handler_json
6672   (vl_api_sw_interface_get_table_reply_t * mp)
6673 {
6674   vat_main_t *vam = &vat_main;
6675   vat_json_node_t node;
6676
6677   vat_json_init_object (&node);
6678   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6679   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6680
6681   vat_json_print (vam->ofp, &node);
6682   vat_json_free (&node);
6683
6684   vam->retval = ntohl (mp->retval);
6685   vam->result_ready = 1;
6686 }
6687
6688 static int
6689 api_sw_interface_get_table (vat_main_t * vam)
6690 {
6691   unformat_input_t *i = vam->input;
6692   vl_api_sw_interface_get_table_t *mp;
6693   u32 sw_if_index;
6694   u8 sw_if_index_set = 0;
6695   u8 is_ipv6 = 0;
6696   int ret;
6697
6698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6699     {
6700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6701         sw_if_index_set = 1;
6702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "ipv6"))
6705         is_ipv6 = 1;
6706       else
6707         break;
6708     }
6709
6710   if (sw_if_index_set == 0)
6711     {
6712       errmsg ("missing interface name or sw_if_index");
6713       return -99;
6714     }
6715
6716   M (SW_INTERFACE_GET_TABLE, mp);
6717   mp->sw_if_index = htonl (sw_if_index);
6718   mp->is_ipv6 = is_ipv6;
6719
6720   S (mp);
6721   W (ret);
6722   return ret;
6723 }
6724
6725 static int
6726 api_sw_interface_set_vpath (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_sw_interface_set_vpath_t *mp;
6730   u32 sw_if_index = 0;
6731   u8 sw_if_index_set = 0;
6732   u8 is_enable = 0;
6733   int ret;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6739         sw_if_index_set = 1;
6740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "enable"))
6743         is_enable = 1;
6744       else if (unformat (i, "disable"))
6745         is_enable = 0;
6746       else
6747         break;
6748     }
6749
6750   if (sw_if_index_set == 0)
6751     {
6752       errmsg ("missing interface name or sw_if_index");
6753       return -99;
6754     }
6755
6756   /* Construct the API message */
6757   M (SW_INTERFACE_SET_VPATH, mp);
6758
6759   mp->sw_if_index = ntohl (sw_if_index);
6760   mp->enable = is_enable;
6761
6762   /* send it... */
6763   S (mp);
6764
6765   /* Wait for a reply... */
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6775   u32 sw_if_index = 0;
6776   u8 sw_if_index_set = 0;
6777   u8 is_enable = 1;
6778   u8 is_ipv6 = 0;
6779   int ret;
6780
6781   /* Parse args required to build the message */
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6785         sw_if_index_set = 1;
6786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6787         sw_if_index_set = 1;
6788       else if (unformat (i, "enable"))
6789         is_enable = 1;
6790       else if (unformat (i, "disable"))
6791         is_enable = 0;
6792       else if (unformat (i, "ip4"))
6793         is_ipv6 = 0;
6794       else if (unformat (i, "ip6"))
6795         is_ipv6 = 1;
6796       else
6797         break;
6798     }
6799
6800   if (sw_if_index_set == 0)
6801     {
6802       errmsg ("missing interface name or sw_if_index");
6803       return -99;
6804     }
6805
6806   /* Construct the API message */
6807   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6808
6809   mp->sw_if_index = ntohl (sw_if_index);
6810   mp->enable = is_enable;
6811   mp->is_ipv6 = is_ipv6;
6812
6813   /* send it... */
6814   S (mp);
6815
6816   /* Wait for a reply... */
6817   W (ret);
6818   return ret;
6819 }
6820
6821 static int
6822 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_sw_interface_set_geneve_bypass_t *mp;
6826   u32 sw_if_index = 0;
6827   u8 sw_if_index_set = 0;
6828   u8 is_enable = 1;
6829   u8 is_ipv6 = 0;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "enable"))
6840         is_enable = 1;
6841       else if (unformat (i, "disable"))
6842         is_enable = 0;
6843       else if (unformat (i, "ip4"))
6844         is_ipv6 = 0;
6845       else if (unformat (i, "ip6"))
6846         is_ipv6 = 1;
6847       else
6848         break;
6849     }
6850
6851   if (sw_if_index_set == 0)
6852     {
6853       errmsg ("missing interface name or sw_if_index");
6854       return -99;
6855     }
6856
6857   /* Construct the API message */
6858   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6859
6860   mp->sw_if_index = ntohl (sw_if_index);
6861   mp->enable = is_enable;
6862   mp->is_ipv6 = is_ipv6;
6863
6864   /* send it... */
6865   S (mp);
6866
6867   /* Wait for a reply... */
6868   W (ret);
6869   return ret;
6870 }
6871
6872 static int
6873 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6874 {
6875   unformat_input_t *i = vam->input;
6876   vl_api_sw_interface_set_l2_xconnect_t *mp;
6877   u32 rx_sw_if_index;
6878   u8 rx_sw_if_index_set = 0;
6879   u32 tx_sw_if_index;
6880   u8 tx_sw_if_index_set = 0;
6881   u8 enable = 1;
6882   int ret;
6883
6884   /* Parse args required to build the message */
6885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886     {
6887       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6888         rx_sw_if_index_set = 1;
6889       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6890         tx_sw_if_index_set = 1;
6891       else if (unformat (i, "rx"))
6892         {
6893           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894             {
6895               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6896                             &rx_sw_if_index))
6897                 rx_sw_if_index_set = 1;
6898             }
6899           else
6900             break;
6901         }
6902       else if (unformat (i, "tx"))
6903         {
6904           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905             {
6906               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6907                             &tx_sw_if_index))
6908                 tx_sw_if_index_set = 1;
6909             }
6910           else
6911             break;
6912         }
6913       else if (unformat (i, "enable"))
6914         enable = 1;
6915       else if (unformat (i, "disable"))
6916         enable = 0;
6917       else
6918         break;
6919     }
6920
6921   if (rx_sw_if_index_set == 0)
6922     {
6923       errmsg ("missing rx interface name or rx_sw_if_index");
6924       return -99;
6925     }
6926
6927   if (enable && (tx_sw_if_index_set == 0))
6928     {
6929       errmsg ("missing tx interface name or tx_sw_if_index");
6930       return -99;
6931     }
6932
6933   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6934
6935   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6936   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6937   mp->enable = enable;
6938
6939   S (mp);
6940   W (ret);
6941   return ret;
6942 }
6943
6944 static int
6945 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_sw_interface_set_l2_bridge_t *mp;
6949   u32 rx_sw_if_index;
6950   u8 rx_sw_if_index_set = 0;
6951   u32 bd_id;
6952   u8 bd_id_set = 0;
6953   u8 bvi = 0;
6954   u32 shg = 0;
6955   u8 enable = 1;
6956   int ret;
6957
6958   /* Parse args required to build the message */
6959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960     {
6961       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6962         rx_sw_if_index_set = 1;
6963       else if (unformat (i, "bd_id %d", &bd_id))
6964         bd_id_set = 1;
6965       else
6966         if (unformat
6967             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6968         rx_sw_if_index_set = 1;
6969       else if (unformat (i, "shg %d", &shg))
6970         ;
6971       else if (unformat (i, "bvi"))
6972         bvi = 1;
6973       else if (unformat (i, "enable"))
6974         enable = 1;
6975       else if (unformat (i, "disable"))
6976         enable = 0;
6977       else
6978         break;
6979     }
6980
6981   if (rx_sw_if_index_set == 0)
6982     {
6983       errmsg ("missing rx interface name or sw_if_index");
6984       return -99;
6985     }
6986
6987   if (enable && (bd_id_set == 0))
6988     {
6989       errmsg ("missing bridge domain");
6990       return -99;
6991     }
6992
6993   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6994
6995   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6996   mp->bd_id = ntohl (bd_id);
6997   mp->shg = (u8) shg;
6998   mp->bvi = bvi;
6999   mp->enable = enable;
7000
7001   S (mp);
7002   W (ret);
7003   return ret;
7004 }
7005
7006 static int
7007 api_bridge_domain_dump (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_bridge_domain_dump_t *mp;
7011   vl_api_control_ping_t *mp_ping;
7012   u32 bd_id = ~0;
7013   int ret;
7014
7015   /* Parse args required to build the message */
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "bd_id %d", &bd_id))
7019         ;
7020       else
7021         break;
7022     }
7023
7024   M (BRIDGE_DOMAIN_DUMP, mp);
7025   mp->bd_id = ntohl (bd_id);
7026   S (mp);
7027
7028   /* Use a control ping for synchronization */
7029   MPING (CONTROL_PING, mp_ping);
7030   S (mp_ping);
7031
7032   W (ret);
7033   return ret;
7034 }
7035
7036 static int
7037 api_bridge_domain_add_del (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_bridge_domain_add_del_t *mp;
7041   u32 bd_id = ~0;
7042   u8 is_add = 1;
7043   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7044   u8 *bd_tag = NULL;
7045   u32 mac_age = 0;
7046   int ret;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "bd_id %d", &bd_id))
7052         ;
7053       else if (unformat (i, "flood %d", &flood))
7054         ;
7055       else if (unformat (i, "uu-flood %d", &uu_flood))
7056         ;
7057       else if (unformat (i, "forward %d", &forward))
7058         ;
7059       else if (unformat (i, "learn %d", &learn))
7060         ;
7061       else if (unformat (i, "arp-term %d", &arp_term))
7062         ;
7063       else if (unformat (i, "mac-age %d", &mac_age))
7064         ;
7065       else if (unformat (i, "bd-tag %s", &bd_tag))
7066         ;
7067       else if (unformat (i, "del"))
7068         {
7069           is_add = 0;
7070           flood = uu_flood = forward = learn = 0;
7071         }
7072       else
7073         break;
7074     }
7075
7076   if (bd_id == ~0)
7077     {
7078       errmsg ("missing bridge domain");
7079       ret = -99;
7080       goto done;
7081     }
7082
7083   if (mac_age > 255)
7084     {
7085       errmsg ("mac age must be less than 256 ");
7086       ret = -99;
7087       goto done;
7088     }
7089
7090   if ((bd_tag) && (vec_len (bd_tag) > 63))
7091     {
7092       errmsg ("bd-tag cannot be longer than 63");
7093       ret = -99;
7094       goto done;
7095     }
7096
7097   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7098
7099   mp->bd_id = ntohl (bd_id);
7100   mp->flood = flood;
7101   mp->uu_flood = uu_flood;
7102   mp->forward = forward;
7103   mp->learn = learn;
7104   mp->arp_term = arp_term;
7105   mp->is_add = is_add;
7106   mp->mac_age = (u8) mac_age;
7107   if (bd_tag)
7108     {
7109       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7110       mp->bd_tag[vec_len (bd_tag)] = 0;
7111     }
7112   S (mp);
7113   W (ret);
7114
7115 done:
7116   vec_free (bd_tag);
7117   return ret;
7118 }
7119
7120 static int
7121 api_l2fib_flush_bd (vat_main_t * vam)
7122 {
7123   unformat_input_t *i = vam->input;
7124   vl_api_l2fib_flush_bd_t *mp;
7125   u32 bd_id = ~0;
7126   int ret;
7127
7128   /* Parse args required to build the message */
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "bd_id %d", &bd_id));
7132       else
7133         break;
7134     }
7135
7136   if (bd_id == ~0)
7137     {
7138       errmsg ("missing bridge domain");
7139       return -99;
7140     }
7141
7142   M (L2FIB_FLUSH_BD, mp);
7143
7144   mp->bd_id = htonl (bd_id);
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2fib_flush_int (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2fib_flush_int_t *mp;
7156   u32 sw_if_index = ~0;
7157   int ret;
7158
7159   /* Parse args required to build the message */
7160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161     {
7162       if (unformat (i, "sw_if_index %d", &sw_if_index));
7163       else
7164         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7165       else
7166         break;
7167     }
7168
7169   if (sw_if_index == ~0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174
7175   M (L2FIB_FLUSH_INT, mp);
7176
7177   mp->sw_if_index = ntohl (sw_if_index);
7178
7179   S (mp);
7180   W (ret);
7181   return ret;
7182 }
7183
7184 static int
7185 api_l2fib_add_del (vat_main_t * vam)
7186 {
7187   unformat_input_t *i = vam->input;
7188   vl_api_l2fib_add_del_t *mp;
7189   f64 timeout;
7190   u8 mac[6] = { 0 };
7191   u8 mac_set = 0;
7192   u32 bd_id;
7193   u8 bd_id_set = 0;
7194   u32 sw_if_index = ~0;
7195   u8 sw_if_index_set = 0;
7196   u8 is_add = 1;
7197   u8 static_mac = 0;
7198   u8 filter_mac = 0;
7199   u8 bvi_mac = 0;
7200   int count = 1;
7201   f64 before = 0;
7202   int j;
7203
7204   /* Parse args required to build the message */
7205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7206     {
7207       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7208         mac_set = 1;
7209       else if (unformat (i, "bd_id %d", &bd_id))
7210         bd_id_set = 1;
7211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7212         sw_if_index_set = 1;
7213       else if (unformat (i, "sw_if"))
7214         {
7215           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216             {
7217               if (unformat
7218                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7219                 sw_if_index_set = 1;
7220             }
7221           else
7222             break;
7223         }
7224       else if (unformat (i, "static"))
7225         static_mac = 1;
7226       else if (unformat (i, "filter"))
7227         {
7228           filter_mac = 1;
7229           static_mac = 1;
7230         }
7231       else if (unformat (i, "bvi"))
7232         {
7233           bvi_mac = 1;
7234           static_mac = 1;
7235         }
7236       else if (unformat (i, "del"))
7237         is_add = 0;
7238       else if (unformat (i, "count %d", &count))
7239         ;
7240       else
7241         break;
7242     }
7243
7244   if (mac_set == 0)
7245     {
7246       errmsg ("missing mac address");
7247       return -99;
7248     }
7249
7250   if (bd_id_set == 0)
7251     {
7252       errmsg ("missing bridge domain");
7253       return -99;
7254     }
7255
7256   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7257     {
7258       errmsg ("missing interface name or sw_if_index");
7259       return -99;
7260     }
7261
7262   if (count > 1)
7263     {
7264       /* Turn on async mode */
7265       vam->async_mode = 1;
7266       vam->async_errors = 0;
7267       before = vat_time_now (vam);
7268     }
7269
7270   for (j = 0; j < count; j++)
7271     {
7272       M (L2FIB_ADD_DEL, mp);
7273
7274       clib_memcpy (mp->mac, mac, 6);
7275       mp->bd_id = ntohl (bd_id);
7276       mp->is_add = is_add;
7277
7278       if (is_add)
7279         {
7280           mp->sw_if_index = ntohl (sw_if_index);
7281           mp->static_mac = static_mac;
7282           mp->filter_mac = filter_mac;
7283           mp->bvi_mac = bvi_mac;
7284         }
7285       increment_mac_address (mac);
7286       /* send it... */
7287       S (mp);
7288     }
7289
7290   if (count > 1)
7291     {
7292       vl_api_control_ping_t *mp_ping;
7293       f64 after;
7294
7295       /* Shut off async mode */
7296       vam->async_mode = 0;
7297
7298       MPING (CONTROL_PING, mp_ping);
7299       S (mp_ping);
7300
7301       timeout = vat_time_now (vam) + 1.0;
7302       while (vat_time_now (vam) < timeout)
7303         if (vam->result_ready == 1)
7304           goto out;
7305       vam->retval = -99;
7306
7307     out:
7308       if (vam->retval == -99)
7309         errmsg ("timeout");
7310
7311       if (vam->async_errors > 0)
7312         {
7313           errmsg ("%d asynchronous errors", vam->async_errors);
7314           vam->retval = -98;
7315         }
7316       vam->async_errors = 0;
7317       after = vat_time_now (vam);
7318
7319       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7320              count, after - before, count / (after - before));
7321     }
7322   else
7323     {
7324       int ret;
7325
7326       /* Wait for a reply... */
7327       W (ret);
7328       return ret;
7329     }
7330   /* Return the good/bad news */
7331   return (vam->retval);
7332 }
7333
7334 static int
7335 api_bridge_domain_set_mac_age (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_bridge_domain_set_mac_age_t *mp;
7339   u32 bd_id = ~0;
7340   u32 mac_age = 0;
7341   int ret;
7342
7343   /* Parse args required to build the message */
7344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7345     {
7346       if (unformat (i, "bd_id %d", &bd_id));
7347       else if (unformat (i, "mac-age %d", &mac_age));
7348       else
7349         break;
7350     }
7351
7352   if (bd_id == ~0)
7353     {
7354       errmsg ("missing bridge domain");
7355       return -99;
7356     }
7357
7358   if (mac_age > 255)
7359     {
7360       errmsg ("mac age must be less than 256 ");
7361       return -99;
7362     }
7363
7364   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7365
7366   mp->bd_id = htonl (bd_id);
7367   mp->mac_age = (u8) mac_age;
7368
7369   S (mp);
7370   W (ret);
7371   return ret;
7372 }
7373
7374 static int
7375 api_l2_flags (vat_main_t * vam)
7376 {
7377   unformat_input_t *i = vam->input;
7378   vl_api_l2_flags_t *mp;
7379   u32 sw_if_index;
7380   u32 flags = 0;
7381   u8 sw_if_index_set = 0;
7382   u8 is_set = 0;
7383   int ret;
7384
7385   /* Parse args required to build the message */
7386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7387     {
7388       if (unformat (i, "sw_if_index %d", &sw_if_index))
7389         sw_if_index_set = 1;
7390       else if (unformat (i, "sw_if"))
7391         {
7392           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393             {
7394               if (unformat
7395                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7396                 sw_if_index_set = 1;
7397             }
7398           else
7399             break;
7400         }
7401       else if (unformat (i, "learn"))
7402         flags |= L2_LEARN;
7403       else if (unformat (i, "forward"))
7404         flags |= L2_FWD;
7405       else if (unformat (i, "flood"))
7406         flags |= L2_FLOOD;
7407       else if (unformat (i, "uu-flood"))
7408         flags |= L2_UU_FLOOD;
7409       else if (unformat (i, "arp-term"))
7410         flags |= L2_ARP_TERM;
7411       else if (unformat (i, "off"))
7412         is_set = 0;
7413       else if (unformat (i, "disable"))
7414         is_set = 0;
7415       else
7416         break;
7417     }
7418
7419   if (sw_if_index_set == 0)
7420     {
7421       errmsg ("missing interface name or sw_if_index");
7422       return -99;
7423     }
7424
7425   M (L2_FLAGS, mp);
7426
7427   mp->sw_if_index = ntohl (sw_if_index);
7428   mp->feature_bitmap = ntohl (flags);
7429   mp->is_set = is_set;
7430
7431   S (mp);
7432   W (ret);
7433   return ret;
7434 }
7435
7436 static int
7437 api_bridge_flags (vat_main_t * vam)
7438 {
7439   unformat_input_t *i = vam->input;
7440   vl_api_bridge_flags_t *mp;
7441   u32 bd_id;
7442   u8 bd_id_set = 0;
7443   u8 is_set = 1;
7444   u32 flags = 0;
7445   int ret;
7446
7447   /* Parse args required to build the message */
7448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (unformat (i, "bd_id %d", &bd_id))
7451         bd_id_set = 1;
7452       else if (unformat (i, "learn"))
7453         flags |= L2_LEARN;
7454       else if (unformat (i, "forward"))
7455         flags |= L2_FWD;
7456       else if (unformat (i, "flood"))
7457         flags |= L2_FLOOD;
7458       else if (unformat (i, "uu-flood"))
7459         flags |= L2_UU_FLOOD;
7460       else if (unformat (i, "arp-term"))
7461         flags |= L2_ARP_TERM;
7462       else if (unformat (i, "off"))
7463         is_set = 0;
7464       else if (unformat (i, "disable"))
7465         is_set = 0;
7466       else
7467         break;
7468     }
7469
7470   if (bd_id_set == 0)
7471     {
7472       errmsg ("missing bridge domain");
7473       return -99;
7474     }
7475
7476   M (BRIDGE_FLAGS, mp);
7477
7478   mp->bd_id = ntohl (bd_id);
7479   mp->feature_bitmap = ntohl (flags);
7480   mp->is_set = is_set;
7481
7482   S (mp);
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_bd_ip_mac_add_del (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_bd_ip_mac_add_del_t *mp;
7492   u32 bd_id;
7493   u8 is_ipv6 = 0;
7494   u8 is_add = 1;
7495   u8 bd_id_set = 0;
7496   u8 ip_set = 0;
7497   u8 mac_set = 0;
7498   ip4_address_t v4addr;
7499   ip6_address_t v6addr;
7500   u8 macaddr[6];
7501   int ret;
7502
7503
7504   /* Parse args required to build the message */
7505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7506     {
7507       if (unformat (i, "bd_id %d", &bd_id))
7508         {
7509           bd_id_set++;
7510         }
7511       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7512         {
7513           ip_set++;
7514         }
7515       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7516         {
7517           ip_set++;
7518           is_ipv6++;
7519         }
7520       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7521         {
7522           mac_set++;
7523         }
7524       else if (unformat (i, "del"))
7525         is_add = 0;
7526       else
7527         break;
7528     }
7529
7530   if (bd_id_set == 0)
7531     {
7532       errmsg ("missing bridge domain");
7533       return -99;
7534     }
7535   else if (ip_set == 0)
7536     {
7537       errmsg ("missing IP address");
7538       return -99;
7539     }
7540   else if (mac_set == 0)
7541     {
7542       errmsg ("missing MAC address");
7543       return -99;
7544     }
7545
7546   M (BD_IP_MAC_ADD_DEL, mp);
7547
7548   mp->bd_id = ntohl (bd_id);
7549   mp->is_ipv6 = is_ipv6;
7550   mp->is_add = is_add;
7551   if (is_ipv6)
7552     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7553   else
7554     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7555   clib_memcpy (mp->mac_address, macaddr, 6);
7556   S (mp);
7557   W (ret);
7558   return ret;
7559 }
7560
7561 static int
7562 api_tap_connect (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_tap_connect_t *mp;
7566   u8 mac_address[6];
7567   u8 random_mac = 1;
7568   u8 name_set = 0;
7569   u8 *tap_name;
7570   u8 *tag = 0;
7571   ip4_address_t ip4_address;
7572   u32 ip4_mask_width;
7573   int ip4_address_set = 0;
7574   ip6_address_t ip6_address;
7575   u32 ip6_mask_width;
7576   int ip6_address_set = 0;
7577   int ret;
7578
7579   memset (mac_address, 0, sizeof (mac_address));
7580
7581   /* Parse args required to build the message */
7582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7583     {
7584       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7585         {
7586           random_mac = 0;
7587         }
7588       else if (unformat (i, "random-mac"))
7589         random_mac = 1;
7590       else if (unformat (i, "tapname %s", &tap_name))
7591         name_set = 1;
7592       else if (unformat (i, "tag %s", &tag))
7593         ;
7594       else if (unformat (i, "address %U/%d",
7595                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7596         ip4_address_set = 1;
7597       else if (unformat (i, "address %U/%d",
7598                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7599         ip6_address_set = 1;
7600       else
7601         break;
7602     }
7603
7604   if (name_set == 0)
7605     {
7606       errmsg ("missing tap name");
7607       return -99;
7608     }
7609   if (vec_len (tap_name) > 63)
7610     {
7611       errmsg ("tap name too long");
7612       return -99;
7613     }
7614   vec_add1 (tap_name, 0);
7615
7616   if (vec_len (tag) > 63)
7617     {
7618       errmsg ("tag too long");
7619       return -99;
7620     }
7621
7622   /* Construct the API message */
7623   M (TAP_CONNECT, mp);
7624
7625   mp->use_random_mac = random_mac;
7626   clib_memcpy (mp->mac_address, mac_address, 6);
7627   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7628   if (tag)
7629     clib_memcpy (mp->tag, tag, vec_len (tag));
7630
7631   if (ip4_address_set)
7632     {
7633       mp->ip4_address_set = 1;
7634       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7635       mp->ip4_mask_width = ip4_mask_width;
7636     }
7637   if (ip6_address_set)
7638     {
7639       mp->ip6_address_set = 1;
7640       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7641       mp->ip6_mask_width = ip6_mask_width;
7642     }
7643
7644   vec_free (tap_name);
7645   vec_free (tag);
7646
7647   /* send it... */
7648   S (mp);
7649
7650   /* Wait for a reply... */
7651   W (ret);
7652   return ret;
7653 }
7654
7655 static int
7656 api_tap_modify (vat_main_t * vam)
7657 {
7658   unformat_input_t *i = vam->input;
7659   vl_api_tap_modify_t *mp;
7660   u8 mac_address[6];
7661   u8 random_mac = 1;
7662   u8 name_set = 0;
7663   u8 *tap_name;
7664   u32 sw_if_index = ~0;
7665   u8 sw_if_index_set = 0;
7666   int ret;
7667
7668   memset (mac_address, 0, sizeof (mac_address));
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7674         sw_if_index_set = 1;
7675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7676         sw_if_index_set = 1;
7677       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7678         {
7679           random_mac = 0;
7680         }
7681       else if (unformat (i, "random-mac"))
7682         random_mac = 1;
7683       else if (unformat (i, "tapname %s", &tap_name))
7684         name_set = 1;
7685       else
7686         break;
7687     }
7688
7689   if (sw_if_index_set == 0)
7690     {
7691       errmsg ("missing vpp interface name");
7692       return -99;
7693     }
7694   if (name_set == 0)
7695     {
7696       errmsg ("missing tap name");
7697       return -99;
7698     }
7699   if (vec_len (tap_name) > 63)
7700     {
7701       errmsg ("tap name too long");
7702     }
7703   vec_add1 (tap_name, 0);
7704
7705   /* Construct the API message */
7706   M (TAP_MODIFY, mp);
7707
7708   mp->use_random_mac = random_mac;
7709   mp->sw_if_index = ntohl (sw_if_index);
7710   clib_memcpy (mp->mac_address, mac_address, 6);
7711   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7712   vec_free (tap_name);
7713
7714   /* send it... */
7715   S (mp);
7716
7717   /* Wait for a reply... */
7718   W (ret);
7719   return ret;
7720 }
7721
7722 static int
7723 api_tap_delete (vat_main_t * vam)
7724 {
7725   unformat_input_t *i = vam->input;
7726   vl_api_tap_delete_t *mp;
7727   u32 sw_if_index = ~0;
7728   u8 sw_if_index_set = 0;
7729   int ret;
7730
7731   /* Parse args required to build the message */
7732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7733     {
7734       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7735         sw_if_index_set = 1;
7736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7737         sw_if_index_set = 1;
7738       else
7739         break;
7740     }
7741
7742   if (sw_if_index_set == 0)
7743     {
7744       errmsg ("missing vpp interface name");
7745       return -99;
7746     }
7747
7748   /* Construct the API message */
7749   M (TAP_DELETE, mp);
7750
7751   mp->sw_if_index = ntohl (sw_if_index);
7752
7753   /* send it... */
7754   S (mp);
7755
7756   /* Wait for a reply... */
7757   W (ret);
7758   return ret;
7759 }
7760
7761 static int
7762 api_tap_create_v2 (vat_main_t * vam)
7763 {
7764   unformat_input_t *i = vam->input;
7765   vl_api_tap_create_v2_t *mp;
7766   u8 mac_address[6];
7767   u8 random_mac = 1;
7768   u32 id = ~0;
7769   u8 *host_if_name = 0;
7770   u8 *host_ns = 0;
7771   u8 host_mac_addr[6];
7772   u8 host_mac_addr_set = 0;
7773   u8 *host_bridge = 0;
7774   ip4_address_t host_ip4_addr;
7775   u32 host_ip4_prefix_len = 0;
7776   ip6_address_t host_ip6_addr;
7777   u32 host_ip6_prefix_len = 0;
7778   int ret;
7779   int rx_ring_sz = 0, tx_ring_sz = 0;
7780
7781   memset (mac_address, 0, sizeof (mac_address));
7782
7783   /* Parse args required to build the message */
7784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7787         {
7788           random_mac = 0;
7789         }
7790       else if (unformat (i, "id %s", &id))
7791         ;
7792       else if (unformat (i, "host-if-name %s", &host_if_name))
7793         ;
7794       else if (unformat (i, "host-ns %s", &host_ns))
7795         ;
7796       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7797                          host_mac_addr))
7798         host_mac_addr_set = 1;
7799       else if (unformat (i, "host-bridge %s", &host_bridge))
7800         ;
7801       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7802                          &host_ip4_addr, &host_ip4_prefix_len))
7803         ;
7804       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7805                          &host_ip6_addr, &host_ip6_prefix_len))
7806         ;
7807       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7808         ;
7809       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7810         ;
7811       else
7812         break;
7813     }
7814
7815   if (vec_len (host_if_name) > 63)
7816     {
7817       errmsg ("tap name too long. ");
7818       return -99;
7819     }
7820   if (vec_len (host_ns) > 63)
7821     {
7822       errmsg ("host name space too long. ");
7823       return -99;
7824     }
7825   if (vec_len (host_bridge) > 63)
7826     {
7827       errmsg ("host bridge name too long. ");
7828       return -99;
7829     }
7830   if (host_ip4_prefix_len > 32)
7831     {
7832       errmsg ("host ip4 prefix length not valid. ");
7833       return -99;
7834     }
7835   if (host_ip6_prefix_len > 128)
7836     {
7837       errmsg ("host ip6 prefix length not valid. ");
7838       return -99;
7839     }
7840   if (!is_pow2 (rx_ring_sz))
7841     {
7842       errmsg ("rx ring size must be power of 2. ");
7843       return -99;
7844     }
7845   if (rx_ring_sz > 32768)
7846     {
7847       errmsg ("rx ring size must be 32768 or lower. ");
7848       return -99;
7849     }
7850   if (!is_pow2 (tx_ring_sz))
7851     {
7852       errmsg ("tx ring size must be power of 2. ");
7853       return -99;
7854     }
7855   if (tx_ring_sz > 32768)
7856     {
7857       errmsg ("tx ring size must be 32768 or lower. ");
7858       return -99;
7859     }
7860
7861   /* Construct the API message */
7862   M (TAP_CREATE_V2, mp);
7863
7864   mp->use_random_mac = random_mac;
7865
7866   mp->id = id;
7867   mp->host_namespace_set = host_ns != 0;
7868   mp->host_bridge_set = host_bridge != 0;
7869   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7870   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7871   mp->rx_ring_sz = rx_ring_sz;
7872   mp->tx_ring_sz = tx_ring_sz;
7873
7874   if (random_mac)
7875     clib_memcpy (mp->mac_address, mac_address, 6);
7876   if (host_mac_addr_set)
7877     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7878   if (host_if_name)
7879     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7880   if (host_ns)
7881     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7882   if (host_bridge)
7883     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7884   if (host_ip4_prefix_len)
7885     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7886   if (host_ip4_prefix_len)
7887     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7888
7889
7890   vec_free (host_ns);
7891   vec_free (host_if_name);
7892   vec_free (host_bridge);
7893
7894   /* send it... */
7895   S (mp);
7896
7897   /* Wait for a reply... */
7898   W (ret);
7899   return ret;
7900 }
7901
7902 static int
7903 api_tap_delete_v2 (vat_main_t * vam)
7904 {
7905   unformat_input_t *i = vam->input;
7906   vl_api_tap_delete_v2_t *mp;
7907   u32 sw_if_index = ~0;
7908   u8 sw_if_index_set = 0;
7909   int ret;
7910
7911   /* Parse args required to build the message */
7912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7913     {
7914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7915         sw_if_index_set = 1;
7916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917         sw_if_index_set = 1;
7918       else
7919         break;
7920     }
7921
7922   if (sw_if_index_set == 0)
7923     {
7924       errmsg ("missing vpp interface name. ");
7925       return -99;
7926     }
7927
7928   /* Construct the API message */
7929   M (TAP_DELETE_V2, mp);
7930
7931   mp->sw_if_index = ntohl (sw_if_index);
7932
7933   /* send it... */
7934   S (mp);
7935
7936   /* Wait for a reply... */
7937   W (ret);
7938   return ret;
7939 }
7940
7941 static int
7942 api_ip_table_add_del (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_ip_table_add_del_t *mp;
7946   u32 table_id = ~0;
7947   u8 is_ipv6 = 0;
7948   u8 is_add = 1;
7949   int ret = 0;
7950
7951   /* Parse args required to build the message */
7952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7953     {
7954       if (unformat (i, "ipv6"))
7955         is_ipv6 = 1;
7956       else if (unformat (i, "del"))
7957         is_add = 0;
7958       else if (unformat (i, "add"))
7959         is_add = 1;
7960       else if (unformat (i, "table %d", &table_id))
7961         ;
7962       else
7963         {
7964           clib_warning ("parse error '%U'", format_unformat_error, i);
7965           return -99;
7966         }
7967     }
7968
7969   if (~0 == table_id)
7970     {
7971       errmsg ("missing table-ID");
7972       return -99;
7973     }
7974
7975   /* Construct the API message */
7976   M (IP_TABLE_ADD_DEL, mp);
7977
7978   mp->table_id = ntohl (table_id);
7979   mp->is_ipv6 = is_ipv6;
7980   mp->is_add = is_add;
7981
7982   /* send it... */
7983   S (mp);
7984
7985   /* Wait for a reply... */
7986   W (ret);
7987
7988   return ret;
7989 }
7990
7991 static int
7992 api_ip_add_del_route (vat_main_t * vam)
7993 {
7994   unformat_input_t *i = vam->input;
7995   vl_api_ip_add_del_route_t *mp;
7996   u32 sw_if_index = ~0, vrf_id = 0;
7997   u8 is_ipv6 = 0;
7998   u8 is_local = 0, is_drop = 0;
7999   u8 is_unreach = 0, is_prohibit = 0;
8000   u8 is_add = 1;
8001   u32 next_hop_weight = 1;
8002   u8 is_multipath = 0;
8003   u8 address_set = 0;
8004   u8 address_length_set = 0;
8005   u32 next_hop_table_id = 0;
8006   u32 resolve_attempts = 0;
8007   u32 dst_address_length = 0;
8008   u8 next_hop_set = 0;
8009   ip4_address_t v4_dst_address, v4_next_hop_address;
8010   ip6_address_t v6_dst_address, v6_next_hop_address;
8011   int count = 1;
8012   int j;
8013   f64 before = 0;
8014   u32 random_add_del = 0;
8015   u32 *random_vector = 0;
8016   uword *random_hash;
8017   u32 random_seed = 0xdeaddabe;
8018   u32 classify_table_index = ~0;
8019   u8 is_classify = 0;
8020   u8 resolve_host = 0, resolve_attached = 0;
8021   mpls_label_t *next_hop_out_label_stack = NULL;
8022   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8023   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8024
8025   /* Parse args required to build the message */
8026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8029         ;
8030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8031         ;
8032       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8033         {
8034           address_set = 1;
8035           is_ipv6 = 0;
8036         }
8037       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8038         {
8039           address_set = 1;
8040           is_ipv6 = 1;
8041         }
8042       else if (unformat (i, "/%d", &dst_address_length))
8043         {
8044           address_length_set = 1;
8045         }
8046
8047       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8048                                          &v4_next_hop_address))
8049         {
8050           next_hop_set = 1;
8051         }
8052       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8053                                          &v6_next_hop_address))
8054         {
8055           next_hop_set = 1;
8056         }
8057       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8058         ;
8059       else if (unformat (i, "weight %d", &next_hop_weight))
8060         ;
8061       else if (unformat (i, "drop"))
8062         {
8063           is_drop = 1;
8064         }
8065       else if (unformat (i, "null-send-unreach"))
8066         {
8067           is_unreach = 1;
8068         }
8069       else if (unformat (i, "null-send-prohibit"))
8070         {
8071           is_prohibit = 1;
8072         }
8073       else if (unformat (i, "local"))
8074         {
8075           is_local = 1;
8076         }
8077       else if (unformat (i, "classify %d", &classify_table_index))
8078         {
8079           is_classify = 1;
8080         }
8081       else if (unformat (i, "del"))
8082         is_add = 0;
8083       else if (unformat (i, "add"))
8084         is_add = 1;
8085       else if (unformat (i, "resolve-via-host"))
8086         resolve_host = 1;
8087       else if (unformat (i, "resolve-via-attached"))
8088         resolve_attached = 1;
8089       else if (unformat (i, "multipath"))
8090         is_multipath = 1;
8091       else if (unformat (i, "vrf %d", &vrf_id))
8092         ;
8093       else if (unformat (i, "count %d", &count))
8094         ;
8095       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8096         ;
8097       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8098         ;
8099       else if (unformat (i, "out-label %d", &next_hop_out_label))
8100         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8101       else if (unformat (i, "via-label %d", &next_hop_via_label))
8102         ;
8103       else if (unformat (i, "random"))
8104         random_add_del = 1;
8105       else if (unformat (i, "seed %d", &random_seed))
8106         ;
8107       else
8108         {
8109           clib_warning ("parse error '%U'", format_unformat_error, i);
8110           return -99;
8111         }
8112     }
8113
8114   if (!next_hop_set && !is_drop && !is_local &&
8115       !is_classify && !is_unreach && !is_prohibit &&
8116       MPLS_LABEL_INVALID == next_hop_via_label)
8117     {
8118       errmsg
8119         ("next hop / local / drop / unreach / prohibit / classify not set");
8120       return -99;
8121     }
8122
8123   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8124     {
8125       errmsg ("next hop and next-hop via label set");
8126       return -99;
8127     }
8128   if (address_set == 0)
8129     {
8130       errmsg ("missing addresses");
8131       return -99;
8132     }
8133
8134   if (address_length_set == 0)
8135     {
8136       errmsg ("missing address length");
8137       return -99;
8138     }
8139
8140   /* Generate a pile of unique, random routes */
8141   if (random_add_del)
8142     {
8143       u32 this_random_address;
8144       random_hash = hash_create (count, sizeof (uword));
8145
8146       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8147       for (j = 0; j <= count; j++)
8148         {
8149           do
8150             {
8151               this_random_address = random_u32 (&random_seed);
8152               this_random_address =
8153                 clib_host_to_net_u32 (this_random_address);
8154             }
8155           while (hash_get (random_hash, this_random_address));
8156           vec_add1 (random_vector, this_random_address);
8157           hash_set (random_hash, this_random_address, 1);
8158         }
8159       hash_free (random_hash);
8160       v4_dst_address.as_u32 = random_vector[0];
8161     }
8162
8163   if (count > 1)
8164     {
8165       /* Turn on async mode */
8166       vam->async_mode = 1;
8167       vam->async_errors = 0;
8168       before = vat_time_now (vam);
8169     }
8170
8171   for (j = 0; j < count; j++)
8172     {
8173       /* Construct the API message */
8174       M2 (IP_ADD_DEL_ROUTE, mp,
8175           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8176
8177       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8178       mp->table_id = ntohl (vrf_id);
8179
8180       mp->is_add = is_add;
8181       mp->is_drop = is_drop;
8182       mp->is_unreach = is_unreach;
8183       mp->is_prohibit = is_prohibit;
8184       mp->is_ipv6 = is_ipv6;
8185       mp->is_local = is_local;
8186       mp->is_classify = is_classify;
8187       mp->is_multipath = is_multipath;
8188       mp->is_resolve_host = resolve_host;
8189       mp->is_resolve_attached = resolve_attached;
8190       mp->next_hop_weight = next_hop_weight;
8191       mp->dst_address_length = dst_address_length;
8192       mp->next_hop_table_id = ntohl (next_hop_table_id);
8193       mp->classify_table_index = ntohl (classify_table_index);
8194       mp->next_hop_via_label = ntohl (next_hop_via_label);
8195       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8196       if (0 != mp->next_hop_n_out_labels)
8197         {
8198           memcpy (mp->next_hop_out_label_stack,
8199                   next_hop_out_label_stack,
8200                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8201           vec_free (next_hop_out_label_stack);
8202         }
8203
8204       if (is_ipv6)
8205         {
8206           clib_memcpy (mp->dst_address, &v6_dst_address,
8207                        sizeof (v6_dst_address));
8208           if (next_hop_set)
8209             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8210                          sizeof (v6_next_hop_address));
8211           increment_v6_address (&v6_dst_address);
8212         }
8213       else
8214         {
8215           clib_memcpy (mp->dst_address, &v4_dst_address,
8216                        sizeof (v4_dst_address));
8217           if (next_hop_set)
8218             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8219                          sizeof (v4_next_hop_address));
8220           if (random_add_del)
8221             v4_dst_address.as_u32 = random_vector[j + 1];
8222           else
8223             increment_v4_address (&v4_dst_address);
8224         }
8225       /* send it... */
8226       S (mp);
8227       /* If we receive SIGTERM, stop now... */
8228       if (vam->do_exit)
8229         break;
8230     }
8231
8232   /* When testing multiple add/del ops, use a control-ping to sync */
8233   if (count > 1)
8234     {
8235       vl_api_control_ping_t *mp_ping;
8236       f64 after;
8237       f64 timeout;
8238
8239       /* Shut off async mode */
8240       vam->async_mode = 0;
8241
8242       MPING (CONTROL_PING, mp_ping);
8243       S (mp_ping);
8244
8245       timeout = vat_time_now (vam) + 1.0;
8246       while (vat_time_now (vam) < timeout)
8247         if (vam->result_ready == 1)
8248           goto out;
8249       vam->retval = -99;
8250
8251     out:
8252       if (vam->retval == -99)
8253         errmsg ("timeout");
8254
8255       if (vam->async_errors > 0)
8256         {
8257           errmsg ("%d asynchronous errors", vam->async_errors);
8258           vam->retval = -98;
8259         }
8260       vam->async_errors = 0;
8261       after = vat_time_now (vam);
8262
8263       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8264       if (j > 0)
8265         count = j;
8266
8267       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8268              count, after - before, count / (after - before));
8269     }
8270   else
8271     {
8272       int ret;
8273
8274       /* Wait for a reply... */
8275       W (ret);
8276       return ret;
8277     }
8278
8279   /* Return the good/bad news */
8280   return (vam->retval);
8281 }
8282
8283 static int
8284 api_ip_mroute_add_del (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_ip_mroute_add_del_t *mp;
8288   u32 sw_if_index = ~0, vrf_id = 0;
8289   u8 is_ipv6 = 0;
8290   u8 is_local = 0;
8291   u8 is_add = 1;
8292   u8 address_set = 0;
8293   u32 grp_address_length = 0;
8294   ip4_address_t v4_grp_address, v4_src_address;
8295   ip6_address_t v6_grp_address, v6_src_address;
8296   mfib_itf_flags_t iflags = 0;
8297   mfib_entry_flags_t eflags = 0;
8298   int ret;
8299
8300   /* Parse args required to build the message */
8301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8302     {
8303       if (unformat (i, "sw_if_index %d", &sw_if_index))
8304         ;
8305       else if (unformat (i, "%U %U",
8306                          unformat_ip4_address, &v4_src_address,
8307                          unformat_ip4_address, &v4_grp_address))
8308         {
8309           grp_address_length = 64;
8310           address_set = 1;
8311           is_ipv6 = 0;
8312         }
8313       else if (unformat (i, "%U %U",
8314                          unformat_ip6_address, &v6_src_address,
8315                          unformat_ip6_address, &v6_grp_address))
8316         {
8317           grp_address_length = 256;
8318           address_set = 1;
8319           is_ipv6 = 1;
8320         }
8321       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8322         {
8323           memset (&v4_src_address, 0, sizeof (v4_src_address));
8324           grp_address_length = 32;
8325           address_set = 1;
8326           is_ipv6 = 0;
8327         }
8328       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8329         {
8330           memset (&v6_src_address, 0, sizeof (v6_src_address));
8331           grp_address_length = 128;
8332           address_set = 1;
8333           is_ipv6 = 1;
8334         }
8335       else if (unformat (i, "/%d", &grp_address_length))
8336         ;
8337       else if (unformat (i, "local"))
8338         {
8339           is_local = 1;
8340         }
8341       else if (unformat (i, "del"))
8342         is_add = 0;
8343       else if (unformat (i, "add"))
8344         is_add = 1;
8345       else if (unformat (i, "vrf %d", &vrf_id))
8346         ;
8347       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8348         ;
8349       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8350         ;
8351       else
8352         {
8353           clib_warning ("parse error '%U'", format_unformat_error, i);
8354           return -99;
8355         }
8356     }
8357
8358   if (address_set == 0)
8359     {
8360       errmsg ("missing addresses\n");
8361       return -99;
8362     }
8363
8364   /* Construct the API message */
8365   M (IP_MROUTE_ADD_DEL, mp);
8366
8367   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8368   mp->table_id = ntohl (vrf_id);
8369
8370   mp->is_add = is_add;
8371   mp->is_ipv6 = is_ipv6;
8372   mp->is_local = is_local;
8373   mp->itf_flags = ntohl (iflags);
8374   mp->entry_flags = ntohl (eflags);
8375   mp->grp_address_length = grp_address_length;
8376   mp->grp_address_length = ntohs (mp->grp_address_length);
8377
8378   if (is_ipv6)
8379     {
8380       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8381       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8382     }
8383   else
8384     {
8385       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8386       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8387
8388     }
8389
8390   /* send it... */
8391   S (mp);
8392   /* Wait for a reply... */
8393   W (ret);
8394   return ret;
8395 }
8396
8397 static int
8398 api_mpls_table_add_del (vat_main_t * vam)
8399 {
8400   unformat_input_t *i = vam->input;
8401   vl_api_mpls_table_add_del_t *mp;
8402   u32 table_id = ~0;
8403   u8 is_add = 1;
8404   int ret = 0;
8405
8406   /* Parse args required to build the message */
8407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (i, "table %d", &table_id))
8410         ;
8411       else if (unformat (i, "del"))
8412         is_add = 0;
8413       else if (unformat (i, "add"))
8414         is_add = 1;
8415       else
8416         {
8417           clib_warning ("parse error '%U'", format_unformat_error, i);
8418           return -99;
8419         }
8420     }
8421
8422   if (~0 == table_id)
8423     {
8424       errmsg ("missing table-ID");
8425       return -99;
8426     }
8427
8428   /* Construct the API message */
8429   M (MPLS_TABLE_ADD_DEL, mp);
8430
8431   mp->mt_table_id = ntohl (table_id);
8432   mp->mt_is_add = is_add;
8433
8434   /* send it... */
8435   S (mp);
8436
8437   /* Wait for a reply... */
8438   W (ret);
8439
8440   return ret;
8441 }
8442
8443 static int
8444 api_mpls_route_add_del (vat_main_t * vam)
8445 {
8446   unformat_input_t *i = vam->input;
8447   vl_api_mpls_route_add_del_t *mp;
8448   u32 sw_if_index = ~0, table_id = 0;
8449   u8 is_add = 1;
8450   u32 next_hop_weight = 1;
8451   u8 is_multipath = 0;
8452   u32 next_hop_table_id = 0;
8453   u8 next_hop_set = 0;
8454   ip4_address_t v4_next_hop_address = {
8455     .as_u32 = 0,
8456   };
8457   ip6_address_t v6_next_hop_address = { {0} };
8458   int count = 1;
8459   int j;
8460   f64 before = 0;
8461   u32 classify_table_index = ~0;
8462   u8 is_classify = 0;
8463   u8 resolve_host = 0, resolve_attached = 0;
8464   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8465   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8466   mpls_label_t *next_hop_out_label_stack = NULL;
8467   mpls_label_t local_label = MPLS_LABEL_INVALID;
8468   u8 is_eos = 0;
8469   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8470
8471   /* Parse args required to build the message */
8472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8473     {
8474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8475         ;
8476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8477         ;
8478       else if (unformat (i, "%d", &local_label))
8479         ;
8480       else if (unformat (i, "eos"))
8481         is_eos = 1;
8482       else if (unformat (i, "non-eos"))
8483         is_eos = 0;
8484       else if (unformat (i, "via %U", unformat_ip4_address,
8485                          &v4_next_hop_address))
8486         {
8487           next_hop_set = 1;
8488           next_hop_proto = DPO_PROTO_IP4;
8489         }
8490       else if (unformat (i, "via %U", unformat_ip6_address,
8491                          &v6_next_hop_address))
8492         {
8493           next_hop_set = 1;
8494           next_hop_proto = DPO_PROTO_IP6;
8495         }
8496       else if (unformat (i, "weight %d", &next_hop_weight))
8497         ;
8498       else if (unformat (i, "classify %d", &classify_table_index))
8499         {
8500           is_classify = 1;
8501         }
8502       else if (unformat (i, "del"))
8503         is_add = 0;
8504       else if (unformat (i, "add"))
8505         is_add = 1;
8506       else if (unformat (i, "resolve-via-host"))
8507         resolve_host = 1;
8508       else if (unformat (i, "resolve-via-attached"))
8509         resolve_attached = 1;
8510       else if (unformat (i, "multipath"))
8511         is_multipath = 1;
8512       else if (unformat (i, "count %d", &count))
8513         ;
8514       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8515         {
8516           next_hop_set = 1;
8517           next_hop_proto = DPO_PROTO_IP4;
8518         }
8519       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8520         {
8521           next_hop_set = 1;
8522           next_hop_proto = DPO_PROTO_IP6;
8523         }
8524       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8525         ;
8526       else if (unformat (i, "via-label %d", &next_hop_via_label))
8527         ;
8528       else if (unformat (i, "out-label %d", &next_hop_out_label))
8529         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8530       else
8531         {
8532           clib_warning ("parse error '%U'", format_unformat_error, i);
8533           return -99;
8534         }
8535     }
8536
8537   if (!next_hop_set && !is_classify)
8538     {
8539       errmsg ("next hop / classify not set");
8540       return -99;
8541     }
8542
8543   if (MPLS_LABEL_INVALID == local_label)
8544     {
8545       errmsg ("missing label");
8546       return -99;
8547     }
8548
8549   if (count > 1)
8550     {
8551       /* Turn on async mode */
8552       vam->async_mode = 1;
8553       vam->async_errors = 0;
8554       before = vat_time_now (vam);
8555     }
8556
8557   for (j = 0; j < count; j++)
8558     {
8559       /* Construct the API message */
8560       M2 (MPLS_ROUTE_ADD_DEL, mp,
8561           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8562
8563       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8564       mp->mr_table_id = ntohl (table_id);
8565
8566       mp->mr_is_add = is_add;
8567       mp->mr_next_hop_proto = next_hop_proto;
8568       mp->mr_is_classify = is_classify;
8569       mp->mr_is_multipath = is_multipath;
8570       mp->mr_is_resolve_host = resolve_host;
8571       mp->mr_is_resolve_attached = resolve_attached;
8572       mp->mr_next_hop_weight = next_hop_weight;
8573       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8574       mp->mr_classify_table_index = ntohl (classify_table_index);
8575       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8576       mp->mr_label = ntohl (local_label);
8577       mp->mr_eos = is_eos;
8578
8579       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8580       if (0 != mp->mr_next_hop_n_out_labels)
8581         {
8582           memcpy (mp->mr_next_hop_out_label_stack,
8583                   next_hop_out_label_stack,
8584                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8585           vec_free (next_hop_out_label_stack);
8586         }
8587
8588       if (next_hop_set)
8589         {
8590           if (DPO_PROTO_IP4 == next_hop_proto)
8591             {
8592               clib_memcpy (mp->mr_next_hop,
8593                            &v4_next_hop_address,
8594                            sizeof (v4_next_hop_address));
8595             }
8596           else if (DPO_PROTO_IP6 == next_hop_proto)
8597
8598             {
8599               clib_memcpy (mp->mr_next_hop,
8600                            &v6_next_hop_address,
8601                            sizeof (v6_next_hop_address));
8602             }
8603         }
8604       local_label++;
8605
8606       /* send it... */
8607       S (mp);
8608       /* If we receive SIGTERM, stop now... */
8609       if (vam->do_exit)
8610         break;
8611     }
8612
8613   /* When testing multiple add/del ops, use a control-ping to sync */
8614   if (count > 1)
8615     {
8616       vl_api_control_ping_t *mp_ping;
8617       f64 after;
8618       f64 timeout;
8619
8620       /* Shut off async mode */
8621       vam->async_mode = 0;
8622
8623       MPING (CONTROL_PING, mp_ping);
8624       S (mp_ping);
8625
8626       timeout = vat_time_now (vam) + 1.0;
8627       while (vat_time_now (vam) < timeout)
8628         if (vam->result_ready == 1)
8629           goto out;
8630       vam->retval = -99;
8631
8632     out:
8633       if (vam->retval == -99)
8634         errmsg ("timeout");
8635
8636       if (vam->async_errors > 0)
8637         {
8638           errmsg ("%d asynchronous errors", vam->async_errors);
8639           vam->retval = -98;
8640         }
8641       vam->async_errors = 0;
8642       after = vat_time_now (vam);
8643
8644       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8645       if (j > 0)
8646         count = j;
8647
8648       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8649              count, after - before, count / (after - before));
8650     }
8651   else
8652     {
8653       int ret;
8654
8655       /* Wait for a reply... */
8656       W (ret);
8657       return ret;
8658     }
8659
8660   /* Return the good/bad news */
8661   return (vam->retval);
8662 }
8663
8664 static int
8665 api_mpls_ip_bind_unbind (vat_main_t * vam)
8666 {
8667   unformat_input_t *i = vam->input;
8668   vl_api_mpls_ip_bind_unbind_t *mp;
8669   u32 ip_table_id = 0;
8670   u8 is_bind = 1;
8671   u8 is_ip4 = 1;
8672   ip4_address_t v4_address;
8673   ip6_address_t v6_address;
8674   u32 address_length;
8675   u8 address_set = 0;
8676   mpls_label_t local_label = MPLS_LABEL_INVALID;
8677   int ret;
8678
8679   /* Parse args required to build the message */
8680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8681     {
8682       if (unformat (i, "%U/%d", unformat_ip4_address,
8683                     &v4_address, &address_length))
8684         {
8685           is_ip4 = 1;
8686           address_set = 1;
8687         }
8688       else if (unformat (i, "%U/%d", unformat_ip6_address,
8689                          &v6_address, &address_length))
8690         {
8691           is_ip4 = 0;
8692           address_set = 1;
8693         }
8694       else if (unformat (i, "%d", &local_label))
8695         ;
8696       else if (unformat (i, "table-id %d", &ip_table_id))
8697         ;
8698       else if (unformat (i, "unbind"))
8699         is_bind = 0;
8700       else if (unformat (i, "bind"))
8701         is_bind = 1;
8702       else
8703         {
8704           clib_warning ("parse error '%U'", format_unformat_error, i);
8705           return -99;
8706         }
8707     }
8708
8709   if (!address_set)
8710     {
8711       errmsg ("IP addres not set");
8712       return -99;
8713     }
8714
8715   if (MPLS_LABEL_INVALID == local_label)
8716     {
8717       errmsg ("missing label");
8718       return -99;
8719     }
8720
8721   /* Construct the API message */
8722   M (MPLS_IP_BIND_UNBIND, mp);
8723
8724   mp->mb_is_bind = is_bind;
8725   mp->mb_is_ip4 = is_ip4;
8726   mp->mb_ip_table_id = ntohl (ip_table_id);
8727   mp->mb_mpls_table_id = 0;
8728   mp->mb_label = ntohl (local_label);
8729   mp->mb_address_length = address_length;
8730
8731   if (is_ip4)
8732     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8733   else
8734     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8735
8736   /* send it... */
8737   S (mp);
8738
8739   /* Wait for a reply... */
8740   W (ret);
8741   return ret;
8742 }
8743
8744 static int
8745 api_bier_table_add_del (vat_main_t * vam)
8746 {
8747   unformat_input_t *i = vam->input;
8748   vl_api_bier_table_add_del_t *mp;
8749   u8 is_add = 1;
8750   u32 set = 0, sub_domain = 0, hdr_len = 3;
8751   mpls_label_t local_label = MPLS_LABEL_INVALID;
8752   int ret;
8753
8754   /* Parse args required to build the message */
8755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8756     {
8757       if (unformat (i, "sub-domain %d", &sub_domain))
8758         ;
8759       else if (unformat (i, "set %d", &set))
8760         ;
8761       else if (unformat (i, "label %d", &local_label))
8762         ;
8763       else if (unformat (i, "hdr-len %d", &hdr_len))
8764         ;
8765       else if (unformat (i, "add"))
8766         is_add = 1;
8767       else if (unformat (i, "del"))
8768         is_add = 0;
8769       else
8770         {
8771           clib_warning ("parse error '%U'", format_unformat_error, i);
8772           return -99;
8773         }
8774     }
8775
8776   if (MPLS_LABEL_INVALID == local_label)
8777     {
8778       errmsg ("missing label\n");
8779       return -99;
8780     }
8781
8782   /* Construct the API message */
8783   M (BIER_TABLE_ADD_DEL, mp);
8784
8785   mp->bt_is_add = is_add;
8786   mp->bt_label = ntohl (local_label);
8787   mp->bt_tbl_id.bt_set = set;
8788   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8789   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8790
8791   /* send it... */
8792   S (mp);
8793
8794   /* Wait for a reply... */
8795   W (ret);
8796
8797   return (ret);
8798 }
8799
8800 static int
8801 api_bier_route_add_del (vat_main_t * vam)
8802 {
8803   unformat_input_t *i = vam->input;
8804   vl_api_bier_route_add_del_t *mp;
8805   u8 is_add = 1;
8806   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8807   ip4_address_t v4_next_hop_address;
8808   ip6_address_t v6_next_hop_address;
8809   u8 next_hop_set = 0;
8810   u8 next_hop_proto_is_ip4 = 1;
8811   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8812   int ret;
8813
8814   /* Parse args required to build the message */
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8818         {
8819           next_hop_proto_is_ip4 = 1;
8820           next_hop_set = 1;
8821         }
8822       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8823         {
8824           next_hop_proto_is_ip4 = 0;
8825           next_hop_set = 1;
8826         }
8827       if (unformat (i, "sub-domain %d", &sub_domain))
8828         ;
8829       else if (unformat (i, "set %d", &set))
8830         ;
8831       else if (unformat (i, "hdr-len %d", &hdr_len))
8832         ;
8833       else if (unformat (i, "bp %d", &bp))
8834         ;
8835       else if (unformat (i, "add"))
8836         is_add = 1;
8837       else if (unformat (i, "del"))
8838         is_add = 0;
8839       else if (unformat (i, "out-label %d", &next_hop_out_label))
8840         ;
8841       else
8842         {
8843           clib_warning ("parse error '%U'", format_unformat_error, i);
8844           return -99;
8845         }
8846     }
8847
8848   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8849     {
8850       errmsg ("next hop / label set\n");
8851       return -99;
8852     }
8853   if (0 == bp)
8854     {
8855       errmsg ("bit=position not set\n");
8856       return -99;
8857     }
8858
8859   /* Construct the API message */
8860   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8861
8862   mp->br_is_add = is_add;
8863   mp->br_tbl_id.bt_set = set;
8864   mp->br_tbl_id.bt_sub_domain = sub_domain;
8865   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8866   mp->br_bp = ntohs (bp);
8867   mp->br_n_paths = 1;
8868   mp->br_paths[0].n_labels = 1;
8869   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8870   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8871
8872   if (next_hop_proto_is_ip4)
8873     {
8874       clib_memcpy (mp->br_paths[0].next_hop,
8875                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8876     }
8877   else
8878     {
8879       clib_memcpy (mp->br_paths[0].next_hop,
8880                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8881     }
8882
8883   /* send it... */
8884   S (mp);
8885
8886   /* Wait for a reply... */
8887   W (ret);
8888
8889   return (ret);
8890 }
8891
8892 static int
8893 api_proxy_arp_add_del (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_proxy_arp_add_del_t *mp;
8897   u32 vrf_id = 0;
8898   u8 is_add = 1;
8899   ip4_address_t lo, hi;
8900   u8 range_set = 0;
8901   int ret;
8902
8903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8904     {
8905       if (unformat (i, "vrf %d", &vrf_id))
8906         ;
8907       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8908                          unformat_ip4_address, &hi))
8909         range_set = 1;
8910       else if (unformat (i, "del"))
8911         is_add = 0;
8912       else
8913         {
8914           clib_warning ("parse error '%U'", format_unformat_error, i);
8915           return -99;
8916         }
8917     }
8918
8919   if (range_set == 0)
8920     {
8921       errmsg ("address range not set");
8922       return -99;
8923     }
8924
8925   M (PROXY_ARP_ADD_DEL, mp);
8926
8927   mp->vrf_id = ntohl (vrf_id);
8928   mp->is_add = is_add;
8929   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8930   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8931
8932   S (mp);
8933   W (ret);
8934   return ret;
8935 }
8936
8937 static int
8938 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8939 {
8940   unformat_input_t *i = vam->input;
8941   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8942   u32 sw_if_index;
8943   u8 enable = 1;
8944   u8 sw_if_index_set = 0;
8945   int ret;
8946
8947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8948     {
8949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8950         sw_if_index_set = 1;
8951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8952         sw_if_index_set = 1;
8953       else if (unformat (i, "enable"))
8954         enable = 1;
8955       else if (unformat (i, "disable"))
8956         enable = 0;
8957       else
8958         {
8959           clib_warning ("parse error '%U'", format_unformat_error, i);
8960           return -99;
8961         }
8962     }
8963
8964   if (sw_if_index_set == 0)
8965     {
8966       errmsg ("missing interface name or sw_if_index");
8967       return -99;
8968     }
8969
8970   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8971
8972   mp->sw_if_index = ntohl (sw_if_index);
8973   mp->enable_disable = enable;
8974
8975   S (mp);
8976   W (ret);
8977   return ret;
8978 }
8979
8980 static int
8981 api_mpls_tunnel_add_del (vat_main_t * vam)
8982 {
8983   unformat_input_t *i = vam->input;
8984   vl_api_mpls_tunnel_add_del_t *mp;
8985
8986   u8 is_add = 1;
8987   u8 l2_only = 0;
8988   u32 sw_if_index = ~0;
8989   u32 next_hop_sw_if_index = ~0;
8990   u32 next_hop_proto_is_ip4 = 1;
8991
8992   u32 next_hop_table_id = 0;
8993   ip4_address_t v4_next_hop_address = {
8994     .as_u32 = 0,
8995   };
8996   ip6_address_t v6_next_hop_address = { {0} };
8997   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8998   int ret;
8999
9000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9001     {
9002       if (unformat (i, "add"))
9003         is_add = 1;
9004       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9005         is_add = 0;
9006       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9007         ;
9008       else if (unformat (i, "via %U",
9009                          unformat_ip4_address, &v4_next_hop_address))
9010         {
9011           next_hop_proto_is_ip4 = 1;
9012         }
9013       else if (unformat (i, "via %U",
9014                          unformat_ip6_address, &v6_next_hop_address))
9015         {
9016           next_hop_proto_is_ip4 = 0;
9017         }
9018       else if (unformat (i, "l2-only"))
9019         l2_only = 1;
9020       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9021         ;
9022       else if (unformat (i, "out-label %d", &next_hop_out_label))
9023         vec_add1 (labels, ntohl (next_hop_out_label));
9024       else
9025         {
9026           clib_warning ("parse error '%U'", format_unformat_error, i);
9027           return -99;
9028         }
9029     }
9030
9031   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9032
9033   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9034   mp->mt_sw_if_index = ntohl (sw_if_index);
9035   mp->mt_is_add = is_add;
9036   mp->mt_l2_only = l2_only;
9037   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9038   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9039
9040   mp->mt_next_hop_n_out_labels = vec_len (labels);
9041
9042   if (0 != mp->mt_next_hop_n_out_labels)
9043     {
9044       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9045                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9046       vec_free (labels);
9047     }
9048
9049   if (next_hop_proto_is_ip4)
9050     {
9051       clib_memcpy (mp->mt_next_hop,
9052                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9053     }
9054   else
9055     {
9056       clib_memcpy (mp->mt_next_hop,
9057                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9058     }
9059
9060   S (mp);
9061   W (ret);
9062   return ret;
9063 }
9064
9065 static int
9066 api_sw_interface_set_unnumbered (vat_main_t * vam)
9067 {
9068   unformat_input_t *i = vam->input;
9069   vl_api_sw_interface_set_unnumbered_t *mp;
9070   u32 sw_if_index;
9071   u32 unnum_sw_index = ~0;
9072   u8 is_add = 1;
9073   u8 sw_if_index_set = 0;
9074   int ret;
9075
9076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9077     {
9078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9079         sw_if_index_set = 1;
9080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9081         sw_if_index_set = 1;
9082       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9083         ;
9084       else if (unformat (i, "del"))
9085         is_add = 0;
9086       else
9087         {
9088           clib_warning ("parse error '%U'", format_unformat_error, i);
9089           return -99;
9090         }
9091     }
9092
9093   if (sw_if_index_set == 0)
9094     {
9095       errmsg ("missing interface name or sw_if_index");
9096       return -99;
9097     }
9098
9099   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9100
9101   mp->sw_if_index = ntohl (sw_if_index);
9102   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9103   mp->is_add = is_add;
9104
9105   S (mp);
9106   W (ret);
9107   return ret;
9108 }
9109
9110 static int
9111 api_ip_neighbor_add_del (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_ip_neighbor_add_del_t *mp;
9115   u32 sw_if_index;
9116   u8 sw_if_index_set = 0;
9117   u8 is_add = 1;
9118   u8 is_static = 0;
9119   u8 is_no_fib_entry = 0;
9120   u8 mac_address[6];
9121   u8 mac_set = 0;
9122   u8 v4_address_set = 0;
9123   u8 v6_address_set = 0;
9124   ip4_address_t v4address;
9125   ip6_address_t v6address;
9126   int ret;
9127
9128   memset (mac_address, 0, sizeof (mac_address));
9129
9130   /* Parse args required to build the message */
9131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9132     {
9133       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9134         {
9135           mac_set = 1;
9136         }
9137       else if (unformat (i, "del"))
9138         is_add = 0;
9139       else
9140         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9141         sw_if_index_set = 1;
9142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9143         sw_if_index_set = 1;
9144       else if (unformat (i, "is_static"))
9145         is_static = 1;
9146       else if (unformat (i, "no-fib-entry"))
9147         is_no_fib_entry = 1;
9148       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9149         v4_address_set = 1;
9150       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9151         v6_address_set = 1;
9152       else
9153         {
9154           clib_warning ("parse error '%U'", format_unformat_error, i);
9155           return -99;
9156         }
9157     }
9158
9159   if (sw_if_index_set == 0)
9160     {
9161       errmsg ("missing interface name or sw_if_index");
9162       return -99;
9163     }
9164   if (v4_address_set && v6_address_set)
9165     {
9166       errmsg ("both v4 and v6 addresses set");
9167       return -99;
9168     }
9169   if (!v4_address_set && !v6_address_set)
9170     {
9171       errmsg ("no address set");
9172       return -99;
9173     }
9174
9175   /* Construct the API message */
9176   M (IP_NEIGHBOR_ADD_DEL, mp);
9177
9178   mp->sw_if_index = ntohl (sw_if_index);
9179   mp->is_add = is_add;
9180   mp->is_static = is_static;
9181   mp->is_no_adj_fib = is_no_fib_entry;
9182   if (mac_set)
9183     clib_memcpy (mp->mac_address, mac_address, 6);
9184   if (v6_address_set)
9185     {
9186       mp->is_ipv6 = 1;
9187       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9188     }
9189   else
9190     {
9191       /* mp->is_ipv6 = 0; via memset in M macro above */
9192       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9193     }
9194
9195   /* send it... */
9196   S (mp);
9197
9198   /* Wait for a reply, return good/bad news  */
9199   W (ret);
9200   return ret;
9201 }
9202
9203 static int
9204 api_create_vlan_subif (vat_main_t * vam)
9205 {
9206   unformat_input_t *i = vam->input;
9207   vl_api_create_vlan_subif_t *mp;
9208   u32 sw_if_index;
9209   u8 sw_if_index_set = 0;
9210   u32 vlan_id;
9211   u8 vlan_id_set = 0;
9212   int ret;
9213
9214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9215     {
9216       if (unformat (i, "sw_if_index %d", &sw_if_index))
9217         sw_if_index_set = 1;
9218       else
9219         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9220         sw_if_index_set = 1;
9221       else if (unformat (i, "vlan %d", &vlan_id))
9222         vlan_id_set = 1;
9223       else
9224         {
9225           clib_warning ("parse error '%U'", format_unformat_error, i);
9226           return -99;
9227         }
9228     }
9229
9230   if (sw_if_index_set == 0)
9231     {
9232       errmsg ("missing interface name or sw_if_index");
9233       return -99;
9234     }
9235
9236   if (vlan_id_set == 0)
9237     {
9238       errmsg ("missing vlan_id");
9239       return -99;
9240     }
9241   M (CREATE_VLAN_SUBIF, mp);
9242
9243   mp->sw_if_index = ntohl (sw_if_index);
9244   mp->vlan_id = ntohl (vlan_id);
9245
9246   S (mp);
9247   W (ret);
9248   return ret;
9249 }
9250
9251 #define foreach_create_subif_bit                \
9252 _(no_tags)                                      \
9253 _(one_tag)                                      \
9254 _(two_tags)                                     \
9255 _(dot1ad)                                       \
9256 _(exact_match)                                  \
9257 _(default_sub)                                  \
9258 _(outer_vlan_id_any)                            \
9259 _(inner_vlan_id_any)
9260
9261 static int
9262 api_create_subif (vat_main_t * vam)
9263 {
9264   unformat_input_t *i = vam->input;
9265   vl_api_create_subif_t *mp;
9266   u32 sw_if_index;
9267   u8 sw_if_index_set = 0;
9268   u32 sub_id;
9269   u8 sub_id_set = 0;
9270   u32 no_tags = 0;
9271   u32 one_tag = 0;
9272   u32 two_tags = 0;
9273   u32 dot1ad = 0;
9274   u32 exact_match = 0;
9275   u32 default_sub = 0;
9276   u32 outer_vlan_id_any = 0;
9277   u32 inner_vlan_id_any = 0;
9278   u32 tmp;
9279   u16 outer_vlan_id = 0;
9280   u16 inner_vlan_id = 0;
9281   int ret;
9282
9283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9284     {
9285       if (unformat (i, "sw_if_index %d", &sw_if_index))
9286         sw_if_index_set = 1;
9287       else
9288         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9289         sw_if_index_set = 1;
9290       else if (unformat (i, "sub_id %d", &sub_id))
9291         sub_id_set = 1;
9292       else if (unformat (i, "outer_vlan_id %d", &tmp))
9293         outer_vlan_id = tmp;
9294       else if (unformat (i, "inner_vlan_id %d", &tmp))
9295         inner_vlan_id = tmp;
9296
9297 #define _(a) else if (unformat (i, #a)) a = 1 ;
9298       foreach_create_subif_bit
9299 #undef _
9300         else
9301         {
9302           clib_warning ("parse error '%U'", format_unformat_error, i);
9303           return -99;
9304         }
9305     }
9306
9307   if (sw_if_index_set == 0)
9308     {
9309       errmsg ("missing interface name or sw_if_index");
9310       return -99;
9311     }
9312
9313   if (sub_id_set == 0)
9314     {
9315       errmsg ("missing sub_id");
9316       return -99;
9317     }
9318   M (CREATE_SUBIF, mp);
9319
9320   mp->sw_if_index = ntohl (sw_if_index);
9321   mp->sub_id = ntohl (sub_id);
9322
9323 #define _(a) mp->a = a;
9324   foreach_create_subif_bit;
9325 #undef _
9326
9327   mp->outer_vlan_id = ntohs (outer_vlan_id);
9328   mp->inner_vlan_id = ntohs (inner_vlan_id);
9329
9330   S (mp);
9331   W (ret);
9332   return ret;
9333 }
9334
9335 static int
9336 api_oam_add_del (vat_main_t * vam)
9337 {
9338   unformat_input_t *i = vam->input;
9339   vl_api_oam_add_del_t *mp;
9340   u32 vrf_id = 0;
9341   u8 is_add = 1;
9342   ip4_address_t src, dst;
9343   u8 src_set = 0;
9344   u8 dst_set = 0;
9345   int ret;
9346
9347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9348     {
9349       if (unformat (i, "vrf %d", &vrf_id))
9350         ;
9351       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9352         src_set = 1;
9353       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9354         dst_set = 1;
9355       else if (unformat (i, "del"))
9356         is_add = 0;
9357       else
9358         {
9359           clib_warning ("parse error '%U'", format_unformat_error, i);
9360           return -99;
9361         }
9362     }
9363
9364   if (src_set == 0)
9365     {
9366       errmsg ("missing src addr");
9367       return -99;
9368     }
9369
9370   if (dst_set == 0)
9371     {
9372       errmsg ("missing dst addr");
9373       return -99;
9374     }
9375
9376   M (OAM_ADD_DEL, mp);
9377
9378   mp->vrf_id = ntohl (vrf_id);
9379   mp->is_add = is_add;
9380   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9381   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9382
9383   S (mp);
9384   W (ret);
9385   return ret;
9386 }
9387
9388 static int
9389 api_reset_fib (vat_main_t * vam)
9390 {
9391   unformat_input_t *i = vam->input;
9392   vl_api_reset_fib_t *mp;
9393   u32 vrf_id = 0;
9394   u8 is_ipv6 = 0;
9395   u8 vrf_id_set = 0;
9396
9397   int ret;
9398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9399     {
9400       if (unformat (i, "vrf %d", &vrf_id))
9401         vrf_id_set = 1;
9402       else if (unformat (i, "ipv6"))
9403         is_ipv6 = 1;
9404       else
9405         {
9406           clib_warning ("parse error '%U'", format_unformat_error, i);
9407           return -99;
9408         }
9409     }
9410
9411   if (vrf_id_set == 0)
9412     {
9413       errmsg ("missing vrf id");
9414       return -99;
9415     }
9416
9417   M (RESET_FIB, mp);
9418
9419   mp->vrf_id = ntohl (vrf_id);
9420   mp->is_ipv6 = is_ipv6;
9421
9422   S (mp);
9423   W (ret);
9424   return ret;
9425 }
9426
9427 static int
9428 api_dhcp_proxy_config (vat_main_t * vam)
9429 {
9430   unformat_input_t *i = vam->input;
9431   vl_api_dhcp_proxy_config_t *mp;
9432   u32 rx_vrf_id = 0;
9433   u32 server_vrf_id = 0;
9434   u8 is_add = 1;
9435   u8 v4_address_set = 0;
9436   u8 v6_address_set = 0;
9437   ip4_address_t v4address;
9438   ip6_address_t v6address;
9439   u8 v4_src_address_set = 0;
9440   u8 v6_src_address_set = 0;
9441   ip4_address_t v4srcaddress;
9442   ip6_address_t v6srcaddress;
9443   int ret;
9444
9445   /* Parse args required to build the message */
9446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9447     {
9448       if (unformat (i, "del"))
9449         is_add = 0;
9450       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9451         ;
9452       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9453         ;
9454       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9455         v4_address_set = 1;
9456       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9457         v6_address_set = 1;
9458       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9459         v4_src_address_set = 1;
9460       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9461         v6_src_address_set = 1;
9462       else
9463         break;
9464     }
9465
9466   if (v4_address_set && v6_address_set)
9467     {
9468       errmsg ("both v4 and v6 server addresses set");
9469       return -99;
9470     }
9471   if (!v4_address_set && !v6_address_set)
9472     {
9473       errmsg ("no server addresses set");
9474       return -99;
9475     }
9476
9477   if (v4_src_address_set && v6_src_address_set)
9478     {
9479       errmsg ("both v4 and v6  src addresses set");
9480       return -99;
9481     }
9482   if (!v4_src_address_set && !v6_src_address_set)
9483     {
9484       errmsg ("no src addresses set");
9485       return -99;
9486     }
9487
9488   if (!(v4_src_address_set && v4_address_set) &&
9489       !(v6_src_address_set && v6_address_set))
9490     {
9491       errmsg ("no matching server and src addresses set");
9492       return -99;
9493     }
9494
9495   /* Construct the API message */
9496   M (DHCP_PROXY_CONFIG, mp);
9497
9498   mp->is_add = is_add;
9499   mp->rx_vrf_id = ntohl (rx_vrf_id);
9500   mp->server_vrf_id = ntohl (server_vrf_id);
9501   if (v6_address_set)
9502     {
9503       mp->is_ipv6 = 1;
9504       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9505       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9506     }
9507   else
9508     {
9509       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9510       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9511     }
9512
9513   /* send it... */
9514   S (mp);
9515
9516   /* Wait for a reply, return good/bad news  */
9517   W (ret);
9518   return ret;
9519 }
9520
9521 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9522 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9523
9524 static void
9525 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9526 {
9527   vat_main_t *vam = &vat_main;
9528   u32 i, count = mp->count;
9529   vl_api_dhcp_server_t *s;
9530
9531   if (mp->is_ipv6)
9532     print (vam->ofp,
9533            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9534            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9535            ntohl (mp->rx_vrf_id),
9536            format_ip6_address, mp->dhcp_src_address,
9537            mp->vss_type, mp->vss_vpn_ascii_id,
9538            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9539   else
9540     print (vam->ofp,
9541            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9542            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9543            ntohl (mp->rx_vrf_id),
9544            format_ip4_address, mp->dhcp_src_address,
9545            mp->vss_type, mp->vss_vpn_ascii_id,
9546            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9547
9548   for (i = 0; i < count; i++)
9549     {
9550       s = &mp->servers[i];
9551
9552       if (mp->is_ipv6)
9553         print (vam->ofp,
9554                " Server Table-ID %d, Server Address %U",
9555                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9556       else
9557         print (vam->ofp,
9558                " Server Table-ID %d, Server Address %U",
9559                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9560     }
9561 }
9562
9563 static void vl_api_dhcp_proxy_details_t_handler_json
9564   (vl_api_dhcp_proxy_details_t * mp)
9565 {
9566   vat_main_t *vam = &vat_main;
9567   vat_json_node_t *node = NULL;
9568   u32 i, count = mp->count;
9569   struct in_addr ip4;
9570   struct in6_addr ip6;
9571   vl_api_dhcp_server_t *s;
9572
9573   if (VAT_JSON_ARRAY != vam->json_tree.type)
9574     {
9575       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9576       vat_json_init_array (&vam->json_tree);
9577     }
9578   node = vat_json_array_add (&vam->json_tree);
9579
9580   vat_json_init_object (node);
9581   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9582   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9583                              sizeof (mp->vss_type));
9584   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9585                                    mp->vss_vpn_ascii_id);
9586   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9587   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9588
9589   if (mp->is_ipv6)
9590     {
9591       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9592       vat_json_object_add_ip6 (node, "src_address", ip6);
9593     }
9594   else
9595     {
9596       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9597       vat_json_object_add_ip4 (node, "src_address", ip4);
9598     }
9599
9600   for (i = 0; i < count; i++)
9601     {
9602       s = &mp->servers[i];
9603
9604       vat_json_object_add_uint (node, "server-table-id",
9605                                 ntohl (s->server_vrf_id));
9606
9607       if (mp->is_ipv6)
9608         {
9609           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9610           vat_json_object_add_ip4 (node, "src_address", ip4);
9611         }
9612       else
9613         {
9614           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9615           vat_json_object_add_ip6 (node, "server_address", ip6);
9616         }
9617     }
9618 }
9619
9620 static int
9621 api_dhcp_proxy_dump (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_control_ping_t *mp_ping;
9625   vl_api_dhcp_proxy_dump_t *mp;
9626   u8 is_ipv6 = 0;
9627   int ret;
9628
9629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9630     {
9631       if (unformat (i, "ipv6"))
9632         is_ipv6 = 1;
9633       else
9634         {
9635           clib_warning ("parse error '%U'", format_unformat_error, i);
9636           return -99;
9637         }
9638     }
9639
9640   M (DHCP_PROXY_DUMP, mp);
9641
9642   mp->is_ip6 = is_ipv6;
9643   S (mp);
9644
9645   /* Use a control ping for synchronization */
9646   MPING (CONTROL_PING, mp_ping);
9647   S (mp_ping);
9648
9649   W (ret);
9650   return ret;
9651 }
9652
9653 static int
9654 api_dhcp_proxy_set_vss (vat_main_t * vam)
9655 {
9656   unformat_input_t *i = vam->input;
9657   vl_api_dhcp_proxy_set_vss_t *mp;
9658   u8 is_ipv6 = 0;
9659   u8 is_add = 1;
9660   u32 tbl_id = ~0;
9661   u8 vss_type = VSS_TYPE_DEFAULT;
9662   u8 *vpn_ascii_id = 0;
9663   u32 oui = 0;
9664   u32 fib_id = 0;
9665   int ret;
9666
9667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9668     {
9669       if (unformat (i, "tbl_id %d", &tbl_id))
9670         ;
9671       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9672         vss_type = VSS_TYPE_ASCII;
9673       else if (unformat (i, "fib_id %d", &fib_id))
9674         vss_type = VSS_TYPE_VPN_ID;
9675       else if (unformat (i, "oui %d", &oui))
9676         vss_type = VSS_TYPE_VPN_ID;
9677       else if (unformat (i, "ipv6"))
9678         is_ipv6 = 1;
9679       else if (unformat (i, "del"))
9680         is_add = 0;
9681       else
9682         break;
9683     }
9684
9685   if (tbl_id == ~0)
9686     {
9687       errmsg ("missing tbl_id ");
9688       vec_free (vpn_ascii_id);
9689       return -99;
9690     }
9691
9692   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9693     {
9694       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9695       vec_free (vpn_ascii_id);
9696       return -99;
9697     }
9698
9699   M (DHCP_PROXY_SET_VSS, mp);
9700   mp->tbl_id = ntohl (tbl_id);
9701   mp->vss_type = vss_type;
9702   if (vpn_ascii_id)
9703     {
9704       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9705       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9706     }
9707   mp->vpn_index = ntohl (fib_id);
9708   mp->oui = ntohl (oui);
9709   mp->is_ipv6 = is_ipv6;
9710   mp->is_add = is_add;
9711
9712   S (mp);
9713   W (ret);
9714
9715   vec_free (vpn_ascii_id);
9716   return ret;
9717 }
9718
9719 static int
9720 api_dhcp_client_config (vat_main_t * vam)
9721 {
9722   unformat_input_t *i = vam->input;
9723   vl_api_dhcp_client_config_t *mp;
9724   u32 sw_if_index;
9725   u8 sw_if_index_set = 0;
9726   u8 is_add = 1;
9727   u8 *hostname = 0;
9728   u8 disable_event = 0;
9729   int ret;
9730
9731   /* Parse args required to build the message */
9732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9733     {
9734       if (unformat (i, "del"))
9735         is_add = 0;
9736       else
9737         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9738         sw_if_index_set = 1;
9739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9740         sw_if_index_set = 1;
9741       else if (unformat (i, "hostname %s", &hostname))
9742         ;
9743       else if (unformat (i, "disable_event"))
9744         disable_event = 1;
9745       else
9746         break;
9747     }
9748
9749   if (sw_if_index_set == 0)
9750     {
9751       errmsg ("missing interface name or sw_if_index");
9752       return -99;
9753     }
9754
9755   if (vec_len (hostname) > 63)
9756     {
9757       errmsg ("hostname too long");
9758     }
9759   vec_add1 (hostname, 0);
9760
9761   /* Construct the API message */
9762   M (DHCP_CLIENT_CONFIG, mp);
9763
9764   mp->sw_if_index = htonl (sw_if_index);
9765   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9766   vec_free (hostname);
9767   mp->is_add = is_add;
9768   mp->want_dhcp_event = disable_event ? 0 : 1;
9769   mp->pid = htonl (getpid ());
9770
9771   /* send it... */
9772   S (mp);
9773
9774   /* Wait for a reply, return good/bad news  */
9775   W (ret);
9776   return ret;
9777 }
9778
9779 static int
9780 api_set_ip_flow_hash (vat_main_t * vam)
9781 {
9782   unformat_input_t *i = vam->input;
9783   vl_api_set_ip_flow_hash_t *mp;
9784   u32 vrf_id = 0;
9785   u8 is_ipv6 = 0;
9786   u8 vrf_id_set = 0;
9787   u8 src = 0;
9788   u8 dst = 0;
9789   u8 sport = 0;
9790   u8 dport = 0;
9791   u8 proto = 0;
9792   u8 reverse = 0;
9793   int ret;
9794
9795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9796     {
9797       if (unformat (i, "vrf %d", &vrf_id))
9798         vrf_id_set = 1;
9799       else if (unformat (i, "ipv6"))
9800         is_ipv6 = 1;
9801       else if (unformat (i, "src"))
9802         src = 1;
9803       else if (unformat (i, "dst"))
9804         dst = 1;
9805       else if (unformat (i, "sport"))
9806         sport = 1;
9807       else if (unformat (i, "dport"))
9808         dport = 1;
9809       else if (unformat (i, "proto"))
9810         proto = 1;
9811       else if (unformat (i, "reverse"))
9812         reverse = 1;
9813
9814       else
9815         {
9816           clib_warning ("parse error '%U'", format_unformat_error, i);
9817           return -99;
9818         }
9819     }
9820
9821   if (vrf_id_set == 0)
9822     {
9823       errmsg ("missing vrf id");
9824       return -99;
9825     }
9826
9827   M (SET_IP_FLOW_HASH, mp);
9828   mp->src = src;
9829   mp->dst = dst;
9830   mp->sport = sport;
9831   mp->dport = dport;
9832   mp->proto = proto;
9833   mp->reverse = reverse;
9834   mp->vrf_id = ntohl (vrf_id);
9835   mp->is_ipv6 = is_ipv6;
9836
9837   S (mp);
9838   W (ret);
9839   return ret;
9840 }
9841
9842 static int
9843 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9844 {
9845   unformat_input_t *i = vam->input;
9846   vl_api_sw_interface_ip6_enable_disable_t *mp;
9847   u32 sw_if_index;
9848   u8 sw_if_index_set = 0;
9849   u8 enable = 0;
9850   int ret;
9851
9852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9855         sw_if_index_set = 1;
9856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9857         sw_if_index_set = 1;
9858       else if (unformat (i, "enable"))
9859         enable = 1;
9860       else if (unformat (i, "disable"))
9861         enable = 0;
9862       else
9863         {
9864           clib_warning ("parse error '%U'", format_unformat_error, i);
9865           return -99;
9866         }
9867     }
9868
9869   if (sw_if_index_set == 0)
9870     {
9871       errmsg ("missing interface name or sw_if_index");
9872       return -99;
9873     }
9874
9875   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9876
9877   mp->sw_if_index = ntohl (sw_if_index);
9878   mp->enable = enable;
9879
9880   S (mp);
9881   W (ret);
9882   return ret;
9883 }
9884
9885 static int
9886 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9890   u32 sw_if_index;
9891   u8 sw_if_index_set = 0;
9892   u8 v6_address_set = 0;
9893   ip6_address_t v6address;
9894   int ret;
9895
9896   /* Parse args required to build the message */
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9904         v6_address_set = 1;
9905       else
9906         break;
9907     }
9908
9909   if (sw_if_index_set == 0)
9910     {
9911       errmsg ("missing interface name or sw_if_index");
9912       return -99;
9913     }
9914   if (!v6_address_set)
9915     {
9916       errmsg ("no address set");
9917       return -99;
9918     }
9919
9920   /* Construct the API message */
9921   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9922
9923   mp->sw_if_index = ntohl (sw_if_index);
9924   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9925
9926   /* send it... */
9927   S (mp);
9928
9929   /* Wait for a reply, return good/bad news  */
9930   W (ret);
9931   return ret;
9932 }
9933
9934 static int
9935 api_ip6nd_proxy_add_del (vat_main_t * vam)
9936 {
9937   unformat_input_t *i = vam->input;
9938   vl_api_ip6nd_proxy_add_del_t *mp;
9939   u32 sw_if_index = ~0;
9940   u8 v6_address_set = 0;
9941   ip6_address_t v6address;
9942   u8 is_del = 0;
9943   int ret;
9944
9945   /* Parse args required to build the message */
9946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9947     {
9948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9949         ;
9950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9951         ;
9952       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9953         v6_address_set = 1;
9954       if (unformat (i, "del"))
9955         is_del = 1;
9956       else
9957         {
9958           clib_warning ("parse error '%U'", format_unformat_error, i);
9959           return -99;
9960         }
9961     }
9962
9963   if (sw_if_index == ~0)
9964     {
9965       errmsg ("missing interface name or sw_if_index");
9966       return -99;
9967     }
9968   if (!v6_address_set)
9969     {
9970       errmsg ("no address set");
9971       return -99;
9972     }
9973
9974   /* Construct the API message */
9975   M (IP6ND_PROXY_ADD_DEL, mp);
9976
9977   mp->is_del = is_del;
9978   mp->sw_if_index = ntohl (sw_if_index);
9979   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9980
9981   /* send it... */
9982   S (mp);
9983
9984   /* Wait for a reply, return good/bad news  */
9985   W (ret);
9986   return ret;
9987 }
9988
9989 static int
9990 api_ip6nd_proxy_dump (vat_main_t * vam)
9991 {
9992   vl_api_ip6nd_proxy_dump_t *mp;
9993   vl_api_control_ping_t *mp_ping;
9994   int ret;
9995
9996   M (IP6ND_PROXY_DUMP, mp);
9997
9998   S (mp);
9999
10000   /* Use a control ping for synchronization */
10001   MPING (CONTROL_PING, mp_ping);
10002   S (mp_ping);
10003
10004   W (ret);
10005   return ret;
10006 }
10007
10008 static void vl_api_ip6nd_proxy_details_t_handler
10009   (vl_api_ip6nd_proxy_details_t * mp)
10010 {
10011   vat_main_t *vam = &vat_main;
10012
10013   print (vam->ofp, "host %U sw_if_index %d",
10014          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10015 }
10016
10017 static void vl_api_ip6nd_proxy_details_t_handler_json
10018   (vl_api_ip6nd_proxy_details_t * mp)
10019 {
10020   vat_main_t *vam = &vat_main;
10021   struct in6_addr ip6;
10022   vat_json_node_t *node = NULL;
10023
10024   if (VAT_JSON_ARRAY != vam->json_tree.type)
10025     {
10026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10027       vat_json_init_array (&vam->json_tree);
10028     }
10029   node = vat_json_array_add (&vam->json_tree);
10030
10031   vat_json_init_object (node);
10032   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10033
10034   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10035   vat_json_object_add_ip6 (node, "host", ip6);
10036 }
10037
10038 static int
10039 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10040 {
10041   unformat_input_t *i = vam->input;
10042   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10043   u32 sw_if_index;
10044   u8 sw_if_index_set = 0;
10045   u32 address_length = 0;
10046   u8 v6_address_set = 0;
10047   ip6_address_t v6address;
10048   u8 use_default = 0;
10049   u8 no_advertise = 0;
10050   u8 off_link = 0;
10051   u8 no_autoconfig = 0;
10052   u8 no_onlink = 0;
10053   u8 is_no = 0;
10054   u32 val_lifetime = 0;
10055   u32 pref_lifetime = 0;
10056   int ret;
10057
10058   /* Parse args required to build the message */
10059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10060     {
10061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10062         sw_if_index_set = 1;
10063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10064         sw_if_index_set = 1;
10065       else if (unformat (i, "%U/%d",
10066                          unformat_ip6_address, &v6address, &address_length))
10067         v6_address_set = 1;
10068       else if (unformat (i, "val_life %d", &val_lifetime))
10069         ;
10070       else if (unformat (i, "pref_life %d", &pref_lifetime))
10071         ;
10072       else if (unformat (i, "def"))
10073         use_default = 1;
10074       else if (unformat (i, "noadv"))
10075         no_advertise = 1;
10076       else if (unformat (i, "offl"))
10077         off_link = 1;
10078       else if (unformat (i, "noauto"))
10079         no_autoconfig = 1;
10080       else if (unformat (i, "nolink"))
10081         no_onlink = 1;
10082       else if (unformat (i, "isno"))
10083         is_no = 1;
10084       else
10085         {
10086           clib_warning ("parse error '%U'", format_unformat_error, i);
10087           return -99;
10088         }
10089     }
10090
10091   if (sw_if_index_set == 0)
10092     {
10093       errmsg ("missing interface name or sw_if_index");
10094       return -99;
10095     }
10096   if (!v6_address_set)
10097     {
10098       errmsg ("no address set");
10099       return -99;
10100     }
10101
10102   /* Construct the API message */
10103   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10104
10105   mp->sw_if_index = ntohl (sw_if_index);
10106   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10107   mp->address_length = address_length;
10108   mp->use_default = use_default;
10109   mp->no_advertise = no_advertise;
10110   mp->off_link = off_link;
10111   mp->no_autoconfig = no_autoconfig;
10112   mp->no_onlink = no_onlink;
10113   mp->is_no = is_no;
10114   mp->val_lifetime = ntohl (val_lifetime);
10115   mp->pref_lifetime = ntohl (pref_lifetime);
10116
10117   /* send it... */
10118   S (mp);
10119
10120   /* Wait for a reply, return good/bad news  */
10121   W (ret);
10122   return ret;
10123 }
10124
10125 static int
10126 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10127 {
10128   unformat_input_t *i = vam->input;
10129   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10130   u32 sw_if_index;
10131   u8 sw_if_index_set = 0;
10132   u8 suppress = 0;
10133   u8 managed = 0;
10134   u8 other = 0;
10135   u8 ll_option = 0;
10136   u8 send_unicast = 0;
10137   u8 cease = 0;
10138   u8 is_no = 0;
10139   u8 default_router = 0;
10140   u32 max_interval = 0;
10141   u32 min_interval = 0;
10142   u32 lifetime = 0;
10143   u32 initial_count = 0;
10144   u32 initial_interval = 0;
10145   int ret;
10146
10147
10148   /* Parse args required to build the message */
10149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10152         sw_if_index_set = 1;
10153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10154         sw_if_index_set = 1;
10155       else if (unformat (i, "maxint %d", &max_interval))
10156         ;
10157       else if (unformat (i, "minint %d", &min_interval))
10158         ;
10159       else if (unformat (i, "life %d", &lifetime))
10160         ;
10161       else if (unformat (i, "count %d", &initial_count))
10162         ;
10163       else if (unformat (i, "interval %d", &initial_interval))
10164         ;
10165       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10166         suppress = 1;
10167       else if (unformat (i, "managed"))
10168         managed = 1;
10169       else if (unformat (i, "other"))
10170         other = 1;
10171       else if (unformat (i, "ll"))
10172         ll_option = 1;
10173       else if (unformat (i, "send"))
10174         send_unicast = 1;
10175       else if (unformat (i, "cease"))
10176         cease = 1;
10177       else if (unformat (i, "isno"))
10178         is_no = 1;
10179       else if (unformat (i, "def"))
10180         default_router = 1;
10181       else
10182         {
10183           clib_warning ("parse error '%U'", format_unformat_error, i);
10184           return -99;
10185         }
10186     }
10187
10188   if (sw_if_index_set == 0)
10189     {
10190       errmsg ("missing interface name or sw_if_index");
10191       return -99;
10192     }
10193
10194   /* Construct the API message */
10195   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10196
10197   mp->sw_if_index = ntohl (sw_if_index);
10198   mp->max_interval = ntohl (max_interval);
10199   mp->min_interval = ntohl (min_interval);
10200   mp->lifetime = ntohl (lifetime);
10201   mp->initial_count = ntohl (initial_count);
10202   mp->initial_interval = ntohl (initial_interval);
10203   mp->suppress = suppress;
10204   mp->managed = managed;
10205   mp->other = other;
10206   mp->ll_option = ll_option;
10207   mp->send_unicast = send_unicast;
10208   mp->cease = cease;
10209   mp->is_no = is_no;
10210   mp->default_router = default_router;
10211
10212   /* send it... */
10213   S (mp);
10214
10215   /* Wait for a reply, return good/bad news  */
10216   W (ret);
10217   return ret;
10218 }
10219
10220 static int
10221 api_set_arp_neighbor_limit (vat_main_t * vam)
10222 {
10223   unformat_input_t *i = vam->input;
10224   vl_api_set_arp_neighbor_limit_t *mp;
10225   u32 arp_nbr_limit;
10226   u8 limit_set = 0;
10227   u8 is_ipv6 = 0;
10228   int ret;
10229
10230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10231     {
10232       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10233         limit_set = 1;
10234       else if (unformat (i, "ipv6"))
10235         is_ipv6 = 1;
10236       else
10237         {
10238           clib_warning ("parse error '%U'", format_unformat_error, i);
10239           return -99;
10240         }
10241     }
10242
10243   if (limit_set == 0)
10244     {
10245       errmsg ("missing limit value");
10246       return -99;
10247     }
10248
10249   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10250
10251   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10252   mp->is_ipv6 = is_ipv6;
10253
10254   S (mp);
10255   W (ret);
10256   return ret;
10257 }
10258
10259 static int
10260 api_l2_patch_add_del (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   vl_api_l2_patch_add_del_t *mp;
10264   u32 rx_sw_if_index;
10265   u8 rx_sw_if_index_set = 0;
10266   u32 tx_sw_if_index;
10267   u8 tx_sw_if_index_set = 0;
10268   u8 is_add = 1;
10269   int ret;
10270
10271   /* Parse args required to build the message */
10272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10273     {
10274       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10275         rx_sw_if_index_set = 1;
10276       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10277         tx_sw_if_index_set = 1;
10278       else if (unformat (i, "rx"))
10279         {
10280           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10281             {
10282               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10283                             &rx_sw_if_index))
10284                 rx_sw_if_index_set = 1;
10285             }
10286           else
10287             break;
10288         }
10289       else if (unformat (i, "tx"))
10290         {
10291           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10292             {
10293               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10294                             &tx_sw_if_index))
10295                 tx_sw_if_index_set = 1;
10296             }
10297           else
10298             break;
10299         }
10300       else if (unformat (i, "del"))
10301         is_add = 0;
10302       else
10303         break;
10304     }
10305
10306   if (rx_sw_if_index_set == 0)
10307     {
10308       errmsg ("missing rx interface name or rx_sw_if_index");
10309       return -99;
10310     }
10311
10312   if (tx_sw_if_index_set == 0)
10313     {
10314       errmsg ("missing tx interface name or tx_sw_if_index");
10315       return -99;
10316     }
10317
10318   M (L2_PATCH_ADD_DEL, mp);
10319
10320   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10321   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10322   mp->is_add = is_add;
10323
10324   S (mp);
10325   W (ret);
10326   return ret;
10327 }
10328
10329 u8 is_del;
10330 u8 localsid_addr[16];
10331 u8 end_psp;
10332 u8 behavior;
10333 u32 sw_if_index;
10334 u32 vlan_index;
10335 u32 fib_table;
10336 u8 nh_addr[16];
10337
10338 static int
10339 api_sr_localsid_add_del (vat_main_t * vam)
10340 {
10341   unformat_input_t *i = vam->input;
10342   vl_api_sr_localsid_add_del_t *mp;
10343
10344   u8 is_del;
10345   ip6_address_t localsid;
10346   u8 end_psp = 0;
10347   u8 behavior = ~0;
10348   u32 sw_if_index;
10349   u32 fib_table = ~(u32) 0;
10350   ip6_address_t next_hop;
10351
10352   bool nexthop_set = 0;
10353
10354   int ret;
10355
10356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10357     {
10358       if (unformat (i, "del"))
10359         is_del = 1;
10360       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10361       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10362         nexthop_set = 1;
10363       else if (unformat (i, "behavior %u", &behavior));
10364       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10365       else if (unformat (i, "fib-table %u", &fib_table));
10366       else if (unformat (i, "end.psp %u", &behavior));
10367       else
10368         break;
10369     }
10370
10371   M (SR_LOCALSID_ADD_DEL, mp);
10372
10373   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10374   if (nexthop_set)
10375     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10376   mp->behavior = behavior;
10377   mp->sw_if_index = ntohl (sw_if_index);
10378   mp->fib_table = ntohl (fib_table);
10379   mp->end_psp = end_psp;
10380   mp->is_del = is_del;
10381
10382   S (mp);
10383   W (ret);
10384   return ret;
10385 }
10386
10387 static int
10388 api_ioam_enable (vat_main_t * vam)
10389 {
10390   unformat_input_t *input = vam->input;
10391   vl_api_ioam_enable_t *mp;
10392   u32 id = 0;
10393   int has_trace_option = 0;
10394   int has_pot_option = 0;
10395   int has_seqno_option = 0;
10396   int has_analyse_option = 0;
10397   int ret;
10398
10399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (input, "trace"))
10402         has_trace_option = 1;
10403       else if (unformat (input, "pot"))
10404         has_pot_option = 1;
10405       else if (unformat (input, "seqno"))
10406         has_seqno_option = 1;
10407       else if (unformat (input, "analyse"))
10408         has_analyse_option = 1;
10409       else
10410         break;
10411     }
10412   M (IOAM_ENABLE, mp);
10413   mp->id = htons (id);
10414   mp->seqno = has_seqno_option;
10415   mp->analyse = has_analyse_option;
10416   mp->pot_enable = has_pot_option;
10417   mp->trace_enable = has_trace_option;
10418
10419   S (mp);
10420   W (ret);
10421   return ret;
10422 }
10423
10424
10425 static int
10426 api_ioam_disable (vat_main_t * vam)
10427 {
10428   vl_api_ioam_disable_t *mp;
10429   int ret;
10430
10431   M (IOAM_DISABLE, mp);
10432   S (mp);
10433   W (ret);
10434   return ret;
10435 }
10436
10437 #define foreach_tcp_proto_field                 \
10438 _(src_port)                                     \
10439 _(dst_port)
10440
10441 #define foreach_udp_proto_field                 \
10442 _(src_port)                                     \
10443 _(dst_port)
10444
10445 #define foreach_ip4_proto_field                 \
10446 _(src_address)                                  \
10447 _(dst_address)                                  \
10448 _(tos)                                          \
10449 _(length)                                       \
10450 _(fragment_id)                                  \
10451 _(ttl)                                          \
10452 _(protocol)                                     \
10453 _(checksum)
10454
10455 typedef struct
10456 {
10457   u16 src_port, dst_port;
10458 } tcpudp_header_t;
10459
10460 #if VPP_API_TEST_BUILTIN == 0
10461 uword
10462 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10463 {
10464   u8 **maskp = va_arg (*args, u8 **);
10465   u8 *mask = 0;
10466   u8 found_something = 0;
10467   tcp_header_t *tcp;
10468
10469 #define _(a) u8 a=0;
10470   foreach_tcp_proto_field;
10471 #undef _
10472
10473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10474     {
10475       if (0);
10476 #define _(a) else if (unformat (input, #a)) a=1;
10477       foreach_tcp_proto_field
10478 #undef _
10479         else
10480         break;
10481     }
10482
10483 #define _(a) found_something += a;
10484   foreach_tcp_proto_field;
10485 #undef _
10486
10487   if (found_something == 0)
10488     return 0;
10489
10490   vec_validate (mask, sizeof (*tcp) - 1);
10491
10492   tcp = (tcp_header_t *) mask;
10493
10494 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10495   foreach_tcp_proto_field;
10496 #undef _
10497
10498   *maskp = mask;
10499   return 1;
10500 }
10501
10502 uword
10503 unformat_udp_mask (unformat_input_t * input, va_list * args)
10504 {
10505   u8 **maskp = va_arg (*args, u8 **);
10506   u8 *mask = 0;
10507   u8 found_something = 0;
10508   udp_header_t *udp;
10509
10510 #define _(a) u8 a=0;
10511   foreach_udp_proto_field;
10512 #undef _
10513
10514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (0);
10517 #define _(a) else if (unformat (input, #a)) a=1;
10518       foreach_udp_proto_field
10519 #undef _
10520         else
10521         break;
10522     }
10523
10524 #define _(a) found_something += a;
10525   foreach_udp_proto_field;
10526 #undef _
10527
10528   if (found_something == 0)
10529     return 0;
10530
10531   vec_validate (mask, sizeof (*udp) - 1);
10532
10533   udp = (udp_header_t *) mask;
10534
10535 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10536   foreach_udp_proto_field;
10537 #undef _
10538
10539   *maskp = mask;
10540   return 1;
10541 }
10542
10543 uword
10544 unformat_l4_mask (unformat_input_t * input, va_list * args)
10545 {
10546   u8 **maskp = va_arg (*args, u8 **);
10547   u16 src_port = 0, dst_port = 0;
10548   tcpudp_header_t *tcpudp;
10549
10550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10553         return 1;
10554       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10555         return 1;
10556       else if (unformat (input, "src_port"))
10557         src_port = 0xFFFF;
10558       else if (unformat (input, "dst_port"))
10559         dst_port = 0xFFFF;
10560       else
10561         return 0;
10562     }
10563
10564   if (!src_port && !dst_port)
10565     return 0;
10566
10567   u8 *mask = 0;
10568   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10569
10570   tcpudp = (tcpudp_header_t *) mask;
10571   tcpudp->src_port = src_port;
10572   tcpudp->dst_port = dst_port;
10573
10574   *maskp = mask;
10575
10576   return 1;
10577 }
10578
10579 uword
10580 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10581 {
10582   u8 **maskp = va_arg (*args, u8 **);
10583   u8 *mask = 0;
10584   u8 found_something = 0;
10585   ip4_header_t *ip;
10586
10587 #define _(a) u8 a=0;
10588   foreach_ip4_proto_field;
10589 #undef _
10590   u8 version = 0;
10591   u8 hdr_length = 0;
10592
10593
10594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (input, "version"))
10597         version = 1;
10598       else if (unformat (input, "hdr_length"))
10599         hdr_length = 1;
10600       else if (unformat (input, "src"))
10601         src_address = 1;
10602       else if (unformat (input, "dst"))
10603         dst_address = 1;
10604       else if (unformat (input, "proto"))
10605         protocol = 1;
10606
10607 #define _(a) else if (unformat (input, #a)) a=1;
10608       foreach_ip4_proto_field
10609 #undef _
10610         else
10611         break;
10612     }
10613
10614 #define _(a) found_something += a;
10615   foreach_ip4_proto_field;
10616 #undef _
10617
10618   if (found_something == 0)
10619     return 0;
10620
10621   vec_validate (mask, sizeof (*ip) - 1);
10622
10623   ip = (ip4_header_t *) mask;
10624
10625 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10626   foreach_ip4_proto_field;
10627 #undef _
10628
10629   ip->ip_version_and_header_length = 0;
10630
10631   if (version)
10632     ip->ip_version_and_header_length |= 0xF0;
10633
10634   if (hdr_length)
10635     ip->ip_version_and_header_length |= 0x0F;
10636
10637   *maskp = mask;
10638   return 1;
10639 }
10640
10641 #define foreach_ip6_proto_field                 \
10642 _(src_address)                                  \
10643 _(dst_address)                                  \
10644 _(payload_length)                               \
10645 _(hop_limit)                                    \
10646 _(protocol)
10647
10648 uword
10649 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10650 {
10651   u8 **maskp = va_arg (*args, u8 **);
10652   u8 *mask = 0;
10653   u8 found_something = 0;
10654   ip6_header_t *ip;
10655   u32 ip_version_traffic_class_and_flow_label;
10656
10657 #define _(a) u8 a=0;
10658   foreach_ip6_proto_field;
10659 #undef _
10660   u8 version = 0;
10661   u8 traffic_class = 0;
10662   u8 flow_label = 0;
10663
10664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10665     {
10666       if (unformat (input, "version"))
10667         version = 1;
10668       else if (unformat (input, "traffic-class"))
10669         traffic_class = 1;
10670       else if (unformat (input, "flow-label"))
10671         flow_label = 1;
10672       else if (unformat (input, "src"))
10673         src_address = 1;
10674       else if (unformat (input, "dst"))
10675         dst_address = 1;
10676       else if (unformat (input, "proto"))
10677         protocol = 1;
10678
10679 #define _(a) else if (unformat (input, #a)) a=1;
10680       foreach_ip6_proto_field
10681 #undef _
10682         else
10683         break;
10684     }
10685
10686 #define _(a) found_something += a;
10687   foreach_ip6_proto_field;
10688 #undef _
10689
10690   if (found_something == 0)
10691     return 0;
10692
10693   vec_validate (mask, sizeof (*ip) - 1);
10694
10695   ip = (ip6_header_t *) mask;
10696
10697 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10698   foreach_ip6_proto_field;
10699 #undef _
10700
10701   ip_version_traffic_class_and_flow_label = 0;
10702
10703   if (version)
10704     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10705
10706   if (traffic_class)
10707     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10708
10709   if (flow_label)
10710     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10711
10712   ip->ip_version_traffic_class_and_flow_label =
10713     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10714
10715   *maskp = mask;
10716   return 1;
10717 }
10718
10719 uword
10720 unformat_l3_mask (unformat_input_t * input, va_list * args)
10721 {
10722   u8 **maskp = va_arg (*args, u8 **);
10723
10724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10725     {
10726       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10727         return 1;
10728       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10729         return 1;
10730       else
10731         break;
10732     }
10733   return 0;
10734 }
10735
10736 uword
10737 unformat_l2_mask (unformat_input_t * input, va_list * args)
10738 {
10739   u8 **maskp = va_arg (*args, u8 **);
10740   u8 *mask = 0;
10741   u8 src = 0;
10742   u8 dst = 0;
10743   u8 proto = 0;
10744   u8 tag1 = 0;
10745   u8 tag2 = 0;
10746   u8 ignore_tag1 = 0;
10747   u8 ignore_tag2 = 0;
10748   u8 cos1 = 0;
10749   u8 cos2 = 0;
10750   u8 dot1q = 0;
10751   u8 dot1ad = 0;
10752   int len = 14;
10753
10754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10755     {
10756       if (unformat (input, "src"))
10757         src = 1;
10758       else if (unformat (input, "dst"))
10759         dst = 1;
10760       else if (unformat (input, "proto"))
10761         proto = 1;
10762       else if (unformat (input, "tag1"))
10763         tag1 = 1;
10764       else if (unformat (input, "tag2"))
10765         tag2 = 1;
10766       else if (unformat (input, "ignore-tag1"))
10767         ignore_tag1 = 1;
10768       else if (unformat (input, "ignore-tag2"))
10769         ignore_tag2 = 1;
10770       else if (unformat (input, "cos1"))
10771         cos1 = 1;
10772       else if (unformat (input, "cos2"))
10773         cos2 = 1;
10774       else if (unformat (input, "dot1q"))
10775         dot1q = 1;
10776       else if (unformat (input, "dot1ad"))
10777         dot1ad = 1;
10778       else
10779         break;
10780     }
10781   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10782        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10783     return 0;
10784
10785   if (tag1 || ignore_tag1 || cos1 || dot1q)
10786     len = 18;
10787   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10788     len = 22;
10789
10790   vec_validate (mask, len - 1);
10791
10792   if (dst)
10793     memset (mask, 0xff, 6);
10794
10795   if (src)
10796     memset (mask + 6, 0xff, 6);
10797
10798   if (tag2 || dot1ad)
10799     {
10800       /* inner vlan tag */
10801       if (tag2)
10802         {
10803           mask[19] = 0xff;
10804           mask[18] = 0x0f;
10805         }
10806       if (cos2)
10807         mask[18] |= 0xe0;
10808       if (proto)
10809         mask[21] = mask[20] = 0xff;
10810       if (tag1)
10811         {
10812           mask[15] = 0xff;
10813           mask[14] = 0x0f;
10814         }
10815       if (cos1)
10816         mask[14] |= 0xe0;
10817       *maskp = mask;
10818       return 1;
10819     }
10820   if (tag1 | dot1q)
10821     {
10822       if (tag1)
10823         {
10824           mask[15] = 0xff;
10825           mask[14] = 0x0f;
10826         }
10827       if (cos1)
10828         mask[14] |= 0xe0;
10829       if (proto)
10830         mask[16] = mask[17] = 0xff;
10831
10832       *maskp = mask;
10833       return 1;
10834     }
10835   if (cos2)
10836     mask[18] |= 0xe0;
10837   if (cos1)
10838     mask[14] |= 0xe0;
10839   if (proto)
10840     mask[12] = mask[13] = 0xff;
10841
10842   *maskp = mask;
10843   return 1;
10844 }
10845
10846 uword
10847 unformat_classify_mask (unformat_input_t * input, va_list * args)
10848 {
10849   u8 **maskp = va_arg (*args, u8 **);
10850   u32 *skipp = va_arg (*args, u32 *);
10851   u32 *matchp = va_arg (*args, u32 *);
10852   u32 match;
10853   u8 *mask = 0;
10854   u8 *l2 = 0;
10855   u8 *l3 = 0;
10856   u8 *l4 = 0;
10857   int i;
10858
10859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10862         ;
10863       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10864         ;
10865       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10866         ;
10867       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10868         ;
10869       else
10870         break;
10871     }
10872
10873   if (l4 && !l3)
10874     {
10875       vec_free (mask);
10876       vec_free (l2);
10877       vec_free (l4);
10878       return 0;
10879     }
10880
10881   if (mask || l2 || l3 || l4)
10882     {
10883       if (l2 || l3 || l4)
10884         {
10885           /* "With a free Ethernet header in every package" */
10886           if (l2 == 0)
10887             vec_validate (l2, 13);
10888           mask = l2;
10889           if (vec_len (l3))
10890             {
10891               vec_append (mask, l3);
10892               vec_free (l3);
10893             }
10894           if (vec_len (l4))
10895             {
10896               vec_append (mask, l4);
10897               vec_free (l4);
10898             }
10899         }
10900
10901       /* Scan forward looking for the first significant mask octet */
10902       for (i = 0; i < vec_len (mask); i++)
10903         if (mask[i])
10904           break;
10905
10906       /* compute (skip, match) params */
10907       *skipp = i / sizeof (u32x4);
10908       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10909
10910       /* Pad mask to an even multiple of the vector size */
10911       while (vec_len (mask) % sizeof (u32x4))
10912         vec_add1 (mask, 0);
10913
10914       match = vec_len (mask) / sizeof (u32x4);
10915
10916       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10917         {
10918           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10919           if (*tmp || *(tmp + 1))
10920             break;
10921           match--;
10922         }
10923       if (match == 0)
10924         clib_warning ("BUG: match 0");
10925
10926       _vec_len (mask) = match * sizeof (u32x4);
10927
10928       *matchp = match;
10929       *maskp = mask;
10930
10931       return 1;
10932     }
10933
10934   return 0;
10935 }
10936 #endif /* VPP_API_TEST_BUILTIN */
10937
10938 #define foreach_l2_next                         \
10939 _(drop, DROP)                                   \
10940 _(ethernet, ETHERNET_INPUT)                     \
10941 _(ip4, IP4_INPUT)                               \
10942 _(ip6, IP6_INPUT)
10943
10944 uword
10945 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10946 {
10947   u32 *miss_next_indexp = va_arg (*args, u32 *);
10948   u32 next_index = 0;
10949   u32 tmp;
10950
10951 #define _(n,N) \
10952   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10953   foreach_l2_next;
10954 #undef _
10955
10956   if (unformat (input, "%d", &tmp))
10957     {
10958       next_index = tmp;
10959       goto out;
10960     }
10961
10962   return 0;
10963
10964 out:
10965   *miss_next_indexp = next_index;
10966   return 1;
10967 }
10968
10969 #define foreach_ip_next                         \
10970 _(drop, DROP)                                   \
10971 _(local, LOCAL)                                 \
10972 _(rewrite, REWRITE)
10973
10974 uword
10975 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10976 {
10977   u32 *miss_next_indexp = va_arg (*args, u32 *);
10978   u32 next_index = 0;
10979   u32 tmp;
10980
10981 #define _(n,N) \
10982   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10983   foreach_ip_next;
10984 #undef _
10985
10986   if (unformat (input, "%d", &tmp))
10987     {
10988       next_index = tmp;
10989       goto out;
10990     }
10991
10992   return 0;
10993
10994 out:
10995   *miss_next_indexp = next_index;
10996   return 1;
10997 }
10998
10999 #define foreach_acl_next                        \
11000 _(deny, DENY)
11001
11002 uword
11003 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11004 {
11005   u32 *miss_next_indexp = va_arg (*args, u32 *);
11006   u32 next_index = 0;
11007   u32 tmp;
11008
11009 #define _(n,N) \
11010   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11011   foreach_acl_next;
11012 #undef _
11013
11014   if (unformat (input, "permit"))
11015     {
11016       next_index = ~0;
11017       goto out;
11018     }
11019   else if (unformat (input, "%d", &tmp))
11020     {
11021       next_index = tmp;
11022       goto out;
11023     }
11024
11025   return 0;
11026
11027 out:
11028   *miss_next_indexp = next_index;
11029   return 1;
11030 }
11031
11032 uword
11033 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11034 {
11035   u32 *r = va_arg (*args, u32 *);
11036
11037   if (unformat (input, "conform-color"))
11038     *r = POLICE_CONFORM;
11039   else if (unformat (input, "exceed-color"))
11040     *r = POLICE_EXCEED;
11041   else
11042     return 0;
11043
11044   return 1;
11045 }
11046
11047 static int
11048 api_classify_add_del_table (vat_main_t * vam)
11049 {
11050   unformat_input_t *i = vam->input;
11051   vl_api_classify_add_del_table_t *mp;
11052
11053   u32 nbuckets = 2;
11054   u32 skip = ~0;
11055   u32 match = ~0;
11056   int is_add = 1;
11057   int del_chain = 0;
11058   u32 table_index = ~0;
11059   u32 next_table_index = ~0;
11060   u32 miss_next_index = ~0;
11061   u32 memory_size = 32 << 20;
11062   u8 *mask = 0;
11063   u32 current_data_flag = 0;
11064   int current_data_offset = 0;
11065   int ret;
11066
11067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11068     {
11069       if (unformat (i, "del"))
11070         is_add = 0;
11071       else if (unformat (i, "del-chain"))
11072         {
11073           is_add = 0;
11074           del_chain = 1;
11075         }
11076       else if (unformat (i, "buckets %d", &nbuckets))
11077         ;
11078       else if (unformat (i, "memory_size %d", &memory_size))
11079         ;
11080       else if (unformat (i, "skip %d", &skip))
11081         ;
11082       else if (unformat (i, "match %d", &match))
11083         ;
11084       else if (unformat (i, "table %d", &table_index))
11085         ;
11086       else if (unformat (i, "mask %U", unformat_classify_mask,
11087                          &mask, &skip, &match))
11088         ;
11089       else if (unformat (i, "next-table %d", &next_table_index))
11090         ;
11091       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11092                          &miss_next_index))
11093         ;
11094       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11095                          &miss_next_index))
11096         ;
11097       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11098                          &miss_next_index))
11099         ;
11100       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11101         ;
11102       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11103         ;
11104       else
11105         break;
11106     }
11107
11108   if (is_add && mask == 0)
11109     {
11110       errmsg ("Mask required");
11111       return -99;
11112     }
11113
11114   if (is_add && skip == ~0)
11115     {
11116       errmsg ("skip count required");
11117       return -99;
11118     }
11119
11120   if (is_add && match == ~0)
11121     {
11122       errmsg ("match count required");
11123       return -99;
11124     }
11125
11126   if (!is_add && table_index == ~0)
11127     {
11128       errmsg ("table index required for delete");
11129       return -99;
11130     }
11131
11132   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11133
11134   mp->is_add = is_add;
11135   mp->del_chain = del_chain;
11136   mp->table_index = ntohl (table_index);
11137   mp->nbuckets = ntohl (nbuckets);
11138   mp->memory_size = ntohl (memory_size);
11139   mp->skip_n_vectors = ntohl (skip);
11140   mp->match_n_vectors = ntohl (match);
11141   mp->next_table_index = ntohl (next_table_index);
11142   mp->miss_next_index = ntohl (miss_next_index);
11143   mp->current_data_flag = ntohl (current_data_flag);
11144   mp->current_data_offset = ntohl (current_data_offset);
11145   clib_memcpy (mp->mask, mask, vec_len (mask));
11146
11147   vec_free (mask);
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 #if VPP_API_TEST_BUILTIN == 0
11155 uword
11156 unformat_l4_match (unformat_input_t * input, va_list * args)
11157 {
11158   u8 **matchp = va_arg (*args, u8 **);
11159
11160   u8 *proto_header = 0;
11161   int src_port = 0;
11162   int dst_port = 0;
11163
11164   tcpudp_header_t h;
11165
11166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11167     {
11168       if (unformat (input, "src_port %d", &src_port))
11169         ;
11170       else if (unformat (input, "dst_port %d", &dst_port))
11171         ;
11172       else
11173         return 0;
11174     }
11175
11176   h.src_port = clib_host_to_net_u16 (src_port);
11177   h.dst_port = clib_host_to_net_u16 (dst_port);
11178   vec_validate (proto_header, sizeof (h) - 1);
11179   memcpy (proto_header, &h, sizeof (h));
11180
11181   *matchp = proto_header;
11182
11183   return 1;
11184 }
11185
11186 uword
11187 unformat_ip4_match (unformat_input_t * input, va_list * args)
11188 {
11189   u8 **matchp = va_arg (*args, u8 **);
11190   u8 *match = 0;
11191   ip4_header_t *ip;
11192   int version = 0;
11193   u32 version_val;
11194   int hdr_length = 0;
11195   u32 hdr_length_val;
11196   int src = 0, dst = 0;
11197   ip4_address_t src_val, dst_val;
11198   int proto = 0;
11199   u32 proto_val;
11200   int tos = 0;
11201   u32 tos_val;
11202   int length = 0;
11203   u32 length_val;
11204   int fragment_id = 0;
11205   u32 fragment_id_val;
11206   int ttl = 0;
11207   int ttl_val;
11208   int checksum = 0;
11209   u32 checksum_val;
11210
11211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11212     {
11213       if (unformat (input, "version %d", &version_val))
11214         version = 1;
11215       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11216         hdr_length = 1;
11217       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11218         src = 1;
11219       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11220         dst = 1;
11221       else if (unformat (input, "proto %d", &proto_val))
11222         proto = 1;
11223       else if (unformat (input, "tos %d", &tos_val))
11224         tos = 1;
11225       else if (unformat (input, "length %d", &length_val))
11226         length = 1;
11227       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11228         fragment_id = 1;
11229       else if (unformat (input, "ttl %d", &ttl_val))
11230         ttl = 1;
11231       else if (unformat (input, "checksum %d", &checksum_val))
11232         checksum = 1;
11233       else
11234         break;
11235     }
11236
11237   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11238       + ttl + checksum == 0)
11239     return 0;
11240
11241   /*
11242    * Aligned because we use the real comparison functions
11243    */
11244   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11245
11246   ip = (ip4_header_t *) match;
11247
11248   /* These are realistically matched in practice */
11249   if (src)
11250     ip->src_address.as_u32 = src_val.as_u32;
11251
11252   if (dst)
11253     ip->dst_address.as_u32 = dst_val.as_u32;
11254
11255   if (proto)
11256     ip->protocol = proto_val;
11257
11258
11259   /* These are not, but they're included for completeness */
11260   if (version)
11261     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11262
11263   if (hdr_length)
11264     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11265
11266   if (tos)
11267     ip->tos = tos_val;
11268
11269   if (length)
11270     ip->length = clib_host_to_net_u16 (length_val);
11271
11272   if (ttl)
11273     ip->ttl = ttl_val;
11274
11275   if (checksum)
11276     ip->checksum = clib_host_to_net_u16 (checksum_val);
11277
11278   *matchp = match;
11279   return 1;
11280 }
11281
11282 uword
11283 unformat_ip6_match (unformat_input_t * input, va_list * args)
11284 {
11285   u8 **matchp = va_arg (*args, u8 **);
11286   u8 *match = 0;
11287   ip6_header_t *ip;
11288   int version = 0;
11289   u32 version_val;
11290   u8 traffic_class = 0;
11291   u32 traffic_class_val = 0;
11292   u8 flow_label = 0;
11293   u8 flow_label_val;
11294   int src = 0, dst = 0;
11295   ip6_address_t src_val, dst_val;
11296   int proto = 0;
11297   u32 proto_val;
11298   int payload_length = 0;
11299   u32 payload_length_val;
11300   int hop_limit = 0;
11301   int hop_limit_val;
11302   u32 ip_version_traffic_class_and_flow_label;
11303
11304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11305     {
11306       if (unformat (input, "version %d", &version_val))
11307         version = 1;
11308       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11309         traffic_class = 1;
11310       else if (unformat (input, "flow_label %d", &flow_label_val))
11311         flow_label = 1;
11312       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11313         src = 1;
11314       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11315         dst = 1;
11316       else if (unformat (input, "proto %d", &proto_val))
11317         proto = 1;
11318       else if (unformat (input, "payload_length %d", &payload_length_val))
11319         payload_length = 1;
11320       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11321         hop_limit = 1;
11322       else
11323         break;
11324     }
11325
11326   if (version + traffic_class + flow_label + src + dst + proto +
11327       payload_length + hop_limit == 0)
11328     return 0;
11329
11330   /*
11331    * Aligned because we use the real comparison functions
11332    */
11333   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11334
11335   ip = (ip6_header_t *) match;
11336
11337   if (src)
11338     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11339
11340   if (dst)
11341     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11342
11343   if (proto)
11344     ip->protocol = proto_val;
11345
11346   ip_version_traffic_class_and_flow_label = 0;
11347
11348   if (version)
11349     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11350
11351   if (traffic_class)
11352     ip_version_traffic_class_and_flow_label |=
11353       (traffic_class_val & 0xFF) << 20;
11354
11355   if (flow_label)
11356     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11357
11358   ip->ip_version_traffic_class_and_flow_label =
11359     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11360
11361   if (payload_length)
11362     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11363
11364   if (hop_limit)
11365     ip->hop_limit = hop_limit_val;
11366
11367   *matchp = match;
11368   return 1;
11369 }
11370
11371 uword
11372 unformat_l3_match (unformat_input_t * input, va_list * args)
11373 {
11374   u8 **matchp = va_arg (*args, u8 **);
11375
11376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11377     {
11378       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11379         return 1;
11380       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11381         return 1;
11382       else
11383         break;
11384     }
11385   return 0;
11386 }
11387
11388 uword
11389 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11390 {
11391   u8 *tagp = va_arg (*args, u8 *);
11392   u32 tag;
11393
11394   if (unformat (input, "%d", &tag))
11395     {
11396       tagp[0] = (tag >> 8) & 0x0F;
11397       tagp[1] = tag & 0xFF;
11398       return 1;
11399     }
11400
11401   return 0;
11402 }
11403
11404 uword
11405 unformat_l2_match (unformat_input_t * input, va_list * args)
11406 {
11407   u8 **matchp = va_arg (*args, u8 **);
11408   u8 *match = 0;
11409   u8 src = 0;
11410   u8 src_val[6];
11411   u8 dst = 0;
11412   u8 dst_val[6];
11413   u8 proto = 0;
11414   u16 proto_val;
11415   u8 tag1 = 0;
11416   u8 tag1_val[2];
11417   u8 tag2 = 0;
11418   u8 tag2_val[2];
11419   int len = 14;
11420   u8 ignore_tag1 = 0;
11421   u8 ignore_tag2 = 0;
11422   u8 cos1 = 0;
11423   u8 cos2 = 0;
11424   u32 cos1_val = 0;
11425   u32 cos2_val = 0;
11426
11427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11428     {
11429       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11430         src = 1;
11431       else
11432         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11433         dst = 1;
11434       else if (unformat (input, "proto %U",
11435                          unformat_ethernet_type_host_byte_order, &proto_val))
11436         proto = 1;
11437       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11438         tag1 = 1;
11439       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11440         tag2 = 1;
11441       else if (unformat (input, "ignore-tag1"))
11442         ignore_tag1 = 1;
11443       else if (unformat (input, "ignore-tag2"))
11444         ignore_tag2 = 1;
11445       else if (unformat (input, "cos1 %d", &cos1_val))
11446         cos1 = 1;
11447       else if (unformat (input, "cos2 %d", &cos2_val))
11448         cos2 = 1;
11449       else
11450         break;
11451     }
11452   if ((src + dst + proto + tag1 + tag2 +
11453        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11454     return 0;
11455
11456   if (tag1 || ignore_tag1 || cos1)
11457     len = 18;
11458   if (tag2 || ignore_tag2 || cos2)
11459     len = 22;
11460
11461   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11462
11463   if (dst)
11464     clib_memcpy (match, dst_val, 6);
11465
11466   if (src)
11467     clib_memcpy (match + 6, src_val, 6);
11468
11469   if (tag2)
11470     {
11471       /* inner vlan tag */
11472       match[19] = tag2_val[1];
11473       match[18] = tag2_val[0];
11474       if (cos2)
11475         match[18] |= (cos2_val & 0x7) << 5;
11476       if (proto)
11477         {
11478           match[21] = proto_val & 0xff;
11479           match[20] = proto_val >> 8;
11480         }
11481       if (tag1)
11482         {
11483           match[15] = tag1_val[1];
11484           match[14] = tag1_val[0];
11485         }
11486       if (cos1)
11487         match[14] |= (cos1_val & 0x7) << 5;
11488       *matchp = match;
11489       return 1;
11490     }
11491   if (tag1)
11492     {
11493       match[15] = tag1_val[1];
11494       match[14] = tag1_val[0];
11495       if (proto)
11496         {
11497           match[17] = proto_val & 0xff;
11498           match[16] = proto_val >> 8;
11499         }
11500       if (cos1)
11501         match[14] |= (cos1_val & 0x7) << 5;
11502
11503       *matchp = match;
11504       return 1;
11505     }
11506   if (cos2)
11507     match[18] |= (cos2_val & 0x7) << 5;
11508   if (cos1)
11509     match[14] |= (cos1_val & 0x7) << 5;
11510   if (proto)
11511     {
11512       match[13] = proto_val & 0xff;
11513       match[12] = proto_val >> 8;
11514     }
11515
11516   *matchp = match;
11517   return 1;
11518 }
11519 #endif
11520
11521 uword
11522 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11523 {
11524   u8 **matchp = va_arg (*args, u8 **);
11525   u32 skip_n_vectors = va_arg (*args, u32);
11526   u32 match_n_vectors = va_arg (*args, u32);
11527
11528   u8 *match = 0;
11529   u8 *l2 = 0;
11530   u8 *l3 = 0;
11531   u8 *l4 = 0;
11532
11533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (input, "hex %U", unformat_hex_string, &match))
11536         ;
11537       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11538         ;
11539       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11540         ;
11541       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11542         ;
11543       else
11544         break;
11545     }
11546
11547   if (l4 && !l3)
11548     {
11549       vec_free (match);
11550       vec_free (l2);
11551       vec_free (l4);
11552       return 0;
11553     }
11554
11555   if (match || l2 || l3 || l4)
11556     {
11557       if (l2 || l3 || l4)
11558         {
11559           /* "Win a free Ethernet header in every packet" */
11560           if (l2 == 0)
11561             vec_validate_aligned (l2, 13, sizeof (u32x4));
11562           match = l2;
11563           if (vec_len (l3))
11564             {
11565               vec_append_aligned (match, l3, sizeof (u32x4));
11566               vec_free (l3);
11567             }
11568           if (vec_len (l4))
11569             {
11570               vec_append_aligned (match, l4, sizeof (u32x4));
11571               vec_free (l4);
11572             }
11573         }
11574
11575       /* Make sure the vector is big enough even if key is all 0's */
11576       vec_validate_aligned
11577         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11578          sizeof (u32x4));
11579
11580       /* Set size, include skipped vectors */
11581       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11582
11583       *matchp = match;
11584
11585       return 1;
11586     }
11587
11588   return 0;
11589 }
11590
11591 static int
11592 api_classify_add_del_session (vat_main_t * vam)
11593 {
11594   unformat_input_t *i = vam->input;
11595   vl_api_classify_add_del_session_t *mp;
11596   int is_add = 1;
11597   u32 table_index = ~0;
11598   u32 hit_next_index = ~0;
11599   u32 opaque_index = ~0;
11600   u8 *match = 0;
11601   i32 advance = 0;
11602   u32 skip_n_vectors = 0;
11603   u32 match_n_vectors = 0;
11604   u32 action = 0;
11605   u32 metadata = 0;
11606   int ret;
11607
11608   /*
11609    * Warning: you have to supply skip_n and match_n
11610    * because the API client cant simply look at the classify
11611    * table object.
11612    */
11613
11614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11615     {
11616       if (unformat (i, "del"))
11617         is_add = 0;
11618       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11619                          &hit_next_index))
11620         ;
11621       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11622                          &hit_next_index))
11623         ;
11624       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11625                          &hit_next_index))
11626         ;
11627       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11628         ;
11629       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11630         ;
11631       else if (unformat (i, "opaque-index %d", &opaque_index))
11632         ;
11633       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11634         ;
11635       else if (unformat (i, "match_n %d", &match_n_vectors))
11636         ;
11637       else if (unformat (i, "match %U", api_unformat_classify_match,
11638                          &match, skip_n_vectors, match_n_vectors))
11639         ;
11640       else if (unformat (i, "advance %d", &advance))
11641         ;
11642       else if (unformat (i, "table-index %d", &table_index))
11643         ;
11644       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11645         action = 1;
11646       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11647         action = 2;
11648       else if (unformat (i, "action %d", &action))
11649         ;
11650       else if (unformat (i, "metadata %d", &metadata))
11651         ;
11652       else
11653         break;
11654     }
11655
11656   if (table_index == ~0)
11657     {
11658       errmsg ("Table index required");
11659       return -99;
11660     }
11661
11662   if (is_add && match == 0)
11663     {
11664       errmsg ("Match value required");
11665       return -99;
11666     }
11667
11668   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11669
11670   mp->is_add = is_add;
11671   mp->table_index = ntohl (table_index);
11672   mp->hit_next_index = ntohl (hit_next_index);
11673   mp->opaque_index = ntohl (opaque_index);
11674   mp->advance = ntohl (advance);
11675   mp->action = action;
11676   mp->metadata = ntohl (metadata);
11677   clib_memcpy (mp->match, match, vec_len (match));
11678   vec_free (match);
11679
11680   S (mp);
11681   W (ret);
11682   return ret;
11683 }
11684
11685 static int
11686 api_classify_set_interface_ip_table (vat_main_t * vam)
11687 {
11688   unformat_input_t *i = vam->input;
11689   vl_api_classify_set_interface_ip_table_t *mp;
11690   u32 sw_if_index;
11691   int sw_if_index_set;
11692   u32 table_index = ~0;
11693   u8 is_ipv6 = 0;
11694   int ret;
11695
11696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11697     {
11698       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11699         sw_if_index_set = 1;
11700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11701         sw_if_index_set = 1;
11702       else if (unformat (i, "table %d", &table_index))
11703         ;
11704       else
11705         {
11706           clib_warning ("parse error '%U'", format_unformat_error, i);
11707           return -99;
11708         }
11709     }
11710
11711   if (sw_if_index_set == 0)
11712     {
11713       errmsg ("missing interface name or sw_if_index");
11714       return -99;
11715     }
11716
11717
11718   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11719
11720   mp->sw_if_index = ntohl (sw_if_index);
11721   mp->table_index = ntohl (table_index);
11722   mp->is_ipv6 = is_ipv6;
11723
11724   S (mp);
11725   W (ret);
11726   return ret;
11727 }
11728
11729 static int
11730 api_classify_set_interface_l2_tables (vat_main_t * vam)
11731 {
11732   unformat_input_t *i = vam->input;
11733   vl_api_classify_set_interface_l2_tables_t *mp;
11734   u32 sw_if_index;
11735   int sw_if_index_set;
11736   u32 ip4_table_index = ~0;
11737   u32 ip6_table_index = ~0;
11738   u32 other_table_index = ~0;
11739   u32 is_input = 1;
11740   int ret;
11741
11742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11745         sw_if_index_set = 1;
11746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11747         sw_if_index_set = 1;
11748       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11749         ;
11750       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11751         ;
11752       else if (unformat (i, "other-table %d", &other_table_index))
11753         ;
11754       else if (unformat (i, "is-input %d", &is_input))
11755         ;
11756       else
11757         {
11758           clib_warning ("parse error '%U'", format_unformat_error, i);
11759           return -99;
11760         }
11761     }
11762
11763   if (sw_if_index_set == 0)
11764     {
11765       errmsg ("missing interface name or sw_if_index");
11766       return -99;
11767     }
11768
11769
11770   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11771
11772   mp->sw_if_index = ntohl (sw_if_index);
11773   mp->ip4_table_index = ntohl (ip4_table_index);
11774   mp->ip6_table_index = ntohl (ip6_table_index);
11775   mp->other_table_index = ntohl (other_table_index);
11776   mp->is_input = (u8) is_input;
11777
11778   S (mp);
11779   W (ret);
11780   return ret;
11781 }
11782
11783 static int
11784 api_set_ipfix_exporter (vat_main_t * vam)
11785 {
11786   unformat_input_t *i = vam->input;
11787   vl_api_set_ipfix_exporter_t *mp;
11788   ip4_address_t collector_address;
11789   u8 collector_address_set = 0;
11790   u32 collector_port = ~0;
11791   ip4_address_t src_address;
11792   u8 src_address_set = 0;
11793   u32 vrf_id = ~0;
11794   u32 path_mtu = ~0;
11795   u32 template_interval = ~0;
11796   u8 udp_checksum = 0;
11797   int ret;
11798
11799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11800     {
11801       if (unformat (i, "collector_address %U", unformat_ip4_address,
11802                     &collector_address))
11803         collector_address_set = 1;
11804       else if (unformat (i, "collector_port %d", &collector_port))
11805         ;
11806       else if (unformat (i, "src_address %U", unformat_ip4_address,
11807                          &src_address))
11808         src_address_set = 1;
11809       else if (unformat (i, "vrf_id %d", &vrf_id))
11810         ;
11811       else if (unformat (i, "path_mtu %d", &path_mtu))
11812         ;
11813       else if (unformat (i, "template_interval %d", &template_interval))
11814         ;
11815       else if (unformat (i, "udp_checksum"))
11816         udp_checksum = 1;
11817       else
11818         break;
11819     }
11820
11821   if (collector_address_set == 0)
11822     {
11823       errmsg ("collector_address required");
11824       return -99;
11825     }
11826
11827   if (src_address_set == 0)
11828     {
11829       errmsg ("src_address required");
11830       return -99;
11831     }
11832
11833   M (SET_IPFIX_EXPORTER, mp);
11834
11835   memcpy (mp->collector_address, collector_address.data,
11836           sizeof (collector_address.data));
11837   mp->collector_port = htons ((u16) collector_port);
11838   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11839   mp->vrf_id = htonl (vrf_id);
11840   mp->path_mtu = htonl (path_mtu);
11841   mp->template_interval = htonl (template_interval);
11842   mp->udp_checksum = udp_checksum;
11843
11844   S (mp);
11845   W (ret);
11846   return ret;
11847 }
11848
11849 static int
11850 api_set_ipfix_classify_stream (vat_main_t * vam)
11851 {
11852   unformat_input_t *i = vam->input;
11853   vl_api_set_ipfix_classify_stream_t *mp;
11854   u32 domain_id = 0;
11855   u32 src_port = UDP_DST_PORT_ipfix;
11856   int ret;
11857
11858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11859     {
11860       if (unformat (i, "domain %d", &domain_id))
11861         ;
11862       else if (unformat (i, "src_port %d", &src_port))
11863         ;
11864       else
11865         {
11866           errmsg ("unknown input `%U'", format_unformat_error, i);
11867           return -99;
11868         }
11869     }
11870
11871   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11872
11873   mp->domain_id = htonl (domain_id);
11874   mp->src_port = htons ((u16) src_port);
11875
11876   S (mp);
11877   W (ret);
11878   return ret;
11879 }
11880
11881 static int
11882 api_ipfix_classify_table_add_del (vat_main_t * vam)
11883 {
11884   unformat_input_t *i = vam->input;
11885   vl_api_ipfix_classify_table_add_del_t *mp;
11886   int is_add = -1;
11887   u32 classify_table_index = ~0;
11888   u8 ip_version = 0;
11889   u8 transport_protocol = 255;
11890   int ret;
11891
11892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (i, "add"))
11895         is_add = 1;
11896       else if (unformat (i, "del"))
11897         is_add = 0;
11898       else if (unformat (i, "table %d", &classify_table_index))
11899         ;
11900       else if (unformat (i, "ip4"))
11901         ip_version = 4;
11902       else if (unformat (i, "ip6"))
11903         ip_version = 6;
11904       else if (unformat (i, "tcp"))
11905         transport_protocol = 6;
11906       else if (unformat (i, "udp"))
11907         transport_protocol = 17;
11908       else
11909         {
11910           errmsg ("unknown input `%U'", format_unformat_error, i);
11911           return -99;
11912         }
11913     }
11914
11915   if (is_add == -1)
11916     {
11917       errmsg ("expecting: add|del");
11918       return -99;
11919     }
11920   if (classify_table_index == ~0)
11921     {
11922       errmsg ("classifier table not specified");
11923       return -99;
11924     }
11925   if (ip_version == 0)
11926     {
11927       errmsg ("IP version not specified");
11928       return -99;
11929     }
11930
11931   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11932
11933   mp->is_add = is_add;
11934   mp->table_id = htonl (classify_table_index);
11935   mp->ip_version = ip_version;
11936   mp->transport_protocol = transport_protocol;
11937
11938   S (mp);
11939   W (ret);
11940   return ret;
11941 }
11942
11943 static int
11944 api_get_node_index (vat_main_t * vam)
11945 {
11946   unformat_input_t *i = vam->input;
11947   vl_api_get_node_index_t *mp;
11948   u8 *name = 0;
11949   int ret;
11950
11951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (i, "node %s", &name))
11954         ;
11955       else
11956         break;
11957     }
11958   if (name == 0)
11959     {
11960       errmsg ("node name required");
11961       return -99;
11962     }
11963   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11964     {
11965       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11966       return -99;
11967     }
11968
11969   M (GET_NODE_INDEX, mp);
11970   clib_memcpy (mp->node_name, name, vec_len (name));
11971   vec_free (name);
11972
11973   S (mp);
11974   W (ret);
11975   return ret;
11976 }
11977
11978 static int
11979 api_get_next_index (vat_main_t * vam)
11980 {
11981   unformat_input_t *i = vam->input;
11982   vl_api_get_next_index_t *mp;
11983   u8 *node_name = 0, *next_node_name = 0;
11984   int ret;
11985
11986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11987     {
11988       if (unformat (i, "node-name %s", &node_name))
11989         ;
11990       else if (unformat (i, "next-node-name %s", &next_node_name))
11991         break;
11992     }
11993
11994   if (node_name == 0)
11995     {
11996       errmsg ("node name required");
11997       return -99;
11998     }
11999   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12000     {
12001       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12002       return -99;
12003     }
12004
12005   if (next_node_name == 0)
12006     {
12007       errmsg ("next node name required");
12008       return -99;
12009     }
12010   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12011     {
12012       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12013       return -99;
12014     }
12015
12016   M (GET_NEXT_INDEX, mp);
12017   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12018   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12019   vec_free (node_name);
12020   vec_free (next_node_name);
12021
12022   S (mp);
12023   W (ret);
12024   return ret;
12025 }
12026
12027 static int
12028 api_add_node_next (vat_main_t * vam)
12029 {
12030   unformat_input_t *i = vam->input;
12031   vl_api_add_node_next_t *mp;
12032   u8 *name = 0;
12033   u8 *next = 0;
12034   int ret;
12035
12036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12037     {
12038       if (unformat (i, "node %s", &name))
12039         ;
12040       else if (unformat (i, "next %s", &next))
12041         ;
12042       else
12043         break;
12044     }
12045   if (name == 0)
12046     {
12047       errmsg ("node name required");
12048       return -99;
12049     }
12050   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12051     {
12052       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12053       return -99;
12054     }
12055   if (next == 0)
12056     {
12057       errmsg ("next node required");
12058       return -99;
12059     }
12060   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12061     {
12062       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12063       return -99;
12064     }
12065
12066   M (ADD_NODE_NEXT, mp);
12067   clib_memcpy (mp->node_name, name, vec_len (name));
12068   clib_memcpy (mp->next_name, next, vec_len (next));
12069   vec_free (name);
12070   vec_free (next);
12071
12072   S (mp);
12073   W (ret);
12074   return ret;
12075 }
12076
12077 static int
12078 api_l2tpv3_create_tunnel (vat_main_t * vam)
12079 {
12080   unformat_input_t *i = vam->input;
12081   ip6_address_t client_address, our_address;
12082   int client_address_set = 0;
12083   int our_address_set = 0;
12084   u32 local_session_id = 0;
12085   u32 remote_session_id = 0;
12086   u64 local_cookie = 0;
12087   u64 remote_cookie = 0;
12088   u8 l2_sublayer_present = 0;
12089   vl_api_l2tpv3_create_tunnel_t *mp;
12090   int ret;
12091
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "client_address %U", unformat_ip6_address,
12095                     &client_address))
12096         client_address_set = 1;
12097       else if (unformat (i, "our_address %U", unformat_ip6_address,
12098                          &our_address))
12099         our_address_set = 1;
12100       else if (unformat (i, "local_session_id %d", &local_session_id))
12101         ;
12102       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12103         ;
12104       else if (unformat (i, "local_cookie %lld", &local_cookie))
12105         ;
12106       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12107         ;
12108       else if (unformat (i, "l2-sublayer-present"))
12109         l2_sublayer_present = 1;
12110       else
12111         break;
12112     }
12113
12114   if (client_address_set == 0)
12115     {
12116       errmsg ("client_address required");
12117       return -99;
12118     }
12119
12120   if (our_address_set == 0)
12121     {
12122       errmsg ("our_address required");
12123       return -99;
12124     }
12125
12126   M (L2TPV3_CREATE_TUNNEL, mp);
12127
12128   clib_memcpy (mp->client_address, client_address.as_u8,
12129                sizeof (mp->client_address));
12130
12131   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12132
12133   mp->local_session_id = ntohl (local_session_id);
12134   mp->remote_session_id = ntohl (remote_session_id);
12135   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12136   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12137   mp->l2_sublayer_present = l2_sublayer_present;
12138   mp->is_ipv6 = 1;
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145 static int
12146 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12147 {
12148   unformat_input_t *i = vam->input;
12149   u32 sw_if_index;
12150   u8 sw_if_index_set = 0;
12151   u64 new_local_cookie = 0;
12152   u64 new_remote_cookie = 0;
12153   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12154   int ret;
12155
12156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12157     {
12158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12159         sw_if_index_set = 1;
12160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12161         sw_if_index_set = 1;
12162       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12163         ;
12164       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12165         ;
12166       else
12167         break;
12168     }
12169
12170   if (sw_if_index_set == 0)
12171     {
12172       errmsg ("missing interface name or sw_if_index");
12173       return -99;
12174     }
12175
12176   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12177
12178   mp->sw_if_index = ntohl (sw_if_index);
12179   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12180   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12181
12182   S (mp);
12183   W (ret);
12184   return ret;
12185 }
12186
12187 static int
12188 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12189 {
12190   unformat_input_t *i = vam->input;
12191   vl_api_l2tpv3_interface_enable_disable_t *mp;
12192   u32 sw_if_index;
12193   u8 sw_if_index_set = 0;
12194   u8 enable_disable = 1;
12195   int ret;
12196
12197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12198     {
12199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12200         sw_if_index_set = 1;
12201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12202         sw_if_index_set = 1;
12203       else if (unformat (i, "enable"))
12204         enable_disable = 1;
12205       else if (unformat (i, "disable"))
12206         enable_disable = 0;
12207       else
12208         break;
12209     }
12210
12211   if (sw_if_index_set == 0)
12212     {
12213       errmsg ("missing interface name or sw_if_index");
12214       return -99;
12215     }
12216
12217   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12218
12219   mp->sw_if_index = ntohl (sw_if_index);
12220   mp->enable_disable = enable_disable;
12221
12222   S (mp);
12223   W (ret);
12224   return ret;
12225 }
12226
12227 static int
12228 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12229 {
12230   unformat_input_t *i = vam->input;
12231   vl_api_l2tpv3_set_lookup_key_t *mp;
12232   u8 key = ~0;
12233   int ret;
12234
12235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12236     {
12237       if (unformat (i, "lookup_v6_src"))
12238         key = L2T_LOOKUP_SRC_ADDRESS;
12239       else if (unformat (i, "lookup_v6_dst"))
12240         key = L2T_LOOKUP_DST_ADDRESS;
12241       else if (unformat (i, "lookup_session_id"))
12242         key = L2T_LOOKUP_SESSION_ID;
12243       else
12244         break;
12245     }
12246
12247   if (key == (u8) ~ 0)
12248     {
12249       errmsg ("l2tp session lookup key unset");
12250       return -99;
12251     }
12252
12253   M (L2TPV3_SET_LOOKUP_KEY, mp);
12254
12255   mp->key = key;
12256
12257   S (mp);
12258   W (ret);
12259   return ret;
12260 }
12261
12262 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12263   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12264 {
12265   vat_main_t *vam = &vat_main;
12266
12267   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12268          format_ip6_address, mp->our_address,
12269          format_ip6_address, mp->client_address,
12270          clib_net_to_host_u32 (mp->sw_if_index));
12271
12272   print (vam->ofp,
12273          "   local cookies %016llx %016llx remote cookie %016llx",
12274          clib_net_to_host_u64 (mp->local_cookie[0]),
12275          clib_net_to_host_u64 (mp->local_cookie[1]),
12276          clib_net_to_host_u64 (mp->remote_cookie));
12277
12278   print (vam->ofp, "   local session-id %d remote session-id %d",
12279          clib_net_to_host_u32 (mp->local_session_id),
12280          clib_net_to_host_u32 (mp->remote_session_id));
12281
12282   print (vam->ofp, "   l2 specific sublayer %s\n",
12283          mp->l2_sublayer_present ? "preset" : "absent");
12284
12285 }
12286
12287 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12288   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12289 {
12290   vat_main_t *vam = &vat_main;
12291   vat_json_node_t *node = NULL;
12292   struct in6_addr addr;
12293
12294   if (VAT_JSON_ARRAY != vam->json_tree.type)
12295     {
12296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12297       vat_json_init_array (&vam->json_tree);
12298     }
12299   node = vat_json_array_add (&vam->json_tree);
12300
12301   vat_json_init_object (node);
12302
12303   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12304   vat_json_object_add_ip6 (node, "our_address", addr);
12305   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12306   vat_json_object_add_ip6 (node, "client_address", addr);
12307
12308   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12309   vat_json_init_array (lc);
12310   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12311   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12312   vat_json_object_add_uint (node, "remote_cookie",
12313                             clib_net_to_host_u64 (mp->remote_cookie));
12314
12315   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12316   vat_json_object_add_uint (node, "local_session_id",
12317                             clib_net_to_host_u32 (mp->local_session_id));
12318   vat_json_object_add_uint (node, "remote_session_id",
12319                             clib_net_to_host_u32 (mp->remote_session_id));
12320   vat_json_object_add_string_copy (node, "l2_sublayer",
12321                                    mp->l2_sublayer_present ? (u8 *) "present"
12322                                    : (u8 *) "absent");
12323 }
12324
12325 static int
12326 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12327 {
12328   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12329   vl_api_control_ping_t *mp_ping;
12330   int ret;
12331
12332   /* Get list of l2tpv3-tunnel interfaces */
12333   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12334   S (mp);
12335
12336   /* Use a control ping for synchronization */
12337   MPING (CONTROL_PING, mp_ping);
12338   S (mp_ping);
12339
12340   W (ret);
12341   return ret;
12342 }
12343
12344
12345 static void vl_api_sw_interface_tap_details_t_handler
12346   (vl_api_sw_interface_tap_details_t * mp)
12347 {
12348   vat_main_t *vam = &vat_main;
12349
12350   print (vam->ofp, "%-16s %d",
12351          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12352 }
12353
12354 static void vl_api_sw_interface_tap_details_t_handler_json
12355   (vl_api_sw_interface_tap_details_t * mp)
12356 {
12357   vat_main_t *vam = &vat_main;
12358   vat_json_node_t *node = NULL;
12359
12360   if (VAT_JSON_ARRAY != vam->json_tree.type)
12361     {
12362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12363       vat_json_init_array (&vam->json_tree);
12364     }
12365   node = vat_json_array_add (&vam->json_tree);
12366
12367   vat_json_init_object (node);
12368   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12369   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12370 }
12371
12372 static int
12373 api_sw_interface_tap_dump (vat_main_t * vam)
12374 {
12375   vl_api_sw_interface_tap_dump_t *mp;
12376   vl_api_control_ping_t *mp_ping;
12377   int ret;
12378
12379   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12380   /* Get list of tap interfaces */
12381   M (SW_INTERFACE_TAP_DUMP, mp);
12382   S (mp);
12383
12384   /* Use a control ping for synchronization */
12385   MPING (CONTROL_PING, mp_ping);
12386   S (mp_ping);
12387
12388   W (ret);
12389   return ret;
12390 }
12391
12392 static void vl_api_sw_interface_tap_v2_details_t_handler
12393   (vl_api_sw_interface_tap_v2_details_t * mp)
12394 {
12395   vat_main_t *vam = &vat_main;
12396
12397   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12398                     mp->host_ip4_prefix_len);
12399   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12400                     mp->host_ip6_prefix_len);
12401
12402   print (vam->ofp,
12403          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12404          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12405          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12406          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12407          mp->host_bridge, ip4, ip6);
12408
12409   vec_free (ip4);
12410   vec_free (ip6);
12411 }
12412
12413 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12414   (vl_api_sw_interface_tap_v2_details_t * mp)
12415 {
12416   vat_main_t *vam = &vat_main;
12417   vat_json_node_t *node = NULL;
12418
12419   if (VAT_JSON_ARRAY != vam->json_tree.type)
12420     {
12421       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12422       vat_json_init_array (&vam->json_tree);
12423     }
12424   node = vat_json_array_add (&vam->json_tree);
12425
12426   vat_json_init_object (node);
12427   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12428   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12429   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12430   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12431   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12432   vat_json_object_add_string_copy (node, "host_mac_addr",
12433                                    format (0, "%U", format_ethernet_address,
12434                                            &mp->host_mac_addr));
12435   vat_json_object_add_string_copy (node, "host_namespace",
12436                                    mp->host_namespace);
12437   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12438   vat_json_object_add_string_copy (node, "host_ip4_addr",
12439                                    format (0, "%U/%d", format_ip4_address,
12440                                            mp->host_ip4_addr,
12441                                            mp->host_ip4_prefix_len));
12442   vat_json_object_add_string_copy (node, "host_ip6_addr",
12443                                    format (0, "%U/%d", format_ip6_address,
12444                                            mp->host_ip6_addr,
12445                                            mp->host_ip6_prefix_len));
12446
12447 }
12448
12449 static int
12450 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12451 {
12452   vl_api_sw_interface_tap_v2_dump_t *mp;
12453   vl_api_control_ping_t *mp_ping;
12454   int ret;
12455
12456   print (vam->ofp,
12457          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12458          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12459          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12460          "host_ip6_addr");
12461
12462   /* Get list of tap interfaces */
12463   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12464   S (mp);
12465
12466   /* Use a control ping for synchronization */
12467   MPING (CONTROL_PING, mp_ping);
12468   S (mp_ping);
12469
12470   W (ret);
12471   return ret;
12472 }
12473
12474 static uword unformat_vxlan_decap_next
12475   (unformat_input_t * input, va_list * args)
12476 {
12477   u32 *result = va_arg (*args, u32 *);
12478   u32 tmp;
12479
12480   if (unformat (input, "l2"))
12481     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12482   else if (unformat (input, "%d", &tmp))
12483     *result = tmp;
12484   else
12485     return 0;
12486   return 1;
12487 }
12488
12489 static int
12490 api_vxlan_add_del_tunnel (vat_main_t * vam)
12491 {
12492   unformat_input_t *line_input = vam->input;
12493   vl_api_vxlan_add_del_tunnel_t *mp;
12494   ip46_address_t src, dst;
12495   u8 is_add = 1;
12496   u8 ipv4_set = 0, ipv6_set = 0;
12497   u8 src_set = 0;
12498   u8 dst_set = 0;
12499   u8 grp_set = 0;
12500   u32 mcast_sw_if_index = ~0;
12501   u32 encap_vrf_id = 0;
12502   u32 decap_next_index = ~0;
12503   u32 vni = 0;
12504   int ret;
12505
12506   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12507   memset (&src, 0, sizeof src);
12508   memset (&dst, 0, sizeof dst);
12509
12510   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12511     {
12512       if (unformat (line_input, "del"))
12513         is_add = 0;
12514       else
12515         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12516         {
12517           ipv4_set = 1;
12518           src_set = 1;
12519         }
12520       else
12521         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12522         {
12523           ipv4_set = 1;
12524           dst_set = 1;
12525         }
12526       else
12527         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12528         {
12529           ipv6_set = 1;
12530           src_set = 1;
12531         }
12532       else
12533         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12534         {
12535           ipv6_set = 1;
12536           dst_set = 1;
12537         }
12538       else if (unformat (line_input, "group %U %U",
12539                          unformat_ip4_address, &dst.ip4,
12540                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12541         {
12542           grp_set = dst_set = 1;
12543           ipv4_set = 1;
12544         }
12545       else if (unformat (line_input, "group %U",
12546                          unformat_ip4_address, &dst.ip4))
12547         {
12548           grp_set = dst_set = 1;
12549           ipv4_set = 1;
12550         }
12551       else if (unformat (line_input, "group %U %U",
12552                          unformat_ip6_address, &dst.ip6,
12553                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12554         {
12555           grp_set = dst_set = 1;
12556           ipv6_set = 1;
12557         }
12558       else if (unformat (line_input, "group %U",
12559                          unformat_ip6_address, &dst.ip6))
12560         {
12561           grp_set = dst_set = 1;
12562           ipv6_set = 1;
12563         }
12564       else
12565         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12566         ;
12567       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12568         ;
12569       else if (unformat (line_input, "decap-next %U",
12570                          unformat_vxlan_decap_next, &decap_next_index))
12571         ;
12572       else if (unformat (line_input, "vni %d", &vni))
12573         ;
12574       else
12575         {
12576           errmsg ("parse error '%U'", format_unformat_error, line_input);
12577           return -99;
12578         }
12579     }
12580
12581   if (src_set == 0)
12582     {
12583       errmsg ("tunnel src address not specified");
12584       return -99;
12585     }
12586   if (dst_set == 0)
12587     {
12588       errmsg ("tunnel dst address not specified");
12589       return -99;
12590     }
12591
12592   if (grp_set && !ip46_address_is_multicast (&dst))
12593     {
12594       errmsg ("tunnel group address not multicast");
12595       return -99;
12596     }
12597   if (grp_set && mcast_sw_if_index == ~0)
12598     {
12599       errmsg ("tunnel nonexistent multicast device");
12600       return -99;
12601     }
12602   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12603     {
12604       errmsg ("tunnel dst address must be unicast");
12605       return -99;
12606     }
12607
12608
12609   if (ipv4_set && ipv6_set)
12610     {
12611       errmsg ("both IPv4 and IPv6 addresses specified");
12612       return -99;
12613     }
12614
12615   if ((vni == 0) || (vni >> 24))
12616     {
12617       errmsg ("vni not specified or out of range");
12618       return -99;
12619     }
12620
12621   M (VXLAN_ADD_DEL_TUNNEL, mp);
12622
12623   if (ipv6_set)
12624     {
12625       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12626       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12627     }
12628   else
12629     {
12630       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12631       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12632     }
12633   mp->encap_vrf_id = ntohl (encap_vrf_id);
12634   mp->decap_next_index = ntohl (decap_next_index);
12635   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12636   mp->vni = ntohl (vni);
12637   mp->is_add = is_add;
12638   mp->is_ipv6 = ipv6_set;
12639
12640   S (mp);
12641   W (ret);
12642   return ret;
12643 }
12644
12645 static void vl_api_vxlan_tunnel_details_t_handler
12646   (vl_api_vxlan_tunnel_details_t * mp)
12647 {
12648   vat_main_t *vam = &vat_main;
12649   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12650   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12651
12652   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12653          ntohl (mp->sw_if_index),
12654          format_ip46_address, &src, IP46_TYPE_ANY,
12655          format_ip46_address, &dst, IP46_TYPE_ANY,
12656          ntohl (mp->encap_vrf_id),
12657          ntohl (mp->decap_next_index), ntohl (mp->vni),
12658          ntohl (mp->mcast_sw_if_index));
12659 }
12660
12661 static void vl_api_vxlan_tunnel_details_t_handler_json
12662   (vl_api_vxlan_tunnel_details_t * mp)
12663 {
12664   vat_main_t *vam = &vat_main;
12665   vat_json_node_t *node = NULL;
12666
12667   if (VAT_JSON_ARRAY != vam->json_tree.type)
12668     {
12669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12670       vat_json_init_array (&vam->json_tree);
12671     }
12672   node = vat_json_array_add (&vam->json_tree);
12673
12674   vat_json_init_object (node);
12675   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12676   if (mp->is_ipv6)
12677     {
12678       struct in6_addr ip6;
12679
12680       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12681       vat_json_object_add_ip6 (node, "src_address", ip6);
12682       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12683       vat_json_object_add_ip6 (node, "dst_address", ip6);
12684     }
12685   else
12686     {
12687       struct in_addr ip4;
12688
12689       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12690       vat_json_object_add_ip4 (node, "src_address", ip4);
12691       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12692       vat_json_object_add_ip4 (node, "dst_address", ip4);
12693     }
12694   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12695   vat_json_object_add_uint (node, "decap_next_index",
12696                             ntohl (mp->decap_next_index));
12697   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12698   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12699   vat_json_object_add_uint (node, "mcast_sw_if_index",
12700                             ntohl (mp->mcast_sw_if_index));
12701 }
12702
12703 static int
12704 api_vxlan_tunnel_dump (vat_main_t * vam)
12705 {
12706   unformat_input_t *i = vam->input;
12707   vl_api_vxlan_tunnel_dump_t *mp;
12708   vl_api_control_ping_t *mp_ping;
12709   u32 sw_if_index;
12710   u8 sw_if_index_set = 0;
12711   int ret;
12712
12713   /* Parse args required to build the message */
12714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12715     {
12716       if (unformat (i, "sw_if_index %d", &sw_if_index))
12717         sw_if_index_set = 1;
12718       else
12719         break;
12720     }
12721
12722   if (sw_if_index_set == 0)
12723     {
12724       sw_if_index = ~0;
12725     }
12726
12727   if (!vam->json_output)
12728     {
12729       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12730              "sw_if_index", "src_address", "dst_address",
12731              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12732     }
12733
12734   /* Get list of vxlan-tunnel interfaces */
12735   M (VXLAN_TUNNEL_DUMP, mp);
12736
12737   mp->sw_if_index = htonl (sw_if_index);
12738
12739   S (mp);
12740
12741   /* Use a control ping for synchronization */
12742   MPING (CONTROL_PING, mp_ping);
12743   S (mp_ping);
12744
12745   W (ret);
12746   return ret;
12747 }
12748
12749 static uword unformat_geneve_decap_next
12750   (unformat_input_t * input, va_list * args)
12751 {
12752   u32 *result = va_arg (*args, u32 *);
12753   u32 tmp;
12754
12755   if (unformat (input, "l2"))
12756     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12757   else if (unformat (input, "%d", &tmp))
12758     *result = tmp;
12759   else
12760     return 0;
12761   return 1;
12762 }
12763
12764 static int
12765 api_geneve_add_del_tunnel (vat_main_t * vam)
12766 {
12767   unformat_input_t *line_input = vam->input;
12768   vl_api_geneve_add_del_tunnel_t *mp;
12769   ip46_address_t src, dst;
12770   u8 is_add = 1;
12771   u8 ipv4_set = 0, ipv6_set = 0;
12772   u8 src_set = 0;
12773   u8 dst_set = 0;
12774   u8 grp_set = 0;
12775   u32 mcast_sw_if_index = ~0;
12776   u32 encap_vrf_id = 0;
12777   u32 decap_next_index = ~0;
12778   u32 vni = 0;
12779   int ret;
12780
12781   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12782   memset (&src, 0, sizeof src);
12783   memset (&dst, 0, sizeof dst);
12784
12785   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12786     {
12787       if (unformat (line_input, "del"))
12788         is_add = 0;
12789       else
12790         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12791         {
12792           ipv4_set = 1;
12793           src_set = 1;
12794         }
12795       else
12796         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12797         {
12798           ipv4_set = 1;
12799           dst_set = 1;
12800         }
12801       else
12802         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12803         {
12804           ipv6_set = 1;
12805           src_set = 1;
12806         }
12807       else
12808         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12809         {
12810           ipv6_set = 1;
12811           dst_set = 1;
12812         }
12813       else if (unformat (line_input, "group %U %U",
12814                          unformat_ip4_address, &dst.ip4,
12815                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12816         {
12817           grp_set = dst_set = 1;
12818           ipv4_set = 1;
12819         }
12820       else if (unformat (line_input, "group %U",
12821                          unformat_ip4_address, &dst.ip4))
12822         {
12823           grp_set = dst_set = 1;
12824           ipv4_set = 1;
12825         }
12826       else if (unformat (line_input, "group %U %U",
12827                          unformat_ip6_address, &dst.ip6,
12828                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12829         {
12830           grp_set = dst_set = 1;
12831           ipv6_set = 1;
12832         }
12833       else if (unformat (line_input, "group %U",
12834                          unformat_ip6_address, &dst.ip6))
12835         {
12836           grp_set = dst_set = 1;
12837           ipv6_set = 1;
12838         }
12839       else
12840         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12841         ;
12842       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12843         ;
12844       else if (unformat (line_input, "decap-next %U",
12845                          unformat_geneve_decap_next, &decap_next_index))
12846         ;
12847       else if (unformat (line_input, "vni %d", &vni))
12848         ;
12849       else
12850         {
12851           errmsg ("parse error '%U'", format_unformat_error, line_input);
12852           return -99;
12853         }
12854     }
12855
12856   if (src_set == 0)
12857     {
12858       errmsg ("tunnel src address not specified");
12859       return -99;
12860     }
12861   if (dst_set == 0)
12862     {
12863       errmsg ("tunnel dst address not specified");
12864       return -99;
12865     }
12866
12867   if (grp_set && !ip46_address_is_multicast (&dst))
12868     {
12869       errmsg ("tunnel group address not multicast");
12870       return -99;
12871     }
12872   if (grp_set && mcast_sw_if_index == ~0)
12873     {
12874       errmsg ("tunnel nonexistent multicast device");
12875       return -99;
12876     }
12877   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12878     {
12879       errmsg ("tunnel dst address must be unicast");
12880       return -99;
12881     }
12882
12883
12884   if (ipv4_set && ipv6_set)
12885     {
12886       errmsg ("both IPv4 and IPv6 addresses specified");
12887       return -99;
12888     }
12889
12890   if ((vni == 0) || (vni >> 24))
12891     {
12892       errmsg ("vni not specified or out of range");
12893       return -99;
12894     }
12895
12896   M (GENEVE_ADD_DEL_TUNNEL, mp);
12897
12898   if (ipv6_set)
12899     {
12900       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12901       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12902     }
12903   else
12904     {
12905       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12906       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12907     }
12908   mp->encap_vrf_id = ntohl (encap_vrf_id);
12909   mp->decap_next_index = ntohl (decap_next_index);
12910   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12911   mp->vni = ntohl (vni);
12912   mp->is_add = is_add;
12913   mp->is_ipv6 = ipv6_set;
12914
12915   S (mp);
12916   W (ret);
12917   return ret;
12918 }
12919
12920 static void vl_api_geneve_tunnel_details_t_handler
12921   (vl_api_geneve_tunnel_details_t * mp)
12922 {
12923   vat_main_t *vam = &vat_main;
12924   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12925   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12926
12927   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12928          ntohl (mp->sw_if_index),
12929          format_ip46_address, &src, IP46_TYPE_ANY,
12930          format_ip46_address, &dst, IP46_TYPE_ANY,
12931          ntohl (mp->encap_vrf_id),
12932          ntohl (mp->decap_next_index), ntohl (mp->vni),
12933          ntohl (mp->mcast_sw_if_index));
12934 }
12935
12936 static void vl_api_geneve_tunnel_details_t_handler_json
12937   (vl_api_geneve_tunnel_details_t * mp)
12938 {
12939   vat_main_t *vam = &vat_main;
12940   vat_json_node_t *node = NULL;
12941
12942   if (VAT_JSON_ARRAY != vam->json_tree.type)
12943     {
12944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12945       vat_json_init_array (&vam->json_tree);
12946     }
12947   node = vat_json_array_add (&vam->json_tree);
12948
12949   vat_json_init_object (node);
12950   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12951   if (mp->is_ipv6)
12952     {
12953       struct in6_addr ip6;
12954
12955       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12956       vat_json_object_add_ip6 (node, "src_address", ip6);
12957       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12958       vat_json_object_add_ip6 (node, "dst_address", ip6);
12959     }
12960   else
12961     {
12962       struct in_addr ip4;
12963
12964       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12965       vat_json_object_add_ip4 (node, "src_address", ip4);
12966       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12967       vat_json_object_add_ip4 (node, "dst_address", ip4);
12968     }
12969   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12970   vat_json_object_add_uint (node, "decap_next_index",
12971                             ntohl (mp->decap_next_index));
12972   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12973   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12974   vat_json_object_add_uint (node, "mcast_sw_if_index",
12975                             ntohl (mp->mcast_sw_if_index));
12976 }
12977
12978 static int
12979 api_geneve_tunnel_dump (vat_main_t * vam)
12980 {
12981   unformat_input_t *i = vam->input;
12982   vl_api_geneve_tunnel_dump_t *mp;
12983   vl_api_control_ping_t *mp_ping;
12984   u32 sw_if_index;
12985   u8 sw_if_index_set = 0;
12986   int ret;
12987
12988   /* Parse args required to build the message */
12989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat (i, "sw_if_index %d", &sw_if_index))
12992         sw_if_index_set = 1;
12993       else
12994         break;
12995     }
12996
12997   if (sw_if_index_set == 0)
12998     {
12999       sw_if_index = ~0;
13000     }
13001
13002   if (!vam->json_output)
13003     {
13004       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13005              "sw_if_index", "local_address", "remote_address",
13006              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13007     }
13008
13009   /* Get list of geneve-tunnel interfaces */
13010   M (GENEVE_TUNNEL_DUMP, mp);
13011
13012   mp->sw_if_index = htonl (sw_if_index);
13013
13014   S (mp);
13015
13016   /* Use a control ping for synchronization */
13017   M (CONTROL_PING, mp_ping);
13018   S (mp_ping);
13019
13020   W (ret);
13021   return ret;
13022 }
13023
13024 static int
13025 api_gre_add_del_tunnel (vat_main_t * vam)
13026 {
13027   unformat_input_t *line_input = vam->input;
13028   vl_api_gre_add_del_tunnel_t *mp;
13029   ip4_address_t src4, dst4;
13030   ip6_address_t src6, dst6;
13031   u8 is_add = 1;
13032   u8 ipv4_set = 0;
13033   u8 ipv6_set = 0;
13034   u8 teb = 0;
13035   u8 src_set = 0;
13036   u8 dst_set = 0;
13037   u32 outer_fib_id = 0;
13038   int ret;
13039
13040   memset (&src4, 0, sizeof src4);
13041   memset (&dst4, 0, sizeof dst4);
13042   memset (&src6, 0, sizeof src6);
13043   memset (&dst6, 0, sizeof dst6);
13044
13045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13046     {
13047       if (unformat (line_input, "del"))
13048         is_add = 0;
13049       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13050         {
13051           src_set = 1;
13052           ipv4_set = 1;
13053         }
13054       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13055         {
13056           dst_set = 1;
13057           ipv4_set = 1;
13058         }
13059       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13060         {
13061           src_set = 1;
13062           ipv6_set = 1;
13063         }
13064       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13065         {
13066           dst_set = 1;
13067           ipv6_set = 1;
13068         }
13069       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13070         ;
13071       else if (unformat (line_input, "teb"))
13072         teb = 1;
13073       else
13074         {
13075           errmsg ("parse error '%U'", format_unformat_error, line_input);
13076           return -99;
13077         }
13078     }
13079
13080   if (src_set == 0)
13081     {
13082       errmsg ("tunnel src address not specified");
13083       return -99;
13084     }
13085   if (dst_set == 0)
13086     {
13087       errmsg ("tunnel dst address not specified");
13088       return -99;
13089     }
13090   if (ipv4_set && ipv6_set)
13091     {
13092       errmsg ("both IPv4 and IPv6 addresses specified");
13093       return -99;
13094     }
13095
13096
13097   M (GRE_ADD_DEL_TUNNEL, mp);
13098
13099   if (ipv4_set)
13100     {
13101       clib_memcpy (&mp->src_address, &src4, 4);
13102       clib_memcpy (&mp->dst_address, &dst4, 4);
13103     }
13104   else
13105     {
13106       clib_memcpy (&mp->src_address, &src6, 16);
13107       clib_memcpy (&mp->dst_address, &dst6, 16);
13108     }
13109   mp->outer_fib_id = ntohl (outer_fib_id);
13110   mp->is_add = is_add;
13111   mp->teb = teb;
13112   mp->is_ipv6 = ipv6_set;
13113
13114   S (mp);
13115   W (ret);
13116   return ret;
13117 }
13118
13119 static void vl_api_gre_tunnel_details_t_handler
13120   (vl_api_gre_tunnel_details_t * mp)
13121 {
13122   vat_main_t *vam = &vat_main;
13123   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13124   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13125
13126   print (vam->ofp, "%11d%24U%24U%6d%14d",
13127          ntohl (mp->sw_if_index),
13128          format_ip46_address, &src, IP46_TYPE_ANY,
13129          format_ip46_address, &dst, IP46_TYPE_ANY,
13130          mp->teb, ntohl (mp->outer_fib_id));
13131 }
13132
13133 static void vl_api_gre_tunnel_details_t_handler_json
13134   (vl_api_gre_tunnel_details_t * mp)
13135 {
13136   vat_main_t *vam = &vat_main;
13137   vat_json_node_t *node = NULL;
13138   struct in_addr ip4;
13139   struct in6_addr ip6;
13140
13141   if (VAT_JSON_ARRAY != vam->json_tree.type)
13142     {
13143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13144       vat_json_init_array (&vam->json_tree);
13145     }
13146   node = vat_json_array_add (&vam->json_tree);
13147
13148   vat_json_init_object (node);
13149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13150   if (!mp->is_ipv6)
13151     {
13152       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13153       vat_json_object_add_ip4 (node, "src_address", ip4);
13154       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13155       vat_json_object_add_ip4 (node, "dst_address", ip4);
13156     }
13157   else
13158     {
13159       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13160       vat_json_object_add_ip6 (node, "src_address", ip6);
13161       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13162       vat_json_object_add_ip6 (node, "dst_address", ip6);
13163     }
13164   vat_json_object_add_uint (node, "teb", mp->teb);
13165   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13166   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13167 }
13168
13169 static int
13170 api_gre_tunnel_dump (vat_main_t * vam)
13171 {
13172   unformat_input_t *i = vam->input;
13173   vl_api_gre_tunnel_dump_t *mp;
13174   vl_api_control_ping_t *mp_ping;
13175   u32 sw_if_index;
13176   u8 sw_if_index_set = 0;
13177   int ret;
13178
13179   /* Parse args required to build the message */
13180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13181     {
13182       if (unformat (i, "sw_if_index %d", &sw_if_index))
13183         sw_if_index_set = 1;
13184       else
13185         break;
13186     }
13187
13188   if (sw_if_index_set == 0)
13189     {
13190       sw_if_index = ~0;
13191     }
13192
13193   if (!vam->json_output)
13194     {
13195       print (vam->ofp, "%11s%24s%24s%6s%14s",
13196              "sw_if_index", "src_address", "dst_address", "teb",
13197              "outer_fib_id");
13198     }
13199
13200   /* Get list of gre-tunnel interfaces */
13201   M (GRE_TUNNEL_DUMP, mp);
13202
13203   mp->sw_if_index = htonl (sw_if_index);
13204
13205   S (mp);
13206
13207   /* Use a control ping for synchronization */
13208   MPING (CONTROL_PING, mp_ping);
13209   S (mp_ping);
13210
13211   W (ret);
13212   return ret;
13213 }
13214
13215 static int
13216 api_l2_fib_clear_table (vat_main_t * vam)
13217 {
13218 //  unformat_input_t * i = vam->input;
13219   vl_api_l2_fib_clear_table_t *mp;
13220   int ret;
13221
13222   M (L2_FIB_CLEAR_TABLE, mp);
13223
13224   S (mp);
13225   W (ret);
13226   return ret;
13227 }
13228
13229 static int
13230 api_l2_interface_efp_filter (vat_main_t * vam)
13231 {
13232   unformat_input_t *i = vam->input;
13233   vl_api_l2_interface_efp_filter_t *mp;
13234   u32 sw_if_index;
13235   u8 enable = 1;
13236   u8 sw_if_index_set = 0;
13237   int ret;
13238
13239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13240     {
13241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13242         sw_if_index_set = 1;
13243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13244         sw_if_index_set = 1;
13245       else if (unformat (i, "enable"))
13246         enable = 1;
13247       else if (unformat (i, "disable"))
13248         enable = 0;
13249       else
13250         {
13251           clib_warning ("parse error '%U'", format_unformat_error, i);
13252           return -99;
13253         }
13254     }
13255
13256   if (sw_if_index_set == 0)
13257     {
13258       errmsg ("missing sw_if_index");
13259       return -99;
13260     }
13261
13262   M (L2_INTERFACE_EFP_FILTER, mp);
13263
13264   mp->sw_if_index = ntohl (sw_if_index);
13265   mp->enable_disable = enable;
13266
13267   S (mp);
13268   W (ret);
13269   return ret;
13270 }
13271
13272 #define foreach_vtr_op                          \
13273 _("disable",  L2_VTR_DISABLED)                  \
13274 _("push-1",  L2_VTR_PUSH_1)                     \
13275 _("push-2",  L2_VTR_PUSH_2)                     \
13276 _("pop-1",  L2_VTR_POP_1)                       \
13277 _("pop-2",  L2_VTR_POP_2)                       \
13278 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13279 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13280 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13281 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13282
13283 static int
13284 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13285 {
13286   unformat_input_t *i = vam->input;
13287   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13288   u32 sw_if_index;
13289   u8 sw_if_index_set = 0;
13290   u8 vtr_op_set = 0;
13291   u32 vtr_op = 0;
13292   u32 push_dot1q = 1;
13293   u32 tag1 = ~0;
13294   u32 tag2 = ~0;
13295   int ret;
13296
13297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13298     {
13299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13300         sw_if_index_set = 1;
13301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13302         sw_if_index_set = 1;
13303       else if (unformat (i, "vtr_op %d", &vtr_op))
13304         vtr_op_set = 1;
13305 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13306       foreach_vtr_op
13307 #undef _
13308         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13309         ;
13310       else if (unformat (i, "tag1 %d", &tag1))
13311         ;
13312       else if (unformat (i, "tag2 %d", &tag2))
13313         ;
13314       else
13315         {
13316           clib_warning ("parse error '%U'", format_unformat_error, i);
13317           return -99;
13318         }
13319     }
13320
13321   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13322     {
13323       errmsg ("missing vtr operation or sw_if_index");
13324       return -99;
13325     }
13326
13327   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13328   mp->sw_if_index = ntohl (sw_if_index);
13329   mp->vtr_op = ntohl (vtr_op);
13330   mp->push_dot1q = ntohl (push_dot1q);
13331   mp->tag1 = ntohl (tag1);
13332   mp->tag2 = ntohl (tag2);
13333
13334   S (mp);
13335   W (ret);
13336   return ret;
13337 }
13338
13339 static int
13340 api_create_vhost_user_if (vat_main_t * vam)
13341 {
13342   unformat_input_t *i = vam->input;
13343   vl_api_create_vhost_user_if_t *mp;
13344   u8 *file_name;
13345   u8 is_server = 0;
13346   u8 file_name_set = 0;
13347   u32 custom_dev_instance = ~0;
13348   u8 hwaddr[6];
13349   u8 use_custom_mac = 0;
13350   u8 *tag = 0;
13351   int ret;
13352
13353   /* Shut up coverity */
13354   memset (hwaddr, 0, sizeof (hwaddr));
13355
13356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13357     {
13358       if (unformat (i, "socket %s", &file_name))
13359         {
13360           file_name_set = 1;
13361         }
13362       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13363         ;
13364       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13365         use_custom_mac = 1;
13366       else if (unformat (i, "server"))
13367         is_server = 1;
13368       else if (unformat (i, "tag %s", &tag))
13369         ;
13370       else
13371         break;
13372     }
13373
13374   if (file_name_set == 0)
13375     {
13376       errmsg ("missing socket file name");
13377       return -99;
13378     }
13379
13380   if (vec_len (file_name) > 255)
13381     {
13382       errmsg ("socket file name too long");
13383       return -99;
13384     }
13385   vec_add1 (file_name, 0);
13386
13387   M (CREATE_VHOST_USER_IF, mp);
13388
13389   mp->is_server = is_server;
13390   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13391   vec_free (file_name);
13392   if (custom_dev_instance != ~0)
13393     {
13394       mp->renumber = 1;
13395       mp->custom_dev_instance = ntohl (custom_dev_instance);
13396     }
13397   mp->use_custom_mac = use_custom_mac;
13398   clib_memcpy (mp->mac_address, hwaddr, 6);
13399   if (tag)
13400     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13401   vec_free (tag);
13402
13403   S (mp);
13404   W (ret);
13405   return ret;
13406 }
13407
13408 static int
13409 api_modify_vhost_user_if (vat_main_t * vam)
13410 {
13411   unformat_input_t *i = vam->input;
13412   vl_api_modify_vhost_user_if_t *mp;
13413   u8 *file_name;
13414   u8 is_server = 0;
13415   u8 file_name_set = 0;
13416   u32 custom_dev_instance = ~0;
13417   u8 sw_if_index_set = 0;
13418   u32 sw_if_index = (u32) ~ 0;
13419   int ret;
13420
13421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13424         sw_if_index_set = 1;
13425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13426         sw_if_index_set = 1;
13427       else if (unformat (i, "socket %s", &file_name))
13428         {
13429           file_name_set = 1;
13430         }
13431       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13432         ;
13433       else if (unformat (i, "server"))
13434         is_server = 1;
13435       else
13436         break;
13437     }
13438
13439   if (sw_if_index_set == 0)
13440     {
13441       errmsg ("missing sw_if_index or interface name");
13442       return -99;
13443     }
13444
13445   if (file_name_set == 0)
13446     {
13447       errmsg ("missing socket file name");
13448       return -99;
13449     }
13450
13451   if (vec_len (file_name) > 255)
13452     {
13453       errmsg ("socket file name too long");
13454       return -99;
13455     }
13456   vec_add1 (file_name, 0);
13457
13458   M (MODIFY_VHOST_USER_IF, mp);
13459
13460   mp->sw_if_index = ntohl (sw_if_index);
13461   mp->is_server = is_server;
13462   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13463   vec_free (file_name);
13464   if (custom_dev_instance != ~0)
13465     {
13466       mp->renumber = 1;
13467       mp->custom_dev_instance = ntohl (custom_dev_instance);
13468     }
13469
13470   S (mp);
13471   W (ret);
13472   return ret;
13473 }
13474
13475 static int
13476 api_delete_vhost_user_if (vat_main_t * vam)
13477 {
13478   unformat_input_t *i = vam->input;
13479   vl_api_delete_vhost_user_if_t *mp;
13480   u32 sw_if_index = ~0;
13481   u8 sw_if_index_set = 0;
13482   int ret;
13483
13484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13485     {
13486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13487         sw_if_index_set = 1;
13488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13489         sw_if_index_set = 1;
13490       else
13491         break;
13492     }
13493
13494   if (sw_if_index_set == 0)
13495     {
13496       errmsg ("missing sw_if_index or interface name");
13497       return -99;
13498     }
13499
13500
13501   M (DELETE_VHOST_USER_IF, mp);
13502
13503   mp->sw_if_index = ntohl (sw_if_index);
13504
13505   S (mp);
13506   W (ret);
13507   return ret;
13508 }
13509
13510 static void vl_api_sw_interface_vhost_user_details_t_handler
13511   (vl_api_sw_interface_vhost_user_details_t * mp)
13512 {
13513   vat_main_t *vam = &vat_main;
13514
13515   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13516          (char *) mp->interface_name,
13517          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13518          clib_net_to_host_u64 (mp->features), mp->is_server,
13519          ntohl (mp->num_regions), (char *) mp->sock_filename);
13520   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13521 }
13522
13523 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13524   (vl_api_sw_interface_vhost_user_details_t * mp)
13525 {
13526   vat_main_t *vam = &vat_main;
13527   vat_json_node_t *node = NULL;
13528
13529   if (VAT_JSON_ARRAY != vam->json_tree.type)
13530     {
13531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13532       vat_json_init_array (&vam->json_tree);
13533     }
13534   node = vat_json_array_add (&vam->json_tree);
13535
13536   vat_json_init_object (node);
13537   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13538   vat_json_object_add_string_copy (node, "interface_name",
13539                                    mp->interface_name);
13540   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13541                             ntohl (mp->virtio_net_hdr_sz));
13542   vat_json_object_add_uint (node, "features",
13543                             clib_net_to_host_u64 (mp->features));
13544   vat_json_object_add_uint (node, "is_server", mp->is_server);
13545   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13546   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13547   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13548 }
13549
13550 static int
13551 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13552 {
13553   vl_api_sw_interface_vhost_user_dump_t *mp;
13554   vl_api_control_ping_t *mp_ping;
13555   int ret;
13556   print (vam->ofp,
13557          "Interface name            idx hdr_sz features server regions filename");
13558
13559   /* Get list of vhost-user interfaces */
13560   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13561   S (mp);
13562
13563   /* Use a control ping for synchronization */
13564   MPING (CONTROL_PING, mp_ping);
13565   S (mp_ping);
13566
13567   W (ret);
13568   return ret;
13569 }
13570
13571 static int
13572 api_show_version (vat_main_t * vam)
13573 {
13574   vl_api_show_version_t *mp;
13575   int ret;
13576
13577   M (SHOW_VERSION, mp);
13578
13579   S (mp);
13580   W (ret);
13581   return ret;
13582 }
13583
13584
13585 static int
13586 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13587 {
13588   unformat_input_t *line_input = vam->input;
13589   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13590   ip4_address_t local4, remote4;
13591   ip6_address_t local6, remote6;
13592   u8 is_add = 1;
13593   u8 ipv4_set = 0, ipv6_set = 0;
13594   u8 local_set = 0;
13595   u8 remote_set = 0;
13596   u8 grp_set = 0;
13597   u32 mcast_sw_if_index = ~0;
13598   u32 encap_vrf_id = 0;
13599   u32 decap_vrf_id = 0;
13600   u8 protocol = ~0;
13601   u32 vni;
13602   u8 vni_set = 0;
13603   int ret;
13604
13605   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13606   memset (&local4, 0, sizeof local4);
13607   memset (&remote4, 0, sizeof remote4);
13608   memset (&local6, 0, sizeof local6);
13609   memset (&remote6, 0, sizeof remote6);
13610
13611   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13612     {
13613       if (unformat (line_input, "del"))
13614         is_add = 0;
13615       else if (unformat (line_input, "local %U",
13616                          unformat_ip4_address, &local4))
13617         {
13618           local_set = 1;
13619           ipv4_set = 1;
13620         }
13621       else if (unformat (line_input, "remote %U",
13622                          unformat_ip4_address, &remote4))
13623         {
13624           remote_set = 1;
13625           ipv4_set = 1;
13626         }
13627       else if (unformat (line_input, "local %U",
13628                          unformat_ip6_address, &local6))
13629         {
13630           local_set = 1;
13631           ipv6_set = 1;
13632         }
13633       else if (unformat (line_input, "remote %U",
13634                          unformat_ip6_address, &remote6))
13635         {
13636           remote_set = 1;
13637           ipv6_set = 1;
13638         }
13639       else if (unformat (line_input, "group %U %U",
13640                          unformat_ip4_address, &remote4,
13641                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13642         {
13643           grp_set = remote_set = 1;
13644           ipv4_set = 1;
13645         }
13646       else if (unformat (line_input, "group %U",
13647                          unformat_ip4_address, &remote4))
13648         {
13649           grp_set = remote_set = 1;
13650           ipv4_set = 1;
13651         }
13652       else if (unformat (line_input, "group %U %U",
13653                          unformat_ip6_address, &remote6,
13654                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13655         {
13656           grp_set = remote_set = 1;
13657           ipv6_set = 1;
13658         }
13659       else if (unformat (line_input, "group %U",
13660                          unformat_ip6_address, &remote6))
13661         {
13662           grp_set = remote_set = 1;
13663           ipv6_set = 1;
13664         }
13665       else
13666         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13667         ;
13668       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13669         ;
13670       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13671         ;
13672       else if (unformat (line_input, "vni %d", &vni))
13673         vni_set = 1;
13674       else if (unformat (line_input, "next-ip4"))
13675         protocol = 1;
13676       else if (unformat (line_input, "next-ip6"))
13677         protocol = 2;
13678       else if (unformat (line_input, "next-ethernet"))
13679         protocol = 3;
13680       else if (unformat (line_input, "next-nsh"))
13681         protocol = 4;
13682       else
13683         {
13684           errmsg ("parse error '%U'", format_unformat_error, line_input);
13685           return -99;
13686         }
13687     }
13688
13689   if (local_set == 0)
13690     {
13691       errmsg ("tunnel local address not specified");
13692       return -99;
13693     }
13694   if (remote_set == 0)
13695     {
13696       errmsg ("tunnel remote address not specified");
13697       return -99;
13698     }
13699   if (grp_set && mcast_sw_if_index == ~0)
13700     {
13701       errmsg ("tunnel nonexistent multicast device");
13702       return -99;
13703     }
13704   if (ipv4_set && ipv6_set)
13705     {
13706       errmsg ("both IPv4 and IPv6 addresses specified");
13707       return -99;
13708     }
13709
13710   if (vni_set == 0)
13711     {
13712       errmsg ("vni not specified");
13713       return -99;
13714     }
13715
13716   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13717
13718
13719   if (ipv6_set)
13720     {
13721       clib_memcpy (&mp->local, &local6, sizeof (local6));
13722       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13723     }
13724   else
13725     {
13726       clib_memcpy (&mp->local, &local4, sizeof (local4));
13727       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13728     }
13729
13730   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13731   mp->encap_vrf_id = ntohl (encap_vrf_id);
13732   mp->decap_vrf_id = ntohl (decap_vrf_id);
13733   mp->protocol = protocol;
13734   mp->vni = ntohl (vni);
13735   mp->is_add = is_add;
13736   mp->is_ipv6 = ipv6_set;
13737
13738   S (mp);
13739   W (ret);
13740   return ret;
13741 }
13742
13743 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13744   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13745 {
13746   vat_main_t *vam = &vat_main;
13747   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13748   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13749
13750   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13751          ntohl (mp->sw_if_index),
13752          format_ip46_address, &local, IP46_TYPE_ANY,
13753          format_ip46_address, &remote, IP46_TYPE_ANY,
13754          ntohl (mp->vni), mp->protocol,
13755          ntohl (mp->mcast_sw_if_index),
13756          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13757 }
13758
13759
13760 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13761   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13762 {
13763   vat_main_t *vam = &vat_main;
13764   vat_json_node_t *node = NULL;
13765   struct in_addr ip4;
13766   struct in6_addr ip6;
13767
13768   if (VAT_JSON_ARRAY != vam->json_tree.type)
13769     {
13770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13771       vat_json_init_array (&vam->json_tree);
13772     }
13773   node = vat_json_array_add (&vam->json_tree);
13774
13775   vat_json_init_object (node);
13776   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13777   if (mp->is_ipv6)
13778     {
13779       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13780       vat_json_object_add_ip6 (node, "local", ip6);
13781       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13782       vat_json_object_add_ip6 (node, "remote", ip6);
13783     }
13784   else
13785     {
13786       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13787       vat_json_object_add_ip4 (node, "local", ip4);
13788       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13789       vat_json_object_add_ip4 (node, "remote", ip4);
13790     }
13791   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13792   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13793   vat_json_object_add_uint (node, "mcast_sw_if_index",
13794                             ntohl (mp->mcast_sw_if_index));
13795   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13796   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13797   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13798 }
13799
13800 static int
13801 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13802 {
13803   unformat_input_t *i = vam->input;
13804   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13805   vl_api_control_ping_t *mp_ping;
13806   u32 sw_if_index;
13807   u8 sw_if_index_set = 0;
13808   int ret;
13809
13810   /* Parse args required to build the message */
13811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (i, "sw_if_index %d", &sw_if_index))
13814         sw_if_index_set = 1;
13815       else
13816         break;
13817     }
13818
13819   if (sw_if_index_set == 0)
13820     {
13821       sw_if_index = ~0;
13822     }
13823
13824   if (!vam->json_output)
13825     {
13826       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13827              "sw_if_index", "local", "remote", "vni",
13828              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13829     }
13830
13831   /* Get list of vxlan-tunnel interfaces */
13832   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13833
13834   mp->sw_if_index = htonl (sw_if_index);
13835
13836   S (mp);
13837
13838   /* Use a control ping for synchronization */
13839   MPING (CONTROL_PING, mp_ping);
13840   S (mp_ping);
13841
13842   W (ret);
13843   return ret;
13844 }
13845
13846 static void vl_api_l2_fib_table_details_t_handler
13847   (vl_api_l2_fib_table_details_t * mp)
13848 {
13849   vat_main_t *vam = &vat_main;
13850
13851   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13852          "       %d       %d     %d",
13853          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13854          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13855          mp->bvi_mac);
13856 }
13857
13858 static void vl_api_l2_fib_table_details_t_handler_json
13859   (vl_api_l2_fib_table_details_t * mp)
13860 {
13861   vat_main_t *vam = &vat_main;
13862   vat_json_node_t *node = NULL;
13863
13864   if (VAT_JSON_ARRAY != vam->json_tree.type)
13865     {
13866       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13867       vat_json_init_array (&vam->json_tree);
13868     }
13869   node = vat_json_array_add (&vam->json_tree);
13870
13871   vat_json_init_object (node);
13872   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13873   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13874   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13875   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13876   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13877   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13878 }
13879
13880 static int
13881 api_l2_fib_table_dump (vat_main_t * vam)
13882 {
13883   unformat_input_t *i = vam->input;
13884   vl_api_l2_fib_table_dump_t *mp;
13885   vl_api_control_ping_t *mp_ping;
13886   u32 bd_id;
13887   u8 bd_id_set = 0;
13888   int ret;
13889
13890   /* Parse args required to build the message */
13891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13892     {
13893       if (unformat (i, "bd_id %d", &bd_id))
13894         bd_id_set = 1;
13895       else
13896         break;
13897     }
13898
13899   if (bd_id_set == 0)
13900     {
13901       errmsg ("missing bridge domain");
13902       return -99;
13903     }
13904
13905   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13906
13907   /* Get list of l2 fib entries */
13908   M (L2_FIB_TABLE_DUMP, mp);
13909
13910   mp->bd_id = ntohl (bd_id);
13911   S (mp);
13912
13913   /* Use a control ping for synchronization */
13914   MPING (CONTROL_PING, mp_ping);
13915   S (mp_ping);
13916
13917   W (ret);
13918   return ret;
13919 }
13920
13921
13922 static int
13923 api_interface_name_renumber (vat_main_t * vam)
13924 {
13925   unformat_input_t *line_input = vam->input;
13926   vl_api_interface_name_renumber_t *mp;
13927   u32 sw_if_index = ~0;
13928   u32 new_show_dev_instance = ~0;
13929   int ret;
13930
13931   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13932     {
13933       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13934                     &sw_if_index))
13935         ;
13936       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13937         ;
13938       else if (unformat (line_input, "new_show_dev_instance %d",
13939                          &new_show_dev_instance))
13940         ;
13941       else
13942         break;
13943     }
13944
13945   if (sw_if_index == ~0)
13946     {
13947       errmsg ("missing interface name or sw_if_index");
13948       return -99;
13949     }
13950
13951   if (new_show_dev_instance == ~0)
13952     {
13953       errmsg ("missing new_show_dev_instance");
13954       return -99;
13955     }
13956
13957   M (INTERFACE_NAME_RENUMBER, mp);
13958
13959   mp->sw_if_index = ntohl (sw_if_index);
13960   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13961
13962   S (mp);
13963   W (ret);
13964   return ret;
13965 }
13966
13967 static int
13968 api_want_ip4_arp_events (vat_main_t * vam)
13969 {
13970   unformat_input_t *line_input = vam->input;
13971   vl_api_want_ip4_arp_events_t *mp;
13972   ip4_address_t address;
13973   int address_set = 0;
13974   u32 enable_disable = 1;
13975   int ret;
13976
13977   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13978     {
13979       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13980         address_set = 1;
13981       else if (unformat (line_input, "del"))
13982         enable_disable = 0;
13983       else
13984         break;
13985     }
13986
13987   if (address_set == 0)
13988     {
13989       errmsg ("missing addresses");
13990       return -99;
13991     }
13992
13993   M (WANT_IP4_ARP_EVENTS, mp);
13994   mp->enable_disable = enable_disable;
13995   mp->pid = htonl (getpid ());
13996   mp->address = address.as_u32;
13997
13998   S (mp);
13999   W (ret);
14000   return ret;
14001 }
14002
14003 static int
14004 api_want_ip6_nd_events (vat_main_t * vam)
14005 {
14006   unformat_input_t *line_input = vam->input;
14007   vl_api_want_ip6_nd_events_t *mp;
14008   ip6_address_t address;
14009   int address_set = 0;
14010   u32 enable_disable = 1;
14011   int ret;
14012
14013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14016         address_set = 1;
14017       else if (unformat (line_input, "del"))
14018         enable_disable = 0;
14019       else
14020         break;
14021     }
14022
14023   if (address_set == 0)
14024     {
14025       errmsg ("missing addresses");
14026       return -99;
14027     }
14028
14029   M (WANT_IP6_ND_EVENTS, mp);
14030   mp->enable_disable = enable_disable;
14031   mp->pid = htonl (getpid ());
14032   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14033
14034   S (mp);
14035   W (ret);
14036   return ret;
14037 }
14038
14039 static int
14040 api_want_l2_macs_events (vat_main_t * vam)
14041 {
14042   unformat_input_t *line_input = vam->input;
14043   vl_api_want_l2_macs_events_t *mp;
14044   u8 enable_disable = 1;
14045   u32 scan_delay = 0;
14046   u32 max_macs_in_event = 0;
14047   u32 learn_limit = 0;
14048   int ret;
14049
14050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14051     {
14052       if (unformat (line_input, "learn-limit %d", &learn_limit))
14053         ;
14054       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14055         ;
14056       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14057         ;
14058       else if (unformat (line_input, "disable"))
14059         enable_disable = 0;
14060       else
14061         break;
14062     }
14063
14064   M (WANT_L2_MACS_EVENTS, mp);
14065   mp->enable_disable = enable_disable;
14066   mp->pid = htonl (getpid ());
14067   mp->learn_limit = htonl (learn_limit);
14068   mp->scan_delay = (u8) scan_delay;
14069   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14070   S (mp);
14071   W (ret);
14072   return ret;
14073 }
14074
14075 static int
14076 api_input_acl_set_interface (vat_main_t * vam)
14077 {
14078   unformat_input_t *i = vam->input;
14079   vl_api_input_acl_set_interface_t *mp;
14080   u32 sw_if_index;
14081   int sw_if_index_set;
14082   u32 ip4_table_index = ~0;
14083   u32 ip6_table_index = ~0;
14084   u32 l2_table_index = ~0;
14085   u8 is_add = 1;
14086   int ret;
14087
14088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14089     {
14090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14091         sw_if_index_set = 1;
14092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14093         sw_if_index_set = 1;
14094       else if (unformat (i, "del"))
14095         is_add = 0;
14096       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14097         ;
14098       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14099         ;
14100       else if (unformat (i, "l2-table %d", &l2_table_index))
14101         ;
14102       else
14103         {
14104           clib_warning ("parse error '%U'", format_unformat_error, i);
14105           return -99;
14106         }
14107     }
14108
14109   if (sw_if_index_set == 0)
14110     {
14111       errmsg ("missing interface name or sw_if_index");
14112       return -99;
14113     }
14114
14115   M (INPUT_ACL_SET_INTERFACE, mp);
14116
14117   mp->sw_if_index = ntohl (sw_if_index);
14118   mp->ip4_table_index = ntohl (ip4_table_index);
14119   mp->ip6_table_index = ntohl (ip6_table_index);
14120   mp->l2_table_index = ntohl (l2_table_index);
14121   mp->is_add = is_add;
14122
14123   S (mp);
14124   W (ret);
14125   return ret;
14126 }
14127
14128 static int
14129 api_ip_address_dump (vat_main_t * vam)
14130 {
14131   unformat_input_t *i = vam->input;
14132   vl_api_ip_address_dump_t *mp;
14133   vl_api_control_ping_t *mp_ping;
14134   u32 sw_if_index = ~0;
14135   u8 sw_if_index_set = 0;
14136   u8 ipv4_set = 0;
14137   u8 ipv6_set = 0;
14138   int ret;
14139
14140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14141     {
14142       if (unformat (i, "sw_if_index %d", &sw_if_index))
14143         sw_if_index_set = 1;
14144       else
14145         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14146         sw_if_index_set = 1;
14147       else if (unformat (i, "ipv4"))
14148         ipv4_set = 1;
14149       else if (unformat (i, "ipv6"))
14150         ipv6_set = 1;
14151       else
14152         break;
14153     }
14154
14155   if (ipv4_set && ipv6_set)
14156     {
14157       errmsg ("ipv4 and ipv6 flags cannot be both set");
14158       return -99;
14159     }
14160
14161   if ((!ipv4_set) && (!ipv6_set))
14162     {
14163       errmsg ("no ipv4 nor ipv6 flag set");
14164       return -99;
14165     }
14166
14167   if (sw_if_index_set == 0)
14168     {
14169       errmsg ("missing interface name or sw_if_index");
14170       return -99;
14171     }
14172
14173   vam->current_sw_if_index = sw_if_index;
14174   vam->is_ipv6 = ipv6_set;
14175
14176   M (IP_ADDRESS_DUMP, mp);
14177   mp->sw_if_index = ntohl (sw_if_index);
14178   mp->is_ipv6 = ipv6_set;
14179   S (mp);
14180
14181   /* Use a control ping for synchronization */
14182   MPING (CONTROL_PING, mp_ping);
14183   S (mp_ping);
14184
14185   W (ret);
14186   return ret;
14187 }
14188
14189 static int
14190 api_ip_dump (vat_main_t * vam)
14191 {
14192   vl_api_ip_dump_t *mp;
14193   vl_api_control_ping_t *mp_ping;
14194   unformat_input_t *in = vam->input;
14195   int ipv4_set = 0;
14196   int ipv6_set = 0;
14197   int is_ipv6;
14198   int i;
14199   int ret;
14200
14201   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14202     {
14203       if (unformat (in, "ipv4"))
14204         ipv4_set = 1;
14205       else if (unformat (in, "ipv6"))
14206         ipv6_set = 1;
14207       else
14208         break;
14209     }
14210
14211   if (ipv4_set && ipv6_set)
14212     {
14213       errmsg ("ipv4 and ipv6 flags cannot be both set");
14214       return -99;
14215     }
14216
14217   if ((!ipv4_set) && (!ipv6_set))
14218     {
14219       errmsg ("no ipv4 nor ipv6 flag set");
14220       return -99;
14221     }
14222
14223   is_ipv6 = ipv6_set;
14224   vam->is_ipv6 = is_ipv6;
14225
14226   /* free old data */
14227   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14228     {
14229       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14230     }
14231   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14232
14233   M (IP_DUMP, mp);
14234   mp->is_ipv6 = ipv6_set;
14235   S (mp);
14236
14237   /* Use a control ping for synchronization */
14238   MPING (CONTROL_PING, mp_ping);
14239   S (mp_ping);
14240
14241   W (ret);
14242   return ret;
14243 }
14244
14245 static int
14246 api_ipsec_spd_add_del (vat_main_t * vam)
14247 {
14248   unformat_input_t *i = vam->input;
14249   vl_api_ipsec_spd_add_del_t *mp;
14250   u32 spd_id = ~0;
14251   u8 is_add = 1;
14252   int ret;
14253
14254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14255     {
14256       if (unformat (i, "spd_id %d", &spd_id))
14257         ;
14258       else if (unformat (i, "del"))
14259         is_add = 0;
14260       else
14261         {
14262           clib_warning ("parse error '%U'", format_unformat_error, i);
14263           return -99;
14264         }
14265     }
14266   if (spd_id == ~0)
14267     {
14268       errmsg ("spd_id must be set");
14269       return -99;
14270     }
14271
14272   M (IPSEC_SPD_ADD_DEL, mp);
14273
14274   mp->spd_id = ntohl (spd_id);
14275   mp->is_add = is_add;
14276
14277   S (mp);
14278   W (ret);
14279   return ret;
14280 }
14281
14282 static int
14283 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14284 {
14285   unformat_input_t *i = vam->input;
14286   vl_api_ipsec_interface_add_del_spd_t *mp;
14287   u32 sw_if_index;
14288   u8 sw_if_index_set = 0;
14289   u32 spd_id = (u32) ~ 0;
14290   u8 is_add = 1;
14291   int ret;
14292
14293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (i, "del"))
14296         is_add = 0;
14297       else if (unformat (i, "spd_id %d", &spd_id))
14298         ;
14299       else
14300         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14301         sw_if_index_set = 1;
14302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14303         sw_if_index_set = 1;
14304       else
14305         {
14306           clib_warning ("parse error '%U'", format_unformat_error, i);
14307           return -99;
14308         }
14309
14310     }
14311
14312   if (spd_id == (u32) ~ 0)
14313     {
14314       errmsg ("spd_id must be set");
14315       return -99;
14316     }
14317
14318   if (sw_if_index_set == 0)
14319     {
14320       errmsg ("missing interface name or sw_if_index");
14321       return -99;
14322     }
14323
14324   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14325
14326   mp->spd_id = ntohl (spd_id);
14327   mp->sw_if_index = ntohl (sw_if_index);
14328   mp->is_add = is_add;
14329
14330   S (mp);
14331   W (ret);
14332   return ret;
14333 }
14334
14335 static int
14336 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14337 {
14338   unformat_input_t *i = vam->input;
14339   vl_api_ipsec_spd_add_del_entry_t *mp;
14340   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14341   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14342   i32 priority = 0;
14343   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14344   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14345   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14346   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14347   int ret;
14348
14349   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14350   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14351   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14352   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14353   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14354   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14355
14356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14357     {
14358       if (unformat (i, "del"))
14359         is_add = 0;
14360       if (unformat (i, "outbound"))
14361         is_outbound = 1;
14362       if (unformat (i, "inbound"))
14363         is_outbound = 0;
14364       else if (unformat (i, "spd_id %d", &spd_id))
14365         ;
14366       else if (unformat (i, "sa_id %d", &sa_id))
14367         ;
14368       else if (unformat (i, "priority %d", &priority))
14369         ;
14370       else if (unformat (i, "protocol %d", &protocol))
14371         ;
14372       else if (unformat (i, "lport_start %d", &lport_start))
14373         ;
14374       else if (unformat (i, "lport_stop %d", &lport_stop))
14375         ;
14376       else if (unformat (i, "rport_start %d", &rport_start))
14377         ;
14378       else if (unformat (i, "rport_stop %d", &rport_stop))
14379         ;
14380       else
14381         if (unformat
14382             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14383         {
14384           is_ipv6 = 0;
14385           is_ip_any = 0;
14386         }
14387       else
14388         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14389         {
14390           is_ipv6 = 0;
14391           is_ip_any = 0;
14392         }
14393       else
14394         if (unformat
14395             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14396         {
14397           is_ipv6 = 0;
14398           is_ip_any = 0;
14399         }
14400       else
14401         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14402         {
14403           is_ipv6 = 0;
14404           is_ip_any = 0;
14405         }
14406       else
14407         if (unformat
14408             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14409         {
14410           is_ipv6 = 1;
14411           is_ip_any = 0;
14412         }
14413       else
14414         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14415         {
14416           is_ipv6 = 1;
14417           is_ip_any = 0;
14418         }
14419       else
14420         if (unformat
14421             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14422         {
14423           is_ipv6 = 1;
14424           is_ip_any = 0;
14425         }
14426       else
14427         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14428         {
14429           is_ipv6 = 1;
14430           is_ip_any = 0;
14431         }
14432       else
14433         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14434         {
14435           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14436             {
14437               clib_warning ("unsupported action: 'resolve'");
14438               return -99;
14439             }
14440         }
14441       else
14442         {
14443           clib_warning ("parse error '%U'", format_unformat_error, i);
14444           return -99;
14445         }
14446
14447     }
14448
14449   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14450
14451   mp->spd_id = ntohl (spd_id);
14452   mp->priority = ntohl (priority);
14453   mp->is_outbound = is_outbound;
14454
14455   mp->is_ipv6 = is_ipv6;
14456   if (is_ipv6 || is_ip_any)
14457     {
14458       clib_memcpy (mp->remote_address_start, &raddr6_start,
14459                    sizeof (ip6_address_t));
14460       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14461                    sizeof (ip6_address_t));
14462       clib_memcpy (mp->local_address_start, &laddr6_start,
14463                    sizeof (ip6_address_t));
14464       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14465                    sizeof (ip6_address_t));
14466     }
14467   else
14468     {
14469       clib_memcpy (mp->remote_address_start, &raddr4_start,
14470                    sizeof (ip4_address_t));
14471       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14472                    sizeof (ip4_address_t));
14473       clib_memcpy (mp->local_address_start, &laddr4_start,
14474                    sizeof (ip4_address_t));
14475       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14476                    sizeof (ip4_address_t));
14477     }
14478   mp->protocol = (u8) protocol;
14479   mp->local_port_start = ntohs ((u16) lport_start);
14480   mp->local_port_stop = ntohs ((u16) lport_stop);
14481   mp->remote_port_start = ntohs ((u16) rport_start);
14482   mp->remote_port_stop = ntohs ((u16) rport_stop);
14483   mp->policy = (u8) policy;
14484   mp->sa_id = ntohl (sa_id);
14485   mp->is_add = is_add;
14486   mp->is_ip_any = is_ip_any;
14487   S (mp);
14488   W (ret);
14489   return ret;
14490 }
14491
14492 static int
14493 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14494 {
14495   unformat_input_t *i = vam->input;
14496   vl_api_ipsec_sad_add_del_entry_t *mp;
14497   u32 sad_id = 0, spi = 0;
14498   u8 *ck = 0, *ik = 0;
14499   u8 is_add = 1;
14500
14501   u8 protocol = IPSEC_PROTOCOL_AH;
14502   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14503   u32 crypto_alg = 0, integ_alg = 0;
14504   ip4_address_t tun_src4;
14505   ip4_address_t tun_dst4;
14506   ip6_address_t tun_src6;
14507   ip6_address_t tun_dst6;
14508   int ret;
14509
14510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14511     {
14512       if (unformat (i, "del"))
14513         is_add = 0;
14514       else if (unformat (i, "sad_id %d", &sad_id))
14515         ;
14516       else if (unformat (i, "spi %d", &spi))
14517         ;
14518       else if (unformat (i, "esp"))
14519         protocol = IPSEC_PROTOCOL_ESP;
14520       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14521         {
14522           is_tunnel = 1;
14523           is_tunnel_ipv6 = 0;
14524         }
14525       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14526         {
14527           is_tunnel = 1;
14528           is_tunnel_ipv6 = 0;
14529         }
14530       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14531         {
14532           is_tunnel = 1;
14533           is_tunnel_ipv6 = 1;
14534         }
14535       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14536         {
14537           is_tunnel = 1;
14538           is_tunnel_ipv6 = 1;
14539         }
14540       else
14541         if (unformat
14542             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14543         {
14544           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14545               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14546             {
14547               clib_warning ("unsupported crypto-alg: '%U'",
14548                             format_ipsec_crypto_alg, crypto_alg);
14549               return -99;
14550             }
14551         }
14552       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14553         ;
14554       else
14555         if (unformat
14556             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14557         {
14558           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14559               integ_alg >= IPSEC_INTEG_N_ALG)
14560             {
14561               clib_warning ("unsupported integ-alg: '%U'",
14562                             format_ipsec_integ_alg, integ_alg);
14563               return -99;
14564             }
14565         }
14566       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14567         ;
14568       else
14569         {
14570           clib_warning ("parse error '%U'", format_unformat_error, i);
14571           return -99;
14572         }
14573
14574     }
14575
14576   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14577
14578   mp->sad_id = ntohl (sad_id);
14579   mp->is_add = is_add;
14580   mp->protocol = protocol;
14581   mp->spi = ntohl (spi);
14582   mp->is_tunnel = is_tunnel;
14583   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14584   mp->crypto_algorithm = crypto_alg;
14585   mp->integrity_algorithm = integ_alg;
14586   mp->crypto_key_length = vec_len (ck);
14587   mp->integrity_key_length = vec_len (ik);
14588
14589   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14590     mp->crypto_key_length = sizeof (mp->crypto_key);
14591
14592   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14593     mp->integrity_key_length = sizeof (mp->integrity_key);
14594
14595   if (ck)
14596     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14597   if (ik)
14598     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14599
14600   if (is_tunnel)
14601     {
14602       if (is_tunnel_ipv6)
14603         {
14604           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14605                        sizeof (ip6_address_t));
14606           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14607                        sizeof (ip6_address_t));
14608         }
14609       else
14610         {
14611           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14612                        sizeof (ip4_address_t));
14613           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14614                        sizeof (ip4_address_t));
14615         }
14616     }
14617
14618   S (mp);
14619   W (ret);
14620   return ret;
14621 }
14622
14623 static int
14624 api_ipsec_sa_set_key (vat_main_t * vam)
14625 {
14626   unformat_input_t *i = vam->input;
14627   vl_api_ipsec_sa_set_key_t *mp;
14628   u32 sa_id;
14629   u8 *ck = 0, *ik = 0;
14630   int ret;
14631
14632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14633     {
14634       if (unformat (i, "sa_id %d", &sa_id))
14635         ;
14636       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14637         ;
14638       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14639         ;
14640       else
14641         {
14642           clib_warning ("parse error '%U'", format_unformat_error, i);
14643           return -99;
14644         }
14645     }
14646
14647   M (IPSEC_SA_SET_KEY, mp);
14648
14649   mp->sa_id = ntohl (sa_id);
14650   mp->crypto_key_length = vec_len (ck);
14651   mp->integrity_key_length = vec_len (ik);
14652
14653   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14654     mp->crypto_key_length = sizeof (mp->crypto_key);
14655
14656   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14657     mp->integrity_key_length = sizeof (mp->integrity_key);
14658
14659   if (ck)
14660     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14661   if (ik)
14662     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14663
14664   S (mp);
14665   W (ret);
14666   return ret;
14667 }
14668
14669 static int
14670 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14671 {
14672   unformat_input_t *i = vam->input;
14673   vl_api_ipsec_tunnel_if_add_del_t *mp;
14674   u32 local_spi = 0, remote_spi = 0;
14675   u32 crypto_alg = 0, integ_alg = 0;
14676   u8 *lck = NULL, *rck = NULL;
14677   u8 *lik = NULL, *rik = NULL;
14678   ip4_address_t local_ip = { {0} };
14679   ip4_address_t remote_ip = { {0} };
14680   u8 is_add = 1;
14681   u8 esn = 0;
14682   u8 anti_replay = 0;
14683   int ret;
14684
14685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14686     {
14687       if (unformat (i, "del"))
14688         is_add = 0;
14689       else if (unformat (i, "esn"))
14690         esn = 1;
14691       else if (unformat (i, "anti_replay"))
14692         anti_replay = 1;
14693       else if (unformat (i, "local_spi %d", &local_spi))
14694         ;
14695       else if (unformat (i, "remote_spi %d", &remote_spi))
14696         ;
14697       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14698         ;
14699       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14700         ;
14701       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14702         ;
14703       else
14704         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14705         ;
14706       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14707         ;
14708       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14709         ;
14710       else
14711         if (unformat
14712             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14713         {
14714           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14715               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14716             {
14717               errmsg ("unsupported crypto-alg: '%U'\n",
14718                       format_ipsec_crypto_alg, crypto_alg);
14719               return -99;
14720             }
14721         }
14722       else
14723         if (unformat
14724             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14725         {
14726           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14727               integ_alg >= IPSEC_INTEG_N_ALG)
14728             {
14729               errmsg ("unsupported integ-alg: '%U'\n",
14730                       format_ipsec_integ_alg, integ_alg);
14731               return -99;
14732             }
14733         }
14734       else
14735         {
14736           errmsg ("parse error '%U'\n", format_unformat_error, i);
14737           return -99;
14738         }
14739     }
14740
14741   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14742
14743   mp->is_add = is_add;
14744   mp->esn = esn;
14745   mp->anti_replay = anti_replay;
14746
14747   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14748   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14749
14750   mp->local_spi = htonl (local_spi);
14751   mp->remote_spi = htonl (remote_spi);
14752   mp->crypto_alg = (u8) crypto_alg;
14753
14754   mp->local_crypto_key_len = 0;
14755   if (lck)
14756     {
14757       mp->local_crypto_key_len = vec_len (lck);
14758       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14759         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14760       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14761     }
14762
14763   mp->remote_crypto_key_len = 0;
14764   if (rck)
14765     {
14766       mp->remote_crypto_key_len = vec_len (rck);
14767       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14768         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14769       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14770     }
14771
14772   mp->integ_alg = (u8) integ_alg;
14773
14774   mp->local_integ_key_len = 0;
14775   if (lik)
14776     {
14777       mp->local_integ_key_len = vec_len (lik);
14778       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14779         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14780       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14781     }
14782
14783   mp->remote_integ_key_len = 0;
14784   if (rik)
14785     {
14786       mp->remote_integ_key_len = vec_len (rik);
14787       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14788         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14789       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14790     }
14791
14792   S (mp);
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static void
14798 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14799 {
14800   vat_main_t *vam = &vat_main;
14801
14802   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14803          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14804          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14805          "tunnel_src_addr %U tunnel_dst_addr %U "
14806          "salt %u seq_outbound %lu last_seq_inbound %lu "
14807          "replay_window %lu total_data_size %lu\n",
14808          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14809          mp->protocol,
14810          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14811          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14812          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14813          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14814          mp->tunnel_src_addr,
14815          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14816          mp->tunnel_dst_addr,
14817          ntohl (mp->salt),
14818          clib_net_to_host_u64 (mp->seq_outbound),
14819          clib_net_to_host_u64 (mp->last_seq_inbound),
14820          clib_net_to_host_u64 (mp->replay_window),
14821          clib_net_to_host_u64 (mp->total_data_size));
14822 }
14823
14824 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14825 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14826
14827 static void vl_api_ipsec_sa_details_t_handler_json
14828   (vl_api_ipsec_sa_details_t * mp)
14829 {
14830   vat_main_t *vam = &vat_main;
14831   vat_json_node_t *node = NULL;
14832   struct in_addr src_ip4, dst_ip4;
14833   struct in6_addr src_ip6, dst_ip6;
14834
14835   if (VAT_JSON_ARRAY != vam->json_tree.type)
14836     {
14837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14838       vat_json_init_array (&vam->json_tree);
14839     }
14840   node = vat_json_array_add (&vam->json_tree);
14841
14842   vat_json_init_object (node);
14843   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14844   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14845   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14846   vat_json_object_add_uint (node, "proto", mp->protocol);
14847   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14848   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14849   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14850   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14851   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14852   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14853   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14854                              mp->crypto_key_len);
14855   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14856                              mp->integ_key_len);
14857   if (mp->is_tunnel_ip6)
14858     {
14859       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14860       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14861       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14862       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14863     }
14864   else
14865     {
14866       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14867       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14868       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14869       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14870     }
14871   vat_json_object_add_uint (node, "replay_window",
14872                             clib_net_to_host_u64 (mp->replay_window));
14873   vat_json_object_add_uint (node, "total_data_size",
14874                             clib_net_to_host_u64 (mp->total_data_size));
14875
14876 }
14877
14878 static int
14879 api_ipsec_sa_dump (vat_main_t * vam)
14880 {
14881   unformat_input_t *i = vam->input;
14882   vl_api_ipsec_sa_dump_t *mp;
14883   vl_api_control_ping_t *mp_ping;
14884   u32 sa_id = ~0;
14885   int ret;
14886
14887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14888     {
14889       if (unformat (i, "sa_id %d", &sa_id))
14890         ;
14891       else
14892         {
14893           clib_warning ("parse error '%U'", format_unformat_error, i);
14894           return -99;
14895         }
14896     }
14897
14898   M (IPSEC_SA_DUMP, mp);
14899
14900   mp->sa_id = ntohl (sa_id);
14901
14902   S (mp);
14903
14904   /* Use a control ping for synchronization */
14905   M (CONTROL_PING, mp_ping);
14906   S (mp_ping);
14907
14908   W (ret);
14909   return ret;
14910 }
14911
14912 static int
14913 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14914 {
14915   unformat_input_t *i = vam->input;
14916   vl_api_ipsec_tunnel_if_set_key_t *mp;
14917   u32 sw_if_index = ~0;
14918   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14919   u8 *key = 0;
14920   u32 alg = ~0;
14921   int ret;
14922
14923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14926         ;
14927       else
14928         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14929         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14930       else
14931         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14932         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14933       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14934         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14935       else
14936         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14937         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14938       else if (unformat (i, "%U", unformat_hex_string, &key))
14939         ;
14940       else
14941         {
14942           clib_warning ("parse error '%U'", format_unformat_error, i);
14943           return -99;
14944         }
14945     }
14946
14947   if (sw_if_index == ~0)
14948     {
14949       errmsg ("interface must be specified");
14950       return -99;
14951     }
14952
14953   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14954     {
14955       errmsg ("key type must be specified");
14956       return -99;
14957     }
14958
14959   if (alg == ~0)
14960     {
14961       errmsg ("algorithm must be specified");
14962       return -99;
14963     }
14964
14965   if (vec_len (key) == 0)
14966     {
14967       errmsg ("key must be specified");
14968       return -99;
14969     }
14970
14971   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14972
14973   mp->sw_if_index = htonl (sw_if_index);
14974   mp->alg = alg;
14975   mp->key_type = key_type;
14976   mp->key_len = vec_len (key);
14977   clib_memcpy (mp->key, key, vec_len (key));
14978
14979   S (mp);
14980   W (ret);
14981
14982   return ret;
14983 }
14984
14985 static int
14986 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14987 {
14988   unformat_input_t *i = vam->input;
14989   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14990   u32 sw_if_index = ~0;
14991   u32 sa_id = ~0;
14992   u8 is_outbound = (u8) ~ 0;
14993   int ret;
14994
14995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14996     {
14997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14998         ;
14999       else if (unformat (i, "sa_id %d", &sa_id))
15000         ;
15001       else if (unformat (i, "outbound"))
15002         is_outbound = 1;
15003       else if (unformat (i, "inbound"))
15004         is_outbound = 0;
15005       else
15006         {
15007           clib_warning ("parse error '%U'", format_unformat_error, i);
15008           return -99;
15009         }
15010     }
15011
15012   if (sw_if_index == ~0)
15013     {
15014       errmsg ("interface must be specified");
15015       return -99;
15016     }
15017
15018   if (sa_id == ~0)
15019     {
15020       errmsg ("SA ID must be specified");
15021       return -99;
15022     }
15023
15024   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15025
15026   mp->sw_if_index = htonl (sw_if_index);
15027   mp->sa_id = htonl (sa_id);
15028   mp->is_outbound = is_outbound;
15029
15030   S (mp);
15031   W (ret);
15032
15033   return ret;
15034 }
15035
15036 static int
15037 api_ikev2_profile_add_del (vat_main_t * vam)
15038 {
15039   unformat_input_t *i = vam->input;
15040   vl_api_ikev2_profile_add_del_t *mp;
15041   u8 is_add = 1;
15042   u8 *name = 0;
15043   int ret;
15044
15045   const char *valid_chars = "a-zA-Z0-9_";
15046
15047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15048     {
15049       if (unformat (i, "del"))
15050         is_add = 0;
15051       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15052         vec_add1 (name, 0);
15053       else
15054         {
15055           errmsg ("parse error '%U'", format_unformat_error, i);
15056           return -99;
15057         }
15058     }
15059
15060   if (!vec_len (name))
15061     {
15062       errmsg ("profile name must be specified");
15063       return -99;
15064     }
15065
15066   if (vec_len (name) > 64)
15067     {
15068       errmsg ("profile name too long");
15069       return -99;
15070     }
15071
15072   M (IKEV2_PROFILE_ADD_DEL, mp);
15073
15074   clib_memcpy (mp->name, name, vec_len (name));
15075   mp->is_add = is_add;
15076   vec_free (name);
15077
15078   S (mp);
15079   W (ret);
15080   return ret;
15081 }
15082
15083 static int
15084 api_ikev2_profile_set_auth (vat_main_t * vam)
15085 {
15086   unformat_input_t *i = vam->input;
15087   vl_api_ikev2_profile_set_auth_t *mp;
15088   u8 *name = 0;
15089   u8 *data = 0;
15090   u32 auth_method = 0;
15091   u8 is_hex = 0;
15092   int ret;
15093
15094   const char *valid_chars = "a-zA-Z0-9_";
15095
15096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15099         vec_add1 (name, 0);
15100       else if (unformat (i, "auth_method %U",
15101                          unformat_ikev2_auth_method, &auth_method))
15102         ;
15103       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15104         is_hex = 1;
15105       else if (unformat (i, "auth_data %v", &data))
15106         ;
15107       else
15108         {
15109           errmsg ("parse error '%U'", format_unformat_error, i);
15110           return -99;
15111         }
15112     }
15113
15114   if (!vec_len (name))
15115     {
15116       errmsg ("profile name must be specified");
15117       return -99;
15118     }
15119
15120   if (vec_len (name) > 64)
15121     {
15122       errmsg ("profile name too long");
15123       return -99;
15124     }
15125
15126   if (!vec_len (data))
15127     {
15128       errmsg ("auth_data must be specified");
15129       return -99;
15130     }
15131
15132   if (!auth_method)
15133     {
15134       errmsg ("auth_method must be specified");
15135       return -99;
15136     }
15137
15138   M (IKEV2_PROFILE_SET_AUTH, mp);
15139
15140   mp->is_hex = is_hex;
15141   mp->auth_method = (u8) auth_method;
15142   mp->data_len = vec_len (data);
15143   clib_memcpy (mp->name, name, vec_len (name));
15144   clib_memcpy (mp->data, data, vec_len (data));
15145   vec_free (name);
15146   vec_free (data);
15147
15148   S (mp);
15149   W (ret);
15150   return ret;
15151 }
15152
15153 static int
15154 api_ikev2_profile_set_id (vat_main_t * vam)
15155 {
15156   unformat_input_t *i = vam->input;
15157   vl_api_ikev2_profile_set_id_t *mp;
15158   u8 *name = 0;
15159   u8 *data = 0;
15160   u8 is_local = 0;
15161   u32 id_type = 0;
15162   ip4_address_t ip4;
15163   int ret;
15164
15165   const char *valid_chars = "a-zA-Z0-9_";
15166
15167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15168     {
15169       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15170         vec_add1 (name, 0);
15171       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15172         ;
15173       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15174         {
15175           data = vec_new (u8, 4);
15176           clib_memcpy (data, ip4.as_u8, 4);
15177         }
15178       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15179         ;
15180       else if (unformat (i, "id_data %v", &data))
15181         ;
15182       else if (unformat (i, "local"))
15183         is_local = 1;
15184       else if (unformat (i, "remote"))
15185         is_local = 0;
15186       else
15187         {
15188           errmsg ("parse error '%U'", format_unformat_error, i);
15189           return -99;
15190         }
15191     }
15192
15193   if (!vec_len (name))
15194     {
15195       errmsg ("profile name must be specified");
15196       return -99;
15197     }
15198
15199   if (vec_len (name) > 64)
15200     {
15201       errmsg ("profile name too long");
15202       return -99;
15203     }
15204
15205   if (!vec_len (data))
15206     {
15207       errmsg ("id_data must be specified");
15208       return -99;
15209     }
15210
15211   if (!id_type)
15212     {
15213       errmsg ("id_type must be specified");
15214       return -99;
15215     }
15216
15217   M (IKEV2_PROFILE_SET_ID, mp);
15218
15219   mp->is_local = is_local;
15220   mp->id_type = (u8) id_type;
15221   mp->data_len = vec_len (data);
15222   clib_memcpy (mp->name, name, vec_len (name));
15223   clib_memcpy (mp->data, data, vec_len (data));
15224   vec_free (name);
15225   vec_free (data);
15226
15227   S (mp);
15228   W (ret);
15229   return ret;
15230 }
15231
15232 static int
15233 api_ikev2_profile_set_ts (vat_main_t * vam)
15234 {
15235   unformat_input_t *i = vam->input;
15236   vl_api_ikev2_profile_set_ts_t *mp;
15237   u8 *name = 0;
15238   u8 is_local = 0;
15239   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15240   ip4_address_t start_addr, end_addr;
15241
15242   const char *valid_chars = "a-zA-Z0-9_";
15243   int ret;
15244
15245   start_addr.as_u32 = 0;
15246   end_addr.as_u32 = (u32) ~ 0;
15247
15248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15249     {
15250       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15251         vec_add1 (name, 0);
15252       else if (unformat (i, "protocol %d", &proto))
15253         ;
15254       else if (unformat (i, "start_port %d", &start_port))
15255         ;
15256       else if (unformat (i, "end_port %d", &end_port))
15257         ;
15258       else
15259         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15260         ;
15261       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15262         ;
15263       else if (unformat (i, "local"))
15264         is_local = 1;
15265       else if (unformat (i, "remote"))
15266         is_local = 0;
15267       else
15268         {
15269           errmsg ("parse error '%U'", format_unformat_error, i);
15270           return -99;
15271         }
15272     }
15273
15274   if (!vec_len (name))
15275     {
15276       errmsg ("profile name must be specified");
15277       return -99;
15278     }
15279
15280   if (vec_len (name) > 64)
15281     {
15282       errmsg ("profile name too long");
15283       return -99;
15284     }
15285
15286   M (IKEV2_PROFILE_SET_TS, mp);
15287
15288   mp->is_local = is_local;
15289   mp->proto = (u8) proto;
15290   mp->start_port = (u16) start_port;
15291   mp->end_port = (u16) end_port;
15292   mp->start_addr = start_addr.as_u32;
15293   mp->end_addr = end_addr.as_u32;
15294   clib_memcpy (mp->name, name, vec_len (name));
15295   vec_free (name);
15296
15297   S (mp);
15298   W (ret);
15299   return ret;
15300 }
15301
15302 static int
15303 api_ikev2_set_local_key (vat_main_t * vam)
15304 {
15305   unformat_input_t *i = vam->input;
15306   vl_api_ikev2_set_local_key_t *mp;
15307   u8 *file = 0;
15308   int ret;
15309
15310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15311     {
15312       if (unformat (i, "file %v", &file))
15313         vec_add1 (file, 0);
15314       else
15315         {
15316           errmsg ("parse error '%U'", format_unformat_error, i);
15317           return -99;
15318         }
15319     }
15320
15321   if (!vec_len (file))
15322     {
15323       errmsg ("RSA key file must be specified");
15324       return -99;
15325     }
15326
15327   if (vec_len (file) > 256)
15328     {
15329       errmsg ("file name too long");
15330       return -99;
15331     }
15332
15333   M (IKEV2_SET_LOCAL_KEY, mp);
15334
15335   clib_memcpy (mp->key_file, file, vec_len (file));
15336   vec_free (file);
15337
15338   S (mp);
15339   W (ret);
15340   return ret;
15341 }
15342
15343 static int
15344 api_ikev2_set_responder (vat_main_t * vam)
15345 {
15346   unformat_input_t *i = vam->input;
15347   vl_api_ikev2_set_responder_t *mp;
15348   int ret;
15349   u8 *name = 0;
15350   u32 sw_if_index = ~0;
15351   ip4_address_t address;
15352
15353   const char *valid_chars = "a-zA-Z0-9_";
15354
15355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat
15358           (i, "%U interface %d address %U", unformat_token, valid_chars,
15359            &name, &sw_if_index, unformat_ip4_address, &address))
15360         vec_add1 (name, 0);
15361       else
15362         {
15363           errmsg ("parse error '%U'", format_unformat_error, i);
15364           return -99;
15365         }
15366     }
15367
15368   if (!vec_len (name))
15369     {
15370       errmsg ("profile name must be specified");
15371       return -99;
15372     }
15373
15374   if (vec_len (name) > 64)
15375     {
15376       errmsg ("profile name too long");
15377       return -99;
15378     }
15379
15380   M (IKEV2_SET_RESPONDER, mp);
15381
15382   clib_memcpy (mp->name, name, vec_len (name));
15383   vec_free (name);
15384
15385   mp->sw_if_index = sw_if_index;
15386   clib_memcpy (mp->address, &address, sizeof (address));
15387
15388   S (mp);
15389   W (ret);
15390   return ret;
15391 }
15392
15393 static int
15394 api_ikev2_set_ike_transforms (vat_main_t * vam)
15395 {
15396   unformat_input_t *i = vam->input;
15397   vl_api_ikev2_set_ike_transforms_t *mp;
15398   int ret;
15399   u8 *name = 0;
15400   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15401
15402   const char *valid_chars = "a-zA-Z0-9_";
15403
15404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15405     {
15406       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15407                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15408         vec_add1 (name, 0);
15409       else
15410         {
15411           errmsg ("parse error '%U'", format_unformat_error, i);
15412           return -99;
15413         }
15414     }
15415
15416   if (!vec_len (name))
15417     {
15418       errmsg ("profile name must be specified");
15419       return -99;
15420     }
15421
15422   if (vec_len (name) > 64)
15423     {
15424       errmsg ("profile name too long");
15425       return -99;
15426     }
15427
15428   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15429
15430   clib_memcpy (mp->name, name, vec_len (name));
15431   vec_free (name);
15432   mp->crypto_alg = crypto_alg;
15433   mp->crypto_key_size = crypto_key_size;
15434   mp->integ_alg = integ_alg;
15435   mp->dh_group = dh_group;
15436
15437   S (mp);
15438   W (ret);
15439   return ret;
15440 }
15441
15442
15443 static int
15444 api_ikev2_set_esp_transforms (vat_main_t * vam)
15445 {
15446   unformat_input_t *i = vam->input;
15447   vl_api_ikev2_set_esp_transforms_t *mp;
15448   int ret;
15449   u8 *name = 0;
15450   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15451
15452   const char *valid_chars = "a-zA-Z0-9_";
15453
15454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15455     {
15456       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15457                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15458         vec_add1 (name, 0);
15459       else
15460         {
15461           errmsg ("parse error '%U'", format_unformat_error, i);
15462           return -99;
15463         }
15464     }
15465
15466   if (!vec_len (name))
15467     {
15468       errmsg ("profile name must be specified");
15469       return -99;
15470     }
15471
15472   if (vec_len (name) > 64)
15473     {
15474       errmsg ("profile name too long");
15475       return -99;
15476     }
15477
15478   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15479
15480   clib_memcpy (mp->name, name, vec_len (name));
15481   vec_free (name);
15482   mp->crypto_alg = crypto_alg;
15483   mp->crypto_key_size = crypto_key_size;
15484   mp->integ_alg = integ_alg;
15485   mp->dh_group = dh_group;
15486
15487   S (mp);
15488   W (ret);
15489   return ret;
15490 }
15491
15492 static int
15493 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15494 {
15495   unformat_input_t *i = vam->input;
15496   vl_api_ikev2_set_sa_lifetime_t *mp;
15497   int ret;
15498   u8 *name = 0;
15499   u64 lifetime, lifetime_maxdata;
15500   u32 lifetime_jitter, handover;
15501
15502   const char *valid_chars = "a-zA-Z0-9_";
15503
15504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15505     {
15506       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15507                     &lifetime, &lifetime_jitter, &handover,
15508                     &lifetime_maxdata))
15509         vec_add1 (name, 0);
15510       else
15511         {
15512           errmsg ("parse error '%U'", format_unformat_error, i);
15513           return -99;
15514         }
15515     }
15516
15517   if (!vec_len (name))
15518     {
15519       errmsg ("profile name must be specified");
15520       return -99;
15521     }
15522
15523   if (vec_len (name) > 64)
15524     {
15525       errmsg ("profile name too long");
15526       return -99;
15527     }
15528
15529   M (IKEV2_SET_SA_LIFETIME, mp);
15530
15531   clib_memcpy (mp->name, name, vec_len (name));
15532   vec_free (name);
15533   mp->lifetime = lifetime;
15534   mp->lifetime_jitter = lifetime_jitter;
15535   mp->handover = handover;
15536   mp->lifetime_maxdata = lifetime_maxdata;
15537
15538   S (mp);
15539   W (ret);
15540   return ret;
15541 }
15542
15543 static int
15544 api_ikev2_initiate_sa_init (vat_main_t * vam)
15545 {
15546   unformat_input_t *i = vam->input;
15547   vl_api_ikev2_initiate_sa_init_t *mp;
15548   int ret;
15549   u8 *name = 0;
15550
15551   const char *valid_chars = "a-zA-Z0-9_";
15552
15553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15554     {
15555       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15556         vec_add1 (name, 0);
15557       else
15558         {
15559           errmsg ("parse error '%U'", format_unformat_error, i);
15560           return -99;
15561         }
15562     }
15563
15564   if (!vec_len (name))
15565     {
15566       errmsg ("profile name must be specified");
15567       return -99;
15568     }
15569
15570   if (vec_len (name) > 64)
15571     {
15572       errmsg ("profile name too long");
15573       return -99;
15574     }
15575
15576   M (IKEV2_INITIATE_SA_INIT, mp);
15577
15578   clib_memcpy (mp->name, name, vec_len (name));
15579   vec_free (name);
15580
15581   S (mp);
15582   W (ret);
15583   return ret;
15584 }
15585
15586 static int
15587 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15588 {
15589   unformat_input_t *i = vam->input;
15590   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15591   int ret;
15592   u64 ispi;
15593
15594
15595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15596     {
15597       if (unformat (i, "%lx", &ispi))
15598         ;
15599       else
15600         {
15601           errmsg ("parse error '%U'", format_unformat_error, i);
15602           return -99;
15603         }
15604     }
15605
15606   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15607
15608   mp->ispi = ispi;
15609
15610   S (mp);
15611   W (ret);
15612   return ret;
15613 }
15614
15615 static int
15616 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15617 {
15618   unformat_input_t *i = vam->input;
15619   vl_api_ikev2_initiate_del_child_sa_t *mp;
15620   int ret;
15621   u32 ispi;
15622
15623
15624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15625     {
15626       if (unformat (i, "%x", &ispi))
15627         ;
15628       else
15629         {
15630           errmsg ("parse error '%U'", format_unformat_error, i);
15631           return -99;
15632         }
15633     }
15634
15635   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15636
15637   mp->ispi = ispi;
15638
15639   S (mp);
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15646 {
15647   unformat_input_t *i = vam->input;
15648   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15649   int ret;
15650   u32 ispi;
15651
15652
15653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15654     {
15655       if (unformat (i, "%x", &ispi))
15656         ;
15657       else
15658         {
15659           errmsg ("parse error '%U'", format_unformat_error, i);
15660           return -99;
15661         }
15662     }
15663
15664   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15665
15666   mp->ispi = ispi;
15667
15668   S (mp);
15669   W (ret);
15670   return ret;
15671 }
15672
15673 /*
15674  * MAP
15675  */
15676 static int
15677 api_map_add_domain (vat_main_t * vam)
15678 {
15679   unformat_input_t *i = vam->input;
15680   vl_api_map_add_domain_t *mp;
15681
15682   ip4_address_t ip4_prefix;
15683   ip6_address_t ip6_prefix;
15684   ip6_address_t ip6_src;
15685   u32 num_m_args = 0;
15686   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15687     0, psid_length = 0;
15688   u8 is_translation = 0;
15689   u32 mtu = 0;
15690   u32 ip6_src_len = 128;
15691   int ret;
15692
15693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15694     {
15695       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15696                     &ip4_prefix, &ip4_prefix_len))
15697         num_m_args++;
15698       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15699                          &ip6_prefix, &ip6_prefix_len))
15700         num_m_args++;
15701       else
15702         if (unformat
15703             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15704              &ip6_src_len))
15705         num_m_args++;
15706       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15707         num_m_args++;
15708       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15709         num_m_args++;
15710       else if (unformat (i, "psid-offset %d", &psid_offset))
15711         num_m_args++;
15712       else if (unformat (i, "psid-len %d", &psid_length))
15713         num_m_args++;
15714       else if (unformat (i, "mtu %d", &mtu))
15715         num_m_args++;
15716       else if (unformat (i, "map-t"))
15717         is_translation = 1;
15718       else
15719         {
15720           clib_warning ("parse error '%U'", format_unformat_error, i);
15721           return -99;
15722         }
15723     }
15724
15725   if (num_m_args < 3)
15726     {
15727       errmsg ("mandatory argument(s) missing");
15728       return -99;
15729     }
15730
15731   /* Construct the API message */
15732   M (MAP_ADD_DOMAIN, mp);
15733
15734   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15735   mp->ip4_prefix_len = ip4_prefix_len;
15736
15737   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15738   mp->ip6_prefix_len = ip6_prefix_len;
15739
15740   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15741   mp->ip6_src_prefix_len = ip6_src_len;
15742
15743   mp->ea_bits_len = ea_bits_len;
15744   mp->psid_offset = psid_offset;
15745   mp->psid_length = psid_length;
15746   mp->is_translation = is_translation;
15747   mp->mtu = htons (mtu);
15748
15749   /* send it... */
15750   S (mp);
15751
15752   /* Wait for a reply, return good/bad news  */
15753   W (ret);
15754   return ret;
15755 }
15756
15757 static int
15758 api_map_del_domain (vat_main_t * vam)
15759 {
15760   unformat_input_t *i = vam->input;
15761   vl_api_map_del_domain_t *mp;
15762
15763   u32 num_m_args = 0;
15764   u32 index;
15765   int ret;
15766
15767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15768     {
15769       if (unformat (i, "index %d", &index))
15770         num_m_args++;
15771       else
15772         {
15773           clib_warning ("parse error '%U'", format_unformat_error, i);
15774           return -99;
15775         }
15776     }
15777
15778   if (num_m_args != 1)
15779     {
15780       errmsg ("mandatory argument(s) missing");
15781       return -99;
15782     }
15783
15784   /* Construct the API message */
15785   M (MAP_DEL_DOMAIN, mp);
15786
15787   mp->index = ntohl (index);
15788
15789   /* send it... */
15790   S (mp);
15791
15792   /* Wait for a reply, return good/bad news  */
15793   W (ret);
15794   return ret;
15795 }
15796
15797 static int
15798 api_map_add_del_rule (vat_main_t * vam)
15799 {
15800   unformat_input_t *i = vam->input;
15801   vl_api_map_add_del_rule_t *mp;
15802   u8 is_add = 1;
15803   ip6_address_t ip6_dst;
15804   u32 num_m_args = 0, index, psid = 0;
15805   int ret;
15806
15807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15808     {
15809       if (unformat (i, "index %d", &index))
15810         num_m_args++;
15811       else if (unformat (i, "psid %d", &psid))
15812         num_m_args++;
15813       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15814         num_m_args++;
15815       else if (unformat (i, "del"))
15816         {
15817           is_add = 0;
15818         }
15819       else
15820         {
15821           clib_warning ("parse error '%U'", format_unformat_error, i);
15822           return -99;
15823         }
15824     }
15825
15826   /* Construct the API message */
15827   M (MAP_ADD_DEL_RULE, mp);
15828
15829   mp->index = ntohl (index);
15830   mp->is_add = is_add;
15831   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15832   mp->psid = ntohs (psid);
15833
15834   /* send it... */
15835   S (mp);
15836
15837   /* Wait for a reply, return good/bad news  */
15838   W (ret);
15839   return ret;
15840 }
15841
15842 static int
15843 api_map_domain_dump (vat_main_t * vam)
15844 {
15845   vl_api_map_domain_dump_t *mp;
15846   vl_api_control_ping_t *mp_ping;
15847   int ret;
15848
15849   /* Construct the API message */
15850   M (MAP_DOMAIN_DUMP, mp);
15851
15852   /* send it... */
15853   S (mp);
15854
15855   /* Use a control ping for synchronization */
15856   MPING (CONTROL_PING, mp_ping);
15857   S (mp_ping);
15858
15859   W (ret);
15860   return ret;
15861 }
15862
15863 static int
15864 api_map_rule_dump (vat_main_t * vam)
15865 {
15866   unformat_input_t *i = vam->input;
15867   vl_api_map_rule_dump_t *mp;
15868   vl_api_control_ping_t *mp_ping;
15869   u32 domain_index = ~0;
15870   int ret;
15871
15872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15873     {
15874       if (unformat (i, "index %u", &domain_index))
15875         ;
15876       else
15877         break;
15878     }
15879
15880   if (domain_index == ~0)
15881     {
15882       clib_warning ("parse error: domain index expected");
15883       return -99;
15884     }
15885
15886   /* Construct the API message */
15887   M (MAP_RULE_DUMP, mp);
15888
15889   mp->domain_index = htonl (domain_index);
15890
15891   /* send it... */
15892   S (mp);
15893
15894   /* Use a control ping for synchronization */
15895   MPING (CONTROL_PING, mp_ping);
15896   S (mp_ping);
15897
15898   W (ret);
15899   return ret;
15900 }
15901
15902 static void vl_api_map_add_domain_reply_t_handler
15903   (vl_api_map_add_domain_reply_t * mp)
15904 {
15905   vat_main_t *vam = &vat_main;
15906   i32 retval = ntohl (mp->retval);
15907
15908   if (vam->async_mode)
15909     {
15910       vam->async_errors += (retval < 0);
15911     }
15912   else
15913     {
15914       vam->retval = retval;
15915       vam->result_ready = 1;
15916     }
15917 }
15918
15919 static void vl_api_map_add_domain_reply_t_handler_json
15920   (vl_api_map_add_domain_reply_t * mp)
15921 {
15922   vat_main_t *vam = &vat_main;
15923   vat_json_node_t node;
15924
15925   vat_json_init_object (&node);
15926   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15927   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15928
15929   vat_json_print (vam->ofp, &node);
15930   vat_json_free (&node);
15931
15932   vam->retval = ntohl (mp->retval);
15933   vam->result_ready = 1;
15934 }
15935
15936 static int
15937 api_get_first_msg_id (vat_main_t * vam)
15938 {
15939   vl_api_get_first_msg_id_t *mp;
15940   unformat_input_t *i = vam->input;
15941   u8 *name;
15942   u8 name_set = 0;
15943   int ret;
15944
15945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15946     {
15947       if (unformat (i, "client %s", &name))
15948         name_set = 1;
15949       else
15950         break;
15951     }
15952
15953   if (name_set == 0)
15954     {
15955       errmsg ("missing client name");
15956       return -99;
15957     }
15958   vec_add1 (name, 0);
15959
15960   if (vec_len (name) > 63)
15961     {
15962       errmsg ("client name too long");
15963       return -99;
15964     }
15965
15966   M (GET_FIRST_MSG_ID, mp);
15967   clib_memcpy (mp->name, name, vec_len (name));
15968   S (mp);
15969   W (ret);
15970   return ret;
15971 }
15972
15973 static int
15974 api_cop_interface_enable_disable (vat_main_t * vam)
15975 {
15976   unformat_input_t *line_input = vam->input;
15977   vl_api_cop_interface_enable_disable_t *mp;
15978   u32 sw_if_index = ~0;
15979   u8 enable_disable = 1;
15980   int ret;
15981
15982   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15983     {
15984       if (unformat (line_input, "disable"))
15985         enable_disable = 0;
15986       if (unformat (line_input, "enable"))
15987         enable_disable = 1;
15988       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15989                          vam, &sw_if_index))
15990         ;
15991       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15992         ;
15993       else
15994         break;
15995     }
15996
15997   if (sw_if_index == ~0)
15998     {
15999       errmsg ("missing interface name or sw_if_index");
16000       return -99;
16001     }
16002
16003   /* Construct the API message */
16004   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16005   mp->sw_if_index = ntohl (sw_if_index);
16006   mp->enable_disable = enable_disable;
16007
16008   /* send it... */
16009   S (mp);
16010   /* Wait for the reply */
16011   W (ret);
16012   return ret;
16013 }
16014
16015 static int
16016 api_cop_whitelist_enable_disable (vat_main_t * vam)
16017 {
16018   unformat_input_t *line_input = vam->input;
16019   vl_api_cop_whitelist_enable_disable_t *mp;
16020   u32 sw_if_index = ~0;
16021   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16022   u32 fib_id = 0;
16023   int ret;
16024
16025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16026     {
16027       if (unformat (line_input, "ip4"))
16028         ip4 = 1;
16029       else if (unformat (line_input, "ip6"))
16030         ip6 = 1;
16031       else if (unformat (line_input, "default"))
16032         default_cop = 1;
16033       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16034                          vam, &sw_if_index))
16035         ;
16036       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16037         ;
16038       else if (unformat (line_input, "fib-id %d", &fib_id))
16039         ;
16040       else
16041         break;
16042     }
16043
16044   if (sw_if_index == ~0)
16045     {
16046       errmsg ("missing interface name or sw_if_index");
16047       return -99;
16048     }
16049
16050   /* Construct the API message */
16051   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16052   mp->sw_if_index = ntohl (sw_if_index);
16053   mp->fib_id = ntohl (fib_id);
16054   mp->ip4 = ip4;
16055   mp->ip6 = ip6;
16056   mp->default_cop = default_cop;
16057
16058   /* send it... */
16059   S (mp);
16060   /* Wait for the reply */
16061   W (ret);
16062   return ret;
16063 }
16064
16065 static int
16066 api_get_node_graph (vat_main_t * vam)
16067 {
16068   vl_api_get_node_graph_t *mp;
16069   int ret;
16070
16071   M (GET_NODE_GRAPH, mp);
16072
16073   /* send it... */
16074   S (mp);
16075   /* Wait for the reply */
16076   W (ret);
16077   return ret;
16078 }
16079
16080 /* *INDENT-OFF* */
16081 /** Used for parsing LISP eids */
16082 typedef CLIB_PACKED(struct{
16083   u8 addr[16];   /**< eid address */
16084   u32 len;       /**< prefix length if IP */
16085   u8 type;      /**< type of eid */
16086 }) lisp_eid_vat_t;
16087 /* *INDENT-ON* */
16088
16089 static uword
16090 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16091 {
16092   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16093
16094   memset (a, 0, sizeof (a[0]));
16095
16096   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16097     {
16098       a->type = 0;              /* ipv4 type */
16099     }
16100   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16101     {
16102       a->type = 1;              /* ipv6 type */
16103     }
16104   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16105     {
16106       a->type = 2;              /* mac type */
16107     }
16108   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16109     {
16110       a->type = 3;              /* NSH type */
16111       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16112       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16113     }
16114   else
16115     {
16116       return 0;
16117     }
16118
16119   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16120     {
16121       return 0;
16122     }
16123
16124   return 1;
16125 }
16126
16127 static int
16128 lisp_eid_size_vat (u8 type)
16129 {
16130   switch (type)
16131     {
16132     case 0:
16133       return 4;
16134     case 1:
16135       return 16;
16136     case 2:
16137       return 6;
16138     case 3:
16139       return 5;
16140     }
16141   return 0;
16142 }
16143
16144 static void
16145 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16146 {
16147   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16148 }
16149
16150 static int
16151 api_one_add_del_locator_set (vat_main_t * vam)
16152 {
16153   unformat_input_t *input = vam->input;
16154   vl_api_one_add_del_locator_set_t *mp;
16155   u8 is_add = 1;
16156   u8 *locator_set_name = NULL;
16157   u8 locator_set_name_set = 0;
16158   vl_api_local_locator_t locator, *locators = 0;
16159   u32 sw_if_index, priority, weight;
16160   u32 data_len = 0;
16161
16162   int ret;
16163   /* Parse args required to build the message */
16164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16165     {
16166       if (unformat (input, "del"))
16167         {
16168           is_add = 0;
16169         }
16170       else if (unformat (input, "locator-set %s", &locator_set_name))
16171         {
16172           locator_set_name_set = 1;
16173         }
16174       else if (unformat (input, "sw_if_index %u p %u w %u",
16175                          &sw_if_index, &priority, &weight))
16176         {
16177           locator.sw_if_index = htonl (sw_if_index);
16178           locator.priority = priority;
16179           locator.weight = weight;
16180           vec_add1 (locators, locator);
16181         }
16182       else
16183         if (unformat
16184             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16185              &sw_if_index, &priority, &weight))
16186         {
16187           locator.sw_if_index = htonl (sw_if_index);
16188           locator.priority = priority;
16189           locator.weight = weight;
16190           vec_add1 (locators, locator);
16191         }
16192       else
16193         break;
16194     }
16195
16196   if (locator_set_name_set == 0)
16197     {
16198       errmsg ("missing locator-set name");
16199       vec_free (locators);
16200       return -99;
16201     }
16202
16203   if (vec_len (locator_set_name) > 64)
16204     {
16205       errmsg ("locator-set name too long");
16206       vec_free (locator_set_name);
16207       vec_free (locators);
16208       return -99;
16209     }
16210   vec_add1 (locator_set_name, 0);
16211
16212   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16213
16214   /* Construct the API message */
16215   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16216
16217   mp->is_add = is_add;
16218   clib_memcpy (mp->locator_set_name, locator_set_name,
16219                vec_len (locator_set_name));
16220   vec_free (locator_set_name);
16221
16222   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16223   if (locators)
16224     clib_memcpy (mp->locators, locators, data_len);
16225   vec_free (locators);
16226
16227   /* send it... */
16228   S (mp);
16229
16230   /* Wait for a reply... */
16231   W (ret);
16232   return ret;
16233 }
16234
16235 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16236
16237 static int
16238 api_one_add_del_locator (vat_main_t * vam)
16239 {
16240   unformat_input_t *input = vam->input;
16241   vl_api_one_add_del_locator_t *mp;
16242   u32 tmp_if_index = ~0;
16243   u32 sw_if_index = ~0;
16244   u8 sw_if_index_set = 0;
16245   u8 sw_if_index_if_name_set = 0;
16246   u32 priority = ~0;
16247   u8 priority_set = 0;
16248   u32 weight = ~0;
16249   u8 weight_set = 0;
16250   u8 is_add = 1;
16251   u8 *locator_set_name = NULL;
16252   u8 locator_set_name_set = 0;
16253   int ret;
16254
16255   /* Parse args required to build the message */
16256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16257     {
16258       if (unformat (input, "del"))
16259         {
16260           is_add = 0;
16261         }
16262       else if (unformat (input, "locator-set %s", &locator_set_name))
16263         {
16264           locator_set_name_set = 1;
16265         }
16266       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16267                          &tmp_if_index))
16268         {
16269           sw_if_index_if_name_set = 1;
16270           sw_if_index = tmp_if_index;
16271         }
16272       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16273         {
16274           sw_if_index_set = 1;
16275           sw_if_index = tmp_if_index;
16276         }
16277       else if (unformat (input, "p %d", &priority))
16278         {
16279           priority_set = 1;
16280         }
16281       else if (unformat (input, "w %d", &weight))
16282         {
16283           weight_set = 1;
16284         }
16285       else
16286         break;
16287     }
16288
16289   if (locator_set_name_set == 0)
16290     {
16291       errmsg ("missing locator-set name");
16292       return -99;
16293     }
16294
16295   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16296     {
16297       errmsg ("missing sw_if_index");
16298       vec_free (locator_set_name);
16299       return -99;
16300     }
16301
16302   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16303     {
16304       errmsg ("cannot use both params interface name and sw_if_index");
16305       vec_free (locator_set_name);
16306       return -99;
16307     }
16308
16309   if (priority_set == 0)
16310     {
16311       errmsg ("missing locator-set priority");
16312       vec_free (locator_set_name);
16313       return -99;
16314     }
16315
16316   if (weight_set == 0)
16317     {
16318       errmsg ("missing locator-set weight");
16319       vec_free (locator_set_name);
16320       return -99;
16321     }
16322
16323   if (vec_len (locator_set_name) > 64)
16324     {
16325       errmsg ("locator-set name too long");
16326       vec_free (locator_set_name);
16327       return -99;
16328     }
16329   vec_add1 (locator_set_name, 0);
16330
16331   /* Construct the API message */
16332   M (ONE_ADD_DEL_LOCATOR, mp);
16333
16334   mp->is_add = is_add;
16335   mp->sw_if_index = ntohl (sw_if_index);
16336   mp->priority = priority;
16337   mp->weight = weight;
16338   clib_memcpy (mp->locator_set_name, locator_set_name,
16339                vec_len (locator_set_name));
16340   vec_free (locator_set_name);
16341
16342   /* send it... */
16343   S (mp);
16344
16345   /* Wait for a reply... */
16346   W (ret);
16347   return ret;
16348 }
16349
16350 #define api_lisp_add_del_locator api_one_add_del_locator
16351
16352 uword
16353 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16354 {
16355   u32 *key_id = va_arg (*args, u32 *);
16356   u8 *s = 0;
16357
16358   if (unformat (input, "%s", &s))
16359     {
16360       if (!strcmp ((char *) s, "sha1"))
16361         key_id[0] = HMAC_SHA_1_96;
16362       else if (!strcmp ((char *) s, "sha256"))
16363         key_id[0] = HMAC_SHA_256_128;
16364       else
16365         {
16366           clib_warning ("invalid key_id: '%s'", s);
16367           key_id[0] = HMAC_NO_KEY;
16368         }
16369     }
16370   else
16371     return 0;
16372
16373   vec_free (s);
16374   return 1;
16375 }
16376
16377 static int
16378 api_one_add_del_local_eid (vat_main_t * vam)
16379 {
16380   unformat_input_t *input = vam->input;
16381   vl_api_one_add_del_local_eid_t *mp;
16382   u8 is_add = 1;
16383   u8 eid_set = 0;
16384   lisp_eid_vat_t _eid, *eid = &_eid;
16385   u8 *locator_set_name = 0;
16386   u8 locator_set_name_set = 0;
16387   u32 vni = 0;
16388   u16 key_id = 0;
16389   u8 *key = 0;
16390   int ret;
16391
16392   /* Parse args required to build the message */
16393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16394     {
16395       if (unformat (input, "del"))
16396         {
16397           is_add = 0;
16398         }
16399       else if (unformat (input, "vni %d", &vni))
16400         {
16401           ;
16402         }
16403       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16404         {
16405           eid_set = 1;
16406         }
16407       else if (unformat (input, "locator-set %s", &locator_set_name))
16408         {
16409           locator_set_name_set = 1;
16410         }
16411       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16412         ;
16413       else if (unformat (input, "secret-key %_%v%_", &key))
16414         ;
16415       else
16416         break;
16417     }
16418
16419   if (locator_set_name_set == 0)
16420     {
16421       errmsg ("missing locator-set name");
16422       return -99;
16423     }
16424
16425   if (0 == eid_set)
16426     {
16427       errmsg ("EID address not set!");
16428       vec_free (locator_set_name);
16429       return -99;
16430     }
16431
16432   if (key && (0 == key_id))
16433     {
16434       errmsg ("invalid key_id!");
16435       return -99;
16436     }
16437
16438   if (vec_len (key) > 64)
16439     {
16440       errmsg ("key too long");
16441       vec_free (key);
16442       return -99;
16443     }
16444
16445   if (vec_len (locator_set_name) > 64)
16446     {
16447       errmsg ("locator-set name too long");
16448       vec_free (locator_set_name);
16449       return -99;
16450     }
16451   vec_add1 (locator_set_name, 0);
16452
16453   /* Construct the API message */
16454   M (ONE_ADD_DEL_LOCAL_EID, mp);
16455
16456   mp->is_add = is_add;
16457   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16458   mp->eid_type = eid->type;
16459   mp->prefix_len = eid->len;
16460   mp->vni = clib_host_to_net_u32 (vni);
16461   mp->key_id = clib_host_to_net_u16 (key_id);
16462   clib_memcpy (mp->locator_set_name, locator_set_name,
16463                vec_len (locator_set_name));
16464   clib_memcpy (mp->key, key, vec_len (key));
16465
16466   vec_free (locator_set_name);
16467   vec_free (key);
16468
16469   /* send it... */
16470   S (mp);
16471
16472   /* Wait for a reply... */
16473   W (ret);
16474   return ret;
16475 }
16476
16477 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16478
16479 static int
16480 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16481 {
16482   u32 dp_table = 0, vni = 0;;
16483   unformat_input_t *input = vam->input;
16484   vl_api_gpe_add_del_fwd_entry_t *mp;
16485   u8 is_add = 1;
16486   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16487   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16488   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16489   u32 action = ~0, w;
16490   ip4_address_t rmt_rloc4, lcl_rloc4;
16491   ip6_address_t rmt_rloc6, lcl_rloc6;
16492   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16493   int ret;
16494
16495   memset (&rloc, 0, sizeof (rloc));
16496
16497   /* Parse args required to build the message */
16498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16499     {
16500       if (unformat (input, "del"))
16501         is_add = 0;
16502       else if (unformat (input, "add"))
16503         is_add = 1;
16504       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16505         {
16506           rmt_eid_set = 1;
16507         }
16508       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16509         {
16510           lcl_eid_set = 1;
16511         }
16512       else if (unformat (input, "vrf %d", &dp_table))
16513         ;
16514       else if (unformat (input, "bd %d", &dp_table))
16515         ;
16516       else if (unformat (input, "vni %d", &vni))
16517         ;
16518       else if (unformat (input, "w %d", &w))
16519         {
16520           if (!curr_rloc)
16521             {
16522               errmsg ("No RLOC configured for setting priority/weight!");
16523               return -99;
16524             }
16525           curr_rloc->weight = w;
16526         }
16527       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16528                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16529         {
16530           rloc.is_ip4 = 1;
16531
16532           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16533           rloc.weight = 0;
16534           vec_add1 (lcl_locs, rloc);
16535
16536           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16537           vec_add1 (rmt_locs, rloc);
16538           /* weight saved in rmt loc */
16539           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16540         }
16541       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16542                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16543         {
16544           rloc.is_ip4 = 0;
16545           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16546           rloc.weight = 0;
16547           vec_add1 (lcl_locs, rloc);
16548
16549           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16550           vec_add1 (rmt_locs, rloc);
16551           /* weight saved in rmt loc */
16552           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16553         }
16554       else if (unformat (input, "action %d", &action))
16555         {
16556           ;
16557         }
16558       else
16559         {
16560           clib_warning ("parse error '%U'", format_unformat_error, input);
16561           return -99;
16562         }
16563     }
16564
16565   if (!rmt_eid_set)
16566     {
16567       errmsg ("remote eid addresses not set");
16568       return -99;
16569     }
16570
16571   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16572     {
16573       errmsg ("eid types don't match");
16574       return -99;
16575     }
16576
16577   if (0 == rmt_locs && (u32) ~ 0 == action)
16578     {
16579       errmsg ("action not set for negative mapping");
16580       return -99;
16581     }
16582
16583   /* Construct the API message */
16584   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16585       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16586
16587   mp->is_add = is_add;
16588   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16589   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16590   mp->eid_type = rmt_eid->type;
16591   mp->dp_table = clib_host_to_net_u32 (dp_table);
16592   mp->vni = clib_host_to_net_u32 (vni);
16593   mp->rmt_len = rmt_eid->len;
16594   mp->lcl_len = lcl_eid->len;
16595   mp->action = action;
16596
16597   if (0 != rmt_locs && 0 != lcl_locs)
16598     {
16599       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16600       clib_memcpy (mp->locs, lcl_locs,
16601                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16602
16603       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16604       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16605                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16606     }
16607   vec_free (lcl_locs);
16608   vec_free (rmt_locs);
16609
16610   /* send it... */
16611   S (mp);
16612
16613   /* Wait for a reply... */
16614   W (ret);
16615   return ret;
16616 }
16617
16618 static int
16619 api_one_add_del_map_server (vat_main_t * vam)
16620 {
16621   unformat_input_t *input = vam->input;
16622   vl_api_one_add_del_map_server_t *mp;
16623   u8 is_add = 1;
16624   u8 ipv4_set = 0;
16625   u8 ipv6_set = 0;
16626   ip4_address_t ipv4;
16627   ip6_address_t ipv6;
16628   int ret;
16629
16630   /* Parse args required to build the message */
16631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16632     {
16633       if (unformat (input, "del"))
16634         {
16635           is_add = 0;
16636         }
16637       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16638         {
16639           ipv4_set = 1;
16640         }
16641       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16642         {
16643           ipv6_set = 1;
16644         }
16645       else
16646         break;
16647     }
16648
16649   if (ipv4_set && ipv6_set)
16650     {
16651       errmsg ("both eid v4 and v6 addresses set");
16652       return -99;
16653     }
16654
16655   if (!ipv4_set && !ipv6_set)
16656     {
16657       errmsg ("eid addresses not set");
16658       return -99;
16659     }
16660
16661   /* Construct the API message */
16662   M (ONE_ADD_DEL_MAP_SERVER, mp);
16663
16664   mp->is_add = is_add;
16665   if (ipv6_set)
16666     {
16667       mp->is_ipv6 = 1;
16668       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16669     }
16670   else
16671     {
16672       mp->is_ipv6 = 0;
16673       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16674     }
16675
16676   /* send it... */
16677   S (mp);
16678
16679   /* Wait for a reply... */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 #define api_lisp_add_del_map_server api_one_add_del_map_server
16685
16686 static int
16687 api_one_add_del_map_resolver (vat_main_t * vam)
16688 {
16689   unformat_input_t *input = vam->input;
16690   vl_api_one_add_del_map_resolver_t *mp;
16691   u8 is_add = 1;
16692   u8 ipv4_set = 0;
16693   u8 ipv6_set = 0;
16694   ip4_address_t ipv4;
16695   ip6_address_t ipv6;
16696   int ret;
16697
16698   /* Parse args required to build the message */
16699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (input, "del"))
16702         {
16703           is_add = 0;
16704         }
16705       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16706         {
16707           ipv4_set = 1;
16708         }
16709       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16710         {
16711           ipv6_set = 1;
16712         }
16713       else
16714         break;
16715     }
16716
16717   if (ipv4_set && ipv6_set)
16718     {
16719       errmsg ("both eid v4 and v6 addresses set");
16720       return -99;
16721     }
16722
16723   if (!ipv4_set && !ipv6_set)
16724     {
16725       errmsg ("eid addresses not set");
16726       return -99;
16727     }
16728
16729   /* Construct the API message */
16730   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16731
16732   mp->is_add = is_add;
16733   if (ipv6_set)
16734     {
16735       mp->is_ipv6 = 1;
16736       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16737     }
16738   else
16739     {
16740       mp->is_ipv6 = 0;
16741       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16742     }
16743
16744   /* send it... */
16745   S (mp);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16753
16754 static int
16755 api_lisp_gpe_enable_disable (vat_main_t * vam)
16756 {
16757   unformat_input_t *input = vam->input;
16758   vl_api_gpe_enable_disable_t *mp;
16759   u8 is_set = 0;
16760   u8 is_en = 1;
16761   int ret;
16762
16763   /* Parse args required to build the message */
16764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16765     {
16766       if (unformat (input, "enable"))
16767         {
16768           is_set = 1;
16769           is_en = 1;
16770         }
16771       else if (unformat (input, "disable"))
16772         {
16773           is_set = 1;
16774           is_en = 0;
16775         }
16776       else
16777         break;
16778     }
16779
16780   if (is_set == 0)
16781     {
16782       errmsg ("Value not set");
16783       return -99;
16784     }
16785
16786   /* Construct the API message */
16787   M (GPE_ENABLE_DISABLE, mp);
16788
16789   mp->is_en = is_en;
16790
16791   /* send it... */
16792   S (mp);
16793
16794   /* Wait for a reply... */
16795   W (ret);
16796   return ret;
16797 }
16798
16799 static int
16800 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16801 {
16802   unformat_input_t *input = vam->input;
16803   vl_api_one_rloc_probe_enable_disable_t *mp;
16804   u8 is_set = 0;
16805   u8 is_en = 0;
16806   int ret;
16807
16808   /* Parse args required to build the message */
16809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16810     {
16811       if (unformat (input, "enable"))
16812         {
16813           is_set = 1;
16814           is_en = 1;
16815         }
16816       else if (unformat (input, "disable"))
16817         is_set = 1;
16818       else
16819         break;
16820     }
16821
16822   if (!is_set)
16823     {
16824       errmsg ("Value not set");
16825       return -99;
16826     }
16827
16828   /* Construct the API message */
16829   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16830
16831   mp->is_enabled = is_en;
16832
16833   /* send it... */
16834   S (mp);
16835
16836   /* Wait for a reply... */
16837   W (ret);
16838   return ret;
16839 }
16840
16841 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16842
16843 static int
16844 api_one_map_register_enable_disable (vat_main_t * vam)
16845 {
16846   unformat_input_t *input = vam->input;
16847   vl_api_one_map_register_enable_disable_t *mp;
16848   u8 is_set = 0;
16849   u8 is_en = 0;
16850   int ret;
16851
16852   /* Parse args required to build the message */
16853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16854     {
16855       if (unformat (input, "enable"))
16856         {
16857           is_set = 1;
16858           is_en = 1;
16859         }
16860       else if (unformat (input, "disable"))
16861         is_set = 1;
16862       else
16863         break;
16864     }
16865
16866   if (!is_set)
16867     {
16868       errmsg ("Value not set");
16869       return -99;
16870     }
16871
16872   /* Construct the API message */
16873   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16874
16875   mp->is_enabled = is_en;
16876
16877   /* send it... */
16878   S (mp);
16879
16880   /* Wait for a reply... */
16881   W (ret);
16882   return ret;
16883 }
16884
16885 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16886
16887 static int
16888 api_one_enable_disable (vat_main_t * vam)
16889 {
16890   unformat_input_t *input = vam->input;
16891   vl_api_one_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         {
16906           is_set = 1;
16907         }
16908       else
16909         break;
16910     }
16911
16912   if (!is_set)
16913     {
16914       errmsg ("Value not set");
16915       return -99;
16916     }
16917
16918   /* Construct the API message */
16919   M (ONE_ENABLE_DISABLE, mp);
16920
16921   mp->is_en = is_en;
16922
16923   /* send it... */
16924   S (mp);
16925
16926   /* Wait for a reply... */
16927   W (ret);
16928   return ret;
16929 }
16930
16931 #define api_lisp_enable_disable api_one_enable_disable
16932
16933 static int
16934 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16935 {
16936   unformat_input_t *input = vam->input;
16937   vl_api_one_enable_disable_xtr_mode_t *mp;
16938   u8 is_set = 0;
16939   u8 is_en = 0;
16940   int ret;
16941
16942   /* Parse args required to build the message */
16943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16944     {
16945       if (unformat (input, "enable"))
16946         {
16947           is_set = 1;
16948           is_en = 1;
16949         }
16950       else if (unformat (input, "disable"))
16951         {
16952           is_set = 1;
16953         }
16954       else
16955         break;
16956     }
16957
16958   if (!is_set)
16959     {
16960       errmsg ("Value not set");
16961       return -99;
16962     }
16963
16964   /* Construct the API message */
16965   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16966
16967   mp->is_en = is_en;
16968
16969   /* send it... */
16970   S (mp);
16971
16972   /* Wait for a reply... */
16973   W (ret);
16974   return ret;
16975 }
16976
16977 static int
16978 api_one_show_xtr_mode (vat_main_t * vam)
16979 {
16980   vl_api_one_show_xtr_mode_t *mp;
16981   int ret;
16982
16983   /* Construct the API message */
16984   M (ONE_SHOW_XTR_MODE, mp);
16985
16986   /* send it... */
16987   S (mp);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 static int
16995 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16996 {
16997   unformat_input_t *input = vam->input;
16998   vl_api_one_enable_disable_pitr_mode_t *mp;
16999   u8 is_set = 0;
17000   u8 is_en = 0;
17001   int ret;
17002
17003   /* Parse args required to build the message */
17004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17005     {
17006       if (unformat (input, "enable"))
17007         {
17008           is_set = 1;
17009           is_en = 1;
17010         }
17011       else if (unformat (input, "disable"))
17012         {
17013           is_set = 1;
17014         }
17015       else
17016         break;
17017     }
17018
17019   if (!is_set)
17020     {
17021       errmsg ("Value not set");
17022       return -99;
17023     }
17024
17025   /* Construct the API message */
17026   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17027
17028   mp->is_en = is_en;
17029
17030   /* send it... */
17031   S (mp);
17032
17033   /* Wait for a reply... */
17034   W (ret);
17035   return ret;
17036 }
17037
17038 static int
17039 api_one_show_pitr_mode (vat_main_t * vam)
17040 {
17041   vl_api_one_show_pitr_mode_t *mp;
17042   int ret;
17043
17044   /* Construct the API message */
17045   M (ONE_SHOW_PITR_MODE, mp);
17046
17047   /* send it... */
17048   S (mp);
17049
17050   /* Wait for a reply... */
17051   W (ret);
17052   return ret;
17053 }
17054
17055 static int
17056 api_one_enable_disable_petr_mode (vat_main_t * vam)
17057 {
17058   unformat_input_t *input = vam->input;
17059   vl_api_one_enable_disable_petr_mode_t *mp;
17060   u8 is_set = 0;
17061   u8 is_en = 0;
17062   int ret;
17063
17064   /* Parse args required to build the message */
17065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17066     {
17067       if (unformat (input, "enable"))
17068         {
17069           is_set = 1;
17070           is_en = 1;
17071         }
17072       else if (unformat (input, "disable"))
17073         {
17074           is_set = 1;
17075         }
17076       else
17077         break;
17078     }
17079
17080   if (!is_set)
17081     {
17082       errmsg ("Value not set");
17083       return -99;
17084     }
17085
17086   /* Construct the API message */
17087   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17088
17089   mp->is_en = is_en;
17090
17091   /* send it... */
17092   S (mp);
17093
17094   /* Wait for a reply... */
17095   W (ret);
17096   return ret;
17097 }
17098
17099 static int
17100 api_one_show_petr_mode (vat_main_t * vam)
17101 {
17102   vl_api_one_show_petr_mode_t *mp;
17103   int ret;
17104
17105   /* Construct the API message */
17106   M (ONE_SHOW_PETR_MODE, mp);
17107
17108   /* send it... */
17109   S (mp);
17110
17111   /* Wait for a reply... */
17112   W (ret);
17113   return ret;
17114 }
17115
17116 static int
17117 api_show_one_map_register_state (vat_main_t * vam)
17118 {
17119   vl_api_show_one_map_register_state_t *mp;
17120   int ret;
17121
17122   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17123
17124   /* send */
17125   S (mp);
17126
17127   /* wait for reply */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 #define api_show_lisp_map_register_state api_show_one_map_register_state
17133
17134 static int
17135 api_show_one_rloc_probe_state (vat_main_t * vam)
17136 {
17137   vl_api_show_one_rloc_probe_state_t *mp;
17138   int ret;
17139
17140   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17141
17142   /* send */
17143   S (mp);
17144
17145   /* wait for reply */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17151
17152 static int
17153 api_one_add_del_ndp_entry (vat_main_t * vam)
17154 {
17155   vl_api_one_add_del_ndp_entry_t *mp;
17156   unformat_input_t *input = vam->input;
17157   u8 is_add = 1;
17158   u8 mac_set = 0;
17159   u8 bd_set = 0;
17160   u8 ip_set = 0;
17161   u8 mac[6] = { 0, };
17162   u8 ip6[16] = { 0, };
17163   u32 bd = ~0;
17164   int ret;
17165
17166   /* Parse args required to build the message */
17167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17168     {
17169       if (unformat (input, "del"))
17170         is_add = 0;
17171       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17172         mac_set = 1;
17173       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17174         ip_set = 1;
17175       else if (unformat (input, "bd %d", &bd))
17176         bd_set = 1;
17177       else
17178         {
17179           errmsg ("parse error '%U'", format_unformat_error, input);
17180           return -99;
17181         }
17182     }
17183
17184   if (!bd_set || !ip_set || (!mac_set && is_add))
17185     {
17186       errmsg ("Missing BD, IP or MAC!");
17187       return -99;
17188     }
17189
17190   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17191   mp->is_add = is_add;
17192   clib_memcpy (mp->mac, mac, 6);
17193   mp->bd = clib_host_to_net_u32 (bd);
17194   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17195
17196   /* send */
17197   S (mp);
17198
17199   /* wait for reply */
17200   W (ret);
17201   return ret;
17202 }
17203
17204 static int
17205 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17206 {
17207   vl_api_one_add_del_l2_arp_entry_t *mp;
17208   unformat_input_t *input = vam->input;
17209   u8 is_add = 1;
17210   u8 mac_set = 0;
17211   u8 bd_set = 0;
17212   u8 ip_set = 0;
17213   u8 mac[6] = { 0, };
17214   u32 ip4 = 0, bd = ~0;
17215   int ret;
17216
17217   /* Parse args required to build the message */
17218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17219     {
17220       if (unformat (input, "del"))
17221         is_add = 0;
17222       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17223         mac_set = 1;
17224       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17225         ip_set = 1;
17226       else if (unformat (input, "bd %d", &bd))
17227         bd_set = 1;
17228       else
17229         {
17230           errmsg ("parse error '%U'", format_unformat_error, input);
17231           return -99;
17232         }
17233     }
17234
17235   if (!bd_set || !ip_set || (!mac_set && is_add))
17236     {
17237       errmsg ("Missing BD, IP or MAC!");
17238       return -99;
17239     }
17240
17241   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17242   mp->is_add = is_add;
17243   clib_memcpy (mp->mac, mac, 6);
17244   mp->bd = clib_host_to_net_u32 (bd);
17245   mp->ip4 = ip4;
17246
17247   /* send */
17248   S (mp);
17249
17250   /* wait for reply */
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static int
17256 api_one_ndp_bd_get (vat_main_t * vam)
17257 {
17258   vl_api_one_ndp_bd_get_t *mp;
17259   int ret;
17260
17261   M (ONE_NDP_BD_GET, mp);
17262
17263   /* send */
17264   S (mp);
17265
17266   /* wait for reply */
17267   W (ret);
17268   return ret;
17269 }
17270
17271 static int
17272 api_one_ndp_entries_get (vat_main_t * vam)
17273 {
17274   vl_api_one_ndp_entries_get_t *mp;
17275   unformat_input_t *input = vam->input;
17276   u8 bd_set = 0;
17277   u32 bd = ~0;
17278   int ret;
17279
17280   /* Parse args required to build the message */
17281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17282     {
17283       if (unformat (input, "bd %d", &bd))
17284         bd_set = 1;
17285       else
17286         {
17287           errmsg ("parse error '%U'", format_unformat_error, input);
17288           return -99;
17289         }
17290     }
17291
17292   if (!bd_set)
17293     {
17294       errmsg ("Expected bridge domain!");
17295       return -99;
17296     }
17297
17298   M (ONE_NDP_ENTRIES_GET, mp);
17299   mp->bd = clib_host_to_net_u32 (bd);
17300
17301   /* send */
17302   S (mp);
17303
17304   /* wait for reply */
17305   W (ret);
17306   return ret;
17307 }
17308
17309 static int
17310 api_one_l2_arp_bd_get (vat_main_t * vam)
17311 {
17312   vl_api_one_l2_arp_bd_get_t *mp;
17313   int ret;
17314
17315   M (ONE_L2_ARP_BD_GET, mp);
17316
17317   /* send */
17318   S (mp);
17319
17320   /* wait for reply */
17321   W (ret);
17322   return ret;
17323 }
17324
17325 static int
17326 api_one_l2_arp_entries_get (vat_main_t * vam)
17327 {
17328   vl_api_one_l2_arp_entries_get_t *mp;
17329   unformat_input_t *input = vam->input;
17330   u8 bd_set = 0;
17331   u32 bd = ~0;
17332   int ret;
17333
17334   /* Parse args required to build the message */
17335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17336     {
17337       if (unformat (input, "bd %d", &bd))
17338         bd_set = 1;
17339       else
17340         {
17341           errmsg ("parse error '%U'", format_unformat_error, input);
17342           return -99;
17343         }
17344     }
17345
17346   if (!bd_set)
17347     {
17348       errmsg ("Expected bridge domain!");
17349       return -99;
17350     }
17351
17352   M (ONE_L2_ARP_ENTRIES_GET, mp);
17353   mp->bd = clib_host_to_net_u32 (bd);
17354
17355   /* send */
17356   S (mp);
17357
17358   /* wait for reply */
17359   W (ret);
17360   return ret;
17361 }
17362
17363 static int
17364 api_one_stats_enable_disable (vat_main_t * vam)
17365 {
17366   vl_api_one_stats_enable_disable_t *mp;
17367   unformat_input_t *input = vam->input;
17368   u8 is_set = 0;
17369   u8 is_en = 0;
17370   int ret;
17371
17372   /* Parse args required to build the message */
17373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17374     {
17375       if (unformat (input, "enable"))
17376         {
17377           is_set = 1;
17378           is_en = 1;
17379         }
17380       else if (unformat (input, "disable"))
17381         {
17382           is_set = 1;
17383         }
17384       else
17385         break;
17386     }
17387
17388   if (!is_set)
17389     {
17390       errmsg ("Value not set");
17391       return -99;
17392     }
17393
17394   M (ONE_STATS_ENABLE_DISABLE, mp);
17395   mp->is_en = is_en;
17396
17397   /* send */
17398   S (mp);
17399
17400   /* wait for reply */
17401   W (ret);
17402   return ret;
17403 }
17404
17405 static int
17406 api_show_one_stats_enable_disable (vat_main_t * vam)
17407 {
17408   vl_api_show_one_stats_enable_disable_t *mp;
17409   int ret;
17410
17411   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17412
17413   /* send */
17414   S (mp);
17415
17416   /* wait for reply */
17417   W (ret);
17418   return ret;
17419 }
17420
17421 static int
17422 api_show_one_map_request_mode (vat_main_t * vam)
17423 {
17424   vl_api_show_one_map_request_mode_t *mp;
17425   int ret;
17426
17427   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17428
17429   /* send */
17430   S (mp);
17431
17432   /* wait for reply */
17433   W (ret);
17434   return ret;
17435 }
17436
17437 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17438
17439 static int
17440 api_one_map_request_mode (vat_main_t * vam)
17441 {
17442   unformat_input_t *input = vam->input;
17443   vl_api_one_map_request_mode_t *mp;
17444   u8 mode = 0;
17445   int ret;
17446
17447   /* Parse args required to build the message */
17448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (input, "dst-only"))
17451         mode = 0;
17452       else if (unformat (input, "src-dst"))
17453         mode = 1;
17454       else
17455         {
17456           errmsg ("parse error '%U'", format_unformat_error, input);
17457           return -99;
17458         }
17459     }
17460
17461   M (ONE_MAP_REQUEST_MODE, mp);
17462
17463   mp->mode = mode;
17464
17465   /* send */
17466   S (mp);
17467
17468   /* wait for reply */
17469   W (ret);
17470   return ret;
17471 }
17472
17473 #define api_lisp_map_request_mode api_one_map_request_mode
17474
17475 /**
17476  * Enable/disable ONE proxy ITR.
17477  *
17478  * @param vam vpp API test context
17479  * @return return code
17480  */
17481 static int
17482 api_one_pitr_set_locator_set (vat_main_t * vam)
17483 {
17484   u8 ls_name_set = 0;
17485   unformat_input_t *input = vam->input;
17486   vl_api_one_pitr_set_locator_set_t *mp;
17487   u8 is_add = 1;
17488   u8 *ls_name = 0;
17489   int ret;
17490
17491   /* Parse args required to build the message */
17492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (input, "del"))
17495         is_add = 0;
17496       else if (unformat (input, "locator-set %s", &ls_name))
17497         ls_name_set = 1;
17498       else
17499         {
17500           errmsg ("parse error '%U'", format_unformat_error, input);
17501           return -99;
17502         }
17503     }
17504
17505   if (!ls_name_set)
17506     {
17507       errmsg ("locator-set name not set!");
17508       return -99;
17509     }
17510
17511   M (ONE_PITR_SET_LOCATOR_SET, mp);
17512
17513   mp->is_add = is_add;
17514   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17515   vec_free (ls_name);
17516
17517   /* send */
17518   S (mp);
17519
17520   /* wait for reply */
17521   W (ret);
17522   return ret;
17523 }
17524
17525 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17526
17527 static int
17528 api_one_nsh_set_locator_set (vat_main_t * vam)
17529 {
17530   u8 ls_name_set = 0;
17531   unformat_input_t *input = vam->input;
17532   vl_api_one_nsh_set_locator_set_t *mp;
17533   u8 is_add = 1;
17534   u8 *ls_name = 0;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "del"))
17541         is_add = 0;
17542       else if (unformat (input, "ls %s", &ls_name))
17543         ls_name_set = 1;
17544       else
17545         {
17546           errmsg ("parse error '%U'", format_unformat_error, input);
17547           return -99;
17548         }
17549     }
17550
17551   if (!ls_name_set && is_add)
17552     {
17553       errmsg ("locator-set name not set!");
17554       return -99;
17555     }
17556
17557   M (ONE_NSH_SET_LOCATOR_SET, mp);
17558
17559   mp->is_add = is_add;
17560   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17561   vec_free (ls_name);
17562
17563   /* send */
17564   S (mp);
17565
17566   /* wait for reply */
17567   W (ret);
17568   return ret;
17569 }
17570
17571 static int
17572 api_show_one_pitr (vat_main_t * vam)
17573 {
17574   vl_api_show_one_pitr_t *mp;
17575   int ret;
17576
17577   if (!vam->json_output)
17578     {
17579       print (vam->ofp, "%=20s", "lisp status:");
17580     }
17581
17582   M (SHOW_ONE_PITR, mp);
17583   /* send it... */
17584   S (mp);
17585
17586   /* Wait for a reply... */
17587   W (ret);
17588   return ret;
17589 }
17590
17591 #define api_show_lisp_pitr api_show_one_pitr
17592
17593 static int
17594 api_one_use_petr (vat_main_t * vam)
17595 {
17596   unformat_input_t *input = vam->input;
17597   vl_api_one_use_petr_t *mp;
17598   u8 is_add = 0;
17599   ip_address_t ip;
17600   int ret;
17601
17602   memset (&ip, 0, sizeof (ip));
17603
17604   /* Parse args required to build the message */
17605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17606     {
17607       if (unformat (input, "disable"))
17608         is_add = 0;
17609       else
17610         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17611         {
17612           is_add = 1;
17613           ip_addr_version (&ip) = IP4;
17614         }
17615       else
17616         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17617         {
17618           is_add = 1;
17619           ip_addr_version (&ip) = IP6;
17620         }
17621       else
17622         {
17623           errmsg ("parse error '%U'", format_unformat_error, input);
17624           return -99;
17625         }
17626     }
17627
17628   M (ONE_USE_PETR, mp);
17629
17630   mp->is_add = is_add;
17631   if (is_add)
17632     {
17633       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17634       if (mp->is_ip4)
17635         clib_memcpy (mp->address, &ip, 4);
17636       else
17637         clib_memcpy (mp->address, &ip, 16);
17638     }
17639
17640   /* send */
17641   S (mp);
17642
17643   /* wait for reply */
17644   W (ret);
17645   return ret;
17646 }
17647
17648 #define api_lisp_use_petr api_one_use_petr
17649
17650 static int
17651 api_show_one_nsh_mapping (vat_main_t * vam)
17652 {
17653   vl_api_show_one_use_petr_t *mp;
17654   int ret;
17655
17656   if (!vam->json_output)
17657     {
17658       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17659     }
17660
17661   M (SHOW_ONE_NSH_MAPPING, mp);
17662   /* send it... */
17663   S (mp);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 static int
17671 api_show_one_use_petr (vat_main_t * vam)
17672 {
17673   vl_api_show_one_use_petr_t *mp;
17674   int ret;
17675
17676   if (!vam->json_output)
17677     {
17678       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17679     }
17680
17681   M (SHOW_ONE_USE_PETR, mp);
17682   /* send it... */
17683   S (mp);
17684
17685   /* Wait for a reply... */
17686   W (ret);
17687   return ret;
17688 }
17689
17690 #define api_show_lisp_use_petr api_show_one_use_petr
17691
17692 /**
17693  * Add/delete mapping between vni and vrf
17694  */
17695 static int
17696 api_one_eid_table_add_del_map (vat_main_t * vam)
17697 {
17698   unformat_input_t *input = vam->input;
17699   vl_api_one_eid_table_add_del_map_t *mp;
17700   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17701   u32 vni, vrf, bd_index;
17702   int ret;
17703
17704   /* Parse args required to build the message */
17705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17706     {
17707       if (unformat (input, "del"))
17708         is_add = 0;
17709       else if (unformat (input, "vrf %d", &vrf))
17710         vrf_set = 1;
17711       else if (unformat (input, "bd_index %d", &bd_index))
17712         bd_index_set = 1;
17713       else if (unformat (input, "vni %d", &vni))
17714         vni_set = 1;
17715       else
17716         break;
17717     }
17718
17719   if (!vni_set || (!vrf_set && !bd_index_set))
17720     {
17721       errmsg ("missing arguments!");
17722       return -99;
17723     }
17724
17725   if (vrf_set && bd_index_set)
17726     {
17727       errmsg ("error: both vrf and bd entered!");
17728       return -99;
17729     }
17730
17731   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17732
17733   mp->is_add = is_add;
17734   mp->vni = htonl (vni);
17735   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17736   mp->is_l2 = bd_index_set;
17737
17738   /* send */
17739   S (mp);
17740
17741   /* wait for reply */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17747
17748 uword
17749 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17750 {
17751   u32 *action = va_arg (*args, u32 *);
17752   u8 *s = 0;
17753
17754   if (unformat (input, "%s", &s))
17755     {
17756       if (!strcmp ((char *) s, "no-action"))
17757         action[0] = 0;
17758       else if (!strcmp ((char *) s, "natively-forward"))
17759         action[0] = 1;
17760       else if (!strcmp ((char *) s, "send-map-request"))
17761         action[0] = 2;
17762       else if (!strcmp ((char *) s, "drop"))
17763         action[0] = 3;
17764       else
17765         {
17766           clib_warning ("invalid action: '%s'", s);
17767           action[0] = 3;
17768         }
17769     }
17770   else
17771     return 0;
17772
17773   vec_free (s);
17774   return 1;
17775 }
17776
17777 /**
17778  * Add/del remote mapping to/from ONE control plane
17779  *
17780  * @param vam vpp API test context
17781  * @return return code
17782  */
17783 static int
17784 api_one_add_del_remote_mapping (vat_main_t * vam)
17785 {
17786   unformat_input_t *input = vam->input;
17787   vl_api_one_add_del_remote_mapping_t *mp;
17788   u32 vni = 0;
17789   lisp_eid_vat_t _eid, *eid = &_eid;
17790   lisp_eid_vat_t _seid, *seid = &_seid;
17791   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17792   u32 action = ~0, p, w, data_len;
17793   ip4_address_t rloc4;
17794   ip6_address_t rloc6;
17795   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17796   int ret;
17797
17798   memset (&rloc, 0, sizeof (rloc));
17799
17800   /* Parse args required to build the message */
17801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17802     {
17803       if (unformat (input, "del-all"))
17804         {
17805           del_all = 1;
17806         }
17807       else if (unformat (input, "del"))
17808         {
17809           is_add = 0;
17810         }
17811       else if (unformat (input, "add"))
17812         {
17813           is_add = 1;
17814         }
17815       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17816         {
17817           eid_set = 1;
17818         }
17819       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17820         {
17821           seid_set = 1;
17822         }
17823       else if (unformat (input, "vni %d", &vni))
17824         {
17825           ;
17826         }
17827       else if (unformat (input, "p %d w %d", &p, &w))
17828         {
17829           if (!curr_rloc)
17830             {
17831               errmsg ("No RLOC configured for setting priority/weight!");
17832               return -99;
17833             }
17834           curr_rloc->priority = p;
17835           curr_rloc->weight = w;
17836         }
17837       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17838         {
17839           rloc.is_ip4 = 1;
17840           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17841           vec_add1 (rlocs, rloc);
17842           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17843         }
17844       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17845         {
17846           rloc.is_ip4 = 0;
17847           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17848           vec_add1 (rlocs, rloc);
17849           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17850         }
17851       else if (unformat (input, "action %U",
17852                          unformat_negative_mapping_action, &action))
17853         {
17854           ;
17855         }
17856       else
17857         {
17858           clib_warning ("parse error '%U'", format_unformat_error, input);
17859           return -99;
17860         }
17861     }
17862
17863   if (0 == eid_set)
17864     {
17865       errmsg ("missing params!");
17866       return -99;
17867     }
17868
17869   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17870     {
17871       errmsg ("no action set for negative map-reply!");
17872       return -99;
17873     }
17874
17875   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17876
17877   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17878   mp->is_add = is_add;
17879   mp->vni = htonl (vni);
17880   mp->action = (u8) action;
17881   mp->is_src_dst = seid_set;
17882   mp->eid_len = eid->len;
17883   mp->seid_len = seid->len;
17884   mp->del_all = del_all;
17885   mp->eid_type = eid->type;
17886   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17887   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17888
17889   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17890   clib_memcpy (mp->rlocs, rlocs, data_len);
17891   vec_free (rlocs);
17892
17893   /* send it... */
17894   S (mp);
17895
17896   /* Wait for a reply... */
17897   W (ret);
17898   return ret;
17899 }
17900
17901 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17902
17903 /**
17904  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17905  * forwarding entries in data-plane accordingly.
17906  *
17907  * @param vam vpp API test context
17908  * @return return code
17909  */
17910 static int
17911 api_one_add_del_adjacency (vat_main_t * vam)
17912 {
17913   unformat_input_t *input = vam->input;
17914   vl_api_one_add_del_adjacency_t *mp;
17915   u32 vni = 0;
17916   ip4_address_t leid4, reid4;
17917   ip6_address_t leid6, reid6;
17918   u8 reid_mac[6] = { 0 };
17919   u8 leid_mac[6] = { 0 };
17920   u8 reid_type, leid_type;
17921   u32 leid_len = 0, reid_len = 0, len;
17922   u8 is_add = 1;
17923   int ret;
17924
17925   leid_type = reid_type = (u8) ~ 0;
17926
17927   /* Parse args required to build the message */
17928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17929     {
17930       if (unformat (input, "del"))
17931         {
17932           is_add = 0;
17933         }
17934       else if (unformat (input, "add"))
17935         {
17936           is_add = 1;
17937         }
17938       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17939                          &reid4, &len))
17940         {
17941           reid_type = 0;        /* ipv4 */
17942           reid_len = len;
17943         }
17944       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17945                          &reid6, &len))
17946         {
17947           reid_type = 1;        /* ipv6 */
17948           reid_len = len;
17949         }
17950       else if (unformat (input, "reid %U", unformat_ethernet_address,
17951                          reid_mac))
17952         {
17953           reid_type = 2;        /* mac */
17954         }
17955       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17956                          &leid4, &len))
17957         {
17958           leid_type = 0;        /* ipv4 */
17959           leid_len = len;
17960         }
17961       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17962                          &leid6, &len))
17963         {
17964           leid_type = 1;        /* ipv6 */
17965           leid_len = len;
17966         }
17967       else if (unformat (input, "leid %U", unformat_ethernet_address,
17968                          leid_mac))
17969         {
17970           leid_type = 2;        /* mac */
17971         }
17972       else if (unformat (input, "vni %d", &vni))
17973         {
17974           ;
17975         }
17976       else
17977         {
17978           errmsg ("parse error '%U'", format_unformat_error, input);
17979           return -99;
17980         }
17981     }
17982
17983   if ((u8) ~ 0 == reid_type)
17984     {
17985       errmsg ("missing params!");
17986       return -99;
17987     }
17988
17989   if (leid_type != reid_type)
17990     {
17991       errmsg ("remote and local EIDs are of different types!");
17992       return -99;
17993     }
17994
17995   M (ONE_ADD_DEL_ADJACENCY, mp);
17996   mp->is_add = is_add;
17997   mp->vni = htonl (vni);
17998   mp->leid_len = leid_len;
17999   mp->reid_len = reid_len;
18000   mp->eid_type = reid_type;
18001
18002   switch (mp->eid_type)
18003     {
18004     case 0:
18005       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18006       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18007       break;
18008     case 1:
18009       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18010       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18011       break;
18012     case 2:
18013       clib_memcpy (mp->leid, leid_mac, 6);
18014       clib_memcpy (mp->reid, reid_mac, 6);
18015       break;
18016     default:
18017       errmsg ("unknown EID type %d!", mp->eid_type);
18018       return 0;
18019     }
18020
18021   /* send it... */
18022   S (mp);
18023
18024   /* Wait for a reply... */
18025   W (ret);
18026   return ret;
18027 }
18028
18029 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18030
18031 uword
18032 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18033 {
18034   u32 *mode = va_arg (*args, u32 *);
18035
18036   if (unformat (input, "lisp"))
18037     *mode = 0;
18038   else if (unformat (input, "vxlan"))
18039     *mode = 1;
18040   else
18041     return 0;
18042
18043   return 1;
18044 }
18045
18046 static int
18047 api_gpe_get_encap_mode (vat_main_t * vam)
18048 {
18049   vl_api_gpe_get_encap_mode_t *mp;
18050   int ret;
18051
18052   /* Construct the API message */
18053   M (GPE_GET_ENCAP_MODE, mp);
18054
18055   /* send it... */
18056   S (mp);
18057
18058   /* Wait for a reply... */
18059   W (ret);
18060   return ret;
18061 }
18062
18063 static int
18064 api_gpe_set_encap_mode (vat_main_t * vam)
18065 {
18066   unformat_input_t *input = vam->input;
18067   vl_api_gpe_set_encap_mode_t *mp;
18068   int ret;
18069   u32 mode = 0;
18070
18071   /* Parse args required to build the message */
18072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18073     {
18074       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18075         ;
18076       else
18077         break;
18078     }
18079
18080   /* Construct the API message */
18081   M (GPE_SET_ENCAP_MODE, mp);
18082
18083   mp->mode = mode;
18084
18085   /* send it... */
18086   S (mp);
18087
18088   /* Wait for a reply... */
18089   W (ret);
18090   return ret;
18091 }
18092
18093 static int
18094 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18095 {
18096   unformat_input_t *input = vam->input;
18097   vl_api_gpe_add_del_iface_t *mp;
18098   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18099   u32 dp_table = 0, vni = 0;
18100   int ret;
18101
18102   /* Parse args required to build the message */
18103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18104     {
18105       if (unformat (input, "up"))
18106         {
18107           action_set = 1;
18108           is_add = 1;
18109         }
18110       else if (unformat (input, "down"))
18111         {
18112           action_set = 1;
18113           is_add = 0;
18114         }
18115       else if (unformat (input, "table_id %d", &dp_table))
18116         {
18117           dp_table_set = 1;
18118         }
18119       else if (unformat (input, "bd_id %d", &dp_table))
18120         {
18121           dp_table_set = 1;
18122           is_l2 = 1;
18123         }
18124       else if (unformat (input, "vni %d", &vni))
18125         {
18126           vni_set = 1;
18127         }
18128       else
18129         break;
18130     }
18131
18132   if (action_set == 0)
18133     {
18134       errmsg ("Action not set");
18135       return -99;
18136     }
18137   if (dp_table_set == 0 || vni_set == 0)
18138     {
18139       errmsg ("vni and dp_table must be set");
18140       return -99;
18141     }
18142
18143   /* Construct the API message */
18144   M (GPE_ADD_DEL_IFACE, mp);
18145
18146   mp->is_add = is_add;
18147   mp->dp_table = clib_host_to_net_u32 (dp_table);
18148   mp->is_l2 = is_l2;
18149   mp->vni = clib_host_to_net_u32 (vni);
18150
18151   /* send it... */
18152   S (mp);
18153
18154   /* Wait for a reply... */
18155   W (ret);
18156   return ret;
18157 }
18158
18159 static int
18160 api_one_map_register_fallback_threshold (vat_main_t * vam)
18161 {
18162   unformat_input_t *input = vam->input;
18163   vl_api_one_map_register_fallback_threshold_t *mp;
18164   u32 value = 0;
18165   u8 is_set = 0;
18166   int ret;
18167
18168   /* Parse args required to build the message */
18169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18170     {
18171       if (unformat (input, "%u", &value))
18172         is_set = 1;
18173       else
18174         {
18175           clib_warning ("parse error '%U'", format_unformat_error, input);
18176           return -99;
18177         }
18178     }
18179
18180   if (!is_set)
18181     {
18182       errmsg ("fallback threshold value is missing!");
18183       return -99;
18184     }
18185
18186   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18187   mp->value = clib_host_to_net_u32 (value);
18188
18189   /* send it... */
18190   S (mp);
18191
18192   /* Wait for a reply... */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18199 {
18200   vl_api_show_one_map_register_fallback_threshold_t *mp;
18201   int ret;
18202
18203   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18204
18205   /* send it... */
18206   S (mp);
18207
18208   /* Wait for a reply... */
18209   W (ret);
18210   return ret;
18211 }
18212
18213 uword
18214 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18215 {
18216   u32 *proto = va_arg (*args, u32 *);
18217
18218   if (unformat (input, "udp"))
18219     *proto = 1;
18220   else if (unformat (input, "api"))
18221     *proto = 2;
18222   else
18223     return 0;
18224
18225   return 1;
18226 }
18227
18228 static int
18229 api_one_set_transport_protocol (vat_main_t * vam)
18230 {
18231   unformat_input_t *input = vam->input;
18232   vl_api_one_set_transport_protocol_t *mp;
18233   u8 is_set = 0;
18234   u32 protocol = 0;
18235   int ret;
18236
18237   /* Parse args required to build the message */
18238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18239     {
18240       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18241         is_set = 1;
18242       else
18243         {
18244           clib_warning ("parse error '%U'", format_unformat_error, input);
18245           return -99;
18246         }
18247     }
18248
18249   if (!is_set)
18250     {
18251       errmsg ("Transport protocol missing!");
18252       return -99;
18253     }
18254
18255   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18256   mp->protocol = (u8) protocol;
18257
18258   /* send it... */
18259   S (mp);
18260
18261   /* Wait for a reply... */
18262   W (ret);
18263   return ret;
18264 }
18265
18266 static int
18267 api_one_get_transport_protocol (vat_main_t * vam)
18268 {
18269   vl_api_one_get_transport_protocol_t *mp;
18270   int ret;
18271
18272   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18273
18274   /* send it... */
18275   S (mp);
18276
18277   /* Wait for a reply... */
18278   W (ret);
18279   return ret;
18280 }
18281
18282 static int
18283 api_one_map_register_set_ttl (vat_main_t * vam)
18284 {
18285   unformat_input_t *input = vam->input;
18286   vl_api_one_map_register_set_ttl_t *mp;
18287   u32 ttl = 0;
18288   u8 is_set = 0;
18289   int ret;
18290
18291   /* Parse args required to build the message */
18292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18293     {
18294       if (unformat (input, "%u", &ttl))
18295         is_set = 1;
18296       else
18297         {
18298           clib_warning ("parse error '%U'", format_unformat_error, input);
18299           return -99;
18300         }
18301     }
18302
18303   if (!is_set)
18304     {
18305       errmsg ("TTL value missing!");
18306       return -99;
18307     }
18308
18309   M (ONE_MAP_REGISTER_SET_TTL, mp);
18310   mp->ttl = clib_host_to_net_u32 (ttl);
18311
18312   /* send it... */
18313   S (mp);
18314
18315   /* Wait for a reply... */
18316   W (ret);
18317   return ret;
18318 }
18319
18320 static int
18321 api_show_one_map_register_ttl (vat_main_t * vam)
18322 {
18323   vl_api_show_one_map_register_ttl_t *mp;
18324   int ret;
18325
18326   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18327
18328   /* send it... */
18329   S (mp);
18330
18331   /* Wait for a reply... */
18332   W (ret);
18333   return ret;
18334 }
18335
18336 /**
18337  * Add/del map request itr rlocs from ONE control plane and updates
18338  *
18339  * @param vam vpp API test context
18340  * @return return code
18341  */
18342 static int
18343 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18344 {
18345   unformat_input_t *input = vam->input;
18346   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18347   u8 *locator_set_name = 0;
18348   u8 locator_set_name_set = 0;
18349   u8 is_add = 1;
18350   int ret;
18351
18352   /* Parse args required to build the message */
18353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18354     {
18355       if (unformat (input, "del"))
18356         {
18357           is_add = 0;
18358         }
18359       else if (unformat (input, "%_%v%_", &locator_set_name))
18360         {
18361           locator_set_name_set = 1;
18362         }
18363       else
18364         {
18365           clib_warning ("parse error '%U'", format_unformat_error, input);
18366           return -99;
18367         }
18368     }
18369
18370   if (is_add && !locator_set_name_set)
18371     {
18372       errmsg ("itr-rloc is not set!");
18373       return -99;
18374     }
18375
18376   if (is_add && vec_len (locator_set_name) > 64)
18377     {
18378       errmsg ("itr-rloc locator-set name too long");
18379       vec_free (locator_set_name);
18380       return -99;
18381     }
18382
18383   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18384   mp->is_add = is_add;
18385   if (is_add)
18386     {
18387       clib_memcpy (mp->locator_set_name, locator_set_name,
18388                    vec_len (locator_set_name));
18389     }
18390   else
18391     {
18392       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18393     }
18394   vec_free (locator_set_name);
18395
18396   /* send it... */
18397   S (mp);
18398
18399   /* Wait for a reply... */
18400   W (ret);
18401   return ret;
18402 }
18403
18404 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18405
18406 static int
18407 api_one_locator_dump (vat_main_t * vam)
18408 {
18409   unformat_input_t *input = vam->input;
18410   vl_api_one_locator_dump_t *mp;
18411   vl_api_control_ping_t *mp_ping;
18412   u8 is_index_set = 0, is_name_set = 0;
18413   u8 *ls_name = 0;
18414   u32 ls_index = ~0;
18415   int ret;
18416
18417   /* Parse args required to build the message */
18418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18419     {
18420       if (unformat (input, "ls_name %_%v%_", &ls_name))
18421         {
18422           is_name_set = 1;
18423         }
18424       else if (unformat (input, "ls_index %d", &ls_index))
18425         {
18426           is_index_set = 1;
18427         }
18428       else
18429         {
18430           errmsg ("parse error '%U'", format_unformat_error, input);
18431           return -99;
18432         }
18433     }
18434
18435   if (!is_index_set && !is_name_set)
18436     {
18437       errmsg ("error: expected one of index or name!");
18438       return -99;
18439     }
18440
18441   if (is_index_set && is_name_set)
18442     {
18443       errmsg ("error: only one param expected!");
18444       return -99;
18445     }
18446
18447   if (vec_len (ls_name) > 62)
18448     {
18449       errmsg ("error: locator set name too long!");
18450       return -99;
18451     }
18452
18453   if (!vam->json_output)
18454     {
18455       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18456     }
18457
18458   M (ONE_LOCATOR_DUMP, mp);
18459   mp->is_index_set = is_index_set;
18460
18461   if (is_index_set)
18462     mp->ls_index = clib_host_to_net_u32 (ls_index);
18463   else
18464     {
18465       vec_add1 (ls_name, 0);
18466       strncpy ((char *) mp->ls_name, (char *) ls_name,
18467                sizeof (mp->ls_name) - 1);
18468     }
18469
18470   /* send it... */
18471   S (mp);
18472
18473   /* Use a control ping for synchronization */
18474   MPING (CONTROL_PING, mp_ping);
18475   S (mp_ping);
18476
18477   /* Wait for a reply... */
18478   W (ret);
18479   return ret;
18480 }
18481
18482 #define api_lisp_locator_dump api_one_locator_dump
18483
18484 static int
18485 api_one_locator_set_dump (vat_main_t * vam)
18486 {
18487   vl_api_one_locator_set_dump_t *mp;
18488   vl_api_control_ping_t *mp_ping;
18489   unformat_input_t *input = vam->input;
18490   u8 filter = 0;
18491   int ret;
18492
18493   /* Parse args required to build the message */
18494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18495     {
18496       if (unformat (input, "local"))
18497         {
18498           filter = 1;
18499         }
18500       else if (unformat (input, "remote"))
18501         {
18502           filter = 2;
18503         }
18504       else
18505         {
18506           errmsg ("parse error '%U'", format_unformat_error, input);
18507           return -99;
18508         }
18509     }
18510
18511   if (!vam->json_output)
18512     {
18513       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18514     }
18515
18516   M (ONE_LOCATOR_SET_DUMP, mp);
18517
18518   mp->filter = filter;
18519
18520   /* send it... */
18521   S (mp);
18522
18523   /* Use a control ping for synchronization */
18524   MPING (CONTROL_PING, mp_ping);
18525   S (mp_ping);
18526
18527   /* Wait for a reply... */
18528   W (ret);
18529   return ret;
18530 }
18531
18532 #define api_lisp_locator_set_dump api_one_locator_set_dump
18533
18534 static int
18535 api_one_eid_table_map_dump (vat_main_t * vam)
18536 {
18537   u8 is_l2 = 0;
18538   u8 mode_set = 0;
18539   unformat_input_t *input = vam->input;
18540   vl_api_one_eid_table_map_dump_t *mp;
18541   vl_api_control_ping_t *mp_ping;
18542   int ret;
18543
18544   /* Parse args required to build the message */
18545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18546     {
18547       if (unformat (input, "l2"))
18548         {
18549           is_l2 = 1;
18550           mode_set = 1;
18551         }
18552       else if (unformat (input, "l3"))
18553         {
18554           is_l2 = 0;
18555           mode_set = 1;
18556         }
18557       else
18558         {
18559           errmsg ("parse error '%U'", format_unformat_error, input);
18560           return -99;
18561         }
18562     }
18563
18564   if (!mode_set)
18565     {
18566       errmsg ("expected one of 'l2' or 'l3' parameter!");
18567       return -99;
18568     }
18569
18570   if (!vam->json_output)
18571     {
18572       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18573     }
18574
18575   M (ONE_EID_TABLE_MAP_DUMP, mp);
18576   mp->is_l2 = is_l2;
18577
18578   /* send it... */
18579   S (mp);
18580
18581   /* Use a control ping for synchronization */
18582   MPING (CONTROL_PING, mp_ping);
18583   S (mp_ping);
18584
18585   /* Wait for a reply... */
18586   W (ret);
18587   return ret;
18588 }
18589
18590 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18591
18592 static int
18593 api_one_eid_table_vni_dump (vat_main_t * vam)
18594 {
18595   vl_api_one_eid_table_vni_dump_t *mp;
18596   vl_api_control_ping_t *mp_ping;
18597   int ret;
18598
18599   if (!vam->json_output)
18600     {
18601       print (vam->ofp, "VNI");
18602     }
18603
18604   M (ONE_EID_TABLE_VNI_DUMP, mp);
18605
18606   /* send it... */
18607   S (mp);
18608
18609   /* Use a control ping for synchronization */
18610   MPING (CONTROL_PING, mp_ping);
18611   S (mp_ping);
18612
18613   /* Wait for a reply... */
18614   W (ret);
18615   return ret;
18616 }
18617
18618 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18619
18620 static int
18621 api_one_eid_table_dump (vat_main_t * vam)
18622 {
18623   unformat_input_t *i = vam->input;
18624   vl_api_one_eid_table_dump_t *mp;
18625   vl_api_control_ping_t *mp_ping;
18626   struct in_addr ip4;
18627   struct in6_addr ip6;
18628   u8 mac[6];
18629   u8 eid_type = ~0, eid_set = 0;
18630   u32 prefix_length = ~0, t, vni = 0;
18631   u8 filter = 0;
18632   int ret;
18633   lisp_nsh_api_t nsh;
18634
18635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18636     {
18637       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18638         {
18639           eid_set = 1;
18640           eid_type = 0;
18641           prefix_length = t;
18642         }
18643       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18644         {
18645           eid_set = 1;
18646           eid_type = 1;
18647           prefix_length = t;
18648         }
18649       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18650         {
18651           eid_set = 1;
18652           eid_type = 2;
18653         }
18654       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18655         {
18656           eid_set = 1;
18657           eid_type = 3;
18658         }
18659       else if (unformat (i, "vni %d", &t))
18660         {
18661           vni = t;
18662         }
18663       else if (unformat (i, "local"))
18664         {
18665           filter = 1;
18666         }
18667       else if (unformat (i, "remote"))
18668         {
18669           filter = 2;
18670         }
18671       else
18672         {
18673           errmsg ("parse error '%U'", format_unformat_error, i);
18674           return -99;
18675         }
18676     }
18677
18678   if (!vam->json_output)
18679     {
18680       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18681              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18682     }
18683
18684   M (ONE_EID_TABLE_DUMP, mp);
18685
18686   mp->filter = filter;
18687   if (eid_set)
18688     {
18689       mp->eid_set = 1;
18690       mp->vni = htonl (vni);
18691       mp->eid_type = eid_type;
18692       switch (eid_type)
18693         {
18694         case 0:
18695           mp->prefix_length = prefix_length;
18696           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18697           break;
18698         case 1:
18699           mp->prefix_length = prefix_length;
18700           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18701           break;
18702         case 2:
18703           clib_memcpy (mp->eid, mac, sizeof (mac));
18704           break;
18705         case 3:
18706           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18707           break;
18708         default:
18709           errmsg ("unknown EID type %d!", eid_type);
18710           return -99;
18711         }
18712     }
18713
18714   /* send it... */
18715   S (mp);
18716
18717   /* Use a control ping for synchronization */
18718   MPING (CONTROL_PING, mp_ping);
18719   S (mp_ping);
18720
18721   /* Wait for a reply... */
18722   W (ret);
18723   return ret;
18724 }
18725
18726 #define api_lisp_eid_table_dump api_one_eid_table_dump
18727
18728 static int
18729 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18730 {
18731   unformat_input_t *i = vam->input;
18732   vl_api_gpe_fwd_entries_get_t *mp;
18733   u8 vni_set = 0;
18734   u32 vni = ~0;
18735   int ret;
18736
18737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18738     {
18739       if (unformat (i, "vni %d", &vni))
18740         {
18741           vni_set = 1;
18742         }
18743       else
18744         {
18745           errmsg ("parse error '%U'", format_unformat_error, i);
18746           return -99;
18747         }
18748     }
18749
18750   if (!vni_set)
18751     {
18752       errmsg ("vni not set!");
18753       return -99;
18754     }
18755
18756   if (!vam->json_output)
18757     {
18758       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18759              "leid", "reid");
18760     }
18761
18762   M (GPE_FWD_ENTRIES_GET, mp);
18763   mp->vni = clib_host_to_net_u32 (vni);
18764
18765   /* send it... */
18766   S (mp);
18767
18768   /* Wait for a reply... */
18769   W (ret);
18770   return ret;
18771 }
18772
18773 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18774 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18775 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18776 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18777 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18778 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18779 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18780 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18781
18782 static int
18783 api_one_adjacencies_get (vat_main_t * vam)
18784 {
18785   unformat_input_t *i = vam->input;
18786   vl_api_one_adjacencies_get_t *mp;
18787   u8 vni_set = 0;
18788   u32 vni = ~0;
18789   int ret;
18790
18791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18792     {
18793       if (unformat (i, "vni %d", &vni))
18794         {
18795           vni_set = 1;
18796         }
18797       else
18798         {
18799           errmsg ("parse error '%U'", format_unformat_error, i);
18800           return -99;
18801         }
18802     }
18803
18804   if (!vni_set)
18805     {
18806       errmsg ("vni not set!");
18807       return -99;
18808     }
18809
18810   if (!vam->json_output)
18811     {
18812       print (vam->ofp, "%s %40s", "leid", "reid");
18813     }
18814
18815   M (ONE_ADJACENCIES_GET, mp);
18816   mp->vni = clib_host_to_net_u32 (vni);
18817
18818   /* send it... */
18819   S (mp);
18820
18821   /* Wait for a reply... */
18822   W (ret);
18823   return ret;
18824 }
18825
18826 #define api_lisp_adjacencies_get api_one_adjacencies_get
18827
18828 static int
18829 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18830 {
18831   unformat_input_t *i = vam->input;
18832   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18833   int ret;
18834   u8 ip_family_set = 0, is_ip4 = 1;
18835
18836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18837     {
18838       if (unformat (i, "ip4"))
18839         {
18840           ip_family_set = 1;
18841           is_ip4 = 1;
18842         }
18843       else if (unformat (i, "ip6"))
18844         {
18845           ip_family_set = 1;
18846           is_ip4 = 0;
18847         }
18848       else
18849         {
18850           errmsg ("parse error '%U'", format_unformat_error, i);
18851           return -99;
18852         }
18853     }
18854
18855   if (!ip_family_set)
18856     {
18857       errmsg ("ip family not set!");
18858       return -99;
18859     }
18860
18861   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18862   mp->is_ip4 = is_ip4;
18863
18864   /* send it... */
18865   S (mp);
18866
18867   /* Wait for a reply... */
18868   W (ret);
18869   return ret;
18870 }
18871
18872 static int
18873 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18874 {
18875   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18876   int ret;
18877
18878   if (!vam->json_output)
18879     {
18880       print (vam->ofp, "VNIs");
18881     }
18882
18883   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18884
18885   /* send it... */
18886   S (mp);
18887
18888   /* Wait for a reply... */
18889   W (ret);
18890   return ret;
18891 }
18892
18893 static int
18894 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18895 {
18896   unformat_input_t *i = vam->input;
18897   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18898   int ret = 0;
18899   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18900   struct in_addr ip4;
18901   struct in6_addr ip6;
18902   u32 table_id = 0, nh_sw_if_index = ~0;
18903
18904   memset (&ip4, 0, sizeof (ip4));
18905   memset (&ip6, 0, sizeof (ip6));
18906
18907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18908     {
18909       if (unformat (i, "del"))
18910         is_add = 0;
18911       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18912                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18913         {
18914           ip_set = 1;
18915           is_ip4 = 1;
18916         }
18917       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18918                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18919         {
18920           ip_set = 1;
18921           is_ip4 = 0;
18922         }
18923       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18924         {
18925           ip_set = 1;
18926           is_ip4 = 1;
18927           nh_sw_if_index = ~0;
18928         }
18929       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18930         {
18931           ip_set = 1;
18932           is_ip4 = 0;
18933           nh_sw_if_index = ~0;
18934         }
18935       else if (unformat (i, "table %d", &table_id))
18936         ;
18937       else
18938         {
18939           errmsg ("parse error '%U'", format_unformat_error, i);
18940           return -99;
18941         }
18942     }
18943
18944   if (!ip_set)
18945     {
18946       errmsg ("nh addr not set!");
18947       return -99;
18948     }
18949
18950   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18951   mp->is_add = is_add;
18952   mp->table_id = clib_host_to_net_u32 (table_id);
18953   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18954   mp->is_ip4 = is_ip4;
18955   if (is_ip4)
18956     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18957   else
18958     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18959
18960   /* send it... */
18961   S (mp);
18962
18963   /* Wait for a reply... */
18964   W (ret);
18965   return ret;
18966 }
18967
18968 static int
18969 api_one_map_server_dump (vat_main_t * vam)
18970 {
18971   vl_api_one_map_server_dump_t *mp;
18972   vl_api_control_ping_t *mp_ping;
18973   int ret;
18974
18975   if (!vam->json_output)
18976     {
18977       print (vam->ofp, "%=20s", "Map server");
18978     }
18979
18980   M (ONE_MAP_SERVER_DUMP, mp);
18981   /* send it... */
18982   S (mp);
18983
18984   /* Use a control ping for synchronization */
18985   MPING (CONTROL_PING, mp_ping);
18986   S (mp_ping);
18987
18988   /* Wait for a reply... */
18989   W (ret);
18990   return ret;
18991 }
18992
18993 #define api_lisp_map_server_dump api_one_map_server_dump
18994
18995 static int
18996 api_one_map_resolver_dump (vat_main_t * vam)
18997 {
18998   vl_api_one_map_resolver_dump_t *mp;
18999   vl_api_control_ping_t *mp_ping;
19000   int ret;
19001
19002   if (!vam->json_output)
19003     {
19004       print (vam->ofp, "%=20s", "Map resolver");
19005     }
19006
19007   M (ONE_MAP_RESOLVER_DUMP, mp);
19008   /* send it... */
19009   S (mp);
19010
19011   /* Use a control ping for synchronization */
19012   MPING (CONTROL_PING, mp_ping);
19013   S (mp_ping);
19014
19015   /* Wait for a reply... */
19016   W (ret);
19017   return ret;
19018 }
19019
19020 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19021
19022 static int
19023 api_one_stats_flush (vat_main_t * vam)
19024 {
19025   vl_api_one_stats_flush_t *mp;
19026   int ret = 0;
19027
19028   M (ONE_STATS_FLUSH, mp);
19029   S (mp);
19030   W (ret);
19031   return ret;
19032 }
19033
19034 static int
19035 api_one_stats_dump (vat_main_t * vam)
19036 {
19037   vl_api_one_stats_dump_t *mp;
19038   vl_api_control_ping_t *mp_ping;
19039   int ret;
19040
19041   M (ONE_STATS_DUMP, mp);
19042   /* send it... */
19043   S (mp);
19044
19045   /* Use a control ping for synchronization */
19046   MPING (CONTROL_PING, mp_ping);
19047   S (mp_ping);
19048
19049   /* Wait for a reply... */
19050   W (ret);
19051   return ret;
19052 }
19053
19054 static int
19055 api_show_one_status (vat_main_t * vam)
19056 {
19057   vl_api_show_one_status_t *mp;
19058   int ret;
19059
19060   if (!vam->json_output)
19061     {
19062       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19063     }
19064
19065   M (SHOW_ONE_STATUS, mp);
19066   /* send it... */
19067   S (mp);
19068   /* Wait for a reply... */
19069   W (ret);
19070   return ret;
19071 }
19072
19073 #define api_show_lisp_status api_show_one_status
19074
19075 static int
19076 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19077 {
19078   vl_api_gpe_fwd_entry_path_dump_t *mp;
19079   vl_api_control_ping_t *mp_ping;
19080   unformat_input_t *i = vam->input;
19081   u32 fwd_entry_index = ~0;
19082   int ret;
19083
19084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19085     {
19086       if (unformat (i, "index %d", &fwd_entry_index))
19087         ;
19088       else
19089         break;
19090     }
19091
19092   if (~0 == fwd_entry_index)
19093     {
19094       errmsg ("no index specified!");
19095       return -99;
19096     }
19097
19098   if (!vam->json_output)
19099     {
19100       print (vam->ofp, "first line");
19101     }
19102
19103   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19104
19105   /* send it... */
19106   S (mp);
19107   /* Use a control ping for synchronization */
19108   MPING (CONTROL_PING, mp_ping);
19109   S (mp_ping);
19110
19111   /* Wait for a reply... */
19112   W (ret);
19113   return ret;
19114 }
19115
19116 static int
19117 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19118 {
19119   vl_api_one_get_map_request_itr_rlocs_t *mp;
19120   int ret;
19121
19122   if (!vam->json_output)
19123     {
19124       print (vam->ofp, "%=20s", "itr-rlocs:");
19125     }
19126
19127   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19128   /* send it... */
19129   S (mp);
19130   /* Wait for a reply... */
19131   W (ret);
19132   return ret;
19133 }
19134
19135 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19136
19137 static int
19138 api_af_packet_create (vat_main_t * vam)
19139 {
19140   unformat_input_t *i = vam->input;
19141   vl_api_af_packet_create_t *mp;
19142   u8 *host_if_name = 0;
19143   u8 hw_addr[6];
19144   u8 random_hw_addr = 1;
19145   int ret;
19146
19147   memset (hw_addr, 0, sizeof (hw_addr));
19148
19149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19150     {
19151       if (unformat (i, "name %s", &host_if_name))
19152         vec_add1 (host_if_name, 0);
19153       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19154         random_hw_addr = 0;
19155       else
19156         break;
19157     }
19158
19159   if (!vec_len (host_if_name))
19160     {
19161       errmsg ("host-interface name must be specified");
19162       return -99;
19163     }
19164
19165   if (vec_len (host_if_name) > 64)
19166     {
19167       errmsg ("host-interface name too long");
19168       return -99;
19169     }
19170
19171   M (AF_PACKET_CREATE, mp);
19172
19173   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19174   clib_memcpy (mp->hw_addr, hw_addr, 6);
19175   mp->use_random_hw_addr = random_hw_addr;
19176   vec_free (host_if_name);
19177
19178   S (mp);
19179
19180   /* *INDENT-OFF* */
19181   W2 (ret,
19182       ({
19183         if (ret == 0)
19184           fprintf (vam->ofp ? vam->ofp : stderr,
19185                    " new sw_if_index = %d\n", vam->sw_if_index);
19186       }));
19187   /* *INDENT-ON* */
19188   return ret;
19189 }
19190
19191 static int
19192 api_af_packet_delete (vat_main_t * vam)
19193 {
19194   unformat_input_t *i = vam->input;
19195   vl_api_af_packet_delete_t *mp;
19196   u8 *host_if_name = 0;
19197   int ret;
19198
19199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19200     {
19201       if (unformat (i, "name %s", &host_if_name))
19202         vec_add1 (host_if_name, 0);
19203       else
19204         break;
19205     }
19206
19207   if (!vec_len (host_if_name))
19208     {
19209       errmsg ("host-interface name must be specified");
19210       return -99;
19211     }
19212
19213   if (vec_len (host_if_name) > 64)
19214     {
19215       errmsg ("host-interface name too long");
19216       return -99;
19217     }
19218
19219   M (AF_PACKET_DELETE, mp);
19220
19221   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19222   vec_free (host_if_name);
19223
19224   S (mp);
19225   W (ret);
19226   return ret;
19227 }
19228
19229 static int
19230 api_policer_add_del (vat_main_t * vam)
19231 {
19232   unformat_input_t *i = vam->input;
19233   vl_api_policer_add_del_t *mp;
19234   u8 is_add = 1;
19235   u8 *name = 0;
19236   u32 cir = 0;
19237   u32 eir = 0;
19238   u64 cb = 0;
19239   u64 eb = 0;
19240   u8 rate_type = 0;
19241   u8 round_type = 0;
19242   u8 type = 0;
19243   u8 color_aware = 0;
19244   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19245   int ret;
19246
19247   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19248   conform_action.dscp = 0;
19249   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19250   exceed_action.dscp = 0;
19251   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19252   violate_action.dscp = 0;
19253
19254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19255     {
19256       if (unformat (i, "del"))
19257         is_add = 0;
19258       else if (unformat (i, "name %s", &name))
19259         vec_add1 (name, 0);
19260       else if (unformat (i, "cir %u", &cir))
19261         ;
19262       else if (unformat (i, "eir %u", &eir))
19263         ;
19264       else if (unformat (i, "cb %u", &cb))
19265         ;
19266       else if (unformat (i, "eb %u", &eb))
19267         ;
19268       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19269                          &rate_type))
19270         ;
19271       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19272                          &round_type))
19273         ;
19274       else if (unformat (i, "type %U", unformat_policer_type, &type))
19275         ;
19276       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19277                          &conform_action))
19278         ;
19279       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19280                          &exceed_action))
19281         ;
19282       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19283                          &violate_action))
19284         ;
19285       else if (unformat (i, "color-aware"))
19286         color_aware = 1;
19287       else
19288         break;
19289     }
19290
19291   if (!vec_len (name))
19292     {
19293       errmsg ("policer name must be specified");
19294       return -99;
19295     }
19296
19297   if (vec_len (name) > 64)
19298     {
19299       errmsg ("policer name too long");
19300       return -99;
19301     }
19302
19303   M (POLICER_ADD_DEL, mp);
19304
19305   clib_memcpy (mp->name, name, vec_len (name));
19306   vec_free (name);
19307   mp->is_add = is_add;
19308   mp->cir = ntohl (cir);
19309   mp->eir = ntohl (eir);
19310   mp->cb = clib_net_to_host_u64 (cb);
19311   mp->eb = clib_net_to_host_u64 (eb);
19312   mp->rate_type = rate_type;
19313   mp->round_type = round_type;
19314   mp->type = type;
19315   mp->conform_action_type = conform_action.action_type;
19316   mp->conform_dscp = conform_action.dscp;
19317   mp->exceed_action_type = exceed_action.action_type;
19318   mp->exceed_dscp = exceed_action.dscp;
19319   mp->violate_action_type = violate_action.action_type;
19320   mp->violate_dscp = violate_action.dscp;
19321   mp->color_aware = color_aware;
19322
19323   S (mp);
19324   W (ret);
19325   return ret;
19326 }
19327
19328 static int
19329 api_policer_dump (vat_main_t * vam)
19330 {
19331   unformat_input_t *i = vam->input;
19332   vl_api_policer_dump_t *mp;
19333   vl_api_control_ping_t *mp_ping;
19334   u8 *match_name = 0;
19335   u8 match_name_valid = 0;
19336   int ret;
19337
19338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19339     {
19340       if (unformat (i, "name %s", &match_name))
19341         {
19342           vec_add1 (match_name, 0);
19343           match_name_valid = 1;
19344         }
19345       else
19346         break;
19347     }
19348
19349   M (POLICER_DUMP, mp);
19350   mp->match_name_valid = match_name_valid;
19351   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19352   vec_free (match_name);
19353   /* send it... */
19354   S (mp);
19355
19356   /* Use a control ping for synchronization */
19357   MPING (CONTROL_PING, mp_ping);
19358   S (mp_ping);
19359
19360   /* Wait for a reply... */
19361   W (ret);
19362   return ret;
19363 }
19364
19365 static int
19366 api_policer_classify_set_interface (vat_main_t * vam)
19367 {
19368   unformat_input_t *i = vam->input;
19369   vl_api_policer_classify_set_interface_t *mp;
19370   u32 sw_if_index;
19371   int sw_if_index_set;
19372   u32 ip4_table_index = ~0;
19373   u32 ip6_table_index = ~0;
19374   u32 l2_table_index = ~0;
19375   u8 is_add = 1;
19376   int ret;
19377
19378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19379     {
19380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19381         sw_if_index_set = 1;
19382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19383         sw_if_index_set = 1;
19384       else if (unformat (i, "del"))
19385         is_add = 0;
19386       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19387         ;
19388       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19389         ;
19390       else if (unformat (i, "l2-table %d", &l2_table_index))
19391         ;
19392       else
19393         {
19394           clib_warning ("parse error '%U'", format_unformat_error, i);
19395           return -99;
19396         }
19397     }
19398
19399   if (sw_if_index_set == 0)
19400     {
19401       errmsg ("missing interface name or sw_if_index");
19402       return -99;
19403     }
19404
19405   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19406
19407   mp->sw_if_index = ntohl (sw_if_index);
19408   mp->ip4_table_index = ntohl (ip4_table_index);
19409   mp->ip6_table_index = ntohl (ip6_table_index);
19410   mp->l2_table_index = ntohl (l2_table_index);
19411   mp->is_add = is_add;
19412
19413   S (mp);
19414   W (ret);
19415   return ret;
19416 }
19417
19418 static int
19419 api_policer_classify_dump (vat_main_t * vam)
19420 {
19421   unformat_input_t *i = vam->input;
19422   vl_api_policer_classify_dump_t *mp;
19423   vl_api_control_ping_t *mp_ping;
19424   u8 type = POLICER_CLASSIFY_N_TABLES;
19425   int ret;
19426
19427   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19428     ;
19429   else
19430     {
19431       errmsg ("classify table type must be specified");
19432       return -99;
19433     }
19434
19435   if (!vam->json_output)
19436     {
19437       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19438     }
19439
19440   M (POLICER_CLASSIFY_DUMP, mp);
19441   mp->type = type;
19442   /* send it... */
19443   S (mp);
19444
19445   /* Use a control ping for synchronization */
19446   MPING (CONTROL_PING, mp_ping);
19447   S (mp_ping);
19448
19449   /* Wait for a reply... */
19450   W (ret);
19451   return ret;
19452 }
19453
19454 static int
19455 api_netmap_create (vat_main_t * vam)
19456 {
19457   unformat_input_t *i = vam->input;
19458   vl_api_netmap_create_t *mp;
19459   u8 *if_name = 0;
19460   u8 hw_addr[6];
19461   u8 random_hw_addr = 1;
19462   u8 is_pipe = 0;
19463   u8 is_master = 0;
19464   int ret;
19465
19466   memset (hw_addr, 0, sizeof (hw_addr));
19467
19468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19469     {
19470       if (unformat (i, "name %s", &if_name))
19471         vec_add1 (if_name, 0);
19472       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19473         random_hw_addr = 0;
19474       else if (unformat (i, "pipe"))
19475         is_pipe = 1;
19476       else if (unformat (i, "master"))
19477         is_master = 1;
19478       else if (unformat (i, "slave"))
19479         is_master = 0;
19480       else
19481         break;
19482     }
19483
19484   if (!vec_len (if_name))
19485     {
19486       errmsg ("interface name must be specified");
19487       return -99;
19488     }
19489
19490   if (vec_len (if_name) > 64)
19491     {
19492       errmsg ("interface name too long");
19493       return -99;
19494     }
19495
19496   M (NETMAP_CREATE, mp);
19497
19498   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19499   clib_memcpy (mp->hw_addr, hw_addr, 6);
19500   mp->use_random_hw_addr = random_hw_addr;
19501   mp->is_pipe = is_pipe;
19502   mp->is_master = is_master;
19503   vec_free (if_name);
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508 }
19509
19510 static int
19511 api_netmap_delete (vat_main_t * vam)
19512 {
19513   unformat_input_t *i = vam->input;
19514   vl_api_netmap_delete_t *mp;
19515   u8 *if_name = 0;
19516   int ret;
19517
19518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19519     {
19520       if (unformat (i, "name %s", &if_name))
19521         vec_add1 (if_name, 0);
19522       else
19523         break;
19524     }
19525
19526   if (!vec_len (if_name))
19527     {
19528       errmsg ("interface name must be specified");
19529       return -99;
19530     }
19531
19532   if (vec_len (if_name) > 64)
19533     {
19534       errmsg ("interface name too long");
19535       return -99;
19536     }
19537
19538   M (NETMAP_DELETE, mp);
19539
19540   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19541   vec_free (if_name);
19542
19543   S (mp);
19544   W (ret);
19545   return ret;
19546 }
19547
19548 static void
19549 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19550 {
19551   if (fp->afi == IP46_TYPE_IP6)
19552     print (vam->ofp,
19553            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19554            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19555            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19556            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19557            format_ip6_address, fp->next_hop);
19558   else if (fp->afi == IP46_TYPE_IP4)
19559     print (vam->ofp,
19560            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19561            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19562            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19563            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19564            format_ip4_address, fp->next_hop);
19565 }
19566
19567 static void
19568 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19569                                  vl_api_fib_path2_t * fp)
19570 {
19571   struct in_addr ip4;
19572   struct in6_addr ip6;
19573
19574   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19575   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19576   vat_json_object_add_uint (node, "is_local", fp->is_local);
19577   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19578   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19579   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19580   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19581   if (fp->afi == IP46_TYPE_IP4)
19582     {
19583       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19584       vat_json_object_add_ip4 (node, "next_hop", ip4);
19585     }
19586   else if (fp->afi == IP46_TYPE_IP6)
19587     {
19588       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19589       vat_json_object_add_ip6 (node, "next_hop", ip6);
19590     }
19591 }
19592
19593 static void
19594 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19595 {
19596   vat_main_t *vam = &vat_main;
19597   int count = ntohl (mp->mt_count);
19598   vl_api_fib_path2_t *fp;
19599   i32 i;
19600
19601   print (vam->ofp, "[%d]: sw_if_index %d via:",
19602          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19603   fp = mp->mt_paths;
19604   for (i = 0; i < count; i++)
19605     {
19606       vl_api_mpls_fib_path_print (vam, fp);
19607       fp++;
19608     }
19609
19610   print (vam->ofp, "");
19611 }
19612
19613 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19614 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19615
19616 static void
19617 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19618 {
19619   vat_main_t *vam = &vat_main;
19620   vat_json_node_t *node = NULL;
19621   int count = ntohl (mp->mt_count);
19622   vl_api_fib_path2_t *fp;
19623   i32 i;
19624
19625   if (VAT_JSON_ARRAY != vam->json_tree.type)
19626     {
19627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19628       vat_json_init_array (&vam->json_tree);
19629     }
19630   node = vat_json_array_add (&vam->json_tree);
19631
19632   vat_json_init_object (node);
19633   vat_json_object_add_uint (node, "tunnel_index",
19634                             ntohl (mp->mt_tunnel_index));
19635   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19636
19637   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19638
19639   fp = mp->mt_paths;
19640   for (i = 0; i < count; i++)
19641     {
19642       vl_api_mpls_fib_path_json_print (node, fp);
19643       fp++;
19644     }
19645 }
19646
19647 static int
19648 api_mpls_tunnel_dump (vat_main_t * vam)
19649 {
19650   vl_api_mpls_tunnel_dump_t *mp;
19651   vl_api_control_ping_t *mp_ping;
19652   i32 index = -1;
19653   int ret;
19654
19655   /* Parse args required to build the message */
19656   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19657     {
19658       if (!unformat (vam->input, "tunnel_index %d", &index))
19659         {
19660           index = -1;
19661           break;
19662         }
19663     }
19664
19665   print (vam->ofp, "  tunnel_index %d", index);
19666
19667   M (MPLS_TUNNEL_DUMP, mp);
19668   mp->tunnel_index = htonl (index);
19669   S (mp);
19670
19671   /* Use a control ping for synchronization */
19672   MPING (CONTROL_PING, mp_ping);
19673   S (mp_ping);
19674
19675   W (ret);
19676   return ret;
19677 }
19678
19679 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19680 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19681
19682
19683 static void
19684 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19685 {
19686   vat_main_t *vam = &vat_main;
19687   int count = ntohl (mp->count);
19688   vl_api_fib_path2_t *fp;
19689   int i;
19690
19691   print (vam->ofp,
19692          "table-id %d, label %u, ess_bit %u",
19693          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19694   fp = mp->path;
19695   for (i = 0; i < count; i++)
19696     {
19697       vl_api_mpls_fib_path_print (vam, fp);
19698       fp++;
19699     }
19700 }
19701
19702 static void vl_api_mpls_fib_details_t_handler_json
19703   (vl_api_mpls_fib_details_t * mp)
19704 {
19705   vat_main_t *vam = &vat_main;
19706   int count = ntohl (mp->count);
19707   vat_json_node_t *node = NULL;
19708   vl_api_fib_path2_t *fp;
19709   int i;
19710
19711   if (VAT_JSON_ARRAY != vam->json_tree.type)
19712     {
19713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19714       vat_json_init_array (&vam->json_tree);
19715     }
19716   node = vat_json_array_add (&vam->json_tree);
19717
19718   vat_json_init_object (node);
19719   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19720   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19721   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19722   vat_json_object_add_uint (node, "path_count", count);
19723   fp = mp->path;
19724   for (i = 0; i < count; i++)
19725     {
19726       vl_api_mpls_fib_path_json_print (node, fp);
19727       fp++;
19728     }
19729 }
19730
19731 static int
19732 api_mpls_fib_dump (vat_main_t * vam)
19733 {
19734   vl_api_mpls_fib_dump_t *mp;
19735   vl_api_control_ping_t *mp_ping;
19736   int ret;
19737
19738   M (MPLS_FIB_DUMP, mp);
19739   S (mp);
19740
19741   /* Use a control ping for synchronization */
19742   MPING (CONTROL_PING, mp_ping);
19743   S (mp_ping);
19744
19745   W (ret);
19746   return ret;
19747 }
19748
19749 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19750 #define vl_api_ip_fib_details_t_print vl_noop_handler
19751
19752 static void
19753 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19754 {
19755   vat_main_t *vam = &vat_main;
19756   int count = ntohl (mp->count);
19757   vl_api_fib_path_t *fp;
19758   int i;
19759
19760   print (vam->ofp,
19761          "table-id %d, prefix %U/%d",
19762          ntohl (mp->table_id), format_ip4_address, mp->address,
19763          mp->address_length);
19764   fp = mp->path;
19765   for (i = 0; i < count; i++)
19766     {
19767       if (fp->afi == IP46_TYPE_IP6)
19768         print (vam->ofp,
19769                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19770                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19771                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19772                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19773                format_ip6_address, fp->next_hop);
19774       else if (fp->afi == IP46_TYPE_IP4)
19775         print (vam->ofp,
19776                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19777                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19778                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19779                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19780                format_ip4_address, fp->next_hop);
19781       fp++;
19782     }
19783 }
19784
19785 static void vl_api_ip_fib_details_t_handler_json
19786   (vl_api_ip_fib_details_t * mp)
19787 {
19788   vat_main_t *vam = &vat_main;
19789   int count = ntohl (mp->count);
19790   vat_json_node_t *node = NULL;
19791   struct in_addr ip4;
19792   struct in6_addr ip6;
19793   vl_api_fib_path_t *fp;
19794   int i;
19795
19796   if (VAT_JSON_ARRAY != vam->json_tree.type)
19797     {
19798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19799       vat_json_init_array (&vam->json_tree);
19800     }
19801   node = vat_json_array_add (&vam->json_tree);
19802
19803   vat_json_init_object (node);
19804   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19805   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19806   vat_json_object_add_ip4 (node, "prefix", ip4);
19807   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19808   vat_json_object_add_uint (node, "path_count", count);
19809   fp = mp->path;
19810   for (i = 0; i < count; i++)
19811     {
19812       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19813       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19814       vat_json_object_add_uint (node, "is_local", fp->is_local);
19815       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19816       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19817       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19818       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19819       if (fp->afi == IP46_TYPE_IP4)
19820         {
19821           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19822           vat_json_object_add_ip4 (node, "next_hop", ip4);
19823         }
19824       else if (fp->afi == IP46_TYPE_IP6)
19825         {
19826           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19827           vat_json_object_add_ip6 (node, "next_hop", ip6);
19828         }
19829     }
19830 }
19831
19832 static int
19833 api_ip_fib_dump (vat_main_t * vam)
19834 {
19835   vl_api_ip_fib_dump_t *mp;
19836   vl_api_control_ping_t *mp_ping;
19837   int ret;
19838
19839   M (IP_FIB_DUMP, mp);
19840   S (mp);
19841
19842   /* Use a control ping for synchronization */
19843   MPING (CONTROL_PING, mp_ping);
19844   S (mp_ping);
19845
19846   W (ret);
19847   return ret;
19848 }
19849
19850 static int
19851 api_ip_mfib_dump (vat_main_t * vam)
19852 {
19853   vl_api_ip_mfib_dump_t *mp;
19854   vl_api_control_ping_t *mp_ping;
19855   int ret;
19856
19857   M (IP_MFIB_DUMP, mp);
19858   S (mp);
19859
19860   /* Use a control ping for synchronization */
19861   MPING (CONTROL_PING, mp_ping);
19862   S (mp_ping);
19863
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static void vl_api_ip_neighbor_details_t_handler
19869   (vl_api_ip_neighbor_details_t * mp)
19870 {
19871   vat_main_t *vam = &vat_main;
19872
19873   print (vam->ofp, "%c %U %U",
19874          (mp->is_static) ? 'S' : 'D',
19875          format_ethernet_address, &mp->mac_address,
19876          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19877          &mp->ip_address);
19878 }
19879
19880 static void vl_api_ip_neighbor_details_t_handler_json
19881   (vl_api_ip_neighbor_details_t * mp)
19882 {
19883
19884   vat_main_t *vam = &vat_main;
19885   vat_json_node_t *node;
19886   struct in_addr ip4;
19887   struct in6_addr ip6;
19888
19889   if (VAT_JSON_ARRAY != vam->json_tree.type)
19890     {
19891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19892       vat_json_init_array (&vam->json_tree);
19893     }
19894   node = vat_json_array_add (&vam->json_tree);
19895
19896   vat_json_init_object (node);
19897   vat_json_object_add_string_copy (node, "flag",
19898                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19899                                    "dynamic");
19900
19901   vat_json_object_add_string_copy (node, "link_layer",
19902                                    format (0, "%U", format_ethernet_address,
19903                                            &mp->mac_address));
19904
19905   if (mp->is_ipv6)
19906     {
19907       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19908       vat_json_object_add_ip6 (node, "ip_address", ip6);
19909     }
19910   else
19911     {
19912       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19913       vat_json_object_add_ip4 (node, "ip_address", ip4);
19914     }
19915 }
19916
19917 static int
19918 api_ip_neighbor_dump (vat_main_t * vam)
19919 {
19920   unformat_input_t *i = vam->input;
19921   vl_api_ip_neighbor_dump_t *mp;
19922   vl_api_control_ping_t *mp_ping;
19923   u8 is_ipv6 = 0;
19924   u32 sw_if_index = ~0;
19925   int ret;
19926
19927   /* Parse args required to build the message */
19928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19929     {
19930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19931         ;
19932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19933         ;
19934       else if (unformat (i, "ip6"))
19935         is_ipv6 = 1;
19936       else
19937         break;
19938     }
19939
19940   if (sw_if_index == ~0)
19941     {
19942       errmsg ("missing interface name or sw_if_index");
19943       return -99;
19944     }
19945
19946   M (IP_NEIGHBOR_DUMP, mp);
19947   mp->is_ipv6 = (u8) is_ipv6;
19948   mp->sw_if_index = ntohl (sw_if_index);
19949   S (mp);
19950
19951   /* Use a control ping for synchronization */
19952   MPING (CONTROL_PING, mp_ping);
19953   S (mp_ping);
19954
19955   W (ret);
19956   return ret;
19957 }
19958
19959 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19960 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19961
19962 static void
19963 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19964 {
19965   vat_main_t *vam = &vat_main;
19966   int count = ntohl (mp->count);
19967   vl_api_fib_path_t *fp;
19968   int i;
19969
19970   print (vam->ofp,
19971          "table-id %d, prefix %U/%d",
19972          ntohl (mp->table_id), format_ip6_address, mp->address,
19973          mp->address_length);
19974   fp = mp->path;
19975   for (i = 0; i < count; i++)
19976     {
19977       if (fp->afi == IP46_TYPE_IP6)
19978         print (vam->ofp,
19979                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19980                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19981                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19982                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19983                format_ip6_address, fp->next_hop);
19984       else if (fp->afi == IP46_TYPE_IP4)
19985         print (vam->ofp,
19986                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19987                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19988                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19989                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19990                format_ip4_address, fp->next_hop);
19991       fp++;
19992     }
19993 }
19994
19995 static void vl_api_ip6_fib_details_t_handler_json
19996   (vl_api_ip6_fib_details_t * mp)
19997 {
19998   vat_main_t *vam = &vat_main;
19999   int count = ntohl (mp->count);
20000   vat_json_node_t *node = NULL;
20001   struct in_addr ip4;
20002   struct in6_addr ip6;
20003   vl_api_fib_path_t *fp;
20004   int i;
20005
20006   if (VAT_JSON_ARRAY != vam->json_tree.type)
20007     {
20008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20009       vat_json_init_array (&vam->json_tree);
20010     }
20011   node = vat_json_array_add (&vam->json_tree);
20012
20013   vat_json_init_object (node);
20014   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20015   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20016   vat_json_object_add_ip6 (node, "prefix", ip6);
20017   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20018   vat_json_object_add_uint (node, "path_count", count);
20019   fp = mp->path;
20020   for (i = 0; i < count; i++)
20021     {
20022       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20023       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20024       vat_json_object_add_uint (node, "is_local", fp->is_local);
20025       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20026       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20027       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20028       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20029       if (fp->afi == IP46_TYPE_IP4)
20030         {
20031           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20032           vat_json_object_add_ip4 (node, "next_hop", ip4);
20033         }
20034       else if (fp->afi == IP46_TYPE_IP6)
20035         {
20036           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20037           vat_json_object_add_ip6 (node, "next_hop", ip6);
20038         }
20039     }
20040 }
20041
20042 static int
20043 api_ip6_fib_dump (vat_main_t * vam)
20044 {
20045   vl_api_ip6_fib_dump_t *mp;
20046   vl_api_control_ping_t *mp_ping;
20047   int ret;
20048
20049   M (IP6_FIB_DUMP, mp);
20050   S (mp);
20051
20052   /* Use a control ping for synchronization */
20053   MPING (CONTROL_PING, mp_ping);
20054   S (mp_ping);
20055
20056   W (ret);
20057   return ret;
20058 }
20059
20060 static int
20061 api_ip6_mfib_dump (vat_main_t * vam)
20062 {
20063   vl_api_ip6_mfib_dump_t *mp;
20064   vl_api_control_ping_t *mp_ping;
20065   int ret;
20066
20067   M (IP6_MFIB_DUMP, mp);
20068   S (mp);
20069
20070   /* Use a control ping for synchronization */
20071   MPING (CONTROL_PING, mp_ping);
20072   S (mp_ping);
20073
20074   W (ret);
20075   return ret;
20076 }
20077
20078 int
20079 api_classify_table_ids (vat_main_t * vam)
20080 {
20081   vl_api_classify_table_ids_t *mp;
20082   int ret;
20083
20084   /* Construct the API message */
20085   M (CLASSIFY_TABLE_IDS, mp);
20086   mp->context = 0;
20087
20088   S (mp);
20089   W (ret);
20090   return ret;
20091 }
20092
20093 int
20094 api_classify_table_by_interface (vat_main_t * vam)
20095 {
20096   unformat_input_t *input = vam->input;
20097   vl_api_classify_table_by_interface_t *mp;
20098
20099   u32 sw_if_index = ~0;
20100   int ret;
20101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20102     {
20103       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20104         ;
20105       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20106         ;
20107       else
20108         break;
20109     }
20110   if (sw_if_index == ~0)
20111     {
20112       errmsg ("missing interface name or sw_if_index");
20113       return -99;
20114     }
20115
20116   /* Construct the API message */
20117   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20118   mp->context = 0;
20119   mp->sw_if_index = ntohl (sw_if_index);
20120
20121   S (mp);
20122   W (ret);
20123   return ret;
20124 }
20125
20126 int
20127 api_classify_table_info (vat_main_t * vam)
20128 {
20129   unformat_input_t *input = vam->input;
20130   vl_api_classify_table_info_t *mp;
20131
20132   u32 table_id = ~0;
20133   int ret;
20134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20135     {
20136       if (unformat (input, "table_id %d", &table_id))
20137         ;
20138       else
20139         break;
20140     }
20141   if (table_id == ~0)
20142     {
20143       errmsg ("missing table id");
20144       return -99;
20145     }
20146
20147   /* Construct the API message */
20148   M (CLASSIFY_TABLE_INFO, mp);
20149   mp->context = 0;
20150   mp->table_id = ntohl (table_id);
20151
20152   S (mp);
20153   W (ret);
20154   return ret;
20155 }
20156
20157 int
20158 api_classify_session_dump (vat_main_t * vam)
20159 {
20160   unformat_input_t *input = vam->input;
20161   vl_api_classify_session_dump_t *mp;
20162   vl_api_control_ping_t *mp_ping;
20163
20164   u32 table_id = ~0;
20165   int ret;
20166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20167     {
20168       if (unformat (input, "table_id %d", &table_id))
20169         ;
20170       else
20171         break;
20172     }
20173   if (table_id == ~0)
20174     {
20175       errmsg ("missing table id");
20176       return -99;
20177     }
20178
20179   /* Construct the API message */
20180   M (CLASSIFY_SESSION_DUMP, mp);
20181   mp->context = 0;
20182   mp->table_id = ntohl (table_id);
20183   S (mp);
20184
20185   /* Use a control ping for synchronization */
20186   MPING (CONTROL_PING, mp_ping);
20187   S (mp_ping);
20188
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static void
20194 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20195 {
20196   vat_main_t *vam = &vat_main;
20197
20198   print (vam->ofp, "collector_address %U, collector_port %d, "
20199          "src_address %U, vrf_id %d, path_mtu %u, "
20200          "template_interval %u, udp_checksum %d",
20201          format_ip4_address, mp->collector_address,
20202          ntohs (mp->collector_port),
20203          format_ip4_address, mp->src_address,
20204          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20205          ntohl (mp->template_interval), mp->udp_checksum);
20206
20207   vam->retval = 0;
20208   vam->result_ready = 1;
20209 }
20210
20211 static void
20212   vl_api_ipfix_exporter_details_t_handler_json
20213   (vl_api_ipfix_exporter_details_t * mp)
20214 {
20215   vat_main_t *vam = &vat_main;
20216   vat_json_node_t node;
20217   struct in_addr collector_address;
20218   struct in_addr src_address;
20219
20220   vat_json_init_object (&node);
20221   clib_memcpy (&collector_address, &mp->collector_address,
20222                sizeof (collector_address));
20223   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20224   vat_json_object_add_uint (&node, "collector_port",
20225                             ntohs (mp->collector_port));
20226   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20227   vat_json_object_add_ip4 (&node, "src_address", src_address);
20228   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20229   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20230   vat_json_object_add_uint (&node, "template_interval",
20231                             ntohl (mp->template_interval));
20232   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20233
20234   vat_json_print (vam->ofp, &node);
20235   vat_json_free (&node);
20236   vam->retval = 0;
20237   vam->result_ready = 1;
20238 }
20239
20240 int
20241 api_ipfix_exporter_dump (vat_main_t * vam)
20242 {
20243   vl_api_ipfix_exporter_dump_t *mp;
20244   int ret;
20245
20246   /* Construct the API message */
20247   M (IPFIX_EXPORTER_DUMP, mp);
20248   mp->context = 0;
20249
20250   S (mp);
20251   W (ret);
20252   return ret;
20253 }
20254
20255 static int
20256 api_ipfix_classify_stream_dump (vat_main_t * vam)
20257 {
20258   vl_api_ipfix_classify_stream_dump_t *mp;
20259   int ret;
20260
20261   /* Construct the API message */
20262   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20263   mp->context = 0;
20264
20265   S (mp);
20266   W (ret);
20267   return ret;
20268   /* NOTREACHED */
20269   return 0;
20270 }
20271
20272 static void
20273   vl_api_ipfix_classify_stream_details_t_handler
20274   (vl_api_ipfix_classify_stream_details_t * mp)
20275 {
20276   vat_main_t *vam = &vat_main;
20277   print (vam->ofp, "domain_id %d, src_port %d",
20278          ntohl (mp->domain_id), ntohs (mp->src_port));
20279   vam->retval = 0;
20280   vam->result_ready = 1;
20281 }
20282
20283 static void
20284   vl_api_ipfix_classify_stream_details_t_handler_json
20285   (vl_api_ipfix_classify_stream_details_t * mp)
20286 {
20287   vat_main_t *vam = &vat_main;
20288   vat_json_node_t node;
20289
20290   vat_json_init_object (&node);
20291   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20292   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20293
20294   vat_json_print (vam->ofp, &node);
20295   vat_json_free (&node);
20296   vam->retval = 0;
20297   vam->result_ready = 1;
20298 }
20299
20300 static int
20301 api_ipfix_classify_table_dump (vat_main_t * vam)
20302 {
20303   vl_api_ipfix_classify_table_dump_t *mp;
20304   vl_api_control_ping_t *mp_ping;
20305   int ret;
20306
20307   if (!vam->json_output)
20308     {
20309       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20310              "transport_protocol");
20311     }
20312
20313   /* Construct the API message */
20314   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20315
20316   /* send it... */
20317   S (mp);
20318
20319   /* Use a control ping for synchronization */
20320   MPING (CONTROL_PING, mp_ping);
20321   S (mp_ping);
20322
20323   W (ret);
20324   return ret;
20325 }
20326
20327 static void
20328   vl_api_ipfix_classify_table_details_t_handler
20329   (vl_api_ipfix_classify_table_details_t * mp)
20330 {
20331   vat_main_t *vam = &vat_main;
20332   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20333          mp->transport_protocol);
20334 }
20335
20336 static void
20337   vl_api_ipfix_classify_table_details_t_handler_json
20338   (vl_api_ipfix_classify_table_details_t * mp)
20339 {
20340   vat_json_node_t *node = NULL;
20341   vat_main_t *vam = &vat_main;
20342
20343   if (VAT_JSON_ARRAY != vam->json_tree.type)
20344     {
20345       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20346       vat_json_init_array (&vam->json_tree);
20347     }
20348
20349   node = vat_json_array_add (&vam->json_tree);
20350   vat_json_init_object (node);
20351
20352   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20353   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20354   vat_json_object_add_uint (node, "transport_protocol",
20355                             mp->transport_protocol);
20356 }
20357
20358 static int
20359 api_sw_interface_span_enable_disable (vat_main_t * vam)
20360 {
20361   unformat_input_t *i = vam->input;
20362   vl_api_sw_interface_span_enable_disable_t *mp;
20363   u32 src_sw_if_index = ~0;
20364   u32 dst_sw_if_index = ~0;
20365   u8 state = 3;
20366   int ret;
20367   u8 is_l2 = 0;
20368
20369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20370     {
20371       if (unformat
20372           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20373         ;
20374       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20375         ;
20376       else
20377         if (unformat
20378             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20379         ;
20380       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20381         ;
20382       else if (unformat (i, "disable"))
20383         state = 0;
20384       else if (unformat (i, "rx"))
20385         state = 1;
20386       else if (unformat (i, "tx"))
20387         state = 2;
20388       else if (unformat (i, "both"))
20389         state = 3;
20390       else if (unformat (i, "l2"))
20391         is_l2 = 1;
20392       else
20393         break;
20394     }
20395
20396   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20397
20398   mp->sw_if_index_from = htonl (src_sw_if_index);
20399   mp->sw_if_index_to = htonl (dst_sw_if_index);
20400   mp->state = state;
20401   mp->is_l2 = is_l2;
20402
20403   S (mp);
20404   W (ret);
20405   return ret;
20406 }
20407
20408 static void
20409 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20410                                             * mp)
20411 {
20412   vat_main_t *vam = &vat_main;
20413   u8 *sw_if_from_name = 0;
20414   u8 *sw_if_to_name = 0;
20415   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20416   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20417   char *states[] = { "none", "rx", "tx", "both" };
20418   hash_pair_t *p;
20419
20420   /* *INDENT-OFF* */
20421   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20422   ({
20423     if ((u32) p->value[0] == sw_if_index_from)
20424       {
20425         sw_if_from_name = (u8 *)(p->key);
20426         if (sw_if_to_name)
20427           break;
20428       }
20429     if ((u32) p->value[0] == sw_if_index_to)
20430       {
20431         sw_if_to_name = (u8 *)(p->key);
20432         if (sw_if_from_name)
20433           break;
20434       }
20435   }));
20436   /* *INDENT-ON* */
20437   print (vam->ofp, "%20s => %20s (%s)",
20438          sw_if_from_name, sw_if_to_name, states[mp->state]);
20439 }
20440
20441 static void
20442   vl_api_sw_interface_span_details_t_handler_json
20443   (vl_api_sw_interface_span_details_t * mp)
20444 {
20445   vat_main_t *vam = &vat_main;
20446   vat_json_node_t *node = NULL;
20447   u8 *sw_if_from_name = 0;
20448   u8 *sw_if_to_name = 0;
20449   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20450   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20451   hash_pair_t *p;
20452
20453   /* *INDENT-OFF* */
20454   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20455   ({
20456     if ((u32) p->value[0] == sw_if_index_from)
20457       {
20458         sw_if_from_name = (u8 *)(p->key);
20459         if (sw_if_to_name)
20460           break;
20461       }
20462     if ((u32) p->value[0] == sw_if_index_to)
20463       {
20464         sw_if_to_name = (u8 *)(p->key);
20465         if (sw_if_from_name)
20466           break;
20467       }
20468   }));
20469   /* *INDENT-ON* */
20470
20471   if (VAT_JSON_ARRAY != vam->json_tree.type)
20472     {
20473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20474       vat_json_init_array (&vam->json_tree);
20475     }
20476   node = vat_json_array_add (&vam->json_tree);
20477
20478   vat_json_init_object (node);
20479   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20480   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20481   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20482   if (0 != sw_if_to_name)
20483     {
20484       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20485     }
20486   vat_json_object_add_uint (node, "state", mp->state);
20487 }
20488
20489 static int
20490 api_sw_interface_span_dump (vat_main_t * vam)
20491 {
20492   unformat_input_t *input = vam->input;
20493   vl_api_sw_interface_span_dump_t *mp;
20494   vl_api_control_ping_t *mp_ping;
20495   u8 is_l2 = 0;
20496   int ret;
20497
20498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20499     {
20500       if (unformat (input, "l2"))
20501         is_l2 = 1;
20502       else
20503         break;
20504     }
20505
20506   M (SW_INTERFACE_SPAN_DUMP, mp);
20507   mp->is_l2 = is_l2;
20508   S (mp);
20509
20510   /* Use a control ping for synchronization */
20511   MPING (CONTROL_PING, mp_ping);
20512   S (mp_ping);
20513
20514   W (ret);
20515   return ret;
20516 }
20517
20518 int
20519 api_pg_create_interface (vat_main_t * vam)
20520 {
20521   unformat_input_t *input = vam->input;
20522   vl_api_pg_create_interface_t *mp;
20523
20524   u32 if_id = ~0;
20525   int ret;
20526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20527     {
20528       if (unformat (input, "if_id %d", &if_id))
20529         ;
20530       else
20531         break;
20532     }
20533   if (if_id == ~0)
20534     {
20535       errmsg ("missing pg interface index");
20536       return -99;
20537     }
20538
20539   /* Construct the API message */
20540   M (PG_CREATE_INTERFACE, mp);
20541   mp->context = 0;
20542   mp->interface_id = ntohl (if_id);
20543
20544   S (mp);
20545   W (ret);
20546   return ret;
20547 }
20548
20549 int
20550 api_pg_capture (vat_main_t * vam)
20551 {
20552   unformat_input_t *input = vam->input;
20553   vl_api_pg_capture_t *mp;
20554
20555   u32 if_id = ~0;
20556   u8 enable = 1;
20557   u32 count = 1;
20558   u8 pcap_file_set = 0;
20559   u8 *pcap_file = 0;
20560   int ret;
20561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20562     {
20563       if (unformat (input, "if_id %d", &if_id))
20564         ;
20565       else if (unformat (input, "pcap %s", &pcap_file))
20566         pcap_file_set = 1;
20567       else if (unformat (input, "count %d", &count))
20568         ;
20569       else if (unformat (input, "disable"))
20570         enable = 0;
20571       else
20572         break;
20573     }
20574   if (if_id == ~0)
20575     {
20576       errmsg ("missing pg interface index");
20577       return -99;
20578     }
20579   if (pcap_file_set > 0)
20580     {
20581       if (vec_len (pcap_file) > 255)
20582         {
20583           errmsg ("pcap file name is too long");
20584           return -99;
20585         }
20586     }
20587
20588   u32 name_len = vec_len (pcap_file);
20589   /* Construct the API message */
20590   M (PG_CAPTURE, mp);
20591   mp->context = 0;
20592   mp->interface_id = ntohl (if_id);
20593   mp->is_enabled = enable;
20594   mp->count = ntohl (count);
20595   mp->pcap_name_length = ntohl (name_len);
20596   if (pcap_file_set != 0)
20597     {
20598       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20599     }
20600   vec_free (pcap_file);
20601
20602   S (mp);
20603   W (ret);
20604   return ret;
20605 }
20606
20607 int
20608 api_pg_enable_disable (vat_main_t * vam)
20609 {
20610   unformat_input_t *input = vam->input;
20611   vl_api_pg_enable_disable_t *mp;
20612
20613   u8 enable = 1;
20614   u8 stream_name_set = 0;
20615   u8 *stream_name = 0;
20616   int ret;
20617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20618     {
20619       if (unformat (input, "stream %s", &stream_name))
20620         stream_name_set = 1;
20621       else if (unformat (input, "disable"))
20622         enable = 0;
20623       else
20624         break;
20625     }
20626
20627   if (stream_name_set > 0)
20628     {
20629       if (vec_len (stream_name) > 255)
20630         {
20631           errmsg ("stream name too long");
20632           return -99;
20633         }
20634     }
20635
20636   u32 name_len = vec_len (stream_name);
20637   /* Construct the API message */
20638   M (PG_ENABLE_DISABLE, mp);
20639   mp->context = 0;
20640   mp->is_enabled = enable;
20641   if (stream_name_set != 0)
20642     {
20643       mp->stream_name_length = ntohl (name_len);
20644       clib_memcpy (mp->stream_name, stream_name, name_len);
20645     }
20646   vec_free (stream_name);
20647
20648   S (mp);
20649   W (ret);
20650   return ret;
20651 }
20652
20653 int
20654 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20655 {
20656   unformat_input_t *input = vam->input;
20657   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20658
20659   u16 *low_ports = 0;
20660   u16 *high_ports = 0;
20661   u16 this_low;
20662   u16 this_hi;
20663   ip4_address_t ip4_addr;
20664   ip6_address_t ip6_addr;
20665   u32 length;
20666   u32 tmp, tmp2;
20667   u8 prefix_set = 0;
20668   u32 vrf_id = ~0;
20669   u8 is_add = 1;
20670   u8 is_ipv6 = 0;
20671   int ret;
20672
20673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20674     {
20675       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20676         {
20677           prefix_set = 1;
20678         }
20679       else
20680         if (unformat
20681             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20682         {
20683           prefix_set = 1;
20684           is_ipv6 = 1;
20685         }
20686       else if (unformat (input, "vrf %d", &vrf_id))
20687         ;
20688       else if (unformat (input, "del"))
20689         is_add = 0;
20690       else if (unformat (input, "port %d", &tmp))
20691         {
20692           if (tmp == 0 || tmp > 65535)
20693             {
20694               errmsg ("port %d out of range", tmp);
20695               return -99;
20696             }
20697           this_low = tmp;
20698           this_hi = this_low + 1;
20699           vec_add1 (low_ports, this_low);
20700           vec_add1 (high_ports, this_hi);
20701         }
20702       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20703         {
20704           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20705             {
20706               errmsg ("incorrect range parameters");
20707               return -99;
20708             }
20709           this_low = tmp;
20710           /* Note: in debug CLI +1 is added to high before
20711              passing to real fn that does "the work"
20712              (ip_source_and_port_range_check_add_del).
20713              This fn is a wrapper around the binary API fn a
20714              control plane will call, which expects this increment
20715              to have occurred. Hence letting the binary API control
20716              plane fn do the increment for consistency between VAT
20717              and other control planes.
20718            */
20719           this_hi = tmp2;
20720           vec_add1 (low_ports, this_low);
20721           vec_add1 (high_ports, this_hi);
20722         }
20723       else
20724         break;
20725     }
20726
20727   if (prefix_set == 0)
20728     {
20729       errmsg ("<address>/<mask> not specified");
20730       return -99;
20731     }
20732
20733   if (vrf_id == ~0)
20734     {
20735       errmsg ("VRF ID required, not specified");
20736       return -99;
20737     }
20738
20739   if (vrf_id == 0)
20740     {
20741       errmsg
20742         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20743       return -99;
20744     }
20745
20746   if (vec_len (low_ports) == 0)
20747     {
20748       errmsg ("At least one port or port range required");
20749       return -99;
20750     }
20751
20752   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20753
20754   mp->is_add = is_add;
20755
20756   if (is_ipv6)
20757     {
20758       mp->is_ipv6 = 1;
20759       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20760     }
20761   else
20762     {
20763       mp->is_ipv6 = 0;
20764       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20765     }
20766
20767   mp->mask_length = length;
20768   mp->number_of_ranges = vec_len (low_ports);
20769
20770   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20771   vec_free (low_ports);
20772
20773   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20774   vec_free (high_ports);
20775
20776   mp->vrf_id = ntohl (vrf_id);
20777
20778   S (mp);
20779   W (ret);
20780   return ret;
20781 }
20782
20783 int
20784 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20785 {
20786   unformat_input_t *input = vam->input;
20787   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20788   u32 sw_if_index = ~0;
20789   int vrf_set = 0;
20790   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20791   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20792   u8 is_add = 1;
20793   int ret;
20794
20795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20796     {
20797       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20798         ;
20799       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20800         ;
20801       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20802         vrf_set = 1;
20803       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20804         vrf_set = 1;
20805       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20806         vrf_set = 1;
20807       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20808         vrf_set = 1;
20809       else if (unformat (input, "del"))
20810         is_add = 0;
20811       else
20812         break;
20813     }
20814
20815   if (sw_if_index == ~0)
20816     {
20817       errmsg ("Interface required but not specified");
20818       return -99;
20819     }
20820
20821   if (vrf_set == 0)
20822     {
20823       errmsg ("VRF ID required but not specified");
20824       return -99;
20825     }
20826
20827   if (tcp_out_vrf_id == 0
20828       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20829     {
20830       errmsg
20831         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20832       return -99;
20833     }
20834
20835   /* Construct the API message */
20836   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20837
20838   mp->sw_if_index = ntohl (sw_if_index);
20839   mp->is_add = is_add;
20840   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20841   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20842   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20843   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20844
20845   /* send it... */
20846   S (mp);
20847
20848   /* Wait for a reply... */
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static int
20854 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20855 {
20856   unformat_input_t *i = vam->input;
20857   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20858   u32 local_sa_id = 0;
20859   u32 remote_sa_id = 0;
20860   ip4_address_t src_address;
20861   ip4_address_t dst_address;
20862   u8 is_add = 1;
20863   int ret;
20864
20865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20866     {
20867       if (unformat (i, "local_sa %d", &local_sa_id))
20868         ;
20869       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20870         ;
20871       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20872         ;
20873       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20874         ;
20875       else if (unformat (i, "del"))
20876         is_add = 0;
20877       else
20878         {
20879           clib_warning ("parse error '%U'", format_unformat_error, i);
20880           return -99;
20881         }
20882     }
20883
20884   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20885
20886   mp->local_sa_id = ntohl (local_sa_id);
20887   mp->remote_sa_id = ntohl (remote_sa_id);
20888   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20889   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20890   mp->is_add = is_add;
20891
20892   S (mp);
20893   W (ret);
20894   return ret;
20895 }
20896
20897 static int
20898 api_punt (vat_main_t * vam)
20899 {
20900   unformat_input_t *i = vam->input;
20901   vl_api_punt_t *mp;
20902   u32 ipv = ~0;
20903   u32 protocol = ~0;
20904   u32 port = ~0;
20905   int is_add = 1;
20906   int ret;
20907
20908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20909     {
20910       if (unformat (i, "ip %d", &ipv))
20911         ;
20912       else if (unformat (i, "protocol %d", &protocol))
20913         ;
20914       else if (unformat (i, "port %d", &port))
20915         ;
20916       else if (unformat (i, "del"))
20917         is_add = 0;
20918       else
20919         {
20920           clib_warning ("parse error '%U'", format_unformat_error, i);
20921           return -99;
20922         }
20923     }
20924
20925   M (PUNT, mp);
20926
20927   mp->is_add = (u8) is_add;
20928   mp->ipv = (u8) ipv;
20929   mp->l4_protocol = (u8) protocol;
20930   mp->l4_port = htons ((u16) port);
20931
20932   S (mp);
20933   W (ret);
20934   return ret;
20935 }
20936
20937 static void vl_api_ipsec_gre_tunnel_details_t_handler
20938   (vl_api_ipsec_gre_tunnel_details_t * mp)
20939 {
20940   vat_main_t *vam = &vat_main;
20941
20942   print (vam->ofp, "%11d%15U%15U%14d%14d",
20943          ntohl (mp->sw_if_index),
20944          format_ip4_address, &mp->src_address,
20945          format_ip4_address, &mp->dst_address,
20946          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20947 }
20948
20949 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20950   (vl_api_ipsec_gre_tunnel_details_t * mp)
20951 {
20952   vat_main_t *vam = &vat_main;
20953   vat_json_node_t *node = NULL;
20954   struct in_addr ip4;
20955
20956   if (VAT_JSON_ARRAY != vam->json_tree.type)
20957     {
20958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20959       vat_json_init_array (&vam->json_tree);
20960     }
20961   node = vat_json_array_add (&vam->json_tree);
20962
20963   vat_json_init_object (node);
20964   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20965   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20966   vat_json_object_add_ip4 (node, "src_address", ip4);
20967   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20968   vat_json_object_add_ip4 (node, "dst_address", ip4);
20969   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20970   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20971 }
20972
20973 static int
20974 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20975 {
20976   unformat_input_t *i = vam->input;
20977   vl_api_ipsec_gre_tunnel_dump_t *mp;
20978   vl_api_control_ping_t *mp_ping;
20979   u32 sw_if_index;
20980   u8 sw_if_index_set = 0;
20981   int ret;
20982
20983   /* Parse args required to build the message */
20984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20985     {
20986       if (unformat (i, "sw_if_index %d", &sw_if_index))
20987         sw_if_index_set = 1;
20988       else
20989         break;
20990     }
20991
20992   if (sw_if_index_set == 0)
20993     {
20994       sw_if_index = ~0;
20995     }
20996
20997   if (!vam->json_output)
20998     {
20999       print (vam->ofp, "%11s%15s%15s%14s%14s",
21000              "sw_if_index", "src_address", "dst_address",
21001              "local_sa_id", "remote_sa_id");
21002     }
21003
21004   /* Get list of gre-tunnel interfaces */
21005   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21006
21007   mp->sw_if_index = htonl (sw_if_index);
21008
21009   S (mp);
21010
21011   /* Use a control ping for synchronization */
21012   MPING (CONTROL_PING, mp_ping);
21013   S (mp_ping);
21014
21015   W (ret);
21016   return ret;
21017 }
21018
21019 static int
21020 api_delete_subif (vat_main_t * vam)
21021 {
21022   unformat_input_t *i = vam->input;
21023   vl_api_delete_subif_t *mp;
21024   u32 sw_if_index = ~0;
21025   int ret;
21026
21027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21028     {
21029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21030         ;
21031       if (unformat (i, "sw_if_index %d", &sw_if_index))
21032         ;
21033       else
21034         break;
21035     }
21036
21037   if (sw_if_index == ~0)
21038     {
21039       errmsg ("missing sw_if_index");
21040       return -99;
21041     }
21042
21043   /* Construct the API message */
21044   M (DELETE_SUBIF, mp);
21045   mp->sw_if_index = ntohl (sw_if_index);
21046
21047   S (mp);
21048   W (ret);
21049   return ret;
21050 }
21051
21052 #define foreach_pbb_vtr_op      \
21053 _("disable",  L2_VTR_DISABLED)  \
21054 _("pop",  L2_VTR_POP_2)         \
21055 _("push",  L2_VTR_PUSH_2)
21056
21057 static int
21058 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21059 {
21060   unformat_input_t *i = vam->input;
21061   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21062   u32 sw_if_index = ~0, vtr_op = ~0;
21063   u16 outer_tag = ~0;
21064   u8 dmac[6], smac[6];
21065   u8 dmac_set = 0, smac_set = 0;
21066   u16 vlanid = 0;
21067   u32 sid = ~0;
21068   u32 tmp;
21069   int ret;
21070
21071   /* Shut up coverity */
21072   memset (dmac, 0, sizeof (dmac));
21073   memset (smac, 0, sizeof (smac));
21074
21075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21076     {
21077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21078         ;
21079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21080         ;
21081       else if (unformat (i, "vtr_op %d", &vtr_op))
21082         ;
21083 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21084       foreach_pbb_vtr_op
21085 #undef _
21086         else if (unformat (i, "translate_pbb_stag"))
21087         {
21088           if (unformat (i, "%d", &tmp))
21089             {
21090               vtr_op = L2_VTR_TRANSLATE_2_1;
21091               outer_tag = tmp;
21092             }
21093           else
21094             {
21095               errmsg
21096                 ("translate_pbb_stag operation requires outer tag definition");
21097               return -99;
21098             }
21099         }
21100       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21101         dmac_set++;
21102       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21103         smac_set++;
21104       else if (unformat (i, "sid %d", &sid))
21105         ;
21106       else if (unformat (i, "vlanid %d", &tmp))
21107         vlanid = tmp;
21108       else
21109         {
21110           clib_warning ("parse error '%U'", format_unformat_error, i);
21111           return -99;
21112         }
21113     }
21114
21115   if ((sw_if_index == ~0) || (vtr_op == ~0))
21116     {
21117       errmsg ("missing sw_if_index or vtr operation");
21118       return -99;
21119     }
21120   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21121       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21122     {
21123       errmsg
21124         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21125       return -99;
21126     }
21127
21128   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21129   mp->sw_if_index = ntohl (sw_if_index);
21130   mp->vtr_op = ntohl (vtr_op);
21131   mp->outer_tag = ntohs (outer_tag);
21132   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21133   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21134   mp->b_vlanid = ntohs (vlanid);
21135   mp->i_sid = ntohl (sid);
21136
21137   S (mp);
21138   W (ret);
21139   return ret;
21140 }
21141
21142 static int
21143 api_flow_classify_set_interface (vat_main_t * vam)
21144 {
21145   unformat_input_t *i = vam->input;
21146   vl_api_flow_classify_set_interface_t *mp;
21147   u32 sw_if_index;
21148   int sw_if_index_set;
21149   u32 ip4_table_index = ~0;
21150   u32 ip6_table_index = ~0;
21151   u8 is_add = 1;
21152   int ret;
21153
21154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21155     {
21156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21157         sw_if_index_set = 1;
21158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21159         sw_if_index_set = 1;
21160       else if (unformat (i, "del"))
21161         is_add = 0;
21162       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21163         ;
21164       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21165         ;
21166       else
21167         {
21168           clib_warning ("parse error '%U'", format_unformat_error, i);
21169           return -99;
21170         }
21171     }
21172
21173   if (sw_if_index_set == 0)
21174     {
21175       errmsg ("missing interface name or sw_if_index");
21176       return -99;
21177     }
21178
21179   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21180
21181   mp->sw_if_index = ntohl (sw_if_index);
21182   mp->ip4_table_index = ntohl (ip4_table_index);
21183   mp->ip6_table_index = ntohl (ip6_table_index);
21184   mp->is_add = is_add;
21185
21186   S (mp);
21187   W (ret);
21188   return ret;
21189 }
21190
21191 static int
21192 api_flow_classify_dump (vat_main_t * vam)
21193 {
21194   unformat_input_t *i = vam->input;
21195   vl_api_flow_classify_dump_t *mp;
21196   vl_api_control_ping_t *mp_ping;
21197   u8 type = FLOW_CLASSIFY_N_TABLES;
21198   int ret;
21199
21200   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21201     ;
21202   else
21203     {
21204       errmsg ("classify table type must be specified");
21205       return -99;
21206     }
21207
21208   if (!vam->json_output)
21209     {
21210       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21211     }
21212
21213   M (FLOW_CLASSIFY_DUMP, mp);
21214   mp->type = type;
21215   /* send it... */
21216   S (mp);
21217
21218   /* Use a control ping for synchronization */
21219   MPING (CONTROL_PING, mp_ping);
21220   S (mp_ping);
21221
21222   /* Wait for a reply... */
21223   W (ret);
21224   return ret;
21225 }
21226
21227 static int
21228 api_feature_enable_disable (vat_main_t * vam)
21229 {
21230   unformat_input_t *i = vam->input;
21231   vl_api_feature_enable_disable_t *mp;
21232   u8 *arc_name = 0;
21233   u8 *feature_name = 0;
21234   u32 sw_if_index = ~0;
21235   u8 enable = 1;
21236   int ret;
21237
21238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21239     {
21240       if (unformat (i, "arc_name %s", &arc_name))
21241         ;
21242       else if (unformat (i, "feature_name %s", &feature_name))
21243         ;
21244       else
21245         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21246         ;
21247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21248         ;
21249       else if (unformat (i, "disable"))
21250         enable = 0;
21251       else
21252         break;
21253     }
21254
21255   if (arc_name == 0)
21256     {
21257       errmsg ("missing arc name");
21258       return -99;
21259     }
21260   if (vec_len (arc_name) > 63)
21261     {
21262       errmsg ("arc name too long");
21263     }
21264
21265   if (feature_name == 0)
21266     {
21267       errmsg ("missing feature name");
21268       return -99;
21269     }
21270   if (vec_len (feature_name) > 63)
21271     {
21272       errmsg ("feature name too long");
21273     }
21274
21275   if (sw_if_index == ~0)
21276     {
21277       errmsg ("missing interface name or sw_if_index");
21278       return -99;
21279     }
21280
21281   /* Construct the API message */
21282   M (FEATURE_ENABLE_DISABLE, mp);
21283   mp->sw_if_index = ntohl (sw_if_index);
21284   mp->enable = enable;
21285   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21286   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21287   vec_free (arc_name);
21288   vec_free (feature_name);
21289
21290   S (mp);
21291   W (ret);
21292   return ret;
21293 }
21294
21295 static int
21296 api_sw_interface_tag_add_del (vat_main_t * vam)
21297 {
21298   unformat_input_t *i = vam->input;
21299   vl_api_sw_interface_tag_add_del_t *mp;
21300   u32 sw_if_index = ~0;
21301   u8 *tag = 0;
21302   u8 enable = 1;
21303   int ret;
21304
21305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21306     {
21307       if (unformat (i, "tag %s", &tag))
21308         ;
21309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21310         ;
21311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21312         ;
21313       else if (unformat (i, "del"))
21314         enable = 0;
21315       else
21316         break;
21317     }
21318
21319   if (sw_if_index == ~0)
21320     {
21321       errmsg ("missing interface name or sw_if_index");
21322       return -99;
21323     }
21324
21325   if (enable && (tag == 0))
21326     {
21327       errmsg ("no tag specified");
21328       return -99;
21329     }
21330
21331   /* Construct the API message */
21332   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21333   mp->sw_if_index = ntohl (sw_if_index);
21334   mp->is_add = enable;
21335   if (enable)
21336     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21337   vec_free (tag);
21338
21339   S (mp);
21340   W (ret);
21341   return ret;
21342 }
21343
21344 static void vl_api_l2_xconnect_details_t_handler
21345   (vl_api_l2_xconnect_details_t * mp)
21346 {
21347   vat_main_t *vam = &vat_main;
21348
21349   print (vam->ofp, "%15d%15d",
21350          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21351 }
21352
21353 static void vl_api_l2_xconnect_details_t_handler_json
21354   (vl_api_l2_xconnect_details_t * mp)
21355 {
21356   vat_main_t *vam = &vat_main;
21357   vat_json_node_t *node = NULL;
21358
21359   if (VAT_JSON_ARRAY != vam->json_tree.type)
21360     {
21361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21362       vat_json_init_array (&vam->json_tree);
21363     }
21364   node = vat_json_array_add (&vam->json_tree);
21365
21366   vat_json_init_object (node);
21367   vat_json_object_add_uint (node, "rx_sw_if_index",
21368                             ntohl (mp->rx_sw_if_index));
21369   vat_json_object_add_uint (node, "tx_sw_if_index",
21370                             ntohl (mp->tx_sw_if_index));
21371 }
21372
21373 static int
21374 api_l2_xconnect_dump (vat_main_t * vam)
21375 {
21376   vl_api_l2_xconnect_dump_t *mp;
21377   vl_api_control_ping_t *mp_ping;
21378   int ret;
21379
21380   if (!vam->json_output)
21381     {
21382       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21383     }
21384
21385   M (L2_XCONNECT_DUMP, mp);
21386
21387   S (mp);
21388
21389   /* Use a control ping for synchronization */
21390   MPING (CONTROL_PING, mp_ping);
21391   S (mp_ping);
21392
21393   W (ret);
21394   return ret;
21395 }
21396
21397 static int
21398 api_sw_interface_set_mtu (vat_main_t * vam)
21399 {
21400   unformat_input_t *i = vam->input;
21401   vl_api_sw_interface_set_mtu_t *mp;
21402   u32 sw_if_index = ~0;
21403   u32 mtu = 0;
21404   int ret;
21405
21406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21407     {
21408       if (unformat (i, "mtu %d", &mtu))
21409         ;
21410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21411         ;
21412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21413         ;
21414       else
21415         break;
21416     }
21417
21418   if (sw_if_index == ~0)
21419     {
21420       errmsg ("missing interface name or sw_if_index");
21421       return -99;
21422     }
21423
21424   if (mtu == 0)
21425     {
21426       errmsg ("no mtu specified");
21427       return -99;
21428     }
21429
21430   /* Construct the API message */
21431   M (SW_INTERFACE_SET_MTU, mp);
21432   mp->sw_if_index = ntohl (sw_if_index);
21433   mp->mtu = ntohs ((u16) mtu);
21434
21435   S (mp);
21436   W (ret);
21437   return ret;
21438 }
21439
21440 static int
21441 api_p2p_ethernet_add (vat_main_t * vam)
21442 {
21443   unformat_input_t *i = vam->input;
21444   vl_api_p2p_ethernet_add_t *mp;
21445   u32 parent_if_index = ~0;
21446   u32 sub_id = ~0;
21447   u8 remote_mac[6];
21448   u8 mac_set = 0;
21449   int ret;
21450
21451   memset (remote_mac, 0, sizeof (remote_mac));
21452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21453     {
21454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21455         ;
21456       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21457         ;
21458       else
21459         if (unformat
21460             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21461         mac_set++;
21462       else if (unformat (i, "sub_id %d", &sub_id))
21463         ;
21464       else
21465         {
21466           clib_warning ("parse error '%U'", format_unformat_error, i);
21467           return -99;
21468         }
21469     }
21470
21471   if (parent_if_index == ~0)
21472     {
21473       errmsg ("missing interface name or sw_if_index");
21474       return -99;
21475     }
21476   if (mac_set == 0)
21477     {
21478       errmsg ("missing remote mac address");
21479       return -99;
21480     }
21481   if (sub_id == ~0)
21482     {
21483       errmsg ("missing sub-interface id");
21484       return -99;
21485     }
21486
21487   M (P2P_ETHERNET_ADD, mp);
21488   mp->parent_if_index = ntohl (parent_if_index);
21489   mp->subif_id = ntohl (sub_id);
21490   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21491
21492   S (mp);
21493   W (ret);
21494   return ret;
21495 }
21496
21497 static int
21498 api_p2p_ethernet_del (vat_main_t * vam)
21499 {
21500   unformat_input_t *i = vam->input;
21501   vl_api_p2p_ethernet_del_t *mp;
21502   u32 parent_if_index = ~0;
21503   u8 remote_mac[6];
21504   u8 mac_set = 0;
21505   int ret;
21506
21507   memset (remote_mac, 0, sizeof (remote_mac));
21508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21509     {
21510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21511         ;
21512       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21513         ;
21514       else
21515         if (unformat
21516             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21517         mac_set++;
21518       else
21519         {
21520           clib_warning ("parse error '%U'", format_unformat_error, i);
21521           return -99;
21522         }
21523     }
21524
21525   if (parent_if_index == ~0)
21526     {
21527       errmsg ("missing interface name or sw_if_index");
21528       return -99;
21529     }
21530   if (mac_set == 0)
21531     {
21532       errmsg ("missing remote mac address");
21533       return -99;
21534     }
21535
21536   M (P2P_ETHERNET_DEL, mp);
21537   mp->parent_if_index = ntohl (parent_if_index);
21538   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21539
21540   S (mp);
21541   W (ret);
21542   return ret;
21543 }
21544
21545 static int
21546 api_lldp_config (vat_main_t * vam)
21547 {
21548   unformat_input_t *i = vam->input;
21549   vl_api_lldp_config_t *mp;
21550   int tx_hold = 0;
21551   int tx_interval = 0;
21552   u8 *sys_name = NULL;
21553   int ret;
21554
21555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21556     {
21557       if (unformat (i, "system-name %s", &sys_name))
21558         ;
21559       else if (unformat (i, "tx-hold %d", &tx_hold))
21560         ;
21561       else if (unformat (i, "tx-interval %d", &tx_interval))
21562         ;
21563       else
21564         {
21565           clib_warning ("parse error '%U'", format_unformat_error, i);
21566           return -99;
21567         }
21568     }
21569
21570   vec_add1 (sys_name, 0);
21571
21572   M (LLDP_CONFIG, mp);
21573   mp->tx_hold = htonl (tx_hold);
21574   mp->tx_interval = htonl (tx_interval);
21575   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21576   vec_free (sys_name);
21577
21578   S (mp);
21579   W (ret);
21580   return ret;
21581 }
21582
21583 static int
21584 api_sw_interface_set_lldp (vat_main_t * vam)
21585 {
21586   unformat_input_t *i = vam->input;
21587   vl_api_sw_interface_set_lldp_t *mp;
21588   u32 sw_if_index = ~0;
21589   u32 enable = 1;
21590   u8 *port_desc = NULL, *mgmt_oid = NULL;
21591   ip4_address_t ip4_addr;
21592   ip6_address_t ip6_addr;
21593   int ret;
21594
21595   memset (&ip4_addr, 0, sizeof (ip4_addr));
21596   memset (&ip6_addr, 0, sizeof (ip6_addr));
21597
21598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21599     {
21600       if (unformat (i, "disable"))
21601         enable = 0;
21602       else
21603         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21604         ;
21605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21606         ;
21607       else if (unformat (i, "port-desc %s", &port_desc))
21608         ;
21609       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21610         ;
21611       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21612         ;
21613       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21614         ;
21615       else
21616         break;
21617     }
21618
21619   if (sw_if_index == ~0)
21620     {
21621       errmsg ("missing interface name or sw_if_index");
21622       return -99;
21623     }
21624
21625   /* Construct the API message */
21626   vec_add1 (port_desc, 0);
21627   vec_add1 (mgmt_oid, 0);
21628   M (SW_INTERFACE_SET_LLDP, mp);
21629   mp->sw_if_index = ntohl (sw_if_index);
21630   mp->enable = enable;
21631   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21632   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21633   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21634   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21635   vec_free (port_desc);
21636   vec_free (mgmt_oid);
21637
21638   S (mp);
21639   W (ret);
21640   return ret;
21641 }
21642
21643 static int
21644 api_tcp_configure_src_addresses (vat_main_t * vam)
21645 {
21646   vl_api_tcp_configure_src_addresses_t *mp;
21647   unformat_input_t *i = vam->input;
21648   ip4_address_t v4first, v4last;
21649   ip6_address_t v6first, v6last;
21650   u8 range_set = 0;
21651   u32 vrf_id = 0;
21652   int ret;
21653
21654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21655     {
21656       if (unformat (i, "%U - %U",
21657                     unformat_ip4_address, &v4first,
21658                     unformat_ip4_address, &v4last))
21659         {
21660           if (range_set)
21661             {
21662               errmsg ("one range per message (range already set)");
21663               return -99;
21664             }
21665           range_set = 1;
21666         }
21667       else if (unformat (i, "%U - %U",
21668                          unformat_ip6_address, &v6first,
21669                          unformat_ip6_address, &v6last))
21670         {
21671           if (range_set)
21672             {
21673               errmsg ("one range per message (range already set)");
21674               return -99;
21675             }
21676           range_set = 2;
21677         }
21678       else if (unformat (i, "vrf %d", &vrf_id))
21679         ;
21680       else
21681         break;
21682     }
21683
21684   if (range_set == 0)
21685     {
21686       errmsg ("address range not set");
21687       return -99;
21688     }
21689
21690   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21691   mp->vrf_id = ntohl (vrf_id);
21692   /* ipv6? */
21693   if (range_set == 2)
21694     {
21695       mp->is_ipv6 = 1;
21696       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21697       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21698     }
21699   else
21700     {
21701       mp->is_ipv6 = 0;
21702       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21703       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21704     }
21705   S (mp);
21706   W (ret);
21707   return ret;
21708 }
21709
21710 static void vl_api_app_namespace_add_del_reply_t_handler
21711   (vl_api_app_namespace_add_del_reply_t * mp)
21712 {
21713   vat_main_t *vam = &vat_main;
21714   i32 retval = ntohl (mp->retval);
21715   if (vam->async_mode)
21716     {
21717       vam->async_errors += (retval < 0);
21718     }
21719   else
21720     {
21721       vam->retval = retval;
21722       if (retval == 0)
21723         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21724       vam->result_ready = 1;
21725     }
21726 }
21727
21728 static void vl_api_app_namespace_add_del_reply_t_handler_json
21729   (vl_api_app_namespace_add_del_reply_t * mp)
21730 {
21731   vat_main_t *vam = &vat_main;
21732   vat_json_node_t node;
21733
21734   vat_json_init_object (&node);
21735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21736   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21737
21738   vat_json_print (vam->ofp, &node);
21739   vat_json_free (&node);
21740
21741   vam->retval = ntohl (mp->retval);
21742   vam->result_ready = 1;
21743 }
21744
21745 static int
21746 api_app_namespace_add_del (vat_main_t * vam)
21747 {
21748   vl_api_app_namespace_add_del_t *mp;
21749   unformat_input_t *i = vam->input;
21750   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21751   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21752   u64 secret;
21753   int ret;
21754
21755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21756     {
21757       if (unformat (i, "id %_%v%_", &ns_id))
21758         ;
21759       else if (unformat (i, "secret %lu", &secret))
21760         secret_set = 1;
21761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21762         sw_if_index_set = 1;
21763       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21764         ;
21765       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21766         ;
21767       else
21768         break;
21769     }
21770   if (!ns_id || !secret_set || !sw_if_index_set)
21771     {
21772       errmsg ("namespace id, secret and sw_if_index must be set");
21773       return -99;
21774     }
21775   if (vec_len (ns_id) > 64)
21776     {
21777       errmsg ("namespace id too long");
21778       return -99;
21779     }
21780   M (APP_NAMESPACE_ADD_DEL, mp);
21781
21782   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21783   mp->namespace_id_len = vec_len (ns_id);
21784   mp->secret = clib_host_to_net_u64 (secret);
21785   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21786   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21787   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21788   vec_free (ns_id);
21789   S (mp);
21790   W (ret);
21791   return ret;
21792 }
21793
21794 static int
21795 api_memfd_segment_create (vat_main_t * vam)
21796 {
21797 #if VPP_API_TEST_BUILTIN == 0
21798   unformat_input_t *i = vam->input;
21799   vl_api_memfd_segment_create_t *mp;
21800   u64 size = 64 << 20;
21801   int ret;
21802
21803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21804     {
21805       if (unformat (i, "size %U", unformat_memory_size, &size))
21806         ;
21807       else
21808         break;
21809     }
21810
21811   M (MEMFD_SEGMENT_CREATE, mp);
21812   mp->requested_size = size;
21813   S (mp);
21814   W (ret);
21815   return ret;
21816
21817 #else
21818   errmsg ("memfd_segment_create (builtin) not supported");
21819   return -99;
21820 #endif
21821 }
21822
21823 static int
21824 api_sock_init_shm (vat_main_t * vam)
21825 {
21826 #if VPP_API_TEST_BUILTIN == 0
21827   unformat_input_t *i = vam->input;
21828   vl_api_shm_elem_config_t *config = 0;
21829   u64 size = 64 << 20;
21830   int rv;
21831
21832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21833     {
21834       if (unformat (i, "size %U", unformat_memory_size, &size))
21835         ;
21836       else
21837         break;
21838     }
21839
21840   /* Try customized config to see if it works */
21841   vec_validate (config, 3);
21842   config[0].type = VL_API_VLIB_RING;
21843   config[0].count = 256;
21844   config[0].size = 256;
21845   config[1].type = VL_API_CLIENT_RING;
21846   config[1].count = 256;
21847   config[1].size = 1024;
21848   config[2].type = VL_API_CLIENT_RING;
21849   config[2].count = 8;
21850   config[2].size = 4096;
21851   config[3].type = VL_API_QUEUE;
21852   config[3].count = 256;
21853   config[3].size = sizeof (uword);
21854   rv = vl_socket_client_init_shm (config);
21855   if (!rv)
21856     vam->client_index_invalid = 1;
21857   return rv;
21858 #else
21859   return -99;
21860 #endif
21861 }
21862
21863 static int
21864 api_dns_enable_disable (vat_main_t * vam)
21865 {
21866   unformat_input_t *line_input = vam->input;
21867   vl_api_dns_enable_disable_t *mp;
21868   u8 enable_disable = 1;
21869   int ret;
21870
21871   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21872     {
21873       if (unformat (line_input, "disable"))
21874         enable_disable = 0;
21875       if (unformat (line_input, "enable"))
21876         enable_disable = 1;
21877       else
21878         break;
21879     }
21880
21881   /* Construct the API message */
21882   M (DNS_ENABLE_DISABLE, mp);
21883   mp->enable = enable_disable;
21884
21885   /* send it... */
21886   S (mp);
21887   /* Wait for the reply */
21888   W (ret);
21889   return ret;
21890 }
21891
21892 static int
21893 api_dns_resolve_name (vat_main_t * vam)
21894 {
21895   unformat_input_t *line_input = vam->input;
21896   vl_api_dns_resolve_name_t *mp;
21897   u8 *name = 0;
21898   int ret;
21899
21900   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21901     {
21902       if (unformat (line_input, "%s", &name))
21903         ;
21904       else
21905         break;
21906     }
21907
21908   if (vec_len (name) > 127)
21909     {
21910       errmsg ("name too long");
21911       return -99;
21912     }
21913
21914   /* Construct the API message */
21915   M (DNS_RESOLVE_NAME, mp);
21916   memcpy (mp->name, name, vec_len (name));
21917   vec_free (name);
21918
21919   /* send it... */
21920   S (mp);
21921   /* Wait for the reply */
21922   W (ret);
21923   return ret;
21924 }
21925
21926 static int
21927 api_dns_resolve_ip (vat_main_t * vam)
21928 {
21929   unformat_input_t *line_input = vam->input;
21930   vl_api_dns_resolve_ip_t *mp;
21931   int is_ip6 = -1;
21932   ip4_address_t addr4;
21933   ip6_address_t addr6;
21934   int ret;
21935
21936   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21937     {
21938       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21939         is_ip6 = 1;
21940       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21941         is_ip6 = 0;
21942       else
21943         break;
21944     }
21945
21946   if (is_ip6 == -1)
21947     {
21948       errmsg ("missing address");
21949       return -99;
21950     }
21951
21952   /* Construct the API message */
21953   M (DNS_RESOLVE_IP, mp);
21954   mp->is_ip6 = is_ip6;
21955   if (is_ip6)
21956     memcpy (mp->address, &addr6, sizeof (addr6));
21957   else
21958     memcpy (mp->address, &addr4, sizeof (addr4));
21959
21960   /* send it... */
21961   S (mp);
21962   /* Wait for the reply */
21963   W (ret);
21964   return ret;
21965 }
21966
21967 static int
21968 api_dns_name_server_add_del (vat_main_t * vam)
21969 {
21970   unformat_input_t *i = vam->input;
21971   vl_api_dns_name_server_add_del_t *mp;
21972   u8 is_add = 1;
21973   ip6_address_t ip6_server;
21974   ip4_address_t ip4_server;
21975   int ip6_set = 0;
21976   int ip4_set = 0;
21977   int ret = 0;
21978
21979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21980     {
21981       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21982         ip6_set = 1;
21983       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21984         ip4_set = 1;
21985       else if (unformat (i, "del"))
21986         is_add = 0;
21987       else
21988         {
21989           clib_warning ("parse error '%U'", format_unformat_error, i);
21990           return -99;
21991         }
21992     }
21993
21994   if (ip4_set && ip6_set)
21995     {
21996       errmsg ("Only one server address allowed per message");
21997       return -99;
21998     }
21999   if ((ip4_set + ip6_set) == 0)
22000     {
22001       errmsg ("Server address required");
22002       return -99;
22003     }
22004
22005   /* Construct the API message */
22006   M (DNS_NAME_SERVER_ADD_DEL, mp);
22007
22008   if (ip6_set)
22009     {
22010       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22011       mp->is_ip6 = 1;
22012     }
22013   else
22014     {
22015       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22016       mp->is_ip6 = 0;
22017     }
22018
22019   mp->is_add = is_add;
22020
22021   /* send it... */
22022   S (mp);
22023
22024   /* Wait for a reply, return good/bad news  */
22025   W (ret);
22026   return ret;
22027 }
22028
22029 static void
22030 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22031 {
22032   vat_main_t *vam = &vat_main;
22033
22034   if (mp->is_ip4)
22035     {
22036       print (vam->ofp,
22037              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22038              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22039              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22040              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22041              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22042              clib_net_to_host_u32 (mp->action_index), mp->tag);
22043     }
22044   else
22045     {
22046       print (vam->ofp,
22047              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22048              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22049              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22050              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22051              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22052              clib_net_to_host_u32 (mp->action_index), mp->tag);
22053     }
22054 }
22055
22056 static void
22057 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22058                                              mp)
22059 {
22060   vat_main_t *vam = &vat_main;
22061   vat_json_node_t *node = NULL;
22062   struct in6_addr ip6;
22063   struct in_addr ip4;
22064
22065   if (VAT_JSON_ARRAY != vam->json_tree.type)
22066     {
22067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22068       vat_json_init_array (&vam->json_tree);
22069     }
22070   node = vat_json_array_add (&vam->json_tree);
22071   vat_json_init_object (node);
22072
22073   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22074   vat_json_object_add_uint (node, "appns_index",
22075                             clib_net_to_host_u32 (mp->appns_index));
22076   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22077   vat_json_object_add_uint (node, "scope", mp->scope);
22078   vat_json_object_add_uint (node, "action_index",
22079                             clib_net_to_host_u32 (mp->action_index));
22080   vat_json_object_add_uint (node, "lcl_port",
22081                             clib_net_to_host_u16 (mp->lcl_port));
22082   vat_json_object_add_uint (node, "rmt_port",
22083                             clib_net_to_host_u16 (mp->rmt_port));
22084   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22085   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22086   vat_json_object_add_string_copy (node, "tag", mp->tag);
22087   if (mp->is_ip4)
22088     {
22089       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22090       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22091       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22092       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22093     }
22094   else
22095     {
22096       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22097       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22098       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22099       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22100     }
22101 }
22102
22103 static int
22104 api_session_rule_add_del (vat_main_t * vam)
22105 {
22106   vl_api_session_rule_add_del_t *mp;
22107   unformat_input_t *i = vam->input;
22108   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22109   u32 appns_index = 0, scope = 0;
22110   ip4_address_t lcl_ip4, rmt_ip4;
22111   ip6_address_t lcl_ip6, rmt_ip6;
22112   u8 is_ip4 = 1, conn_set = 0;
22113   u8 is_add = 1, *tag = 0;
22114   int ret;
22115
22116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22117     {
22118       if (unformat (i, "del"))
22119         is_add = 0;
22120       else if (unformat (i, "add"))
22121         ;
22122       else if (unformat (i, "proto tcp"))
22123         proto = 0;
22124       else if (unformat (i, "proto udp"))
22125         proto = 1;
22126       else if (unformat (i, "appns %d", &appns_index))
22127         ;
22128       else if (unformat (i, "scope %d", &scope))
22129         ;
22130       else if (unformat (i, "tag %_%v%_", &tag))
22131         ;
22132       else
22133         if (unformat
22134             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22135              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22136              &rmt_port))
22137         {
22138           is_ip4 = 1;
22139           conn_set = 1;
22140         }
22141       else
22142         if (unformat
22143             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22144              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22145              &rmt_port))
22146         {
22147           is_ip4 = 0;
22148           conn_set = 1;
22149         }
22150       else if (unformat (i, "action %d", &action))
22151         ;
22152       else
22153         break;
22154     }
22155   if (proto == ~0 || !conn_set || action == ~0)
22156     {
22157       errmsg ("transport proto, connection and action must be set");
22158       return -99;
22159     }
22160
22161   if (scope > 3)
22162     {
22163       errmsg ("scope should be 0-3");
22164       return -99;
22165     }
22166
22167   M (SESSION_RULE_ADD_DEL, mp);
22168
22169   mp->is_ip4 = is_ip4;
22170   mp->transport_proto = proto;
22171   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22172   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22173   mp->lcl_plen = lcl_plen;
22174   mp->rmt_plen = rmt_plen;
22175   mp->action_index = clib_host_to_net_u32 (action);
22176   mp->appns_index = clib_host_to_net_u32 (appns_index);
22177   mp->scope = scope;
22178   mp->is_add = is_add;
22179   if (is_ip4)
22180     {
22181       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22182       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22183     }
22184   else
22185     {
22186       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22187       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22188     }
22189   if (tag)
22190     {
22191       clib_memcpy (mp->tag, tag, vec_len (tag));
22192       vec_free (tag);
22193     }
22194
22195   S (mp);
22196   W (ret);
22197   return ret;
22198 }
22199
22200 static int
22201 api_session_rules_dump (vat_main_t * vam)
22202 {
22203   vl_api_session_rules_dump_t *mp;
22204   vl_api_control_ping_t *mp_ping;
22205   int ret;
22206
22207   if (!vam->json_output)
22208     {
22209       print (vam->ofp, "%=20s", "Session Rules");
22210     }
22211
22212   M (SESSION_RULES_DUMP, mp);
22213   /* send it... */
22214   S (mp);
22215
22216   /* Use a control ping for synchronization */
22217   MPING (CONTROL_PING, mp_ping);
22218   S (mp_ping);
22219
22220   /* Wait for a reply... */
22221   W (ret);
22222   return ret;
22223 }
22224
22225 static int
22226 api_ip_container_proxy_add_del (vat_main_t * vam)
22227 {
22228   vl_api_ip_container_proxy_add_del_t *mp;
22229   unformat_input_t *i = vam->input;
22230   u32 plen = ~0, sw_if_index = ~0;
22231   ip4_address_t ip4;
22232   ip6_address_t ip6;
22233   u8 is_ip4 = 1;
22234   u8 is_add = 1;
22235   int ret;
22236
22237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22238     {
22239       if (unformat (i, "del"))
22240         is_add = 0;
22241       else if (unformat (i, "add"))
22242         ;
22243       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22244         {
22245           is_ip4 = 1;
22246           plen = 32;
22247         }
22248       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22249         {
22250           is_ip4 = 0;
22251           plen = 128;
22252         }
22253       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22254         ;
22255       else
22256         break;
22257     }
22258   if (sw_if_index == ~0 || plen == ~0)
22259     {
22260       errmsg ("address and sw_if_index must be set");
22261       return -99;
22262     }
22263
22264   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22265
22266   mp->is_ip4 = is_ip4;
22267   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22268   mp->plen = plen;
22269   mp->is_add = is_add;
22270   if (is_ip4)
22271     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22272   else
22273     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22274
22275   S (mp);
22276   W (ret);
22277   return ret;
22278 }
22279
22280 static int
22281 q_or_quit (vat_main_t * vam)
22282 {
22283 #if VPP_API_TEST_BUILTIN == 0
22284   longjmp (vam->jump_buf, 1);
22285 #endif
22286   return 0;                     /* not so much */
22287 }
22288
22289 static int
22290 q (vat_main_t * vam)
22291 {
22292   return q_or_quit (vam);
22293 }
22294
22295 static int
22296 quit (vat_main_t * vam)
22297 {
22298   return q_or_quit (vam);
22299 }
22300
22301 static int
22302 comment (vat_main_t * vam)
22303 {
22304   return 0;
22305 }
22306
22307 static int
22308 cmd_cmp (void *a1, void *a2)
22309 {
22310   u8 **c1 = a1;
22311   u8 **c2 = a2;
22312
22313   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22314 }
22315
22316 static int
22317 help (vat_main_t * vam)
22318 {
22319   u8 **cmds = 0;
22320   u8 *name = 0;
22321   hash_pair_t *p;
22322   unformat_input_t *i = vam->input;
22323   int j;
22324
22325   if (unformat (i, "%s", &name))
22326     {
22327       uword *hs;
22328
22329       vec_add1 (name, 0);
22330
22331       hs = hash_get_mem (vam->help_by_name, name);
22332       if (hs)
22333         print (vam->ofp, "usage: %s %s", name, hs[0]);
22334       else
22335         print (vam->ofp, "No such msg / command '%s'", name);
22336       vec_free (name);
22337       return 0;
22338     }
22339
22340   print (vam->ofp, "Help is available for the following:");
22341
22342     /* *INDENT-OFF* */
22343     hash_foreach_pair (p, vam->function_by_name,
22344     ({
22345       vec_add1 (cmds, (u8 *)(p->key));
22346     }));
22347     /* *INDENT-ON* */
22348
22349   vec_sort_with_function (cmds, cmd_cmp);
22350
22351   for (j = 0; j < vec_len (cmds); j++)
22352     print (vam->ofp, "%s", cmds[j]);
22353
22354   vec_free (cmds);
22355   return 0;
22356 }
22357
22358 static int
22359 set (vat_main_t * vam)
22360 {
22361   u8 *name = 0, *value = 0;
22362   unformat_input_t *i = vam->input;
22363
22364   if (unformat (i, "%s", &name))
22365     {
22366       /* The input buffer is a vector, not a string. */
22367       value = vec_dup (i->buffer);
22368       vec_delete (value, i->index, 0);
22369       /* Almost certainly has a trailing newline */
22370       if (value[vec_len (value) - 1] == '\n')
22371         value[vec_len (value) - 1] = 0;
22372       /* Make sure it's a proper string, one way or the other */
22373       vec_add1 (value, 0);
22374       (void) clib_macro_set_value (&vam->macro_main,
22375                                    (char *) name, (char *) value);
22376     }
22377   else
22378     errmsg ("usage: set <name> <value>");
22379
22380   vec_free (name);
22381   vec_free (value);
22382   return 0;
22383 }
22384
22385 static int
22386 unset (vat_main_t * vam)
22387 {
22388   u8 *name = 0;
22389
22390   if (unformat (vam->input, "%s", &name))
22391     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22392       errmsg ("unset: %s wasn't set", name);
22393   vec_free (name);
22394   return 0;
22395 }
22396
22397 typedef struct
22398 {
22399   u8 *name;
22400   u8 *value;
22401 } macro_sort_t;
22402
22403
22404 static int
22405 macro_sort_cmp (void *a1, void *a2)
22406 {
22407   macro_sort_t *s1 = a1;
22408   macro_sort_t *s2 = a2;
22409
22410   return strcmp ((char *) (s1->name), (char *) (s2->name));
22411 }
22412
22413 static int
22414 dump_macro_table (vat_main_t * vam)
22415 {
22416   macro_sort_t *sort_me = 0, *sm;
22417   int i;
22418   hash_pair_t *p;
22419
22420     /* *INDENT-OFF* */
22421     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22422     ({
22423       vec_add2 (sort_me, sm, 1);
22424       sm->name = (u8 *)(p->key);
22425       sm->value = (u8 *) (p->value[0]);
22426     }));
22427     /* *INDENT-ON* */
22428
22429   vec_sort_with_function (sort_me, macro_sort_cmp);
22430
22431   if (vec_len (sort_me))
22432     print (vam->ofp, "%-15s%s", "Name", "Value");
22433   else
22434     print (vam->ofp, "The macro table is empty...");
22435
22436   for (i = 0; i < vec_len (sort_me); i++)
22437     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22438   return 0;
22439 }
22440
22441 static int
22442 dump_node_table (vat_main_t * vam)
22443 {
22444   int i, j;
22445   vlib_node_t *node, *next_node;
22446
22447   if (vec_len (vam->graph_nodes) == 0)
22448     {
22449       print (vam->ofp, "Node table empty, issue get_node_graph...");
22450       return 0;
22451     }
22452
22453   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22454     {
22455       node = vam->graph_nodes[i];
22456       print (vam->ofp, "[%d] %s", i, node->name);
22457       for (j = 0; j < vec_len (node->next_nodes); j++)
22458         {
22459           if (node->next_nodes[j] != ~0)
22460             {
22461               next_node = vam->graph_nodes[node->next_nodes[j]];
22462               print (vam->ofp, "  [%d] %s", j, next_node->name);
22463             }
22464         }
22465     }
22466   return 0;
22467 }
22468
22469 static int
22470 value_sort_cmp (void *a1, void *a2)
22471 {
22472   name_sort_t *n1 = a1;
22473   name_sort_t *n2 = a2;
22474
22475   if (n1->value < n2->value)
22476     return -1;
22477   if (n1->value > n2->value)
22478     return 1;
22479   return 0;
22480 }
22481
22482
22483 static int
22484 dump_msg_api_table (vat_main_t * vam)
22485 {
22486   api_main_t *am = &api_main;
22487   name_sort_t *nses = 0, *ns;
22488   hash_pair_t *hp;
22489   int i;
22490
22491   /* *INDENT-OFF* */
22492   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22493   ({
22494     vec_add2 (nses, ns, 1);
22495     ns->name = (u8 *)(hp->key);
22496     ns->value = (u32) hp->value[0];
22497   }));
22498   /* *INDENT-ON* */
22499
22500   vec_sort_with_function (nses, value_sort_cmp);
22501
22502   for (i = 0; i < vec_len (nses); i++)
22503     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22504   vec_free (nses);
22505   return 0;
22506 }
22507
22508 static int
22509 get_msg_id (vat_main_t * vam)
22510 {
22511   u8 *name_and_crc;
22512   u32 message_index;
22513
22514   if (unformat (vam->input, "%s", &name_and_crc))
22515     {
22516       message_index = vl_msg_api_get_msg_index (name_and_crc);
22517       if (message_index == ~0)
22518         {
22519           print (vam->ofp, " '%s' not found", name_and_crc);
22520           return 0;
22521         }
22522       print (vam->ofp, " '%s' has message index %d",
22523              name_and_crc, message_index);
22524       return 0;
22525     }
22526   errmsg ("name_and_crc required...");
22527   return 0;
22528 }
22529
22530 static int
22531 search_node_table (vat_main_t * vam)
22532 {
22533   unformat_input_t *line_input = vam->input;
22534   u8 *node_to_find;
22535   int j;
22536   vlib_node_t *node, *next_node;
22537   uword *p;
22538
22539   if (vam->graph_node_index_by_name == 0)
22540     {
22541       print (vam->ofp, "Node table empty, issue get_node_graph...");
22542       return 0;
22543     }
22544
22545   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22546     {
22547       if (unformat (line_input, "%s", &node_to_find))
22548         {
22549           vec_add1 (node_to_find, 0);
22550           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22551           if (p == 0)
22552             {
22553               print (vam->ofp, "%s not found...", node_to_find);
22554               goto out;
22555             }
22556           node = vam->graph_nodes[p[0]];
22557           print (vam->ofp, "[%d] %s", p[0], node->name);
22558           for (j = 0; j < vec_len (node->next_nodes); j++)
22559             {
22560               if (node->next_nodes[j] != ~0)
22561                 {
22562                   next_node = vam->graph_nodes[node->next_nodes[j]];
22563                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22564                 }
22565             }
22566         }
22567
22568       else
22569         {
22570           clib_warning ("parse error '%U'", format_unformat_error,
22571                         line_input);
22572           return -99;
22573         }
22574
22575     out:
22576       vec_free (node_to_find);
22577
22578     }
22579
22580   return 0;
22581 }
22582
22583
22584 static int
22585 script (vat_main_t * vam)
22586 {
22587 #if (VPP_API_TEST_BUILTIN==0)
22588   u8 *s = 0;
22589   char *save_current_file;
22590   unformat_input_t save_input;
22591   jmp_buf save_jump_buf;
22592   u32 save_line_number;
22593
22594   FILE *new_fp, *save_ifp;
22595
22596   if (unformat (vam->input, "%s", &s))
22597     {
22598       new_fp = fopen ((char *) s, "r");
22599       if (new_fp == 0)
22600         {
22601           errmsg ("Couldn't open script file %s", s);
22602           vec_free (s);
22603           return -99;
22604         }
22605     }
22606   else
22607     {
22608       errmsg ("Missing script name");
22609       return -99;
22610     }
22611
22612   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22613   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22614   save_ifp = vam->ifp;
22615   save_line_number = vam->input_line_number;
22616   save_current_file = (char *) vam->current_file;
22617
22618   vam->input_line_number = 0;
22619   vam->ifp = new_fp;
22620   vam->current_file = s;
22621   do_one_file (vam);
22622
22623   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22624   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22625   vam->ifp = save_ifp;
22626   vam->input_line_number = save_line_number;
22627   vam->current_file = (u8 *) save_current_file;
22628   vec_free (s);
22629
22630   return 0;
22631 #else
22632   clib_warning ("use the exec command...");
22633   return -99;
22634 #endif
22635 }
22636
22637 static int
22638 echo (vat_main_t * vam)
22639 {
22640   print (vam->ofp, "%v", vam->input->buffer);
22641   return 0;
22642 }
22643
22644 /* List of API message constructors, CLI names map to api_xxx */
22645 #define foreach_vpe_api_msg                                             \
22646 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22647 _(sw_interface_dump,"")                                                 \
22648 _(sw_interface_set_flags,                                               \
22649   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22650 _(sw_interface_add_del_address,                                         \
22651   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22652 _(sw_interface_set_rx_mode,                                             \
22653   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22654 _(sw_interface_set_table,                                               \
22655   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22656 _(sw_interface_set_mpls_enable,                                         \
22657   "<intfc> | sw_if_index [disable | dis]")                              \
22658 _(sw_interface_set_vpath,                                               \
22659   "<intfc> | sw_if_index <id> enable | disable")                        \
22660 _(sw_interface_set_vxlan_bypass,                                        \
22661   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22662 _(sw_interface_set_geneve_bypass,                                       \
22663   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22664 _(sw_interface_set_l2_xconnect,                                         \
22665   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22666   "enable | disable")                                                   \
22667 _(sw_interface_set_l2_bridge,                                           \
22668   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22669   "[shg <split-horizon-group>] [bvi]\n"                                 \
22670   "enable | disable")                                                   \
22671 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22672 _(bridge_domain_add_del,                                                \
22673   "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") \
22674 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22675 _(l2fib_add_del,                                                        \
22676   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22677 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22678 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22679 _(l2_flags,                                                             \
22680   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22681 _(bridge_flags,                                                         \
22682   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22683 _(tap_connect,                                                          \
22684   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22685 _(tap_modify,                                                           \
22686   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22687 _(tap_delete,                                                           \
22688   "<vpp-if-name> | sw_if_index <id>")                                   \
22689 _(sw_interface_tap_dump, "")                                            \
22690 _(tap_create_v2,                                                        \
22691   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22692 _(tap_delete_v2,                                                        \
22693   "<vpp-if-name> | sw_if_index <id>")                                   \
22694 _(sw_interface_tap_v2_dump, "")                                         \
22695 _(ip_table_add_del,                                                     \
22696   "table-id <n> [ipv6]\n")                                              \
22697 _(ip_add_del_route,                                                     \
22698   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22699   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22700   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22701   "[multipath] [count <n>]")                                            \
22702 _(ip_mroute_add_del,                                                    \
22703   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22704   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22705 _(mpls_table_add_del,                                                   \
22706   "table-id <n>\n")                                                     \
22707 _(mpls_route_add_del,                                                   \
22708   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22709   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22710   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22711   "[multipath] [count <n>]")                                            \
22712 _(mpls_ip_bind_unbind,                                                  \
22713   "<label> <addr/len>")                                                 \
22714 _(mpls_tunnel_add_del,                                                  \
22715   " via <addr> [table-id <n>]\n"                                        \
22716   "sw_if_index <id>] [l2]  [del]")                                      \
22717 _(bier_table_add_del,                                                   \
22718   "<label> <sub-domain> <set> <bsl> [del]")                             \
22719 _(bier_route_add_del,                                                   \
22720   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22721   "[<intfc> | sw_if_index <id>]"                                        \
22722   "[weight <n>] [del] [multipath]")                                     \
22723 _(proxy_arp_add_del,                                                    \
22724   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22725 _(proxy_arp_intfc_enable_disable,                                       \
22726   "<intfc> | sw_if_index <id> enable | disable")                        \
22727 _(sw_interface_set_unnumbered,                                          \
22728   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22729 _(ip_neighbor_add_del,                                                  \
22730   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22731   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22732 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22733 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22734   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22735   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22736   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22737 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22738 _(reset_fib, "vrf <n> [ipv6]")                                          \
22739 _(dhcp_proxy_config,                                                    \
22740   "svr <v46-address> src <v46-address>\n"                               \
22741    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22742 _(dhcp_proxy_set_vss,                                                   \
22743   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22744 _(dhcp_proxy_dump, "ip6")                                               \
22745 _(dhcp_client_config,                                                   \
22746   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22747 _(set_ip_flow_hash,                                                     \
22748   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22749 _(sw_interface_ip6_enable_disable,                                      \
22750   "<intfc> | sw_if_index <id> enable | disable")                        \
22751 _(sw_interface_ip6_set_link_local_address,                              \
22752   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22753 _(ip6nd_proxy_add_del,                                                  \
22754   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22755 _(ip6nd_proxy_dump, "")                                                 \
22756 _(sw_interface_ip6nd_ra_prefix,                                         \
22757   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22758   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22759   "[nolink] [isno]")                                                    \
22760 _(sw_interface_ip6nd_ra_config,                                         \
22761   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22762   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22763   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22764 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22765 _(l2_patch_add_del,                                                     \
22766   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22767   "enable | disable")                                                   \
22768 _(sr_localsid_add_del,                                                  \
22769   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22770   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22771 _(classify_add_del_table,                                               \
22772   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22773   " [del] [del-chain] mask <mask-value>\n"                              \
22774   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22775   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22776 _(classify_add_del_session,                                             \
22777   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22778   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22779   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22780   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22781 _(classify_set_interface_ip_table,                                      \
22782   "<intfc> | sw_if_index <nn> table <nn>")                              \
22783 _(classify_set_interface_l2_tables,                                     \
22784   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22785   "  [other-table <nn>]")                                               \
22786 _(get_node_index, "node <node-name")                                    \
22787 _(add_node_next, "node <node-name> next <next-node-name>")              \
22788 _(l2tpv3_create_tunnel,                                                 \
22789   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22790   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22791   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22792 _(l2tpv3_set_tunnel_cookies,                                            \
22793   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22794   "[new_remote_cookie <nn>]\n")                                         \
22795 _(l2tpv3_interface_enable_disable,                                      \
22796   "<intfc> | sw_if_index <nn> enable | disable")                        \
22797 _(l2tpv3_set_lookup_key,                                                \
22798   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22799 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22800 _(vxlan_add_del_tunnel,                                                 \
22801   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22802   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22803   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22804 _(geneve_add_del_tunnel,                                                \
22805   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22806   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22807   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22808 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22809 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22810 _(gre_add_del_tunnel,                                                   \
22811   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22812 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22813 _(l2_fib_clear_table, "")                                               \
22814 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22815 _(l2_interface_vlan_tag_rewrite,                                        \
22816   "<intfc> | sw_if_index <nn> \n"                                       \
22817   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22818   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22819 _(create_vhost_user_if,                                                 \
22820         "socket <filename> [server] [renumber <dev_instance>] "         \
22821         "[mac <mac_address>]")                                          \
22822 _(modify_vhost_user_if,                                                 \
22823         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22824         "[server] [renumber <dev_instance>]")                           \
22825 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22826 _(sw_interface_vhost_user_dump, "")                                     \
22827 _(show_version, "")                                                     \
22828 _(vxlan_gpe_add_del_tunnel,                                             \
22829   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22830   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22831   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22832   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22833 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22834 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22835 _(interface_name_renumber,                                              \
22836   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22837 _(input_acl_set_interface,                                              \
22838   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22839   "  [l2-table <nn>] [del]")                                            \
22840 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22841 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22842 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22843 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22844 _(ip_dump, "ipv4 | ipv6")                                               \
22845 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22846 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22847   "  spid_id <n> ")                                                     \
22848 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22849   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22850   "  integ_alg <alg> integ_key <hex>")                                  \
22851 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22852   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22853   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22854   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22855 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22856 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22857   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22858   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22859   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22860 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22861 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22862   "  <alg> <hex>\n")                                                    \
22863 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22864 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22865 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22866   "(auth_data 0x<data> | auth_data <data>)")                            \
22867 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22868   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22869 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22870   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22871   "(local|remote)")                                                     \
22872 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22873 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22874 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22875 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22876 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22877 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22878 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22879 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22880 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22881 _(delete_loopback,"sw_if_index <nn>")                                   \
22882 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22883 _(map_add_domain,                                                       \
22884   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22885   "ip6-src <ip6addr> "                                                  \
22886   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22887 _(map_del_domain, "index <n>")                                          \
22888 _(map_add_del_rule,                                                     \
22889   "index <n> psid <n> dst <ip6addr> [del]")                             \
22890 _(map_domain_dump, "")                                                  \
22891 _(map_rule_dump, "index <map-domain>")                                  \
22892 _(want_interface_events,  "enable|disable")                             \
22893 _(want_stats,"enable|disable")                                          \
22894 _(get_first_msg_id, "client <name>")                                    \
22895 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22896 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22897   "fib-id <nn> [ip4][ip6][default]")                                    \
22898 _(get_node_graph, " ")                                                  \
22899 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22900 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22901 _(ioam_disable, "")                                                     \
22902 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22903                             " sw_if_index <sw_if_index> p <priority> "  \
22904                             "w <weight>] [del]")                        \
22905 _(one_add_del_locator, "locator-set <locator_name> "                    \
22906                         "iface <intf> | sw_if_index <sw_if_index> "     \
22907                         "p <priority> w <weight> [del]")                \
22908 _(one_add_del_local_eid,"vni <vni> eid "                                \
22909                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22910                          "locator-set <locator_name> [del]"             \
22911                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22912 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22913 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22914 _(one_enable_disable, "enable|disable")                                 \
22915 _(one_map_register_enable_disable, "enable|disable")                    \
22916 _(one_map_register_fallback_threshold, "<value>")                       \
22917 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22918 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22919                                "[seid <seid>] "                         \
22920                                "rloc <locator> p <prio> "               \
22921                                "w <weight> [rloc <loc> ... ] "          \
22922                                "action <action> [del-all]")             \
22923 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22924                           "<local-eid>")                                \
22925 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22926 _(one_use_petr, "ip-address> | disable")                                \
22927 _(one_map_request_mode, "src-dst|dst-only")                             \
22928 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22929 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22930 _(one_locator_set_dump, "[local | remote]")                             \
22931 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22932 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22933                        "[local] | [remote]")                            \
22934 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22935 _(one_ndp_bd_get, "")                                                   \
22936 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22937 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22938 _(one_l2_arp_bd_get, "")                                                \
22939 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22940 _(one_stats_enable_disable, "enable|disalbe")                           \
22941 _(show_one_stats_enable_disable, "")                                    \
22942 _(one_eid_table_vni_dump, "")                                           \
22943 _(one_eid_table_map_dump, "l2|l3")                                      \
22944 _(one_map_resolver_dump, "")                                            \
22945 _(one_map_server_dump, "")                                              \
22946 _(one_adjacencies_get, "vni <vni>")                                     \
22947 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22948 _(show_one_rloc_probe_state, "")                                        \
22949 _(show_one_map_register_state, "")                                      \
22950 _(show_one_status, "")                                                  \
22951 _(one_stats_dump, "")                                                   \
22952 _(one_stats_flush, "")                                                  \
22953 _(one_get_map_request_itr_rlocs, "")                                    \
22954 _(one_map_register_set_ttl, "<ttl>")                                    \
22955 _(one_set_transport_protocol, "udp|api")                                \
22956 _(one_get_transport_protocol, "")                                       \
22957 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22958 _(one_show_xtr_mode, "")                                                \
22959 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22960 _(one_show_pitr_mode, "")                                               \
22961 _(one_enable_disable_petr_mode, "enable|disable")                       \
22962 _(one_show_petr_mode, "")                                               \
22963 _(show_one_nsh_mapping, "")                                             \
22964 _(show_one_pitr, "")                                                    \
22965 _(show_one_use_petr, "")                                                \
22966 _(show_one_map_request_mode, "")                                        \
22967 _(show_one_map_register_ttl, "")                                        \
22968 _(show_one_map_register_fallback_threshold, "")                         \
22969 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22970                             " sw_if_index <sw_if_index> p <priority> "  \
22971                             "w <weight>] [del]")                        \
22972 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22973                         "iface <intf> | sw_if_index <sw_if_index> "     \
22974                         "p <priority> w <weight> [del]")                \
22975 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22976                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22977                          "locator-set <locator_name> [del]"             \
22978                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22979 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22980 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22981 _(lisp_enable_disable, "enable|disable")                                \
22982 _(lisp_map_register_enable_disable, "enable|disable")                   \
22983 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22984 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22985                                "[seid <seid>] "                         \
22986                                "rloc <locator> p <prio> "               \
22987                                "w <weight> [rloc <loc> ... ] "          \
22988                                "action <action> [del-all]")             \
22989 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22990                           "<local-eid>")                                \
22991 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22992 _(lisp_use_petr, "<ip-address> | disable")                              \
22993 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22994 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22995 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22996 _(lisp_locator_set_dump, "[local | remote]")                            \
22997 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22998 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22999                        "[local] | [remote]")                            \
23000 _(lisp_eid_table_vni_dump, "")                                          \
23001 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23002 _(lisp_map_resolver_dump, "")                                           \
23003 _(lisp_map_server_dump, "")                                             \
23004 _(lisp_adjacencies_get, "vni <vni>")                                    \
23005 _(gpe_fwd_entry_vnis_get, "")                                           \
23006 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23007 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23008                                 "[table <table-id>]")                   \
23009 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23010 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23011 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23012 _(gpe_get_encap_mode, "")                                               \
23013 _(lisp_gpe_add_del_iface, "up|down")                                    \
23014 _(lisp_gpe_enable_disable, "enable|disable")                            \
23015 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23016   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23017 _(show_lisp_rloc_probe_state, "")                                       \
23018 _(show_lisp_map_register_state, "")                                     \
23019 _(show_lisp_status, "")                                                 \
23020 _(lisp_get_map_request_itr_rlocs, "")                                   \
23021 _(show_lisp_pitr, "")                                                   \
23022 _(show_lisp_use_petr, "")                                               \
23023 _(show_lisp_map_request_mode, "")                                       \
23024 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23025 _(af_packet_delete, "name <host interface name>")                       \
23026 _(policer_add_del, "name <policer name> <params> [del]")                \
23027 _(policer_dump, "[name <policer name>]")                                \
23028 _(policer_classify_set_interface,                                       \
23029   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23030   "  [l2-table <nn>] [del]")                                            \
23031 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23032 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23033     "[master|slave]")                                                   \
23034 _(netmap_delete, "name <interface name>")                               \
23035 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23036 _(mpls_fib_dump, "")                                                    \
23037 _(classify_table_ids, "")                                               \
23038 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23039 _(classify_table_info, "table_id <nn>")                                 \
23040 _(classify_session_dump, "table_id <nn>")                               \
23041 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23042     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23043     "[template_interval <nn>] [udp_checksum]")                          \
23044 _(ipfix_exporter_dump, "")                                              \
23045 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23046 _(ipfix_classify_stream_dump, "")                                       \
23047 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23048 _(ipfix_classify_table_dump, "")                                        \
23049 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23050 _(sw_interface_span_dump, "[l2]")                                           \
23051 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23052 _(pg_create_interface, "if_id <nn>")                                    \
23053 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23054 _(pg_enable_disable, "[stream <id>] disable")                           \
23055 _(ip_source_and_port_range_check_add_del,                               \
23056   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23057 _(ip_source_and_port_range_check_interface_add_del,                     \
23058   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23059   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23060 _(ipsec_gre_add_del_tunnel,                                             \
23061   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23062 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23063 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23064 _(l2_interface_pbb_tag_rewrite,                                         \
23065   "<intfc> | sw_if_index <nn> \n"                                       \
23066   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23067   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23068 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23069 _(flow_classify_set_interface,                                          \
23070   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23071 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23072 _(ip_fib_dump, "")                                                      \
23073 _(ip_mfib_dump, "")                                                     \
23074 _(ip6_fib_dump, "")                                                     \
23075 _(ip6_mfib_dump, "")                                                    \
23076 _(feature_enable_disable, "arc_name <arc_name> "                        \
23077   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23078 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23079 "[disable]")                                                            \
23080 _(l2_xconnect_dump, "")                                                 \
23081 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23082 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23083 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23084 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23085 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23086 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23087 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23088   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23089 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23090 _(memfd_segment_create,"size <nnn>")                                    \
23091 _(sock_init_shm, "size <nnn>")                                          \
23092 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23093 _(dns_enable_disable, "[enable][disable]")                              \
23094 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23095 _(dns_resolve_name, "<hostname>")                                       \
23096 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23097 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23098 _(dns_resolve_name, "<hostname>")                                       \
23099 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23100   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23101 _(session_rules_dump, "")                                               \
23102 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23103
23104 /* List of command functions, CLI names map directly to functions */
23105 #define foreach_cli_function                                    \
23106 _(comment, "usage: comment <ignore-rest-of-line>")              \
23107 _(dump_interface_table, "usage: dump_interface_table")          \
23108 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23109 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23110 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23111 _(dump_stats_table, "usage: dump_stats_table")                  \
23112 _(dump_macro_table, "usage: dump_macro_table ")                 \
23113 _(dump_node_table, "usage: dump_node_table")                    \
23114 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23115 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23116 _(echo, "usage: echo <message>")                                \
23117 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23118 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23119 _(help, "usage: help")                                          \
23120 _(q, "usage: quit")                                             \
23121 _(quit, "usage: quit")                                          \
23122 _(search_node_table, "usage: search_node_table <name>...")      \
23123 _(set, "usage: set <variable-name> <value>")                    \
23124 _(script, "usage: script <file-name>")                          \
23125 _(unset, "usage: unset <variable-name>")
23126 #define _(N,n)                                  \
23127     static void vl_api_##n##_t_handler_uni      \
23128     (vl_api_##n##_t * mp)                       \
23129     {                                           \
23130         vat_main_t * vam = &vat_main;           \
23131         if (vam->json_output) {                 \
23132             vl_api_##n##_t_handler_json(mp);    \
23133         } else {                                \
23134             vl_api_##n##_t_handler(mp);         \
23135         }                                       \
23136     }
23137 foreach_vpe_api_reply_msg;
23138 #if VPP_API_TEST_BUILTIN == 0
23139 foreach_standalone_reply_msg;
23140 #endif
23141 #undef _
23142
23143 void
23144 vat_api_hookup (vat_main_t * vam)
23145 {
23146 #define _(N,n)                                                  \
23147     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23148                            vl_api_##n##_t_handler_uni,          \
23149                            vl_noop_handler,                     \
23150                            vl_api_##n##_t_endian,               \
23151                            vl_api_##n##_t_print,                \
23152                            sizeof(vl_api_##n##_t), 1);
23153   foreach_vpe_api_reply_msg;
23154 #if VPP_API_TEST_BUILTIN == 0
23155   foreach_standalone_reply_msg;
23156 #endif
23157 #undef _
23158
23159 #if (VPP_API_TEST_BUILTIN==0)
23160   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23161
23162   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23163
23164   vam->function_by_name = hash_create_string (0, sizeof (uword));
23165
23166   vam->help_by_name = hash_create_string (0, sizeof (uword));
23167 #endif
23168
23169   /* API messages we can send */
23170 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23171   foreach_vpe_api_msg;
23172 #undef _
23173
23174   /* Help strings */
23175 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23176   foreach_vpe_api_msg;
23177 #undef _
23178
23179   /* CLI functions */
23180 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23181   foreach_cli_function;
23182 #undef _
23183
23184   /* Help strings */
23185 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23186   foreach_cli_function;
23187 #undef _
23188 }
23189
23190 #if VPP_API_TEST_BUILTIN
23191 static clib_error_t *
23192 vat_api_hookup_shim (vlib_main_t * vm)
23193 {
23194   vat_api_hookup (&vat_main);
23195   return 0;
23196 }
23197
23198 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23199 #endif
23200
23201 /*
23202  * fd.io coding-style-patch-verification: ON
23203  *
23204  * Local Variables:
23205  * eval: (c-set-style "gnu")
23206  * End:
23207  */