Remove vpp_api_test interface name filter catalog
[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 <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 /* Parse an IP4 address %d.%d.%d.%d. */
180 uword
181 unformat_ip4_address (unformat_input_t * input, va_list * args)
182 {
183   u8 *result = va_arg (*args, u8 *);
184   unsigned a[4];
185
186   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
187     return 0;
188
189   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
190     return 0;
191
192   result[0] = a[0];
193   result[1] = a[1];
194   result[2] = a[2];
195   result[3] = a[3];
196
197   return 1;
198 }
199
200 uword
201 unformat_ethernet_address (unformat_input_t * input, va_list * args)
202 {
203   u8 *result = va_arg (*args, u8 *);
204   u32 i, a[6];
205
206   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
207                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
208     return 0;
209
210   /* Check range. */
211   for (i = 0; i < 6; i++)
212     if (a[i] >= (1 << 8))
213       return 0;
214
215   for (i = 0; i < 6; i++)
216     result[i] = a[i];
217
218   return 1;
219 }
220
221 /* Returns ethernet type as an int in host byte order. */
222 uword
223 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
224                                         va_list * args)
225 {
226   u16 *result = va_arg (*args, u16 *);
227   int type;
228
229   /* Numeric type. */
230   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
231     {
232       if (type >= (1 << 16))
233         return 0;
234       *result = type;
235       return 1;
236     }
237   return 0;
238 }
239
240 /* Parse an IP6 address. */
241 uword
242 unformat_ip6_address (unformat_input_t * input, va_list * args)
243 {
244   ip6_address_t *result = va_arg (*args, ip6_address_t *);
245   u16 hex_quads[8];
246   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
247   uword c, n_colon, double_colon_index;
248
249   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
250   double_colon_index = ARRAY_LEN (hex_quads);
251   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
252     {
253       hex_digit = 16;
254       if (c >= '0' && c <= '9')
255         hex_digit = c - '0';
256       else if (c >= 'a' && c <= 'f')
257         hex_digit = c + 10 - 'a';
258       else if (c >= 'A' && c <= 'F')
259         hex_digit = c + 10 - 'A';
260       else if (c == ':' && n_colon < 2)
261         n_colon++;
262       else
263         {
264           unformat_put_input (input);
265           break;
266         }
267
268       /* Too many hex quads. */
269       if (n_hex_quads >= ARRAY_LEN (hex_quads))
270         return 0;
271
272       if (hex_digit < 16)
273         {
274           hex_quad = (hex_quad << 4) | hex_digit;
275
276           /* Hex quad must fit in 16 bits. */
277           if (n_hex_digits >= 4)
278             return 0;
279
280           n_colon = 0;
281           n_hex_digits++;
282         }
283
284       /* Save position of :: */
285       if (n_colon == 2)
286         {
287           /* More than one :: ? */
288           if (double_colon_index < ARRAY_LEN (hex_quads))
289             return 0;
290           double_colon_index = n_hex_quads;
291         }
292
293       if (n_colon > 0 && n_hex_digits > 0)
294         {
295           hex_quads[n_hex_quads++] = hex_quad;
296           hex_quad = 0;
297           n_hex_digits = 0;
298         }
299     }
300
301   if (n_hex_digits > 0)
302     hex_quads[n_hex_quads++] = hex_quad;
303
304   {
305     word i;
306
307     /* Expand :: to appropriate number of zero hex quads. */
308     if (double_colon_index < ARRAY_LEN (hex_quads))
309       {
310         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
311
312         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
313           hex_quads[n_zero + i] = hex_quads[i];
314
315         for (i = 0; i < n_zero; i++)
316           hex_quads[double_colon_index + i] = 0;
317
318         n_hex_quads = ARRAY_LEN (hex_quads);
319       }
320
321     /* Too few hex quads given. */
322     if (n_hex_quads < ARRAY_LEN (hex_quads))
323       return 0;
324
325     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
326       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
327
328     return 1;
329   }
330 }
331
332 uword
333 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
339   foreach_ipsec_policy_action
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 uword
347 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
348 {
349   u32 *r = va_arg (*args, u32 *);
350
351   if (0);
352 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
353   foreach_ipsec_crypto_alg
354 #undef _
355     else
356     return 0;
357   return 1;
358 }
359
360 u8 *
361 format_ipsec_crypto_alg (u8 * s, va_list * args)
362 {
363   u32 i = va_arg (*args, u32);
364   u8 *t = 0;
365
366   switch (i)
367     {
368 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
369       foreach_ipsec_crypto_alg
370 #undef _
371     default:
372       return format (s, "unknown");
373     }
374   return format (s, "%s", t);
375 }
376
377 uword
378 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
384   foreach_ipsec_integ_alg
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390
391 u8 *
392 format_ipsec_integ_alg (u8 * s, va_list * args)
393 {
394   u32 i = va_arg (*args, u32);
395   u8 *t = 0;
396
397   switch (i)
398     {
399 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
400       foreach_ipsec_integ_alg
401 #undef _
402     default:
403       return format (s, "unknown");
404     }
405   return format (s, "%s", t);
406 }
407
408 uword
409 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
410 {
411   u32 *r = va_arg (*args, u32 *);
412
413   if (0);
414 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
415   foreach_ikev2_auth_method
416 #undef _
417     else
418     return 0;
419   return 1;
420 }
421
422 uword
423 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
424 {
425   u32 *r = va_arg (*args, u32 *);
426
427   if (0);
428 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
429   foreach_ikev2_id_type
430 #undef _
431     else
432     return 0;
433   return 1;
434 }
435 #else /* VPP_API_TEST_BUILTIN == 1 */
436 static uword
437 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
438 {
439   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
440   vnet_main_t *vnm = vnet_get_main ();
441   u32 *result = va_arg (*args, u32 *);
442   u32 sw_if_index;
443
444   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
445     return 0;
446
447   *result = sw_if_index;
448   return 1;
449 }
450 #endif /* VPP_API_TEST_BUILTIN */
451
452 static uword
453 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
454 {
455   u8 *r = va_arg (*args, u8 *);
456
457   if (unformat (input, "kbps"))
458     *r = SSE2_QOS_RATE_KBPS;
459   else if (unformat (input, "pps"))
460     *r = SSE2_QOS_RATE_PPS;
461   else
462     return 0;
463   return 1;
464 }
465
466 static uword
467 unformat_policer_round_type (unformat_input_t * input, va_list * args)
468 {
469   u8 *r = va_arg (*args, u8 *);
470
471   if (unformat (input, "closest"))
472     *r = SSE2_QOS_ROUND_TO_CLOSEST;
473   else if (unformat (input, "up"))
474     *r = SSE2_QOS_ROUND_TO_UP;
475   else if (unformat (input, "down"))
476     *r = SSE2_QOS_ROUND_TO_DOWN;
477   else
478     return 0;
479   return 1;
480 }
481
482 static uword
483 unformat_policer_type (unformat_input_t * input, va_list * args)
484 {
485   u8 *r = va_arg (*args, u8 *);
486
487   if (unformat (input, "1r2c"))
488     *r = SSE2_QOS_POLICER_TYPE_1R2C;
489   else if (unformat (input, "1r3c"))
490     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
491   else if (unformat (input, "2r3c-2698"))
492     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
493   else if (unformat (input, "2r3c-4115"))
494     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
495   else if (unformat (input, "2r3c-mef5cf1"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
497   else
498     return 0;
499   return 1;
500 }
501
502 static uword
503 unformat_dscp (unformat_input_t * input, va_list * va)
504 {
505   u8 *r = va_arg (*va, u8 *);
506
507   if (0);
508 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
509   foreach_vnet_dscp
510 #undef _
511     else
512     return 0;
513   return 1;
514 }
515
516 static uword
517 unformat_policer_action_type (unformat_input_t * input, va_list * va)
518 {
519   sse2_qos_pol_action_params_st *a
520     = va_arg (*va, sse2_qos_pol_action_params_st *);
521
522   if (unformat (input, "drop"))
523     a->action_type = SSE2_QOS_ACTION_DROP;
524   else if (unformat (input, "transmit"))
525     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
526   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
527     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
528   else
529     return 0;
530   return 1;
531 }
532
533 static uword
534 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
535 {
536   u32 *r = va_arg (*va, u32 *);
537   u32 tid;
538
539   if (unformat (input, "ip4"))
540     tid = POLICER_CLASSIFY_TABLE_IP4;
541   else if (unformat (input, "ip6"))
542     tid = POLICER_CLASSIFY_TABLE_IP6;
543   else if (unformat (input, "l2"))
544     tid = POLICER_CLASSIFY_TABLE_L2;
545   else
546     return 0;
547
548   *r = tid;
549   return 1;
550 }
551
552 static uword
553 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
554 {
555   u32 *r = va_arg (*va, u32 *);
556   u32 tid;
557
558   if (unformat (input, "ip4"))
559     tid = FLOW_CLASSIFY_TABLE_IP4;
560   else if (unformat (input, "ip6"))
561     tid = FLOW_CLASSIFY_TABLE_IP6;
562   else
563     return 0;
564
565   *r = tid;
566   return 1;
567 }
568
569 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
570 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
571 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
572 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
573
574 #if (VPP_API_TEST_BUILTIN==0)
575 uword
576 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
577 {
578   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
579   mfib_itf_attribute_t attr;
580
581   old = *iflags;
582   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
583   {
584     if (unformat (input, mfib_itf_flag_long_names[attr]))
585       *iflags |= (1 << attr);
586   }
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_names[attr]))
590       *iflags |= (1 << attr);
591   }
592
593   return (old == *iflags ? 0 : 1);
594 }
595
596 uword
597 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
598 {
599   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
600   mfib_entry_attribute_t attr;
601
602   old = *eflags;
603   FOR_EACH_MFIB_ATTRIBUTE (attr)
604   {
605     if (unformat (input, mfib_flag_long_names[attr]))
606       *eflags |= (1 << attr);
607   }
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_names[attr]))
611       *eflags |= (1 << attr);
612   }
613
614   return (old == *eflags ? 0 : 1);
615 }
616
617 u8 *
618 format_ip4_address (u8 * s, va_list * args)
619 {
620   u8 *a = va_arg (*args, u8 *);
621   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
622 }
623
624 u8 *
625 format_ip6_address (u8 * s, va_list * args)
626 {
627   ip6_address_t *a = va_arg (*args, ip6_address_t *);
628   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
629
630   i_max_n_zero = ARRAY_LEN (a->as_u16);
631   max_n_zeros = 0;
632   i_first_zero = i_max_n_zero;
633   n_zeros = 0;
634   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
635     {
636       u32 is_zero = a->as_u16[i] == 0;
637       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
638         {
639           i_first_zero = i;
640           n_zeros = 0;
641         }
642       n_zeros += is_zero;
643       if ((!is_zero && n_zeros > max_n_zeros)
644           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
645         {
646           i_max_n_zero = i_first_zero;
647           max_n_zeros = n_zeros;
648           i_first_zero = ARRAY_LEN (a->as_u16);
649           n_zeros = 0;
650         }
651     }
652
653   last_double_colon = 0;
654   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
655     {
656       if (i == i_max_n_zero && max_n_zeros > 1)
657         {
658           s = format (s, "::");
659           i += max_n_zeros - 1;
660           last_double_colon = 1;
661         }
662       else
663         {
664           s = format (s, "%s%x",
665                       (last_double_colon || i == 0) ? "" : ":",
666                       clib_net_to_host_u16 (a->as_u16[i]));
667           last_double_colon = 0;
668         }
669     }
670
671   return s;
672 }
673
674 /* Format an IP46 address. */
675 u8 *
676 format_ip46_address (u8 * s, va_list * args)
677 {
678   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
679   ip46_type_t type = va_arg (*args, ip46_type_t);
680   int is_ip4 = 1;
681
682   switch (type)
683     {
684     case IP46_TYPE_ANY:
685       is_ip4 = ip46_address_is_ip4 (ip46);
686       break;
687     case IP46_TYPE_IP4:
688       is_ip4 = 1;
689       break;
690     case IP46_TYPE_IP6:
691       is_ip4 = 0;
692       break;
693     }
694
695   return is_ip4 ?
696     format (s, "%U", format_ip4_address, &ip46->ip4) :
697     format (s, "%U", format_ip6_address, &ip46->ip6);
698 }
699
700 u8 *
701 format_ethernet_address (u8 * s, va_list * args)
702 {
703   u8 *a = va_arg (*args, u8 *);
704
705   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
706                  a[0], a[1], a[2], a[3], a[4], a[5]);
707 }
708 #endif
709
710 static void
711 increment_v4_address (ip4_address_t * a)
712 {
713   u32 v;
714
715   v = ntohl (a->as_u32) + 1;
716   a->as_u32 = ntohl (v);
717 }
718
719 static void
720 increment_v6_address (ip6_address_t * a)
721 {
722   u64 v0, v1;
723
724   v0 = clib_net_to_host_u64 (a->as_u64[0]);
725   v1 = clib_net_to_host_u64 (a->as_u64[1]);
726
727   v1 += 1;
728   if (v1 == 0)
729     v0 += 1;
730   a->as_u64[0] = clib_net_to_host_u64 (v0);
731   a->as_u64[1] = clib_net_to_host_u64 (v1);
732 }
733
734 static void
735 increment_mac_address (u8 * mac)
736 {
737   u64 tmp = *((u64 *) mac);
738   tmp = clib_net_to_host_u64 (tmp);
739   tmp += 1 << 16;               /* skip unused (least significant) octets */
740   tmp = clib_host_to_net_u64 (tmp);
741
742   clib_memcpy (mac, &tmp, 6);
743 }
744
745 static void vl_api_create_loopback_reply_t_handler
746   (vl_api_create_loopback_reply_t * mp)
747 {
748   vat_main_t *vam = &vat_main;
749   i32 retval = ntohl (mp->retval);
750
751   vam->retval = retval;
752   vam->regenerate_interface_table = 1;
753   vam->sw_if_index = ntohl (mp->sw_if_index);
754   vam->result_ready = 1;
755 }
756
757 static void vl_api_create_loopback_reply_t_handler_json
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   vat_json_node_t node;
762
763   vat_json_init_object (&node);
764   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
765   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
766
767   vat_json_print (vam->ofp, &node);
768   vat_json_free (&node);
769   vam->retval = ntohl (mp->retval);
770   vam->result_ready = 1;
771 }
772
773 static void vl_api_create_loopback_instance_reply_t_handler
774   (vl_api_create_loopback_instance_reply_t * mp)
775 {
776   vat_main_t *vam = &vat_main;
777   i32 retval = ntohl (mp->retval);
778
779   vam->retval = retval;
780   vam->regenerate_interface_table = 1;
781   vam->sw_if_index = ntohl (mp->sw_if_index);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler_json
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   vat_json_node_t node;
790
791   vat_json_init_object (&node);
792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
794
795   vat_json_print (vam->ofp, &node);
796   vat_json_free (&node);
797   vam->retval = ntohl (mp->retval);
798   vam->result_ready = 1;
799 }
800
801 static void vl_api_af_packet_create_reply_t_handler
802   (vl_api_af_packet_create_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler_json
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825
826   vam->retval = ntohl (mp->retval);
827   vam->result_ready = 1;
828 }
829
830 static void vl_api_create_vlan_subif_reply_t_handler
831   (vl_api_create_vlan_subif_reply_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   i32 retval = ntohl (mp->retval);
835
836   vam->retval = retval;
837   vam->regenerate_interface_table = 1;
838   vam->sw_if_index = ntohl (mp->sw_if_index);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler_json
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   vat_json_node_t node;
847
848   vat_json_init_object (&node);
849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852   vat_json_print (vam->ofp, &node);
853   vat_json_free (&node);
854
855   vam->retval = ntohl (mp->retval);
856   vam->result_ready = 1;
857 }
858
859 static void vl_api_create_subif_reply_t_handler
860   (vl_api_create_subif_reply_t * mp)
861 {
862   vat_main_t *vam = &vat_main;
863   i32 retval = ntohl (mp->retval);
864
865   vam->retval = retval;
866   vam->regenerate_interface_table = 1;
867   vam->sw_if_index = ntohl (mp->sw_if_index);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler_json
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   vat_json_node_t node;
876
877   vat_json_init_object (&node);
878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
879   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
880
881   vat_json_print (vam->ofp, &node);
882   vat_json_free (&node);
883
884   vam->retval = ntohl (mp->retval);
885   vam->result_ready = 1;
886 }
887
888 static void vl_api_interface_name_renumber_reply_t_handler
889   (vl_api_interface_name_renumber_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->regenerate_interface_table = 1;
896   vam->result_ready = 1;
897 }
898
899 static void vl_api_interface_name_renumber_reply_t_handler_json
900   (vl_api_interface_name_renumber_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904
905   vat_json_init_object (&node);
906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 /*
916  * Special-case: build the interface table, maintain
917  * the next loopback sw_if_index vbl.
918  */
919 static void vl_api_sw_interface_details_t_handler
920   (vl_api_sw_interface_details_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   u8 *s = format (0, "%s%c", mp->interface_name, 0);
924
925   hash_set_mem (vam->sw_if_index_by_interface_name, s,
926                 ntohl (mp->sw_if_index));
927
928   /* In sub interface case, fill the sub interface table entry */
929   if (mp->sw_if_index != mp->sup_sw_if_index)
930     {
931       sw_interface_subif_t *sub = NULL;
932
933       vec_add2 (vam->sw_if_subif_table, sub, 1);
934
935       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
936       strncpy ((char *) sub->interface_name, (char *) s,
937                vec_len (sub->interface_name));
938       sub->sw_if_index = ntohl (mp->sw_if_index);
939       sub->sub_id = ntohl (mp->sub_id);
940
941       sub->sub_dot1ad = mp->sub_dot1ad;
942       sub->sub_number_of_tags = mp->sub_number_of_tags;
943       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
944       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
945       sub->sub_exact_match = mp->sub_exact_match;
946       sub->sub_default = mp->sub_default;
947       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
948       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
949
950       /* vlan tag rewrite */
951       sub->vtr_op = ntohl (mp->vtr_op);
952       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
953       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
954       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
955     }
956 }
957
958 static void vl_api_sw_interface_details_t_handler_json
959   (vl_api_sw_interface_details_t * mp)
960 {
961   vat_main_t *vam = &vat_main;
962   vat_json_node_t *node = NULL;
963
964   if (VAT_JSON_ARRAY != vam->json_tree.type)
965     {
966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
967       vat_json_init_array (&vam->json_tree);
968     }
969   node = vat_json_array_add (&vam->json_tree);
970
971   vat_json_init_object (node);
972   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
973   vat_json_object_add_uint (node, "sup_sw_if_index",
974                             ntohl (mp->sup_sw_if_index));
975   vat_json_object_add_uint (node, "l2_address_length",
976                             ntohl (mp->l2_address_length));
977   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
978                              sizeof (mp->l2_address));
979   vat_json_object_add_string_copy (node, "interface_name",
980                                    mp->interface_name);
981   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
982   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
983   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
984   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
985   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
986   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
987   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
988   vat_json_object_add_uint (node, "sub_number_of_tags",
989                             mp->sub_number_of_tags);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id",
991                             ntohs (mp->sub_outer_vlan_id));
992   vat_json_object_add_uint (node, "sub_inner_vlan_id",
993                             ntohs (mp->sub_inner_vlan_id));
994   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
995   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
996   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
997                             mp->sub_outer_vlan_id_any);
998   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
999                             mp->sub_inner_vlan_id_any);
1000   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1001   vat_json_object_add_uint (node, "vtr_push_dot1q",
1002                             ntohl (mp->vtr_push_dot1q));
1003   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1004   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1005   if (mp->sub_dot1ah)
1006     {
1007       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1008                                        format (0, "%U",
1009                                                format_ethernet_address,
1010                                                &mp->b_dmac));
1011       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1012                                        format (0, "%U",
1013                                                format_ethernet_address,
1014                                                &mp->b_smac));
1015       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1016       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1017     }
1018 }
1019
1020 #if VPP_API_TEST_BUILTIN == 0
1021 static void vl_api_sw_interface_event_t_handler
1022   (vl_api_sw_interface_event_t * mp)
1023 {
1024   vat_main_t *vam = &vat_main;
1025   if (vam->interface_event_display)
1026     errmsg ("interface flags: sw_if_index %d %s %s",
1027             ntohl (mp->sw_if_index),
1028             mp->admin_up_down ? "admin-up" : "admin-down",
1029             mp->link_up_down ? "link-up" : "link-down");
1030 }
1031 #endif
1032
1033 static void vl_api_sw_interface_event_t_handler_json
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   /* JSON output not supported */
1037 }
1038
1039 static void
1040 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1041 {
1042   vat_main_t *vam = &vat_main;
1043   i32 retval = ntohl (mp->retval);
1044
1045   vam->retval = retval;
1046   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void
1051 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055   api_main_t *am = &api_main;
1056   void *oldheap;
1057   u8 *reply;
1058
1059   vat_json_init_object (&node);
1060   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1061   vat_json_object_add_uint (&node, "reply_in_shmem",
1062                             ntohl (mp->reply_in_shmem));
1063   /* Toss the shared-memory original... */
1064   pthread_mutex_lock (&am->vlib_rp->mutex);
1065   oldheap = svm_push_data_heap (am->vlib_rp);
1066
1067   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vec_free (reply);
1069
1070   svm_pop_heap (oldheap);
1071   pthread_mutex_unlock (&am->vlib_rp->mutex);
1072
1073   vat_json_print (vam->ofp, &node);
1074   vat_json_free (&node);
1075
1076   vam->retval = ntohl (mp->retval);
1077   vam->result_ready = 1;
1078 }
1079
1080 static void
1081 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1082 {
1083   vat_main_t *vam = &vat_main;
1084   i32 retval = ntohl (mp->retval);
1085   u32 length = ntohl (mp->length);
1086
1087   vec_reset_length (vam->cmd_reply);
1088
1089   vam->retval = retval;
1090   if (retval == 0)
1091     {
1092       vec_validate (vam->cmd_reply, length);
1093       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1094       vam->cmd_reply[length] = 0;
1095     }
1096   vam->result_ready = 1;
1097 }
1098
1099 static void
1100 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1101 {
1102   vat_main_t *vam = &vat_main;
1103   vat_json_node_t node;
1104
1105   vec_reset_length (vam->cmd_reply);
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1110
1111   vat_json_print (vam->ofp, &node);
1112   vat_json_free (&node);
1113
1114   vam->retval = ntohl (mp->retval);
1115   vam->result_ready = 1;
1116 }
1117
1118 static void vl_api_classify_add_del_table_reply_t_handler
1119   (vl_api_classify_add_del_table_reply_t * mp)
1120 {
1121   vat_main_t *vam = &vat_main;
1122   i32 retval = ntohl (mp->retval);
1123   if (vam->async_mode)
1124     {
1125       vam->async_errors += (retval < 0);
1126     }
1127   else
1128     {
1129       vam->retval = retval;
1130       if (retval == 0 &&
1131           ((mp->new_table_index != 0xFFFFFFFF) ||
1132            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1133            (mp->match_n_vectors != 0xFFFFFFFF)))
1134         /*
1135          * Note: this is just barely thread-safe, depends on
1136          * the main thread spinning waiting for an answer...
1137          */
1138         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1139                 ntohl (mp->new_table_index),
1140                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1141       vam->result_ready = 1;
1142     }
1143 }
1144
1145 static void vl_api_classify_add_del_table_reply_t_handler_json
1146   (vl_api_classify_add_del_table_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vat_json_init_object (&node);
1152   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1153   vat_json_object_add_uint (&node, "new_table_index",
1154                             ntohl (mp->new_table_index));
1155   vat_json_object_add_uint (&node, "skip_n_vectors",
1156                             ntohl (mp->skip_n_vectors));
1157   vat_json_object_add_uint (&node, "match_n_vectors",
1158                             ntohl (mp->match_n_vectors));
1159
1160   vat_json_print (vam->ofp, &node);
1161   vat_json_free (&node);
1162
1163   vam->retval = ntohl (mp->retval);
1164   vam->result_ready = 1;
1165 }
1166
1167 static void vl_api_get_node_index_reply_t_handler
1168   (vl_api_get_node_index_reply_t * mp)
1169 {
1170   vat_main_t *vam = &vat_main;
1171   i32 retval = ntohl (mp->retval);
1172   if (vam->async_mode)
1173     {
1174       vam->async_errors += (retval < 0);
1175     }
1176   else
1177     {
1178       vam->retval = retval;
1179       if (retval == 0)
1180         errmsg ("node index %d", ntohl (mp->node_index));
1181       vam->result_ready = 1;
1182     }
1183 }
1184
1185 static void vl_api_get_node_index_reply_t_handler_json
1186   (vl_api_get_node_index_reply_t * mp)
1187 {
1188   vat_main_t *vam = &vat_main;
1189   vat_json_node_t node;
1190
1191   vat_json_init_object (&node);
1192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1193   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1194
1195   vat_json_print (vam->ofp, &node);
1196   vat_json_free (&node);
1197
1198   vam->retval = ntohl (mp->retval);
1199   vam->result_ready = 1;
1200 }
1201
1202 static void vl_api_get_next_index_reply_t_handler
1203   (vl_api_get_next_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   i32 retval = ntohl (mp->retval);
1207   if (vam->async_mode)
1208     {
1209       vam->async_errors += (retval < 0);
1210     }
1211   else
1212     {
1213       vam->retval = retval;
1214       if (retval == 0)
1215         errmsg ("next node index %d", ntohl (mp->next_index));
1216       vam->result_ready = 1;
1217     }
1218 }
1219
1220 static void vl_api_get_next_index_reply_t_handler_json
1221   (vl_api_get_next_index_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   vat_json_node_t node;
1225
1226   vat_json_init_object (&node);
1227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1228   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1229
1230   vat_json_print (vam->ofp, &node);
1231   vat_json_free (&node);
1232
1233   vam->retval = ntohl (mp->retval);
1234   vam->result_ready = 1;
1235 }
1236
1237 static void vl_api_add_node_next_reply_t_handler
1238   (vl_api_add_node_next_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   i32 retval = ntohl (mp->retval);
1242   if (vam->async_mode)
1243     {
1244       vam->async_errors += (retval < 0);
1245     }
1246   else
1247     {
1248       vam->retval = retval;
1249       if (retval == 0)
1250         errmsg ("next index %d", ntohl (mp->next_index));
1251       vam->result_ready = 1;
1252     }
1253 }
1254
1255 static void vl_api_add_node_next_reply_t_handler_json
1256   (vl_api_add_node_next_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   vat_json_node_t node;
1260
1261   vat_json_init_object (&node);
1262   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1263   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1264
1265   vat_json_print (vam->ofp, &node);
1266   vat_json_free (&node);
1267
1268   vam->retval = ntohl (mp->retval);
1269   vam->result_ready = 1;
1270 }
1271
1272 static void vl_api_show_version_reply_t_handler
1273   (vl_api_show_version_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   i32 retval = ntohl (mp->retval);
1277
1278   if (retval >= 0)
1279     {
1280       errmsg ("        program: %s", mp->program);
1281       errmsg ("        version: %s", mp->version);
1282       errmsg ("     build date: %s", mp->build_date);
1283       errmsg ("build directory: %s", mp->build_directory);
1284     }
1285   vam->retval = retval;
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler_json
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_string_copy (&node, "program", mp->program);
1298   vat_json_object_add_string_copy (&node, "version", mp->version);
1299   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1300   vat_json_object_add_string_copy (&node, "build_directory",
1301                                    mp->build_directory);
1302
1303   vat_json_print (vam->ofp, &node);
1304   vat_json_free (&node);
1305
1306   vam->retval = ntohl (mp->retval);
1307   vam->result_ready = 1;
1308 }
1309
1310 static void
1311 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip4_address, &mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 static void
1327 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1328 {
1329   u32 sw_if_index = ntohl (mp->sw_if_index);
1330   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1331           mp->mac_ip ? "mac/ip binding" : "address resolution",
1332           ntohl (mp->pid), format_ip6_address, mp->address,
1333           format_ethernet_address, mp->new_mac, sw_if_index);
1334 }
1335
1336 static void
1337 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1338 {
1339   /* JSON output not supported */
1340 }
1341
1342 static void
1343 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1344 {
1345   u32 n_macs = ntohl (mp->n_macs);
1346   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1347           ntohl (mp->pid), mp->client_index, n_macs);
1348   int i;
1349   for (i = 0; i < n_macs; i++)
1350     {
1351       vl_api_mac_entry_t *mac = &mp->mac[i];
1352       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1353               i + 1, ntohl (mac->sw_if_index),
1354               format_ethernet_address, mac->mac_addr, mac->is_del);
1355       if (i == 1000)
1356         break;
1357     }
1358 }
1359
1360 static void
1361 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1362 {
1363   /* JSON output not supported */
1364 }
1365
1366 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1367 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1368
1369 /*
1370  * Special-case: build the bridge domain table, maintain
1371  * the next bd id vbl.
1372  */
1373 static void vl_api_bridge_domain_details_t_handler
1374   (vl_api_bridge_domain_details_t * mp)
1375 {
1376   vat_main_t *vam = &vat_main;
1377   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1378   int i;
1379
1380   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1381          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1382
1383   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1384          ntohl (mp->bd_id), mp->learn, mp->forward,
1385          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1386
1387   if (n_sw_ifs)
1388     {
1389       vl_api_bridge_domain_sw_if_t *sw_ifs;
1390       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1391              "Interface Name");
1392
1393       sw_ifs = mp->sw_if_details;
1394       for (i = 0; i < n_sw_ifs; i++)
1395         {
1396           u8 *sw_if_name = 0;
1397           u32 sw_if_index;
1398           hash_pair_t *p;
1399
1400           sw_if_index = ntohl (sw_ifs->sw_if_index);
1401
1402           /* *INDENT-OFF* */
1403           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1404                              ({
1405                                if ((u32) p->value[0] == sw_if_index)
1406                                  {
1407                                    sw_if_name = (u8 *)(p->key);
1408                                    break;
1409                                  }
1410                              }));
1411           /* *INDENT-ON* */
1412           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1413                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1414                  "sw_if_index not found!");
1415
1416           sw_ifs++;
1417         }
1418     }
1419 }
1420
1421 static void vl_api_bridge_domain_details_t_handler_json
1422   (vl_api_bridge_domain_details_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   vat_json_node_t *node, *array = NULL;
1426   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1427
1428   if (VAT_JSON_ARRAY != vam->json_tree.type)
1429     {
1430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1431       vat_json_init_array (&vam->json_tree);
1432     }
1433   node = vat_json_array_add (&vam->json_tree);
1434
1435   vat_json_init_object (node);
1436   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1437   vat_json_object_add_uint (node, "flood", mp->flood);
1438   vat_json_object_add_uint (node, "forward", mp->forward);
1439   vat_json_object_add_uint (node, "learn", mp->learn);
1440   vat_json_object_add_uint (node, "bvi_sw_if_index",
1441                             ntohl (mp->bvi_sw_if_index));
1442   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1443   array = vat_json_object_add (node, "sw_if");
1444   vat_json_init_array (array);
1445
1446
1447
1448   if (n_sw_ifs)
1449     {
1450       vl_api_bridge_domain_sw_if_t *sw_ifs;
1451       int i;
1452
1453       sw_ifs = mp->sw_if_details;
1454       for (i = 0; i < n_sw_ifs; i++)
1455         {
1456           node = vat_json_array_add (array);
1457           vat_json_init_object (node);
1458           vat_json_object_add_uint (node, "sw_if_index",
1459                                     ntohl (sw_ifs->sw_if_index));
1460           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1461           sw_ifs++;
1462         }
1463     }
1464 }
1465
1466 static void vl_api_control_ping_reply_t_handler
1467   (vl_api_control_ping_reply_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   i32 retval = ntohl (mp->retval);
1471   if (vam->async_mode)
1472     {
1473       vam->async_errors += (retval < 0);
1474     }
1475   else
1476     {
1477       vam->retval = retval;
1478       vam->result_ready = 1;
1479     }
1480   if (vam->socket_client_main)
1481     vam->socket_client_main->control_pings_outstanding--;
1482 }
1483
1484 static void vl_api_control_ping_reply_t_handler_json
1485   (vl_api_control_ping_reply_t * mp)
1486 {
1487   vat_main_t *vam = &vat_main;
1488   i32 retval = ntohl (mp->retval);
1489
1490   if (VAT_JSON_NONE != vam->json_tree.type)
1491     {
1492       vat_json_print (vam->ofp, &vam->json_tree);
1493       vat_json_free (&vam->json_tree);
1494       vam->json_tree.type = VAT_JSON_NONE;
1495     }
1496   else
1497     {
1498       /* just print [] */
1499       vat_json_init_array (&vam->json_tree);
1500       vat_json_print (vam->ofp, &vam->json_tree);
1501       vam->json_tree.type = VAT_JSON_NONE;
1502     }
1503
1504   vam->retval = retval;
1505   vam->result_ready = 1;
1506 }
1507
1508 static void
1509   vl_api_bridge_domain_set_mac_age_reply_t_handler
1510   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   i32 retval = ntohl (mp->retval);
1514   if (vam->async_mode)
1515     {
1516       vam->async_errors += (retval < 0);
1517     }
1518   else
1519     {
1520       vam->retval = retval;
1521       vam->result_ready = 1;
1522     }
1523 }
1524
1525 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1526   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   vat_json_node_t node;
1530
1531   vat_json_init_object (&node);
1532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1533
1534   vat_json_print (vam->ofp, &node);
1535   vat_json_free (&node);
1536
1537   vam->retval = ntohl (mp->retval);
1538   vam->result_ready = 1;
1539 }
1540
1541 static void
1542 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_l2_flags_reply_t_handler_json
1558   (vl_api_l2_flags_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1566                             ntohl (mp->resulting_feature_bitmap));
1567
1568   vat_json_print (vam->ofp, &node);
1569   vat_json_free (&node);
1570
1571   vam->retval = ntohl (mp->retval);
1572   vam->result_ready = 1;
1573 }
1574
1575 static void vl_api_bridge_flags_reply_t_handler
1576   (vl_api_bridge_flags_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_bridge_flags_reply_t_handler_json
1592   (vl_api_bridge_flags_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1600                             ntohl (mp->resulting_feature_bitmap));
1601
1602   vat_json_print (vam->ofp, &node);
1603   vat_json_free (&node);
1604
1605   vam->retval = ntohl (mp->retval);
1606   vam->result_ready = 1;
1607 }
1608
1609 static void vl_api_tap_connect_reply_t_handler
1610   (vl_api_tap_connect_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614   if (vam->async_mode)
1615     {
1616       vam->async_errors += (retval < 0);
1617     }
1618   else
1619     {
1620       vam->retval = retval;
1621       vam->sw_if_index = ntohl (mp->sw_if_index);
1622       vam->result_ready = 1;
1623     }
1624
1625 }
1626
1627 static void vl_api_tap_connect_reply_t_handler_json
1628   (vl_api_tap_connect_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   vat_json_node_t node;
1632
1633   vat_json_init_object (&node);
1634   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1635   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1636
1637   vat_json_print (vam->ofp, &node);
1638   vat_json_free (&node);
1639
1640   vam->retval = ntohl (mp->retval);
1641   vam->result_ready = 1;
1642
1643 }
1644
1645 static void
1646 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   i32 retval = ntohl (mp->retval);
1650   if (vam->async_mode)
1651     {
1652       vam->async_errors += (retval < 0);
1653     }
1654   else
1655     {
1656       vam->retval = retval;
1657       vam->sw_if_index = ntohl (mp->sw_if_index);
1658       vam->result_ready = 1;
1659     }
1660 }
1661
1662 static void vl_api_tap_modify_reply_t_handler_json
1663   (vl_api_tap_modify_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   vat_json_node_t node;
1667
1668   vat_json_init_object (&node);
1669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1671
1672   vat_json_print (vam->ofp, &node);
1673   vat_json_free (&node);
1674
1675   vam->retval = ntohl (mp->retval);
1676   vam->result_ready = 1;
1677 }
1678
1679 static void
1680 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   i32 retval = ntohl (mp->retval);
1684   if (vam->async_mode)
1685     {
1686       vam->async_errors += (retval < 0);
1687     }
1688   else
1689     {
1690       vam->retval = retval;
1691       vam->result_ready = 1;
1692     }
1693 }
1694
1695 static void vl_api_tap_delete_reply_t_handler_json
1696   (vl_api_tap_delete_reply_t * mp)
1697 {
1698   vat_main_t *vam = &vat_main;
1699   vat_json_node_t node;
1700
1701   vat_json_init_object (&node);
1702   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1703
1704   vat_json_print (vam->ofp, &node);
1705   vat_json_free (&node);
1706
1707   vam->retval = ntohl (mp->retval);
1708   vam->result_ready = 1;
1709 }
1710
1711 static void
1712 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   i32 retval = ntohl (mp->retval);
1716   if (vam->async_mode)
1717     {
1718       vam->async_errors += (retval < 0);
1719     }
1720   else
1721     {
1722       vam->retval = retval;
1723       vam->sw_if_index = ntohl (mp->sw_if_index);
1724       vam->result_ready = 1;
1725     }
1726
1727 }
1728
1729 static void vl_api_tap_create_v2_reply_t_handler_json
1730   (vl_api_tap_create_v2_reply_t * mp)
1731 {
1732   vat_main_t *vam = &vat_main;
1733   vat_json_node_t node;
1734
1735   vat_json_init_object (&node);
1736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1737   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1738
1739   vat_json_print (vam->ofp, &node);
1740   vat_json_free (&node);
1741
1742   vam->retval = ntohl (mp->retval);
1743   vam->result_ready = 1;
1744
1745 }
1746
1747 static void
1748 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   i32 retval = ntohl (mp->retval);
1752   if (vam->async_mode)
1753     {
1754       vam->async_errors += (retval < 0);
1755     }
1756   else
1757     {
1758       vam->retval = retval;
1759       vam->result_ready = 1;
1760     }
1761 }
1762
1763 static void vl_api_tap_delete_v2_reply_t_handler_json
1764   (vl_api_tap_delete_v2_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   vat_json_node_t node;
1768
1769   vat_json_init_object (&node);
1770   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1771
1772   vat_json_print (vam->ofp, &node);
1773   vat_json_free (&node);
1774
1775   vam->retval = ntohl (mp->retval);
1776   vam->result_ready = 1;
1777 }
1778
1779 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1780   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   i32 retval = ntohl (mp->retval);
1784   if (vam->async_mode)
1785     {
1786       vam->async_errors += (retval < 0);
1787     }
1788   else
1789     {
1790       vam->retval = retval;
1791       vam->result_ready = 1;
1792     }
1793 }
1794
1795 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1796   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   vat_json_node_t node;
1800
1801   vat_json_init_object (&node);
1802   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1803   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1804                             ntohl (mp->sw_if_index));
1805
1806   vat_json_print (vam->ofp, &node);
1807   vat_json_free (&node);
1808
1809   vam->retval = ntohl (mp->retval);
1810   vam->result_ready = 1;
1811 }
1812
1813 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1814   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   i32 retval = ntohl (mp->retval);
1818   if (vam->async_mode)
1819     {
1820       vam->async_errors += (retval < 0);
1821     }
1822   else
1823     {
1824       vam->retval = retval;
1825       vam->sw_if_index = ntohl (mp->sw_if_index);
1826       vam->result_ready = 1;
1827     }
1828 }
1829
1830 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1831   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   vat_json_node_t node;
1835
1836   vat_json_init_object (&node);
1837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1838   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1839
1840   vat_json_print (vam->ofp, &node);
1841   vat_json_free (&node);
1842
1843   vam->retval = ntohl (mp->retval);
1844   vam->result_ready = 1;
1845 }
1846
1847 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1848   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851   i32 retval = ntohl (mp->retval);
1852   if (vam->async_mode)
1853     {
1854       vam->async_errors += (retval < 0);
1855     }
1856   else
1857     {
1858       vam->retval = retval;
1859       vam->result_ready = 1;
1860     }
1861 }
1862
1863 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1864   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1865 {
1866   vat_main_t *vam = &vat_main;
1867   vat_json_node_t node;
1868
1869   vat_json_init_object (&node);
1870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1871   vat_json_object_add_uint (&node, "fwd_entry_index",
1872                             clib_net_to_host_u32 (mp->fwd_entry_index));
1873
1874   vat_json_print (vam->ofp, &node);
1875   vat_json_free (&node);
1876
1877   vam->retval = ntohl (mp->retval);
1878   vam->result_ready = 1;
1879 }
1880
1881 u8 *
1882 format_lisp_transport_protocol (u8 * s, va_list * args)
1883 {
1884   u32 proto = va_arg (*args, u32);
1885
1886   switch (proto)
1887     {
1888     case 1:
1889       return format (s, "udp");
1890     case 2:
1891       return format (s, "api");
1892     default:
1893       return 0;
1894     }
1895   return 0;
1896 }
1897
1898 static void vl_api_one_get_transport_protocol_reply_t_handler
1899   (vl_api_one_get_transport_protocol_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   i32 retval = ntohl (mp->retval);
1903   if (vam->async_mode)
1904     {
1905       vam->async_errors += (retval < 0);
1906     }
1907   else
1908     {
1909       u32 proto = mp->protocol;
1910       print (vam->ofp, "Transport protocol: %U",
1911              format_lisp_transport_protocol, proto);
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1918   (vl_api_one_get_transport_protocol_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922   u8 *s;
1923
1924   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1925   vec_add1 (s, 0);
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1930
1931   vec_free (s);
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void vl_api_one_add_del_locator_set_reply_t_handler
1940   (vl_api_one_add_del_locator_set_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1956   (vl_api_one_add_del_locator_set_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1973   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   i32 retval = ntohl (mp->retval);
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->sw_if_index = ntohl (mp->sw_if_index);
1985       vam->result_ready = 1;
1986     }
1987   vam->regenerate_interface_table = 1;
1988 }
1989
1990 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1991   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   vat_json_node_t node;
1995
1996   vat_json_init_object (&node);
1997   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1998   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1999
2000   vat_json_print (vam->ofp, &node);
2001   vat_json_free (&node);
2002
2003   vam->retval = ntohl (mp->retval);
2004   vam->result_ready = 1;
2005 }
2006
2007 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2008   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   i32 retval = ntohl (mp->retval);
2012   if (vam->async_mode)
2013     {
2014       vam->async_errors += (retval < 0);
2015     }
2016   else
2017     {
2018       vam->retval = retval;
2019       vam->sw_if_index = ntohl (mp->sw_if_index);
2020       vam->result_ready = 1;
2021     }
2022 }
2023
2024 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2025   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2026 {
2027   vat_main_t *vam = &vat_main;
2028   vat_json_node_t node;
2029
2030   vat_json_init_object (&node);
2031   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2032   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2033
2034   vat_json_print (vam->ofp, &node);
2035   vat_json_free (&node);
2036
2037   vam->retval = ntohl (mp->retval);
2038   vam->result_ready = 1;
2039 }
2040
2041 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2042   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   i32 retval = ntohl (mp->retval);
2046   if (vam->async_mode)
2047     {
2048       vam->async_errors += (retval < 0);
2049     }
2050   else
2051     {
2052       vam->retval = retval;
2053       vam->sw_if_index = ntohl (mp->sw_if_index);
2054       vam->result_ready = 1;
2055     }
2056   vam->regenerate_interface_table = 1;
2057 }
2058
2059 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2060   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vat_json_node_t node;
2064
2065   vat_json_init_object (&node);
2066   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2067   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2068
2069   vat_json_print (vam->ofp, &node);
2070   vat_json_free (&node);
2071
2072   vam->retval = ntohl (mp->retval);
2073   vam->result_ready = 1;
2074 }
2075
2076 static void vl_api_gre_add_del_tunnel_reply_t_handler
2077   (vl_api_gre_add_del_tunnel_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   i32 retval = ntohl (mp->retval);
2081   if (vam->async_mode)
2082     {
2083       vam->async_errors += (retval < 0);
2084     }
2085   else
2086     {
2087       vam->retval = retval;
2088       vam->sw_if_index = ntohl (mp->sw_if_index);
2089       vam->result_ready = 1;
2090     }
2091 }
2092
2093 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2094   (vl_api_gre_add_del_tunnel_reply_t * mp)
2095 {
2096   vat_main_t *vam = &vat_main;
2097   vat_json_node_t node;
2098
2099   vat_json_init_object (&node);
2100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2101   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2102
2103   vat_json_print (vam->ofp, &node);
2104   vat_json_free (&node);
2105
2106   vam->retval = ntohl (mp->retval);
2107   vam->result_ready = 1;
2108 }
2109
2110 static void vl_api_create_vhost_user_if_reply_t_handler
2111   (vl_api_create_vhost_user_if_reply_t * mp)
2112 {
2113   vat_main_t *vam = &vat_main;
2114   i32 retval = ntohl (mp->retval);
2115   if (vam->async_mode)
2116     {
2117       vam->async_errors += (retval < 0);
2118     }
2119   else
2120     {
2121       vam->retval = retval;
2122       vam->sw_if_index = ntohl (mp->sw_if_index);
2123       vam->result_ready = 1;
2124     }
2125   vam->regenerate_interface_table = 1;
2126 }
2127
2128 static void vl_api_create_vhost_user_if_reply_t_handler_json
2129   (vl_api_create_vhost_user_if_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   vat_json_node_t node;
2133
2134   vat_json_init_object (&node);
2135   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2136   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2137
2138   vat_json_print (vam->ofp, &node);
2139   vat_json_free (&node);
2140
2141   vam->retval = ntohl (mp->retval);
2142   vam->result_ready = 1;
2143 }
2144
2145 static clib_error_t *
2146 receive_fd_msg (int socket_fd, int *my_fd)
2147 {
2148   char msgbuf[16];
2149   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2150   struct msghdr mh = { 0 };
2151   struct iovec iov[1];
2152   ssize_t size;
2153   struct ucred *cr = 0;
2154   struct cmsghdr *cmsg;
2155   pid_t pid __attribute__ ((unused));
2156   uid_t uid __attribute__ ((unused));
2157   gid_t gid __attribute__ ((unused));
2158
2159   iov[0].iov_base = msgbuf;
2160   iov[0].iov_len = 5;
2161   mh.msg_iov = iov;
2162   mh.msg_iovlen = 1;
2163   mh.msg_control = ctl;
2164   mh.msg_controllen = sizeof (ctl);
2165
2166   memset (ctl, 0, sizeof (ctl));
2167
2168   /* receive the incoming message */
2169   size = recvmsg (socket_fd, &mh, 0);
2170   if (size != 5)
2171     {
2172       return (size == 0) ? clib_error_return (0, "disconnected") :
2173         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2174                                 socket_fd);
2175     }
2176
2177   cmsg = CMSG_FIRSTHDR (&mh);
2178   while (cmsg)
2179     {
2180       if (cmsg->cmsg_level == SOL_SOCKET)
2181         {
2182           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2183             {
2184               cr = (struct ucred *) CMSG_DATA (cmsg);
2185               uid = cr->uid;
2186               gid = cr->gid;
2187               pid = cr->pid;
2188             }
2189           else if (cmsg->cmsg_type == SCM_RIGHTS)
2190             {
2191               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2192             }
2193         }
2194       cmsg = CMSG_NXTHDR (&mh, cmsg);
2195     }
2196   return 0;
2197 }
2198
2199 static void vl_api_memfd_segment_create_reply_t_handler
2200   (vl_api_memfd_segment_create_reply_t * mp)
2201 {
2202   /* Dont bother in the builtin version */
2203 #if VPP_API_TEST_BUILTIN == 0
2204   vat_main_t *vam = &vat_main;
2205   api_main_t *am = &api_main;
2206   socket_client_main_t *scm = vam->socket_client_main;
2207   int my_fd = -1;
2208   clib_error_t *error;
2209   memfd_private_t memfd;
2210   i32 retval = ntohl (mp->retval);
2211
2212   if (retval == 0)
2213     {
2214       error = receive_fd_msg (scm->socket_fd, &my_fd);
2215       if (error)
2216         {
2217           retval = -99;
2218           goto out;
2219         }
2220
2221       memset (&memfd, 0, sizeof (memfd));
2222       memfd.fd = my_fd;
2223
2224       vam->client_index_invalid = 1;
2225
2226       /* Note: this closes memfd.fd */
2227       retval = memfd_slave_init (&memfd);
2228       if (retval)
2229         clib_warning ("WARNING: segment map returned %d", retval);
2230
2231       /* Pivot to the memory client segment that vpp just created */
2232
2233       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2234
2235       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2236
2237       vl_client_install_client_message_handlers ();
2238
2239       vl_client_connect_to_vlib_no_map ("pvt",
2240                                         "vpp_api_test(p)",
2241                                         32 /* input_queue_length */ );
2242       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2243
2244       vl_socket_client_enable_disable (0 /* disable socket */ );
2245     }
2246
2247 out:
2248   if (vam->async_mode)
2249     {
2250       vam->async_errors += (retval < 0);
2251     }
2252   else
2253     {
2254       vam->retval = retval;
2255       vam->result_ready = 1;
2256     }
2257 #endif
2258 }
2259
2260 static void vl_api_memfd_segment_create_reply_t_handler_json
2261   (vl_api_memfd_segment_create_reply_t * mp)
2262 {
2263   clib_warning ("no");
2264 }
2265
2266 static void vl_api_dns_resolve_name_reply_t_handler
2267   (vl_api_dns_resolve_name_reply_t * mp)
2268 {
2269   vat_main_t *vam = &vat_main;
2270   i32 retval = ntohl (mp->retval);
2271   if (vam->async_mode)
2272     {
2273       vam->async_errors += (retval < 0);
2274     }
2275   else
2276     {
2277       vam->retval = retval;
2278       vam->result_ready = 1;
2279
2280       if (retval == 0)
2281         {
2282           if (mp->ip4_set)
2283             clib_warning ("ip4 address %U", format_ip4_address,
2284                           (ip4_address_t *) mp->ip4_address);
2285           if (mp->ip6_set)
2286             clib_warning ("ip6 address %U", format_ip6_address,
2287                           (ip6_address_t *) mp->ip6_address);
2288         }
2289       else
2290         clib_warning ("retval %d", retval);
2291     }
2292 }
2293
2294 static void vl_api_dns_resolve_name_reply_t_handler_json
2295   (vl_api_dns_resolve_name_reply_t * mp)
2296 {
2297   clib_warning ("not implemented");
2298 }
2299
2300 static void vl_api_dns_resolve_ip_reply_t_handler
2301   (vl_api_dns_resolve_ip_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       vam->retval = retval;
2312       vam->result_ready = 1;
2313
2314       if (retval == 0)
2315         {
2316           clib_warning ("canonical name %s", mp->name);
2317         }
2318       else
2319         clib_warning ("retval %d", retval);
2320     }
2321 }
2322
2323 static void vl_api_dns_resolve_ip_reply_t_handler_json
2324   (vl_api_dns_resolve_ip_reply_t * mp)
2325 {
2326   clib_warning ("not implemented");
2327 }
2328
2329
2330 static void vl_api_ip_address_details_t_handler
2331   (vl_api_ip_address_details_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   static ip_address_details_t empty_ip_address_details = { {0} };
2335   ip_address_details_t *address = NULL;
2336   ip_details_t *current_ip_details = NULL;
2337   ip_details_t *details = NULL;
2338
2339   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2340
2341   if (!details || vam->current_sw_if_index >= vec_len (details)
2342       || !details[vam->current_sw_if_index].present)
2343     {
2344       errmsg ("ip address details arrived but not stored");
2345       errmsg ("ip_dump should be called first");
2346       return;
2347     }
2348
2349   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2350
2351 #define addresses (current_ip_details->addr)
2352
2353   vec_validate_init_empty (addresses, vec_len (addresses),
2354                            empty_ip_address_details);
2355
2356   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2357
2358   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2359   address->prefix_length = mp->prefix_length;
2360 #undef addresses
2361 }
2362
2363 static void vl_api_ip_address_details_t_handler_json
2364   (vl_api_ip_address_details_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   vat_json_node_t *node = NULL;
2368   struct in6_addr ip6;
2369   struct in_addr ip4;
2370
2371   if (VAT_JSON_ARRAY != vam->json_tree.type)
2372     {
2373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2374       vat_json_init_array (&vam->json_tree);
2375     }
2376   node = vat_json_array_add (&vam->json_tree);
2377
2378   vat_json_init_object (node);
2379   if (vam->is_ipv6)
2380     {
2381       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2382       vat_json_object_add_ip6 (node, "ip", ip6);
2383     }
2384   else
2385     {
2386       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2387       vat_json_object_add_ip4 (node, "ip", ip4);
2388     }
2389   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2390 }
2391
2392 static void
2393 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   static ip_details_t empty_ip_details = { 0 };
2397   ip_details_t *ip = NULL;
2398   u32 sw_if_index = ~0;
2399
2400   sw_if_index = ntohl (mp->sw_if_index);
2401
2402   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2403                            sw_if_index, empty_ip_details);
2404
2405   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2406                          sw_if_index);
2407
2408   ip->present = 1;
2409 }
2410
2411 static void
2412 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415
2416   if (VAT_JSON_ARRAY != vam->json_tree.type)
2417     {
2418       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2419       vat_json_init_array (&vam->json_tree);
2420     }
2421   vat_json_array_add_uint (&vam->json_tree,
2422                            clib_net_to_host_u32 (mp->sw_if_index));
2423 }
2424
2425 static void vl_api_map_domain_details_t_handler_json
2426   (vl_api_map_domain_details_t * mp)
2427 {
2428   vat_json_node_t *node = NULL;
2429   vat_main_t *vam = &vat_main;
2430   struct in6_addr ip6;
2431   struct in_addr ip4;
2432
2433   if (VAT_JSON_ARRAY != vam->json_tree.type)
2434     {
2435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2436       vat_json_init_array (&vam->json_tree);
2437     }
2438
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441
2442   vat_json_object_add_uint (node, "domain_index",
2443                             clib_net_to_host_u32 (mp->domain_index));
2444   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2445   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2446   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2447   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2448   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2449   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2450   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2451   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2452   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2453   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2454   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2455   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2456   vat_json_object_add_uint (node, "flags", mp->flags);
2457   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2458   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2459 }
2460
2461 static void vl_api_map_domain_details_t_handler
2462   (vl_api_map_domain_details_t * mp)
2463 {
2464   vat_main_t *vam = &vat_main;
2465
2466   if (mp->is_translation)
2467     {
2468       print (vam->ofp,
2469              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2470              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2471              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2472              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2473              clib_net_to_host_u32 (mp->domain_index));
2474     }
2475   else
2476     {
2477       print (vam->ofp,
2478              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2479              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2480              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2481              format_ip6_address, mp->ip6_src,
2482              clib_net_to_host_u32 (mp->domain_index));
2483     }
2484   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2485          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2486          mp->is_translation ? "map-t" : "");
2487 }
2488
2489 static void vl_api_map_rule_details_t_handler_json
2490   (vl_api_map_rule_details_t * mp)
2491 {
2492   struct in6_addr ip6;
2493   vat_json_node_t *node = NULL;
2494   vat_main_t *vam = &vat_main;
2495
2496   if (VAT_JSON_ARRAY != vam->json_tree.type)
2497     {
2498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2499       vat_json_init_array (&vam->json_tree);
2500     }
2501
2502   node = vat_json_array_add (&vam->json_tree);
2503   vat_json_init_object (node);
2504
2505   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2506   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2507   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2508 }
2509
2510 static void
2511 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2515          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2516 }
2517
2518 static void
2519 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2520 {
2521   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2522           "router_addr %U host_mac %U",
2523           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2524           format_ip4_address, &mp->host_address,
2525           format_ip4_address, &mp->router_address,
2526           format_ethernet_address, mp->host_mac);
2527 }
2528
2529 static void vl_api_dhcp_compl_event_t_handler_json
2530   (vl_api_dhcp_compl_event_t * mp)
2531 {
2532   /* JSON output not supported */
2533 }
2534
2535 static void
2536 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2537                               u32 counter)
2538 {
2539   vat_main_t *vam = &vat_main;
2540   static u64 default_counter = 0;
2541
2542   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2543                            NULL);
2544   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2545                            sw_if_index, default_counter);
2546   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2547 }
2548
2549 static void
2550 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2551                                 interface_counter_t counter)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   static interface_counter_t default_counter = { 0, };
2555
2556   vec_validate_init_empty (vam->combined_interface_counters,
2557                            vnet_counter_type, NULL);
2558   vec_validate_init_empty (vam->combined_interface_counters
2559                            [vnet_counter_type], sw_if_index, default_counter);
2560   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2561 }
2562
2563 static void vl_api_vnet_interface_simple_counters_t_handler
2564   (vl_api_vnet_interface_simple_counters_t * mp)
2565 {
2566   /* not supported */
2567 }
2568
2569 static void vl_api_vnet_interface_combined_counters_t_handler
2570   (vl_api_vnet_interface_combined_counters_t * mp)
2571 {
2572   /* not supported */
2573 }
2574
2575 static void vl_api_vnet_interface_simple_counters_t_handler_json
2576   (vl_api_vnet_interface_simple_counters_t * mp)
2577 {
2578   u64 *v_packets;
2579   u64 packets;
2580   u32 count;
2581   u32 first_sw_if_index;
2582   int i;
2583
2584   count = ntohl (mp->count);
2585   first_sw_if_index = ntohl (mp->first_sw_if_index);
2586
2587   v_packets = (u64 *) & mp->data;
2588   for (i = 0; i < count; i++)
2589     {
2590       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2591       set_simple_interface_counter (mp->vnet_counter_type,
2592                                     first_sw_if_index + i, packets);
2593       v_packets++;
2594     }
2595 }
2596
2597 static void vl_api_vnet_interface_combined_counters_t_handler_json
2598   (vl_api_vnet_interface_combined_counters_t * mp)
2599 {
2600   interface_counter_t counter;
2601   vlib_counter_t *v;
2602   u32 first_sw_if_index;
2603   int i;
2604   u32 count;
2605
2606   count = ntohl (mp->count);
2607   first_sw_if_index = ntohl (mp->first_sw_if_index);
2608
2609   v = (vlib_counter_t *) & mp->data;
2610   for (i = 0; i < count; i++)
2611     {
2612       counter.packets =
2613         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2614       counter.bytes =
2615         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2616       set_combined_interface_counter (mp->vnet_counter_type,
2617                                       first_sw_if_index + i, counter);
2618       v++;
2619     }
2620 }
2621
2622 static u32
2623 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i;
2627
2628   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2629     {
2630       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2631         {
2632           return i;
2633         }
2634     }
2635   return ~0;
2636 }
2637
2638 static u32
2639 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2640 {
2641   vat_main_t *vam = &vat_main;
2642   u32 i;
2643
2644   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2645     {
2646       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2647         {
2648           return i;
2649         }
2650     }
2651   return ~0;
2652 }
2653
2654 static void vl_api_vnet_ip4_fib_counters_t_handler
2655   (vl_api_vnet_ip4_fib_counters_t * mp)
2656 {
2657   /* not supported */
2658 }
2659
2660 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2661   (vl_api_vnet_ip4_fib_counters_t * mp)
2662 {
2663   vat_main_t *vam = &vat_main;
2664   vl_api_ip4_fib_counter_t *v;
2665   ip4_fib_counter_t *counter;
2666   struct in_addr ip4;
2667   u32 vrf_id;
2668   u32 vrf_index;
2669   u32 count;
2670   int i;
2671
2672   vrf_id = ntohl (mp->vrf_id);
2673   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2674   if (~0 == vrf_index)
2675     {
2676       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2677       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2678       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2679       vec_validate (vam->ip4_fib_counters, vrf_index);
2680       vam->ip4_fib_counters[vrf_index] = NULL;
2681     }
2682
2683   vec_free (vam->ip4_fib_counters[vrf_index]);
2684   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2685   count = ntohl (mp->count);
2686   for (i = 0; i < count; i++)
2687     {
2688       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2689       counter = &vam->ip4_fib_counters[vrf_index][i];
2690       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2691       counter->address = ip4;
2692       counter->address_length = v->address_length;
2693       counter->packets = clib_net_to_host_u64 (v->packets);
2694       counter->bytes = clib_net_to_host_u64 (v->bytes);
2695       v++;
2696     }
2697 }
2698
2699 static void vl_api_vnet_ip4_nbr_counters_t_handler
2700   (vl_api_vnet_ip4_nbr_counters_t * mp)
2701 {
2702   /* not supported */
2703 }
2704
2705 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2706   (vl_api_vnet_ip4_nbr_counters_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vl_api_ip4_nbr_counter_t *v;
2710   ip4_nbr_counter_t *counter;
2711   u32 sw_if_index;
2712   u32 count;
2713   int i;
2714
2715   sw_if_index = ntohl (mp->sw_if_index);
2716   count = ntohl (mp->count);
2717   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2718
2719   if (mp->begin)
2720     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2721
2722   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2723   for (i = 0; i < count; i++)
2724     {
2725       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2726       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2727       counter->address.s_addr = v->address;
2728       counter->packets = clib_net_to_host_u64 (v->packets);
2729       counter->bytes = clib_net_to_host_u64 (v->bytes);
2730       counter->linkt = v->link_type;
2731       v++;
2732     }
2733 }
2734
2735 static void vl_api_vnet_ip6_fib_counters_t_handler
2736   (vl_api_vnet_ip6_fib_counters_t * mp)
2737 {
2738   /* not supported */
2739 }
2740
2741 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2742   (vl_api_vnet_ip6_fib_counters_t * mp)
2743 {
2744   vat_main_t *vam = &vat_main;
2745   vl_api_ip6_fib_counter_t *v;
2746   ip6_fib_counter_t *counter;
2747   struct in6_addr ip6;
2748   u32 vrf_id;
2749   u32 vrf_index;
2750   u32 count;
2751   int i;
2752
2753   vrf_id = ntohl (mp->vrf_id);
2754   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2755   if (~0 == vrf_index)
2756     {
2757       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2758       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2759       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2760       vec_validate (vam->ip6_fib_counters, vrf_index);
2761       vam->ip6_fib_counters[vrf_index] = NULL;
2762     }
2763
2764   vec_free (vam->ip6_fib_counters[vrf_index]);
2765   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2766   count = ntohl (mp->count);
2767   for (i = 0; i < count; i++)
2768     {
2769       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2770       counter = &vam->ip6_fib_counters[vrf_index][i];
2771       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2772       counter->address = ip6;
2773       counter->address_length = v->address_length;
2774       counter->packets = clib_net_to_host_u64 (v->packets);
2775       counter->bytes = clib_net_to_host_u64 (v->bytes);
2776       v++;
2777     }
2778 }
2779
2780 static void vl_api_vnet_ip6_nbr_counters_t_handler
2781   (vl_api_vnet_ip6_nbr_counters_t * mp)
2782 {
2783   /* not supported */
2784 }
2785
2786 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2787   (vl_api_vnet_ip6_nbr_counters_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vl_api_ip6_nbr_counter_t *v;
2791   ip6_nbr_counter_t *counter;
2792   struct in6_addr ip6;
2793   u32 sw_if_index;
2794   u32 count;
2795   int i;
2796
2797   sw_if_index = ntohl (mp->sw_if_index);
2798   count = ntohl (mp->count);
2799   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2800
2801   if (mp->begin)
2802     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2803
2804   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2805   for (i = 0; i < count; i++)
2806     {
2807       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2808       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2809       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2810       counter->address = ip6;
2811       counter->packets = clib_net_to_host_u64 (v->packets);
2812       counter->bytes = clib_net_to_host_u64 (v->bytes);
2813       v++;
2814     }
2815 }
2816
2817 static void vl_api_get_first_msg_id_reply_t_handler
2818   (vl_api_get_first_msg_id_reply_t * mp)
2819 {
2820   vat_main_t *vam = &vat_main;
2821   i32 retval = ntohl (mp->retval);
2822
2823   if (vam->async_mode)
2824     {
2825       vam->async_errors += (retval < 0);
2826     }
2827   else
2828     {
2829       vam->retval = retval;
2830       vam->result_ready = 1;
2831     }
2832   if (retval >= 0)
2833     {
2834       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2835     }
2836 }
2837
2838 static void vl_api_get_first_msg_id_reply_t_handler_json
2839   (vl_api_get_first_msg_id_reply_t * mp)
2840 {
2841   vat_main_t *vam = &vat_main;
2842   vat_json_node_t node;
2843
2844   vat_json_init_object (&node);
2845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2846   vat_json_object_add_uint (&node, "first_msg_id",
2847                             (uint) ntohs (mp->first_msg_id));
2848
2849   vat_json_print (vam->ofp, &node);
2850   vat_json_free (&node);
2851
2852   vam->retval = ntohl (mp->retval);
2853   vam->result_ready = 1;
2854 }
2855
2856 static void vl_api_get_node_graph_reply_t_handler
2857   (vl_api_get_node_graph_reply_t * mp)
2858 {
2859   vat_main_t *vam = &vat_main;
2860   api_main_t *am = &api_main;
2861   i32 retval = ntohl (mp->retval);
2862   u8 *pvt_copy, *reply;
2863   void *oldheap;
2864   vlib_node_t *node;
2865   int i;
2866
2867   if (vam->async_mode)
2868     {
2869       vam->async_errors += (retval < 0);
2870     }
2871   else
2872     {
2873       vam->retval = retval;
2874       vam->result_ready = 1;
2875     }
2876
2877   /* "Should never happen..." */
2878   if (retval != 0)
2879     return;
2880
2881   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2882   pvt_copy = vec_dup (reply);
2883
2884   /* Toss the shared-memory original... */
2885   pthread_mutex_lock (&am->vlib_rp->mutex);
2886   oldheap = svm_push_data_heap (am->vlib_rp);
2887
2888   vec_free (reply);
2889
2890   svm_pop_heap (oldheap);
2891   pthread_mutex_unlock (&am->vlib_rp->mutex);
2892
2893   if (vam->graph_nodes)
2894     {
2895       hash_free (vam->graph_node_index_by_name);
2896
2897       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2898         {
2899           node = vam->graph_nodes[i];
2900           vec_free (node->name);
2901           vec_free (node->next_nodes);
2902           vec_free (node);
2903         }
2904       vec_free (vam->graph_nodes);
2905     }
2906
2907   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2908   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2909   vec_free (pvt_copy);
2910
2911   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2912     {
2913       node = vam->graph_nodes[i];
2914       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2915     }
2916 }
2917
2918 static void vl_api_get_node_graph_reply_t_handler_json
2919   (vl_api_get_node_graph_reply_t * mp)
2920 {
2921   vat_main_t *vam = &vat_main;
2922   api_main_t *am = &api_main;
2923   void *oldheap;
2924   vat_json_node_t node;
2925   u8 *reply;
2926
2927   /* $$$$ make this real? */
2928   vat_json_init_object (&node);
2929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2930   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2931
2932   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2933
2934   /* Toss the shared-memory original... */
2935   pthread_mutex_lock (&am->vlib_rp->mutex);
2936   oldheap = svm_push_data_heap (am->vlib_rp);
2937
2938   vec_free (reply);
2939
2940   svm_pop_heap (oldheap);
2941   pthread_mutex_unlock (&am->vlib_rp->mutex);
2942
2943   vat_json_print (vam->ofp, &node);
2944   vat_json_free (&node);
2945
2946   vam->retval = ntohl (mp->retval);
2947   vam->result_ready = 1;
2948 }
2949
2950 static void
2951 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   u8 *s = 0;
2955
2956   if (mp->local)
2957     {
2958       s = format (s, "%=16d%=16d%=16d",
2959                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2960     }
2961   else
2962     {
2963       s = format (s, "%=16U%=16d%=16d",
2964                   mp->is_ipv6 ? format_ip6_address :
2965                   format_ip4_address,
2966                   mp->ip_address, mp->priority, mp->weight);
2967     }
2968
2969   print (vam->ofp, "%v", s);
2970   vec_free (s);
2971 }
2972
2973 static void
2974 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2975 {
2976   vat_main_t *vam = &vat_main;
2977   vat_json_node_t *node = NULL;
2978   struct in6_addr ip6;
2979   struct in_addr ip4;
2980
2981   if (VAT_JSON_ARRAY != vam->json_tree.type)
2982     {
2983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2984       vat_json_init_array (&vam->json_tree);
2985     }
2986   node = vat_json_array_add (&vam->json_tree);
2987   vat_json_init_object (node);
2988
2989   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2990   vat_json_object_add_uint (node, "priority", mp->priority);
2991   vat_json_object_add_uint (node, "weight", mp->weight);
2992
2993   if (mp->local)
2994     vat_json_object_add_uint (node, "sw_if_index",
2995                               clib_net_to_host_u32 (mp->sw_if_index));
2996   else
2997     {
2998       if (mp->is_ipv6)
2999         {
3000           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3001           vat_json_object_add_ip6 (node, "address", ip6);
3002         }
3003       else
3004         {
3005           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3006           vat_json_object_add_ip4 (node, "address", ip4);
3007         }
3008     }
3009 }
3010
3011 static void
3012 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3013                                           mp)
3014 {
3015   vat_main_t *vam = &vat_main;
3016   u8 *ls_name = 0;
3017
3018   ls_name = format (0, "%s", mp->ls_name);
3019
3020   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3021          ls_name);
3022   vec_free (ls_name);
3023 }
3024
3025 static void
3026   vl_api_one_locator_set_details_t_handler_json
3027   (vl_api_one_locator_set_details_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   vat_json_node_t *node = 0;
3031   u8 *ls_name = 0;
3032
3033   ls_name = format (0, "%s", mp->ls_name);
3034   vec_add1 (ls_name, 0);
3035
3036   if (VAT_JSON_ARRAY != vam->json_tree.type)
3037     {
3038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3039       vat_json_init_array (&vam->json_tree);
3040     }
3041   node = vat_json_array_add (&vam->json_tree);
3042
3043   vat_json_init_object (node);
3044   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3045   vat_json_object_add_uint (node, "ls_index",
3046                             clib_net_to_host_u32 (mp->ls_index));
3047   vec_free (ls_name);
3048 }
3049
3050 typedef struct
3051 {
3052   u32 spi;
3053   u8 si;
3054 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3055
3056 uword
3057 unformat_nsh_address (unformat_input_t * input, va_list * args)
3058 {
3059   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3060   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3061 }
3062
3063 u8 *
3064 format_nsh_address_vat (u8 * s, va_list * args)
3065 {
3066   nsh_t *a = va_arg (*args, nsh_t *);
3067   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3068 }
3069
3070 static u8 *
3071 format_lisp_flat_eid (u8 * s, va_list * args)
3072 {
3073   u32 type = va_arg (*args, u32);
3074   u8 *eid = va_arg (*args, u8 *);
3075   u32 eid_len = va_arg (*args, u32);
3076
3077   switch (type)
3078     {
3079     case 0:
3080       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3081     case 1:
3082       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3083     case 2:
3084       return format (s, "%U", format_ethernet_address, eid);
3085     case 3:
3086       return format (s, "%U", format_nsh_address_vat, eid);
3087     }
3088   return 0;
3089 }
3090
3091 static u8 *
3092 format_lisp_eid_vat (u8 * s, va_list * args)
3093 {
3094   u32 type = va_arg (*args, u32);
3095   u8 *eid = va_arg (*args, u8 *);
3096   u32 eid_len = va_arg (*args, u32);
3097   u8 *seid = va_arg (*args, u8 *);
3098   u32 seid_len = va_arg (*args, u32);
3099   u32 is_src_dst = va_arg (*args, u32);
3100
3101   if (is_src_dst)
3102     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3103
3104   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3105
3106   return s;
3107 }
3108
3109 static void
3110 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113   u8 *s = 0, *eid = 0;
3114
3115   if (~0 == mp->locator_set_index)
3116     s = format (0, "action: %d", mp->action);
3117   else
3118     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3119
3120   eid = format (0, "%U", format_lisp_eid_vat,
3121                 mp->eid_type,
3122                 mp->eid,
3123                 mp->eid_prefix_len,
3124                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3125   vec_add1 (eid, 0);
3126
3127   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3128          clib_net_to_host_u32 (mp->vni),
3129          eid,
3130          mp->is_local ? "local" : "remote",
3131          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3132          clib_net_to_host_u16 (mp->key_id), mp->key);
3133
3134   vec_free (s);
3135   vec_free (eid);
3136 }
3137
3138 static void
3139 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3140                                              * mp)
3141 {
3142   vat_main_t *vam = &vat_main;
3143   vat_json_node_t *node = 0;
3144   u8 *eid = 0;
3145
3146   if (VAT_JSON_ARRAY != vam->json_tree.type)
3147     {
3148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3149       vat_json_init_array (&vam->json_tree);
3150     }
3151   node = vat_json_array_add (&vam->json_tree);
3152
3153   vat_json_init_object (node);
3154   if (~0 == mp->locator_set_index)
3155     vat_json_object_add_uint (node, "action", mp->action);
3156   else
3157     vat_json_object_add_uint (node, "locator_set_index",
3158                               clib_net_to_host_u32 (mp->locator_set_index));
3159
3160   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3161   if (mp->eid_type == 3)
3162     {
3163       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3164       vat_json_init_object (nsh_json);
3165       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3166       vat_json_object_add_uint (nsh_json, "spi",
3167                                 clib_net_to_host_u32 (nsh->spi));
3168       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3169     }
3170   else
3171     {
3172       eid = format (0, "%U", format_lisp_eid_vat,
3173                     mp->eid_type,
3174                     mp->eid,
3175                     mp->eid_prefix_len,
3176                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3177       vec_add1 (eid, 0);
3178       vat_json_object_add_string_copy (node, "eid", eid);
3179       vec_free (eid);
3180     }
3181   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3182   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3183   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3184
3185   if (mp->key_id)
3186     {
3187       vat_json_object_add_uint (node, "key_id",
3188                                 clib_net_to_host_u16 (mp->key_id));
3189       vat_json_object_add_string_copy (node, "key", mp->key);
3190     }
3191 }
3192
3193 static void
3194 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   u8 *seid = 0, *deid = 0;
3198   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3199
3200   deid = format (0, "%U", format_lisp_eid_vat,
3201                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3202
3203   seid = format (0, "%U", format_lisp_eid_vat,
3204                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3205
3206   vec_add1 (deid, 0);
3207   vec_add1 (seid, 0);
3208
3209   if (mp->is_ip4)
3210     format_ip_address_fcn = format_ip4_address;
3211   else
3212     format_ip_address_fcn = format_ip6_address;
3213
3214
3215   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3216          clib_net_to_host_u32 (mp->vni),
3217          seid, deid,
3218          format_ip_address_fcn, mp->lloc,
3219          format_ip_address_fcn, mp->rloc,
3220          clib_net_to_host_u32 (mp->pkt_count),
3221          clib_net_to_host_u32 (mp->bytes));
3222
3223   vec_free (deid);
3224   vec_free (seid);
3225 }
3226
3227 static void
3228 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3229 {
3230   struct in6_addr ip6;
3231   struct in_addr ip4;
3232   vat_main_t *vam = &vat_main;
3233   vat_json_node_t *node = 0;
3234   u8 *deid = 0, *seid = 0;
3235
3236   if (VAT_JSON_ARRAY != vam->json_tree.type)
3237     {
3238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3239       vat_json_init_array (&vam->json_tree);
3240     }
3241   node = vat_json_array_add (&vam->json_tree);
3242
3243   vat_json_init_object (node);
3244   deid = format (0, "%U", format_lisp_eid_vat,
3245                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3246
3247   seid = format (0, "%U", format_lisp_eid_vat,
3248                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3249
3250   vec_add1 (deid, 0);
3251   vec_add1 (seid, 0);
3252
3253   vat_json_object_add_string_copy (node, "seid", seid);
3254   vat_json_object_add_string_copy (node, "deid", deid);
3255   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3256
3257   if (mp->is_ip4)
3258     {
3259       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3260       vat_json_object_add_ip4 (node, "lloc", ip4);
3261       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3262       vat_json_object_add_ip4 (node, "rloc", ip4);
3263     }
3264   else
3265     {
3266       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3267       vat_json_object_add_ip6 (node, "lloc", ip6);
3268       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3269       vat_json_object_add_ip6 (node, "rloc", ip6);
3270     }
3271   vat_json_object_add_uint (node, "pkt_count",
3272                             clib_net_to_host_u32 (mp->pkt_count));
3273   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3274
3275   vec_free (deid);
3276   vec_free (seid);
3277 }
3278
3279 static void
3280   vl_api_one_eid_table_map_details_t_handler
3281   (vl_api_one_eid_table_map_details_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284
3285   u8 *line = format (0, "%=10d%=10d",
3286                      clib_net_to_host_u32 (mp->vni),
3287                      clib_net_to_host_u32 (mp->dp_table));
3288   print (vam->ofp, "%v", line);
3289   vec_free (line);
3290 }
3291
3292 static void
3293   vl_api_one_eid_table_map_details_t_handler_json
3294   (vl_api_one_eid_table_map_details_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t *node = NULL;
3298
3299   if (VAT_JSON_ARRAY != vam->json_tree.type)
3300     {
3301       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3302       vat_json_init_array (&vam->json_tree);
3303     }
3304   node = vat_json_array_add (&vam->json_tree);
3305   vat_json_init_object (node);
3306   vat_json_object_add_uint (node, "dp_table",
3307                             clib_net_to_host_u32 (mp->dp_table));
3308   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3309 }
3310
3311 static void
3312   vl_api_one_eid_table_vni_details_t_handler
3313   (vl_api_one_eid_table_vni_details_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316
3317   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3318   print (vam->ofp, "%v", line);
3319   vec_free (line);
3320 }
3321
3322 static void
3323   vl_api_one_eid_table_vni_details_t_handler_json
3324   (vl_api_one_eid_table_vni_details_t * mp)
3325 {
3326   vat_main_t *vam = &vat_main;
3327   vat_json_node_t *node = NULL;
3328
3329   if (VAT_JSON_ARRAY != vam->json_tree.type)
3330     {
3331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3332       vat_json_init_array (&vam->json_tree);
3333     }
3334   node = vat_json_array_add (&vam->json_tree);
3335   vat_json_init_object (node);
3336   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3337 }
3338
3339 static void
3340   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3341   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3342 {
3343   vat_main_t *vam = &vat_main;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3347   print (vam->ofp, "fallback threshold value: %d", mp->value);
3348
3349   vam->retval = retval;
3350   vam->result_ready = 1;
3351 }
3352
3353 static void
3354   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3355   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3356 {
3357   vat_main_t *vam = &vat_main;
3358   vat_json_node_t _node, *node = &_node;
3359   int retval = clib_net_to_host_u32 (mp->retval);
3360
3361   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3362   vat_json_init_object (node);
3363   vat_json_object_add_uint (node, "value", mp->value);
3364
3365   vat_json_print (vam->ofp, node);
3366   vat_json_free (node);
3367
3368   vam->retval = retval;
3369   vam->result_ready = 1;
3370 }
3371
3372 static void
3373   vl_api_show_one_map_register_state_reply_t_handler
3374   (vl_api_show_one_map_register_state_reply_t * mp)
3375 {
3376   vat_main_t *vam = &vat_main;
3377   int retval = clib_net_to_host_u32 (mp->retval);
3378
3379   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3380
3381   vam->retval = retval;
3382   vam->result_ready = 1;
3383 }
3384
3385 static void
3386   vl_api_show_one_map_register_state_reply_t_handler_json
3387   (vl_api_show_one_map_register_state_reply_t * mp)
3388 {
3389   vat_main_t *vam = &vat_main;
3390   vat_json_node_t _node, *node = &_node;
3391   int retval = clib_net_to_host_u32 (mp->retval);
3392
3393   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3394
3395   vat_json_init_object (node);
3396   vat_json_object_add_string_copy (node, "state", s);
3397
3398   vat_json_print (vam->ofp, node);
3399   vat_json_free (node);
3400
3401   vam->retval = retval;
3402   vam->result_ready = 1;
3403   vec_free (s);
3404 }
3405
3406 static void
3407   vl_api_show_one_rloc_probe_state_reply_t_handler
3408   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   int retval = clib_net_to_host_u32 (mp->retval);
3412
3413   if (retval)
3414     goto end;
3415
3416   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3417 end:
3418   vam->retval = retval;
3419   vam->result_ready = 1;
3420 }
3421
3422 static void
3423   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3424   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3425 {
3426   vat_main_t *vam = &vat_main;
3427   vat_json_node_t _node, *node = &_node;
3428   int retval = clib_net_to_host_u32 (mp->retval);
3429
3430   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3431   vat_json_init_object (node);
3432   vat_json_object_add_string_copy (node, "state", s);
3433
3434   vat_json_print (vam->ofp, node);
3435   vat_json_free (node);
3436
3437   vam->retval = retval;
3438   vam->result_ready = 1;
3439   vec_free (s);
3440 }
3441
3442 static void
3443   vl_api_show_one_stats_enable_disable_reply_t_handler
3444   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   int retval = clib_net_to_host_u32 (mp->retval);
3448
3449   if (retval)
3450     goto end;
3451
3452   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3453 end:
3454   vam->retval = retval;
3455   vam->result_ready = 1;
3456 }
3457
3458 static void
3459   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3460   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3461 {
3462   vat_main_t *vam = &vat_main;
3463   vat_json_node_t _node, *node = &_node;
3464   int retval = clib_net_to_host_u32 (mp->retval);
3465
3466   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3467   vat_json_init_object (node);
3468   vat_json_object_add_string_copy (node, "state", s);
3469
3470   vat_json_print (vam->ofp, node);
3471   vat_json_free (node);
3472
3473   vam->retval = retval;
3474   vam->result_ready = 1;
3475   vec_free (s);
3476 }
3477
3478 static void
3479 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3480 {
3481   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3482   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3483   e->vni = clib_net_to_host_u32 (e->vni);
3484 }
3485
3486 static void
3487   gpe_fwd_entries_get_reply_t_net_to_host
3488   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3489 {
3490   u32 i;
3491
3492   mp->count = clib_net_to_host_u32 (mp->count);
3493   for (i = 0; i < mp->count; i++)
3494     {
3495       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3496     }
3497 }
3498
3499 static u8 *
3500 format_gpe_encap_mode (u8 * s, va_list * args)
3501 {
3502   u32 mode = va_arg (*args, u32);
3503
3504   switch (mode)
3505     {
3506     case 0:
3507       return format (s, "lisp");
3508     case 1:
3509       return format (s, "vxlan");
3510     }
3511   return 0;
3512 }
3513
3514 static void
3515   vl_api_gpe_get_encap_mode_reply_t_handler
3516   (vl_api_gpe_get_encap_mode_reply_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519
3520   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3521   vam->retval = ntohl (mp->retval);
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526   vl_api_gpe_get_encap_mode_reply_t_handler_json
3527   (vl_api_gpe_get_encap_mode_reply_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   vat_json_node_t node;
3531
3532   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3533   vec_add1 (encap_mode, 0);
3534
3535   vat_json_init_object (&node);
3536   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3537
3538   vec_free (encap_mode);
3539   vat_json_print (vam->ofp, &node);
3540   vat_json_free (&node);
3541
3542   vam->retval = ntohl (mp->retval);
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_gpe_fwd_entry_path_details_t_handler
3548   (vl_api_gpe_fwd_entry_path_details_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3552
3553   if (mp->lcl_loc.is_ip4)
3554     format_ip_address_fcn = format_ip4_address;
3555   else
3556     format_ip_address_fcn = format_ip6_address;
3557
3558   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3559          format_ip_address_fcn, &mp->lcl_loc,
3560          format_ip_address_fcn, &mp->rmt_loc);
3561 }
3562
3563 static void
3564 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3565 {
3566   struct in6_addr ip6;
3567   struct in_addr ip4;
3568
3569   if (loc->is_ip4)
3570     {
3571       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3572       vat_json_object_add_ip4 (n, "address", ip4);
3573     }
3574   else
3575     {
3576       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3577       vat_json_object_add_ip6 (n, "address", ip6);
3578     }
3579   vat_json_object_add_uint (n, "weight", loc->weight);
3580 }
3581
3582 static void
3583   vl_api_gpe_fwd_entry_path_details_t_handler_json
3584   (vl_api_gpe_fwd_entry_path_details_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   vat_json_node_t *node = NULL;
3588   vat_json_node_t *loc_node;
3589
3590   if (VAT_JSON_ARRAY != vam->json_tree.type)
3591     {
3592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3593       vat_json_init_array (&vam->json_tree);
3594     }
3595   node = vat_json_array_add (&vam->json_tree);
3596   vat_json_init_object (node);
3597
3598   loc_node = vat_json_object_add (node, "local_locator");
3599   vat_json_init_object (loc_node);
3600   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3601
3602   loc_node = vat_json_object_add (node, "remote_locator");
3603   vat_json_init_object (loc_node);
3604   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3605 }
3606
3607 static void
3608   vl_api_gpe_fwd_entries_get_reply_t_handler
3609   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   u32 i;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614   vl_api_gpe_fwd_entry_t *e;
3615
3616   if (retval)
3617     goto end;
3618
3619   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3620
3621   for (i = 0; i < mp->count; i++)
3622     {
3623       e = &mp->entries[i];
3624       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3625              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3626              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3627     }
3628
3629 end:
3630   vam->retval = retval;
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3636   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3637 {
3638   u8 *s = 0;
3639   vat_main_t *vam = &vat_main;
3640   vat_json_node_t *e = 0, root;
3641   u32 i;
3642   int retval = clib_net_to_host_u32 (mp->retval);
3643   vl_api_gpe_fwd_entry_t *fwd;
3644
3645   if (retval)
3646     goto end;
3647
3648   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3649   vat_json_init_array (&root);
3650
3651   for (i = 0; i < mp->count; i++)
3652     {
3653       e = vat_json_array_add (&root);
3654       fwd = &mp->entries[i];
3655
3656       vat_json_init_object (e);
3657       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3658       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3659       vat_json_object_add_int (e, "vni", fwd->vni);
3660       vat_json_object_add_int (e, "action", fwd->action);
3661
3662       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3663                   fwd->leid_prefix_len);
3664       vec_add1 (s, 0);
3665       vat_json_object_add_string_copy (e, "leid", s);
3666       vec_free (s);
3667
3668       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3669                   fwd->reid_prefix_len);
3670       vec_add1 (s, 0);
3671       vat_json_object_add_string_copy (e, "reid", s);
3672       vec_free (s);
3673     }
3674
3675   vat_json_print (vam->ofp, &root);
3676   vat_json_free (&root);
3677
3678 end:
3679   vam->retval = retval;
3680   vam->result_ready = 1;
3681 }
3682
3683 static void
3684   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3685   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   u32 i, n;
3689   int retval = clib_net_to_host_u32 (mp->retval);
3690   vl_api_gpe_native_fwd_rpath_t *r;
3691
3692   if (retval)
3693     goto end;
3694
3695   n = clib_net_to_host_u32 (mp->count);
3696
3697   for (i = 0; i < n; i++)
3698     {
3699       r = &mp->entries[i];
3700       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3701              clib_net_to_host_u32 (r->fib_index),
3702              clib_net_to_host_u32 (r->nh_sw_if_index),
3703              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3704     }
3705
3706 end:
3707   vam->retval = retval;
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3713   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   vat_json_node_t root, *e;
3717   u32 i, n;
3718   int retval = clib_net_to_host_u32 (mp->retval);
3719   vl_api_gpe_native_fwd_rpath_t *r;
3720   u8 *s;
3721
3722   if (retval)
3723     goto end;
3724
3725   n = clib_net_to_host_u32 (mp->count);
3726   vat_json_init_array (&root);
3727
3728   for (i = 0; i < n; i++)
3729     {
3730       e = vat_json_array_add (&root);
3731       vat_json_init_object (e);
3732       r = &mp->entries[i];
3733       s =
3734         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3735                 r->nh_addr);
3736       vec_add1 (s, 0);
3737       vat_json_object_add_string_copy (e, "ip4", s);
3738       vec_free (s);
3739
3740       vat_json_object_add_uint (e, "fib_index",
3741                                 clib_net_to_host_u32 (r->fib_index));
3742       vat_json_object_add_uint (e, "nh_sw_if_index",
3743                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3744     }
3745
3746   vat_json_print (vam->ofp, &root);
3747   vat_json_free (&root);
3748
3749 end:
3750   vam->retval = retval;
3751   vam->result_ready = 1;
3752 }
3753
3754 static void
3755   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3756   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3757 {
3758   vat_main_t *vam = &vat_main;
3759   u32 i, n;
3760   int retval = clib_net_to_host_u32 (mp->retval);
3761
3762   if (retval)
3763     goto end;
3764
3765   n = clib_net_to_host_u32 (mp->count);
3766
3767   for (i = 0; i < n; i++)
3768     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3769
3770 end:
3771   vam->retval = retval;
3772   vam->result_ready = 1;
3773 }
3774
3775 static void
3776   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3777   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   vat_json_node_t root;
3781   u32 i, n;
3782   int retval = clib_net_to_host_u32 (mp->retval);
3783
3784   if (retval)
3785     goto end;
3786
3787   n = clib_net_to_host_u32 (mp->count);
3788   vat_json_init_array (&root);
3789
3790   for (i = 0; i < n; i++)
3791     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3792
3793   vat_json_print (vam->ofp, &root);
3794   vat_json_free (&root);
3795
3796 end:
3797   vam->retval = retval;
3798   vam->result_ready = 1;
3799 }
3800
3801 static void
3802   vl_api_one_ndp_entries_get_reply_t_handler
3803   (vl_api_one_ndp_entries_get_reply_t * mp)
3804 {
3805   vat_main_t *vam = &vat_main;
3806   u32 i, n;
3807   int retval = clib_net_to_host_u32 (mp->retval);
3808
3809   if (retval)
3810     goto end;
3811
3812   n = clib_net_to_host_u32 (mp->count);
3813
3814   for (i = 0; i < n; i++)
3815     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3816            format_ethernet_address, mp->entries[i].mac);
3817
3818 end:
3819   vam->retval = retval;
3820   vam->result_ready = 1;
3821 }
3822
3823 static void
3824   vl_api_one_ndp_entries_get_reply_t_handler_json
3825   (vl_api_one_ndp_entries_get_reply_t * mp)
3826 {
3827   u8 *s = 0;
3828   vat_main_t *vam = &vat_main;
3829   vat_json_node_t *e = 0, root;
3830   u32 i, n;
3831   int retval = clib_net_to_host_u32 (mp->retval);
3832   vl_api_one_ndp_entry_t *arp_entry;
3833
3834   if (retval)
3835     goto end;
3836
3837   n = clib_net_to_host_u32 (mp->count);
3838   vat_json_init_array (&root);
3839
3840   for (i = 0; i < n; i++)
3841     {
3842       e = vat_json_array_add (&root);
3843       arp_entry = &mp->entries[i];
3844
3845       vat_json_init_object (e);
3846       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3847       vec_add1 (s, 0);
3848
3849       vat_json_object_add_string_copy (e, "mac", s);
3850       vec_free (s);
3851
3852       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3853       vec_add1 (s, 0);
3854       vat_json_object_add_string_copy (e, "ip6", s);
3855       vec_free (s);
3856     }
3857
3858   vat_json_print (vam->ofp, &root);
3859   vat_json_free (&root);
3860
3861 end:
3862   vam->retval = retval;
3863   vam->result_ready = 1;
3864 }
3865
3866 static void
3867   vl_api_one_l2_arp_entries_get_reply_t_handler
3868   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3869 {
3870   vat_main_t *vam = &vat_main;
3871   u32 i, n;
3872   int retval = clib_net_to_host_u32 (mp->retval);
3873
3874   if (retval)
3875     goto end;
3876
3877   n = clib_net_to_host_u32 (mp->count);
3878
3879   for (i = 0; i < n; i++)
3880     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3881            format_ethernet_address, mp->entries[i].mac);
3882
3883 end:
3884   vam->retval = retval;
3885   vam->result_ready = 1;
3886 }
3887
3888 static void
3889   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3890   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3891 {
3892   u8 *s = 0;
3893   vat_main_t *vam = &vat_main;
3894   vat_json_node_t *e = 0, root;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897   vl_api_one_l2_arp_entry_t *arp_entry;
3898
3899   if (retval)
3900     goto end;
3901
3902   n = clib_net_to_host_u32 (mp->count);
3903   vat_json_init_array (&root);
3904
3905   for (i = 0; i < n; i++)
3906     {
3907       e = vat_json_array_add (&root);
3908       arp_entry = &mp->entries[i];
3909
3910       vat_json_init_object (e);
3911       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3912       vec_add1 (s, 0);
3913
3914       vat_json_object_add_string_copy (e, "mac", s);
3915       vec_free (s);
3916
3917       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3918       vec_add1 (s, 0);
3919       vat_json_object_add_string_copy (e, "ip4", s);
3920       vec_free (s);
3921     }
3922
3923   vat_json_print (vam->ofp, &root);
3924   vat_json_free (&root);
3925
3926 end:
3927   vam->retval = retval;
3928   vam->result_ready = 1;
3929 }
3930
3931 static void
3932 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3933 {
3934   vat_main_t *vam = &vat_main;
3935   u32 i, n;
3936   int retval = clib_net_to_host_u32 (mp->retval);
3937
3938   if (retval)
3939     goto end;
3940
3941   n = clib_net_to_host_u32 (mp->count);
3942
3943   for (i = 0; i < n; i++)
3944     {
3945       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3946     }
3947
3948 end:
3949   vam->retval = retval;
3950   vam->result_ready = 1;
3951 }
3952
3953 static void
3954   vl_api_one_ndp_bd_get_reply_t_handler_json
3955   (vl_api_one_ndp_bd_get_reply_t * mp)
3956 {
3957   vat_main_t *vam = &vat_main;
3958   vat_json_node_t root;
3959   u32 i, n;
3960   int retval = clib_net_to_host_u32 (mp->retval);
3961
3962   if (retval)
3963     goto end;
3964
3965   n = clib_net_to_host_u32 (mp->count);
3966   vat_json_init_array (&root);
3967
3968   for (i = 0; i < n; i++)
3969     {
3970       vat_json_array_add_uint (&root,
3971                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3972     }
3973
3974   vat_json_print (vam->ofp, &root);
3975   vat_json_free (&root);
3976
3977 end:
3978   vam->retval = retval;
3979   vam->result_ready = 1;
3980 }
3981
3982 static void
3983   vl_api_one_l2_arp_bd_get_reply_t_handler
3984   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3985 {
3986   vat_main_t *vam = &vat_main;
3987   u32 i, n;
3988   int retval = clib_net_to_host_u32 (mp->retval);
3989
3990   if (retval)
3991     goto end;
3992
3993   n = clib_net_to_host_u32 (mp->count);
3994
3995   for (i = 0; i < n; i++)
3996     {
3997       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3998     }
3999
4000 end:
4001   vam->retval = retval;
4002   vam->result_ready = 1;
4003 }
4004
4005 static void
4006   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4007   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4008 {
4009   vat_main_t *vam = &vat_main;
4010   vat_json_node_t root;
4011   u32 i, n;
4012   int retval = clib_net_to_host_u32 (mp->retval);
4013
4014   if (retval)
4015     goto end;
4016
4017   n = clib_net_to_host_u32 (mp->count);
4018   vat_json_init_array (&root);
4019
4020   for (i = 0; i < n; i++)
4021     {
4022       vat_json_array_add_uint (&root,
4023                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4024     }
4025
4026   vat_json_print (vam->ofp, &root);
4027   vat_json_free (&root);
4028
4029 end:
4030   vam->retval = retval;
4031   vam->result_ready = 1;
4032 }
4033
4034 static void
4035   vl_api_one_adjacencies_get_reply_t_handler
4036   (vl_api_one_adjacencies_get_reply_t * mp)
4037 {
4038   vat_main_t *vam = &vat_main;
4039   u32 i, n;
4040   int retval = clib_net_to_host_u32 (mp->retval);
4041   vl_api_one_adjacency_t *a;
4042
4043   if (retval)
4044     goto end;
4045
4046   n = clib_net_to_host_u32 (mp->count);
4047
4048   for (i = 0; i < n; i++)
4049     {
4050       a = &mp->adjacencies[i];
4051       print (vam->ofp, "%U %40U",
4052              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4053              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4054     }
4055
4056 end:
4057   vam->retval = retval;
4058   vam->result_ready = 1;
4059 }
4060
4061 static void
4062   vl_api_one_adjacencies_get_reply_t_handler_json
4063   (vl_api_one_adjacencies_get_reply_t * mp)
4064 {
4065   u8 *s = 0;
4066   vat_main_t *vam = &vat_main;
4067   vat_json_node_t *e = 0, root;
4068   u32 i, n;
4069   int retval = clib_net_to_host_u32 (mp->retval);
4070   vl_api_one_adjacency_t *a;
4071
4072   if (retval)
4073     goto end;
4074
4075   n = clib_net_to_host_u32 (mp->count);
4076   vat_json_init_array (&root);
4077
4078   for (i = 0; i < n; i++)
4079     {
4080       e = vat_json_array_add (&root);
4081       a = &mp->adjacencies[i];
4082
4083       vat_json_init_object (e);
4084       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4085                   a->leid_prefix_len);
4086       vec_add1 (s, 0);
4087       vat_json_object_add_string_copy (e, "leid", s);
4088       vec_free (s);
4089
4090       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4091                   a->reid_prefix_len);
4092       vec_add1 (s, 0);
4093       vat_json_object_add_string_copy (e, "reid", s);
4094       vec_free (s);
4095     }
4096
4097   vat_json_print (vam->ofp, &root);
4098   vat_json_free (&root);
4099
4100 end:
4101   vam->retval = retval;
4102   vam->result_ready = 1;
4103 }
4104
4105 static void
4106 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4107 {
4108   vat_main_t *vam = &vat_main;
4109
4110   print (vam->ofp, "%=20U",
4111          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4112          mp->ip_address);
4113 }
4114
4115 static void
4116   vl_api_one_map_server_details_t_handler_json
4117   (vl_api_one_map_server_details_t * mp)
4118 {
4119   vat_main_t *vam = &vat_main;
4120   vat_json_node_t *node = NULL;
4121   struct in6_addr ip6;
4122   struct in_addr ip4;
4123
4124   if (VAT_JSON_ARRAY != vam->json_tree.type)
4125     {
4126       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4127       vat_json_init_array (&vam->json_tree);
4128     }
4129   node = vat_json_array_add (&vam->json_tree);
4130
4131   vat_json_init_object (node);
4132   if (mp->is_ipv6)
4133     {
4134       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4135       vat_json_object_add_ip6 (node, "map-server", ip6);
4136     }
4137   else
4138     {
4139       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4140       vat_json_object_add_ip4 (node, "map-server", ip4);
4141     }
4142 }
4143
4144 static void
4145 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4146                                            * mp)
4147 {
4148   vat_main_t *vam = &vat_main;
4149
4150   print (vam->ofp, "%=20U",
4151          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4152          mp->ip_address);
4153 }
4154
4155 static void
4156   vl_api_one_map_resolver_details_t_handler_json
4157   (vl_api_one_map_resolver_details_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t *node = NULL;
4161   struct in6_addr ip6;
4162   struct in_addr ip4;
4163
4164   if (VAT_JSON_ARRAY != vam->json_tree.type)
4165     {
4166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4167       vat_json_init_array (&vam->json_tree);
4168     }
4169   node = vat_json_array_add (&vam->json_tree);
4170
4171   vat_json_init_object (node);
4172   if (mp->is_ipv6)
4173     {
4174       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4175       vat_json_object_add_ip6 (node, "map resolver", ip6);
4176     }
4177   else
4178     {
4179       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4180       vat_json_object_add_ip4 (node, "map resolver", ip4);
4181     }
4182 }
4183
4184 static void
4185 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   i32 retval = ntohl (mp->retval);
4189
4190   if (0 <= retval)
4191     {
4192       print (vam->ofp, "feature: %s\ngpe: %s",
4193              mp->feature_status ? "enabled" : "disabled",
4194              mp->gpe_status ? "enabled" : "disabled");
4195     }
4196
4197   vam->retval = retval;
4198   vam->result_ready = 1;
4199 }
4200
4201 static void
4202   vl_api_show_one_status_reply_t_handler_json
4203   (vl_api_show_one_status_reply_t * mp)
4204 {
4205   vat_main_t *vam = &vat_main;
4206   vat_json_node_t node;
4207   u8 *gpe_status = NULL;
4208   u8 *feature_status = NULL;
4209
4210   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4211   feature_status = format (0, "%s",
4212                            mp->feature_status ? "enabled" : "disabled");
4213   vec_add1 (gpe_status, 0);
4214   vec_add1 (feature_status, 0);
4215
4216   vat_json_init_object (&node);
4217   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4218   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4219
4220   vec_free (gpe_status);
4221   vec_free (feature_status);
4222
4223   vat_json_print (vam->ofp, &node);
4224   vat_json_free (&node);
4225
4226   vam->retval = ntohl (mp->retval);
4227   vam->result_ready = 1;
4228 }
4229
4230 static void
4231   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4232   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4233 {
4234   vat_main_t *vam = &vat_main;
4235   i32 retval = ntohl (mp->retval);
4236
4237   if (retval >= 0)
4238     {
4239       print (vam->ofp, "%=20s", mp->locator_set_name);
4240     }
4241
4242   vam->retval = retval;
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4248   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   vat_json_node_t *node = NULL;
4252
4253   if (VAT_JSON_ARRAY != vam->json_tree.type)
4254     {
4255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4256       vat_json_init_array (&vam->json_tree);
4257     }
4258   node = vat_json_array_add (&vam->json_tree);
4259
4260   vat_json_init_object (node);
4261   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4262
4263   vat_json_print (vam->ofp, node);
4264   vat_json_free (node);
4265
4266   vam->retval = ntohl (mp->retval);
4267   vam->result_ready = 1;
4268 }
4269
4270 static u8 *
4271 format_lisp_map_request_mode (u8 * s, va_list * args)
4272 {
4273   u32 mode = va_arg (*args, u32);
4274
4275   switch (mode)
4276     {
4277     case 0:
4278       return format (0, "dst-only");
4279     case 1:
4280       return format (0, "src-dst");
4281     }
4282   return 0;
4283 }
4284
4285 static void
4286   vl_api_show_one_map_request_mode_reply_t_handler
4287   (vl_api_show_one_map_request_mode_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       u32 mode = mp->mode;
4295       print (vam->ofp, "map_request_mode: %U",
4296              format_lisp_map_request_mode, mode);
4297     }
4298
4299   vam->retval = retval;
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_show_one_map_request_mode_reply_t_handler_json
4305   (vl_api_show_one_map_request_mode_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   vat_json_node_t node;
4309   u8 *s = 0;
4310   u32 mode;
4311
4312   mode = mp->mode;
4313   s = format (0, "%U", format_lisp_map_request_mode, mode);
4314   vec_add1 (s, 0);
4315
4316   vat_json_init_object (&node);
4317   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4318   vat_json_print (vam->ofp, &node);
4319   vat_json_free (&node);
4320
4321   vec_free (s);
4322   vam->retval = ntohl (mp->retval);
4323   vam->result_ready = 1;
4324 }
4325
4326 static void
4327   vl_api_one_show_xtr_mode_reply_t_handler
4328   (vl_api_one_show_xtr_mode_reply_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331   i32 retval = ntohl (mp->retval);
4332
4333   if (0 <= retval)
4334     {
4335       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4336     }
4337
4338   vam->retval = retval;
4339   vam->result_ready = 1;
4340 }
4341
4342 static void
4343   vl_api_one_show_xtr_mode_reply_t_handler_json
4344   (vl_api_one_show_xtr_mode_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   vat_json_node_t node;
4348   u8 *status = 0;
4349
4350   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4351   vec_add1 (status, 0);
4352
4353   vat_json_init_object (&node);
4354   vat_json_object_add_string_copy (&node, "status", status);
4355
4356   vec_free (status);
4357
4358   vat_json_print (vam->ofp, &node);
4359   vat_json_free (&node);
4360
4361   vam->retval = ntohl (mp->retval);
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_one_show_pitr_mode_reply_t_handler
4367   (vl_api_one_show_pitr_mode_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   i32 retval = ntohl (mp->retval);
4371
4372   if (0 <= retval)
4373     {
4374       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4375     }
4376
4377   vam->retval = retval;
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_one_show_pitr_mode_reply_t_handler_json
4383   (vl_api_one_show_pitr_mode_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   vat_json_node_t node;
4387   u8 *status = 0;
4388
4389   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4390   vec_add1 (status, 0);
4391
4392   vat_json_init_object (&node);
4393   vat_json_object_add_string_copy (&node, "status", status);
4394
4395   vec_free (status);
4396
4397   vat_json_print (vam->ofp, &node);
4398   vat_json_free (&node);
4399
4400   vam->retval = ntohl (mp->retval);
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_one_show_petr_mode_reply_t_handler
4406   (vl_api_one_show_petr_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   i32 retval = ntohl (mp->retval);
4410
4411   if (0 <= retval)
4412     {
4413       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4414     }
4415
4416   vam->retval = retval;
4417   vam->result_ready = 1;
4418 }
4419
4420 static void
4421   vl_api_one_show_petr_mode_reply_t_handler_json
4422   (vl_api_one_show_petr_mode_reply_t * mp)
4423 {
4424   vat_main_t *vam = &vat_main;
4425   vat_json_node_t node;
4426   u8 *status = 0;
4427
4428   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4429   vec_add1 (status, 0);
4430
4431   vat_json_init_object (&node);
4432   vat_json_object_add_string_copy (&node, "status", status);
4433
4434   vec_free (status);
4435
4436   vat_json_print (vam->ofp, &node);
4437   vat_json_free (&node);
4438
4439   vam->retval = ntohl (mp->retval);
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_show_one_use_petr_reply_t_handler
4445   (vl_api_show_one_use_petr_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   i32 retval = ntohl (mp->retval);
4449
4450   if (0 <= retval)
4451     {
4452       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4453       if (mp->status)
4454         {
4455           print (vam->ofp, "Proxy-ETR address; %U",
4456                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4457                  mp->address);
4458         }
4459     }
4460
4461   vam->retval = retval;
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466   vl_api_show_one_use_petr_reply_t_handler_json
4467   (vl_api_show_one_use_petr_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   vat_json_node_t node;
4471   u8 *status = 0;
4472   struct in_addr ip4;
4473   struct in6_addr ip6;
4474
4475   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4476   vec_add1 (status, 0);
4477
4478   vat_json_init_object (&node);
4479   vat_json_object_add_string_copy (&node, "status", status);
4480   if (mp->status)
4481     {
4482       if (mp->is_ip4)
4483         {
4484           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4485           vat_json_object_add_ip6 (&node, "address", ip6);
4486         }
4487       else
4488         {
4489           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4490           vat_json_object_add_ip4 (&node, "address", ip4);
4491         }
4492     }
4493
4494   vec_free (status);
4495
4496   vat_json_print (vam->ofp, &node);
4497   vat_json_free (&node);
4498
4499   vam->retval = ntohl (mp->retval);
4500   vam->result_ready = 1;
4501 }
4502
4503 static void
4504   vl_api_show_one_nsh_mapping_reply_t_handler
4505   (vl_api_show_one_nsh_mapping_reply_t * mp)
4506 {
4507   vat_main_t *vam = &vat_main;
4508   i32 retval = ntohl (mp->retval);
4509
4510   if (0 <= retval)
4511     {
4512       print (vam->ofp, "%-20s%-16s",
4513              mp->is_set ? "set" : "not-set",
4514              mp->is_set ? (char *) mp->locator_set_name : "");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_show_one_nsh_mapping_reply_t_handler_json
4523   (vl_api_show_one_nsh_mapping_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_set ? "yes" : "no");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "is_set", status);
4534   if (mp->is_set)
4535     {
4536       vat_json_object_add_string_copy (&node, "locator_set",
4537                                        mp->locator_set_name);
4538     }
4539
4540   vec_free (status);
4541
4542   vat_json_print (vam->ofp, &node);
4543   vat_json_free (&node);
4544
4545   vam->retval = ntohl (mp->retval);
4546   vam->result_ready = 1;
4547 }
4548
4549 static void
4550   vl_api_show_one_map_register_ttl_reply_t_handler
4551   (vl_api_show_one_map_register_ttl_reply_t * mp)
4552 {
4553   vat_main_t *vam = &vat_main;
4554   i32 retval = ntohl (mp->retval);
4555
4556   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4557
4558   if (0 <= retval)
4559     {
4560       print (vam->ofp, "ttl: %u", mp->ttl);
4561     }
4562
4563   vam->retval = retval;
4564   vam->result_ready = 1;
4565 }
4566
4567 static void
4568   vl_api_show_one_map_register_ttl_reply_t_handler_json
4569   (vl_api_show_one_map_register_ttl_reply_t * mp)
4570 {
4571   vat_main_t *vam = &vat_main;
4572   vat_json_node_t node;
4573
4574   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4575   vat_json_init_object (&node);
4576   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4577
4578   vat_json_print (vam->ofp, &node);
4579   vat_json_free (&node);
4580
4581   vam->retval = ntohl (mp->retval);
4582   vam->result_ready = 1;
4583 }
4584
4585 static void
4586 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4587 {
4588   vat_main_t *vam = &vat_main;
4589   i32 retval = ntohl (mp->retval);
4590
4591   if (0 <= retval)
4592     {
4593       print (vam->ofp, "%-20s%-16s",
4594              mp->status ? "enabled" : "disabled",
4595              mp->status ? (char *) mp->locator_set_name : "");
4596     }
4597
4598   vam->retval = retval;
4599   vam->result_ready = 1;
4600 }
4601
4602 static void
4603 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4604 {
4605   vat_main_t *vam = &vat_main;
4606   vat_json_node_t node;
4607   u8 *status = 0;
4608
4609   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4610   vec_add1 (status, 0);
4611
4612   vat_json_init_object (&node);
4613   vat_json_object_add_string_copy (&node, "status", status);
4614   if (mp->status)
4615     {
4616       vat_json_object_add_string_copy (&node, "locator_set",
4617                                        mp->locator_set_name);
4618     }
4619
4620   vec_free (status);
4621
4622   vat_json_print (vam->ofp, &node);
4623   vat_json_free (&node);
4624
4625   vam->retval = ntohl (mp->retval);
4626   vam->result_ready = 1;
4627 }
4628
4629 static u8 *
4630 format_policer_type (u8 * s, va_list * va)
4631 {
4632   u32 i = va_arg (*va, u32);
4633
4634   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4635     s = format (s, "1r2c");
4636   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4637     s = format (s, "1r3c");
4638   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4639     s = format (s, "2r3c-2698");
4640   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4641     s = format (s, "2r3c-4115");
4642   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4643     s = format (s, "2r3c-mef5cf1");
4644   else
4645     s = format (s, "ILLEGAL");
4646   return s;
4647 }
4648
4649 static u8 *
4650 format_policer_rate_type (u8 * s, va_list * va)
4651 {
4652   u32 i = va_arg (*va, u32);
4653
4654   if (i == SSE2_QOS_RATE_KBPS)
4655     s = format (s, "kbps");
4656   else if (i == SSE2_QOS_RATE_PPS)
4657     s = format (s, "pps");
4658   else
4659     s = format (s, "ILLEGAL");
4660   return s;
4661 }
4662
4663 static u8 *
4664 format_policer_round_type (u8 * s, va_list * va)
4665 {
4666   u32 i = va_arg (*va, u32);
4667
4668   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4669     s = format (s, "closest");
4670   else if (i == SSE2_QOS_ROUND_TO_UP)
4671     s = format (s, "up");
4672   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4673     s = format (s, "down");
4674   else
4675     s = format (s, "ILLEGAL");
4676   return s;
4677 }
4678
4679 static u8 *
4680 format_policer_action_type (u8 * s, va_list * va)
4681 {
4682   u32 i = va_arg (*va, u32);
4683
4684   if (i == SSE2_QOS_ACTION_DROP)
4685     s = format (s, "drop");
4686   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4687     s = format (s, "transmit");
4688   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4689     s = format (s, "mark-and-transmit");
4690   else
4691     s = format (s, "ILLEGAL");
4692   return s;
4693 }
4694
4695 static u8 *
4696 format_dscp (u8 * s, va_list * va)
4697 {
4698   u32 i = va_arg (*va, u32);
4699   char *t = 0;
4700
4701   switch (i)
4702     {
4703 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4704       foreach_vnet_dscp
4705 #undef _
4706     default:
4707       return format (s, "ILLEGAL");
4708     }
4709   s = format (s, "%s", t);
4710   return s;
4711 }
4712
4713 static void
4714 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4715 {
4716   vat_main_t *vam = &vat_main;
4717   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4718
4719   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4720     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4721   else
4722     conform_dscp_str = format (0, "");
4723
4724   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4725     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4726   else
4727     exceed_dscp_str = format (0, "");
4728
4729   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4730     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4731   else
4732     violate_dscp_str = format (0, "");
4733
4734   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4735          "rate type %U, round type %U, %s rate, %s color-aware, "
4736          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4737          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4738          "conform action %U%s, exceed action %U%s, violate action %U%s",
4739          mp->name,
4740          format_policer_type, mp->type,
4741          ntohl (mp->cir),
4742          ntohl (mp->eir),
4743          clib_net_to_host_u64 (mp->cb),
4744          clib_net_to_host_u64 (mp->eb),
4745          format_policer_rate_type, mp->rate_type,
4746          format_policer_round_type, mp->round_type,
4747          mp->single_rate ? "single" : "dual",
4748          mp->color_aware ? "is" : "not",
4749          ntohl (mp->cir_tokens_per_period),
4750          ntohl (mp->pir_tokens_per_period),
4751          ntohl (mp->scale),
4752          ntohl (mp->current_limit),
4753          ntohl (mp->current_bucket),
4754          ntohl (mp->extended_limit),
4755          ntohl (mp->extended_bucket),
4756          clib_net_to_host_u64 (mp->last_update_time),
4757          format_policer_action_type, mp->conform_action_type,
4758          conform_dscp_str,
4759          format_policer_action_type, mp->exceed_action_type,
4760          exceed_dscp_str,
4761          format_policer_action_type, mp->violate_action_type,
4762          violate_dscp_str);
4763
4764   vec_free (conform_dscp_str);
4765   vec_free (exceed_dscp_str);
4766   vec_free (violate_dscp_str);
4767 }
4768
4769 static void vl_api_policer_details_t_handler_json
4770   (vl_api_policer_details_t * mp)
4771 {
4772   vat_main_t *vam = &vat_main;
4773   vat_json_node_t *node;
4774   u8 *rate_type_str, *round_type_str, *type_str;
4775   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4776
4777   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4778   round_type_str =
4779     format (0, "%U", format_policer_round_type, mp->round_type);
4780   type_str = format (0, "%U", format_policer_type, mp->type);
4781   conform_action_str = format (0, "%U", format_policer_action_type,
4782                                mp->conform_action_type);
4783   exceed_action_str = format (0, "%U", format_policer_action_type,
4784                               mp->exceed_action_type);
4785   violate_action_str = format (0, "%U", format_policer_action_type,
4786                                mp->violate_action_type);
4787
4788   if (VAT_JSON_ARRAY != vam->json_tree.type)
4789     {
4790       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4791       vat_json_init_array (&vam->json_tree);
4792     }
4793   node = vat_json_array_add (&vam->json_tree);
4794
4795   vat_json_init_object (node);
4796   vat_json_object_add_string_copy (node, "name", mp->name);
4797   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4798   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4799   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4800   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4801   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4802   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4803   vat_json_object_add_string_copy (node, "type", type_str);
4804   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4805   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4806   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4807   vat_json_object_add_uint (node, "cir_tokens_per_period",
4808                             ntohl (mp->cir_tokens_per_period));
4809   vat_json_object_add_uint (node, "eir_tokens_per_period",
4810                             ntohl (mp->pir_tokens_per_period));
4811   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4812   vat_json_object_add_uint (node, "current_bucket",
4813                             ntohl (mp->current_bucket));
4814   vat_json_object_add_uint (node, "extended_limit",
4815                             ntohl (mp->extended_limit));
4816   vat_json_object_add_uint (node, "extended_bucket",
4817                             ntohl (mp->extended_bucket));
4818   vat_json_object_add_uint (node, "last_update_time",
4819                             ntohl (mp->last_update_time));
4820   vat_json_object_add_string_copy (node, "conform_action",
4821                                    conform_action_str);
4822   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4823     {
4824       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4825       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4826       vec_free (dscp_str);
4827     }
4828   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4829   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4830     {
4831       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4832       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4833       vec_free (dscp_str);
4834     }
4835   vat_json_object_add_string_copy (node, "violate_action",
4836                                    violate_action_str);
4837   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4838     {
4839       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4840       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4841       vec_free (dscp_str);
4842     }
4843
4844   vec_free (rate_type_str);
4845   vec_free (round_type_str);
4846   vec_free (type_str);
4847   vec_free (conform_action_str);
4848   vec_free (exceed_action_str);
4849   vec_free (violate_action_str);
4850 }
4851
4852 static void
4853 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4854                                            mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   int i, count = ntohl (mp->count);
4858
4859   if (count > 0)
4860     print (vam->ofp, "classify table ids (%d) : ", count);
4861   for (i = 0; i < count; i++)
4862     {
4863       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4864       print (vam->ofp, (i < count - 1) ? "," : "");
4865     }
4866   vam->retval = ntohl (mp->retval);
4867   vam->result_ready = 1;
4868 }
4869
4870 static void
4871   vl_api_classify_table_ids_reply_t_handler_json
4872   (vl_api_classify_table_ids_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   int i, count = ntohl (mp->count);
4876
4877   if (count > 0)
4878     {
4879       vat_json_node_t node;
4880
4881       vat_json_init_object (&node);
4882       for (i = 0; i < count; i++)
4883         {
4884           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4885         }
4886       vat_json_print (vam->ofp, &node);
4887       vat_json_free (&node);
4888     }
4889   vam->retval = ntohl (mp->retval);
4890   vam->result_ready = 1;
4891 }
4892
4893 static void
4894   vl_api_classify_table_by_interface_reply_t_handler
4895   (vl_api_classify_table_by_interface_reply_t * mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898   u32 table_id;
4899
4900   table_id = ntohl (mp->l2_table_id);
4901   if (table_id != ~0)
4902     print (vam->ofp, "l2 table id : %d", table_id);
4903   else
4904     print (vam->ofp, "l2 table id : No input ACL tables configured");
4905   table_id = ntohl (mp->ip4_table_id);
4906   if (table_id != ~0)
4907     print (vam->ofp, "ip4 table id : %d", table_id);
4908   else
4909     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4910   table_id = ntohl (mp->ip6_table_id);
4911   if (table_id != ~0)
4912     print (vam->ofp, "ip6 table id : %d", table_id);
4913   else
4914     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 static void
4920   vl_api_classify_table_by_interface_reply_t_handler_json
4921   (vl_api_classify_table_by_interface_reply_t * mp)
4922 {
4923   vat_main_t *vam = &vat_main;
4924   vat_json_node_t node;
4925
4926   vat_json_init_object (&node);
4927
4928   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4929   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4930   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4931
4932   vat_json_print (vam->ofp, &node);
4933   vat_json_free (&node);
4934
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_policer_add_del_reply_t_handler
4940   (vl_api_policer_add_del_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   i32 retval = ntohl (mp->retval);
4944   if (vam->async_mode)
4945     {
4946       vam->async_errors += (retval < 0);
4947     }
4948   else
4949     {
4950       vam->retval = retval;
4951       vam->result_ready = 1;
4952       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4953         /*
4954          * Note: this is just barely thread-safe, depends on
4955          * the main thread spinning waiting for an answer...
4956          */
4957         errmsg ("policer index %d", ntohl (mp->policer_index));
4958     }
4959 }
4960
4961 static void vl_api_policer_add_del_reply_t_handler_json
4962   (vl_api_policer_add_del_reply_t * mp)
4963 {
4964   vat_main_t *vam = &vat_main;
4965   vat_json_node_t node;
4966
4967   vat_json_init_object (&node);
4968   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4969   vat_json_object_add_uint (&node, "policer_index",
4970                             ntohl (mp->policer_index));
4971
4972   vat_json_print (vam->ofp, &node);
4973   vat_json_free (&node);
4974
4975   vam->retval = ntohl (mp->retval);
4976   vam->result_ready = 1;
4977 }
4978
4979 /* Format hex dump. */
4980 u8 *
4981 format_hex_bytes (u8 * s, va_list * va)
4982 {
4983   u8 *bytes = va_arg (*va, u8 *);
4984   int n_bytes = va_arg (*va, int);
4985   uword i;
4986
4987   /* Print short or long form depending on byte count. */
4988   uword short_form = n_bytes <= 32;
4989   u32 indent = format_get_indent (s);
4990
4991   if (n_bytes == 0)
4992     return s;
4993
4994   for (i = 0; i < n_bytes; i++)
4995     {
4996       if (!short_form && (i % 32) == 0)
4997         s = format (s, "%08x: ", i);
4998       s = format (s, "%02x", bytes[i]);
4999       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5000         s = format (s, "\n%U", format_white_space, indent);
5001     }
5002
5003   return s;
5004 }
5005
5006 static void
5007 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5008                                             * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011   i32 retval = ntohl (mp->retval);
5012   if (retval == 0)
5013     {
5014       print (vam->ofp, "classify table info :");
5015       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5016              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5017              ntohl (mp->miss_next_index));
5018       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5019              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5020              ntohl (mp->match_n_vectors));
5021       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5022              ntohl (mp->mask_length));
5023     }
5024   vam->retval = retval;
5025   vam->result_ready = 1;
5026 }
5027
5028 static void
5029   vl_api_classify_table_info_reply_t_handler_json
5030   (vl_api_classify_table_info_reply_t * mp)
5031 {
5032   vat_main_t *vam = &vat_main;
5033   vat_json_node_t node;
5034
5035   i32 retval = ntohl (mp->retval);
5036   if (retval == 0)
5037     {
5038       vat_json_init_object (&node);
5039
5040       vat_json_object_add_int (&node, "sessions",
5041                                ntohl (mp->active_sessions));
5042       vat_json_object_add_int (&node, "nexttbl",
5043                                ntohl (mp->next_table_index));
5044       vat_json_object_add_int (&node, "nextnode",
5045                                ntohl (mp->miss_next_index));
5046       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5047       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5048       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5049       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5050                       ntohl (mp->mask_length), 0);
5051       vat_json_object_add_string_copy (&node, "mask", s);
5052
5053       vat_json_print (vam->ofp, &node);
5054       vat_json_free (&node);
5055     }
5056   vam->retval = ntohl (mp->retval);
5057   vam->result_ready = 1;
5058 }
5059
5060 static void
5061 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5062                                            mp)
5063 {
5064   vat_main_t *vam = &vat_main;
5065
5066   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5067          ntohl (mp->hit_next_index), ntohl (mp->advance),
5068          ntohl (mp->opaque_index));
5069   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5070          ntohl (mp->match_length));
5071 }
5072
5073 static void
5074   vl_api_classify_session_details_t_handler_json
5075   (vl_api_classify_session_details_t * mp)
5076 {
5077   vat_main_t *vam = &vat_main;
5078   vat_json_node_t *node = NULL;
5079
5080   if (VAT_JSON_ARRAY != vam->json_tree.type)
5081     {
5082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5083       vat_json_init_array (&vam->json_tree);
5084     }
5085   node = vat_json_array_add (&vam->json_tree);
5086
5087   vat_json_init_object (node);
5088   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5089   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5090   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5091   u8 *s =
5092     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5093             0);
5094   vat_json_object_add_string_copy (node, "match", s);
5095 }
5096
5097 static void vl_api_pg_create_interface_reply_t_handler
5098   (vl_api_pg_create_interface_reply_t * mp)
5099 {
5100   vat_main_t *vam = &vat_main;
5101
5102   vam->retval = ntohl (mp->retval);
5103   vam->result_ready = 1;
5104 }
5105
5106 static void vl_api_pg_create_interface_reply_t_handler_json
5107   (vl_api_pg_create_interface_reply_t * mp)
5108 {
5109   vat_main_t *vam = &vat_main;
5110   vat_json_node_t node;
5111
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       vat_json_init_object (&node);
5116
5117       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5118
5119       vat_json_print (vam->ofp, &node);
5120       vat_json_free (&node);
5121     }
5122   vam->retval = ntohl (mp->retval);
5123   vam->result_ready = 1;
5124 }
5125
5126 static void vl_api_policer_classify_details_t_handler
5127   (vl_api_policer_classify_details_t * mp)
5128 {
5129   vat_main_t *vam = &vat_main;
5130
5131   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5132          ntohl (mp->table_index));
5133 }
5134
5135 static void vl_api_policer_classify_details_t_handler_json
5136   (vl_api_policer_classify_details_t * mp)
5137 {
5138   vat_main_t *vam = &vat_main;
5139   vat_json_node_t *node;
5140
5141   if (VAT_JSON_ARRAY != vam->json_tree.type)
5142     {
5143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5144       vat_json_init_array (&vam->json_tree);
5145     }
5146   node = vat_json_array_add (&vam->json_tree);
5147
5148   vat_json_init_object (node);
5149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5150   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5151 }
5152
5153 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5154   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5155 {
5156   vat_main_t *vam = &vat_main;
5157   i32 retval = ntohl (mp->retval);
5158   if (vam->async_mode)
5159     {
5160       vam->async_errors += (retval < 0);
5161     }
5162   else
5163     {
5164       vam->retval = retval;
5165       vam->sw_if_index = ntohl (mp->sw_if_index);
5166       vam->result_ready = 1;
5167     }
5168   vam->regenerate_interface_table = 1;
5169 }
5170
5171 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5172   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175   vat_json_node_t node;
5176
5177   vat_json_init_object (&node);
5178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5179   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5180
5181   vat_json_print (vam->ofp, &node);
5182   vat_json_free (&node);
5183
5184   vam->retval = ntohl (mp->retval);
5185   vam->result_ready = 1;
5186 }
5187
5188 static void vl_api_flow_classify_details_t_handler
5189   (vl_api_flow_classify_details_t * mp)
5190 {
5191   vat_main_t *vam = &vat_main;
5192
5193   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5194          ntohl (mp->table_index));
5195 }
5196
5197 static void vl_api_flow_classify_details_t_handler_json
5198   (vl_api_flow_classify_details_t * mp)
5199 {
5200   vat_main_t *vam = &vat_main;
5201   vat_json_node_t *node;
5202
5203   if (VAT_JSON_ARRAY != vam->json_tree.type)
5204     {
5205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5206       vat_json_init_array (&vam->json_tree);
5207     }
5208   node = vat_json_array_add (&vam->json_tree);
5209
5210   vat_json_init_object (node);
5211   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5212   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5213 }
5214
5215 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5216 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5217 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5218 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5219 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5220 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5221 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5222 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5223 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5224 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5225 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5226 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5227 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5228 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5229 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5230 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5231 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5232 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5233 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5234 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5235 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5236 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5237
5238 /*
5239  * Generate boilerplate reply handlers, which
5240  * dig the return value out of the xxx_reply_t API message,
5241  * stick it into vam->retval, and set vam->result_ready
5242  *
5243  * Could also do this by pointing N message decode slots at
5244  * a single function, but that could break in subtle ways.
5245  */
5246
5247 #define foreach_standard_reply_retval_handler           \
5248 _(sw_interface_set_flags_reply)                         \
5249 _(sw_interface_add_del_address_reply)                   \
5250 _(sw_interface_set_rx_mode_reply)                       \
5251 _(sw_interface_set_table_reply)                         \
5252 _(sw_interface_set_mpls_enable_reply)                   \
5253 _(sw_interface_set_vpath_reply)                         \
5254 _(sw_interface_set_vxlan_bypass_reply)                  \
5255 _(sw_interface_set_geneve_bypass_reply)                 \
5256 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5257 _(sw_interface_set_l2_bridge_reply)                     \
5258 _(bridge_domain_add_del_reply)                          \
5259 _(sw_interface_set_l2_xconnect_reply)                   \
5260 _(l2fib_add_del_reply)                                  \
5261 _(l2fib_flush_int_reply)                                \
5262 _(l2fib_flush_bd_reply)                                 \
5263 _(ip_add_del_route_reply)                               \
5264 _(ip_table_add_del_reply)                               \
5265 _(ip_mroute_add_del_reply)                              \
5266 _(mpls_route_add_del_reply)                             \
5267 _(mpls_table_add_del_reply)                             \
5268 _(mpls_ip_bind_unbind_reply)                            \
5269 _(bier_route_add_del_reply)                             \
5270 _(bier_table_add_del_reply)                             \
5271 _(proxy_arp_add_del_reply)                              \
5272 _(proxy_arp_intfc_enable_disable_reply)                 \
5273 _(sw_interface_set_unnumbered_reply)                    \
5274 _(ip_neighbor_add_del_reply)                            \
5275 _(oam_add_del_reply)                                    \
5276 _(reset_fib_reply)                                      \
5277 _(dhcp_proxy_config_reply)                              \
5278 _(dhcp_proxy_set_vss_reply)                             \
5279 _(dhcp_client_config_reply)                             \
5280 _(set_ip_flow_hash_reply)                               \
5281 _(sw_interface_ip6_enable_disable_reply)                \
5282 _(sw_interface_ip6_set_link_local_address_reply)        \
5283 _(ip6nd_proxy_add_del_reply)                            \
5284 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5285 _(sw_interface_ip6nd_ra_config_reply)                   \
5286 _(set_arp_neighbor_limit_reply)                         \
5287 _(l2_patch_add_del_reply)                               \
5288 _(sr_policy_add_reply)                                  \
5289 _(sr_policy_mod_reply)                                  \
5290 _(sr_policy_del_reply)                                  \
5291 _(sr_localsid_add_del_reply)                            \
5292 _(sr_steering_add_del_reply)                            \
5293 _(classify_add_del_session_reply)                       \
5294 _(classify_set_interface_ip_table_reply)                \
5295 _(classify_set_interface_l2_tables_reply)               \
5296 _(l2tpv3_set_tunnel_cookies_reply)                      \
5297 _(l2tpv3_interface_enable_disable_reply)                \
5298 _(l2tpv3_set_lookup_key_reply)                          \
5299 _(l2_fib_clear_table_reply)                             \
5300 _(l2_interface_efp_filter_reply)                        \
5301 _(l2_interface_vlan_tag_rewrite_reply)                  \
5302 _(modify_vhost_user_if_reply)                           \
5303 _(delete_vhost_user_if_reply)                           \
5304 _(want_ip4_arp_events_reply)                            \
5305 _(want_ip6_nd_events_reply)                             \
5306 _(want_l2_macs_events_reply)                            \
5307 _(input_acl_set_interface_reply)                        \
5308 _(ipsec_spd_add_del_reply)                              \
5309 _(ipsec_interface_add_del_spd_reply)                    \
5310 _(ipsec_spd_add_del_entry_reply)                        \
5311 _(ipsec_sad_add_del_entry_reply)                        \
5312 _(ipsec_sa_set_key_reply)                               \
5313 _(ipsec_tunnel_if_add_del_reply)                        \
5314 _(ipsec_tunnel_if_set_key_reply)                        \
5315 _(ipsec_tunnel_if_set_sa_reply)                         \
5316 _(ikev2_profile_add_del_reply)                          \
5317 _(ikev2_profile_set_auth_reply)                         \
5318 _(ikev2_profile_set_id_reply)                           \
5319 _(ikev2_profile_set_ts_reply)                           \
5320 _(ikev2_set_local_key_reply)                            \
5321 _(ikev2_set_responder_reply)                            \
5322 _(ikev2_set_ike_transforms_reply)                       \
5323 _(ikev2_set_esp_transforms_reply)                       \
5324 _(ikev2_set_sa_lifetime_reply)                          \
5325 _(ikev2_initiate_sa_init_reply)                         \
5326 _(ikev2_initiate_del_ike_sa_reply)                      \
5327 _(ikev2_initiate_del_child_sa_reply)                    \
5328 _(ikev2_initiate_rekey_child_sa_reply)                  \
5329 _(delete_loopback_reply)                                \
5330 _(bd_ip_mac_add_del_reply)                              \
5331 _(map_del_domain_reply)                                 \
5332 _(map_add_del_rule_reply)                               \
5333 _(want_interface_events_reply)                          \
5334 _(want_stats_reply)                                     \
5335 _(cop_interface_enable_disable_reply)                   \
5336 _(cop_whitelist_enable_disable_reply)                   \
5337 _(sw_interface_clear_stats_reply)                       \
5338 _(ioam_enable_reply)                                    \
5339 _(ioam_disable_reply)                                   \
5340 _(one_add_del_locator_reply)                            \
5341 _(one_add_del_local_eid_reply)                          \
5342 _(one_add_del_remote_mapping_reply)                     \
5343 _(one_add_del_adjacency_reply)                          \
5344 _(one_add_del_map_resolver_reply)                       \
5345 _(one_add_del_map_server_reply)                         \
5346 _(one_enable_disable_reply)                             \
5347 _(one_rloc_probe_enable_disable_reply)                  \
5348 _(one_map_register_enable_disable_reply)                \
5349 _(one_map_register_set_ttl_reply)                       \
5350 _(one_set_transport_protocol_reply)                     \
5351 _(one_map_register_fallback_threshold_reply)            \
5352 _(one_pitr_set_locator_set_reply)                       \
5353 _(one_map_request_mode_reply)                           \
5354 _(one_add_del_map_request_itr_rlocs_reply)              \
5355 _(one_eid_table_add_del_map_reply)                      \
5356 _(one_use_petr_reply)                                   \
5357 _(one_stats_enable_disable_reply)                       \
5358 _(one_add_del_l2_arp_entry_reply)                       \
5359 _(one_add_del_ndp_entry_reply)                          \
5360 _(one_stats_flush_reply)                                \
5361 _(one_enable_disable_xtr_mode_reply)                    \
5362 _(one_enable_disable_pitr_mode_reply)                   \
5363 _(one_enable_disable_petr_mode_reply)                   \
5364 _(gpe_enable_disable_reply)                             \
5365 _(gpe_set_encap_mode_reply)                             \
5366 _(gpe_add_del_iface_reply)                              \
5367 _(gpe_add_del_native_fwd_rpath_reply)                   \
5368 _(af_packet_delete_reply)                               \
5369 _(policer_classify_set_interface_reply)                 \
5370 _(netmap_create_reply)                                  \
5371 _(netmap_delete_reply)                                  \
5372 _(set_ipfix_exporter_reply)                             \
5373 _(set_ipfix_classify_stream_reply)                      \
5374 _(ipfix_classify_table_add_del_reply)                   \
5375 _(flow_classify_set_interface_reply)                    \
5376 _(sw_interface_span_enable_disable_reply)               \
5377 _(pg_capture_reply)                                     \
5378 _(pg_enable_disable_reply)                              \
5379 _(ip_source_and_port_range_check_add_del_reply)         \
5380 _(ip_source_and_port_range_check_interface_add_del_reply)\
5381 _(delete_subif_reply)                                   \
5382 _(l2_interface_pbb_tag_rewrite_reply)                   \
5383 _(punt_reply)                                           \
5384 _(feature_enable_disable_reply)                         \
5385 _(sw_interface_tag_add_del_reply)                       \
5386 _(sw_interface_set_mtu_reply)                           \
5387 _(p2p_ethernet_add_reply)                               \
5388 _(p2p_ethernet_del_reply)                               \
5389 _(lldp_config_reply)                                    \
5390 _(sw_interface_set_lldp_reply)                          \
5391 _(tcp_configure_src_addresses_reply)                    \
5392 _(dns_enable_disable_reply)                             \
5393 _(dns_name_server_add_del_reply)                        \
5394 _(session_rule_add_del_reply)                           \
5395 _(ip_container_proxy_add_del_reply)
5396
5397 #define _(n)                                    \
5398     static void vl_api_##n##_t_handler          \
5399     (vl_api_##n##_t * mp)                       \
5400     {                                           \
5401         vat_main_t * vam = &vat_main;           \
5402         i32 retval = ntohl(mp->retval);         \
5403         if (vam->async_mode) {                  \
5404             vam->async_errors += (retval < 0);  \
5405         } else {                                \
5406             vam->retval = retval;               \
5407             vam->result_ready = 1;              \
5408         }                                       \
5409     }
5410 foreach_standard_reply_retval_handler;
5411 #undef _
5412
5413 #define _(n)                                    \
5414     static void vl_api_##n##_t_handler_json     \
5415     (vl_api_##n##_t * mp)                       \
5416     {                                           \
5417         vat_main_t * vam = &vat_main;           \
5418         vat_json_node_t node;                   \
5419         vat_json_init_object(&node);            \
5420         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5421         vat_json_print(vam->ofp, &node);        \
5422         vam->retval = ntohl(mp->retval);        \
5423         vam->result_ready = 1;                  \
5424     }
5425 foreach_standard_reply_retval_handler;
5426 #undef _
5427
5428 /*
5429  * Table of message reply handlers, must include boilerplate handlers
5430  * we just generated
5431  */
5432
5433 #define foreach_vpe_api_reply_msg                                       \
5434 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5435 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5436 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5437 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5438 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5439 _(CLI_REPLY, cli_reply)                                                 \
5440 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5441 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5442   sw_interface_add_del_address_reply)                                   \
5443 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5444 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5445 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5446 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5447 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5448 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5449 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5450 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5451   sw_interface_set_l2_xconnect_reply)                                   \
5452 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5453   sw_interface_set_l2_bridge_reply)                                     \
5454 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5455 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5456 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5457 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5458 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5459 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5460 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5461 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5462 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5463 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5464 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5465 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5466 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5467 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5468 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5469 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5470 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5471 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5472 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5473 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5474 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5475 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5476 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5477 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5478 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5479   proxy_arp_intfc_enable_disable_reply)                                 \
5480 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5481 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5482   sw_interface_set_unnumbered_reply)                                    \
5483 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5484 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5485 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5486 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5487 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5488 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5489 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5490 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5491 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5492 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5493 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5494   sw_interface_ip6_enable_disable_reply)                                \
5495 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5496   sw_interface_ip6_set_link_local_address_reply)                        \
5497 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5498 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5499 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5500   sw_interface_ip6nd_ra_prefix_reply)                                   \
5501 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5502   sw_interface_ip6nd_ra_config_reply)                                   \
5503 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5504 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5505 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5506 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5507 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5508 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5509 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5510 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5511 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5512 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5513 classify_set_interface_ip_table_reply)                                  \
5514 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5515   classify_set_interface_l2_tables_reply)                               \
5516 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5517 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5518 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5519 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5520 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5521   l2tpv3_interface_enable_disable_reply)                                \
5522 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5523 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5524 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5525 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5526 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5527 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5528 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5529 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5530 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5531 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5532 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5533 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5534 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5535 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5536 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5537 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5538 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5539 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5540 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5541 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5542 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5543 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5544 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5545 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5546 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5547 _(L2_MACS_EVENT, l2_macs_event)                                         \
5548 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5549 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5550 _(IP_DETAILS, ip_details)                                               \
5551 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5552 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5553 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5554 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5555 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5556 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5557 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5558 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5559 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5560 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5561 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5562 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5563 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5564 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5565 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5566 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5567 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5568 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5569 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5570 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5571 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5572 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5573 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5574 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5575 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5576 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5577 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5578 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5579 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5580 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5581 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5582 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5583 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5584 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5585 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5586 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5587 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5588 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5589 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5590 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5591 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5592 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5593 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5594 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5595 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5596 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5597 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5598 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5599   one_map_register_enable_disable_reply)                                \
5600 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5601 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5602 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5603 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5604   one_map_register_fallback_threshold_reply)                            \
5605 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5606   one_rloc_probe_enable_disable_reply)                                  \
5607 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5608 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5609 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5610 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5611 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5612 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5613 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5614 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5615 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5616 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5617 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5618 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5619 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5620 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5621 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5622 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5623   show_one_stats_enable_disable_reply)                                  \
5624 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5625 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5626 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5627 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5628 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5629 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5630 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5631 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5632   one_enable_disable_pitr_mode_reply)                                   \
5633 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5634   one_enable_disable_petr_mode_reply)                                   \
5635 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5636 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5637 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5638 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5639 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5640 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5641 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5642 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5643 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5644 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5645 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5646 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5647   gpe_add_del_native_fwd_rpath_reply)                                   \
5648 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5649   gpe_fwd_entry_path_details)                                           \
5650 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5651 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5652   one_add_del_map_request_itr_rlocs_reply)                              \
5653 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5654   one_get_map_request_itr_rlocs_reply)                                  \
5655 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5656 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5657 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5658 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5659 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5660 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5661   show_one_map_register_state_reply)                                    \
5662 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5663 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5664   show_one_map_register_fallback_threshold_reply)                       \
5665 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5666 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5667 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5668 _(POLICER_DETAILS, policer_details)                                     \
5669 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5670 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5671 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5672 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5673 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5674 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5675 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5676 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5677 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5678 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5679 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5680 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5681 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5682 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5683 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5684 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5685 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5686 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5687 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5688 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5689 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5690 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5691 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5692 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5693 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5694  ip_source_and_port_range_check_add_del_reply)                          \
5695 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5696  ip_source_and_port_range_check_interface_add_del_reply)                \
5697 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5698 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5699 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5700 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5701 _(PUNT_REPLY, punt_reply)                                               \
5702 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5703 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5704 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5705 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5706 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5707 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5708 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5709 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5710 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5711 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5712 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5713 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5714 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5715 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5716 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5717 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5718 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5719 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5720 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5721 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5722 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5723
5724 #define foreach_standalone_reply_msg                                    \
5725 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5726 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5727 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5728 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5729 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5730 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5731 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5732 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5733
5734 typedef struct
5735 {
5736   u8 *name;
5737   u32 value;
5738 } name_sort_t;
5739
5740
5741 #define STR_VTR_OP_CASE(op)     \
5742     case L2_VTR_ ## op:         \
5743         return "" # op;
5744
5745 static const char *
5746 str_vtr_op (u32 vtr_op)
5747 {
5748   switch (vtr_op)
5749     {
5750       STR_VTR_OP_CASE (DISABLED);
5751       STR_VTR_OP_CASE (PUSH_1);
5752       STR_VTR_OP_CASE (PUSH_2);
5753       STR_VTR_OP_CASE (POP_1);
5754       STR_VTR_OP_CASE (POP_2);
5755       STR_VTR_OP_CASE (TRANSLATE_1_1);
5756       STR_VTR_OP_CASE (TRANSLATE_1_2);
5757       STR_VTR_OP_CASE (TRANSLATE_2_1);
5758       STR_VTR_OP_CASE (TRANSLATE_2_2);
5759     }
5760
5761   return "UNKNOWN";
5762 }
5763
5764 static int
5765 dump_sub_interface_table (vat_main_t * vam)
5766 {
5767   const sw_interface_subif_t *sub = NULL;
5768
5769   if (vam->json_output)
5770     {
5771       clib_warning
5772         ("JSON output supported only for VPE API calls and dump_stats_table");
5773       return -99;
5774     }
5775
5776   print (vam->ofp,
5777          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5778          "Interface", "sw_if_index",
5779          "sub id", "dot1ad", "tags", "outer id",
5780          "inner id", "exact", "default", "outer any", "inner any");
5781
5782   vec_foreach (sub, vam->sw_if_subif_table)
5783   {
5784     print (vam->ofp,
5785            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5786            sub->interface_name,
5787            sub->sw_if_index,
5788            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5789            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5790            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5791            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5792     if (sub->vtr_op != L2_VTR_DISABLED)
5793       {
5794         print (vam->ofp,
5795                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5796                "tag1: %d tag2: %d ]",
5797                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5798                sub->vtr_tag1, sub->vtr_tag2);
5799       }
5800   }
5801
5802   return 0;
5803 }
5804
5805 static int
5806 name_sort_cmp (void *a1, void *a2)
5807 {
5808   name_sort_t *n1 = a1;
5809   name_sort_t *n2 = a2;
5810
5811   return strcmp ((char *) n1->name, (char *) n2->name);
5812 }
5813
5814 static int
5815 dump_interface_table (vat_main_t * vam)
5816 {
5817   hash_pair_t *p;
5818   name_sort_t *nses = 0, *ns;
5819
5820   if (vam->json_output)
5821     {
5822       clib_warning
5823         ("JSON output supported only for VPE API calls and dump_stats_table");
5824       return -99;
5825     }
5826
5827   /* *INDENT-OFF* */
5828   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5829   ({
5830     vec_add2 (nses, ns, 1);
5831     ns->name = (u8 *)(p->key);
5832     ns->value = (u32) p->value[0];
5833   }));
5834   /* *INDENT-ON* */
5835
5836   vec_sort_with_function (nses, name_sort_cmp);
5837
5838   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5839   vec_foreach (ns, nses)
5840   {
5841     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5842   }
5843   vec_free (nses);
5844   return 0;
5845 }
5846
5847 static int
5848 dump_ip_table (vat_main_t * vam, int is_ipv6)
5849 {
5850   const ip_details_t *det = NULL;
5851   const ip_address_details_t *address = NULL;
5852   u32 i = ~0;
5853
5854   print (vam->ofp, "%-12s", "sw_if_index");
5855
5856   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5857   {
5858     i++;
5859     if (!det->present)
5860       {
5861         continue;
5862       }
5863     print (vam->ofp, "%-12d", i);
5864     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5865     if (!det->addr)
5866       {
5867         continue;
5868       }
5869     vec_foreach (address, det->addr)
5870     {
5871       print (vam->ofp,
5872              "            %-30U%-13d",
5873              is_ipv6 ? format_ip6_address : format_ip4_address,
5874              address->ip, address->prefix_length);
5875     }
5876   }
5877
5878   return 0;
5879 }
5880
5881 static int
5882 dump_ipv4_table (vat_main_t * vam)
5883 {
5884   if (vam->json_output)
5885     {
5886       clib_warning
5887         ("JSON output supported only for VPE API calls and dump_stats_table");
5888       return -99;
5889     }
5890
5891   return dump_ip_table (vam, 0);
5892 }
5893
5894 static int
5895 dump_ipv6_table (vat_main_t * vam)
5896 {
5897   if (vam->json_output)
5898     {
5899       clib_warning
5900         ("JSON output supported only for VPE API calls and dump_stats_table");
5901       return -99;
5902     }
5903
5904   return dump_ip_table (vam, 1);
5905 }
5906
5907 static char *
5908 counter_type_to_str (u8 counter_type, u8 is_combined)
5909 {
5910   if (!is_combined)
5911     {
5912       switch (counter_type)
5913         {
5914         case VNET_INTERFACE_COUNTER_DROP:
5915           return "drop";
5916         case VNET_INTERFACE_COUNTER_PUNT:
5917           return "punt";
5918         case VNET_INTERFACE_COUNTER_IP4:
5919           return "ip4";
5920         case VNET_INTERFACE_COUNTER_IP6:
5921           return "ip6";
5922         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5923           return "rx-no-buf";
5924         case VNET_INTERFACE_COUNTER_RX_MISS:
5925           return "rx-miss";
5926         case VNET_INTERFACE_COUNTER_RX_ERROR:
5927           return "rx-error";
5928         case VNET_INTERFACE_COUNTER_TX_ERROR:
5929           return "tx-error";
5930         default:
5931           return "INVALID-COUNTER-TYPE";
5932         }
5933     }
5934   else
5935     {
5936       switch (counter_type)
5937         {
5938         case VNET_INTERFACE_COUNTER_RX:
5939           return "rx";
5940         case VNET_INTERFACE_COUNTER_TX:
5941           return "tx";
5942         default:
5943           return "INVALID-COUNTER-TYPE";
5944         }
5945     }
5946 }
5947
5948 static int
5949 dump_stats_table (vat_main_t * vam)
5950 {
5951   vat_json_node_t node;
5952   vat_json_node_t *msg_array;
5953   vat_json_node_t *msg;
5954   vat_json_node_t *counter_array;
5955   vat_json_node_t *counter;
5956   interface_counter_t c;
5957   u64 packets;
5958   ip4_fib_counter_t *c4;
5959   ip6_fib_counter_t *c6;
5960   ip4_nbr_counter_t *n4;
5961   ip6_nbr_counter_t *n6;
5962   int i, j;
5963
5964   if (!vam->json_output)
5965     {
5966       clib_warning ("dump_stats_table supported only in JSON format");
5967       return -99;
5968     }
5969
5970   vat_json_init_object (&node);
5971
5972   /* interface counters */
5973   msg_array = vat_json_object_add (&node, "interface_counters");
5974   vat_json_init_array (msg_array);
5975   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5976     {
5977       msg = vat_json_array_add (msg_array);
5978       vat_json_init_object (msg);
5979       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5980                                        (u8 *) counter_type_to_str (i, 0));
5981       vat_json_object_add_int (msg, "is_combined", 0);
5982       counter_array = vat_json_object_add (msg, "data");
5983       vat_json_init_array (counter_array);
5984       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5985         {
5986           packets = vam->simple_interface_counters[i][j];
5987           vat_json_array_add_uint (counter_array, packets);
5988         }
5989     }
5990   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5991     {
5992       msg = vat_json_array_add (msg_array);
5993       vat_json_init_object (msg);
5994       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5995                                        (u8 *) counter_type_to_str (i, 1));
5996       vat_json_object_add_int (msg, "is_combined", 1);
5997       counter_array = vat_json_object_add (msg, "data");
5998       vat_json_init_array (counter_array);
5999       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6000         {
6001           c = vam->combined_interface_counters[i][j];
6002           counter = vat_json_array_add (counter_array);
6003           vat_json_init_object (counter);
6004           vat_json_object_add_uint (counter, "packets", c.packets);
6005           vat_json_object_add_uint (counter, "bytes", c.bytes);
6006         }
6007     }
6008
6009   /* ip4 fib counters */
6010   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6011   vat_json_init_array (msg_array);
6012   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6013     {
6014       msg = vat_json_array_add (msg_array);
6015       vat_json_init_object (msg);
6016       vat_json_object_add_uint (msg, "vrf_id",
6017                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6018       counter_array = vat_json_object_add (msg, "c");
6019       vat_json_init_array (counter_array);
6020       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6021         {
6022           counter = vat_json_array_add (counter_array);
6023           vat_json_init_object (counter);
6024           c4 = &vam->ip4_fib_counters[i][j];
6025           vat_json_object_add_ip4 (counter, "address", c4->address);
6026           vat_json_object_add_uint (counter, "address_length",
6027                                     c4->address_length);
6028           vat_json_object_add_uint (counter, "packets", c4->packets);
6029           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6030         }
6031     }
6032
6033   /* ip6 fib counters */
6034   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6035   vat_json_init_array (msg_array);
6036   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6037     {
6038       msg = vat_json_array_add (msg_array);
6039       vat_json_init_object (msg);
6040       vat_json_object_add_uint (msg, "vrf_id",
6041                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6042       counter_array = vat_json_object_add (msg, "c");
6043       vat_json_init_array (counter_array);
6044       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6045         {
6046           counter = vat_json_array_add (counter_array);
6047           vat_json_init_object (counter);
6048           c6 = &vam->ip6_fib_counters[i][j];
6049           vat_json_object_add_ip6 (counter, "address", c6->address);
6050           vat_json_object_add_uint (counter, "address_length",
6051                                     c6->address_length);
6052           vat_json_object_add_uint (counter, "packets", c6->packets);
6053           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6054         }
6055     }
6056
6057   /* ip4 nbr counters */
6058   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6059   vat_json_init_array (msg_array);
6060   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6061     {
6062       msg = vat_json_array_add (msg_array);
6063       vat_json_init_object (msg);
6064       vat_json_object_add_uint (msg, "sw_if_index", i);
6065       counter_array = vat_json_object_add (msg, "c");
6066       vat_json_init_array (counter_array);
6067       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6068         {
6069           counter = vat_json_array_add (counter_array);
6070           vat_json_init_object (counter);
6071           n4 = &vam->ip4_nbr_counters[i][j];
6072           vat_json_object_add_ip4 (counter, "address", n4->address);
6073           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6074           vat_json_object_add_uint (counter, "packets", n4->packets);
6075           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6076         }
6077     }
6078
6079   /* ip6 nbr counters */
6080   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6081   vat_json_init_array (msg_array);
6082   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6083     {
6084       msg = vat_json_array_add (msg_array);
6085       vat_json_init_object (msg);
6086       vat_json_object_add_uint (msg, "sw_if_index", i);
6087       counter_array = vat_json_object_add (msg, "c");
6088       vat_json_init_array (counter_array);
6089       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6090         {
6091           counter = vat_json_array_add (counter_array);
6092           vat_json_init_object (counter);
6093           n6 = &vam->ip6_nbr_counters[i][j];
6094           vat_json_object_add_ip6 (counter, "address", n6->address);
6095           vat_json_object_add_uint (counter, "packets", n6->packets);
6096           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6097         }
6098     }
6099
6100   vat_json_print (vam->ofp, &node);
6101   vat_json_free (&node);
6102
6103   return 0;
6104 }
6105
6106 /*
6107  * Pass CLI buffers directly in the CLI_INBAND API message,
6108  * instead of an additional shared memory area.
6109  */
6110 static int
6111 exec_inband (vat_main_t * vam)
6112 {
6113   vl_api_cli_inband_t *mp;
6114   unformat_input_t *i = vam->input;
6115   int ret;
6116
6117   if (vec_len (i->buffer) == 0)
6118     return -1;
6119
6120   if (vam->exec_mode == 0 && unformat (i, "mode"))
6121     {
6122       vam->exec_mode = 1;
6123       return 0;
6124     }
6125   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6126     {
6127       vam->exec_mode = 0;
6128       return 0;
6129     }
6130
6131   /*
6132    * In order for the CLI command to work, it
6133    * must be a vector ending in \n, not a C-string ending
6134    * in \n\0.
6135    */
6136   u32 len = vec_len (vam->input->buffer);
6137   M2 (CLI_INBAND, mp, len);
6138   clib_memcpy (mp->cmd, vam->input->buffer, len);
6139   mp->length = htonl (len);
6140
6141   S (mp);
6142   W (ret);
6143   /* json responses may or may not include a useful reply... */
6144   if (vec_len (vam->cmd_reply))
6145     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6146   return ret;
6147 }
6148
6149 int
6150 exec (vat_main_t * vam)
6151 {
6152   return exec_inband (vam);
6153 }
6154
6155 static int
6156 api_create_loopback (vat_main_t * vam)
6157 {
6158   unformat_input_t *i = vam->input;
6159   vl_api_create_loopback_t *mp;
6160   vl_api_create_loopback_instance_t *mp_lbi;
6161   u8 mac_address[6];
6162   u8 mac_set = 0;
6163   u8 is_specified = 0;
6164   u32 user_instance = 0;
6165   int ret;
6166
6167   memset (mac_address, 0, sizeof (mac_address));
6168
6169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170     {
6171       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6172         mac_set = 1;
6173       if (unformat (i, "instance %d", &user_instance))
6174         is_specified = 1;
6175       else
6176         break;
6177     }
6178
6179   if (is_specified)
6180     {
6181       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6182       mp_lbi->is_specified = is_specified;
6183       if (is_specified)
6184         mp_lbi->user_instance = htonl (user_instance);
6185       if (mac_set)
6186         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6187       S (mp_lbi);
6188     }
6189   else
6190     {
6191       /* Construct the API message */
6192       M (CREATE_LOOPBACK, mp);
6193       if (mac_set)
6194         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6195       S (mp);
6196     }
6197
6198   W (ret);
6199   return ret;
6200 }
6201
6202 static int
6203 api_delete_loopback (vat_main_t * vam)
6204 {
6205   unformat_input_t *i = vam->input;
6206   vl_api_delete_loopback_t *mp;
6207   u32 sw_if_index = ~0;
6208   int ret;
6209
6210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211     {
6212       if (unformat (i, "sw_if_index %d", &sw_if_index))
6213         ;
6214       else
6215         break;
6216     }
6217
6218   if (sw_if_index == ~0)
6219     {
6220       errmsg ("missing sw_if_index");
6221       return -99;
6222     }
6223
6224   /* Construct the API message */
6225   M (DELETE_LOOPBACK, mp);
6226   mp->sw_if_index = ntohl (sw_if_index);
6227
6228   S (mp);
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_want_stats (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_want_stats_t *mp;
6238   int enable = -1;
6239   int ret;
6240
6241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6242     {
6243       if (unformat (i, "enable"))
6244         enable = 1;
6245       else if (unformat (i, "disable"))
6246         enable = 0;
6247       else
6248         break;
6249     }
6250
6251   if (enable == -1)
6252     {
6253       errmsg ("missing enable|disable");
6254       return -99;
6255     }
6256
6257   M (WANT_STATS, mp);
6258   mp->enable_disable = enable;
6259
6260   S (mp);
6261   W (ret);
6262   return ret;
6263 }
6264
6265 static int
6266 api_want_interface_events (vat_main_t * vam)
6267 {
6268   unformat_input_t *i = vam->input;
6269   vl_api_want_interface_events_t *mp;
6270   int enable = -1;
6271   int ret;
6272
6273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6274     {
6275       if (unformat (i, "enable"))
6276         enable = 1;
6277       else if (unformat (i, "disable"))
6278         enable = 0;
6279       else
6280         break;
6281     }
6282
6283   if (enable == -1)
6284     {
6285       errmsg ("missing enable|disable");
6286       return -99;
6287     }
6288
6289   M (WANT_INTERFACE_EVENTS, mp);
6290   mp->enable_disable = enable;
6291
6292   vam->interface_event_display = enable;
6293
6294   S (mp);
6295   W (ret);
6296   return ret;
6297 }
6298
6299
6300 /* Note: non-static, called once to set up the initial intfc table */
6301 int
6302 api_sw_interface_dump (vat_main_t * vam)
6303 {
6304   vl_api_sw_interface_dump_t *mp;
6305   vl_api_control_ping_t *mp_ping;
6306   hash_pair_t *p;
6307   name_sort_t *nses = 0, *ns;
6308   sw_interface_subif_t *sub = NULL;
6309   int ret;
6310
6311   /* Toss the old name table */
6312   /* *INDENT-OFF* */
6313   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6314   ({
6315     vec_add2 (nses, ns, 1);
6316     ns->name = (u8 *)(p->key);
6317     ns->value = (u32) p->value[0];
6318   }));
6319   /* *INDENT-ON* */
6320
6321   hash_free (vam->sw_if_index_by_interface_name);
6322
6323   vec_foreach (ns, nses) vec_free (ns->name);
6324
6325   vec_free (nses);
6326
6327   vec_foreach (sub, vam->sw_if_subif_table)
6328   {
6329     vec_free (sub->interface_name);
6330   }
6331   vec_free (vam->sw_if_subif_table);
6332
6333   /* recreate the interface name hash table */
6334   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6335
6336   /*
6337    * Ask for all interface names. Otherwise, the epic catalog of
6338    * name filters becomes ridiculously long, and vat ends up needing
6339    * to be taught about new interface types.
6340    */
6341   M (SW_INTERFACE_DUMP, mp);
6342   S (mp);
6343
6344   /* Use a control ping for synchronization */
6345   MPING (CONTROL_PING, mp_ping);
6346   S (mp_ping);
6347
6348   W (ret);
6349   return ret;
6350 }
6351
6352 static int
6353 api_sw_interface_set_flags (vat_main_t * vam)
6354 {
6355   unformat_input_t *i = vam->input;
6356   vl_api_sw_interface_set_flags_t *mp;
6357   u32 sw_if_index;
6358   u8 sw_if_index_set = 0;
6359   u8 admin_up = 0;
6360   int ret;
6361
6362   /* Parse args required to build the message */
6363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6364     {
6365       if (unformat (i, "admin-up"))
6366         admin_up = 1;
6367       else if (unformat (i, "admin-down"))
6368         admin_up = 0;
6369       else
6370         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6371         sw_if_index_set = 1;
6372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6373         sw_if_index_set = 1;
6374       else
6375         break;
6376     }
6377
6378   if (sw_if_index_set == 0)
6379     {
6380       errmsg ("missing interface name or sw_if_index");
6381       return -99;
6382     }
6383
6384   /* Construct the API message */
6385   M (SW_INTERFACE_SET_FLAGS, mp);
6386   mp->sw_if_index = ntohl (sw_if_index);
6387   mp->admin_up_down = admin_up;
6388
6389   /* send it... */
6390   S (mp);
6391
6392   /* Wait for a reply, return the good/bad news... */
6393   W (ret);
6394   return ret;
6395 }
6396
6397 static int
6398 api_sw_interface_set_rx_mode (vat_main_t * vam)
6399 {
6400   unformat_input_t *i = vam->input;
6401   vl_api_sw_interface_set_rx_mode_t *mp;
6402   u32 sw_if_index;
6403   u8 sw_if_index_set = 0;
6404   int ret;
6405   u8 queue_id_valid = 0;
6406   u32 queue_id;
6407   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6408
6409   /* Parse args required to build the message */
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "queue %d", &queue_id))
6413         queue_id_valid = 1;
6414       else if (unformat (i, "polling"))
6415         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6416       else if (unformat (i, "interrupt"))
6417         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6418       else if (unformat (i, "adaptive"))
6419         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6420       else
6421         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6422         sw_if_index_set = 1;
6423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6424         sw_if_index_set = 1;
6425       else
6426         break;
6427     }
6428
6429   if (sw_if_index_set == 0)
6430     {
6431       errmsg ("missing interface name or sw_if_index");
6432       return -99;
6433     }
6434   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6435     {
6436       errmsg ("missing rx-mode");
6437       return -99;
6438     }
6439
6440   /* Construct the API message */
6441   M (SW_INTERFACE_SET_RX_MODE, mp);
6442   mp->sw_if_index = ntohl (sw_if_index);
6443   mp->mode = mode;
6444   mp->queue_id_valid = queue_id_valid;
6445   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6446
6447   /* send it... */
6448   S (mp);
6449
6450   /* Wait for a reply, return the good/bad news... */
6451   W (ret);
6452   return ret;
6453 }
6454
6455 static int
6456 api_sw_interface_clear_stats (vat_main_t * vam)
6457 {
6458   unformat_input_t *i = vam->input;
6459   vl_api_sw_interface_clear_stats_t *mp;
6460   u32 sw_if_index;
6461   u8 sw_if_index_set = 0;
6462   int ret;
6463
6464   /* Parse args required to build the message */
6465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6466     {
6467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6468         sw_if_index_set = 1;
6469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6470         sw_if_index_set = 1;
6471       else
6472         break;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_CLEAR_STATS, mp);
6477
6478   if (sw_if_index_set == 1)
6479     mp->sw_if_index = ntohl (sw_if_index);
6480   else
6481     mp->sw_if_index = ~0;
6482
6483   /* send it... */
6484   S (mp);
6485
6486   /* Wait for a reply, return the good/bad news... */
6487   W (ret);
6488   return ret;
6489 }
6490
6491 static int
6492 api_sw_interface_add_del_address (vat_main_t * vam)
6493 {
6494   unformat_input_t *i = vam->input;
6495   vl_api_sw_interface_add_del_address_t *mp;
6496   u32 sw_if_index;
6497   u8 sw_if_index_set = 0;
6498   u8 is_add = 1, del_all = 0;
6499   u32 address_length = 0;
6500   u8 v4_address_set = 0;
6501   u8 v6_address_set = 0;
6502   ip4_address_t v4address;
6503   ip6_address_t v6address;
6504   int ret;
6505
6506   /* Parse args required to build the message */
6507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6508     {
6509       if (unformat (i, "del-all"))
6510         del_all = 1;
6511       else if (unformat (i, "del"))
6512         is_add = 0;
6513       else
6514         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6515         sw_if_index_set = 1;
6516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6517         sw_if_index_set = 1;
6518       else if (unformat (i, "%U/%d",
6519                          unformat_ip4_address, &v4address, &address_length))
6520         v4_address_set = 1;
6521       else if (unformat (i, "%U/%d",
6522                          unformat_ip6_address, &v6address, &address_length))
6523         v6_address_set = 1;
6524       else
6525         break;
6526     }
6527
6528   if (sw_if_index_set == 0)
6529     {
6530       errmsg ("missing interface name or sw_if_index");
6531       return -99;
6532     }
6533   if (v4_address_set && v6_address_set)
6534     {
6535       errmsg ("both v4 and v6 addresses set");
6536       return -99;
6537     }
6538   if (!v4_address_set && !v6_address_set && !del_all)
6539     {
6540       errmsg ("no addresses set");
6541       return -99;
6542     }
6543
6544   /* Construct the API message */
6545   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6546
6547   mp->sw_if_index = ntohl (sw_if_index);
6548   mp->is_add = is_add;
6549   mp->del_all = del_all;
6550   if (v6_address_set)
6551     {
6552       mp->is_ipv6 = 1;
6553       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6554     }
6555   else
6556     {
6557       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6558     }
6559   mp->address_length = address_length;
6560
6561   /* send it... */
6562   S (mp);
6563
6564   /* Wait for a reply, return good/bad news  */
6565   W (ret);
6566   return ret;
6567 }
6568
6569 static int
6570 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6571 {
6572   unformat_input_t *i = vam->input;
6573   vl_api_sw_interface_set_mpls_enable_t *mp;
6574   u32 sw_if_index;
6575   u8 sw_if_index_set = 0;
6576   u8 enable = 1;
6577   int ret;
6578
6579   /* Parse args required to build the message */
6580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6581     {
6582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6585         sw_if_index_set = 1;
6586       else if (unformat (i, "disable"))
6587         enable = 0;
6588       else if (unformat (i, "dis"))
6589         enable = 0;
6590       else
6591         break;
6592     }
6593
6594   if (sw_if_index_set == 0)
6595     {
6596       errmsg ("missing interface name or sw_if_index");
6597       return -99;
6598     }
6599
6600   /* Construct the API message */
6601   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6602
6603   mp->sw_if_index = ntohl (sw_if_index);
6604   mp->enable = enable;
6605
6606   /* send it... */
6607   S (mp);
6608
6609   /* Wait for a reply... */
6610   W (ret);
6611   return ret;
6612 }
6613
6614 static int
6615 api_sw_interface_set_table (vat_main_t * vam)
6616 {
6617   unformat_input_t *i = vam->input;
6618   vl_api_sw_interface_set_table_t *mp;
6619   u32 sw_if_index, vrf_id = 0;
6620   u8 sw_if_index_set = 0;
6621   u8 is_ipv6 = 0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6628         sw_if_index_set = 1;
6629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6630         sw_if_index_set = 1;
6631       else if (unformat (i, "vrf %d", &vrf_id))
6632         ;
6633       else if (unformat (i, "ipv6"))
6634         is_ipv6 = 1;
6635       else
6636         break;
6637     }
6638
6639   if (sw_if_index_set == 0)
6640     {
6641       errmsg ("missing interface name or sw_if_index");
6642       return -99;
6643     }
6644
6645   /* Construct the API message */
6646   M (SW_INTERFACE_SET_TABLE, mp);
6647
6648   mp->sw_if_index = ntohl (sw_if_index);
6649   mp->is_ipv6 = is_ipv6;
6650   mp->vrf_id = ntohl (vrf_id);
6651
6652   /* send it... */
6653   S (mp);
6654
6655   /* Wait for a reply... */
6656   W (ret);
6657   return ret;
6658 }
6659
6660 static void vl_api_sw_interface_get_table_reply_t_handler
6661   (vl_api_sw_interface_get_table_reply_t * mp)
6662 {
6663   vat_main_t *vam = &vat_main;
6664
6665   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6666
6667   vam->retval = ntohl (mp->retval);
6668   vam->result_ready = 1;
6669
6670 }
6671
6672 static void vl_api_sw_interface_get_table_reply_t_handler_json
6673   (vl_api_sw_interface_get_table_reply_t * mp)
6674 {
6675   vat_main_t *vam = &vat_main;
6676   vat_json_node_t node;
6677
6678   vat_json_init_object (&node);
6679   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6680   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6681
6682   vat_json_print (vam->ofp, &node);
6683   vat_json_free (&node);
6684
6685   vam->retval = ntohl (mp->retval);
6686   vam->result_ready = 1;
6687 }
6688
6689 static int
6690 api_sw_interface_get_table (vat_main_t * vam)
6691 {
6692   unformat_input_t *i = vam->input;
6693   vl_api_sw_interface_get_table_t *mp;
6694   u32 sw_if_index;
6695   u8 sw_if_index_set = 0;
6696   u8 is_ipv6 = 0;
6697   int ret;
6698
6699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6700     {
6701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6702         sw_if_index_set = 1;
6703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6704         sw_if_index_set = 1;
6705       else if (unformat (i, "ipv6"))
6706         is_ipv6 = 1;
6707       else
6708         break;
6709     }
6710
6711   if (sw_if_index_set == 0)
6712     {
6713       errmsg ("missing interface name or sw_if_index");
6714       return -99;
6715     }
6716
6717   M (SW_INTERFACE_GET_TABLE, mp);
6718   mp->sw_if_index = htonl (sw_if_index);
6719   mp->is_ipv6 = is_ipv6;
6720
6721   S (mp);
6722   W (ret);
6723   return ret;
6724 }
6725
6726 static int
6727 api_sw_interface_set_vpath (vat_main_t * vam)
6728 {
6729   unformat_input_t *i = vam->input;
6730   vl_api_sw_interface_set_vpath_t *mp;
6731   u32 sw_if_index = 0;
6732   u8 sw_if_index_set = 0;
6733   u8 is_enable = 0;
6734   int ret;
6735
6736   /* Parse args required to build the message */
6737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6738     {
6739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6740         sw_if_index_set = 1;
6741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6742         sw_if_index_set = 1;
6743       else if (unformat (i, "enable"))
6744         is_enable = 1;
6745       else if (unformat (i, "disable"))
6746         is_enable = 0;
6747       else
6748         break;
6749     }
6750
6751   if (sw_if_index_set == 0)
6752     {
6753       errmsg ("missing interface name or sw_if_index");
6754       return -99;
6755     }
6756
6757   /* Construct the API message */
6758   M (SW_INTERFACE_SET_VPATH, mp);
6759
6760   mp->sw_if_index = ntohl (sw_if_index);
6761   mp->enable = is_enable;
6762
6763   /* send it... */
6764   S (mp);
6765
6766   /* Wait for a reply... */
6767   W (ret);
6768   return ret;
6769 }
6770
6771 static int
6772 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6773 {
6774   unformat_input_t *i = vam->input;
6775   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6776   u32 sw_if_index = 0;
6777   u8 sw_if_index_set = 0;
6778   u8 is_enable = 1;
6779   u8 is_ipv6 = 0;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6788         sw_if_index_set = 1;
6789       else if (unformat (i, "enable"))
6790         is_enable = 1;
6791       else if (unformat (i, "disable"))
6792         is_enable = 0;
6793       else if (unformat (i, "ip4"))
6794         is_ipv6 = 0;
6795       else if (unformat (i, "ip6"))
6796         is_ipv6 = 1;
6797       else
6798         break;
6799     }
6800
6801   if (sw_if_index_set == 0)
6802     {
6803       errmsg ("missing interface name or sw_if_index");
6804       return -99;
6805     }
6806
6807   /* Construct the API message */
6808   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811   mp->enable = is_enable;
6812   mp->is_ipv6 = is_ipv6;
6813
6814   /* send it... */
6815   S (mp);
6816
6817   /* Wait for a reply... */
6818   W (ret);
6819   return ret;
6820 }
6821
6822 static int
6823 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6824 {
6825   unformat_input_t *i = vam->input;
6826   vl_api_sw_interface_set_geneve_bypass_t *mp;
6827   u32 sw_if_index = 0;
6828   u8 sw_if_index_set = 0;
6829   u8 is_enable = 1;
6830   u8 is_ipv6 = 0;
6831   int ret;
6832
6833   /* Parse args required to build the message */
6834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6835     {
6836       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6837         sw_if_index_set = 1;
6838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6839         sw_if_index_set = 1;
6840       else if (unformat (i, "enable"))
6841         is_enable = 1;
6842       else if (unformat (i, "disable"))
6843         is_enable = 0;
6844       else if (unformat (i, "ip4"))
6845         is_ipv6 = 0;
6846       else if (unformat (i, "ip6"))
6847         is_ipv6 = 1;
6848       else
6849         break;
6850     }
6851
6852   if (sw_if_index_set == 0)
6853     {
6854       errmsg ("missing interface name or sw_if_index");
6855       return -99;
6856     }
6857
6858   /* Construct the API message */
6859   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6860
6861   mp->sw_if_index = ntohl (sw_if_index);
6862   mp->enable = is_enable;
6863   mp->is_ipv6 = is_ipv6;
6864
6865   /* send it... */
6866   S (mp);
6867
6868   /* Wait for a reply... */
6869   W (ret);
6870   return ret;
6871 }
6872
6873 static int
6874 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6875 {
6876   unformat_input_t *i = vam->input;
6877   vl_api_sw_interface_set_l2_xconnect_t *mp;
6878   u32 rx_sw_if_index;
6879   u8 rx_sw_if_index_set = 0;
6880   u32 tx_sw_if_index;
6881   u8 tx_sw_if_index_set = 0;
6882   u8 enable = 1;
6883   int ret;
6884
6885   /* Parse args required to build the message */
6886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6887     {
6888       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6889         rx_sw_if_index_set = 1;
6890       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6891         tx_sw_if_index_set = 1;
6892       else if (unformat (i, "rx"))
6893         {
6894           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6895             {
6896               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6897                             &rx_sw_if_index))
6898                 rx_sw_if_index_set = 1;
6899             }
6900           else
6901             break;
6902         }
6903       else if (unformat (i, "tx"))
6904         {
6905           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6906             {
6907               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6908                             &tx_sw_if_index))
6909                 tx_sw_if_index_set = 1;
6910             }
6911           else
6912             break;
6913         }
6914       else if (unformat (i, "enable"))
6915         enable = 1;
6916       else if (unformat (i, "disable"))
6917         enable = 0;
6918       else
6919         break;
6920     }
6921
6922   if (rx_sw_if_index_set == 0)
6923     {
6924       errmsg ("missing rx interface name or rx_sw_if_index");
6925       return -99;
6926     }
6927
6928   if (enable && (tx_sw_if_index_set == 0))
6929     {
6930       errmsg ("missing tx interface name or tx_sw_if_index");
6931       return -99;
6932     }
6933
6934   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6935
6936   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6937   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6938   mp->enable = enable;
6939
6940   S (mp);
6941   W (ret);
6942   return ret;
6943 }
6944
6945 static int
6946 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_sw_interface_set_l2_bridge_t *mp;
6950   u32 rx_sw_if_index;
6951   u8 rx_sw_if_index_set = 0;
6952   u32 bd_id;
6953   u8 bd_id_set = 0;
6954   u8 bvi = 0;
6955   u32 shg = 0;
6956   u8 enable = 1;
6957   int ret;
6958
6959   /* Parse args required to build the message */
6960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6961     {
6962       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6963         rx_sw_if_index_set = 1;
6964       else if (unformat (i, "bd_id %d", &bd_id))
6965         bd_id_set = 1;
6966       else
6967         if (unformat
6968             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6969         rx_sw_if_index_set = 1;
6970       else if (unformat (i, "shg %d", &shg))
6971         ;
6972       else if (unformat (i, "bvi"))
6973         bvi = 1;
6974       else if (unformat (i, "enable"))
6975         enable = 1;
6976       else if (unformat (i, "disable"))
6977         enable = 0;
6978       else
6979         break;
6980     }
6981
6982   if (rx_sw_if_index_set == 0)
6983     {
6984       errmsg ("missing rx interface name or sw_if_index");
6985       return -99;
6986     }
6987
6988   if (enable && (bd_id_set == 0))
6989     {
6990       errmsg ("missing bridge domain");
6991       return -99;
6992     }
6993
6994   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6995
6996   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6997   mp->bd_id = ntohl (bd_id);
6998   mp->shg = (u8) shg;
6999   mp->bvi = bvi;
7000   mp->enable = enable;
7001
7002   S (mp);
7003   W (ret);
7004   return ret;
7005 }
7006
7007 static int
7008 api_bridge_domain_dump (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_bridge_domain_dump_t *mp;
7012   vl_api_control_ping_t *mp_ping;
7013   u32 bd_id = ~0;
7014   int ret;
7015
7016   /* Parse args required to build the message */
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "bd_id %d", &bd_id))
7020         ;
7021       else
7022         break;
7023     }
7024
7025   M (BRIDGE_DOMAIN_DUMP, mp);
7026   mp->bd_id = ntohl (bd_id);
7027   S (mp);
7028
7029   /* Use a control ping for synchronization */
7030   MPING (CONTROL_PING, mp_ping);
7031   S (mp_ping);
7032
7033   W (ret);
7034   return ret;
7035 }
7036
7037 static int
7038 api_bridge_domain_add_del (vat_main_t * vam)
7039 {
7040   unformat_input_t *i = vam->input;
7041   vl_api_bridge_domain_add_del_t *mp;
7042   u32 bd_id = ~0;
7043   u8 is_add = 1;
7044   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7045   u8 *bd_tag = NULL;
7046   u32 mac_age = 0;
7047   int ret;
7048
7049   /* Parse args required to build the message */
7050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051     {
7052       if (unformat (i, "bd_id %d", &bd_id))
7053         ;
7054       else if (unformat (i, "flood %d", &flood))
7055         ;
7056       else if (unformat (i, "uu-flood %d", &uu_flood))
7057         ;
7058       else if (unformat (i, "forward %d", &forward))
7059         ;
7060       else if (unformat (i, "learn %d", &learn))
7061         ;
7062       else if (unformat (i, "arp-term %d", &arp_term))
7063         ;
7064       else if (unformat (i, "mac-age %d", &mac_age))
7065         ;
7066       else if (unformat (i, "bd-tag %s", &bd_tag))
7067         ;
7068       else if (unformat (i, "del"))
7069         {
7070           is_add = 0;
7071           flood = uu_flood = forward = learn = 0;
7072         }
7073       else
7074         break;
7075     }
7076
7077   if (bd_id == ~0)
7078     {
7079       errmsg ("missing bridge domain");
7080       ret = -99;
7081       goto done;
7082     }
7083
7084   if (mac_age > 255)
7085     {
7086       errmsg ("mac age must be less than 256 ");
7087       ret = -99;
7088       goto done;
7089     }
7090
7091   if ((bd_tag) && (vec_len (bd_tag) > 63))
7092     {
7093       errmsg ("bd-tag cannot be longer than 63");
7094       ret = -99;
7095       goto done;
7096     }
7097
7098   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7099
7100   mp->bd_id = ntohl (bd_id);
7101   mp->flood = flood;
7102   mp->uu_flood = uu_flood;
7103   mp->forward = forward;
7104   mp->learn = learn;
7105   mp->arp_term = arp_term;
7106   mp->is_add = is_add;
7107   mp->mac_age = (u8) mac_age;
7108   if (bd_tag)
7109     {
7110       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7111       mp->bd_tag[vec_len (bd_tag)] = 0;
7112     }
7113   S (mp);
7114   W (ret);
7115
7116 done:
7117   vec_free (bd_tag);
7118   return ret;
7119 }
7120
7121 static int
7122 api_l2fib_flush_bd (vat_main_t * vam)
7123 {
7124   unformat_input_t *i = vam->input;
7125   vl_api_l2fib_flush_bd_t *mp;
7126   u32 bd_id = ~0;
7127   int ret;
7128
7129   /* Parse args required to build the message */
7130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131     {
7132       if (unformat (i, "bd_id %d", &bd_id));
7133       else
7134         break;
7135     }
7136
7137   if (bd_id == ~0)
7138     {
7139       errmsg ("missing bridge domain");
7140       return -99;
7141     }
7142
7143   M (L2FIB_FLUSH_BD, mp);
7144
7145   mp->bd_id = htonl (bd_id);
7146
7147   S (mp);
7148   W (ret);
7149   return ret;
7150 }
7151
7152 static int
7153 api_l2fib_flush_int (vat_main_t * vam)
7154 {
7155   unformat_input_t *i = vam->input;
7156   vl_api_l2fib_flush_int_t *mp;
7157   u32 sw_if_index = ~0;
7158   int ret;
7159
7160   /* Parse args required to build the message */
7161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7162     {
7163       if (unformat (i, "sw_if_index %d", &sw_if_index));
7164       else
7165         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7166       else
7167         break;
7168     }
7169
7170   if (sw_if_index == ~0)
7171     {
7172       errmsg ("missing interface name or sw_if_index");
7173       return -99;
7174     }
7175
7176   M (L2FIB_FLUSH_INT, mp);
7177
7178   mp->sw_if_index = ntohl (sw_if_index);
7179
7180   S (mp);
7181   W (ret);
7182   return ret;
7183 }
7184
7185 static int
7186 api_l2fib_add_del (vat_main_t * vam)
7187 {
7188   unformat_input_t *i = vam->input;
7189   vl_api_l2fib_add_del_t *mp;
7190   f64 timeout;
7191   u8 mac[6] = { 0 };
7192   u8 mac_set = 0;
7193   u32 bd_id;
7194   u8 bd_id_set = 0;
7195   u32 sw_if_index = ~0;
7196   u8 sw_if_index_set = 0;
7197   u8 is_add = 1;
7198   u8 static_mac = 0;
7199   u8 filter_mac = 0;
7200   u8 bvi_mac = 0;
7201   int count = 1;
7202   f64 before = 0;
7203   int j;
7204
7205   /* Parse args required to build the message */
7206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7207     {
7208       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7209         mac_set = 1;
7210       else if (unformat (i, "bd_id %d", &bd_id))
7211         bd_id_set = 1;
7212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7213         sw_if_index_set = 1;
7214       else if (unformat (i, "sw_if"))
7215         {
7216           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7217             {
7218               if (unformat
7219                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7220                 sw_if_index_set = 1;
7221             }
7222           else
7223             break;
7224         }
7225       else if (unformat (i, "static"))
7226         static_mac = 1;
7227       else if (unformat (i, "filter"))
7228         {
7229           filter_mac = 1;
7230           static_mac = 1;
7231         }
7232       else if (unformat (i, "bvi"))
7233         {
7234           bvi_mac = 1;
7235           static_mac = 1;
7236         }
7237       else if (unformat (i, "del"))
7238         is_add = 0;
7239       else if (unformat (i, "count %d", &count))
7240         ;
7241       else
7242         break;
7243     }
7244
7245   if (mac_set == 0)
7246     {
7247       errmsg ("missing mac address");
7248       return -99;
7249     }
7250
7251   if (bd_id_set == 0)
7252     {
7253       errmsg ("missing bridge domain");
7254       return -99;
7255     }
7256
7257   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7258     {
7259       errmsg ("missing interface name or sw_if_index");
7260       return -99;
7261     }
7262
7263   if (count > 1)
7264     {
7265       /* Turn on async mode */
7266       vam->async_mode = 1;
7267       vam->async_errors = 0;
7268       before = vat_time_now (vam);
7269     }
7270
7271   for (j = 0; j < count; j++)
7272     {
7273       M (L2FIB_ADD_DEL, mp);
7274
7275       clib_memcpy (mp->mac, mac, 6);
7276       mp->bd_id = ntohl (bd_id);
7277       mp->is_add = is_add;
7278
7279       if (is_add)
7280         {
7281           mp->sw_if_index = ntohl (sw_if_index);
7282           mp->static_mac = static_mac;
7283           mp->filter_mac = filter_mac;
7284           mp->bvi_mac = bvi_mac;
7285         }
7286       increment_mac_address (mac);
7287       /* send it... */
7288       S (mp);
7289     }
7290
7291   if (count > 1)
7292     {
7293       vl_api_control_ping_t *mp_ping;
7294       f64 after;
7295
7296       /* Shut off async mode */
7297       vam->async_mode = 0;
7298
7299       MPING (CONTROL_PING, mp_ping);
7300       S (mp_ping);
7301
7302       timeout = vat_time_now (vam) + 1.0;
7303       while (vat_time_now (vam) < timeout)
7304         if (vam->result_ready == 1)
7305           goto out;
7306       vam->retval = -99;
7307
7308     out:
7309       if (vam->retval == -99)
7310         errmsg ("timeout");
7311
7312       if (vam->async_errors > 0)
7313         {
7314           errmsg ("%d asynchronous errors", vam->async_errors);
7315           vam->retval = -98;
7316         }
7317       vam->async_errors = 0;
7318       after = vat_time_now (vam);
7319
7320       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7321              count, after - before, count / (after - before));
7322     }
7323   else
7324     {
7325       int ret;
7326
7327       /* Wait for a reply... */
7328       W (ret);
7329       return ret;
7330     }
7331   /* Return the good/bad news */
7332   return (vam->retval);
7333 }
7334
7335 static int
7336 api_bridge_domain_set_mac_age (vat_main_t * vam)
7337 {
7338   unformat_input_t *i = vam->input;
7339   vl_api_bridge_domain_set_mac_age_t *mp;
7340   u32 bd_id = ~0;
7341   u32 mac_age = 0;
7342   int ret;
7343
7344   /* Parse args required to build the message */
7345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7346     {
7347       if (unformat (i, "bd_id %d", &bd_id));
7348       else if (unformat (i, "mac-age %d", &mac_age));
7349       else
7350         break;
7351     }
7352
7353   if (bd_id == ~0)
7354     {
7355       errmsg ("missing bridge domain");
7356       return -99;
7357     }
7358
7359   if (mac_age > 255)
7360     {
7361       errmsg ("mac age must be less than 256 ");
7362       return -99;
7363     }
7364
7365   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7366
7367   mp->bd_id = htonl (bd_id);
7368   mp->mac_age = (u8) mac_age;
7369
7370   S (mp);
7371   W (ret);
7372   return ret;
7373 }
7374
7375 static int
7376 api_l2_flags (vat_main_t * vam)
7377 {
7378   unformat_input_t *i = vam->input;
7379   vl_api_l2_flags_t *mp;
7380   u32 sw_if_index;
7381   u32 flags = 0;
7382   u8 sw_if_index_set = 0;
7383   u8 is_set = 0;
7384   int ret;
7385
7386   /* Parse args required to build the message */
7387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7388     {
7389       if (unformat (i, "sw_if_index %d", &sw_if_index))
7390         sw_if_index_set = 1;
7391       else if (unformat (i, "sw_if"))
7392         {
7393           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7394             {
7395               if (unformat
7396                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7397                 sw_if_index_set = 1;
7398             }
7399           else
7400             break;
7401         }
7402       else if (unformat (i, "learn"))
7403         flags |= L2_LEARN;
7404       else if (unformat (i, "forward"))
7405         flags |= L2_FWD;
7406       else if (unformat (i, "flood"))
7407         flags |= L2_FLOOD;
7408       else if (unformat (i, "uu-flood"))
7409         flags |= L2_UU_FLOOD;
7410       else if (unformat (i, "arp-term"))
7411         flags |= L2_ARP_TERM;
7412       else if (unformat (i, "off"))
7413         is_set = 0;
7414       else if (unformat (i, "disable"))
7415         is_set = 0;
7416       else
7417         break;
7418     }
7419
7420   if (sw_if_index_set == 0)
7421     {
7422       errmsg ("missing interface name or sw_if_index");
7423       return -99;
7424     }
7425
7426   M (L2_FLAGS, mp);
7427
7428   mp->sw_if_index = ntohl (sw_if_index);
7429   mp->feature_bitmap = ntohl (flags);
7430   mp->is_set = is_set;
7431
7432   S (mp);
7433   W (ret);
7434   return ret;
7435 }
7436
7437 static int
7438 api_bridge_flags (vat_main_t * vam)
7439 {
7440   unformat_input_t *i = vam->input;
7441   vl_api_bridge_flags_t *mp;
7442   u32 bd_id;
7443   u8 bd_id_set = 0;
7444   u8 is_set = 1;
7445   u32 flags = 0;
7446   int ret;
7447
7448   /* Parse args required to build the message */
7449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (i, "bd_id %d", &bd_id))
7452         bd_id_set = 1;
7453       else if (unformat (i, "learn"))
7454         flags |= L2_LEARN;
7455       else if (unformat (i, "forward"))
7456         flags |= L2_FWD;
7457       else if (unformat (i, "flood"))
7458         flags |= L2_FLOOD;
7459       else if (unformat (i, "uu-flood"))
7460         flags |= L2_UU_FLOOD;
7461       else if (unformat (i, "arp-term"))
7462         flags |= L2_ARP_TERM;
7463       else if (unformat (i, "off"))
7464         is_set = 0;
7465       else if (unformat (i, "disable"))
7466         is_set = 0;
7467       else
7468         break;
7469     }
7470
7471   if (bd_id_set == 0)
7472     {
7473       errmsg ("missing bridge domain");
7474       return -99;
7475     }
7476
7477   M (BRIDGE_FLAGS, mp);
7478
7479   mp->bd_id = ntohl (bd_id);
7480   mp->feature_bitmap = ntohl (flags);
7481   mp->is_set = is_set;
7482
7483   S (mp);
7484   W (ret);
7485   return ret;
7486 }
7487
7488 static int
7489 api_bd_ip_mac_add_del (vat_main_t * vam)
7490 {
7491   unformat_input_t *i = vam->input;
7492   vl_api_bd_ip_mac_add_del_t *mp;
7493   u32 bd_id;
7494   u8 is_ipv6 = 0;
7495   u8 is_add = 1;
7496   u8 bd_id_set = 0;
7497   u8 ip_set = 0;
7498   u8 mac_set = 0;
7499   ip4_address_t v4addr;
7500   ip6_address_t v6addr;
7501   u8 macaddr[6];
7502   int ret;
7503
7504
7505   /* Parse args required to build the message */
7506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7507     {
7508       if (unformat (i, "bd_id %d", &bd_id))
7509         {
7510           bd_id_set++;
7511         }
7512       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7513         {
7514           ip_set++;
7515         }
7516       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7517         {
7518           ip_set++;
7519           is_ipv6++;
7520         }
7521       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7522         {
7523           mac_set++;
7524         }
7525       else if (unformat (i, "del"))
7526         is_add = 0;
7527       else
7528         break;
7529     }
7530
7531   if (bd_id_set == 0)
7532     {
7533       errmsg ("missing bridge domain");
7534       return -99;
7535     }
7536   else if (ip_set == 0)
7537     {
7538       errmsg ("missing IP address");
7539       return -99;
7540     }
7541   else if (mac_set == 0)
7542     {
7543       errmsg ("missing MAC address");
7544       return -99;
7545     }
7546
7547   M (BD_IP_MAC_ADD_DEL, mp);
7548
7549   mp->bd_id = ntohl (bd_id);
7550   mp->is_ipv6 = is_ipv6;
7551   mp->is_add = is_add;
7552   if (is_ipv6)
7553     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7554   else
7555     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7556   clib_memcpy (mp->mac_address, macaddr, 6);
7557   S (mp);
7558   W (ret);
7559   return ret;
7560 }
7561
7562 static int
7563 api_tap_connect (vat_main_t * vam)
7564 {
7565   unformat_input_t *i = vam->input;
7566   vl_api_tap_connect_t *mp;
7567   u8 mac_address[6];
7568   u8 random_mac = 1;
7569   u8 name_set = 0;
7570   u8 *tap_name;
7571   u8 *tag = 0;
7572   ip4_address_t ip4_address;
7573   u32 ip4_mask_width;
7574   int ip4_address_set = 0;
7575   ip6_address_t ip6_address;
7576   u32 ip6_mask_width;
7577   int ip6_address_set = 0;
7578   int ret;
7579
7580   memset (mac_address, 0, sizeof (mac_address));
7581
7582   /* Parse args required to build the message */
7583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7584     {
7585       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7586         {
7587           random_mac = 0;
7588         }
7589       else if (unformat (i, "random-mac"))
7590         random_mac = 1;
7591       else if (unformat (i, "tapname %s", &tap_name))
7592         name_set = 1;
7593       else if (unformat (i, "tag %s", &tag))
7594         ;
7595       else if (unformat (i, "address %U/%d",
7596                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7597         ip4_address_set = 1;
7598       else if (unformat (i, "address %U/%d",
7599                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7600         ip6_address_set = 1;
7601       else
7602         break;
7603     }
7604
7605   if (name_set == 0)
7606     {
7607       errmsg ("missing tap name");
7608       return -99;
7609     }
7610   if (vec_len (tap_name) > 63)
7611     {
7612       errmsg ("tap name too long");
7613       return -99;
7614     }
7615   vec_add1 (tap_name, 0);
7616
7617   if (vec_len (tag) > 63)
7618     {
7619       errmsg ("tag too long");
7620       return -99;
7621     }
7622
7623   /* Construct the API message */
7624   M (TAP_CONNECT, mp);
7625
7626   mp->use_random_mac = random_mac;
7627   clib_memcpy (mp->mac_address, mac_address, 6);
7628   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7629   if (tag)
7630     clib_memcpy (mp->tag, tag, vec_len (tag));
7631
7632   if (ip4_address_set)
7633     {
7634       mp->ip4_address_set = 1;
7635       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7636       mp->ip4_mask_width = ip4_mask_width;
7637     }
7638   if (ip6_address_set)
7639     {
7640       mp->ip6_address_set = 1;
7641       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7642       mp->ip6_mask_width = ip6_mask_width;
7643     }
7644
7645   vec_free (tap_name);
7646   vec_free (tag);
7647
7648   /* send it... */
7649   S (mp);
7650
7651   /* Wait for a reply... */
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_tap_modify (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_tap_modify_t *mp;
7661   u8 mac_address[6];
7662   u8 random_mac = 1;
7663   u8 name_set = 0;
7664   u8 *tap_name;
7665   u32 sw_if_index = ~0;
7666   u8 sw_if_index_set = 0;
7667   int ret;
7668
7669   memset (mac_address, 0, sizeof (mac_address));
7670
7671   /* Parse args required to build the message */
7672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7673     {
7674       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7675         sw_if_index_set = 1;
7676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7677         sw_if_index_set = 1;
7678       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7679         {
7680           random_mac = 0;
7681         }
7682       else if (unformat (i, "random-mac"))
7683         random_mac = 1;
7684       else if (unformat (i, "tapname %s", &tap_name))
7685         name_set = 1;
7686       else
7687         break;
7688     }
7689
7690   if (sw_if_index_set == 0)
7691     {
7692       errmsg ("missing vpp interface name");
7693       return -99;
7694     }
7695   if (name_set == 0)
7696     {
7697       errmsg ("missing tap name");
7698       return -99;
7699     }
7700   if (vec_len (tap_name) > 63)
7701     {
7702       errmsg ("tap name too long");
7703     }
7704   vec_add1 (tap_name, 0);
7705
7706   /* Construct the API message */
7707   M (TAP_MODIFY, mp);
7708
7709   mp->use_random_mac = random_mac;
7710   mp->sw_if_index = ntohl (sw_if_index);
7711   clib_memcpy (mp->mac_address, mac_address, 6);
7712   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7713   vec_free (tap_name);
7714
7715   /* send it... */
7716   S (mp);
7717
7718   /* Wait for a reply... */
7719   W (ret);
7720   return ret;
7721 }
7722
7723 static int
7724 api_tap_delete (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_tap_delete_t *mp;
7728   u32 sw_if_index = ~0;
7729   u8 sw_if_index_set = 0;
7730   int ret;
7731
7732   /* Parse args required to build the message */
7733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7734     {
7735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7736         sw_if_index_set = 1;
7737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7738         sw_if_index_set = 1;
7739       else
7740         break;
7741     }
7742
7743   if (sw_if_index_set == 0)
7744     {
7745       errmsg ("missing vpp interface name");
7746       return -99;
7747     }
7748
7749   /* Construct the API message */
7750   M (TAP_DELETE, mp);
7751
7752   mp->sw_if_index = ntohl (sw_if_index);
7753
7754   /* send it... */
7755   S (mp);
7756
7757   /* Wait for a reply... */
7758   W (ret);
7759   return ret;
7760 }
7761
7762 static int
7763 api_tap_create_v2 (vat_main_t * vam)
7764 {
7765   unformat_input_t *i = vam->input;
7766   vl_api_tap_create_v2_t *mp;
7767   u8 mac_address[6];
7768   u8 random_mac = 1;
7769   u32 id = ~0;
7770   u8 *host_if_name = 0;
7771   u8 *host_ns = 0;
7772   u8 host_mac_addr[6];
7773   u8 host_mac_addr_set = 0;
7774   u8 *host_bridge = 0;
7775   ip4_address_t host_ip4_addr;
7776   u32 host_ip4_prefix_len = 0;
7777   ip6_address_t host_ip6_addr;
7778   u32 host_ip6_prefix_len = 0;
7779   int ret;
7780   int rx_ring_sz = 0, tx_ring_sz = 0;
7781
7782   memset (mac_address, 0, sizeof (mac_address));
7783
7784   /* Parse args required to build the message */
7785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7786     {
7787       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7788         {
7789           random_mac = 0;
7790         }
7791       else if (unformat (i, "id %s", &id))
7792         ;
7793       else if (unformat (i, "host-if-name %s", &host_if_name))
7794         ;
7795       else if (unformat (i, "host-ns %s", &host_ns))
7796         ;
7797       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7798                          host_mac_addr))
7799         host_mac_addr_set = 1;
7800       else if (unformat (i, "host-bridge %s", &host_bridge))
7801         ;
7802       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7803                          &host_ip4_addr, &host_ip4_prefix_len))
7804         ;
7805       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7806                          &host_ip6_addr, &host_ip6_prefix_len))
7807         ;
7808       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7809         ;
7810       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7811         ;
7812       else
7813         break;
7814     }
7815
7816   if (vec_len (host_if_name) > 63)
7817     {
7818       errmsg ("tap name too long. ");
7819       return -99;
7820     }
7821   if (vec_len (host_ns) > 63)
7822     {
7823       errmsg ("host name space too long. ");
7824       return -99;
7825     }
7826   if (vec_len (host_bridge) > 63)
7827     {
7828       errmsg ("host bridge name too long. ");
7829       return -99;
7830     }
7831   if (host_ip4_prefix_len > 32)
7832     {
7833       errmsg ("host ip4 prefix length not valid. ");
7834       return -99;
7835     }
7836   if (host_ip6_prefix_len > 128)
7837     {
7838       errmsg ("host ip6 prefix length not valid. ");
7839       return -99;
7840     }
7841   if (!is_pow2 (rx_ring_sz))
7842     {
7843       errmsg ("rx ring size must be power of 2. ");
7844       return -99;
7845     }
7846   if (rx_ring_sz > 32768)
7847     {
7848       errmsg ("rx ring size must be 32768 or lower. ");
7849       return -99;
7850     }
7851   if (!is_pow2 (tx_ring_sz))
7852     {
7853       errmsg ("tx ring size must be power of 2. ");
7854       return -99;
7855     }
7856   if (tx_ring_sz > 32768)
7857     {
7858       errmsg ("tx ring size must be 32768 or lower. ");
7859       return -99;
7860     }
7861
7862   /* Construct the API message */
7863   M (TAP_CREATE_V2, mp);
7864
7865   mp->use_random_mac = random_mac;
7866
7867   mp->id = id;
7868   mp->host_namespace_set = host_ns != 0;
7869   mp->host_bridge_set = host_bridge != 0;
7870   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7871   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7872   mp->rx_ring_sz = rx_ring_sz;
7873   mp->tx_ring_sz = tx_ring_sz;
7874
7875   if (random_mac)
7876     clib_memcpy (mp->mac_address, mac_address, 6);
7877   if (host_mac_addr_set)
7878     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7879   if (host_if_name)
7880     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7881   if (host_ns)
7882     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7883   if (host_bridge)
7884     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7885   if (host_ip4_prefix_len)
7886     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7887   if (host_ip4_prefix_len)
7888     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7889
7890
7891   vec_free (host_ns);
7892   vec_free (host_if_name);
7893   vec_free (host_bridge);
7894
7895   /* send it... */
7896   S (mp);
7897
7898   /* Wait for a reply... */
7899   W (ret);
7900   return ret;
7901 }
7902
7903 static int
7904 api_tap_delete_v2 (vat_main_t * vam)
7905 {
7906   unformat_input_t *i = vam->input;
7907   vl_api_tap_delete_v2_t *mp;
7908   u32 sw_if_index = ~0;
7909   u8 sw_if_index_set = 0;
7910   int ret;
7911
7912   /* Parse args required to build the message */
7913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7916         sw_if_index_set = 1;
7917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7918         sw_if_index_set = 1;
7919       else
7920         break;
7921     }
7922
7923   if (sw_if_index_set == 0)
7924     {
7925       errmsg ("missing vpp interface name. ");
7926       return -99;
7927     }
7928
7929   /* Construct the API message */
7930   M (TAP_DELETE_V2, mp);
7931
7932   mp->sw_if_index = ntohl (sw_if_index);
7933
7934   /* send it... */
7935   S (mp);
7936
7937   /* Wait for a reply... */
7938   W (ret);
7939   return ret;
7940 }
7941
7942 static int
7943 api_ip_table_add_del (vat_main_t * vam)
7944 {
7945   unformat_input_t *i = vam->input;
7946   vl_api_ip_table_add_del_t *mp;
7947   u32 table_id = ~0;
7948   u8 is_ipv6 = 0;
7949   u8 is_add = 1;
7950   int ret = 0;
7951
7952   /* Parse args required to build the message */
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "ipv6"))
7956         is_ipv6 = 1;
7957       else if (unformat (i, "del"))
7958         is_add = 0;
7959       else if (unformat (i, "add"))
7960         is_add = 1;
7961       else if (unformat (i, "table %d", &table_id))
7962         ;
7963       else
7964         {
7965           clib_warning ("parse error '%U'", format_unformat_error, i);
7966           return -99;
7967         }
7968     }
7969
7970   if (~0 == table_id)
7971     {
7972       errmsg ("missing table-ID");
7973       return -99;
7974     }
7975
7976   /* Construct the API message */
7977   M (IP_TABLE_ADD_DEL, mp);
7978
7979   mp->table_id = ntohl (table_id);
7980   mp->is_ipv6 = is_ipv6;
7981   mp->is_add = is_add;
7982
7983   /* send it... */
7984   S (mp);
7985
7986   /* Wait for a reply... */
7987   W (ret);
7988
7989   return ret;
7990 }
7991
7992 static int
7993 api_ip_add_del_route (vat_main_t * vam)
7994 {
7995   unformat_input_t *i = vam->input;
7996   vl_api_ip_add_del_route_t *mp;
7997   u32 sw_if_index = ~0, vrf_id = 0;
7998   u8 is_ipv6 = 0;
7999   u8 is_local = 0, is_drop = 0;
8000   u8 is_unreach = 0, is_prohibit = 0;
8001   u8 is_add = 1;
8002   u32 next_hop_weight = 1;
8003   u8 is_multipath = 0;
8004   u8 address_set = 0;
8005   u8 address_length_set = 0;
8006   u32 next_hop_table_id = 0;
8007   u32 resolve_attempts = 0;
8008   u32 dst_address_length = 0;
8009   u8 next_hop_set = 0;
8010   ip4_address_t v4_dst_address, v4_next_hop_address;
8011   ip6_address_t v6_dst_address, v6_next_hop_address;
8012   int count = 1;
8013   int j;
8014   f64 before = 0;
8015   u32 random_add_del = 0;
8016   u32 *random_vector = 0;
8017   uword *random_hash;
8018   u32 random_seed = 0xdeaddabe;
8019   u32 classify_table_index = ~0;
8020   u8 is_classify = 0;
8021   u8 resolve_host = 0, resolve_attached = 0;
8022   mpls_label_t *next_hop_out_label_stack = NULL;
8023   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8024   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8025
8026   /* Parse args required to build the message */
8027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8028     {
8029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8030         ;
8031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8032         ;
8033       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8034         {
8035           address_set = 1;
8036           is_ipv6 = 0;
8037         }
8038       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8039         {
8040           address_set = 1;
8041           is_ipv6 = 1;
8042         }
8043       else if (unformat (i, "/%d", &dst_address_length))
8044         {
8045           address_length_set = 1;
8046         }
8047
8048       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8049                                          &v4_next_hop_address))
8050         {
8051           next_hop_set = 1;
8052         }
8053       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8054                                          &v6_next_hop_address))
8055         {
8056           next_hop_set = 1;
8057         }
8058       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8059         ;
8060       else if (unformat (i, "weight %d", &next_hop_weight))
8061         ;
8062       else if (unformat (i, "drop"))
8063         {
8064           is_drop = 1;
8065         }
8066       else if (unformat (i, "null-send-unreach"))
8067         {
8068           is_unreach = 1;
8069         }
8070       else if (unformat (i, "null-send-prohibit"))
8071         {
8072           is_prohibit = 1;
8073         }
8074       else if (unformat (i, "local"))
8075         {
8076           is_local = 1;
8077         }
8078       else if (unformat (i, "classify %d", &classify_table_index))
8079         {
8080           is_classify = 1;
8081         }
8082       else if (unformat (i, "del"))
8083         is_add = 0;
8084       else if (unformat (i, "add"))
8085         is_add = 1;
8086       else if (unformat (i, "resolve-via-host"))
8087         resolve_host = 1;
8088       else if (unformat (i, "resolve-via-attached"))
8089         resolve_attached = 1;
8090       else if (unformat (i, "multipath"))
8091         is_multipath = 1;
8092       else if (unformat (i, "vrf %d", &vrf_id))
8093         ;
8094       else if (unformat (i, "count %d", &count))
8095         ;
8096       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8097         ;
8098       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8099         ;
8100       else if (unformat (i, "out-label %d", &next_hop_out_label))
8101         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8102       else if (unformat (i, "via-label %d", &next_hop_via_label))
8103         ;
8104       else if (unformat (i, "random"))
8105         random_add_del = 1;
8106       else if (unformat (i, "seed %d", &random_seed))
8107         ;
8108       else
8109         {
8110           clib_warning ("parse error '%U'", format_unformat_error, i);
8111           return -99;
8112         }
8113     }
8114
8115   if (!next_hop_set && !is_drop && !is_local &&
8116       !is_classify && !is_unreach && !is_prohibit &&
8117       MPLS_LABEL_INVALID == next_hop_via_label)
8118     {
8119       errmsg
8120         ("next hop / local / drop / unreach / prohibit / classify not set");
8121       return -99;
8122     }
8123
8124   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8125     {
8126       errmsg ("next hop and next-hop via label set");
8127       return -99;
8128     }
8129   if (address_set == 0)
8130     {
8131       errmsg ("missing addresses");
8132       return -99;
8133     }
8134
8135   if (address_length_set == 0)
8136     {
8137       errmsg ("missing address length");
8138       return -99;
8139     }
8140
8141   /* Generate a pile of unique, random routes */
8142   if (random_add_del)
8143     {
8144       u32 this_random_address;
8145       random_hash = hash_create (count, sizeof (uword));
8146
8147       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8148       for (j = 0; j <= count; j++)
8149         {
8150           do
8151             {
8152               this_random_address = random_u32 (&random_seed);
8153               this_random_address =
8154                 clib_host_to_net_u32 (this_random_address);
8155             }
8156           while (hash_get (random_hash, this_random_address));
8157           vec_add1 (random_vector, this_random_address);
8158           hash_set (random_hash, this_random_address, 1);
8159         }
8160       hash_free (random_hash);
8161       v4_dst_address.as_u32 = random_vector[0];
8162     }
8163
8164   if (count > 1)
8165     {
8166       /* Turn on async mode */
8167       vam->async_mode = 1;
8168       vam->async_errors = 0;
8169       before = vat_time_now (vam);
8170     }
8171
8172   for (j = 0; j < count; j++)
8173     {
8174       /* Construct the API message */
8175       M2 (IP_ADD_DEL_ROUTE, mp,
8176           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8177
8178       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8179       mp->table_id = ntohl (vrf_id);
8180
8181       mp->is_add = is_add;
8182       mp->is_drop = is_drop;
8183       mp->is_unreach = is_unreach;
8184       mp->is_prohibit = is_prohibit;
8185       mp->is_ipv6 = is_ipv6;
8186       mp->is_local = is_local;
8187       mp->is_classify = is_classify;
8188       mp->is_multipath = is_multipath;
8189       mp->is_resolve_host = resolve_host;
8190       mp->is_resolve_attached = resolve_attached;
8191       mp->next_hop_weight = next_hop_weight;
8192       mp->dst_address_length = dst_address_length;
8193       mp->next_hop_table_id = ntohl (next_hop_table_id);
8194       mp->classify_table_index = ntohl (classify_table_index);
8195       mp->next_hop_via_label = ntohl (next_hop_via_label);
8196       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8197       if (0 != mp->next_hop_n_out_labels)
8198         {
8199           memcpy (mp->next_hop_out_label_stack,
8200                   next_hop_out_label_stack,
8201                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8202           vec_free (next_hop_out_label_stack);
8203         }
8204
8205       if (is_ipv6)
8206         {
8207           clib_memcpy (mp->dst_address, &v6_dst_address,
8208                        sizeof (v6_dst_address));
8209           if (next_hop_set)
8210             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8211                          sizeof (v6_next_hop_address));
8212           increment_v6_address (&v6_dst_address);
8213         }
8214       else
8215         {
8216           clib_memcpy (mp->dst_address, &v4_dst_address,
8217                        sizeof (v4_dst_address));
8218           if (next_hop_set)
8219             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8220                          sizeof (v4_next_hop_address));
8221           if (random_add_del)
8222             v4_dst_address.as_u32 = random_vector[j + 1];
8223           else
8224             increment_v4_address (&v4_dst_address);
8225         }
8226       /* send it... */
8227       S (mp);
8228       /* If we receive SIGTERM, stop now... */
8229       if (vam->do_exit)
8230         break;
8231     }
8232
8233   /* When testing multiple add/del ops, use a control-ping to sync */
8234   if (count > 1)
8235     {
8236       vl_api_control_ping_t *mp_ping;
8237       f64 after;
8238       f64 timeout;
8239
8240       /* Shut off async mode */
8241       vam->async_mode = 0;
8242
8243       MPING (CONTROL_PING, mp_ping);
8244       S (mp_ping);
8245
8246       timeout = vat_time_now (vam) + 1.0;
8247       while (vat_time_now (vam) < timeout)
8248         if (vam->result_ready == 1)
8249           goto out;
8250       vam->retval = -99;
8251
8252     out:
8253       if (vam->retval == -99)
8254         errmsg ("timeout");
8255
8256       if (vam->async_errors > 0)
8257         {
8258           errmsg ("%d asynchronous errors", vam->async_errors);
8259           vam->retval = -98;
8260         }
8261       vam->async_errors = 0;
8262       after = vat_time_now (vam);
8263
8264       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8265       if (j > 0)
8266         count = j;
8267
8268       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8269              count, after - before, count / (after - before));
8270     }
8271   else
8272     {
8273       int ret;
8274
8275       /* Wait for a reply... */
8276       W (ret);
8277       return ret;
8278     }
8279
8280   /* Return the good/bad news */
8281   return (vam->retval);
8282 }
8283
8284 static int
8285 api_ip_mroute_add_del (vat_main_t * vam)
8286 {
8287   unformat_input_t *i = vam->input;
8288   vl_api_ip_mroute_add_del_t *mp;
8289   u32 sw_if_index = ~0, vrf_id = 0;
8290   u8 is_ipv6 = 0;
8291   u8 is_local = 0;
8292   u8 is_add = 1;
8293   u8 address_set = 0;
8294   u32 grp_address_length = 0;
8295   ip4_address_t v4_grp_address, v4_src_address;
8296   ip6_address_t v6_grp_address, v6_src_address;
8297   mfib_itf_flags_t iflags = 0;
8298   mfib_entry_flags_t eflags = 0;
8299   int ret;
8300
8301   /* Parse args required to build the message */
8302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8303     {
8304       if (unformat (i, "sw_if_index %d", &sw_if_index))
8305         ;
8306       else if (unformat (i, "%U %U",
8307                          unformat_ip4_address, &v4_src_address,
8308                          unformat_ip4_address, &v4_grp_address))
8309         {
8310           grp_address_length = 64;
8311           address_set = 1;
8312           is_ipv6 = 0;
8313         }
8314       else if (unformat (i, "%U %U",
8315                          unformat_ip6_address, &v6_src_address,
8316                          unformat_ip6_address, &v6_grp_address))
8317         {
8318           grp_address_length = 256;
8319           address_set = 1;
8320           is_ipv6 = 1;
8321         }
8322       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8323         {
8324           memset (&v4_src_address, 0, sizeof (v4_src_address));
8325           grp_address_length = 32;
8326           address_set = 1;
8327           is_ipv6 = 0;
8328         }
8329       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8330         {
8331           memset (&v6_src_address, 0, sizeof (v6_src_address));
8332           grp_address_length = 128;
8333           address_set = 1;
8334           is_ipv6 = 1;
8335         }
8336       else if (unformat (i, "/%d", &grp_address_length))
8337         ;
8338       else if (unformat (i, "local"))
8339         {
8340           is_local = 1;
8341         }
8342       else if (unformat (i, "del"))
8343         is_add = 0;
8344       else if (unformat (i, "add"))
8345         is_add = 1;
8346       else if (unformat (i, "vrf %d", &vrf_id))
8347         ;
8348       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8349         ;
8350       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8351         ;
8352       else
8353         {
8354           clib_warning ("parse error '%U'", format_unformat_error, i);
8355           return -99;
8356         }
8357     }
8358
8359   if (address_set == 0)
8360     {
8361       errmsg ("missing addresses\n");
8362       return -99;
8363     }
8364
8365   /* Construct the API message */
8366   M (IP_MROUTE_ADD_DEL, mp);
8367
8368   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8369   mp->table_id = ntohl (vrf_id);
8370
8371   mp->is_add = is_add;
8372   mp->is_ipv6 = is_ipv6;
8373   mp->is_local = is_local;
8374   mp->itf_flags = ntohl (iflags);
8375   mp->entry_flags = ntohl (eflags);
8376   mp->grp_address_length = grp_address_length;
8377   mp->grp_address_length = ntohs (mp->grp_address_length);
8378
8379   if (is_ipv6)
8380     {
8381       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8382       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8383     }
8384   else
8385     {
8386       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8387       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8388
8389     }
8390
8391   /* send it... */
8392   S (mp);
8393   /* Wait for a reply... */
8394   W (ret);
8395   return ret;
8396 }
8397
8398 static int
8399 api_mpls_table_add_del (vat_main_t * vam)
8400 {
8401   unformat_input_t *i = vam->input;
8402   vl_api_mpls_table_add_del_t *mp;
8403   u32 table_id = ~0;
8404   u8 is_add = 1;
8405   int ret = 0;
8406
8407   /* Parse args required to build the message */
8408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8409     {
8410       if (unformat (i, "table %d", &table_id))
8411         ;
8412       else if (unformat (i, "del"))
8413         is_add = 0;
8414       else if (unformat (i, "add"))
8415         is_add = 1;
8416       else
8417         {
8418           clib_warning ("parse error '%U'", format_unformat_error, i);
8419           return -99;
8420         }
8421     }
8422
8423   if (~0 == table_id)
8424     {
8425       errmsg ("missing table-ID");
8426       return -99;
8427     }
8428
8429   /* Construct the API message */
8430   M (MPLS_TABLE_ADD_DEL, mp);
8431
8432   mp->mt_table_id = ntohl (table_id);
8433   mp->mt_is_add = is_add;
8434
8435   /* send it... */
8436   S (mp);
8437
8438   /* Wait for a reply... */
8439   W (ret);
8440
8441   return ret;
8442 }
8443
8444 static int
8445 api_mpls_route_add_del (vat_main_t * vam)
8446 {
8447   unformat_input_t *i = vam->input;
8448   vl_api_mpls_route_add_del_t *mp;
8449   u32 sw_if_index = ~0, table_id = 0;
8450   u8 is_add = 1;
8451   u32 next_hop_weight = 1;
8452   u8 is_multipath = 0;
8453   u32 next_hop_table_id = 0;
8454   u8 next_hop_set = 0;
8455   ip4_address_t v4_next_hop_address = {
8456     .as_u32 = 0,
8457   };
8458   ip6_address_t v6_next_hop_address = { {0} };
8459   int count = 1;
8460   int j;
8461   f64 before = 0;
8462   u32 classify_table_index = ~0;
8463   u8 is_classify = 0;
8464   u8 resolve_host = 0, resolve_attached = 0;
8465   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8466   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8467   mpls_label_t *next_hop_out_label_stack = NULL;
8468   mpls_label_t local_label = MPLS_LABEL_INVALID;
8469   u8 is_eos = 0;
8470   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8471
8472   /* Parse args required to build the message */
8473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8476         ;
8477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8478         ;
8479       else if (unformat (i, "%d", &local_label))
8480         ;
8481       else if (unformat (i, "eos"))
8482         is_eos = 1;
8483       else if (unformat (i, "non-eos"))
8484         is_eos = 0;
8485       else if (unformat (i, "via %U", unformat_ip4_address,
8486                          &v4_next_hop_address))
8487         {
8488           next_hop_set = 1;
8489           next_hop_proto = DPO_PROTO_IP4;
8490         }
8491       else if (unformat (i, "via %U", unformat_ip6_address,
8492                          &v6_next_hop_address))
8493         {
8494           next_hop_set = 1;
8495           next_hop_proto = DPO_PROTO_IP6;
8496         }
8497       else if (unformat (i, "weight %d", &next_hop_weight))
8498         ;
8499       else if (unformat (i, "classify %d", &classify_table_index))
8500         {
8501           is_classify = 1;
8502         }
8503       else if (unformat (i, "del"))
8504         is_add = 0;
8505       else if (unformat (i, "add"))
8506         is_add = 1;
8507       else if (unformat (i, "resolve-via-host"))
8508         resolve_host = 1;
8509       else if (unformat (i, "resolve-via-attached"))
8510         resolve_attached = 1;
8511       else if (unformat (i, "multipath"))
8512         is_multipath = 1;
8513       else if (unformat (i, "count %d", &count))
8514         ;
8515       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8516         {
8517           next_hop_set = 1;
8518           next_hop_proto = DPO_PROTO_IP4;
8519         }
8520       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8521         {
8522           next_hop_set = 1;
8523           next_hop_proto = DPO_PROTO_IP6;
8524         }
8525       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8526         ;
8527       else if (unformat (i, "via-label %d", &next_hop_via_label))
8528         ;
8529       else if (unformat (i, "out-label %d", &next_hop_out_label))
8530         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8531       else
8532         {
8533           clib_warning ("parse error '%U'", format_unformat_error, i);
8534           return -99;
8535         }
8536     }
8537
8538   if (!next_hop_set && !is_classify)
8539     {
8540       errmsg ("next hop / classify not set");
8541       return -99;
8542     }
8543
8544   if (MPLS_LABEL_INVALID == local_label)
8545     {
8546       errmsg ("missing label");
8547       return -99;
8548     }
8549
8550   if (count > 1)
8551     {
8552       /* Turn on async mode */
8553       vam->async_mode = 1;
8554       vam->async_errors = 0;
8555       before = vat_time_now (vam);
8556     }
8557
8558   for (j = 0; j < count; j++)
8559     {
8560       /* Construct the API message */
8561       M2 (MPLS_ROUTE_ADD_DEL, mp,
8562           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8563
8564       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8565       mp->mr_table_id = ntohl (table_id);
8566
8567       mp->mr_is_add = is_add;
8568       mp->mr_next_hop_proto = next_hop_proto;
8569       mp->mr_is_classify = is_classify;
8570       mp->mr_is_multipath = is_multipath;
8571       mp->mr_is_resolve_host = resolve_host;
8572       mp->mr_is_resolve_attached = resolve_attached;
8573       mp->mr_next_hop_weight = next_hop_weight;
8574       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8575       mp->mr_classify_table_index = ntohl (classify_table_index);
8576       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8577       mp->mr_label = ntohl (local_label);
8578       mp->mr_eos = is_eos;
8579
8580       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8581       if (0 != mp->mr_next_hop_n_out_labels)
8582         {
8583           memcpy (mp->mr_next_hop_out_label_stack,
8584                   next_hop_out_label_stack,
8585                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8586           vec_free (next_hop_out_label_stack);
8587         }
8588
8589       if (next_hop_set)
8590         {
8591           if (DPO_PROTO_IP4 == next_hop_proto)
8592             {
8593               clib_memcpy (mp->mr_next_hop,
8594                            &v4_next_hop_address,
8595                            sizeof (v4_next_hop_address));
8596             }
8597           else if (DPO_PROTO_IP6 == next_hop_proto)
8598
8599             {
8600               clib_memcpy (mp->mr_next_hop,
8601                            &v6_next_hop_address,
8602                            sizeof (v6_next_hop_address));
8603             }
8604         }
8605       local_label++;
8606
8607       /* send it... */
8608       S (mp);
8609       /* If we receive SIGTERM, stop now... */
8610       if (vam->do_exit)
8611         break;
8612     }
8613
8614   /* When testing multiple add/del ops, use a control-ping to sync */
8615   if (count > 1)
8616     {
8617       vl_api_control_ping_t *mp_ping;
8618       f64 after;
8619       f64 timeout;
8620
8621       /* Shut off async mode */
8622       vam->async_mode = 0;
8623
8624       MPING (CONTROL_PING, mp_ping);
8625       S (mp_ping);
8626
8627       timeout = vat_time_now (vam) + 1.0;
8628       while (vat_time_now (vam) < timeout)
8629         if (vam->result_ready == 1)
8630           goto out;
8631       vam->retval = -99;
8632
8633     out:
8634       if (vam->retval == -99)
8635         errmsg ("timeout");
8636
8637       if (vam->async_errors > 0)
8638         {
8639           errmsg ("%d asynchronous errors", vam->async_errors);
8640           vam->retval = -98;
8641         }
8642       vam->async_errors = 0;
8643       after = vat_time_now (vam);
8644
8645       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8646       if (j > 0)
8647         count = j;
8648
8649       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8650              count, after - before, count / (after - before));
8651     }
8652   else
8653     {
8654       int ret;
8655
8656       /* Wait for a reply... */
8657       W (ret);
8658       return ret;
8659     }
8660
8661   /* Return the good/bad news */
8662   return (vam->retval);
8663 }
8664
8665 static int
8666 api_mpls_ip_bind_unbind (vat_main_t * vam)
8667 {
8668   unformat_input_t *i = vam->input;
8669   vl_api_mpls_ip_bind_unbind_t *mp;
8670   u32 ip_table_id = 0;
8671   u8 is_bind = 1;
8672   u8 is_ip4 = 1;
8673   ip4_address_t v4_address;
8674   ip6_address_t v6_address;
8675   u32 address_length;
8676   u8 address_set = 0;
8677   mpls_label_t local_label = MPLS_LABEL_INVALID;
8678   int ret;
8679
8680   /* Parse args required to build the message */
8681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8682     {
8683       if (unformat (i, "%U/%d", unformat_ip4_address,
8684                     &v4_address, &address_length))
8685         {
8686           is_ip4 = 1;
8687           address_set = 1;
8688         }
8689       else if (unformat (i, "%U/%d", unformat_ip6_address,
8690                          &v6_address, &address_length))
8691         {
8692           is_ip4 = 0;
8693           address_set = 1;
8694         }
8695       else if (unformat (i, "%d", &local_label))
8696         ;
8697       else if (unformat (i, "table-id %d", &ip_table_id))
8698         ;
8699       else if (unformat (i, "unbind"))
8700         is_bind = 0;
8701       else if (unformat (i, "bind"))
8702         is_bind = 1;
8703       else
8704         {
8705           clib_warning ("parse error '%U'", format_unformat_error, i);
8706           return -99;
8707         }
8708     }
8709
8710   if (!address_set)
8711     {
8712       errmsg ("IP addres not set");
8713       return -99;
8714     }
8715
8716   if (MPLS_LABEL_INVALID == local_label)
8717     {
8718       errmsg ("missing label");
8719       return -99;
8720     }
8721
8722   /* Construct the API message */
8723   M (MPLS_IP_BIND_UNBIND, mp);
8724
8725   mp->mb_is_bind = is_bind;
8726   mp->mb_is_ip4 = is_ip4;
8727   mp->mb_ip_table_id = ntohl (ip_table_id);
8728   mp->mb_mpls_table_id = 0;
8729   mp->mb_label = ntohl (local_label);
8730   mp->mb_address_length = address_length;
8731
8732   if (is_ip4)
8733     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8734   else
8735     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8736
8737   /* send it... */
8738   S (mp);
8739
8740   /* Wait for a reply... */
8741   W (ret);
8742   return ret;
8743 }
8744
8745 static int
8746 api_bier_table_add_del (vat_main_t * vam)
8747 {
8748   unformat_input_t *i = vam->input;
8749   vl_api_bier_table_add_del_t *mp;
8750   u8 is_add = 1;
8751   u32 set = 0, sub_domain = 0, hdr_len = 3;
8752   mpls_label_t local_label = MPLS_LABEL_INVALID;
8753   int ret;
8754
8755   /* Parse args required to build the message */
8756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8757     {
8758       if (unformat (i, "sub-domain %d", &sub_domain))
8759         ;
8760       else if (unformat (i, "set %d", &set))
8761         ;
8762       else if (unformat (i, "label %d", &local_label))
8763         ;
8764       else if (unformat (i, "hdr-len %d", &hdr_len))
8765         ;
8766       else if (unformat (i, "add"))
8767         is_add = 1;
8768       else if (unformat (i, "del"))
8769         is_add = 0;
8770       else
8771         {
8772           clib_warning ("parse error '%U'", format_unformat_error, i);
8773           return -99;
8774         }
8775     }
8776
8777   if (MPLS_LABEL_INVALID == local_label)
8778     {
8779       errmsg ("missing label\n");
8780       return -99;
8781     }
8782
8783   /* Construct the API message */
8784   M (BIER_TABLE_ADD_DEL, mp);
8785
8786   mp->bt_is_add = is_add;
8787   mp->bt_label = ntohl (local_label);
8788   mp->bt_tbl_id.bt_set = set;
8789   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8790   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8791
8792   /* send it... */
8793   S (mp);
8794
8795   /* Wait for a reply... */
8796   W (ret);
8797
8798   return (ret);
8799 }
8800
8801 static int
8802 api_bier_route_add_del (vat_main_t * vam)
8803 {
8804   unformat_input_t *i = vam->input;
8805   vl_api_bier_route_add_del_t *mp;
8806   u8 is_add = 1;
8807   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8808   ip4_address_t v4_next_hop_address;
8809   ip6_address_t v6_next_hop_address;
8810   u8 next_hop_set = 0;
8811   u8 next_hop_proto_is_ip4 = 1;
8812   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8813   int ret;
8814
8815   /* Parse args required to build the message */
8816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8819         {
8820           next_hop_proto_is_ip4 = 1;
8821           next_hop_set = 1;
8822         }
8823       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8824         {
8825           next_hop_proto_is_ip4 = 0;
8826           next_hop_set = 1;
8827         }
8828       if (unformat (i, "sub-domain %d", &sub_domain))
8829         ;
8830       else if (unformat (i, "set %d", &set))
8831         ;
8832       else if (unformat (i, "hdr-len %d", &hdr_len))
8833         ;
8834       else if (unformat (i, "bp %d", &bp))
8835         ;
8836       else if (unformat (i, "add"))
8837         is_add = 1;
8838       else if (unformat (i, "del"))
8839         is_add = 0;
8840       else if (unformat (i, "out-label %d", &next_hop_out_label))
8841         ;
8842       else
8843         {
8844           clib_warning ("parse error '%U'", format_unformat_error, i);
8845           return -99;
8846         }
8847     }
8848
8849   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8850     {
8851       errmsg ("next hop / label set\n");
8852       return -99;
8853     }
8854   if (0 == bp)
8855     {
8856       errmsg ("bit=position not set\n");
8857       return -99;
8858     }
8859
8860   /* Construct the API message */
8861   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8862
8863   mp->br_is_add = is_add;
8864   mp->br_tbl_id.bt_set = set;
8865   mp->br_tbl_id.bt_sub_domain = sub_domain;
8866   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8867   mp->br_bp = ntohs (bp);
8868   mp->br_n_paths = 1;
8869   mp->br_paths[0].n_labels = 1;
8870   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8871   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8872
8873   if (next_hop_proto_is_ip4)
8874     {
8875       clib_memcpy (mp->br_paths[0].next_hop,
8876                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8877     }
8878   else
8879     {
8880       clib_memcpy (mp->br_paths[0].next_hop,
8881                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8882     }
8883
8884   /* send it... */
8885   S (mp);
8886
8887   /* Wait for a reply... */
8888   W (ret);
8889
8890   return (ret);
8891 }
8892
8893 static int
8894 api_proxy_arp_add_del (vat_main_t * vam)
8895 {
8896   unformat_input_t *i = vam->input;
8897   vl_api_proxy_arp_add_del_t *mp;
8898   u32 vrf_id = 0;
8899   u8 is_add = 1;
8900   ip4_address_t lo, hi;
8901   u8 range_set = 0;
8902   int ret;
8903
8904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (i, "vrf %d", &vrf_id))
8907         ;
8908       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8909                          unformat_ip4_address, &hi))
8910         range_set = 1;
8911       else if (unformat (i, "del"))
8912         is_add = 0;
8913       else
8914         {
8915           clib_warning ("parse error '%U'", format_unformat_error, i);
8916           return -99;
8917         }
8918     }
8919
8920   if (range_set == 0)
8921     {
8922       errmsg ("address range not set");
8923       return -99;
8924     }
8925
8926   M (PROXY_ARP_ADD_DEL, mp);
8927
8928   mp->vrf_id = ntohl (vrf_id);
8929   mp->is_add = is_add;
8930   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8931   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8932
8933   S (mp);
8934   W (ret);
8935   return ret;
8936 }
8937
8938 static int
8939 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8940 {
8941   unformat_input_t *i = vam->input;
8942   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8943   u32 sw_if_index;
8944   u8 enable = 1;
8945   u8 sw_if_index_set = 0;
8946   int ret;
8947
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8951         sw_if_index_set = 1;
8952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8953         sw_if_index_set = 1;
8954       else if (unformat (i, "enable"))
8955         enable = 1;
8956       else if (unformat (i, "disable"))
8957         enable = 0;
8958       else
8959         {
8960           clib_warning ("parse error '%U'", format_unformat_error, i);
8961           return -99;
8962         }
8963     }
8964
8965   if (sw_if_index_set == 0)
8966     {
8967       errmsg ("missing interface name or sw_if_index");
8968       return -99;
8969     }
8970
8971   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8972
8973   mp->sw_if_index = ntohl (sw_if_index);
8974   mp->enable_disable = enable;
8975
8976   S (mp);
8977   W (ret);
8978   return ret;
8979 }
8980
8981 static int
8982 api_mpls_tunnel_add_del (vat_main_t * vam)
8983 {
8984   unformat_input_t *i = vam->input;
8985   vl_api_mpls_tunnel_add_del_t *mp;
8986
8987   u8 is_add = 1;
8988   u8 l2_only = 0;
8989   u32 sw_if_index = ~0;
8990   u32 next_hop_sw_if_index = ~0;
8991   u32 next_hop_proto_is_ip4 = 1;
8992
8993   u32 next_hop_table_id = 0;
8994   ip4_address_t v4_next_hop_address = {
8995     .as_u32 = 0,
8996   };
8997   ip6_address_t v6_next_hop_address = { {0} };
8998   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8999   int ret;
9000
9001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (i, "add"))
9004         is_add = 1;
9005       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9006         is_add = 0;
9007       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9008         ;
9009       else if (unformat (i, "via %U",
9010                          unformat_ip4_address, &v4_next_hop_address))
9011         {
9012           next_hop_proto_is_ip4 = 1;
9013         }
9014       else if (unformat (i, "via %U",
9015                          unformat_ip6_address, &v6_next_hop_address))
9016         {
9017           next_hop_proto_is_ip4 = 0;
9018         }
9019       else if (unformat (i, "l2-only"))
9020         l2_only = 1;
9021       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9022         ;
9023       else if (unformat (i, "out-label %d", &next_hop_out_label))
9024         vec_add1 (labels, ntohl (next_hop_out_label));
9025       else
9026         {
9027           clib_warning ("parse error '%U'", format_unformat_error, i);
9028           return -99;
9029         }
9030     }
9031
9032   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9033
9034   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9035   mp->mt_sw_if_index = ntohl (sw_if_index);
9036   mp->mt_is_add = is_add;
9037   mp->mt_l2_only = l2_only;
9038   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9039   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9040
9041   mp->mt_next_hop_n_out_labels = vec_len (labels);
9042
9043   if (0 != mp->mt_next_hop_n_out_labels)
9044     {
9045       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9046                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9047       vec_free (labels);
9048     }
9049
9050   if (next_hop_proto_is_ip4)
9051     {
9052       clib_memcpy (mp->mt_next_hop,
9053                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9054     }
9055   else
9056     {
9057       clib_memcpy (mp->mt_next_hop,
9058                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9059     }
9060
9061   S (mp);
9062   W (ret);
9063   return ret;
9064 }
9065
9066 static int
9067 api_sw_interface_set_unnumbered (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_sw_interface_set_unnumbered_t *mp;
9071   u32 sw_if_index;
9072   u32 unnum_sw_index = ~0;
9073   u8 is_add = 1;
9074   u8 sw_if_index_set = 0;
9075   int ret;
9076
9077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9078     {
9079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9080         sw_if_index_set = 1;
9081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9082         sw_if_index_set = 1;
9083       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9084         ;
9085       else if (unformat (i, "del"))
9086         is_add = 0;
9087       else
9088         {
9089           clib_warning ("parse error '%U'", format_unformat_error, i);
9090           return -99;
9091         }
9092     }
9093
9094   if (sw_if_index_set == 0)
9095     {
9096       errmsg ("missing interface name or sw_if_index");
9097       return -99;
9098     }
9099
9100   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9101
9102   mp->sw_if_index = ntohl (sw_if_index);
9103   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9104   mp->is_add = is_add;
9105
9106   S (mp);
9107   W (ret);
9108   return ret;
9109 }
9110
9111 static int
9112 api_ip_neighbor_add_del (vat_main_t * vam)
9113 {
9114   unformat_input_t *i = vam->input;
9115   vl_api_ip_neighbor_add_del_t *mp;
9116   u32 sw_if_index;
9117   u8 sw_if_index_set = 0;
9118   u8 is_add = 1;
9119   u8 is_static = 0;
9120   u8 is_no_fib_entry = 0;
9121   u8 mac_address[6];
9122   u8 mac_set = 0;
9123   u8 v4_address_set = 0;
9124   u8 v6_address_set = 0;
9125   ip4_address_t v4address;
9126   ip6_address_t v6address;
9127   int ret;
9128
9129   memset (mac_address, 0, sizeof (mac_address));
9130
9131   /* Parse args required to build the message */
9132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9133     {
9134       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9135         {
9136           mac_set = 1;
9137         }
9138       else if (unformat (i, "del"))
9139         is_add = 0;
9140       else
9141         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9142         sw_if_index_set = 1;
9143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9144         sw_if_index_set = 1;
9145       else if (unformat (i, "is_static"))
9146         is_static = 1;
9147       else if (unformat (i, "no-fib-entry"))
9148         is_no_fib_entry = 1;
9149       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9150         v4_address_set = 1;
9151       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9152         v6_address_set = 1;
9153       else
9154         {
9155           clib_warning ("parse error '%U'", format_unformat_error, i);
9156           return -99;
9157         }
9158     }
9159
9160   if (sw_if_index_set == 0)
9161     {
9162       errmsg ("missing interface name or sw_if_index");
9163       return -99;
9164     }
9165   if (v4_address_set && v6_address_set)
9166     {
9167       errmsg ("both v4 and v6 addresses set");
9168       return -99;
9169     }
9170   if (!v4_address_set && !v6_address_set)
9171     {
9172       errmsg ("no address set");
9173       return -99;
9174     }
9175
9176   /* Construct the API message */
9177   M (IP_NEIGHBOR_ADD_DEL, mp);
9178
9179   mp->sw_if_index = ntohl (sw_if_index);
9180   mp->is_add = is_add;
9181   mp->is_static = is_static;
9182   mp->is_no_adj_fib = is_no_fib_entry;
9183   if (mac_set)
9184     clib_memcpy (mp->mac_address, mac_address, 6);
9185   if (v6_address_set)
9186     {
9187       mp->is_ipv6 = 1;
9188       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9189     }
9190   else
9191     {
9192       /* mp->is_ipv6 = 0; via memset in M macro above */
9193       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9194     }
9195
9196   /* send it... */
9197   S (mp);
9198
9199   /* Wait for a reply, return good/bad news  */
9200   W (ret);
9201   return ret;
9202 }
9203
9204 static int
9205 api_create_vlan_subif (vat_main_t * vam)
9206 {
9207   unformat_input_t *i = vam->input;
9208   vl_api_create_vlan_subif_t *mp;
9209   u32 sw_if_index;
9210   u8 sw_if_index_set = 0;
9211   u32 vlan_id;
9212   u8 vlan_id_set = 0;
9213   int ret;
9214
9215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9216     {
9217       if (unformat (i, "sw_if_index %d", &sw_if_index))
9218         sw_if_index_set = 1;
9219       else
9220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9221         sw_if_index_set = 1;
9222       else if (unformat (i, "vlan %d", &vlan_id))
9223         vlan_id_set = 1;
9224       else
9225         {
9226           clib_warning ("parse error '%U'", format_unformat_error, i);
9227           return -99;
9228         }
9229     }
9230
9231   if (sw_if_index_set == 0)
9232     {
9233       errmsg ("missing interface name or sw_if_index");
9234       return -99;
9235     }
9236
9237   if (vlan_id_set == 0)
9238     {
9239       errmsg ("missing vlan_id");
9240       return -99;
9241     }
9242   M (CREATE_VLAN_SUBIF, mp);
9243
9244   mp->sw_if_index = ntohl (sw_if_index);
9245   mp->vlan_id = ntohl (vlan_id);
9246
9247   S (mp);
9248   W (ret);
9249   return ret;
9250 }
9251
9252 #define foreach_create_subif_bit                \
9253 _(no_tags)                                      \
9254 _(one_tag)                                      \
9255 _(two_tags)                                     \
9256 _(dot1ad)                                       \
9257 _(exact_match)                                  \
9258 _(default_sub)                                  \
9259 _(outer_vlan_id_any)                            \
9260 _(inner_vlan_id_any)
9261
9262 static int
9263 api_create_subif (vat_main_t * vam)
9264 {
9265   unformat_input_t *i = vam->input;
9266   vl_api_create_subif_t *mp;
9267   u32 sw_if_index;
9268   u8 sw_if_index_set = 0;
9269   u32 sub_id;
9270   u8 sub_id_set = 0;
9271   u32 no_tags = 0;
9272   u32 one_tag = 0;
9273   u32 two_tags = 0;
9274   u32 dot1ad = 0;
9275   u32 exact_match = 0;
9276   u32 default_sub = 0;
9277   u32 outer_vlan_id_any = 0;
9278   u32 inner_vlan_id_any = 0;
9279   u32 tmp;
9280   u16 outer_vlan_id = 0;
9281   u16 inner_vlan_id = 0;
9282   int ret;
9283
9284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9285     {
9286       if (unformat (i, "sw_if_index %d", &sw_if_index))
9287         sw_if_index_set = 1;
9288       else
9289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9290         sw_if_index_set = 1;
9291       else if (unformat (i, "sub_id %d", &sub_id))
9292         sub_id_set = 1;
9293       else if (unformat (i, "outer_vlan_id %d", &tmp))
9294         outer_vlan_id = tmp;
9295       else if (unformat (i, "inner_vlan_id %d", &tmp))
9296         inner_vlan_id = tmp;
9297
9298 #define _(a) else if (unformat (i, #a)) a = 1 ;
9299       foreach_create_subif_bit
9300 #undef _
9301         else
9302         {
9303           clib_warning ("parse error '%U'", format_unformat_error, i);
9304           return -99;
9305         }
9306     }
9307
9308   if (sw_if_index_set == 0)
9309     {
9310       errmsg ("missing interface name or sw_if_index");
9311       return -99;
9312     }
9313
9314   if (sub_id_set == 0)
9315     {
9316       errmsg ("missing sub_id");
9317       return -99;
9318     }
9319   M (CREATE_SUBIF, mp);
9320
9321   mp->sw_if_index = ntohl (sw_if_index);
9322   mp->sub_id = ntohl (sub_id);
9323
9324 #define _(a) mp->a = a;
9325   foreach_create_subif_bit;
9326 #undef _
9327
9328   mp->outer_vlan_id = ntohs (outer_vlan_id);
9329   mp->inner_vlan_id = ntohs (inner_vlan_id);
9330
9331   S (mp);
9332   W (ret);
9333   return ret;
9334 }
9335
9336 static int
9337 api_oam_add_del (vat_main_t * vam)
9338 {
9339   unformat_input_t *i = vam->input;
9340   vl_api_oam_add_del_t *mp;
9341   u32 vrf_id = 0;
9342   u8 is_add = 1;
9343   ip4_address_t src, dst;
9344   u8 src_set = 0;
9345   u8 dst_set = 0;
9346   int ret;
9347
9348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (i, "vrf %d", &vrf_id))
9351         ;
9352       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9353         src_set = 1;
9354       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9355         dst_set = 1;
9356       else if (unformat (i, "del"))
9357         is_add = 0;
9358       else
9359         {
9360           clib_warning ("parse error '%U'", format_unformat_error, i);
9361           return -99;
9362         }
9363     }
9364
9365   if (src_set == 0)
9366     {
9367       errmsg ("missing src addr");
9368       return -99;
9369     }
9370
9371   if (dst_set == 0)
9372     {
9373       errmsg ("missing dst addr");
9374       return -99;
9375     }
9376
9377   M (OAM_ADD_DEL, mp);
9378
9379   mp->vrf_id = ntohl (vrf_id);
9380   mp->is_add = is_add;
9381   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9382   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9383
9384   S (mp);
9385   W (ret);
9386   return ret;
9387 }
9388
9389 static int
9390 api_reset_fib (vat_main_t * vam)
9391 {
9392   unformat_input_t *i = vam->input;
9393   vl_api_reset_fib_t *mp;
9394   u32 vrf_id = 0;
9395   u8 is_ipv6 = 0;
9396   u8 vrf_id_set = 0;
9397
9398   int ret;
9399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9400     {
9401       if (unformat (i, "vrf %d", &vrf_id))
9402         vrf_id_set = 1;
9403       else if (unformat (i, "ipv6"))
9404         is_ipv6 = 1;
9405       else
9406         {
9407           clib_warning ("parse error '%U'", format_unformat_error, i);
9408           return -99;
9409         }
9410     }
9411
9412   if (vrf_id_set == 0)
9413     {
9414       errmsg ("missing vrf id");
9415       return -99;
9416     }
9417
9418   M (RESET_FIB, mp);
9419
9420   mp->vrf_id = ntohl (vrf_id);
9421   mp->is_ipv6 = is_ipv6;
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 static int
9429 api_dhcp_proxy_config (vat_main_t * vam)
9430 {
9431   unformat_input_t *i = vam->input;
9432   vl_api_dhcp_proxy_config_t *mp;
9433   u32 rx_vrf_id = 0;
9434   u32 server_vrf_id = 0;
9435   u8 is_add = 1;
9436   u8 v4_address_set = 0;
9437   u8 v6_address_set = 0;
9438   ip4_address_t v4address;
9439   ip6_address_t v6address;
9440   u8 v4_src_address_set = 0;
9441   u8 v6_src_address_set = 0;
9442   ip4_address_t v4srcaddress;
9443   ip6_address_t v6srcaddress;
9444   int ret;
9445
9446   /* Parse args required to build the message */
9447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9448     {
9449       if (unformat (i, "del"))
9450         is_add = 0;
9451       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9452         ;
9453       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9454         ;
9455       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9456         v4_address_set = 1;
9457       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9458         v6_address_set = 1;
9459       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9460         v4_src_address_set = 1;
9461       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9462         v6_src_address_set = 1;
9463       else
9464         break;
9465     }
9466
9467   if (v4_address_set && v6_address_set)
9468     {
9469       errmsg ("both v4 and v6 server addresses set");
9470       return -99;
9471     }
9472   if (!v4_address_set && !v6_address_set)
9473     {
9474       errmsg ("no server addresses set");
9475       return -99;
9476     }
9477
9478   if (v4_src_address_set && v6_src_address_set)
9479     {
9480       errmsg ("both v4 and v6  src addresses set");
9481       return -99;
9482     }
9483   if (!v4_src_address_set && !v6_src_address_set)
9484     {
9485       errmsg ("no src addresses set");
9486       return -99;
9487     }
9488
9489   if (!(v4_src_address_set && v4_address_set) &&
9490       !(v6_src_address_set && v6_address_set))
9491     {
9492       errmsg ("no matching server and src addresses set");
9493       return -99;
9494     }
9495
9496   /* Construct the API message */
9497   M (DHCP_PROXY_CONFIG, mp);
9498
9499   mp->is_add = is_add;
9500   mp->rx_vrf_id = ntohl (rx_vrf_id);
9501   mp->server_vrf_id = ntohl (server_vrf_id);
9502   if (v6_address_set)
9503     {
9504       mp->is_ipv6 = 1;
9505       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9506       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9507     }
9508   else
9509     {
9510       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9511       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9512     }
9513
9514   /* send it... */
9515   S (mp);
9516
9517   /* Wait for a reply, return good/bad news  */
9518   W (ret);
9519   return ret;
9520 }
9521
9522 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9523 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9524
9525 static void
9526 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9527 {
9528   vat_main_t *vam = &vat_main;
9529   u32 i, count = mp->count;
9530   vl_api_dhcp_server_t *s;
9531
9532   if (mp->is_ipv6)
9533     print (vam->ofp,
9534            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9535            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9536            ntohl (mp->rx_vrf_id),
9537            format_ip6_address, mp->dhcp_src_address,
9538            mp->vss_type, mp->vss_vpn_ascii_id,
9539            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9540   else
9541     print (vam->ofp,
9542            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9543            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9544            ntohl (mp->rx_vrf_id),
9545            format_ip4_address, mp->dhcp_src_address,
9546            mp->vss_type, mp->vss_vpn_ascii_id,
9547            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9548
9549   for (i = 0; i < count; i++)
9550     {
9551       s = &mp->servers[i];
9552
9553       if (mp->is_ipv6)
9554         print (vam->ofp,
9555                " Server Table-ID %d, Server Address %U",
9556                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9557       else
9558         print (vam->ofp,
9559                " Server Table-ID %d, Server Address %U",
9560                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9561     }
9562 }
9563
9564 static void vl_api_dhcp_proxy_details_t_handler_json
9565   (vl_api_dhcp_proxy_details_t * mp)
9566 {
9567   vat_main_t *vam = &vat_main;
9568   vat_json_node_t *node = NULL;
9569   u32 i, count = mp->count;
9570   struct in_addr ip4;
9571   struct in6_addr ip6;
9572   vl_api_dhcp_server_t *s;
9573
9574   if (VAT_JSON_ARRAY != vam->json_tree.type)
9575     {
9576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9577       vat_json_init_array (&vam->json_tree);
9578     }
9579   node = vat_json_array_add (&vam->json_tree);
9580
9581   vat_json_init_object (node);
9582   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9583   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9584                              sizeof (mp->vss_type));
9585   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9586                                    mp->vss_vpn_ascii_id);
9587   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9588   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9589
9590   if (mp->is_ipv6)
9591     {
9592       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9593       vat_json_object_add_ip6 (node, "src_address", ip6);
9594     }
9595   else
9596     {
9597       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9598       vat_json_object_add_ip4 (node, "src_address", ip4);
9599     }
9600
9601   for (i = 0; i < count; i++)
9602     {
9603       s = &mp->servers[i];
9604
9605       vat_json_object_add_uint (node, "server-table-id",
9606                                 ntohl (s->server_vrf_id));
9607
9608       if (mp->is_ipv6)
9609         {
9610           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9611           vat_json_object_add_ip4 (node, "src_address", ip4);
9612         }
9613       else
9614         {
9615           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9616           vat_json_object_add_ip6 (node, "server_address", ip6);
9617         }
9618     }
9619 }
9620
9621 static int
9622 api_dhcp_proxy_dump (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_control_ping_t *mp_ping;
9626   vl_api_dhcp_proxy_dump_t *mp;
9627   u8 is_ipv6 = 0;
9628   int ret;
9629
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "ipv6"))
9633         is_ipv6 = 1;
9634       else
9635         {
9636           clib_warning ("parse error '%U'", format_unformat_error, i);
9637           return -99;
9638         }
9639     }
9640
9641   M (DHCP_PROXY_DUMP, mp);
9642
9643   mp->is_ip6 = is_ipv6;
9644   S (mp);
9645
9646   /* Use a control ping for synchronization */
9647   MPING (CONTROL_PING, mp_ping);
9648   S (mp_ping);
9649
9650   W (ret);
9651   return ret;
9652 }
9653
9654 static int
9655 api_dhcp_proxy_set_vss (vat_main_t * vam)
9656 {
9657   unformat_input_t *i = vam->input;
9658   vl_api_dhcp_proxy_set_vss_t *mp;
9659   u8 is_ipv6 = 0;
9660   u8 is_add = 1;
9661   u32 tbl_id = ~0;
9662   u8 vss_type = VSS_TYPE_DEFAULT;
9663   u8 *vpn_ascii_id = 0;
9664   u32 oui = 0;
9665   u32 fib_id = 0;
9666   int ret;
9667
9668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (i, "tbl_id %d", &tbl_id))
9671         ;
9672       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9673         vss_type = VSS_TYPE_ASCII;
9674       else if (unformat (i, "fib_id %d", &fib_id))
9675         vss_type = VSS_TYPE_VPN_ID;
9676       else if (unformat (i, "oui %d", &oui))
9677         vss_type = VSS_TYPE_VPN_ID;
9678       else if (unformat (i, "ipv6"))
9679         is_ipv6 = 1;
9680       else if (unformat (i, "del"))
9681         is_add = 0;
9682       else
9683         break;
9684     }
9685
9686   if (tbl_id == ~0)
9687     {
9688       errmsg ("missing tbl_id ");
9689       vec_free (vpn_ascii_id);
9690       return -99;
9691     }
9692
9693   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9694     {
9695       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9696       vec_free (vpn_ascii_id);
9697       return -99;
9698     }
9699
9700   M (DHCP_PROXY_SET_VSS, mp);
9701   mp->tbl_id = ntohl (tbl_id);
9702   mp->vss_type = vss_type;
9703   if (vpn_ascii_id)
9704     {
9705       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9706       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9707     }
9708   mp->vpn_index = ntohl (fib_id);
9709   mp->oui = ntohl (oui);
9710   mp->is_ipv6 = is_ipv6;
9711   mp->is_add = is_add;
9712
9713   S (mp);
9714   W (ret);
9715
9716   vec_free (vpn_ascii_id);
9717   return ret;
9718 }
9719
9720 static int
9721 api_dhcp_client_config (vat_main_t * vam)
9722 {
9723   unformat_input_t *i = vam->input;
9724   vl_api_dhcp_client_config_t *mp;
9725   u32 sw_if_index;
9726   u8 sw_if_index_set = 0;
9727   u8 is_add = 1;
9728   u8 *hostname = 0;
9729   u8 disable_event = 0;
9730   int ret;
9731
9732   /* Parse args required to build the message */
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "del"))
9736         is_add = 0;
9737       else
9738         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9739         sw_if_index_set = 1;
9740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9741         sw_if_index_set = 1;
9742       else if (unformat (i, "hostname %s", &hostname))
9743         ;
9744       else if (unformat (i, "disable_event"))
9745         disable_event = 1;
9746       else
9747         break;
9748     }
9749
9750   if (sw_if_index_set == 0)
9751     {
9752       errmsg ("missing interface name or sw_if_index");
9753       return -99;
9754     }
9755
9756   if (vec_len (hostname) > 63)
9757     {
9758       errmsg ("hostname too long");
9759     }
9760   vec_add1 (hostname, 0);
9761
9762   /* Construct the API message */
9763   M (DHCP_CLIENT_CONFIG, mp);
9764
9765   mp->sw_if_index = htonl (sw_if_index);
9766   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9767   vec_free (hostname);
9768   mp->is_add = is_add;
9769   mp->want_dhcp_event = disable_event ? 0 : 1;
9770   mp->pid = htonl (getpid ());
9771
9772   /* send it... */
9773   S (mp);
9774
9775   /* Wait for a reply, return good/bad news  */
9776   W (ret);
9777   return ret;
9778 }
9779
9780 static int
9781 api_set_ip_flow_hash (vat_main_t * vam)
9782 {
9783   unformat_input_t *i = vam->input;
9784   vl_api_set_ip_flow_hash_t *mp;
9785   u32 vrf_id = 0;
9786   u8 is_ipv6 = 0;
9787   u8 vrf_id_set = 0;
9788   u8 src = 0;
9789   u8 dst = 0;
9790   u8 sport = 0;
9791   u8 dport = 0;
9792   u8 proto = 0;
9793   u8 reverse = 0;
9794   int ret;
9795
9796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (i, "vrf %d", &vrf_id))
9799         vrf_id_set = 1;
9800       else if (unformat (i, "ipv6"))
9801         is_ipv6 = 1;
9802       else if (unformat (i, "src"))
9803         src = 1;
9804       else if (unformat (i, "dst"))
9805         dst = 1;
9806       else if (unformat (i, "sport"))
9807         sport = 1;
9808       else if (unformat (i, "dport"))
9809         dport = 1;
9810       else if (unformat (i, "proto"))
9811         proto = 1;
9812       else if (unformat (i, "reverse"))
9813         reverse = 1;
9814
9815       else
9816         {
9817           clib_warning ("parse error '%U'", format_unformat_error, i);
9818           return -99;
9819         }
9820     }
9821
9822   if (vrf_id_set == 0)
9823     {
9824       errmsg ("missing vrf id");
9825       return -99;
9826     }
9827
9828   M (SET_IP_FLOW_HASH, mp);
9829   mp->src = src;
9830   mp->dst = dst;
9831   mp->sport = sport;
9832   mp->dport = dport;
9833   mp->proto = proto;
9834   mp->reverse = reverse;
9835   mp->vrf_id = ntohl (vrf_id);
9836   mp->is_ipv6 = is_ipv6;
9837
9838   S (mp);
9839   W (ret);
9840   return ret;
9841 }
9842
9843 static int
9844 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9845 {
9846   unformat_input_t *i = vam->input;
9847   vl_api_sw_interface_ip6_enable_disable_t *mp;
9848   u32 sw_if_index;
9849   u8 sw_if_index_set = 0;
9850   u8 enable = 0;
9851   int ret;
9852
9853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9854     {
9855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9856         sw_if_index_set = 1;
9857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9858         sw_if_index_set = 1;
9859       else if (unformat (i, "enable"))
9860         enable = 1;
9861       else if (unformat (i, "disable"))
9862         enable = 0;
9863       else
9864         {
9865           clib_warning ("parse error '%U'", format_unformat_error, i);
9866           return -99;
9867         }
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index");
9873       return -99;
9874     }
9875
9876   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9877
9878   mp->sw_if_index = ntohl (sw_if_index);
9879   mp->enable = enable;
9880
9881   S (mp);
9882   W (ret);
9883   return ret;
9884 }
9885
9886 static int
9887 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9888 {
9889   unformat_input_t *i = vam->input;
9890   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9891   u32 sw_if_index;
9892   u8 sw_if_index_set = 0;
9893   u8 v6_address_set = 0;
9894   ip6_address_t v6address;
9895   int ret;
9896
9897   /* Parse args required to build the message */
9898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9901         sw_if_index_set = 1;
9902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9903         sw_if_index_set = 1;
9904       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9905         v6_address_set = 1;
9906       else
9907         break;
9908     }
9909
9910   if (sw_if_index_set == 0)
9911     {
9912       errmsg ("missing interface name or sw_if_index");
9913       return -99;
9914     }
9915   if (!v6_address_set)
9916     {
9917       errmsg ("no address set");
9918       return -99;
9919     }
9920
9921   /* Construct the API message */
9922   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9923
9924   mp->sw_if_index = ntohl (sw_if_index);
9925   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9926
9927   /* send it... */
9928   S (mp);
9929
9930   /* Wait for a reply, return good/bad news  */
9931   W (ret);
9932   return ret;
9933 }
9934
9935 static int
9936 api_ip6nd_proxy_add_del (vat_main_t * vam)
9937 {
9938   unformat_input_t *i = vam->input;
9939   vl_api_ip6nd_proxy_add_del_t *mp;
9940   u32 sw_if_index = ~0;
9941   u8 v6_address_set = 0;
9942   ip6_address_t v6address;
9943   u8 is_del = 0;
9944   int ret;
9945
9946   /* Parse args required to build the message */
9947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9948     {
9949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9950         ;
9951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9952         ;
9953       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9954         v6_address_set = 1;
9955       if (unformat (i, "del"))
9956         is_del = 1;
9957       else
9958         {
9959           clib_warning ("parse error '%U'", format_unformat_error, i);
9960           return -99;
9961         }
9962     }
9963
9964   if (sw_if_index == ~0)
9965     {
9966       errmsg ("missing interface name or sw_if_index");
9967       return -99;
9968     }
9969   if (!v6_address_set)
9970     {
9971       errmsg ("no address set");
9972       return -99;
9973     }
9974
9975   /* Construct the API message */
9976   M (IP6ND_PROXY_ADD_DEL, mp);
9977
9978   mp->is_del = is_del;
9979   mp->sw_if_index = ntohl (sw_if_index);
9980   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9981
9982   /* send it... */
9983   S (mp);
9984
9985   /* Wait for a reply, return good/bad news  */
9986   W (ret);
9987   return ret;
9988 }
9989
9990 static int
9991 api_ip6nd_proxy_dump (vat_main_t * vam)
9992 {
9993   vl_api_ip6nd_proxy_dump_t *mp;
9994   vl_api_control_ping_t *mp_ping;
9995   int ret;
9996
9997   M (IP6ND_PROXY_DUMP, mp);
9998
9999   S (mp);
10000
10001   /* Use a control ping for synchronization */
10002   MPING (CONTROL_PING, mp_ping);
10003   S (mp_ping);
10004
10005   W (ret);
10006   return ret;
10007 }
10008
10009 static void vl_api_ip6nd_proxy_details_t_handler
10010   (vl_api_ip6nd_proxy_details_t * mp)
10011 {
10012   vat_main_t *vam = &vat_main;
10013
10014   print (vam->ofp, "host %U sw_if_index %d",
10015          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10016 }
10017
10018 static void vl_api_ip6nd_proxy_details_t_handler_json
10019   (vl_api_ip6nd_proxy_details_t * mp)
10020 {
10021   vat_main_t *vam = &vat_main;
10022   struct in6_addr ip6;
10023   vat_json_node_t *node = NULL;
10024
10025   if (VAT_JSON_ARRAY != vam->json_tree.type)
10026     {
10027       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10028       vat_json_init_array (&vam->json_tree);
10029     }
10030   node = vat_json_array_add (&vam->json_tree);
10031
10032   vat_json_init_object (node);
10033   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10034
10035   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10036   vat_json_object_add_ip6 (node, "host", ip6);
10037 }
10038
10039 static int
10040 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10041 {
10042   unformat_input_t *i = vam->input;
10043   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10044   u32 sw_if_index;
10045   u8 sw_if_index_set = 0;
10046   u32 address_length = 0;
10047   u8 v6_address_set = 0;
10048   ip6_address_t v6address;
10049   u8 use_default = 0;
10050   u8 no_advertise = 0;
10051   u8 off_link = 0;
10052   u8 no_autoconfig = 0;
10053   u8 no_onlink = 0;
10054   u8 is_no = 0;
10055   u32 val_lifetime = 0;
10056   u32 pref_lifetime = 0;
10057   int ret;
10058
10059   /* Parse args required to build the message */
10060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10061     {
10062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10063         sw_if_index_set = 1;
10064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10065         sw_if_index_set = 1;
10066       else if (unformat (i, "%U/%d",
10067                          unformat_ip6_address, &v6address, &address_length))
10068         v6_address_set = 1;
10069       else if (unformat (i, "val_life %d", &val_lifetime))
10070         ;
10071       else if (unformat (i, "pref_life %d", &pref_lifetime))
10072         ;
10073       else if (unformat (i, "def"))
10074         use_default = 1;
10075       else if (unformat (i, "noadv"))
10076         no_advertise = 1;
10077       else if (unformat (i, "offl"))
10078         off_link = 1;
10079       else if (unformat (i, "noauto"))
10080         no_autoconfig = 1;
10081       else if (unformat (i, "nolink"))
10082         no_onlink = 1;
10083       else if (unformat (i, "isno"))
10084         is_no = 1;
10085       else
10086         {
10087           clib_warning ("parse error '%U'", format_unformat_error, i);
10088           return -99;
10089         }
10090     }
10091
10092   if (sw_if_index_set == 0)
10093     {
10094       errmsg ("missing interface name or sw_if_index");
10095       return -99;
10096     }
10097   if (!v6_address_set)
10098     {
10099       errmsg ("no address set");
10100       return -99;
10101     }
10102
10103   /* Construct the API message */
10104   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10105
10106   mp->sw_if_index = ntohl (sw_if_index);
10107   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10108   mp->address_length = address_length;
10109   mp->use_default = use_default;
10110   mp->no_advertise = no_advertise;
10111   mp->off_link = off_link;
10112   mp->no_autoconfig = no_autoconfig;
10113   mp->no_onlink = no_onlink;
10114   mp->is_no = is_no;
10115   mp->val_lifetime = ntohl (val_lifetime);
10116   mp->pref_lifetime = ntohl (pref_lifetime);
10117
10118   /* send it... */
10119   S (mp);
10120
10121   /* Wait for a reply, return good/bad news  */
10122   W (ret);
10123   return ret;
10124 }
10125
10126 static int
10127 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10128 {
10129   unformat_input_t *i = vam->input;
10130   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10131   u32 sw_if_index;
10132   u8 sw_if_index_set = 0;
10133   u8 suppress = 0;
10134   u8 managed = 0;
10135   u8 other = 0;
10136   u8 ll_option = 0;
10137   u8 send_unicast = 0;
10138   u8 cease = 0;
10139   u8 is_no = 0;
10140   u8 default_router = 0;
10141   u32 max_interval = 0;
10142   u32 min_interval = 0;
10143   u32 lifetime = 0;
10144   u32 initial_count = 0;
10145   u32 initial_interval = 0;
10146   int ret;
10147
10148
10149   /* Parse args required to build the message */
10150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10153         sw_if_index_set = 1;
10154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10155         sw_if_index_set = 1;
10156       else if (unformat (i, "maxint %d", &max_interval))
10157         ;
10158       else if (unformat (i, "minint %d", &min_interval))
10159         ;
10160       else if (unformat (i, "life %d", &lifetime))
10161         ;
10162       else if (unformat (i, "count %d", &initial_count))
10163         ;
10164       else if (unformat (i, "interval %d", &initial_interval))
10165         ;
10166       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10167         suppress = 1;
10168       else if (unformat (i, "managed"))
10169         managed = 1;
10170       else if (unformat (i, "other"))
10171         other = 1;
10172       else if (unformat (i, "ll"))
10173         ll_option = 1;
10174       else if (unformat (i, "send"))
10175         send_unicast = 1;
10176       else if (unformat (i, "cease"))
10177         cease = 1;
10178       else if (unformat (i, "isno"))
10179         is_no = 1;
10180       else if (unformat (i, "def"))
10181         default_router = 1;
10182       else
10183         {
10184           clib_warning ("parse error '%U'", format_unformat_error, i);
10185           return -99;
10186         }
10187     }
10188
10189   if (sw_if_index_set == 0)
10190     {
10191       errmsg ("missing interface name or sw_if_index");
10192       return -99;
10193     }
10194
10195   /* Construct the API message */
10196   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10197
10198   mp->sw_if_index = ntohl (sw_if_index);
10199   mp->max_interval = ntohl (max_interval);
10200   mp->min_interval = ntohl (min_interval);
10201   mp->lifetime = ntohl (lifetime);
10202   mp->initial_count = ntohl (initial_count);
10203   mp->initial_interval = ntohl (initial_interval);
10204   mp->suppress = suppress;
10205   mp->managed = managed;
10206   mp->other = other;
10207   mp->ll_option = ll_option;
10208   mp->send_unicast = send_unicast;
10209   mp->cease = cease;
10210   mp->is_no = is_no;
10211   mp->default_router = default_router;
10212
10213   /* send it... */
10214   S (mp);
10215
10216   /* Wait for a reply, return good/bad news  */
10217   W (ret);
10218   return ret;
10219 }
10220
10221 static int
10222 api_set_arp_neighbor_limit (vat_main_t * vam)
10223 {
10224   unformat_input_t *i = vam->input;
10225   vl_api_set_arp_neighbor_limit_t *mp;
10226   u32 arp_nbr_limit;
10227   u8 limit_set = 0;
10228   u8 is_ipv6 = 0;
10229   int ret;
10230
10231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10232     {
10233       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10234         limit_set = 1;
10235       else if (unformat (i, "ipv6"))
10236         is_ipv6 = 1;
10237       else
10238         {
10239           clib_warning ("parse error '%U'", format_unformat_error, i);
10240           return -99;
10241         }
10242     }
10243
10244   if (limit_set == 0)
10245     {
10246       errmsg ("missing limit value");
10247       return -99;
10248     }
10249
10250   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10251
10252   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10253   mp->is_ipv6 = is_ipv6;
10254
10255   S (mp);
10256   W (ret);
10257   return ret;
10258 }
10259
10260 static int
10261 api_l2_patch_add_del (vat_main_t * vam)
10262 {
10263   unformat_input_t *i = vam->input;
10264   vl_api_l2_patch_add_del_t *mp;
10265   u32 rx_sw_if_index;
10266   u8 rx_sw_if_index_set = 0;
10267   u32 tx_sw_if_index;
10268   u8 tx_sw_if_index_set = 0;
10269   u8 is_add = 1;
10270   int ret;
10271
10272   /* Parse args required to build the message */
10273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10274     {
10275       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10276         rx_sw_if_index_set = 1;
10277       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10278         tx_sw_if_index_set = 1;
10279       else if (unformat (i, "rx"))
10280         {
10281           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10282             {
10283               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10284                             &rx_sw_if_index))
10285                 rx_sw_if_index_set = 1;
10286             }
10287           else
10288             break;
10289         }
10290       else if (unformat (i, "tx"))
10291         {
10292           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10293             {
10294               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10295                             &tx_sw_if_index))
10296                 tx_sw_if_index_set = 1;
10297             }
10298           else
10299             break;
10300         }
10301       else if (unformat (i, "del"))
10302         is_add = 0;
10303       else
10304         break;
10305     }
10306
10307   if (rx_sw_if_index_set == 0)
10308     {
10309       errmsg ("missing rx interface name or rx_sw_if_index");
10310       return -99;
10311     }
10312
10313   if (tx_sw_if_index_set == 0)
10314     {
10315       errmsg ("missing tx interface name or tx_sw_if_index");
10316       return -99;
10317     }
10318
10319   M (L2_PATCH_ADD_DEL, mp);
10320
10321   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10322   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10323   mp->is_add = is_add;
10324
10325   S (mp);
10326   W (ret);
10327   return ret;
10328 }
10329
10330 u8 is_del;
10331 u8 localsid_addr[16];
10332 u8 end_psp;
10333 u8 behavior;
10334 u32 sw_if_index;
10335 u32 vlan_index;
10336 u32 fib_table;
10337 u8 nh_addr[16];
10338
10339 static int
10340 api_sr_localsid_add_del (vat_main_t * vam)
10341 {
10342   unformat_input_t *i = vam->input;
10343   vl_api_sr_localsid_add_del_t *mp;
10344
10345   u8 is_del;
10346   ip6_address_t localsid;
10347   u8 end_psp = 0;
10348   u8 behavior = ~0;
10349   u32 sw_if_index;
10350   u32 fib_table = ~(u32) 0;
10351   ip6_address_t next_hop;
10352
10353   bool nexthop_set = 0;
10354
10355   int ret;
10356
10357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10358     {
10359       if (unformat (i, "del"))
10360         is_del = 1;
10361       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10362       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10363         nexthop_set = 1;
10364       else if (unformat (i, "behavior %u", &behavior));
10365       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10366       else if (unformat (i, "fib-table %u", &fib_table));
10367       else if (unformat (i, "end.psp %u", &behavior));
10368       else
10369         break;
10370     }
10371
10372   M (SR_LOCALSID_ADD_DEL, mp);
10373
10374   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10375   if (nexthop_set)
10376     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10377   mp->behavior = behavior;
10378   mp->sw_if_index = ntohl (sw_if_index);
10379   mp->fib_table = ntohl (fib_table);
10380   mp->end_psp = end_psp;
10381   mp->is_del = is_del;
10382
10383   S (mp);
10384   W (ret);
10385   return ret;
10386 }
10387
10388 static int
10389 api_ioam_enable (vat_main_t * vam)
10390 {
10391   unformat_input_t *input = vam->input;
10392   vl_api_ioam_enable_t *mp;
10393   u32 id = 0;
10394   int has_trace_option = 0;
10395   int has_pot_option = 0;
10396   int has_seqno_option = 0;
10397   int has_analyse_option = 0;
10398   int ret;
10399
10400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10401     {
10402       if (unformat (input, "trace"))
10403         has_trace_option = 1;
10404       else if (unformat (input, "pot"))
10405         has_pot_option = 1;
10406       else if (unformat (input, "seqno"))
10407         has_seqno_option = 1;
10408       else if (unformat (input, "analyse"))
10409         has_analyse_option = 1;
10410       else
10411         break;
10412     }
10413   M (IOAM_ENABLE, mp);
10414   mp->id = htons (id);
10415   mp->seqno = has_seqno_option;
10416   mp->analyse = has_analyse_option;
10417   mp->pot_enable = has_pot_option;
10418   mp->trace_enable = has_trace_option;
10419
10420   S (mp);
10421   W (ret);
10422   return ret;
10423 }
10424
10425
10426 static int
10427 api_ioam_disable (vat_main_t * vam)
10428 {
10429   vl_api_ioam_disable_t *mp;
10430   int ret;
10431
10432   M (IOAM_DISABLE, mp);
10433   S (mp);
10434   W (ret);
10435   return ret;
10436 }
10437
10438 #define foreach_tcp_proto_field                 \
10439 _(src_port)                                     \
10440 _(dst_port)
10441
10442 #define foreach_udp_proto_field                 \
10443 _(src_port)                                     \
10444 _(dst_port)
10445
10446 #define foreach_ip4_proto_field                 \
10447 _(src_address)                                  \
10448 _(dst_address)                                  \
10449 _(tos)                                          \
10450 _(length)                                       \
10451 _(fragment_id)                                  \
10452 _(ttl)                                          \
10453 _(protocol)                                     \
10454 _(checksum)
10455
10456 typedef struct
10457 {
10458   u16 src_port, dst_port;
10459 } tcpudp_header_t;
10460
10461 #if VPP_API_TEST_BUILTIN == 0
10462 uword
10463 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10464 {
10465   u8 **maskp = va_arg (*args, u8 **);
10466   u8 *mask = 0;
10467   u8 found_something = 0;
10468   tcp_header_t *tcp;
10469
10470 #define _(a) u8 a=0;
10471   foreach_tcp_proto_field;
10472 #undef _
10473
10474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (0);
10477 #define _(a) else if (unformat (input, #a)) a=1;
10478       foreach_tcp_proto_field
10479 #undef _
10480         else
10481         break;
10482     }
10483
10484 #define _(a) found_something += a;
10485   foreach_tcp_proto_field;
10486 #undef _
10487
10488   if (found_something == 0)
10489     return 0;
10490
10491   vec_validate (mask, sizeof (*tcp) - 1);
10492
10493   tcp = (tcp_header_t *) mask;
10494
10495 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10496   foreach_tcp_proto_field;
10497 #undef _
10498
10499   *maskp = mask;
10500   return 1;
10501 }
10502
10503 uword
10504 unformat_udp_mask (unformat_input_t * input, va_list * args)
10505 {
10506   u8 **maskp = va_arg (*args, u8 **);
10507   u8 *mask = 0;
10508   u8 found_something = 0;
10509   udp_header_t *udp;
10510
10511 #define _(a) u8 a=0;
10512   foreach_udp_proto_field;
10513 #undef _
10514
10515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10516     {
10517       if (0);
10518 #define _(a) else if (unformat (input, #a)) a=1;
10519       foreach_udp_proto_field
10520 #undef _
10521         else
10522         break;
10523     }
10524
10525 #define _(a) found_something += a;
10526   foreach_udp_proto_field;
10527 #undef _
10528
10529   if (found_something == 0)
10530     return 0;
10531
10532   vec_validate (mask, sizeof (*udp) - 1);
10533
10534   udp = (udp_header_t *) mask;
10535
10536 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10537   foreach_udp_proto_field;
10538 #undef _
10539
10540   *maskp = mask;
10541   return 1;
10542 }
10543
10544 uword
10545 unformat_l4_mask (unformat_input_t * input, va_list * args)
10546 {
10547   u8 **maskp = va_arg (*args, u8 **);
10548   u16 src_port = 0, dst_port = 0;
10549   tcpudp_header_t *tcpudp;
10550
10551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10552     {
10553       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10554         return 1;
10555       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10556         return 1;
10557       else if (unformat (input, "src_port"))
10558         src_port = 0xFFFF;
10559       else if (unformat (input, "dst_port"))
10560         dst_port = 0xFFFF;
10561       else
10562         return 0;
10563     }
10564
10565   if (!src_port && !dst_port)
10566     return 0;
10567
10568   u8 *mask = 0;
10569   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10570
10571   tcpudp = (tcpudp_header_t *) mask;
10572   tcpudp->src_port = src_port;
10573   tcpudp->dst_port = dst_port;
10574
10575   *maskp = mask;
10576
10577   return 1;
10578 }
10579
10580 uword
10581 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10582 {
10583   u8 **maskp = va_arg (*args, u8 **);
10584   u8 *mask = 0;
10585   u8 found_something = 0;
10586   ip4_header_t *ip;
10587
10588 #define _(a) u8 a=0;
10589   foreach_ip4_proto_field;
10590 #undef _
10591   u8 version = 0;
10592   u8 hdr_length = 0;
10593
10594
10595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (input, "version"))
10598         version = 1;
10599       else if (unformat (input, "hdr_length"))
10600         hdr_length = 1;
10601       else if (unformat (input, "src"))
10602         src_address = 1;
10603       else if (unformat (input, "dst"))
10604         dst_address = 1;
10605       else if (unformat (input, "proto"))
10606         protocol = 1;
10607
10608 #define _(a) else if (unformat (input, #a)) a=1;
10609       foreach_ip4_proto_field
10610 #undef _
10611         else
10612         break;
10613     }
10614
10615 #define _(a) found_something += a;
10616   foreach_ip4_proto_field;
10617 #undef _
10618
10619   if (found_something == 0)
10620     return 0;
10621
10622   vec_validate (mask, sizeof (*ip) - 1);
10623
10624   ip = (ip4_header_t *) mask;
10625
10626 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10627   foreach_ip4_proto_field;
10628 #undef _
10629
10630   ip->ip_version_and_header_length = 0;
10631
10632   if (version)
10633     ip->ip_version_and_header_length |= 0xF0;
10634
10635   if (hdr_length)
10636     ip->ip_version_and_header_length |= 0x0F;
10637
10638   *maskp = mask;
10639   return 1;
10640 }
10641
10642 #define foreach_ip6_proto_field                 \
10643 _(src_address)                                  \
10644 _(dst_address)                                  \
10645 _(payload_length)                               \
10646 _(hop_limit)                                    \
10647 _(protocol)
10648
10649 uword
10650 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10651 {
10652   u8 **maskp = va_arg (*args, u8 **);
10653   u8 *mask = 0;
10654   u8 found_something = 0;
10655   ip6_header_t *ip;
10656   u32 ip_version_traffic_class_and_flow_label;
10657
10658 #define _(a) u8 a=0;
10659   foreach_ip6_proto_field;
10660 #undef _
10661   u8 version = 0;
10662   u8 traffic_class = 0;
10663   u8 flow_label = 0;
10664
10665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10666     {
10667       if (unformat (input, "version"))
10668         version = 1;
10669       else if (unformat (input, "traffic-class"))
10670         traffic_class = 1;
10671       else if (unformat (input, "flow-label"))
10672         flow_label = 1;
10673       else if (unformat (input, "src"))
10674         src_address = 1;
10675       else if (unformat (input, "dst"))
10676         dst_address = 1;
10677       else if (unformat (input, "proto"))
10678         protocol = 1;
10679
10680 #define _(a) else if (unformat (input, #a)) a=1;
10681       foreach_ip6_proto_field
10682 #undef _
10683         else
10684         break;
10685     }
10686
10687 #define _(a) found_something += a;
10688   foreach_ip6_proto_field;
10689 #undef _
10690
10691   if (found_something == 0)
10692     return 0;
10693
10694   vec_validate (mask, sizeof (*ip) - 1);
10695
10696   ip = (ip6_header_t *) mask;
10697
10698 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10699   foreach_ip6_proto_field;
10700 #undef _
10701
10702   ip_version_traffic_class_and_flow_label = 0;
10703
10704   if (version)
10705     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10706
10707   if (traffic_class)
10708     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10709
10710   if (flow_label)
10711     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10712
10713   ip->ip_version_traffic_class_and_flow_label =
10714     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10715
10716   *maskp = mask;
10717   return 1;
10718 }
10719
10720 uword
10721 unformat_l3_mask (unformat_input_t * input, va_list * args)
10722 {
10723   u8 **maskp = va_arg (*args, u8 **);
10724
10725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10726     {
10727       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10728         return 1;
10729       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10730         return 1;
10731       else
10732         break;
10733     }
10734   return 0;
10735 }
10736
10737 uword
10738 unformat_l2_mask (unformat_input_t * input, va_list * args)
10739 {
10740   u8 **maskp = va_arg (*args, u8 **);
10741   u8 *mask = 0;
10742   u8 src = 0;
10743   u8 dst = 0;
10744   u8 proto = 0;
10745   u8 tag1 = 0;
10746   u8 tag2 = 0;
10747   u8 ignore_tag1 = 0;
10748   u8 ignore_tag2 = 0;
10749   u8 cos1 = 0;
10750   u8 cos2 = 0;
10751   u8 dot1q = 0;
10752   u8 dot1ad = 0;
10753   int len = 14;
10754
10755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (input, "src"))
10758         src = 1;
10759       else if (unformat (input, "dst"))
10760         dst = 1;
10761       else if (unformat (input, "proto"))
10762         proto = 1;
10763       else if (unformat (input, "tag1"))
10764         tag1 = 1;
10765       else if (unformat (input, "tag2"))
10766         tag2 = 1;
10767       else if (unformat (input, "ignore-tag1"))
10768         ignore_tag1 = 1;
10769       else if (unformat (input, "ignore-tag2"))
10770         ignore_tag2 = 1;
10771       else if (unformat (input, "cos1"))
10772         cos1 = 1;
10773       else if (unformat (input, "cos2"))
10774         cos2 = 1;
10775       else if (unformat (input, "dot1q"))
10776         dot1q = 1;
10777       else if (unformat (input, "dot1ad"))
10778         dot1ad = 1;
10779       else
10780         break;
10781     }
10782   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10783        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10784     return 0;
10785
10786   if (tag1 || ignore_tag1 || cos1 || dot1q)
10787     len = 18;
10788   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10789     len = 22;
10790
10791   vec_validate (mask, len - 1);
10792
10793   if (dst)
10794     memset (mask, 0xff, 6);
10795
10796   if (src)
10797     memset (mask + 6, 0xff, 6);
10798
10799   if (tag2 || dot1ad)
10800     {
10801       /* inner vlan tag */
10802       if (tag2)
10803         {
10804           mask[19] = 0xff;
10805           mask[18] = 0x0f;
10806         }
10807       if (cos2)
10808         mask[18] |= 0xe0;
10809       if (proto)
10810         mask[21] = mask[20] = 0xff;
10811       if (tag1)
10812         {
10813           mask[15] = 0xff;
10814           mask[14] = 0x0f;
10815         }
10816       if (cos1)
10817         mask[14] |= 0xe0;
10818       *maskp = mask;
10819       return 1;
10820     }
10821   if (tag1 | dot1q)
10822     {
10823       if (tag1)
10824         {
10825           mask[15] = 0xff;
10826           mask[14] = 0x0f;
10827         }
10828       if (cos1)
10829         mask[14] |= 0xe0;
10830       if (proto)
10831         mask[16] = mask[17] = 0xff;
10832
10833       *maskp = mask;
10834       return 1;
10835     }
10836   if (cos2)
10837     mask[18] |= 0xe0;
10838   if (cos1)
10839     mask[14] |= 0xe0;
10840   if (proto)
10841     mask[12] = mask[13] = 0xff;
10842
10843   *maskp = mask;
10844   return 1;
10845 }
10846
10847 uword
10848 unformat_classify_mask (unformat_input_t * input, va_list * args)
10849 {
10850   u8 **maskp = va_arg (*args, u8 **);
10851   u32 *skipp = va_arg (*args, u32 *);
10852   u32 *matchp = va_arg (*args, u32 *);
10853   u32 match;
10854   u8 *mask = 0;
10855   u8 *l2 = 0;
10856   u8 *l3 = 0;
10857   u8 *l4 = 0;
10858   int i;
10859
10860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10861     {
10862       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10863         ;
10864       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10865         ;
10866       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10867         ;
10868       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10869         ;
10870       else
10871         break;
10872     }
10873
10874   if (l4 && !l3)
10875     {
10876       vec_free (mask);
10877       vec_free (l2);
10878       vec_free (l4);
10879       return 0;
10880     }
10881
10882   if (mask || l2 || l3 || l4)
10883     {
10884       if (l2 || l3 || l4)
10885         {
10886           /* "With a free Ethernet header in every package" */
10887           if (l2 == 0)
10888             vec_validate (l2, 13);
10889           mask = l2;
10890           if (vec_len (l3))
10891             {
10892               vec_append (mask, l3);
10893               vec_free (l3);
10894             }
10895           if (vec_len (l4))
10896             {
10897               vec_append (mask, l4);
10898               vec_free (l4);
10899             }
10900         }
10901
10902       /* Scan forward looking for the first significant mask octet */
10903       for (i = 0; i < vec_len (mask); i++)
10904         if (mask[i])
10905           break;
10906
10907       /* compute (skip, match) params */
10908       *skipp = i / sizeof (u32x4);
10909       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10910
10911       /* Pad mask to an even multiple of the vector size */
10912       while (vec_len (mask) % sizeof (u32x4))
10913         vec_add1 (mask, 0);
10914
10915       match = vec_len (mask) / sizeof (u32x4);
10916
10917       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10918         {
10919           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10920           if (*tmp || *(tmp + 1))
10921             break;
10922           match--;
10923         }
10924       if (match == 0)
10925         clib_warning ("BUG: match 0");
10926
10927       _vec_len (mask) = match * sizeof (u32x4);
10928
10929       *matchp = match;
10930       *maskp = mask;
10931
10932       return 1;
10933     }
10934
10935   return 0;
10936 }
10937 #endif /* VPP_API_TEST_BUILTIN */
10938
10939 #define foreach_l2_next                         \
10940 _(drop, DROP)                                   \
10941 _(ethernet, ETHERNET_INPUT)                     \
10942 _(ip4, IP4_INPUT)                               \
10943 _(ip6, IP6_INPUT)
10944
10945 uword
10946 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10947 {
10948   u32 *miss_next_indexp = va_arg (*args, u32 *);
10949   u32 next_index = 0;
10950   u32 tmp;
10951
10952 #define _(n,N) \
10953   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10954   foreach_l2_next;
10955 #undef _
10956
10957   if (unformat (input, "%d", &tmp))
10958     {
10959       next_index = tmp;
10960       goto out;
10961     }
10962
10963   return 0;
10964
10965 out:
10966   *miss_next_indexp = next_index;
10967   return 1;
10968 }
10969
10970 #define foreach_ip_next                         \
10971 _(drop, DROP)                                   \
10972 _(local, LOCAL)                                 \
10973 _(rewrite, REWRITE)
10974
10975 uword
10976 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10977 {
10978   u32 *miss_next_indexp = va_arg (*args, u32 *);
10979   u32 next_index = 0;
10980   u32 tmp;
10981
10982 #define _(n,N) \
10983   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10984   foreach_ip_next;
10985 #undef _
10986
10987   if (unformat (input, "%d", &tmp))
10988     {
10989       next_index = tmp;
10990       goto out;
10991     }
10992
10993   return 0;
10994
10995 out:
10996   *miss_next_indexp = next_index;
10997   return 1;
10998 }
10999
11000 #define foreach_acl_next                        \
11001 _(deny, DENY)
11002
11003 uword
11004 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11005 {
11006   u32 *miss_next_indexp = va_arg (*args, u32 *);
11007   u32 next_index = 0;
11008   u32 tmp;
11009
11010 #define _(n,N) \
11011   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11012   foreach_acl_next;
11013 #undef _
11014
11015   if (unformat (input, "permit"))
11016     {
11017       next_index = ~0;
11018       goto out;
11019     }
11020   else if (unformat (input, "%d", &tmp))
11021     {
11022       next_index = tmp;
11023       goto out;
11024     }
11025
11026   return 0;
11027
11028 out:
11029   *miss_next_indexp = next_index;
11030   return 1;
11031 }
11032
11033 uword
11034 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11035 {
11036   u32 *r = va_arg (*args, u32 *);
11037
11038   if (unformat (input, "conform-color"))
11039     *r = POLICE_CONFORM;
11040   else if (unformat (input, "exceed-color"))
11041     *r = POLICE_EXCEED;
11042   else
11043     return 0;
11044
11045   return 1;
11046 }
11047
11048 static int
11049 api_classify_add_del_table (vat_main_t * vam)
11050 {
11051   unformat_input_t *i = vam->input;
11052   vl_api_classify_add_del_table_t *mp;
11053
11054   u32 nbuckets = 2;
11055   u32 skip = ~0;
11056   u32 match = ~0;
11057   int is_add = 1;
11058   int del_chain = 0;
11059   u32 table_index = ~0;
11060   u32 next_table_index = ~0;
11061   u32 miss_next_index = ~0;
11062   u32 memory_size = 32 << 20;
11063   u8 *mask = 0;
11064   u32 current_data_flag = 0;
11065   int current_data_offset = 0;
11066   int ret;
11067
11068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11069     {
11070       if (unformat (i, "del"))
11071         is_add = 0;
11072       else if (unformat (i, "del-chain"))
11073         {
11074           is_add = 0;
11075           del_chain = 1;
11076         }
11077       else if (unformat (i, "buckets %d", &nbuckets))
11078         ;
11079       else if (unformat (i, "memory_size %d", &memory_size))
11080         ;
11081       else if (unformat (i, "skip %d", &skip))
11082         ;
11083       else if (unformat (i, "match %d", &match))
11084         ;
11085       else if (unformat (i, "table %d", &table_index))
11086         ;
11087       else if (unformat (i, "mask %U", unformat_classify_mask,
11088                          &mask, &skip, &match))
11089         ;
11090       else if (unformat (i, "next-table %d", &next_table_index))
11091         ;
11092       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11093                          &miss_next_index))
11094         ;
11095       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11096                          &miss_next_index))
11097         ;
11098       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11099                          &miss_next_index))
11100         ;
11101       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11102         ;
11103       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11104         ;
11105       else
11106         break;
11107     }
11108
11109   if (is_add && mask == 0)
11110     {
11111       errmsg ("Mask required");
11112       return -99;
11113     }
11114
11115   if (is_add && skip == ~0)
11116     {
11117       errmsg ("skip count required");
11118       return -99;
11119     }
11120
11121   if (is_add && match == ~0)
11122     {
11123       errmsg ("match count required");
11124       return -99;
11125     }
11126
11127   if (!is_add && table_index == ~0)
11128     {
11129       errmsg ("table index required for delete");
11130       return -99;
11131     }
11132
11133   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11134
11135   mp->is_add = is_add;
11136   mp->del_chain = del_chain;
11137   mp->table_index = ntohl (table_index);
11138   mp->nbuckets = ntohl (nbuckets);
11139   mp->memory_size = ntohl (memory_size);
11140   mp->skip_n_vectors = ntohl (skip);
11141   mp->match_n_vectors = ntohl (match);
11142   mp->next_table_index = ntohl (next_table_index);
11143   mp->miss_next_index = ntohl (miss_next_index);
11144   mp->current_data_flag = ntohl (current_data_flag);
11145   mp->current_data_offset = ntohl (current_data_offset);
11146   clib_memcpy (mp->mask, mask, vec_len (mask));
11147
11148   vec_free (mask);
11149
11150   S (mp);
11151   W (ret);
11152   return ret;
11153 }
11154
11155 #if VPP_API_TEST_BUILTIN == 0
11156 uword
11157 unformat_l4_match (unformat_input_t * input, va_list * args)
11158 {
11159   u8 **matchp = va_arg (*args, u8 **);
11160
11161   u8 *proto_header = 0;
11162   int src_port = 0;
11163   int dst_port = 0;
11164
11165   tcpudp_header_t h;
11166
11167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11168     {
11169       if (unformat (input, "src_port %d", &src_port))
11170         ;
11171       else if (unformat (input, "dst_port %d", &dst_port))
11172         ;
11173       else
11174         return 0;
11175     }
11176
11177   h.src_port = clib_host_to_net_u16 (src_port);
11178   h.dst_port = clib_host_to_net_u16 (dst_port);
11179   vec_validate (proto_header, sizeof (h) - 1);
11180   memcpy (proto_header, &h, sizeof (h));
11181
11182   *matchp = proto_header;
11183
11184   return 1;
11185 }
11186
11187 uword
11188 unformat_ip4_match (unformat_input_t * input, va_list * args)
11189 {
11190   u8 **matchp = va_arg (*args, u8 **);
11191   u8 *match = 0;
11192   ip4_header_t *ip;
11193   int version = 0;
11194   u32 version_val;
11195   int hdr_length = 0;
11196   u32 hdr_length_val;
11197   int src = 0, dst = 0;
11198   ip4_address_t src_val, dst_val;
11199   int proto = 0;
11200   u32 proto_val;
11201   int tos = 0;
11202   u32 tos_val;
11203   int length = 0;
11204   u32 length_val;
11205   int fragment_id = 0;
11206   u32 fragment_id_val;
11207   int ttl = 0;
11208   int ttl_val;
11209   int checksum = 0;
11210   u32 checksum_val;
11211
11212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11213     {
11214       if (unformat (input, "version %d", &version_val))
11215         version = 1;
11216       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11217         hdr_length = 1;
11218       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11219         src = 1;
11220       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11221         dst = 1;
11222       else if (unformat (input, "proto %d", &proto_val))
11223         proto = 1;
11224       else if (unformat (input, "tos %d", &tos_val))
11225         tos = 1;
11226       else if (unformat (input, "length %d", &length_val))
11227         length = 1;
11228       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11229         fragment_id = 1;
11230       else if (unformat (input, "ttl %d", &ttl_val))
11231         ttl = 1;
11232       else if (unformat (input, "checksum %d", &checksum_val))
11233         checksum = 1;
11234       else
11235         break;
11236     }
11237
11238   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11239       + ttl + checksum == 0)
11240     return 0;
11241
11242   /*
11243    * Aligned because we use the real comparison functions
11244    */
11245   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11246
11247   ip = (ip4_header_t *) match;
11248
11249   /* These are realistically matched in practice */
11250   if (src)
11251     ip->src_address.as_u32 = src_val.as_u32;
11252
11253   if (dst)
11254     ip->dst_address.as_u32 = dst_val.as_u32;
11255
11256   if (proto)
11257     ip->protocol = proto_val;
11258
11259
11260   /* These are not, but they're included for completeness */
11261   if (version)
11262     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11263
11264   if (hdr_length)
11265     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11266
11267   if (tos)
11268     ip->tos = tos_val;
11269
11270   if (length)
11271     ip->length = clib_host_to_net_u16 (length_val);
11272
11273   if (ttl)
11274     ip->ttl = ttl_val;
11275
11276   if (checksum)
11277     ip->checksum = clib_host_to_net_u16 (checksum_val);
11278
11279   *matchp = match;
11280   return 1;
11281 }
11282
11283 uword
11284 unformat_ip6_match (unformat_input_t * input, va_list * args)
11285 {
11286   u8 **matchp = va_arg (*args, u8 **);
11287   u8 *match = 0;
11288   ip6_header_t *ip;
11289   int version = 0;
11290   u32 version_val;
11291   u8 traffic_class = 0;
11292   u32 traffic_class_val = 0;
11293   u8 flow_label = 0;
11294   u8 flow_label_val;
11295   int src = 0, dst = 0;
11296   ip6_address_t src_val, dst_val;
11297   int proto = 0;
11298   u32 proto_val;
11299   int payload_length = 0;
11300   u32 payload_length_val;
11301   int hop_limit = 0;
11302   int hop_limit_val;
11303   u32 ip_version_traffic_class_and_flow_label;
11304
11305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (input, "version %d", &version_val))
11308         version = 1;
11309       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11310         traffic_class = 1;
11311       else if (unformat (input, "flow_label %d", &flow_label_val))
11312         flow_label = 1;
11313       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11314         src = 1;
11315       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11316         dst = 1;
11317       else if (unformat (input, "proto %d", &proto_val))
11318         proto = 1;
11319       else if (unformat (input, "payload_length %d", &payload_length_val))
11320         payload_length = 1;
11321       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11322         hop_limit = 1;
11323       else
11324         break;
11325     }
11326
11327   if (version + traffic_class + flow_label + src + dst + proto +
11328       payload_length + hop_limit == 0)
11329     return 0;
11330
11331   /*
11332    * Aligned because we use the real comparison functions
11333    */
11334   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11335
11336   ip = (ip6_header_t *) match;
11337
11338   if (src)
11339     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11340
11341   if (dst)
11342     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11343
11344   if (proto)
11345     ip->protocol = proto_val;
11346
11347   ip_version_traffic_class_and_flow_label = 0;
11348
11349   if (version)
11350     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11351
11352   if (traffic_class)
11353     ip_version_traffic_class_and_flow_label |=
11354       (traffic_class_val & 0xFF) << 20;
11355
11356   if (flow_label)
11357     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11358
11359   ip->ip_version_traffic_class_and_flow_label =
11360     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11361
11362   if (payload_length)
11363     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11364
11365   if (hop_limit)
11366     ip->hop_limit = hop_limit_val;
11367
11368   *matchp = match;
11369   return 1;
11370 }
11371
11372 uword
11373 unformat_l3_match (unformat_input_t * input, va_list * args)
11374 {
11375   u8 **matchp = va_arg (*args, u8 **);
11376
11377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11378     {
11379       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11380         return 1;
11381       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11382         return 1;
11383       else
11384         break;
11385     }
11386   return 0;
11387 }
11388
11389 uword
11390 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11391 {
11392   u8 *tagp = va_arg (*args, u8 *);
11393   u32 tag;
11394
11395   if (unformat (input, "%d", &tag))
11396     {
11397       tagp[0] = (tag >> 8) & 0x0F;
11398       tagp[1] = tag & 0xFF;
11399       return 1;
11400     }
11401
11402   return 0;
11403 }
11404
11405 uword
11406 unformat_l2_match (unformat_input_t * input, va_list * args)
11407 {
11408   u8 **matchp = va_arg (*args, u8 **);
11409   u8 *match = 0;
11410   u8 src = 0;
11411   u8 src_val[6];
11412   u8 dst = 0;
11413   u8 dst_val[6];
11414   u8 proto = 0;
11415   u16 proto_val;
11416   u8 tag1 = 0;
11417   u8 tag1_val[2];
11418   u8 tag2 = 0;
11419   u8 tag2_val[2];
11420   int len = 14;
11421   u8 ignore_tag1 = 0;
11422   u8 ignore_tag2 = 0;
11423   u8 cos1 = 0;
11424   u8 cos2 = 0;
11425   u32 cos1_val = 0;
11426   u32 cos2_val = 0;
11427
11428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11429     {
11430       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11431         src = 1;
11432       else
11433         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11434         dst = 1;
11435       else if (unformat (input, "proto %U",
11436                          unformat_ethernet_type_host_byte_order, &proto_val))
11437         proto = 1;
11438       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11439         tag1 = 1;
11440       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11441         tag2 = 1;
11442       else if (unformat (input, "ignore-tag1"))
11443         ignore_tag1 = 1;
11444       else if (unformat (input, "ignore-tag2"))
11445         ignore_tag2 = 1;
11446       else if (unformat (input, "cos1 %d", &cos1_val))
11447         cos1 = 1;
11448       else if (unformat (input, "cos2 %d", &cos2_val))
11449         cos2 = 1;
11450       else
11451         break;
11452     }
11453   if ((src + dst + proto + tag1 + tag2 +
11454        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11455     return 0;
11456
11457   if (tag1 || ignore_tag1 || cos1)
11458     len = 18;
11459   if (tag2 || ignore_tag2 || cos2)
11460     len = 22;
11461
11462   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11463
11464   if (dst)
11465     clib_memcpy (match, dst_val, 6);
11466
11467   if (src)
11468     clib_memcpy (match + 6, src_val, 6);
11469
11470   if (tag2)
11471     {
11472       /* inner vlan tag */
11473       match[19] = tag2_val[1];
11474       match[18] = tag2_val[0];
11475       if (cos2)
11476         match[18] |= (cos2_val & 0x7) << 5;
11477       if (proto)
11478         {
11479           match[21] = proto_val & 0xff;
11480           match[20] = proto_val >> 8;
11481         }
11482       if (tag1)
11483         {
11484           match[15] = tag1_val[1];
11485           match[14] = tag1_val[0];
11486         }
11487       if (cos1)
11488         match[14] |= (cos1_val & 0x7) << 5;
11489       *matchp = match;
11490       return 1;
11491     }
11492   if (tag1)
11493     {
11494       match[15] = tag1_val[1];
11495       match[14] = tag1_val[0];
11496       if (proto)
11497         {
11498           match[17] = proto_val & 0xff;
11499           match[16] = proto_val >> 8;
11500         }
11501       if (cos1)
11502         match[14] |= (cos1_val & 0x7) << 5;
11503
11504       *matchp = match;
11505       return 1;
11506     }
11507   if (cos2)
11508     match[18] |= (cos2_val & 0x7) << 5;
11509   if (cos1)
11510     match[14] |= (cos1_val & 0x7) << 5;
11511   if (proto)
11512     {
11513       match[13] = proto_val & 0xff;
11514       match[12] = proto_val >> 8;
11515     }
11516
11517   *matchp = match;
11518   return 1;
11519 }
11520 #endif
11521
11522 uword
11523 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11524 {
11525   u8 **matchp = va_arg (*args, u8 **);
11526   u32 skip_n_vectors = va_arg (*args, u32);
11527   u32 match_n_vectors = va_arg (*args, u32);
11528
11529   u8 *match = 0;
11530   u8 *l2 = 0;
11531   u8 *l3 = 0;
11532   u8 *l4 = 0;
11533
11534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11535     {
11536       if (unformat (input, "hex %U", unformat_hex_string, &match))
11537         ;
11538       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11539         ;
11540       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11541         ;
11542       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11543         ;
11544       else
11545         break;
11546     }
11547
11548   if (l4 && !l3)
11549     {
11550       vec_free (match);
11551       vec_free (l2);
11552       vec_free (l4);
11553       return 0;
11554     }
11555
11556   if (match || l2 || l3 || l4)
11557     {
11558       if (l2 || l3 || l4)
11559         {
11560           /* "Win a free Ethernet header in every packet" */
11561           if (l2 == 0)
11562             vec_validate_aligned (l2, 13, sizeof (u32x4));
11563           match = l2;
11564           if (vec_len (l3))
11565             {
11566               vec_append_aligned (match, l3, sizeof (u32x4));
11567               vec_free (l3);
11568             }
11569           if (vec_len (l4))
11570             {
11571               vec_append_aligned (match, l4, sizeof (u32x4));
11572               vec_free (l4);
11573             }
11574         }
11575
11576       /* Make sure the vector is big enough even if key is all 0's */
11577       vec_validate_aligned
11578         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11579          sizeof (u32x4));
11580
11581       /* Set size, include skipped vectors */
11582       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11583
11584       *matchp = match;
11585
11586       return 1;
11587     }
11588
11589   return 0;
11590 }
11591
11592 static int
11593 api_classify_add_del_session (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   vl_api_classify_add_del_session_t *mp;
11597   int is_add = 1;
11598   u32 table_index = ~0;
11599   u32 hit_next_index = ~0;
11600   u32 opaque_index = ~0;
11601   u8 *match = 0;
11602   i32 advance = 0;
11603   u32 skip_n_vectors = 0;
11604   u32 match_n_vectors = 0;
11605   u32 action = 0;
11606   u32 metadata = 0;
11607   int ret;
11608
11609   /*
11610    * Warning: you have to supply skip_n and match_n
11611    * because the API client cant simply look at the classify
11612    * table object.
11613    */
11614
11615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11616     {
11617       if (unformat (i, "del"))
11618         is_add = 0;
11619       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11620                          &hit_next_index))
11621         ;
11622       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11623                          &hit_next_index))
11624         ;
11625       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11626                          &hit_next_index))
11627         ;
11628       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11629         ;
11630       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11631         ;
11632       else if (unformat (i, "opaque-index %d", &opaque_index))
11633         ;
11634       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11635         ;
11636       else if (unformat (i, "match_n %d", &match_n_vectors))
11637         ;
11638       else if (unformat (i, "match %U", api_unformat_classify_match,
11639                          &match, skip_n_vectors, match_n_vectors))
11640         ;
11641       else if (unformat (i, "advance %d", &advance))
11642         ;
11643       else if (unformat (i, "table-index %d", &table_index))
11644         ;
11645       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11646         action = 1;
11647       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11648         action = 2;
11649       else if (unformat (i, "action %d", &action))
11650         ;
11651       else if (unformat (i, "metadata %d", &metadata))
11652         ;
11653       else
11654         break;
11655     }
11656
11657   if (table_index == ~0)
11658     {
11659       errmsg ("Table index required");
11660       return -99;
11661     }
11662
11663   if (is_add && match == 0)
11664     {
11665       errmsg ("Match value required");
11666       return -99;
11667     }
11668
11669   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11670
11671   mp->is_add = is_add;
11672   mp->table_index = ntohl (table_index);
11673   mp->hit_next_index = ntohl (hit_next_index);
11674   mp->opaque_index = ntohl (opaque_index);
11675   mp->advance = ntohl (advance);
11676   mp->action = action;
11677   mp->metadata = ntohl (metadata);
11678   clib_memcpy (mp->match, match, vec_len (match));
11679   vec_free (match);
11680
11681   S (mp);
11682   W (ret);
11683   return ret;
11684 }
11685
11686 static int
11687 api_classify_set_interface_ip_table (vat_main_t * vam)
11688 {
11689   unformat_input_t *i = vam->input;
11690   vl_api_classify_set_interface_ip_table_t *mp;
11691   u32 sw_if_index;
11692   int sw_if_index_set;
11693   u32 table_index = ~0;
11694   u8 is_ipv6 = 0;
11695   int ret;
11696
11697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11698     {
11699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11700         sw_if_index_set = 1;
11701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11702         sw_if_index_set = 1;
11703       else if (unformat (i, "table %d", &table_index))
11704         ;
11705       else
11706         {
11707           clib_warning ("parse error '%U'", format_unformat_error, i);
11708           return -99;
11709         }
11710     }
11711
11712   if (sw_if_index_set == 0)
11713     {
11714       errmsg ("missing interface name or sw_if_index");
11715       return -99;
11716     }
11717
11718
11719   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11720
11721   mp->sw_if_index = ntohl (sw_if_index);
11722   mp->table_index = ntohl (table_index);
11723   mp->is_ipv6 = is_ipv6;
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_classify_set_interface_l2_tables (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_classify_set_interface_l2_tables_t *mp;
11735   u32 sw_if_index;
11736   int sw_if_index_set;
11737   u32 ip4_table_index = ~0;
11738   u32 ip6_table_index = ~0;
11739   u32 other_table_index = ~0;
11740   u32 is_input = 1;
11741   int ret;
11742
11743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11744     {
11745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11746         sw_if_index_set = 1;
11747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11748         sw_if_index_set = 1;
11749       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11750         ;
11751       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11752         ;
11753       else if (unformat (i, "other-table %d", &other_table_index))
11754         ;
11755       else if (unformat (i, "is-input %d", &is_input))
11756         ;
11757       else
11758         {
11759           clib_warning ("parse error '%U'", format_unformat_error, i);
11760           return -99;
11761         }
11762     }
11763
11764   if (sw_if_index_set == 0)
11765     {
11766       errmsg ("missing interface name or sw_if_index");
11767       return -99;
11768     }
11769
11770
11771   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11772
11773   mp->sw_if_index = ntohl (sw_if_index);
11774   mp->ip4_table_index = ntohl (ip4_table_index);
11775   mp->ip6_table_index = ntohl (ip6_table_index);
11776   mp->other_table_index = ntohl (other_table_index);
11777   mp->is_input = (u8) is_input;
11778
11779   S (mp);
11780   W (ret);
11781   return ret;
11782 }
11783
11784 static int
11785 api_set_ipfix_exporter (vat_main_t * vam)
11786 {
11787   unformat_input_t *i = vam->input;
11788   vl_api_set_ipfix_exporter_t *mp;
11789   ip4_address_t collector_address;
11790   u8 collector_address_set = 0;
11791   u32 collector_port = ~0;
11792   ip4_address_t src_address;
11793   u8 src_address_set = 0;
11794   u32 vrf_id = ~0;
11795   u32 path_mtu = ~0;
11796   u32 template_interval = ~0;
11797   u8 udp_checksum = 0;
11798   int ret;
11799
11800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11801     {
11802       if (unformat (i, "collector_address %U", unformat_ip4_address,
11803                     &collector_address))
11804         collector_address_set = 1;
11805       else if (unformat (i, "collector_port %d", &collector_port))
11806         ;
11807       else if (unformat (i, "src_address %U", unformat_ip4_address,
11808                          &src_address))
11809         src_address_set = 1;
11810       else if (unformat (i, "vrf_id %d", &vrf_id))
11811         ;
11812       else if (unformat (i, "path_mtu %d", &path_mtu))
11813         ;
11814       else if (unformat (i, "template_interval %d", &template_interval))
11815         ;
11816       else if (unformat (i, "udp_checksum"))
11817         udp_checksum = 1;
11818       else
11819         break;
11820     }
11821
11822   if (collector_address_set == 0)
11823     {
11824       errmsg ("collector_address required");
11825       return -99;
11826     }
11827
11828   if (src_address_set == 0)
11829     {
11830       errmsg ("src_address required");
11831       return -99;
11832     }
11833
11834   M (SET_IPFIX_EXPORTER, mp);
11835
11836   memcpy (mp->collector_address, collector_address.data,
11837           sizeof (collector_address.data));
11838   mp->collector_port = htons ((u16) collector_port);
11839   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11840   mp->vrf_id = htonl (vrf_id);
11841   mp->path_mtu = htonl (path_mtu);
11842   mp->template_interval = htonl (template_interval);
11843   mp->udp_checksum = udp_checksum;
11844
11845   S (mp);
11846   W (ret);
11847   return ret;
11848 }
11849
11850 static int
11851 api_set_ipfix_classify_stream (vat_main_t * vam)
11852 {
11853   unformat_input_t *i = vam->input;
11854   vl_api_set_ipfix_classify_stream_t *mp;
11855   u32 domain_id = 0;
11856   u32 src_port = UDP_DST_PORT_ipfix;
11857   int ret;
11858
11859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (i, "domain %d", &domain_id))
11862         ;
11863       else if (unformat (i, "src_port %d", &src_port))
11864         ;
11865       else
11866         {
11867           errmsg ("unknown input `%U'", format_unformat_error, i);
11868           return -99;
11869         }
11870     }
11871
11872   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11873
11874   mp->domain_id = htonl (domain_id);
11875   mp->src_port = htons ((u16) src_port);
11876
11877   S (mp);
11878   W (ret);
11879   return ret;
11880 }
11881
11882 static int
11883 api_ipfix_classify_table_add_del (vat_main_t * vam)
11884 {
11885   unformat_input_t *i = vam->input;
11886   vl_api_ipfix_classify_table_add_del_t *mp;
11887   int is_add = -1;
11888   u32 classify_table_index = ~0;
11889   u8 ip_version = 0;
11890   u8 transport_protocol = 255;
11891   int ret;
11892
11893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (i, "add"))
11896         is_add = 1;
11897       else if (unformat (i, "del"))
11898         is_add = 0;
11899       else if (unformat (i, "table %d", &classify_table_index))
11900         ;
11901       else if (unformat (i, "ip4"))
11902         ip_version = 4;
11903       else if (unformat (i, "ip6"))
11904         ip_version = 6;
11905       else if (unformat (i, "tcp"))
11906         transport_protocol = 6;
11907       else if (unformat (i, "udp"))
11908         transport_protocol = 17;
11909       else
11910         {
11911           errmsg ("unknown input `%U'", format_unformat_error, i);
11912           return -99;
11913         }
11914     }
11915
11916   if (is_add == -1)
11917     {
11918       errmsg ("expecting: add|del");
11919       return -99;
11920     }
11921   if (classify_table_index == ~0)
11922     {
11923       errmsg ("classifier table not specified");
11924       return -99;
11925     }
11926   if (ip_version == 0)
11927     {
11928       errmsg ("IP version not specified");
11929       return -99;
11930     }
11931
11932   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11933
11934   mp->is_add = is_add;
11935   mp->table_id = htonl (classify_table_index);
11936   mp->ip_version = ip_version;
11937   mp->transport_protocol = transport_protocol;
11938
11939   S (mp);
11940   W (ret);
11941   return ret;
11942 }
11943
11944 static int
11945 api_get_node_index (vat_main_t * vam)
11946 {
11947   unformat_input_t *i = vam->input;
11948   vl_api_get_node_index_t *mp;
11949   u8 *name = 0;
11950   int ret;
11951
11952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11953     {
11954       if (unformat (i, "node %s", &name))
11955         ;
11956       else
11957         break;
11958     }
11959   if (name == 0)
11960     {
11961       errmsg ("node name required");
11962       return -99;
11963     }
11964   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11965     {
11966       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11967       return -99;
11968     }
11969
11970   M (GET_NODE_INDEX, mp);
11971   clib_memcpy (mp->node_name, name, vec_len (name));
11972   vec_free (name);
11973
11974   S (mp);
11975   W (ret);
11976   return ret;
11977 }
11978
11979 static int
11980 api_get_next_index (vat_main_t * vam)
11981 {
11982   unformat_input_t *i = vam->input;
11983   vl_api_get_next_index_t *mp;
11984   u8 *node_name = 0, *next_node_name = 0;
11985   int ret;
11986
11987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11988     {
11989       if (unformat (i, "node-name %s", &node_name))
11990         ;
11991       else if (unformat (i, "next-node-name %s", &next_node_name))
11992         break;
11993     }
11994
11995   if (node_name == 0)
11996     {
11997       errmsg ("node name required");
11998       return -99;
11999     }
12000   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12001     {
12002       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12003       return -99;
12004     }
12005
12006   if (next_node_name == 0)
12007     {
12008       errmsg ("next node name required");
12009       return -99;
12010     }
12011   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12012     {
12013       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12014       return -99;
12015     }
12016
12017   M (GET_NEXT_INDEX, mp);
12018   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12019   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12020   vec_free (node_name);
12021   vec_free (next_node_name);
12022
12023   S (mp);
12024   W (ret);
12025   return ret;
12026 }
12027
12028 static int
12029 api_add_node_next (vat_main_t * vam)
12030 {
12031   unformat_input_t *i = vam->input;
12032   vl_api_add_node_next_t *mp;
12033   u8 *name = 0;
12034   u8 *next = 0;
12035   int ret;
12036
12037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12038     {
12039       if (unformat (i, "node %s", &name))
12040         ;
12041       else if (unformat (i, "next %s", &next))
12042         ;
12043       else
12044         break;
12045     }
12046   if (name == 0)
12047     {
12048       errmsg ("node name required");
12049       return -99;
12050     }
12051   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12052     {
12053       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12054       return -99;
12055     }
12056   if (next == 0)
12057     {
12058       errmsg ("next node required");
12059       return -99;
12060     }
12061   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12062     {
12063       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12064       return -99;
12065     }
12066
12067   M (ADD_NODE_NEXT, mp);
12068   clib_memcpy (mp->node_name, name, vec_len (name));
12069   clib_memcpy (mp->next_name, next, vec_len (next));
12070   vec_free (name);
12071   vec_free (next);
12072
12073   S (mp);
12074   W (ret);
12075   return ret;
12076 }
12077
12078 static int
12079 api_l2tpv3_create_tunnel (vat_main_t * vam)
12080 {
12081   unformat_input_t *i = vam->input;
12082   ip6_address_t client_address, our_address;
12083   int client_address_set = 0;
12084   int our_address_set = 0;
12085   u32 local_session_id = 0;
12086   u32 remote_session_id = 0;
12087   u64 local_cookie = 0;
12088   u64 remote_cookie = 0;
12089   u8 l2_sublayer_present = 0;
12090   vl_api_l2tpv3_create_tunnel_t *mp;
12091   int ret;
12092
12093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12094     {
12095       if (unformat (i, "client_address %U", unformat_ip6_address,
12096                     &client_address))
12097         client_address_set = 1;
12098       else if (unformat (i, "our_address %U", unformat_ip6_address,
12099                          &our_address))
12100         our_address_set = 1;
12101       else if (unformat (i, "local_session_id %d", &local_session_id))
12102         ;
12103       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12104         ;
12105       else if (unformat (i, "local_cookie %lld", &local_cookie))
12106         ;
12107       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12108         ;
12109       else if (unformat (i, "l2-sublayer-present"))
12110         l2_sublayer_present = 1;
12111       else
12112         break;
12113     }
12114
12115   if (client_address_set == 0)
12116     {
12117       errmsg ("client_address required");
12118       return -99;
12119     }
12120
12121   if (our_address_set == 0)
12122     {
12123       errmsg ("our_address required");
12124       return -99;
12125     }
12126
12127   M (L2TPV3_CREATE_TUNNEL, mp);
12128
12129   clib_memcpy (mp->client_address, client_address.as_u8,
12130                sizeof (mp->client_address));
12131
12132   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12133
12134   mp->local_session_id = ntohl (local_session_id);
12135   mp->remote_session_id = ntohl (remote_session_id);
12136   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12137   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12138   mp->l2_sublayer_present = l2_sublayer_present;
12139   mp->is_ipv6 = 1;
12140
12141   S (mp);
12142   W (ret);
12143   return ret;
12144 }
12145
12146 static int
12147 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12148 {
12149   unformat_input_t *i = vam->input;
12150   u32 sw_if_index;
12151   u8 sw_if_index_set = 0;
12152   u64 new_local_cookie = 0;
12153   u64 new_remote_cookie = 0;
12154   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12155   int ret;
12156
12157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158     {
12159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12160         sw_if_index_set = 1;
12161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12162         sw_if_index_set = 1;
12163       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12164         ;
12165       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12166         ;
12167       else
12168         break;
12169     }
12170
12171   if (sw_if_index_set == 0)
12172     {
12173       errmsg ("missing interface name or sw_if_index");
12174       return -99;
12175     }
12176
12177   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12178
12179   mp->sw_if_index = ntohl (sw_if_index);
12180   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12181   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12182
12183   S (mp);
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static int
12189 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12190 {
12191   unformat_input_t *i = vam->input;
12192   vl_api_l2tpv3_interface_enable_disable_t *mp;
12193   u32 sw_if_index;
12194   u8 sw_if_index_set = 0;
12195   u8 enable_disable = 1;
12196   int ret;
12197
12198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12201         sw_if_index_set = 1;
12202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12203         sw_if_index_set = 1;
12204       else if (unformat (i, "enable"))
12205         enable_disable = 1;
12206       else if (unformat (i, "disable"))
12207         enable_disable = 0;
12208       else
12209         break;
12210     }
12211
12212   if (sw_if_index_set == 0)
12213     {
12214       errmsg ("missing interface name or sw_if_index");
12215       return -99;
12216     }
12217
12218   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12219
12220   mp->sw_if_index = ntohl (sw_if_index);
12221   mp->enable_disable = enable_disable;
12222
12223   S (mp);
12224   W (ret);
12225   return ret;
12226 }
12227
12228 static int
12229 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12230 {
12231   unformat_input_t *i = vam->input;
12232   vl_api_l2tpv3_set_lookup_key_t *mp;
12233   u8 key = ~0;
12234   int ret;
12235
12236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12237     {
12238       if (unformat (i, "lookup_v6_src"))
12239         key = L2T_LOOKUP_SRC_ADDRESS;
12240       else if (unformat (i, "lookup_v6_dst"))
12241         key = L2T_LOOKUP_DST_ADDRESS;
12242       else if (unformat (i, "lookup_session_id"))
12243         key = L2T_LOOKUP_SESSION_ID;
12244       else
12245         break;
12246     }
12247
12248   if (key == (u8) ~ 0)
12249     {
12250       errmsg ("l2tp session lookup key unset");
12251       return -99;
12252     }
12253
12254   M (L2TPV3_SET_LOOKUP_KEY, mp);
12255
12256   mp->key = key;
12257
12258   S (mp);
12259   W (ret);
12260   return ret;
12261 }
12262
12263 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12264   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12265 {
12266   vat_main_t *vam = &vat_main;
12267
12268   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12269          format_ip6_address, mp->our_address,
12270          format_ip6_address, mp->client_address,
12271          clib_net_to_host_u32 (mp->sw_if_index));
12272
12273   print (vam->ofp,
12274          "   local cookies %016llx %016llx remote cookie %016llx",
12275          clib_net_to_host_u64 (mp->local_cookie[0]),
12276          clib_net_to_host_u64 (mp->local_cookie[1]),
12277          clib_net_to_host_u64 (mp->remote_cookie));
12278
12279   print (vam->ofp, "   local session-id %d remote session-id %d",
12280          clib_net_to_host_u32 (mp->local_session_id),
12281          clib_net_to_host_u32 (mp->remote_session_id));
12282
12283   print (vam->ofp, "   l2 specific sublayer %s\n",
12284          mp->l2_sublayer_present ? "preset" : "absent");
12285
12286 }
12287
12288 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12289   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12290 {
12291   vat_main_t *vam = &vat_main;
12292   vat_json_node_t *node = NULL;
12293   struct in6_addr addr;
12294
12295   if (VAT_JSON_ARRAY != vam->json_tree.type)
12296     {
12297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12298       vat_json_init_array (&vam->json_tree);
12299     }
12300   node = vat_json_array_add (&vam->json_tree);
12301
12302   vat_json_init_object (node);
12303
12304   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12305   vat_json_object_add_ip6 (node, "our_address", addr);
12306   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12307   vat_json_object_add_ip6 (node, "client_address", addr);
12308
12309   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12310   vat_json_init_array (lc);
12311   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12312   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12313   vat_json_object_add_uint (node, "remote_cookie",
12314                             clib_net_to_host_u64 (mp->remote_cookie));
12315
12316   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12317   vat_json_object_add_uint (node, "local_session_id",
12318                             clib_net_to_host_u32 (mp->local_session_id));
12319   vat_json_object_add_uint (node, "remote_session_id",
12320                             clib_net_to_host_u32 (mp->remote_session_id));
12321   vat_json_object_add_string_copy (node, "l2_sublayer",
12322                                    mp->l2_sublayer_present ? (u8 *) "present"
12323                                    : (u8 *) "absent");
12324 }
12325
12326 static int
12327 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12328 {
12329   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12330   vl_api_control_ping_t *mp_ping;
12331   int ret;
12332
12333   /* Get list of l2tpv3-tunnel interfaces */
12334   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12335   S (mp);
12336
12337   /* Use a control ping for synchronization */
12338   MPING (CONTROL_PING, mp_ping);
12339   S (mp_ping);
12340
12341   W (ret);
12342   return ret;
12343 }
12344
12345
12346 static void vl_api_sw_interface_tap_details_t_handler
12347   (vl_api_sw_interface_tap_details_t * mp)
12348 {
12349   vat_main_t *vam = &vat_main;
12350
12351   print (vam->ofp, "%-16s %d",
12352          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12353 }
12354
12355 static void vl_api_sw_interface_tap_details_t_handler_json
12356   (vl_api_sw_interface_tap_details_t * mp)
12357 {
12358   vat_main_t *vam = &vat_main;
12359   vat_json_node_t *node = NULL;
12360
12361   if (VAT_JSON_ARRAY != vam->json_tree.type)
12362     {
12363       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12364       vat_json_init_array (&vam->json_tree);
12365     }
12366   node = vat_json_array_add (&vam->json_tree);
12367
12368   vat_json_init_object (node);
12369   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12370   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12371 }
12372
12373 static int
12374 api_sw_interface_tap_dump (vat_main_t * vam)
12375 {
12376   vl_api_sw_interface_tap_dump_t *mp;
12377   vl_api_control_ping_t *mp_ping;
12378   int ret;
12379
12380   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12381   /* Get list of tap interfaces */
12382   M (SW_INTERFACE_TAP_DUMP, mp);
12383   S (mp);
12384
12385   /* Use a control ping for synchronization */
12386   MPING (CONTROL_PING, mp_ping);
12387   S (mp_ping);
12388
12389   W (ret);
12390   return ret;
12391 }
12392
12393 static void vl_api_sw_interface_tap_v2_details_t_handler
12394   (vl_api_sw_interface_tap_v2_details_t * mp)
12395 {
12396   vat_main_t *vam = &vat_main;
12397
12398   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12399                     mp->host_ip4_prefix_len);
12400   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12401                     mp->host_ip6_prefix_len);
12402
12403   print (vam->ofp,
12404          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12405          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12406          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12407          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12408          mp->host_bridge, ip4, ip6);
12409
12410   vec_free (ip4);
12411   vec_free (ip6);
12412 }
12413
12414 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12415   (vl_api_sw_interface_tap_v2_details_t * mp)
12416 {
12417   vat_main_t *vam = &vat_main;
12418   vat_json_node_t *node = NULL;
12419
12420   if (VAT_JSON_ARRAY != vam->json_tree.type)
12421     {
12422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12423       vat_json_init_array (&vam->json_tree);
12424     }
12425   node = vat_json_array_add (&vam->json_tree);
12426
12427   vat_json_init_object (node);
12428   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12429   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12430   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12431   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12432   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12433   vat_json_object_add_string_copy (node, "host_mac_addr",
12434                                    format (0, "%U", format_ethernet_address,
12435                                            &mp->host_mac_addr));
12436   vat_json_object_add_string_copy (node, "host_namespace",
12437                                    mp->host_namespace);
12438   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12439   vat_json_object_add_string_copy (node, "host_ip4_addr",
12440                                    format (0, "%U/%d", format_ip4_address,
12441                                            mp->host_ip4_addr,
12442                                            mp->host_ip4_prefix_len));
12443   vat_json_object_add_string_copy (node, "host_ip6_addr",
12444                                    format (0, "%U/%d", format_ip6_address,
12445                                            mp->host_ip6_addr,
12446                                            mp->host_ip6_prefix_len));
12447
12448 }
12449
12450 static int
12451 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12452 {
12453   vl_api_sw_interface_tap_v2_dump_t *mp;
12454   vl_api_control_ping_t *mp_ping;
12455   int ret;
12456
12457   print (vam->ofp,
12458          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12459          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12460          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12461          "host_ip6_addr");
12462
12463   /* Get list of tap interfaces */
12464   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12465   S (mp);
12466
12467   /* Use a control ping for synchronization */
12468   MPING (CONTROL_PING, mp_ping);
12469   S (mp_ping);
12470
12471   W (ret);
12472   return ret;
12473 }
12474
12475 static uword unformat_vxlan_decap_next
12476   (unformat_input_t * input, va_list * args)
12477 {
12478   u32 *result = va_arg (*args, u32 *);
12479   u32 tmp;
12480
12481   if (unformat (input, "l2"))
12482     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12483   else if (unformat (input, "%d", &tmp))
12484     *result = tmp;
12485   else
12486     return 0;
12487   return 1;
12488 }
12489
12490 static int
12491 api_vxlan_add_del_tunnel (vat_main_t * vam)
12492 {
12493   unformat_input_t *line_input = vam->input;
12494   vl_api_vxlan_add_del_tunnel_t *mp;
12495   ip46_address_t src, dst;
12496   u8 is_add = 1;
12497   u8 ipv4_set = 0, ipv6_set = 0;
12498   u8 src_set = 0;
12499   u8 dst_set = 0;
12500   u8 grp_set = 0;
12501   u32 mcast_sw_if_index = ~0;
12502   u32 encap_vrf_id = 0;
12503   u32 decap_next_index = ~0;
12504   u32 vni = 0;
12505   int ret;
12506
12507   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12508   memset (&src, 0, sizeof src);
12509   memset (&dst, 0, sizeof dst);
12510
12511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (line_input, "del"))
12514         is_add = 0;
12515       else
12516         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12517         {
12518           ipv4_set = 1;
12519           src_set = 1;
12520         }
12521       else
12522         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12523         {
12524           ipv4_set = 1;
12525           dst_set = 1;
12526         }
12527       else
12528         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12529         {
12530           ipv6_set = 1;
12531           src_set = 1;
12532         }
12533       else
12534         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12535         {
12536           ipv6_set = 1;
12537           dst_set = 1;
12538         }
12539       else if (unformat (line_input, "group %U %U",
12540                          unformat_ip4_address, &dst.ip4,
12541                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12542         {
12543           grp_set = dst_set = 1;
12544           ipv4_set = 1;
12545         }
12546       else if (unformat (line_input, "group %U",
12547                          unformat_ip4_address, &dst.ip4))
12548         {
12549           grp_set = dst_set = 1;
12550           ipv4_set = 1;
12551         }
12552       else if (unformat (line_input, "group %U %U",
12553                          unformat_ip6_address, &dst.ip6,
12554                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12555         {
12556           grp_set = dst_set = 1;
12557           ipv6_set = 1;
12558         }
12559       else if (unformat (line_input, "group %U",
12560                          unformat_ip6_address, &dst.ip6))
12561         {
12562           grp_set = dst_set = 1;
12563           ipv6_set = 1;
12564         }
12565       else
12566         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12567         ;
12568       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12569         ;
12570       else if (unformat (line_input, "decap-next %U",
12571                          unformat_vxlan_decap_next, &decap_next_index))
12572         ;
12573       else if (unformat (line_input, "vni %d", &vni))
12574         ;
12575       else
12576         {
12577           errmsg ("parse error '%U'", format_unformat_error, line_input);
12578           return -99;
12579         }
12580     }
12581
12582   if (src_set == 0)
12583     {
12584       errmsg ("tunnel src address not specified");
12585       return -99;
12586     }
12587   if (dst_set == 0)
12588     {
12589       errmsg ("tunnel dst address not specified");
12590       return -99;
12591     }
12592
12593   if (grp_set && !ip46_address_is_multicast (&dst))
12594     {
12595       errmsg ("tunnel group address not multicast");
12596       return -99;
12597     }
12598   if (grp_set && mcast_sw_if_index == ~0)
12599     {
12600       errmsg ("tunnel nonexistent multicast device");
12601       return -99;
12602     }
12603   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12604     {
12605       errmsg ("tunnel dst address must be unicast");
12606       return -99;
12607     }
12608
12609
12610   if (ipv4_set && ipv6_set)
12611     {
12612       errmsg ("both IPv4 and IPv6 addresses specified");
12613       return -99;
12614     }
12615
12616   if ((vni == 0) || (vni >> 24))
12617     {
12618       errmsg ("vni not specified or out of range");
12619       return -99;
12620     }
12621
12622   M (VXLAN_ADD_DEL_TUNNEL, mp);
12623
12624   if (ipv6_set)
12625     {
12626       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12627       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12628     }
12629   else
12630     {
12631       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12632       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12633     }
12634   mp->encap_vrf_id = ntohl (encap_vrf_id);
12635   mp->decap_next_index = ntohl (decap_next_index);
12636   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12637   mp->vni = ntohl (vni);
12638   mp->is_add = is_add;
12639   mp->is_ipv6 = ipv6_set;
12640
12641   S (mp);
12642   W (ret);
12643   return ret;
12644 }
12645
12646 static void vl_api_vxlan_tunnel_details_t_handler
12647   (vl_api_vxlan_tunnel_details_t * mp)
12648 {
12649   vat_main_t *vam = &vat_main;
12650   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12651   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12652
12653   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12654          ntohl (mp->sw_if_index),
12655          format_ip46_address, &src, IP46_TYPE_ANY,
12656          format_ip46_address, &dst, IP46_TYPE_ANY,
12657          ntohl (mp->encap_vrf_id),
12658          ntohl (mp->decap_next_index), ntohl (mp->vni),
12659          ntohl (mp->mcast_sw_if_index));
12660 }
12661
12662 static void vl_api_vxlan_tunnel_details_t_handler_json
12663   (vl_api_vxlan_tunnel_details_t * mp)
12664 {
12665   vat_main_t *vam = &vat_main;
12666   vat_json_node_t *node = NULL;
12667
12668   if (VAT_JSON_ARRAY != vam->json_tree.type)
12669     {
12670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12671       vat_json_init_array (&vam->json_tree);
12672     }
12673   node = vat_json_array_add (&vam->json_tree);
12674
12675   vat_json_init_object (node);
12676   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12677   if (mp->is_ipv6)
12678     {
12679       struct in6_addr ip6;
12680
12681       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12682       vat_json_object_add_ip6 (node, "src_address", ip6);
12683       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12684       vat_json_object_add_ip6 (node, "dst_address", ip6);
12685     }
12686   else
12687     {
12688       struct in_addr ip4;
12689
12690       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12691       vat_json_object_add_ip4 (node, "src_address", ip4);
12692       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12693       vat_json_object_add_ip4 (node, "dst_address", ip4);
12694     }
12695   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12696   vat_json_object_add_uint (node, "decap_next_index",
12697                             ntohl (mp->decap_next_index));
12698   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12699   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12700   vat_json_object_add_uint (node, "mcast_sw_if_index",
12701                             ntohl (mp->mcast_sw_if_index));
12702 }
12703
12704 static int
12705 api_vxlan_tunnel_dump (vat_main_t * vam)
12706 {
12707   unformat_input_t *i = vam->input;
12708   vl_api_vxlan_tunnel_dump_t *mp;
12709   vl_api_control_ping_t *mp_ping;
12710   u32 sw_if_index;
12711   u8 sw_if_index_set = 0;
12712   int ret;
12713
12714   /* Parse args required to build the message */
12715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12716     {
12717       if (unformat (i, "sw_if_index %d", &sw_if_index))
12718         sw_if_index_set = 1;
12719       else
12720         break;
12721     }
12722
12723   if (sw_if_index_set == 0)
12724     {
12725       sw_if_index = ~0;
12726     }
12727
12728   if (!vam->json_output)
12729     {
12730       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12731              "sw_if_index", "src_address", "dst_address",
12732              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12733     }
12734
12735   /* Get list of vxlan-tunnel interfaces */
12736   M (VXLAN_TUNNEL_DUMP, mp);
12737
12738   mp->sw_if_index = htonl (sw_if_index);
12739
12740   S (mp);
12741
12742   /* Use a control ping for synchronization */
12743   MPING (CONTROL_PING, mp_ping);
12744   S (mp_ping);
12745
12746   W (ret);
12747   return ret;
12748 }
12749
12750 static uword unformat_geneve_decap_next
12751   (unformat_input_t * input, va_list * args)
12752 {
12753   u32 *result = va_arg (*args, u32 *);
12754   u32 tmp;
12755
12756   if (unformat (input, "l2"))
12757     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12758   else if (unformat (input, "%d", &tmp))
12759     *result = tmp;
12760   else
12761     return 0;
12762   return 1;
12763 }
12764
12765 static int
12766 api_geneve_add_del_tunnel (vat_main_t * vam)
12767 {
12768   unformat_input_t *line_input = vam->input;
12769   vl_api_geneve_add_del_tunnel_t *mp;
12770   ip46_address_t src, dst;
12771   u8 is_add = 1;
12772   u8 ipv4_set = 0, ipv6_set = 0;
12773   u8 src_set = 0;
12774   u8 dst_set = 0;
12775   u8 grp_set = 0;
12776   u32 mcast_sw_if_index = ~0;
12777   u32 encap_vrf_id = 0;
12778   u32 decap_next_index = ~0;
12779   u32 vni = 0;
12780   int ret;
12781
12782   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12783   memset (&src, 0, sizeof src);
12784   memset (&dst, 0, sizeof dst);
12785
12786   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12787     {
12788       if (unformat (line_input, "del"))
12789         is_add = 0;
12790       else
12791         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12792         {
12793           ipv4_set = 1;
12794           src_set = 1;
12795         }
12796       else
12797         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12798         {
12799           ipv4_set = 1;
12800           dst_set = 1;
12801         }
12802       else
12803         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12804         {
12805           ipv6_set = 1;
12806           src_set = 1;
12807         }
12808       else
12809         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12810         {
12811           ipv6_set = 1;
12812           dst_set = 1;
12813         }
12814       else if (unformat (line_input, "group %U %U",
12815                          unformat_ip4_address, &dst.ip4,
12816                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12817         {
12818           grp_set = dst_set = 1;
12819           ipv4_set = 1;
12820         }
12821       else if (unformat (line_input, "group %U",
12822                          unformat_ip4_address, &dst.ip4))
12823         {
12824           grp_set = dst_set = 1;
12825           ipv4_set = 1;
12826         }
12827       else if (unformat (line_input, "group %U %U",
12828                          unformat_ip6_address, &dst.ip6,
12829                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12830         {
12831           grp_set = dst_set = 1;
12832           ipv6_set = 1;
12833         }
12834       else if (unformat (line_input, "group %U",
12835                          unformat_ip6_address, &dst.ip6))
12836         {
12837           grp_set = dst_set = 1;
12838           ipv6_set = 1;
12839         }
12840       else
12841         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12842         ;
12843       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12844         ;
12845       else if (unformat (line_input, "decap-next %U",
12846                          unformat_geneve_decap_next, &decap_next_index))
12847         ;
12848       else if (unformat (line_input, "vni %d", &vni))
12849         ;
12850       else
12851         {
12852           errmsg ("parse error '%U'", format_unformat_error, line_input);
12853           return -99;
12854         }
12855     }
12856
12857   if (src_set == 0)
12858     {
12859       errmsg ("tunnel src address not specified");
12860       return -99;
12861     }
12862   if (dst_set == 0)
12863     {
12864       errmsg ("tunnel dst address not specified");
12865       return -99;
12866     }
12867
12868   if (grp_set && !ip46_address_is_multicast (&dst))
12869     {
12870       errmsg ("tunnel group address not multicast");
12871       return -99;
12872     }
12873   if (grp_set && mcast_sw_if_index == ~0)
12874     {
12875       errmsg ("tunnel nonexistent multicast device");
12876       return -99;
12877     }
12878   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12879     {
12880       errmsg ("tunnel dst address must be unicast");
12881       return -99;
12882     }
12883
12884
12885   if (ipv4_set && ipv6_set)
12886     {
12887       errmsg ("both IPv4 and IPv6 addresses specified");
12888       return -99;
12889     }
12890
12891   if ((vni == 0) || (vni >> 24))
12892     {
12893       errmsg ("vni not specified or out of range");
12894       return -99;
12895     }
12896
12897   M (GENEVE_ADD_DEL_TUNNEL, mp);
12898
12899   if (ipv6_set)
12900     {
12901       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12902       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12903     }
12904   else
12905     {
12906       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12907       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12908     }
12909   mp->encap_vrf_id = ntohl (encap_vrf_id);
12910   mp->decap_next_index = ntohl (decap_next_index);
12911   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12912   mp->vni = ntohl (vni);
12913   mp->is_add = is_add;
12914   mp->is_ipv6 = ipv6_set;
12915
12916   S (mp);
12917   W (ret);
12918   return ret;
12919 }
12920
12921 static void vl_api_geneve_tunnel_details_t_handler
12922   (vl_api_geneve_tunnel_details_t * mp)
12923 {
12924   vat_main_t *vam = &vat_main;
12925   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12926   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12927
12928   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12929          ntohl (mp->sw_if_index),
12930          format_ip46_address, &src, IP46_TYPE_ANY,
12931          format_ip46_address, &dst, IP46_TYPE_ANY,
12932          ntohl (mp->encap_vrf_id),
12933          ntohl (mp->decap_next_index), ntohl (mp->vni),
12934          ntohl (mp->mcast_sw_if_index));
12935 }
12936
12937 static void vl_api_geneve_tunnel_details_t_handler_json
12938   (vl_api_geneve_tunnel_details_t * mp)
12939 {
12940   vat_main_t *vam = &vat_main;
12941   vat_json_node_t *node = NULL;
12942
12943   if (VAT_JSON_ARRAY != vam->json_tree.type)
12944     {
12945       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12946       vat_json_init_array (&vam->json_tree);
12947     }
12948   node = vat_json_array_add (&vam->json_tree);
12949
12950   vat_json_init_object (node);
12951   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12952   if (mp->is_ipv6)
12953     {
12954       struct in6_addr ip6;
12955
12956       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12957       vat_json_object_add_ip6 (node, "src_address", ip6);
12958       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12959       vat_json_object_add_ip6 (node, "dst_address", ip6);
12960     }
12961   else
12962     {
12963       struct in_addr ip4;
12964
12965       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12966       vat_json_object_add_ip4 (node, "src_address", ip4);
12967       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12968       vat_json_object_add_ip4 (node, "dst_address", ip4);
12969     }
12970   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12971   vat_json_object_add_uint (node, "decap_next_index",
12972                             ntohl (mp->decap_next_index));
12973   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12974   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12975   vat_json_object_add_uint (node, "mcast_sw_if_index",
12976                             ntohl (mp->mcast_sw_if_index));
12977 }
12978
12979 static int
12980 api_geneve_tunnel_dump (vat_main_t * vam)
12981 {
12982   unformat_input_t *i = vam->input;
12983   vl_api_geneve_tunnel_dump_t *mp;
12984   vl_api_control_ping_t *mp_ping;
12985   u32 sw_if_index;
12986   u8 sw_if_index_set = 0;
12987   int ret;
12988
12989   /* Parse args required to build the message */
12990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12991     {
12992       if (unformat (i, "sw_if_index %d", &sw_if_index))
12993         sw_if_index_set = 1;
12994       else
12995         break;
12996     }
12997
12998   if (sw_if_index_set == 0)
12999     {
13000       sw_if_index = ~0;
13001     }
13002
13003   if (!vam->json_output)
13004     {
13005       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13006              "sw_if_index", "local_address", "remote_address",
13007              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13008     }
13009
13010   /* Get list of geneve-tunnel interfaces */
13011   M (GENEVE_TUNNEL_DUMP, mp);
13012
13013   mp->sw_if_index = htonl (sw_if_index);
13014
13015   S (mp);
13016
13017   /* Use a control ping for synchronization */
13018   M (CONTROL_PING, mp_ping);
13019   S (mp_ping);
13020
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static int
13026 api_gre_add_del_tunnel (vat_main_t * vam)
13027 {
13028   unformat_input_t *line_input = vam->input;
13029   vl_api_gre_add_del_tunnel_t *mp;
13030   ip4_address_t src4, dst4;
13031   ip6_address_t src6, dst6;
13032   u8 is_add = 1;
13033   u8 ipv4_set = 0;
13034   u8 ipv6_set = 0;
13035   u8 teb = 0;
13036   u8 src_set = 0;
13037   u8 dst_set = 0;
13038   u32 outer_fib_id = 0;
13039   int ret;
13040
13041   memset (&src4, 0, sizeof src4);
13042   memset (&dst4, 0, sizeof dst4);
13043   memset (&src6, 0, sizeof src6);
13044   memset (&dst6, 0, sizeof dst6);
13045
13046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13047     {
13048       if (unformat (line_input, "del"))
13049         is_add = 0;
13050       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13051         {
13052           src_set = 1;
13053           ipv4_set = 1;
13054         }
13055       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13056         {
13057           dst_set = 1;
13058           ipv4_set = 1;
13059         }
13060       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13061         {
13062           src_set = 1;
13063           ipv6_set = 1;
13064         }
13065       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13066         {
13067           dst_set = 1;
13068           ipv6_set = 1;
13069         }
13070       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13071         ;
13072       else if (unformat (line_input, "teb"))
13073         teb = 1;
13074       else
13075         {
13076           errmsg ("parse error '%U'", format_unformat_error, line_input);
13077           return -99;
13078         }
13079     }
13080
13081   if (src_set == 0)
13082     {
13083       errmsg ("tunnel src address not specified");
13084       return -99;
13085     }
13086   if (dst_set == 0)
13087     {
13088       errmsg ("tunnel dst address not specified");
13089       return -99;
13090     }
13091   if (ipv4_set && ipv6_set)
13092     {
13093       errmsg ("both IPv4 and IPv6 addresses specified");
13094       return -99;
13095     }
13096
13097
13098   M (GRE_ADD_DEL_TUNNEL, mp);
13099
13100   if (ipv4_set)
13101     {
13102       clib_memcpy (&mp->src_address, &src4, 4);
13103       clib_memcpy (&mp->dst_address, &dst4, 4);
13104     }
13105   else
13106     {
13107       clib_memcpy (&mp->src_address, &src6, 16);
13108       clib_memcpy (&mp->dst_address, &dst6, 16);
13109     }
13110   mp->outer_fib_id = ntohl (outer_fib_id);
13111   mp->is_add = is_add;
13112   mp->teb = teb;
13113   mp->is_ipv6 = ipv6_set;
13114
13115   S (mp);
13116   W (ret);
13117   return ret;
13118 }
13119
13120 static void vl_api_gre_tunnel_details_t_handler
13121   (vl_api_gre_tunnel_details_t * mp)
13122 {
13123   vat_main_t *vam = &vat_main;
13124   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13125   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13126
13127   print (vam->ofp, "%11d%24U%24U%6d%14d",
13128          ntohl (mp->sw_if_index),
13129          format_ip46_address, &src, IP46_TYPE_ANY,
13130          format_ip46_address, &dst, IP46_TYPE_ANY,
13131          mp->teb, ntohl (mp->outer_fib_id));
13132 }
13133
13134 static void vl_api_gre_tunnel_details_t_handler_json
13135   (vl_api_gre_tunnel_details_t * mp)
13136 {
13137   vat_main_t *vam = &vat_main;
13138   vat_json_node_t *node = NULL;
13139   struct in_addr ip4;
13140   struct in6_addr ip6;
13141
13142   if (VAT_JSON_ARRAY != vam->json_tree.type)
13143     {
13144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13145       vat_json_init_array (&vam->json_tree);
13146     }
13147   node = vat_json_array_add (&vam->json_tree);
13148
13149   vat_json_init_object (node);
13150   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13151   if (!mp->is_ipv6)
13152     {
13153       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13154       vat_json_object_add_ip4 (node, "src_address", ip4);
13155       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13156       vat_json_object_add_ip4 (node, "dst_address", ip4);
13157     }
13158   else
13159     {
13160       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13161       vat_json_object_add_ip6 (node, "src_address", ip6);
13162       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13163       vat_json_object_add_ip6 (node, "dst_address", ip6);
13164     }
13165   vat_json_object_add_uint (node, "teb", mp->teb);
13166   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13167   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13168 }
13169
13170 static int
13171 api_gre_tunnel_dump (vat_main_t * vam)
13172 {
13173   unformat_input_t *i = vam->input;
13174   vl_api_gre_tunnel_dump_t *mp;
13175   vl_api_control_ping_t *mp_ping;
13176   u32 sw_if_index;
13177   u8 sw_if_index_set = 0;
13178   int ret;
13179
13180   /* Parse args required to build the message */
13181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13182     {
13183       if (unformat (i, "sw_if_index %d", &sw_if_index))
13184         sw_if_index_set = 1;
13185       else
13186         break;
13187     }
13188
13189   if (sw_if_index_set == 0)
13190     {
13191       sw_if_index = ~0;
13192     }
13193
13194   if (!vam->json_output)
13195     {
13196       print (vam->ofp, "%11s%24s%24s%6s%14s",
13197              "sw_if_index", "src_address", "dst_address", "teb",
13198              "outer_fib_id");
13199     }
13200
13201   /* Get list of gre-tunnel interfaces */
13202   M (GRE_TUNNEL_DUMP, mp);
13203
13204   mp->sw_if_index = htonl (sw_if_index);
13205
13206   S (mp);
13207
13208   /* Use a control ping for synchronization */
13209   MPING (CONTROL_PING, mp_ping);
13210   S (mp_ping);
13211
13212   W (ret);
13213   return ret;
13214 }
13215
13216 static int
13217 api_l2_fib_clear_table (vat_main_t * vam)
13218 {
13219 //  unformat_input_t * i = vam->input;
13220   vl_api_l2_fib_clear_table_t *mp;
13221   int ret;
13222
13223   M (L2_FIB_CLEAR_TABLE, mp);
13224
13225   S (mp);
13226   W (ret);
13227   return ret;
13228 }
13229
13230 static int
13231 api_l2_interface_efp_filter (vat_main_t * vam)
13232 {
13233   unformat_input_t *i = vam->input;
13234   vl_api_l2_interface_efp_filter_t *mp;
13235   u32 sw_if_index;
13236   u8 enable = 1;
13237   u8 sw_if_index_set = 0;
13238   int ret;
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13243         sw_if_index_set = 1;
13244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13245         sw_if_index_set = 1;
13246       else if (unformat (i, "enable"))
13247         enable = 1;
13248       else if (unformat (i, "disable"))
13249         enable = 0;
13250       else
13251         {
13252           clib_warning ("parse error '%U'", format_unformat_error, i);
13253           return -99;
13254         }
13255     }
13256
13257   if (sw_if_index_set == 0)
13258     {
13259       errmsg ("missing sw_if_index");
13260       return -99;
13261     }
13262
13263   M (L2_INTERFACE_EFP_FILTER, mp);
13264
13265   mp->sw_if_index = ntohl (sw_if_index);
13266   mp->enable_disable = enable;
13267
13268   S (mp);
13269   W (ret);
13270   return ret;
13271 }
13272
13273 #define foreach_vtr_op                          \
13274 _("disable",  L2_VTR_DISABLED)                  \
13275 _("push-1",  L2_VTR_PUSH_1)                     \
13276 _("push-2",  L2_VTR_PUSH_2)                     \
13277 _("pop-1",  L2_VTR_POP_1)                       \
13278 _("pop-2",  L2_VTR_POP_2)                       \
13279 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13280 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13281 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13282 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13283
13284 static int
13285 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13286 {
13287   unformat_input_t *i = vam->input;
13288   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13289   u32 sw_if_index;
13290   u8 sw_if_index_set = 0;
13291   u8 vtr_op_set = 0;
13292   u32 vtr_op = 0;
13293   u32 push_dot1q = 1;
13294   u32 tag1 = ~0;
13295   u32 tag2 = ~0;
13296   int ret;
13297
13298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13299     {
13300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13301         sw_if_index_set = 1;
13302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13303         sw_if_index_set = 1;
13304       else if (unformat (i, "vtr_op %d", &vtr_op))
13305         vtr_op_set = 1;
13306 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13307       foreach_vtr_op
13308 #undef _
13309         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13310         ;
13311       else if (unformat (i, "tag1 %d", &tag1))
13312         ;
13313       else if (unformat (i, "tag2 %d", &tag2))
13314         ;
13315       else
13316         {
13317           clib_warning ("parse error '%U'", format_unformat_error, i);
13318           return -99;
13319         }
13320     }
13321
13322   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13323     {
13324       errmsg ("missing vtr operation or sw_if_index");
13325       return -99;
13326     }
13327
13328   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13329   mp->sw_if_index = ntohl (sw_if_index);
13330   mp->vtr_op = ntohl (vtr_op);
13331   mp->push_dot1q = ntohl (push_dot1q);
13332   mp->tag1 = ntohl (tag1);
13333   mp->tag2 = ntohl (tag2);
13334
13335   S (mp);
13336   W (ret);
13337   return ret;
13338 }
13339
13340 static int
13341 api_create_vhost_user_if (vat_main_t * vam)
13342 {
13343   unformat_input_t *i = vam->input;
13344   vl_api_create_vhost_user_if_t *mp;
13345   u8 *file_name;
13346   u8 is_server = 0;
13347   u8 file_name_set = 0;
13348   u32 custom_dev_instance = ~0;
13349   u8 hwaddr[6];
13350   u8 use_custom_mac = 0;
13351   u8 *tag = 0;
13352   int ret;
13353
13354   /* Shut up coverity */
13355   memset (hwaddr, 0, sizeof (hwaddr));
13356
13357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13358     {
13359       if (unformat (i, "socket %s", &file_name))
13360         {
13361           file_name_set = 1;
13362         }
13363       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13364         ;
13365       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13366         use_custom_mac = 1;
13367       else if (unformat (i, "server"))
13368         is_server = 1;
13369       else if (unformat (i, "tag %s", &tag))
13370         ;
13371       else
13372         break;
13373     }
13374
13375   if (file_name_set == 0)
13376     {
13377       errmsg ("missing socket file name");
13378       return -99;
13379     }
13380
13381   if (vec_len (file_name) > 255)
13382     {
13383       errmsg ("socket file name too long");
13384       return -99;
13385     }
13386   vec_add1 (file_name, 0);
13387
13388   M (CREATE_VHOST_USER_IF, mp);
13389
13390   mp->is_server = is_server;
13391   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13392   vec_free (file_name);
13393   if (custom_dev_instance != ~0)
13394     {
13395       mp->renumber = 1;
13396       mp->custom_dev_instance = ntohl (custom_dev_instance);
13397     }
13398   mp->use_custom_mac = use_custom_mac;
13399   clib_memcpy (mp->mac_address, hwaddr, 6);
13400   if (tag)
13401     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13402   vec_free (tag);
13403
13404   S (mp);
13405   W (ret);
13406   return ret;
13407 }
13408
13409 static int
13410 api_modify_vhost_user_if (vat_main_t * vam)
13411 {
13412   unformat_input_t *i = vam->input;
13413   vl_api_modify_vhost_user_if_t *mp;
13414   u8 *file_name;
13415   u8 is_server = 0;
13416   u8 file_name_set = 0;
13417   u32 custom_dev_instance = ~0;
13418   u8 sw_if_index_set = 0;
13419   u32 sw_if_index = (u32) ~ 0;
13420   int ret;
13421
13422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13423     {
13424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13425         sw_if_index_set = 1;
13426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13427         sw_if_index_set = 1;
13428       else if (unformat (i, "socket %s", &file_name))
13429         {
13430           file_name_set = 1;
13431         }
13432       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13433         ;
13434       else if (unformat (i, "server"))
13435         is_server = 1;
13436       else
13437         break;
13438     }
13439
13440   if (sw_if_index_set == 0)
13441     {
13442       errmsg ("missing sw_if_index or interface name");
13443       return -99;
13444     }
13445
13446   if (file_name_set == 0)
13447     {
13448       errmsg ("missing socket file name");
13449       return -99;
13450     }
13451
13452   if (vec_len (file_name) > 255)
13453     {
13454       errmsg ("socket file name too long");
13455       return -99;
13456     }
13457   vec_add1 (file_name, 0);
13458
13459   M (MODIFY_VHOST_USER_IF, mp);
13460
13461   mp->sw_if_index = ntohl (sw_if_index);
13462   mp->is_server = is_server;
13463   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13464   vec_free (file_name);
13465   if (custom_dev_instance != ~0)
13466     {
13467       mp->renumber = 1;
13468       mp->custom_dev_instance = ntohl (custom_dev_instance);
13469     }
13470
13471   S (mp);
13472   W (ret);
13473   return ret;
13474 }
13475
13476 static int
13477 api_delete_vhost_user_if (vat_main_t * vam)
13478 {
13479   unformat_input_t *i = vam->input;
13480   vl_api_delete_vhost_user_if_t *mp;
13481   u32 sw_if_index = ~0;
13482   u8 sw_if_index_set = 0;
13483   int ret;
13484
13485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13486     {
13487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13488         sw_if_index_set = 1;
13489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13490         sw_if_index_set = 1;
13491       else
13492         break;
13493     }
13494
13495   if (sw_if_index_set == 0)
13496     {
13497       errmsg ("missing sw_if_index or interface name");
13498       return -99;
13499     }
13500
13501
13502   M (DELETE_VHOST_USER_IF, mp);
13503
13504   mp->sw_if_index = ntohl (sw_if_index);
13505
13506   S (mp);
13507   W (ret);
13508   return ret;
13509 }
13510
13511 static void vl_api_sw_interface_vhost_user_details_t_handler
13512   (vl_api_sw_interface_vhost_user_details_t * mp)
13513 {
13514   vat_main_t *vam = &vat_main;
13515
13516   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13517          (char *) mp->interface_name,
13518          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13519          clib_net_to_host_u64 (mp->features), mp->is_server,
13520          ntohl (mp->num_regions), (char *) mp->sock_filename);
13521   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13522 }
13523
13524 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13525   (vl_api_sw_interface_vhost_user_details_t * mp)
13526 {
13527   vat_main_t *vam = &vat_main;
13528   vat_json_node_t *node = NULL;
13529
13530   if (VAT_JSON_ARRAY != vam->json_tree.type)
13531     {
13532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13533       vat_json_init_array (&vam->json_tree);
13534     }
13535   node = vat_json_array_add (&vam->json_tree);
13536
13537   vat_json_init_object (node);
13538   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13539   vat_json_object_add_string_copy (node, "interface_name",
13540                                    mp->interface_name);
13541   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13542                             ntohl (mp->virtio_net_hdr_sz));
13543   vat_json_object_add_uint (node, "features",
13544                             clib_net_to_host_u64 (mp->features));
13545   vat_json_object_add_uint (node, "is_server", mp->is_server);
13546   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13547   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13548   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13549 }
13550
13551 static int
13552 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13553 {
13554   vl_api_sw_interface_vhost_user_dump_t *mp;
13555   vl_api_control_ping_t *mp_ping;
13556   int ret;
13557   print (vam->ofp,
13558          "Interface name            idx hdr_sz features server regions filename");
13559
13560   /* Get list of vhost-user interfaces */
13561   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13562   S (mp);
13563
13564   /* Use a control ping for synchronization */
13565   MPING (CONTROL_PING, mp_ping);
13566   S (mp_ping);
13567
13568   W (ret);
13569   return ret;
13570 }
13571
13572 static int
13573 api_show_version (vat_main_t * vam)
13574 {
13575   vl_api_show_version_t *mp;
13576   int ret;
13577
13578   M (SHOW_VERSION, mp);
13579
13580   S (mp);
13581   W (ret);
13582   return ret;
13583 }
13584
13585
13586 static int
13587 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13588 {
13589   unformat_input_t *line_input = vam->input;
13590   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13591   ip4_address_t local4, remote4;
13592   ip6_address_t local6, remote6;
13593   u8 is_add = 1;
13594   u8 ipv4_set = 0, ipv6_set = 0;
13595   u8 local_set = 0;
13596   u8 remote_set = 0;
13597   u8 grp_set = 0;
13598   u32 mcast_sw_if_index = ~0;
13599   u32 encap_vrf_id = 0;
13600   u32 decap_vrf_id = 0;
13601   u8 protocol = ~0;
13602   u32 vni;
13603   u8 vni_set = 0;
13604   int ret;
13605
13606   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13607   memset (&local4, 0, sizeof local4);
13608   memset (&remote4, 0, sizeof remote4);
13609   memset (&local6, 0, sizeof local6);
13610   memset (&remote6, 0, sizeof remote6);
13611
13612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13613     {
13614       if (unformat (line_input, "del"))
13615         is_add = 0;
13616       else if (unformat (line_input, "local %U",
13617                          unformat_ip4_address, &local4))
13618         {
13619           local_set = 1;
13620           ipv4_set = 1;
13621         }
13622       else if (unformat (line_input, "remote %U",
13623                          unformat_ip4_address, &remote4))
13624         {
13625           remote_set = 1;
13626           ipv4_set = 1;
13627         }
13628       else if (unformat (line_input, "local %U",
13629                          unformat_ip6_address, &local6))
13630         {
13631           local_set = 1;
13632           ipv6_set = 1;
13633         }
13634       else if (unformat (line_input, "remote %U",
13635                          unformat_ip6_address, &remote6))
13636         {
13637           remote_set = 1;
13638           ipv6_set = 1;
13639         }
13640       else if (unformat (line_input, "group %U %U",
13641                          unformat_ip4_address, &remote4,
13642                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13643         {
13644           grp_set = remote_set = 1;
13645           ipv4_set = 1;
13646         }
13647       else if (unformat (line_input, "group %U",
13648                          unformat_ip4_address, &remote4))
13649         {
13650           grp_set = remote_set = 1;
13651           ipv4_set = 1;
13652         }
13653       else if (unformat (line_input, "group %U %U",
13654                          unformat_ip6_address, &remote6,
13655                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13656         {
13657           grp_set = remote_set = 1;
13658           ipv6_set = 1;
13659         }
13660       else if (unformat (line_input, "group %U",
13661                          unformat_ip6_address, &remote6))
13662         {
13663           grp_set = remote_set = 1;
13664           ipv6_set = 1;
13665         }
13666       else
13667         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13668         ;
13669       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13670         ;
13671       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13672         ;
13673       else if (unformat (line_input, "vni %d", &vni))
13674         vni_set = 1;
13675       else if (unformat (line_input, "next-ip4"))
13676         protocol = 1;
13677       else if (unformat (line_input, "next-ip6"))
13678         protocol = 2;
13679       else if (unformat (line_input, "next-ethernet"))
13680         protocol = 3;
13681       else if (unformat (line_input, "next-nsh"))
13682         protocol = 4;
13683       else
13684         {
13685           errmsg ("parse error '%U'", format_unformat_error, line_input);
13686           return -99;
13687         }
13688     }
13689
13690   if (local_set == 0)
13691     {
13692       errmsg ("tunnel local address not specified");
13693       return -99;
13694     }
13695   if (remote_set == 0)
13696     {
13697       errmsg ("tunnel remote address not specified");
13698       return -99;
13699     }
13700   if (grp_set && mcast_sw_if_index == ~0)
13701     {
13702       errmsg ("tunnel nonexistent multicast device");
13703       return -99;
13704     }
13705   if (ipv4_set && ipv6_set)
13706     {
13707       errmsg ("both IPv4 and IPv6 addresses specified");
13708       return -99;
13709     }
13710
13711   if (vni_set == 0)
13712     {
13713       errmsg ("vni not specified");
13714       return -99;
13715     }
13716
13717   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13718
13719
13720   if (ipv6_set)
13721     {
13722       clib_memcpy (&mp->local, &local6, sizeof (local6));
13723       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13724     }
13725   else
13726     {
13727       clib_memcpy (&mp->local, &local4, sizeof (local4));
13728       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13729     }
13730
13731   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13732   mp->encap_vrf_id = ntohl (encap_vrf_id);
13733   mp->decap_vrf_id = ntohl (decap_vrf_id);
13734   mp->protocol = protocol;
13735   mp->vni = ntohl (vni);
13736   mp->is_add = is_add;
13737   mp->is_ipv6 = ipv6_set;
13738
13739   S (mp);
13740   W (ret);
13741   return ret;
13742 }
13743
13744 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13745   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13746 {
13747   vat_main_t *vam = &vat_main;
13748   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13749   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13750
13751   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13752          ntohl (mp->sw_if_index),
13753          format_ip46_address, &local, IP46_TYPE_ANY,
13754          format_ip46_address, &remote, IP46_TYPE_ANY,
13755          ntohl (mp->vni), mp->protocol,
13756          ntohl (mp->mcast_sw_if_index),
13757          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13758 }
13759
13760
13761 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13762   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13763 {
13764   vat_main_t *vam = &vat_main;
13765   vat_json_node_t *node = NULL;
13766   struct in_addr ip4;
13767   struct in6_addr ip6;
13768
13769   if (VAT_JSON_ARRAY != vam->json_tree.type)
13770     {
13771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13772       vat_json_init_array (&vam->json_tree);
13773     }
13774   node = vat_json_array_add (&vam->json_tree);
13775
13776   vat_json_init_object (node);
13777   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13778   if (mp->is_ipv6)
13779     {
13780       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13781       vat_json_object_add_ip6 (node, "local", ip6);
13782       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13783       vat_json_object_add_ip6 (node, "remote", ip6);
13784     }
13785   else
13786     {
13787       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13788       vat_json_object_add_ip4 (node, "local", ip4);
13789       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13790       vat_json_object_add_ip4 (node, "remote", ip4);
13791     }
13792   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13793   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13794   vat_json_object_add_uint (node, "mcast_sw_if_index",
13795                             ntohl (mp->mcast_sw_if_index));
13796   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13797   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13798   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13799 }
13800
13801 static int
13802 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13803 {
13804   unformat_input_t *i = vam->input;
13805   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13806   vl_api_control_ping_t *mp_ping;
13807   u32 sw_if_index;
13808   u8 sw_if_index_set = 0;
13809   int ret;
13810
13811   /* Parse args required to build the message */
13812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13813     {
13814       if (unformat (i, "sw_if_index %d", &sw_if_index))
13815         sw_if_index_set = 1;
13816       else
13817         break;
13818     }
13819
13820   if (sw_if_index_set == 0)
13821     {
13822       sw_if_index = ~0;
13823     }
13824
13825   if (!vam->json_output)
13826     {
13827       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13828              "sw_if_index", "local", "remote", "vni",
13829              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13830     }
13831
13832   /* Get list of vxlan-tunnel interfaces */
13833   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13834
13835   mp->sw_if_index = htonl (sw_if_index);
13836
13837   S (mp);
13838
13839   /* Use a control ping for synchronization */
13840   MPING (CONTROL_PING, mp_ping);
13841   S (mp_ping);
13842
13843   W (ret);
13844   return ret;
13845 }
13846
13847 static void vl_api_l2_fib_table_details_t_handler
13848   (vl_api_l2_fib_table_details_t * mp)
13849 {
13850   vat_main_t *vam = &vat_main;
13851
13852   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13853          "       %d       %d     %d",
13854          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13855          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13856          mp->bvi_mac);
13857 }
13858
13859 static void vl_api_l2_fib_table_details_t_handler_json
13860   (vl_api_l2_fib_table_details_t * mp)
13861 {
13862   vat_main_t *vam = &vat_main;
13863   vat_json_node_t *node = NULL;
13864
13865   if (VAT_JSON_ARRAY != vam->json_tree.type)
13866     {
13867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13868       vat_json_init_array (&vam->json_tree);
13869     }
13870   node = vat_json_array_add (&vam->json_tree);
13871
13872   vat_json_init_object (node);
13873   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13874   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13875   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13876   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13877   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13878   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13879 }
13880
13881 static int
13882 api_l2_fib_table_dump (vat_main_t * vam)
13883 {
13884   unformat_input_t *i = vam->input;
13885   vl_api_l2_fib_table_dump_t *mp;
13886   vl_api_control_ping_t *mp_ping;
13887   u32 bd_id;
13888   u8 bd_id_set = 0;
13889   int ret;
13890
13891   /* Parse args required to build the message */
13892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13893     {
13894       if (unformat (i, "bd_id %d", &bd_id))
13895         bd_id_set = 1;
13896       else
13897         break;
13898     }
13899
13900   if (bd_id_set == 0)
13901     {
13902       errmsg ("missing bridge domain");
13903       return -99;
13904     }
13905
13906   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13907
13908   /* Get list of l2 fib entries */
13909   M (L2_FIB_TABLE_DUMP, mp);
13910
13911   mp->bd_id = ntohl (bd_id);
13912   S (mp);
13913
13914   /* Use a control ping for synchronization */
13915   MPING (CONTROL_PING, mp_ping);
13916   S (mp_ping);
13917
13918   W (ret);
13919   return ret;
13920 }
13921
13922
13923 static int
13924 api_interface_name_renumber (vat_main_t * vam)
13925 {
13926   unformat_input_t *line_input = vam->input;
13927   vl_api_interface_name_renumber_t *mp;
13928   u32 sw_if_index = ~0;
13929   u32 new_show_dev_instance = ~0;
13930   int ret;
13931
13932   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13933     {
13934       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13935                     &sw_if_index))
13936         ;
13937       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13938         ;
13939       else if (unformat (line_input, "new_show_dev_instance %d",
13940                          &new_show_dev_instance))
13941         ;
13942       else
13943         break;
13944     }
13945
13946   if (sw_if_index == ~0)
13947     {
13948       errmsg ("missing interface name or sw_if_index");
13949       return -99;
13950     }
13951
13952   if (new_show_dev_instance == ~0)
13953     {
13954       errmsg ("missing new_show_dev_instance");
13955       return -99;
13956     }
13957
13958   M (INTERFACE_NAME_RENUMBER, mp);
13959
13960   mp->sw_if_index = ntohl (sw_if_index);
13961   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13962
13963   S (mp);
13964   W (ret);
13965   return ret;
13966 }
13967
13968 static int
13969 api_want_ip4_arp_events (vat_main_t * vam)
13970 {
13971   unformat_input_t *line_input = vam->input;
13972   vl_api_want_ip4_arp_events_t *mp;
13973   ip4_address_t address;
13974   int address_set = 0;
13975   u32 enable_disable = 1;
13976   int ret;
13977
13978   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13979     {
13980       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13981         address_set = 1;
13982       else if (unformat (line_input, "del"))
13983         enable_disable = 0;
13984       else
13985         break;
13986     }
13987
13988   if (address_set == 0)
13989     {
13990       errmsg ("missing addresses");
13991       return -99;
13992     }
13993
13994   M (WANT_IP4_ARP_EVENTS, mp);
13995   mp->enable_disable = enable_disable;
13996   mp->pid = htonl (getpid ());
13997   mp->address = address.as_u32;
13998
13999   S (mp);
14000   W (ret);
14001   return ret;
14002 }
14003
14004 static int
14005 api_want_ip6_nd_events (vat_main_t * vam)
14006 {
14007   unformat_input_t *line_input = vam->input;
14008   vl_api_want_ip6_nd_events_t *mp;
14009   ip6_address_t address;
14010   int address_set = 0;
14011   u32 enable_disable = 1;
14012   int ret;
14013
14014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14015     {
14016       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14017         address_set = 1;
14018       else if (unformat (line_input, "del"))
14019         enable_disable = 0;
14020       else
14021         break;
14022     }
14023
14024   if (address_set == 0)
14025     {
14026       errmsg ("missing addresses");
14027       return -99;
14028     }
14029
14030   M (WANT_IP6_ND_EVENTS, mp);
14031   mp->enable_disable = enable_disable;
14032   mp->pid = htonl (getpid ());
14033   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14034
14035   S (mp);
14036   W (ret);
14037   return ret;
14038 }
14039
14040 static int
14041 api_want_l2_macs_events (vat_main_t * vam)
14042 {
14043   unformat_input_t *line_input = vam->input;
14044   vl_api_want_l2_macs_events_t *mp;
14045   u8 enable_disable = 1;
14046   u32 scan_delay = 0;
14047   u32 max_macs_in_event = 0;
14048   u32 learn_limit = 0;
14049   int ret;
14050
14051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (line_input, "learn-limit %d", &learn_limit))
14054         ;
14055       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14056         ;
14057       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14058         ;
14059       else if (unformat (line_input, "disable"))
14060         enable_disable = 0;
14061       else
14062         break;
14063     }
14064
14065   M (WANT_L2_MACS_EVENTS, mp);
14066   mp->enable_disable = enable_disable;
14067   mp->pid = htonl (getpid ());
14068   mp->learn_limit = htonl (learn_limit);
14069   mp->scan_delay = (u8) scan_delay;
14070   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14071   S (mp);
14072   W (ret);
14073   return ret;
14074 }
14075
14076 static int
14077 api_input_acl_set_interface (vat_main_t * vam)
14078 {
14079   unformat_input_t *i = vam->input;
14080   vl_api_input_acl_set_interface_t *mp;
14081   u32 sw_if_index;
14082   int sw_if_index_set;
14083   u32 ip4_table_index = ~0;
14084   u32 ip6_table_index = ~0;
14085   u32 l2_table_index = ~0;
14086   u8 is_add = 1;
14087   int ret;
14088
14089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14092         sw_if_index_set = 1;
14093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14094         sw_if_index_set = 1;
14095       else if (unformat (i, "del"))
14096         is_add = 0;
14097       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14098         ;
14099       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14100         ;
14101       else if (unformat (i, "l2-table %d", &l2_table_index))
14102         ;
14103       else
14104         {
14105           clib_warning ("parse error '%U'", format_unformat_error, i);
14106           return -99;
14107         }
14108     }
14109
14110   if (sw_if_index_set == 0)
14111     {
14112       errmsg ("missing interface name or sw_if_index");
14113       return -99;
14114     }
14115
14116   M (INPUT_ACL_SET_INTERFACE, mp);
14117
14118   mp->sw_if_index = ntohl (sw_if_index);
14119   mp->ip4_table_index = ntohl (ip4_table_index);
14120   mp->ip6_table_index = ntohl (ip6_table_index);
14121   mp->l2_table_index = ntohl (l2_table_index);
14122   mp->is_add = is_add;
14123
14124   S (mp);
14125   W (ret);
14126   return ret;
14127 }
14128
14129 static int
14130 api_ip_address_dump (vat_main_t * vam)
14131 {
14132   unformat_input_t *i = vam->input;
14133   vl_api_ip_address_dump_t *mp;
14134   vl_api_control_ping_t *mp_ping;
14135   u32 sw_if_index = ~0;
14136   u8 sw_if_index_set = 0;
14137   u8 ipv4_set = 0;
14138   u8 ipv6_set = 0;
14139   int ret;
14140
14141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14142     {
14143       if (unformat (i, "sw_if_index %d", &sw_if_index))
14144         sw_if_index_set = 1;
14145       else
14146         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14147         sw_if_index_set = 1;
14148       else if (unformat (i, "ipv4"))
14149         ipv4_set = 1;
14150       else if (unformat (i, "ipv6"))
14151         ipv6_set = 1;
14152       else
14153         break;
14154     }
14155
14156   if (ipv4_set && ipv6_set)
14157     {
14158       errmsg ("ipv4 and ipv6 flags cannot be both set");
14159       return -99;
14160     }
14161
14162   if ((!ipv4_set) && (!ipv6_set))
14163     {
14164       errmsg ("no ipv4 nor ipv6 flag set");
14165       return -99;
14166     }
14167
14168   if (sw_if_index_set == 0)
14169     {
14170       errmsg ("missing interface name or sw_if_index");
14171       return -99;
14172     }
14173
14174   vam->current_sw_if_index = sw_if_index;
14175   vam->is_ipv6 = ipv6_set;
14176
14177   M (IP_ADDRESS_DUMP, mp);
14178   mp->sw_if_index = ntohl (sw_if_index);
14179   mp->is_ipv6 = ipv6_set;
14180   S (mp);
14181
14182   /* Use a control ping for synchronization */
14183   MPING (CONTROL_PING, mp_ping);
14184   S (mp_ping);
14185
14186   W (ret);
14187   return ret;
14188 }
14189
14190 static int
14191 api_ip_dump (vat_main_t * vam)
14192 {
14193   vl_api_ip_dump_t *mp;
14194   vl_api_control_ping_t *mp_ping;
14195   unformat_input_t *in = vam->input;
14196   int ipv4_set = 0;
14197   int ipv6_set = 0;
14198   int is_ipv6;
14199   int i;
14200   int ret;
14201
14202   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (in, "ipv4"))
14205         ipv4_set = 1;
14206       else if (unformat (in, "ipv6"))
14207         ipv6_set = 1;
14208       else
14209         break;
14210     }
14211
14212   if (ipv4_set && ipv6_set)
14213     {
14214       errmsg ("ipv4 and ipv6 flags cannot be both set");
14215       return -99;
14216     }
14217
14218   if ((!ipv4_set) && (!ipv6_set))
14219     {
14220       errmsg ("no ipv4 nor ipv6 flag set");
14221       return -99;
14222     }
14223
14224   is_ipv6 = ipv6_set;
14225   vam->is_ipv6 = is_ipv6;
14226
14227   /* free old data */
14228   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14229     {
14230       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14231     }
14232   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14233
14234   M (IP_DUMP, mp);
14235   mp->is_ipv6 = ipv6_set;
14236   S (mp);
14237
14238   /* Use a control ping for synchronization */
14239   MPING (CONTROL_PING, mp_ping);
14240   S (mp_ping);
14241
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static int
14247 api_ipsec_spd_add_del (vat_main_t * vam)
14248 {
14249   unformat_input_t *i = vam->input;
14250   vl_api_ipsec_spd_add_del_t *mp;
14251   u32 spd_id = ~0;
14252   u8 is_add = 1;
14253   int ret;
14254
14255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14256     {
14257       if (unformat (i, "spd_id %d", &spd_id))
14258         ;
14259       else if (unformat (i, "del"))
14260         is_add = 0;
14261       else
14262         {
14263           clib_warning ("parse error '%U'", format_unformat_error, i);
14264           return -99;
14265         }
14266     }
14267   if (spd_id == ~0)
14268     {
14269       errmsg ("spd_id must be set");
14270       return -99;
14271     }
14272
14273   M (IPSEC_SPD_ADD_DEL, mp);
14274
14275   mp->spd_id = ntohl (spd_id);
14276   mp->is_add = is_add;
14277
14278   S (mp);
14279   W (ret);
14280   return ret;
14281 }
14282
14283 static int
14284 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_ipsec_interface_add_del_spd_t *mp;
14288   u32 sw_if_index;
14289   u8 sw_if_index_set = 0;
14290   u32 spd_id = (u32) ~ 0;
14291   u8 is_add = 1;
14292   int ret;
14293
14294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14295     {
14296       if (unformat (i, "del"))
14297         is_add = 0;
14298       else if (unformat (i, "spd_id %d", &spd_id))
14299         ;
14300       else
14301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14302         sw_if_index_set = 1;
14303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14304         sw_if_index_set = 1;
14305       else
14306         {
14307           clib_warning ("parse error '%U'", format_unformat_error, i);
14308           return -99;
14309         }
14310
14311     }
14312
14313   if (spd_id == (u32) ~ 0)
14314     {
14315       errmsg ("spd_id must be set");
14316       return -99;
14317     }
14318
14319   if (sw_if_index_set == 0)
14320     {
14321       errmsg ("missing interface name or sw_if_index");
14322       return -99;
14323     }
14324
14325   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14326
14327   mp->spd_id = ntohl (spd_id);
14328   mp->sw_if_index = ntohl (sw_if_index);
14329   mp->is_add = is_add;
14330
14331   S (mp);
14332   W (ret);
14333   return ret;
14334 }
14335
14336 static int
14337 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14338 {
14339   unformat_input_t *i = vam->input;
14340   vl_api_ipsec_spd_add_del_entry_t *mp;
14341   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14342   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14343   i32 priority = 0;
14344   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14345   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14346   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14347   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14348   int ret;
14349
14350   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14351   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14352   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14353   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14354   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14355   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14356
14357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14358     {
14359       if (unformat (i, "del"))
14360         is_add = 0;
14361       if (unformat (i, "outbound"))
14362         is_outbound = 1;
14363       if (unformat (i, "inbound"))
14364         is_outbound = 0;
14365       else if (unformat (i, "spd_id %d", &spd_id))
14366         ;
14367       else if (unformat (i, "sa_id %d", &sa_id))
14368         ;
14369       else if (unformat (i, "priority %d", &priority))
14370         ;
14371       else if (unformat (i, "protocol %d", &protocol))
14372         ;
14373       else if (unformat (i, "lport_start %d", &lport_start))
14374         ;
14375       else if (unformat (i, "lport_stop %d", &lport_stop))
14376         ;
14377       else if (unformat (i, "rport_start %d", &rport_start))
14378         ;
14379       else if (unformat (i, "rport_stop %d", &rport_stop))
14380         ;
14381       else
14382         if (unformat
14383             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14384         {
14385           is_ipv6 = 0;
14386           is_ip_any = 0;
14387         }
14388       else
14389         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14390         {
14391           is_ipv6 = 0;
14392           is_ip_any = 0;
14393         }
14394       else
14395         if (unformat
14396             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14397         {
14398           is_ipv6 = 0;
14399           is_ip_any = 0;
14400         }
14401       else
14402         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14403         {
14404           is_ipv6 = 0;
14405           is_ip_any = 0;
14406         }
14407       else
14408         if (unformat
14409             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14410         {
14411           is_ipv6 = 1;
14412           is_ip_any = 0;
14413         }
14414       else
14415         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14416         {
14417           is_ipv6 = 1;
14418           is_ip_any = 0;
14419         }
14420       else
14421         if (unformat
14422             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14423         {
14424           is_ipv6 = 1;
14425           is_ip_any = 0;
14426         }
14427       else
14428         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14429         {
14430           is_ipv6 = 1;
14431           is_ip_any = 0;
14432         }
14433       else
14434         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14435         {
14436           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14437             {
14438               clib_warning ("unsupported action: 'resolve'");
14439               return -99;
14440             }
14441         }
14442       else
14443         {
14444           clib_warning ("parse error '%U'", format_unformat_error, i);
14445           return -99;
14446         }
14447
14448     }
14449
14450   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14451
14452   mp->spd_id = ntohl (spd_id);
14453   mp->priority = ntohl (priority);
14454   mp->is_outbound = is_outbound;
14455
14456   mp->is_ipv6 = is_ipv6;
14457   if (is_ipv6 || is_ip_any)
14458     {
14459       clib_memcpy (mp->remote_address_start, &raddr6_start,
14460                    sizeof (ip6_address_t));
14461       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14462                    sizeof (ip6_address_t));
14463       clib_memcpy (mp->local_address_start, &laddr6_start,
14464                    sizeof (ip6_address_t));
14465       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14466                    sizeof (ip6_address_t));
14467     }
14468   else
14469     {
14470       clib_memcpy (mp->remote_address_start, &raddr4_start,
14471                    sizeof (ip4_address_t));
14472       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14473                    sizeof (ip4_address_t));
14474       clib_memcpy (mp->local_address_start, &laddr4_start,
14475                    sizeof (ip4_address_t));
14476       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14477                    sizeof (ip4_address_t));
14478     }
14479   mp->protocol = (u8) protocol;
14480   mp->local_port_start = ntohs ((u16) lport_start);
14481   mp->local_port_stop = ntohs ((u16) lport_stop);
14482   mp->remote_port_start = ntohs ((u16) rport_start);
14483   mp->remote_port_stop = ntohs ((u16) rport_stop);
14484   mp->policy = (u8) policy;
14485   mp->sa_id = ntohl (sa_id);
14486   mp->is_add = is_add;
14487   mp->is_ip_any = is_ip_any;
14488   S (mp);
14489   W (ret);
14490   return ret;
14491 }
14492
14493 static int
14494 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14495 {
14496   unformat_input_t *i = vam->input;
14497   vl_api_ipsec_sad_add_del_entry_t *mp;
14498   u32 sad_id = 0, spi = 0;
14499   u8 *ck = 0, *ik = 0;
14500   u8 is_add = 1;
14501
14502   u8 protocol = IPSEC_PROTOCOL_AH;
14503   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14504   u32 crypto_alg = 0, integ_alg = 0;
14505   ip4_address_t tun_src4;
14506   ip4_address_t tun_dst4;
14507   ip6_address_t tun_src6;
14508   ip6_address_t tun_dst6;
14509   int ret;
14510
14511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14512     {
14513       if (unformat (i, "del"))
14514         is_add = 0;
14515       else if (unformat (i, "sad_id %d", &sad_id))
14516         ;
14517       else if (unformat (i, "spi %d", &spi))
14518         ;
14519       else if (unformat (i, "esp"))
14520         protocol = IPSEC_PROTOCOL_ESP;
14521       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14522         {
14523           is_tunnel = 1;
14524           is_tunnel_ipv6 = 0;
14525         }
14526       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14527         {
14528           is_tunnel = 1;
14529           is_tunnel_ipv6 = 0;
14530         }
14531       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14532         {
14533           is_tunnel = 1;
14534           is_tunnel_ipv6 = 1;
14535         }
14536       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14537         {
14538           is_tunnel = 1;
14539           is_tunnel_ipv6 = 1;
14540         }
14541       else
14542         if (unformat
14543             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14544         {
14545           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14546               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14547             {
14548               clib_warning ("unsupported crypto-alg: '%U'",
14549                             format_ipsec_crypto_alg, crypto_alg);
14550               return -99;
14551             }
14552         }
14553       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14554         ;
14555       else
14556         if (unformat
14557             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14558         {
14559           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14560               integ_alg >= IPSEC_INTEG_N_ALG)
14561             {
14562               clib_warning ("unsupported integ-alg: '%U'",
14563                             format_ipsec_integ_alg, integ_alg);
14564               return -99;
14565             }
14566         }
14567       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14568         ;
14569       else
14570         {
14571           clib_warning ("parse error '%U'", format_unformat_error, i);
14572           return -99;
14573         }
14574
14575     }
14576
14577   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14578
14579   mp->sad_id = ntohl (sad_id);
14580   mp->is_add = is_add;
14581   mp->protocol = protocol;
14582   mp->spi = ntohl (spi);
14583   mp->is_tunnel = is_tunnel;
14584   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14585   mp->crypto_algorithm = crypto_alg;
14586   mp->integrity_algorithm = integ_alg;
14587   mp->crypto_key_length = vec_len (ck);
14588   mp->integrity_key_length = vec_len (ik);
14589
14590   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14591     mp->crypto_key_length = sizeof (mp->crypto_key);
14592
14593   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14594     mp->integrity_key_length = sizeof (mp->integrity_key);
14595
14596   if (ck)
14597     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14598   if (ik)
14599     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14600
14601   if (is_tunnel)
14602     {
14603       if (is_tunnel_ipv6)
14604         {
14605           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14606                        sizeof (ip6_address_t));
14607           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14608                        sizeof (ip6_address_t));
14609         }
14610       else
14611         {
14612           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14613                        sizeof (ip4_address_t));
14614           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14615                        sizeof (ip4_address_t));
14616         }
14617     }
14618
14619   S (mp);
14620   W (ret);
14621   return ret;
14622 }
14623
14624 static int
14625 api_ipsec_sa_set_key (vat_main_t * vam)
14626 {
14627   unformat_input_t *i = vam->input;
14628   vl_api_ipsec_sa_set_key_t *mp;
14629   u32 sa_id;
14630   u8 *ck = 0, *ik = 0;
14631   int ret;
14632
14633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14634     {
14635       if (unformat (i, "sa_id %d", &sa_id))
14636         ;
14637       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14638         ;
14639       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14640         ;
14641       else
14642         {
14643           clib_warning ("parse error '%U'", format_unformat_error, i);
14644           return -99;
14645         }
14646     }
14647
14648   M (IPSEC_SA_SET_KEY, mp);
14649
14650   mp->sa_id = ntohl (sa_id);
14651   mp->crypto_key_length = vec_len (ck);
14652   mp->integrity_key_length = vec_len (ik);
14653
14654   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14655     mp->crypto_key_length = sizeof (mp->crypto_key);
14656
14657   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14658     mp->integrity_key_length = sizeof (mp->integrity_key);
14659
14660   if (ck)
14661     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14662   if (ik)
14663     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14664
14665   S (mp);
14666   W (ret);
14667   return ret;
14668 }
14669
14670 static int
14671 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14672 {
14673   unformat_input_t *i = vam->input;
14674   vl_api_ipsec_tunnel_if_add_del_t *mp;
14675   u32 local_spi = 0, remote_spi = 0;
14676   u32 crypto_alg = 0, integ_alg = 0;
14677   u8 *lck = NULL, *rck = NULL;
14678   u8 *lik = NULL, *rik = NULL;
14679   ip4_address_t local_ip = { {0} };
14680   ip4_address_t remote_ip = { {0} };
14681   u8 is_add = 1;
14682   u8 esn = 0;
14683   u8 anti_replay = 0;
14684   int ret;
14685
14686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (i, "del"))
14689         is_add = 0;
14690       else if (unformat (i, "esn"))
14691         esn = 1;
14692       else if (unformat (i, "anti_replay"))
14693         anti_replay = 1;
14694       else if (unformat (i, "local_spi %d", &local_spi))
14695         ;
14696       else if (unformat (i, "remote_spi %d", &remote_spi))
14697         ;
14698       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14699         ;
14700       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14701         ;
14702       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14703         ;
14704       else
14705         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14706         ;
14707       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14708         ;
14709       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14710         ;
14711       else
14712         if (unformat
14713             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14714         {
14715           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14716               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14717             {
14718               errmsg ("unsupported crypto-alg: '%U'\n",
14719                       format_ipsec_crypto_alg, crypto_alg);
14720               return -99;
14721             }
14722         }
14723       else
14724         if (unformat
14725             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14726         {
14727           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14728               integ_alg >= IPSEC_INTEG_N_ALG)
14729             {
14730               errmsg ("unsupported integ-alg: '%U'\n",
14731                       format_ipsec_integ_alg, integ_alg);
14732               return -99;
14733             }
14734         }
14735       else
14736         {
14737           errmsg ("parse error '%U'\n", format_unformat_error, i);
14738           return -99;
14739         }
14740     }
14741
14742   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14743
14744   mp->is_add = is_add;
14745   mp->esn = esn;
14746   mp->anti_replay = anti_replay;
14747
14748   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14749   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14750
14751   mp->local_spi = htonl (local_spi);
14752   mp->remote_spi = htonl (remote_spi);
14753   mp->crypto_alg = (u8) crypto_alg;
14754
14755   mp->local_crypto_key_len = 0;
14756   if (lck)
14757     {
14758       mp->local_crypto_key_len = vec_len (lck);
14759       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14760         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14761       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14762     }
14763
14764   mp->remote_crypto_key_len = 0;
14765   if (rck)
14766     {
14767       mp->remote_crypto_key_len = vec_len (rck);
14768       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14769         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14770       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14771     }
14772
14773   mp->integ_alg = (u8) integ_alg;
14774
14775   mp->local_integ_key_len = 0;
14776   if (lik)
14777     {
14778       mp->local_integ_key_len = vec_len (lik);
14779       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14780         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14781       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14782     }
14783
14784   mp->remote_integ_key_len = 0;
14785   if (rik)
14786     {
14787       mp->remote_integ_key_len = vec_len (rik);
14788       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14789         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14790       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14791     }
14792
14793   S (mp);
14794   W (ret);
14795   return ret;
14796 }
14797
14798 static void
14799 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14800 {
14801   vat_main_t *vam = &vat_main;
14802
14803   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14804          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14805          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14806          "tunnel_src_addr %U tunnel_dst_addr %U "
14807          "salt %u seq_outbound %lu last_seq_inbound %lu "
14808          "replay_window %lu total_data_size %lu\n",
14809          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14810          mp->protocol,
14811          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14812          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14813          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14814          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14815          mp->tunnel_src_addr,
14816          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14817          mp->tunnel_dst_addr,
14818          ntohl (mp->salt),
14819          clib_net_to_host_u64 (mp->seq_outbound),
14820          clib_net_to_host_u64 (mp->last_seq_inbound),
14821          clib_net_to_host_u64 (mp->replay_window),
14822          clib_net_to_host_u64 (mp->total_data_size));
14823 }
14824
14825 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14826 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14827
14828 static void vl_api_ipsec_sa_details_t_handler_json
14829   (vl_api_ipsec_sa_details_t * mp)
14830 {
14831   vat_main_t *vam = &vat_main;
14832   vat_json_node_t *node = NULL;
14833   struct in_addr src_ip4, dst_ip4;
14834   struct in6_addr src_ip6, dst_ip6;
14835
14836   if (VAT_JSON_ARRAY != vam->json_tree.type)
14837     {
14838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14839       vat_json_init_array (&vam->json_tree);
14840     }
14841   node = vat_json_array_add (&vam->json_tree);
14842
14843   vat_json_init_object (node);
14844   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14845   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14846   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14847   vat_json_object_add_uint (node, "proto", mp->protocol);
14848   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14849   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14850   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14851   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14852   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14853   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14854   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14855                              mp->crypto_key_len);
14856   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14857                              mp->integ_key_len);
14858   if (mp->is_tunnel_ip6)
14859     {
14860       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14861       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14862       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14863       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14864     }
14865   else
14866     {
14867       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14868       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14869       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14870       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14871     }
14872   vat_json_object_add_uint (node, "replay_window",
14873                             clib_net_to_host_u64 (mp->replay_window));
14874   vat_json_object_add_uint (node, "total_data_size",
14875                             clib_net_to_host_u64 (mp->total_data_size));
14876
14877 }
14878
14879 static int
14880 api_ipsec_sa_dump (vat_main_t * vam)
14881 {
14882   unformat_input_t *i = vam->input;
14883   vl_api_ipsec_sa_dump_t *mp;
14884   vl_api_control_ping_t *mp_ping;
14885   u32 sa_id = ~0;
14886   int ret;
14887
14888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14889     {
14890       if (unformat (i, "sa_id %d", &sa_id))
14891         ;
14892       else
14893         {
14894           clib_warning ("parse error '%U'", format_unformat_error, i);
14895           return -99;
14896         }
14897     }
14898
14899   M (IPSEC_SA_DUMP, mp);
14900
14901   mp->sa_id = ntohl (sa_id);
14902
14903   S (mp);
14904
14905   /* Use a control ping for synchronization */
14906   M (CONTROL_PING, mp_ping);
14907   S (mp_ping);
14908
14909   W (ret);
14910   return ret;
14911 }
14912
14913 static int
14914 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14915 {
14916   unformat_input_t *i = vam->input;
14917   vl_api_ipsec_tunnel_if_set_key_t *mp;
14918   u32 sw_if_index = ~0;
14919   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14920   u8 *key = 0;
14921   u32 alg = ~0;
14922   int ret;
14923
14924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14925     {
14926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14927         ;
14928       else
14929         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14930         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14931       else
14932         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14933         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14934       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14935         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14936       else
14937         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14938         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14939       else if (unformat (i, "%U", unformat_hex_string, &key))
14940         ;
14941       else
14942         {
14943           clib_warning ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947
14948   if (sw_if_index == ~0)
14949     {
14950       errmsg ("interface must be specified");
14951       return -99;
14952     }
14953
14954   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14955     {
14956       errmsg ("key type must be specified");
14957       return -99;
14958     }
14959
14960   if (alg == ~0)
14961     {
14962       errmsg ("algorithm must be specified");
14963       return -99;
14964     }
14965
14966   if (vec_len (key) == 0)
14967     {
14968       errmsg ("key must be specified");
14969       return -99;
14970     }
14971
14972   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14973
14974   mp->sw_if_index = htonl (sw_if_index);
14975   mp->alg = alg;
14976   mp->key_type = key_type;
14977   mp->key_len = vec_len (key);
14978   clib_memcpy (mp->key, key, vec_len (key));
14979
14980   S (mp);
14981   W (ret);
14982
14983   return ret;
14984 }
14985
14986 static int
14987 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14988 {
14989   unformat_input_t *i = vam->input;
14990   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14991   u32 sw_if_index = ~0;
14992   u32 sa_id = ~0;
14993   u8 is_outbound = (u8) ~ 0;
14994   int ret;
14995
14996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14997     {
14998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14999         ;
15000       else if (unformat (i, "sa_id %d", &sa_id))
15001         ;
15002       else if (unformat (i, "outbound"))
15003         is_outbound = 1;
15004       else if (unformat (i, "inbound"))
15005         is_outbound = 0;
15006       else
15007         {
15008           clib_warning ("parse error '%U'", format_unformat_error, i);
15009           return -99;
15010         }
15011     }
15012
15013   if (sw_if_index == ~0)
15014     {
15015       errmsg ("interface must be specified");
15016       return -99;
15017     }
15018
15019   if (sa_id == ~0)
15020     {
15021       errmsg ("SA ID must be specified");
15022       return -99;
15023     }
15024
15025   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15026
15027   mp->sw_if_index = htonl (sw_if_index);
15028   mp->sa_id = htonl (sa_id);
15029   mp->is_outbound = is_outbound;
15030
15031   S (mp);
15032   W (ret);
15033
15034   return ret;
15035 }
15036
15037 static int
15038 api_ikev2_profile_add_del (vat_main_t * vam)
15039 {
15040   unformat_input_t *i = vam->input;
15041   vl_api_ikev2_profile_add_del_t *mp;
15042   u8 is_add = 1;
15043   u8 *name = 0;
15044   int ret;
15045
15046   const char *valid_chars = "a-zA-Z0-9_";
15047
15048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15049     {
15050       if (unformat (i, "del"))
15051         is_add = 0;
15052       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15053         vec_add1 (name, 0);
15054       else
15055         {
15056           errmsg ("parse error '%U'", format_unformat_error, i);
15057           return -99;
15058         }
15059     }
15060
15061   if (!vec_len (name))
15062     {
15063       errmsg ("profile name must be specified");
15064       return -99;
15065     }
15066
15067   if (vec_len (name) > 64)
15068     {
15069       errmsg ("profile name too long");
15070       return -99;
15071     }
15072
15073   M (IKEV2_PROFILE_ADD_DEL, mp);
15074
15075   clib_memcpy (mp->name, name, vec_len (name));
15076   mp->is_add = is_add;
15077   vec_free (name);
15078
15079   S (mp);
15080   W (ret);
15081   return ret;
15082 }
15083
15084 static int
15085 api_ikev2_profile_set_auth (vat_main_t * vam)
15086 {
15087   unformat_input_t *i = vam->input;
15088   vl_api_ikev2_profile_set_auth_t *mp;
15089   u8 *name = 0;
15090   u8 *data = 0;
15091   u32 auth_method = 0;
15092   u8 is_hex = 0;
15093   int ret;
15094
15095   const char *valid_chars = "a-zA-Z0-9_";
15096
15097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15100         vec_add1 (name, 0);
15101       else if (unformat (i, "auth_method %U",
15102                          unformat_ikev2_auth_method, &auth_method))
15103         ;
15104       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15105         is_hex = 1;
15106       else if (unformat (i, "auth_data %v", &data))
15107         ;
15108       else
15109         {
15110           errmsg ("parse error '%U'", format_unformat_error, i);
15111           return -99;
15112         }
15113     }
15114
15115   if (!vec_len (name))
15116     {
15117       errmsg ("profile name must be specified");
15118       return -99;
15119     }
15120
15121   if (vec_len (name) > 64)
15122     {
15123       errmsg ("profile name too long");
15124       return -99;
15125     }
15126
15127   if (!vec_len (data))
15128     {
15129       errmsg ("auth_data must be specified");
15130       return -99;
15131     }
15132
15133   if (!auth_method)
15134     {
15135       errmsg ("auth_method must be specified");
15136       return -99;
15137     }
15138
15139   M (IKEV2_PROFILE_SET_AUTH, mp);
15140
15141   mp->is_hex = is_hex;
15142   mp->auth_method = (u8) auth_method;
15143   mp->data_len = vec_len (data);
15144   clib_memcpy (mp->name, name, vec_len (name));
15145   clib_memcpy (mp->data, data, vec_len (data));
15146   vec_free (name);
15147   vec_free (data);
15148
15149   S (mp);
15150   W (ret);
15151   return ret;
15152 }
15153
15154 static int
15155 api_ikev2_profile_set_id (vat_main_t * vam)
15156 {
15157   unformat_input_t *i = vam->input;
15158   vl_api_ikev2_profile_set_id_t *mp;
15159   u8 *name = 0;
15160   u8 *data = 0;
15161   u8 is_local = 0;
15162   u32 id_type = 0;
15163   ip4_address_t ip4;
15164   int ret;
15165
15166   const char *valid_chars = "a-zA-Z0-9_";
15167
15168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15169     {
15170       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15171         vec_add1 (name, 0);
15172       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15173         ;
15174       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15175         {
15176           data = vec_new (u8, 4);
15177           clib_memcpy (data, ip4.as_u8, 4);
15178         }
15179       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15180         ;
15181       else if (unformat (i, "id_data %v", &data))
15182         ;
15183       else if (unformat (i, "local"))
15184         is_local = 1;
15185       else if (unformat (i, "remote"))
15186         is_local = 0;
15187       else
15188         {
15189           errmsg ("parse error '%U'", format_unformat_error, i);
15190           return -99;
15191         }
15192     }
15193
15194   if (!vec_len (name))
15195     {
15196       errmsg ("profile name must be specified");
15197       return -99;
15198     }
15199
15200   if (vec_len (name) > 64)
15201     {
15202       errmsg ("profile name too long");
15203       return -99;
15204     }
15205
15206   if (!vec_len (data))
15207     {
15208       errmsg ("id_data must be specified");
15209       return -99;
15210     }
15211
15212   if (!id_type)
15213     {
15214       errmsg ("id_type must be specified");
15215       return -99;
15216     }
15217
15218   M (IKEV2_PROFILE_SET_ID, mp);
15219
15220   mp->is_local = is_local;
15221   mp->id_type = (u8) id_type;
15222   mp->data_len = vec_len (data);
15223   clib_memcpy (mp->name, name, vec_len (name));
15224   clib_memcpy (mp->data, data, vec_len (data));
15225   vec_free (name);
15226   vec_free (data);
15227
15228   S (mp);
15229   W (ret);
15230   return ret;
15231 }
15232
15233 static int
15234 api_ikev2_profile_set_ts (vat_main_t * vam)
15235 {
15236   unformat_input_t *i = vam->input;
15237   vl_api_ikev2_profile_set_ts_t *mp;
15238   u8 *name = 0;
15239   u8 is_local = 0;
15240   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15241   ip4_address_t start_addr, end_addr;
15242
15243   const char *valid_chars = "a-zA-Z0-9_";
15244   int ret;
15245
15246   start_addr.as_u32 = 0;
15247   end_addr.as_u32 = (u32) ~ 0;
15248
15249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15250     {
15251       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15252         vec_add1 (name, 0);
15253       else if (unformat (i, "protocol %d", &proto))
15254         ;
15255       else if (unformat (i, "start_port %d", &start_port))
15256         ;
15257       else if (unformat (i, "end_port %d", &end_port))
15258         ;
15259       else
15260         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15261         ;
15262       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15263         ;
15264       else if (unformat (i, "local"))
15265         is_local = 1;
15266       else if (unformat (i, "remote"))
15267         is_local = 0;
15268       else
15269         {
15270           errmsg ("parse error '%U'", format_unformat_error, i);
15271           return -99;
15272         }
15273     }
15274
15275   if (!vec_len (name))
15276     {
15277       errmsg ("profile name must be specified");
15278       return -99;
15279     }
15280
15281   if (vec_len (name) > 64)
15282     {
15283       errmsg ("profile name too long");
15284       return -99;
15285     }
15286
15287   M (IKEV2_PROFILE_SET_TS, mp);
15288
15289   mp->is_local = is_local;
15290   mp->proto = (u8) proto;
15291   mp->start_port = (u16) start_port;
15292   mp->end_port = (u16) end_port;
15293   mp->start_addr = start_addr.as_u32;
15294   mp->end_addr = end_addr.as_u32;
15295   clib_memcpy (mp->name, name, vec_len (name));
15296   vec_free (name);
15297
15298   S (mp);
15299   W (ret);
15300   return ret;
15301 }
15302
15303 static int
15304 api_ikev2_set_local_key (vat_main_t * vam)
15305 {
15306   unformat_input_t *i = vam->input;
15307   vl_api_ikev2_set_local_key_t *mp;
15308   u8 *file = 0;
15309   int ret;
15310
15311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15312     {
15313       if (unformat (i, "file %v", &file))
15314         vec_add1 (file, 0);
15315       else
15316         {
15317           errmsg ("parse error '%U'", format_unformat_error, i);
15318           return -99;
15319         }
15320     }
15321
15322   if (!vec_len (file))
15323     {
15324       errmsg ("RSA key file must be specified");
15325       return -99;
15326     }
15327
15328   if (vec_len (file) > 256)
15329     {
15330       errmsg ("file name too long");
15331       return -99;
15332     }
15333
15334   M (IKEV2_SET_LOCAL_KEY, mp);
15335
15336   clib_memcpy (mp->key_file, file, vec_len (file));
15337   vec_free (file);
15338
15339   S (mp);
15340   W (ret);
15341   return ret;
15342 }
15343
15344 static int
15345 api_ikev2_set_responder (vat_main_t * vam)
15346 {
15347   unformat_input_t *i = vam->input;
15348   vl_api_ikev2_set_responder_t *mp;
15349   int ret;
15350   u8 *name = 0;
15351   u32 sw_if_index = ~0;
15352   ip4_address_t address;
15353
15354   const char *valid_chars = "a-zA-Z0-9_";
15355
15356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15357     {
15358       if (unformat
15359           (i, "%U interface %d address %U", unformat_token, valid_chars,
15360            &name, &sw_if_index, unformat_ip4_address, &address))
15361         vec_add1 (name, 0);
15362       else
15363         {
15364           errmsg ("parse error '%U'", format_unformat_error, i);
15365           return -99;
15366         }
15367     }
15368
15369   if (!vec_len (name))
15370     {
15371       errmsg ("profile name must be specified");
15372       return -99;
15373     }
15374
15375   if (vec_len (name) > 64)
15376     {
15377       errmsg ("profile name too long");
15378       return -99;
15379     }
15380
15381   M (IKEV2_SET_RESPONDER, mp);
15382
15383   clib_memcpy (mp->name, name, vec_len (name));
15384   vec_free (name);
15385
15386   mp->sw_if_index = sw_if_index;
15387   clib_memcpy (mp->address, &address, sizeof (address));
15388
15389   S (mp);
15390   W (ret);
15391   return ret;
15392 }
15393
15394 static int
15395 api_ikev2_set_ike_transforms (vat_main_t * vam)
15396 {
15397   unformat_input_t *i = vam->input;
15398   vl_api_ikev2_set_ike_transforms_t *mp;
15399   int ret;
15400   u8 *name = 0;
15401   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15402
15403   const char *valid_chars = "a-zA-Z0-9_";
15404
15405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15406     {
15407       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15408                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15409         vec_add1 (name, 0);
15410       else
15411         {
15412           errmsg ("parse error '%U'", format_unformat_error, i);
15413           return -99;
15414         }
15415     }
15416
15417   if (!vec_len (name))
15418     {
15419       errmsg ("profile name must be specified");
15420       return -99;
15421     }
15422
15423   if (vec_len (name) > 64)
15424     {
15425       errmsg ("profile name too long");
15426       return -99;
15427     }
15428
15429   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15430
15431   clib_memcpy (mp->name, name, vec_len (name));
15432   vec_free (name);
15433   mp->crypto_alg = crypto_alg;
15434   mp->crypto_key_size = crypto_key_size;
15435   mp->integ_alg = integ_alg;
15436   mp->dh_group = dh_group;
15437
15438   S (mp);
15439   W (ret);
15440   return ret;
15441 }
15442
15443
15444 static int
15445 api_ikev2_set_esp_transforms (vat_main_t * vam)
15446 {
15447   unformat_input_t *i = vam->input;
15448   vl_api_ikev2_set_esp_transforms_t *mp;
15449   int ret;
15450   u8 *name = 0;
15451   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15452
15453   const char *valid_chars = "a-zA-Z0-9_";
15454
15455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15456     {
15457       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15458                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15459         vec_add1 (name, 0);
15460       else
15461         {
15462           errmsg ("parse error '%U'", format_unformat_error, i);
15463           return -99;
15464         }
15465     }
15466
15467   if (!vec_len (name))
15468     {
15469       errmsg ("profile name must be specified");
15470       return -99;
15471     }
15472
15473   if (vec_len (name) > 64)
15474     {
15475       errmsg ("profile name too long");
15476       return -99;
15477     }
15478
15479   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15480
15481   clib_memcpy (mp->name, name, vec_len (name));
15482   vec_free (name);
15483   mp->crypto_alg = crypto_alg;
15484   mp->crypto_key_size = crypto_key_size;
15485   mp->integ_alg = integ_alg;
15486   mp->dh_group = dh_group;
15487
15488   S (mp);
15489   W (ret);
15490   return ret;
15491 }
15492
15493 static int
15494 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15495 {
15496   unformat_input_t *i = vam->input;
15497   vl_api_ikev2_set_sa_lifetime_t *mp;
15498   int ret;
15499   u8 *name = 0;
15500   u64 lifetime, lifetime_maxdata;
15501   u32 lifetime_jitter, handover;
15502
15503   const char *valid_chars = "a-zA-Z0-9_";
15504
15505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15508                     &lifetime, &lifetime_jitter, &handover,
15509                     &lifetime_maxdata))
15510         vec_add1 (name, 0);
15511       else
15512         {
15513           errmsg ("parse error '%U'", format_unformat_error, i);
15514           return -99;
15515         }
15516     }
15517
15518   if (!vec_len (name))
15519     {
15520       errmsg ("profile name must be specified");
15521       return -99;
15522     }
15523
15524   if (vec_len (name) > 64)
15525     {
15526       errmsg ("profile name too long");
15527       return -99;
15528     }
15529
15530   M (IKEV2_SET_SA_LIFETIME, mp);
15531
15532   clib_memcpy (mp->name, name, vec_len (name));
15533   vec_free (name);
15534   mp->lifetime = lifetime;
15535   mp->lifetime_jitter = lifetime_jitter;
15536   mp->handover = handover;
15537   mp->lifetime_maxdata = lifetime_maxdata;
15538
15539   S (mp);
15540   W (ret);
15541   return ret;
15542 }
15543
15544 static int
15545 api_ikev2_initiate_sa_init (vat_main_t * vam)
15546 {
15547   unformat_input_t *i = vam->input;
15548   vl_api_ikev2_initiate_sa_init_t *mp;
15549   int ret;
15550   u8 *name = 0;
15551
15552   const char *valid_chars = "a-zA-Z0-9_";
15553
15554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15555     {
15556       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15557         vec_add1 (name, 0);
15558       else
15559         {
15560           errmsg ("parse error '%U'", format_unformat_error, i);
15561           return -99;
15562         }
15563     }
15564
15565   if (!vec_len (name))
15566     {
15567       errmsg ("profile name must be specified");
15568       return -99;
15569     }
15570
15571   if (vec_len (name) > 64)
15572     {
15573       errmsg ("profile name too long");
15574       return -99;
15575     }
15576
15577   M (IKEV2_INITIATE_SA_INIT, mp);
15578
15579   clib_memcpy (mp->name, name, vec_len (name));
15580   vec_free (name);
15581
15582   S (mp);
15583   W (ret);
15584   return ret;
15585 }
15586
15587 static int
15588 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15589 {
15590   unformat_input_t *i = vam->input;
15591   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15592   int ret;
15593   u64 ispi;
15594
15595
15596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15597     {
15598       if (unformat (i, "%lx", &ispi))
15599         ;
15600       else
15601         {
15602           errmsg ("parse error '%U'", format_unformat_error, i);
15603           return -99;
15604         }
15605     }
15606
15607   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15608
15609   mp->ispi = ispi;
15610
15611   S (mp);
15612   W (ret);
15613   return ret;
15614 }
15615
15616 static int
15617 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15618 {
15619   unformat_input_t *i = vam->input;
15620   vl_api_ikev2_initiate_del_child_sa_t *mp;
15621   int ret;
15622   u32 ispi;
15623
15624
15625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15626     {
15627       if (unformat (i, "%x", &ispi))
15628         ;
15629       else
15630         {
15631           errmsg ("parse error '%U'", format_unformat_error, i);
15632           return -99;
15633         }
15634     }
15635
15636   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15637
15638   mp->ispi = ispi;
15639
15640   S (mp);
15641   W (ret);
15642   return ret;
15643 }
15644
15645 static int
15646 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15647 {
15648   unformat_input_t *i = vam->input;
15649   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15650   int ret;
15651   u32 ispi;
15652
15653
15654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15655     {
15656       if (unformat (i, "%x", &ispi))
15657         ;
15658       else
15659         {
15660           errmsg ("parse error '%U'", format_unformat_error, i);
15661           return -99;
15662         }
15663     }
15664
15665   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15666
15667   mp->ispi = ispi;
15668
15669   S (mp);
15670   W (ret);
15671   return ret;
15672 }
15673
15674 /*
15675  * MAP
15676  */
15677 static int
15678 api_map_add_domain (vat_main_t * vam)
15679 {
15680   unformat_input_t *i = vam->input;
15681   vl_api_map_add_domain_t *mp;
15682
15683   ip4_address_t ip4_prefix;
15684   ip6_address_t ip6_prefix;
15685   ip6_address_t ip6_src;
15686   u32 num_m_args = 0;
15687   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15688     0, psid_length = 0;
15689   u8 is_translation = 0;
15690   u32 mtu = 0;
15691   u32 ip6_src_len = 128;
15692   int ret;
15693
15694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15695     {
15696       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15697                     &ip4_prefix, &ip4_prefix_len))
15698         num_m_args++;
15699       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15700                          &ip6_prefix, &ip6_prefix_len))
15701         num_m_args++;
15702       else
15703         if (unformat
15704             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15705              &ip6_src_len))
15706         num_m_args++;
15707       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15708         num_m_args++;
15709       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15710         num_m_args++;
15711       else if (unformat (i, "psid-offset %d", &psid_offset))
15712         num_m_args++;
15713       else if (unformat (i, "psid-len %d", &psid_length))
15714         num_m_args++;
15715       else if (unformat (i, "mtu %d", &mtu))
15716         num_m_args++;
15717       else if (unformat (i, "map-t"))
15718         is_translation = 1;
15719       else
15720         {
15721           clib_warning ("parse error '%U'", format_unformat_error, i);
15722           return -99;
15723         }
15724     }
15725
15726   if (num_m_args < 3)
15727     {
15728       errmsg ("mandatory argument(s) missing");
15729       return -99;
15730     }
15731
15732   /* Construct the API message */
15733   M (MAP_ADD_DOMAIN, mp);
15734
15735   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15736   mp->ip4_prefix_len = ip4_prefix_len;
15737
15738   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15739   mp->ip6_prefix_len = ip6_prefix_len;
15740
15741   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15742   mp->ip6_src_prefix_len = ip6_src_len;
15743
15744   mp->ea_bits_len = ea_bits_len;
15745   mp->psid_offset = psid_offset;
15746   mp->psid_length = psid_length;
15747   mp->is_translation = is_translation;
15748   mp->mtu = htons (mtu);
15749
15750   /* send it... */
15751   S (mp);
15752
15753   /* Wait for a reply, return good/bad news  */
15754   W (ret);
15755   return ret;
15756 }
15757
15758 static int
15759 api_map_del_domain (vat_main_t * vam)
15760 {
15761   unformat_input_t *i = vam->input;
15762   vl_api_map_del_domain_t *mp;
15763
15764   u32 num_m_args = 0;
15765   u32 index;
15766   int ret;
15767
15768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15769     {
15770       if (unformat (i, "index %d", &index))
15771         num_m_args++;
15772       else
15773         {
15774           clib_warning ("parse error '%U'", format_unformat_error, i);
15775           return -99;
15776         }
15777     }
15778
15779   if (num_m_args != 1)
15780     {
15781       errmsg ("mandatory argument(s) missing");
15782       return -99;
15783     }
15784
15785   /* Construct the API message */
15786   M (MAP_DEL_DOMAIN, mp);
15787
15788   mp->index = ntohl (index);
15789
15790   /* send it... */
15791   S (mp);
15792
15793   /* Wait for a reply, return good/bad news  */
15794   W (ret);
15795   return ret;
15796 }
15797
15798 static int
15799 api_map_add_del_rule (vat_main_t * vam)
15800 {
15801   unformat_input_t *i = vam->input;
15802   vl_api_map_add_del_rule_t *mp;
15803   u8 is_add = 1;
15804   ip6_address_t ip6_dst;
15805   u32 num_m_args = 0, index, psid = 0;
15806   int ret;
15807
15808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15809     {
15810       if (unformat (i, "index %d", &index))
15811         num_m_args++;
15812       else if (unformat (i, "psid %d", &psid))
15813         num_m_args++;
15814       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15815         num_m_args++;
15816       else if (unformat (i, "del"))
15817         {
15818           is_add = 0;
15819         }
15820       else
15821         {
15822           clib_warning ("parse error '%U'", format_unformat_error, i);
15823           return -99;
15824         }
15825     }
15826
15827   /* Construct the API message */
15828   M (MAP_ADD_DEL_RULE, mp);
15829
15830   mp->index = ntohl (index);
15831   mp->is_add = is_add;
15832   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15833   mp->psid = ntohs (psid);
15834
15835   /* send it... */
15836   S (mp);
15837
15838   /* Wait for a reply, return good/bad news  */
15839   W (ret);
15840   return ret;
15841 }
15842
15843 static int
15844 api_map_domain_dump (vat_main_t * vam)
15845 {
15846   vl_api_map_domain_dump_t *mp;
15847   vl_api_control_ping_t *mp_ping;
15848   int ret;
15849
15850   /* Construct the API message */
15851   M (MAP_DOMAIN_DUMP, mp);
15852
15853   /* send it... */
15854   S (mp);
15855
15856   /* Use a control ping for synchronization */
15857   MPING (CONTROL_PING, mp_ping);
15858   S (mp_ping);
15859
15860   W (ret);
15861   return ret;
15862 }
15863
15864 static int
15865 api_map_rule_dump (vat_main_t * vam)
15866 {
15867   unformat_input_t *i = vam->input;
15868   vl_api_map_rule_dump_t *mp;
15869   vl_api_control_ping_t *mp_ping;
15870   u32 domain_index = ~0;
15871   int ret;
15872
15873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15874     {
15875       if (unformat (i, "index %u", &domain_index))
15876         ;
15877       else
15878         break;
15879     }
15880
15881   if (domain_index == ~0)
15882     {
15883       clib_warning ("parse error: domain index expected");
15884       return -99;
15885     }
15886
15887   /* Construct the API message */
15888   M (MAP_RULE_DUMP, mp);
15889
15890   mp->domain_index = htonl (domain_index);
15891
15892   /* send it... */
15893   S (mp);
15894
15895   /* Use a control ping for synchronization */
15896   MPING (CONTROL_PING, mp_ping);
15897   S (mp_ping);
15898
15899   W (ret);
15900   return ret;
15901 }
15902
15903 static void vl_api_map_add_domain_reply_t_handler
15904   (vl_api_map_add_domain_reply_t * mp)
15905 {
15906   vat_main_t *vam = &vat_main;
15907   i32 retval = ntohl (mp->retval);
15908
15909   if (vam->async_mode)
15910     {
15911       vam->async_errors += (retval < 0);
15912     }
15913   else
15914     {
15915       vam->retval = retval;
15916       vam->result_ready = 1;
15917     }
15918 }
15919
15920 static void vl_api_map_add_domain_reply_t_handler_json
15921   (vl_api_map_add_domain_reply_t * mp)
15922 {
15923   vat_main_t *vam = &vat_main;
15924   vat_json_node_t node;
15925
15926   vat_json_init_object (&node);
15927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15928   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15929
15930   vat_json_print (vam->ofp, &node);
15931   vat_json_free (&node);
15932
15933   vam->retval = ntohl (mp->retval);
15934   vam->result_ready = 1;
15935 }
15936
15937 static int
15938 api_get_first_msg_id (vat_main_t * vam)
15939 {
15940   vl_api_get_first_msg_id_t *mp;
15941   unformat_input_t *i = vam->input;
15942   u8 *name;
15943   u8 name_set = 0;
15944   int ret;
15945
15946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (i, "client %s", &name))
15949         name_set = 1;
15950       else
15951         break;
15952     }
15953
15954   if (name_set == 0)
15955     {
15956       errmsg ("missing client name");
15957       return -99;
15958     }
15959   vec_add1 (name, 0);
15960
15961   if (vec_len (name) > 63)
15962     {
15963       errmsg ("client name too long");
15964       return -99;
15965     }
15966
15967   M (GET_FIRST_MSG_ID, mp);
15968   clib_memcpy (mp->name, name, vec_len (name));
15969   S (mp);
15970   W (ret);
15971   return ret;
15972 }
15973
15974 static int
15975 api_cop_interface_enable_disable (vat_main_t * vam)
15976 {
15977   unformat_input_t *line_input = vam->input;
15978   vl_api_cop_interface_enable_disable_t *mp;
15979   u32 sw_if_index = ~0;
15980   u8 enable_disable = 1;
15981   int ret;
15982
15983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15984     {
15985       if (unformat (line_input, "disable"))
15986         enable_disable = 0;
15987       if (unformat (line_input, "enable"))
15988         enable_disable = 1;
15989       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15990                          vam, &sw_if_index))
15991         ;
15992       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15993         ;
15994       else
15995         break;
15996     }
15997
15998   if (sw_if_index == ~0)
15999     {
16000       errmsg ("missing interface name or sw_if_index");
16001       return -99;
16002     }
16003
16004   /* Construct the API message */
16005   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16006   mp->sw_if_index = ntohl (sw_if_index);
16007   mp->enable_disable = enable_disable;
16008
16009   /* send it... */
16010   S (mp);
16011   /* Wait for the reply */
16012   W (ret);
16013   return ret;
16014 }
16015
16016 static int
16017 api_cop_whitelist_enable_disable (vat_main_t * vam)
16018 {
16019   unformat_input_t *line_input = vam->input;
16020   vl_api_cop_whitelist_enable_disable_t *mp;
16021   u32 sw_if_index = ~0;
16022   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16023   u32 fib_id = 0;
16024   int ret;
16025
16026   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16027     {
16028       if (unformat (line_input, "ip4"))
16029         ip4 = 1;
16030       else if (unformat (line_input, "ip6"))
16031         ip6 = 1;
16032       else if (unformat (line_input, "default"))
16033         default_cop = 1;
16034       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16035                          vam, &sw_if_index))
16036         ;
16037       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16038         ;
16039       else if (unformat (line_input, "fib-id %d", &fib_id))
16040         ;
16041       else
16042         break;
16043     }
16044
16045   if (sw_if_index == ~0)
16046     {
16047       errmsg ("missing interface name or sw_if_index");
16048       return -99;
16049     }
16050
16051   /* Construct the API message */
16052   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16053   mp->sw_if_index = ntohl (sw_if_index);
16054   mp->fib_id = ntohl (fib_id);
16055   mp->ip4 = ip4;
16056   mp->ip6 = ip6;
16057   mp->default_cop = default_cop;
16058
16059   /* send it... */
16060   S (mp);
16061   /* Wait for the reply */
16062   W (ret);
16063   return ret;
16064 }
16065
16066 static int
16067 api_get_node_graph (vat_main_t * vam)
16068 {
16069   vl_api_get_node_graph_t *mp;
16070   int ret;
16071
16072   M (GET_NODE_GRAPH, mp);
16073
16074   /* send it... */
16075   S (mp);
16076   /* Wait for the reply */
16077   W (ret);
16078   return ret;
16079 }
16080
16081 /* *INDENT-OFF* */
16082 /** Used for parsing LISP eids */
16083 typedef CLIB_PACKED(struct{
16084   u8 addr[16];   /**< eid address */
16085   u32 len;       /**< prefix length if IP */
16086   u8 type;      /**< type of eid */
16087 }) lisp_eid_vat_t;
16088 /* *INDENT-ON* */
16089
16090 static uword
16091 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16092 {
16093   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16094
16095   memset (a, 0, sizeof (a[0]));
16096
16097   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16098     {
16099       a->type = 0;              /* ipv4 type */
16100     }
16101   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16102     {
16103       a->type = 1;              /* ipv6 type */
16104     }
16105   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16106     {
16107       a->type = 2;              /* mac type */
16108     }
16109   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16110     {
16111       a->type = 3;              /* NSH type */
16112       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16113       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16114     }
16115   else
16116     {
16117       return 0;
16118     }
16119
16120   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16121     {
16122       return 0;
16123     }
16124
16125   return 1;
16126 }
16127
16128 static int
16129 lisp_eid_size_vat (u8 type)
16130 {
16131   switch (type)
16132     {
16133     case 0:
16134       return 4;
16135     case 1:
16136       return 16;
16137     case 2:
16138       return 6;
16139     case 3:
16140       return 5;
16141     }
16142   return 0;
16143 }
16144
16145 static void
16146 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16147 {
16148   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16149 }
16150
16151 static int
16152 api_one_add_del_locator_set (vat_main_t * vam)
16153 {
16154   unformat_input_t *input = vam->input;
16155   vl_api_one_add_del_locator_set_t *mp;
16156   u8 is_add = 1;
16157   u8 *locator_set_name = NULL;
16158   u8 locator_set_name_set = 0;
16159   vl_api_local_locator_t locator, *locators = 0;
16160   u32 sw_if_index, priority, weight;
16161   u32 data_len = 0;
16162
16163   int ret;
16164   /* Parse args required to build the message */
16165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16166     {
16167       if (unformat (input, "del"))
16168         {
16169           is_add = 0;
16170         }
16171       else if (unformat (input, "locator-set %s", &locator_set_name))
16172         {
16173           locator_set_name_set = 1;
16174         }
16175       else if (unformat (input, "sw_if_index %u p %u w %u",
16176                          &sw_if_index, &priority, &weight))
16177         {
16178           locator.sw_if_index = htonl (sw_if_index);
16179           locator.priority = priority;
16180           locator.weight = weight;
16181           vec_add1 (locators, locator);
16182         }
16183       else
16184         if (unformat
16185             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16186              &sw_if_index, &priority, &weight))
16187         {
16188           locator.sw_if_index = htonl (sw_if_index);
16189           locator.priority = priority;
16190           locator.weight = weight;
16191           vec_add1 (locators, locator);
16192         }
16193       else
16194         break;
16195     }
16196
16197   if (locator_set_name_set == 0)
16198     {
16199       errmsg ("missing locator-set name");
16200       vec_free (locators);
16201       return -99;
16202     }
16203
16204   if (vec_len (locator_set_name) > 64)
16205     {
16206       errmsg ("locator-set name too long");
16207       vec_free (locator_set_name);
16208       vec_free (locators);
16209       return -99;
16210     }
16211   vec_add1 (locator_set_name, 0);
16212
16213   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16214
16215   /* Construct the API message */
16216   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16217
16218   mp->is_add = is_add;
16219   clib_memcpy (mp->locator_set_name, locator_set_name,
16220                vec_len (locator_set_name));
16221   vec_free (locator_set_name);
16222
16223   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16224   if (locators)
16225     clib_memcpy (mp->locators, locators, data_len);
16226   vec_free (locators);
16227
16228   /* send it... */
16229   S (mp);
16230
16231   /* Wait for a reply... */
16232   W (ret);
16233   return ret;
16234 }
16235
16236 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16237
16238 static int
16239 api_one_add_del_locator (vat_main_t * vam)
16240 {
16241   unformat_input_t *input = vam->input;
16242   vl_api_one_add_del_locator_t *mp;
16243   u32 tmp_if_index = ~0;
16244   u32 sw_if_index = ~0;
16245   u8 sw_if_index_set = 0;
16246   u8 sw_if_index_if_name_set = 0;
16247   u32 priority = ~0;
16248   u8 priority_set = 0;
16249   u32 weight = ~0;
16250   u8 weight_set = 0;
16251   u8 is_add = 1;
16252   u8 *locator_set_name = NULL;
16253   u8 locator_set_name_set = 0;
16254   int ret;
16255
16256   /* Parse args required to build the message */
16257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16258     {
16259       if (unformat (input, "del"))
16260         {
16261           is_add = 0;
16262         }
16263       else if (unformat (input, "locator-set %s", &locator_set_name))
16264         {
16265           locator_set_name_set = 1;
16266         }
16267       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16268                          &tmp_if_index))
16269         {
16270           sw_if_index_if_name_set = 1;
16271           sw_if_index = tmp_if_index;
16272         }
16273       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16274         {
16275           sw_if_index_set = 1;
16276           sw_if_index = tmp_if_index;
16277         }
16278       else if (unformat (input, "p %d", &priority))
16279         {
16280           priority_set = 1;
16281         }
16282       else if (unformat (input, "w %d", &weight))
16283         {
16284           weight_set = 1;
16285         }
16286       else
16287         break;
16288     }
16289
16290   if (locator_set_name_set == 0)
16291     {
16292       errmsg ("missing locator-set name");
16293       return -99;
16294     }
16295
16296   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16297     {
16298       errmsg ("missing sw_if_index");
16299       vec_free (locator_set_name);
16300       return -99;
16301     }
16302
16303   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16304     {
16305       errmsg ("cannot use both params interface name and sw_if_index");
16306       vec_free (locator_set_name);
16307       return -99;
16308     }
16309
16310   if (priority_set == 0)
16311     {
16312       errmsg ("missing locator-set priority");
16313       vec_free (locator_set_name);
16314       return -99;
16315     }
16316
16317   if (weight_set == 0)
16318     {
16319       errmsg ("missing locator-set weight");
16320       vec_free (locator_set_name);
16321       return -99;
16322     }
16323
16324   if (vec_len (locator_set_name) > 64)
16325     {
16326       errmsg ("locator-set name too long");
16327       vec_free (locator_set_name);
16328       return -99;
16329     }
16330   vec_add1 (locator_set_name, 0);
16331
16332   /* Construct the API message */
16333   M (ONE_ADD_DEL_LOCATOR, mp);
16334
16335   mp->is_add = is_add;
16336   mp->sw_if_index = ntohl (sw_if_index);
16337   mp->priority = priority;
16338   mp->weight = weight;
16339   clib_memcpy (mp->locator_set_name, locator_set_name,
16340                vec_len (locator_set_name));
16341   vec_free (locator_set_name);
16342
16343   /* send it... */
16344   S (mp);
16345
16346   /* Wait for a reply... */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 #define api_lisp_add_del_locator api_one_add_del_locator
16352
16353 uword
16354 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16355 {
16356   u32 *key_id = va_arg (*args, u32 *);
16357   u8 *s = 0;
16358
16359   if (unformat (input, "%s", &s))
16360     {
16361       if (!strcmp ((char *) s, "sha1"))
16362         key_id[0] = HMAC_SHA_1_96;
16363       else if (!strcmp ((char *) s, "sha256"))
16364         key_id[0] = HMAC_SHA_256_128;
16365       else
16366         {
16367           clib_warning ("invalid key_id: '%s'", s);
16368           key_id[0] = HMAC_NO_KEY;
16369         }
16370     }
16371   else
16372     return 0;
16373
16374   vec_free (s);
16375   return 1;
16376 }
16377
16378 static int
16379 api_one_add_del_local_eid (vat_main_t * vam)
16380 {
16381   unformat_input_t *input = vam->input;
16382   vl_api_one_add_del_local_eid_t *mp;
16383   u8 is_add = 1;
16384   u8 eid_set = 0;
16385   lisp_eid_vat_t _eid, *eid = &_eid;
16386   u8 *locator_set_name = 0;
16387   u8 locator_set_name_set = 0;
16388   u32 vni = 0;
16389   u16 key_id = 0;
16390   u8 *key = 0;
16391   int ret;
16392
16393   /* Parse args required to build the message */
16394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16395     {
16396       if (unformat (input, "del"))
16397         {
16398           is_add = 0;
16399         }
16400       else if (unformat (input, "vni %d", &vni))
16401         {
16402           ;
16403         }
16404       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16405         {
16406           eid_set = 1;
16407         }
16408       else if (unformat (input, "locator-set %s", &locator_set_name))
16409         {
16410           locator_set_name_set = 1;
16411         }
16412       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16413         ;
16414       else if (unformat (input, "secret-key %_%v%_", &key))
16415         ;
16416       else
16417         break;
16418     }
16419
16420   if (locator_set_name_set == 0)
16421     {
16422       errmsg ("missing locator-set name");
16423       return -99;
16424     }
16425
16426   if (0 == eid_set)
16427     {
16428       errmsg ("EID address not set!");
16429       vec_free (locator_set_name);
16430       return -99;
16431     }
16432
16433   if (key && (0 == key_id))
16434     {
16435       errmsg ("invalid key_id!");
16436       return -99;
16437     }
16438
16439   if (vec_len (key) > 64)
16440     {
16441       errmsg ("key too long");
16442       vec_free (key);
16443       return -99;
16444     }
16445
16446   if (vec_len (locator_set_name) > 64)
16447     {
16448       errmsg ("locator-set name too long");
16449       vec_free (locator_set_name);
16450       return -99;
16451     }
16452   vec_add1 (locator_set_name, 0);
16453
16454   /* Construct the API message */
16455   M (ONE_ADD_DEL_LOCAL_EID, mp);
16456
16457   mp->is_add = is_add;
16458   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16459   mp->eid_type = eid->type;
16460   mp->prefix_len = eid->len;
16461   mp->vni = clib_host_to_net_u32 (vni);
16462   mp->key_id = clib_host_to_net_u16 (key_id);
16463   clib_memcpy (mp->locator_set_name, locator_set_name,
16464                vec_len (locator_set_name));
16465   clib_memcpy (mp->key, key, vec_len (key));
16466
16467   vec_free (locator_set_name);
16468   vec_free (key);
16469
16470   /* send it... */
16471   S (mp);
16472
16473   /* Wait for a reply... */
16474   W (ret);
16475   return ret;
16476 }
16477
16478 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16479
16480 static int
16481 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16482 {
16483   u32 dp_table = 0, vni = 0;;
16484   unformat_input_t *input = vam->input;
16485   vl_api_gpe_add_del_fwd_entry_t *mp;
16486   u8 is_add = 1;
16487   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16488   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16489   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16490   u32 action = ~0, w;
16491   ip4_address_t rmt_rloc4, lcl_rloc4;
16492   ip6_address_t rmt_rloc6, lcl_rloc6;
16493   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16494   int ret;
16495
16496   memset (&rloc, 0, sizeof (rloc));
16497
16498   /* Parse args required to build the message */
16499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16500     {
16501       if (unformat (input, "del"))
16502         is_add = 0;
16503       else if (unformat (input, "add"))
16504         is_add = 1;
16505       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16506         {
16507           rmt_eid_set = 1;
16508         }
16509       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16510         {
16511           lcl_eid_set = 1;
16512         }
16513       else if (unformat (input, "vrf %d", &dp_table))
16514         ;
16515       else if (unformat (input, "bd %d", &dp_table))
16516         ;
16517       else if (unformat (input, "vni %d", &vni))
16518         ;
16519       else if (unformat (input, "w %d", &w))
16520         {
16521           if (!curr_rloc)
16522             {
16523               errmsg ("No RLOC configured for setting priority/weight!");
16524               return -99;
16525             }
16526           curr_rloc->weight = w;
16527         }
16528       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16529                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16530         {
16531           rloc.is_ip4 = 1;
16532
16533           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16534           rloc.weight = 0;
16535           vec_add1 (lcl_locs, rloc);
16536
16537           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16538           vec_add1 (rmt_locs, rloc);
16539           /* weight saved in rmt loc */
16540           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16541         }
16542       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16543                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16544         {
16545           rloc.is_ip4 = 0;
16546           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16547           rloc.weight = 0;
16548           vec_add1 (lcl_locs, rloc);
16549
16550           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16551           vec_add1 (rmt_locs, rloc);
16552           /* weight saved in rmt loc */
16553           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16554         }
16555       else if (unformat (input, "action %d", &action))
16556         {
16557           ;
16558         }
16559       else
16560         {
16561           clib_warning ("parse error '%U'", format_unformat_error, input);
16562           return -99;
16563         }
16564     }
16565
16566   if (!rmt_eid_set)
16567     {
16568       errmsg ("remote eid addresses not set");
16569       return -99;
16570     }
16571
16572   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16573     {
16574       errmsg ("eid types don't match");
16575       return -99;
16576     }
16577
16578   if (0 == rmt_locs && (u32) ~ 0 == action)
16579     {
16580       errmsg ("action not set for negative mapping");
16581       return -99;
16582     }
16583
16584   /* Construct the API message */
16585   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16586       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16587
16588   mp->is_add = is_add;
16589   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16590   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16591   mp->eid_type = rmt_eid->type;
16592   mp->dp_table = clib_host_to_net_u32 (dp_table);
16593   mp->vni = clib_host_to_net_u32 (vni);
16594   mp->rmt_len = rmt_eid->len;
16595   mp->lcl_len = lcl_eid->len;
16596   mp->action = action;
16597
16598   if (0 != rmt_locs && 0 != lcl_locs)
16599     {
16600       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16601       clib_memcpy (mp->locs, lcl_locs,
16602                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16603
16604       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16605       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16606                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16607     }
16608   vec_free (lcl_locs);
16609   vec_free (rmt_locs);
16610
16611   /* send it... */
16612   S (mp);
16613
16614   /* Wait for a reply... */
16615   W (ret);
16616   return ret;
16617 }
16618
16619 static int
16620 api_one_add_del_map_server (vat_main_t * vam)
16621 {
16622   unformat_input_t *input = vam->input;
16623   vl_api_one_add_del_map_server_t *mp;
16624   u8 is_add = 1;
16625   u8 ipv4_set = 0;
16626   u8 ipv6_set = 0;
16627   ip4_address_t ipv4;
16628   ip6_address_t ipv6;
16629   int ret;
16630
16631   /* Parse args required to build the message */
16632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16633     {
16634       if (unformat (input, "del"))
16635         {
16636           is_add = 0;
16637         }
16638       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16639         {
16640           ipv4_set = 1;
16641         }
16642       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16643         {
16644           ipv6_set = 1;
16645         }
16646       else
16647         break;
16648     }
16649
16650   if (ipv4_set && ipv6_set)
16651     {
16652       errmsg ("both eid v4 and v6 addresses set");
16653       return -99;
16654     }
16655
16656   if (!ipv4_set && !ipv6_set)
16657     {
16658       errmsg ("eid addresses not set");
16659       return -99;
16660     }
16661
16662   /* Construct the API message */
16663   M (ONE_ADD_DEL_MAP_SERVER, mp);
16664
16665   mp->is_add = is_add;
16666   if (ipv6_set)
16667     {
16668       mp->is_ipv6 = 1;
16669       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16670     }
16671   else
16672     {
16673       mp->is_ipv6 = 0;
16674       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16675     }
16676
16677   /* send it... */
16678   S (mp);
16679
16680   /* Wait for a reply... */
16681   W (ret);
16682   return ret;
16683 }
16684
16685 #define api_lisp_add_del_map_server api_one_add_del_map_server
16686
16687 static int
16688 api_one_add_del_map_resolver (vat_main_t * vam)
16689 {
16690   unformat_input_t *input = vam->input;
16691   vl_api_one_add_del_map_resolver_t *mp;
16692   u8 is_add = 1;
16693   u8 ipv4_set = 0;
16694   u8 ipv6_set = 0;
16695   ip4_address_t ipv4;
16696   ip6_address_t ipv6;
16697   int ret;
16698
16699   /* Parse args required to build the message */
16700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16701     {
16702       if (unformat (input, "del"))
16703         {
16704           is_add = 0;
16705         }
16706       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16707         {
16708           ipv4_set = 1;
16709         }
16710       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16711         {
16712           ipv6_set = 1;
16713         }
16714       else
16715         break;
16716     }
16717
16718   if (ipv4_set && ipv6_set)
16719     {
16720       errmsg ("both eid v4 and v6 addresses set");
16721       return -99;
16722     }
16723
16724   if (!ipv4_set && !ipv6_set)
16725     {
16726       errmsg ("eid addresses not set");
16727       return -99;
16728     }
16729
16730   /* Construct the API message */
16731   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16732
16733   mp->is_add = is_add;
16734   if (ipv6_set)
16735     {
16736       mp->is_ipv6 = 1;
16737       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16738     }
16739   else
16740     {
16741       mp->is_ipv6 = 0;
16742       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16743     }
16744
16745   /* send it... */
16746   S (mp);
16747
16748   /* Wait for a reply... */
16749   W (ret);
16750   return ret;
16751 }
16752
16753 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16754
16755 static int
16756 api_lisp_gpe_enable_disable (vat_main_t * vam)
16757 {
16758   unformat_input_t *input = vam->input;
16759   vl_api_gpe_enable_disable_t *mp;
16760   u8 is_set = 0;
16761   u8 is_en = 1;
16762   int ret;
16763
16764   /* Parse args required to build the message */
16765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16766     {
16767       if (unformat (input, "enable"))
16768         {
16769           is_set = 1;
16770           is_en = 1;
16771         }
16772       else if (unformat (input, "disable"))
16773         {
16774           is_set = 1;
16775           is_en = 0;
16776         }
16777       else
16778         break;
16779     }
16780
16781   if (is_set == 0)
16782     {
16783       errmsg ("Value not set");
16784       return -99;
16785     }
16786
16787   /* Construct the API message */
16788   M (GPE_ENABLE_DISABLE, mp);
16789
16790   mp->is_en = is_en;
16791
16792   /* send it... */
16793   S (mp);
16794
16795   /* Wait for a reply... */
16796   W (ret);
16797   return ret;
16798 }
16799
16800 static int
16801 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16802 {
16803   unformat_input_t *input = vam->input;
16804   vl_api_one_rloc_probe_enable_disable_t *mp;
16805   u8 is_set = 0;
16806   u8 is_en = 0;
16807   int ret;
16808
16809   /* Parse args required to build the message */
16810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16811     {
16812       if (unformat (input, "enable"))
16813         {
16814           is_set = 1;
16815           is_en = 1;
16816         }
16817       else if (unformat (input, "disable"))
16818         is_set = 1;
16819       else
16820         break;
16821     }
16822
16823   if (!is_set)
16824     {
16825       errmsg ("Value not set");
16826       return -99;
16827     }
16828
16829   /* Construct the API message */
16830   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16831
16832   mp->is_enabled = is_en;
16833
16834   /* send it... */
16835   S (mp);
16836
16837   /* Wait for a reply... */
16838   W (ret);
16839   return ret;
16840 }
16841
16842 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16843
16844 static int
16845 api_one_map_register_enable_disable (vat_main_t * vam)
16846 {
16847   unformat_input_t *input = vam->input;
16848   vl_api_one_map_register_enable_disable_t *mp;
16849   u8 is_set = 0;
16850   u8 is_en = 0;
16851   int ret;
16852
16853   /* Parse args required to build the message */
16854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16855     {
16856       if (unformat (input, "enable"))
16857         {
16858           is_set = 1;
16859           is_en = 1;
16860         }
16861       else if (unformat (input, "disable"))
16862         is_set = 1;
16863       else
16864         break;
16865     }
16866
16867   if (!is_set)
16868     {
16869       errmsg ("Value not set");
16870       return -99;
16871     }
16872
16873   /* Construct the API message */
16874   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16875
16876   mp->is_enabled = is_en;
16877
16878   /* send it... */
16879   S (mp);
16880
16881   /* Wait for a reply... */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16887
16888 static int
16889 api_one_enable_disable (vat_main_t * vam)
16890 {
16891   unformat_input_t *input = vam->input;
16892   vl_api_one_enable_disable_t *mp;
16893   u8 is_set = 0;
16894   u8 is_en = 0;
16895   int ret;
16896
16897   /* Parse args required to build the message */
16898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16899     {
16900       if (unformat (input, "enable"))
16901         {
16902           is_set = 1;
16903           is_en = 1;
16904         }
16905       else if (unformat (input, "disable"))
16906         {
16907           is_set = 1;
16908         }
16909       else
16910         break;
16911     }
16912
16913   if (!is_set)
16914     {
16915       errmsg ("Value not set");
16916       return -99;
16917     }
16918
16919   /* Construct the API message */
16920   M (ONE_ENABLE_DISABLE, mp);
16921
16922   mp->is_en = is_en;
16923
16924   /* send it... */
16925   S (mp);
16926
16927   /* Wait for a reply... */
16928   W (ret);
16929   return ret;
16930 }
16931
16932 #define api_lisp_enable_disable api_one_enable_disable
16933
16934 static int
16935 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16936 {
16937   unformat_input_t *input = vam->input;
16938   vl_api_one_enable_disable_xtr_mode_t *mp;
16939   u8 is_set = 0;
16940   u8 is_en = 0;
16941   int ret;
16942
16943   /* Parse args required to build the message */
16944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16945     {
16946       if (unformat (input, "enable"))
16947         {
16948           is_set = 1;
16949           is_en = 1;
16950         }
16951       else if (unformat (input, "disable"))
16952         {
16953           is_set = 1;
16954         }
16955       else
16956         break;
16957     }
16958
16959   if (!is_set)
16960     {
16961       errmsg ("Value not set");
16962       return -99;
16963     }
16964
16965   /* Construct the API message */
16966   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16967
16968   mp->is_en = is_en;
16969
16970   /* send it... */
16971   S (mp);
16972
16973   /* Wait for a reply... */
16974   W (ret);
16975   return ret;
16976 }
16977
16978 static int
16979 api_one_show_xtr_mode (vat_main_t * vam)
16980 {
16981   vl_api_one_show_xtr_mode_t *mp;
16982   int ret;
16983
16984   /* Construct the API message */
16985   M (ONE_SHOW_XTR_MODE, mp);
16986
16987   /* send it... */
16988   S (mp);
16989
16990   /* Wait for a reply... */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 static int
16996 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16997 {
16998   unformat_input_t *input = vam->input;
16999   vl_api_one_enable_disable_pitr_mode_t *mp;
17000   u8 is_set = 0;
17001   u8 is_en = 0;
17002   int ret;
17003
17004   /* Parse args required to build the message */
17005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006     {
17007       if (unformat (input, "enable"))
17008         {
17009           is_set = 1;
17010           is_en = 1;
17011         }
17012       else if (unformat (input, "disable"))
17013         {
17014           is_set = 1;
17015         }
17016       else
17017         break;
17018     }
17019
17020   if (!is_set)
17021     {
17022       errmsg ("Value not set");
17023       return -99;
17024     }
17025
17026   /* Construct the API message */
17027   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17028
17029   mp->is_en = is_en;
17030
17031   /* send it... */
17032   S (mp);
17033
17034   /* Wait for a reply... */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 static int
17040 api_one_show_pitr_mode (vat_main_t * vam)
17041 {
17042   vl_api_one_show_pitr_mode_t *mp;
17043   int ret;
17044
17045   /* Construct the API message */
17046   M (ONE_SHOW_PITR_MODE, mp);
17047
17048   /* send it... */
17049   S (mp);
17050
17051   /* Wait for a reply... */
17052   W (ret);
17053   return ret;
17054 }
17055
17056 static int
17057 api_one_enable_disable_petr_mode (vat_main_t * vam)
17058 {
17059   unformat_input_t *input = vam->input;
17060   vl_api_one_enable_disable_petr_mode_t *mp;
17061   u8 is_set = 0;
17062   u8 is_en = 0;
17063   int ret;
17064
17065   /* Parse args required to build the message */
17066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17067     {
17068       if (unformat (input, "enable"))
17069         {
17070           is_set = 1;
17071           is_en = 1;
17072         }
17073       else if (unformat (input, "disable"))
17074         {
17075           is_set = 1;
17076         }
17077       else
17078         break;
17079     }
17080
17081   if (!is_set)
17082     {
17083       errmsg ("Value not set");
17084       return -99;
17085     }
17086
17087   /* Construct the API message */
17088   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17089
17090   mp->is_en = is_en;
17091
17092   /* send it... */
17093   S (mp);
17094
17095   /* Wait for a reply... */
17096   W (ret);
17097   return ret;
17098 }
17099
17100 static int
17101 api_one_show_petr_mode (vat_main_t * vam)
17102 {
17103   vl_api_one_show_petr_mode_t *mp;
17104   int ret;
17105
17106   /* Construct the API message */
17107   M (ONE_SHOW_PETR_MODE, mp);
17108
17109   /* send it... */
17110   S (mp);
17111
17112   /* Wait for a reply... */
17113   W (ret);
17114   return ret;
17115 }
17116
17117 static int
17118 api_show_one_map_register_state (vat_main_t * vam)
17119 {
17120   vl_api_show_one_map_register_state_t *mp;
17121   int ret;
17122
17123   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17124
17125   /* send */
17126   S (mp);
17127
17128   /* wait for reply */
17129   W (ret);
17130   return ret;
17131 }
17132
17133 #define api_show_lisp_map_register_state api_show_one_map_register_state
17134
17135 static int
17136 api_show_one_rloc_probe_state (vat_main_t * vam)
17137 {
17138   vl_api_show_one_rloc_probe_state_t *mp;
17139   int ret;
17140
17141   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17142
17143   /* send */
17144   S (mp);
17145
17146   /* wait for reply */
17147   W (ret);
17148   return ret;
17149 }
17150
17151 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17152
17153 static int
17154 api_one_add_del_ndp_entry (vat_main_t * vam)
17155 {
17156   vl_api_one_add_del_ndp_entry_t *mp;
17157   unformat_input_t *input = vam->input;
17158   u8 is_add = 1;
17159   u8 mac_set = 0;
17160   u8 bd_set = 0;
17161   u8 ip_set = 0;
17162   u8 mac[6] = { 0, };
17163   u8 ip6[16] = { 0, };
17164   u32 bd = ~0;
17165   int ret;
17166
17167   /* Parse args required to build the message */
17168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17169     {
17170       if (unformat (input, "del"))
17171         is_add = 0;
17172       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17173         mac_set = 1;
17174       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17175         ip_set = 1;
17176       else if (unformat (input, "bd %d", &bd))
17177         bd_set = 1;
17178       else
17179         {
17180           errmsg ("parse error '%U'", format_unformat_error, input);
17181           return -99;
17182         }
17183     }
17184
17185   if (!bd_set || !ip_set || (!mac_set && is_add))
17186     {
17187       errmsg ("Missing BD, IP or MAC!");
17188       return -99;
17189     }
17190
17191   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17192   mp->is_add = is_add;
17193   clib_memcpy (mp->mac, mac, 6);
17194   mp->bd = clib_host_to_net_u32 (bd);
17195   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17196
17197   /* send */
17198   S (mp);
17199
17200   /* wait for reply */
17201   W (ret);
17202   return ret;
17203 }
17204
17205 static int
17206 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17207 {
17208   vl_api_one_add_del_l2_arp_entry_t *mp;
17209   unformat_input_t *input = vam->input;
17210   u8 is_add = 1;
17211   u8 mac_set = 0;
17212   u8 bd_set = 0;
17213   u8 ip_set = 0;
17214   u8 mac[6] = { 0, };
17215   u32 ip4 = 0, bd = ~0;
17216   int ret;
17217
17218   /* Parse args required to build the message */
17219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17220     {
17221       if (unformat (input, "del"))
17222         is_add = 0;
17223       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17224         mac_set = 1;
17225       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17226         ip_set = 1;
17227       else if (unformat (input, "bd %d", &bd))
17228         bd_set = 1;
17229       else
17230         {
17231           errmsg ("parse error '%U'", format_unformat_error, input);
17232           return -99;
17233         }
17234     }
17235
17236   if (!bd_set || !ip_set || (!mac_set && is_add))
17237     {
17238       errmsg ("Missing BD, IP or MAC!");
17239       return -99;
17240     }
17241
17242   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17243   mp->is_add = is_add;
17244   clib_memcpy (mp->mac, mac, 6);
17245   mp->bd = clib_host_to_net_u32 (bd);
17246   mp->ip4 = ip4;
17247
17248   /* send */
17249   S (mp);
17250
17251   /* wait for reply */
17252   W (ret);
17253   return ret;
17254 }
17255
17256 static int
17257 api_one_ndp_bd_get (vat_main_t * vam)
17258 {
17259   vl_api_one_ndp_bd_get_t *mp;
17260   int ret;
17261
17262   M (ONE_NDP_BD_GET, mp);
17263
17264   /* send */
17265   S (mp);
17266
17267   /* wait for reply */
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_one_ndp_entries_get (vat_main_t * vam)
17274 {
17275   vl_api_one_ndp_entries_get_t *mp;
17276   unformat_input_t *input = vam->input;
17277   u8 bd_set = 0;
17278   u32 bd = ~0;
17279   int ret;
17280
17281   /* Parse args required to build the message */
17282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17283     {
17284       if (unformat (input, "bd %d", &bd))
17285         bd_set = 1;
17286       else
17287         {
17288           errmsg ("parse error '%U'", format_unformat_error, input);
17289           return -99;
17290         }
17291     }
17292
17293   if (!bd_set)
17294     {
17295       errmsg ("Expected bridge domain!");
17296       return -99;
17297     }
17298
17299   M (ONE_NDP_ENTRIES_GET, mp);
17300   mp->bd = clib_host_to_net_u32 (bd);
17301
17302   /* send */
17303   S (mp);
17304
17305   /* wait for reply */
17306   W (ret);
17307   return ret;
17308 }
17309
17310 static int
17311 api_one_l2_arp_bd_get (vat_main_t * vam)
17312 {
17313   vl_api_one_l2_arp_bd_get_t *mp;
17314   int ret;
17315
17316   M (ONE_L2_ARP_BD_GET, mp);
17317
17318   /* send */
17319   S (mp);
17320
17321   /* wait for reply */
17322   W (ret);
17323   return ret;
17324 }
17325
17326 static int
17327 api_one_l2_arp_entries_get (vat_main_t * vam)
17328 {
17329   vl_api_one_l2_arp_entries_get_t *mp;
17330   unformat_input_t *input = vam->input;
17331   u8 bd_set = 0;
17332   u32 bd = ~0;
17333   int ret;
17334
17335   /* Parse args required to build the message */
17336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17337     {
17338       if (unformat (input, "bd %d", &bd))
17339         bd_set = 1;
17340       else
17341         {
17342           errmsg ("parse error '%U'", format_unformat_error, input);
17343           return -99;
17344         }
17345     }
17346
17347   if (!bd_set)
17348     {
17349       errmsg ("Expected bridge domain!");
17350       return -99;
17351     }
17352
17353   M (ONE_L2_ARP_ENTRIES_GET, mp);
17354   mp->bd = clib_host_to_net_u32 (bd);
17355
17356   /* send */
17357   S (mp);
17358
17359   /* wait for reply */
17360   W (ret);
17361   return ret;
17362 }
17363
17364 static int
17365 api_one_stats_enable_disable (vat_main_t * vam)
17366 {
17367   vl_api_one_stats_enable_disable_t *mp;
17368   unformat_input_t *input = vam->input;
17369   u8 is_set = 0;
17370   u8 is_en = 0;
17371   int ret;
17372
17373   /* Parse args required to build the message */
17374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17375     {
17376       if (unformat (input, "enable"))
17377         {
17378           is_set = 1;
17379           is_en = 1;
17380         }
17381       else if (unformat (input, "disable"))
17382         {
17383           is_set = 1;
17384         }
17385       else
17386         break;
17387     }
17388
17389   if (!is_set)
17390     {
17391       errmsg ("Value not set");
17392       return -99;
17393     }
17394
17395   M (ONE_STATS_ENABLE_DISABLE, mp);
17396   mp->is_en = is_en;
17397
17398   /* send */
17399   S (mp);
17400
17401   /* wait for reply */
17402   W (ret);
17403   return ret;
17404 }
17405
17406 static int
17407 api_show_one_stats_enable_disable (vat_main_t * vam)
17408 {
17409   vl_api_show_one_stats_enable_disable_t *mp;
17410   int ret;
17411
17412   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17413
17414   /* send */
17415   S (mp);
17416
17417   /* wait for reply */
17418   W (ret);
17419   return ret;
17420 }
17421
17422 static int
17423 api_show_one_map_request_mode (vat_main_t * vam)
17424 {
17425   vl_api_show_one_map_request_mode_t *mp;
17426   int ret;
17427
17428   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17429
17430   /* send */
17431   S (mp);
17432
17433   /* wait for reply */
17434   W (ret);
17435   return ret;
17436 }
17437
17438 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17439
17440 static int
17441 api_one_map_request_mode (vat_main_t * vam)
17442 {
17443   unformat_input_t *input = vam->input;
17444   vl_api_one_map_request_mode_t *mp;
17445   u8 mode = 0;
17446   int ret;
17447
17448   /* Parse args required to build the message */
17449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17450     {
17451       if (unformat (input, "dst-only"))
17452         mode = 0;
17453       else if (unformat (input, "src-dst"))
17454         mode = 1;
17455       else
17456         {
17457           errmsg ("parse error '%U'", format_unformat_error, input);
17458           return -99;
17459         }
17460     }
17461
17462   M (ONE_MAP_REQUEST_MODE, mp);
17463
17464   mp->mode = mode;
17465
17466   /* send */
17467   S (mp);
17468
17469   /* wait for reply */
17470   W (ret);
17471   return ret;
17472 }
17473
17474 #define api_lisp_map_request_mode api_one_map_request_mode
17475
17476 /**
17477  * Enable/disable ONE proxy ITR.
17478  *
17479  * @param vam vpp API test context
17480  * @return return code
17481  */
17482 static int
17483 api_one_pitr_set_locator_set (vat_main_t * vam)
17484 {
17485   u8 ls_name_set = 0;
17486   unformat_input_t *input = vam->input;
17487   vl_api_one_pitr_set_locator_set_t *mp;
17488   u8 is_add = 1;
17489   u8 *ls_name = 0;
17490   int ret;
17491
17492   /* Parse args required to build the message */
17493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (input, "del"))
17496         is_add = 0;
17497       else if (unformat (input, "locator-set %s", &ls_name))
17498         ls_name_set = 1;
17499       else
17500         {
17501           errmsg ("parse error '%U'", format_unformat_error, input);
17502           return -99;
17503         }
17504     }
17505
17506   if (!ls_name_set)
17507     {
17508       errmsg ("locator-set name not set!");
17509       return -99;
17510     }
17511
17512   M (ONE_PITR_SET_LOCATOR_SET, mp);
17513
17514   mp->is_add = is_add;
17515   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17516   vec_free (ls_name);
17517
17518   /* send */
17519   S (mp);
17520
17521   /* wait for reply */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17527
17528 static int
17529 api_one_nsh_set_locator_set (vat_main_t * vam)
17530 {
17531   u8 ls_name_set = 0;
17532   unformat_input_t *input = vam->input;
17533   vl_api_one_nsh_set_locator_set_t *mp;
17534   u8 is_add = 1;
17535   u8 *ls_name = 0;
17536   int ret;
17537
17538   /* Parse args required to build the message */
17539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17540     {
17541       if (unformat (input, "del"))
17542         is_add = 0;
17543       else if (unformat (input, "ls %s", &ls_name))
17544         ls_name_set = 1;
17545       else
17546         {
17547           errmsg ("parse error '%U'", format_unformat_error, input);
17548           return -99;
17549         }
17550     }
17551
17552   if (!ls_name_set && is_add)
17553     {
17554       errmsg ("locator-set name not set!");
17555       return -99;
17556     }
17557
17558   M (ONE_NSH_SET_LOCATOR_SET, mp);
17559
17560   mp->is_add = is_add;
17561   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17562   vec_free (ls_name);
17563
17564   /* send */
17565   S (mp);
17566
17567   /* wait for reply */
17568   W (ret);
17569   return ret;
17570 }
17571
17572 static int
17573 api_show_one_pitr (vat_main_t * vam)
17574 {
17575   vl_api_show_one_pitr_t *mp;
17576   int ret;
17577
17578   if (!vam->json_output)
17579     {
17580       print (vam->ofp, "%=20s", "lisp status:");
17581     }
17582
17583   M (SHOW_ONE_PITR, mp);
17584   /* send it... */
17585   S (mp);
17586
17587   /* Wait for a reply... */
17588   W (ret);
17589   return ret;
17590 }
17591
17592 #define api_show_lisp_pitr api_show_one_pitr
17593
17594 static int
17595 api_one_use_petr (vat_main_t * vam)
17596 {
17597   unformat_input_t *input = vam->input;
17598   vl_api_one_use_petr_t *mp;
17599   u8 is_add = 0;
17600   ip_address_t ip;
17601   int ret;
17602
17603   memset (&ip, 0, sizeof (ip));
17604
17605   /* Parse args required to build the message */
17606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17607     {
17608       if (unformat (input, "disable"))
17609         is_add = 0;
17610       else
17611         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17612         {
17613           is_add = 1;
17614           ip_addr_version (&ip) = IP4;
17615         }
17616       else
17617         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17618         {
17619           is_add = 1;
17620           ip_addr_version (&ip) = IP6;
17621         }
17622       else
17623         {
17624           errmsg ("parse error '%U'", format_unformat_error, input);
17625           return -99;
17626         }
17627     }
17628
17629   M (ONE_USE_PETR, mp);
17630
17631   mp->is_add = is_add;
17632   if (is_add)
17633     {
17634       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17635       if (mp->is_ip4)
17636         clib_memcpy (mp->address, &ip, 4);
17637       else
17638         clib_memcpy (mp->address, &ip, 16);
17639     }
17640
17641   /* send */
17642   S (mp);
17643
17644   /* wait for reply */
17645   W (ret);
17646   return ret;
17647 }
17648
17649 #define api_lisp_use_petr api_one_use_petr
17650
17651 static int
17652 api_show_one_nsh_mapping (vat_main_t * vam)
17653 {
17654   vl_api_show_one_use_petr_t *mp;
17655   int ret;
17656
17657   if (!vam->json_output)
17658     {
17659       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17660     }
17661
17662   M (SHOW_ONE_NSH_MAPPING, mp);
17663   /* send it... */
17664   S (mp);
17665
17666   /* Wait for a reply... */
17667   W (ret);
17668   return ret;
17669 }
17670
17671 static int
17672 api_show_one_use_petr (vat_main_t * vam)
17673 {
17674   vl_api_show_one_use_petr_t *mp;
17675   int ret;
17676
17677   if (!vam->json_output)
17678     {
17679       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17680     }
17681
17682   M (SHOW_ONE_USE_PETR, mp);
17683   /* send it... */
17684   S (mp);
17685
17686   /* Wait for a reply... */
17687   W (ret);
17688   return ret;
17689 }
17690
17691 #define api_show_lisp_use_petr api_show_one_use_petr
17692
17693 /**
17694  * Add/delete mapping between vni and vrf
17695  */
17696 static int
17697 api_one_eid_table_add_del_map (vat_main_t * vam)
17698 {
17699   unformat_input_t *input = vam->input;
17700   vl_api_one_eid_table_add_del_map_t *mp;
17701   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17702   u32 vni, vrf, bd_index;
17703   int ret;
17704
17705   /* Parse args required to build the message */
17706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17707     {
17708       if (unformat (input, "del"))
17709         is_add = 0;
17710       else if (unformat (input, "vrf %d", &vrf))
17711         vrf_set = 1;
17712       else if (unformat (input, "bd_index %d", &bd_index))
17713         bd_index_set = 1;
17714       else if (unformat (input, "vni %d", &vni))
17715         vni_set = 1;
17716       else
17717         break;
17718     }
17719
17720   if (!vni_set || (!vrf_set && !bd_index_set))
17721     {
17722       errmsg ("missing arguments!");
17723       return -99;
17724     }
17725
17726   if (vrf_set && bd_index_set)
17727     {
17728       errmsg ("error: both vrf and bd entered!");
17729       return -99;
17730     }
17731
17732   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17733
17734   mp->is_add = is_add;
17735   mp->vni = htonl (vni);
17736   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17737   mp->is_l2 = bd_index_set;
17738
17739   /* send */
17740   S (mp);
17741
17742   /* wait for reply */
17743   W (ret);
17744   return ret;
17745 }
17746
17747 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17748
17749 uword
17750 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17751 {
17752   u32 *action = va_arg (*args, u32 *);
17753   u8 *s = 0;
17754
17755   if (unformat (input, "%s", &s))
17756     {
17757       if (!strcmp ((char *) s, "no-action"))
17758         action[0] = 0;
17759       else if (!strcmp ((char *) s, "natively-forward"))
17760         action[0] = 1;
17761       else if (!strcmp ((char *) s, "send-map-request"))
17762         action[0] = 2;
17763       else if (!strcmp ((char *) s, "drop"))
17764         action[0] = 3;
17765       else
17766         {
17767           clib_warning ("invalid action: '%s'", s);
17768           action[0] = 3;
17769         }
17770     }
17771   else
17772     return 0;
17773
17774   vec_free (s);
17775   return 1;
17776 }
17777
17778 /**
17779  * Add/del remote mapping to/from ONE control plane
17780  *
17781  * @param vam vpp API test context
17782  * @return return code
17783  */
17784 static int
17785 api_one_add_del_remote_mapping (vat_main_t * vam)
17786 {
17787   unformat_input_t *input = vam->input;
17788   vl_api_one_add_del_remote_mapping_t *mp;
17789   u32 vni = 0;
17790   lisp_eid_vat_t _eid, *eid = &_eid;
17791   lisp_eid_vat_t _seid, *seid = &_seid;
17792   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17793   u32 action = ~0, p, w, data_len;
17794   ip4_address_t rloc4;
17795   ip6_address_t rloc6;
17796   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17797   int ret;
17798
17799   memset (&rloc, 0, sizeof (rloc));
17800
17801   /* Parse args required to build the message */
17802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17803     {
17804       if (unformat (input, "del-all"))
17805         {
17806           del_all = 1;
17807         }
17808       else if (unformat (input, "del"))
17809         {
17810           is_add = 0;
17811         }
17812       else if (unformat (input, "add"))
17813         {
17814           is_add = 1;
17815         }
17816       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17817         {
17818           eid_set = 1;
17819         }
17820       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17821         {
17822           seid_set = 1;
17823         }
17824       else if (unformat (input, "vni %d", &vni))
17825         {
17826           ;
17827         }
17828       else if (unformat (input, "p %d w %d", &p, &w))
17829         {
17830           if (!curr_rloc)
17831             {
17832               errmsg ("No RLOC configured for setting priority/weight!");
17833               return -99;
17834             }
17835           curr_rloc->priority = p;
17836           curr_rloc->weight = w;
17837         }
17838       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17839         {
17840           rloc.is_ip4 = 1;
17841           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17842           vec_add1 (rlocs, rloc);
17843           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17844         }
17845       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17846         {
17847           rloc.is_ip4 = 0;
17848           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17849           vec_add1 (rlocs, rloc);
17850           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17851         }
17852       else if (unformat (input, "action %U",
17853                          unformat_negative_mapping_action, &action))
17854         {
17855           ;
17856         }
17857       else
17858         {
17859           clib_warning ("parse error '%U'", format_unformat_error, input);
17860           return -99;
17861         }
17862     }
17863
17864   if (0 == eid_set)
17865     {
17866       errmsg ("missing params!");
17867       return -99;
17868     }
17869
17870   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17871     {
17872       errmsg ("no action set for negative map-reply!");
17873       return -99;
17874     }
17875
17876   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17877
17878   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17879   mp->is_add = is_add;
17880   mp->vni = htonl (vni);
17881   mp->action = (u8) action;
17882   mp->is_src_dst = seid_set;
17883   mp->eid_len = eid->len;
17884   mp->seid_len = seid->len;
17885   mp->del_all = del_all;
17886   mp->eid_type = eid->type;
17887   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17888   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17889
17890   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17891   clib_memcpy (mp->rlocs, rlocs, data_len);
17892   vec_free (rlocs);
17893
17894   /* send it... */
17895   S (mp);
17896
17897   /* Wait for a reply... */
17898   W (ret);
17899   return ret;
17900 }
17901
17902 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17903
17904 /**
17905  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17906  * forwarding entries in data-plane accordingly.
17907  *
17908  * @param vam vpp API test context
17909  * @return return code
17910  */
17911 static int
17912 api_one_add_del_adjacency (vat_main_t * vam)
17913 {
17914   unformat_input_t *input = vam->input;
17915   vl_api_one_add_del_adjacency_t *mp;
17916   u32 vni = 0;
17917   ip4_address_t leid4, reid4;
17918   ip6_address_t leid6, reid6;
17919   u8 reid_mac[6] = { 0 };
17920   u8 leid_mac[6] = { 0 };
17921   u8 reid_type, leid_type;
17922   u32 leid_len = 0, reid_len = 0, len;
17923   u8 is_add = 1;
17924   int ret;
17925
17926   leid_type = reid_type = (u8) ~ 0;
17927
17928   /* Parse args required to build the message */
17929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17930     {
17931       if (unformat (input, "del"))
17932         {
17933           is_add = 0;
17934         }
17935       else if (unformat (input, "add"))
17936         {
17937           is_add = 1;
17938         }
17939       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17940                          &reid4, &len))
17941         {
17942           reid_type = 0;        /* ipv4 */
17943           reid_len = len;
17944         }
17945       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17946                          &reid6, &len))
17947         {
17948           reid_type = 1;        /* ipv6 */
17949           reid_len = len;
17950         }
17951       else if (unformat (input, "reid %U", unformat_ethernet_address,
17952                          reid_mac))
17953         {
17954           reid_type = 2;        /* mac */
17955         }
17956       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17957                          &leid4, &len))
17958         {
17959           leid_type = 0;        /* ipv4 */
17960           leid_len = len;
17961         }
17962       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17963                          &leid6, &len))
17964         {
17965           leid_type = 1;        /* ipv6 */
17966           leid_len = len;
17967         }
17968       else if (unformat (input, "leid %U", unformat_ethernet_address,
17969                          leid_mac))
17970         {
17971           leid_type = 2;        /* mac */
17972         }
17973       else if (unformat (input, "vni %d", &vni))
17974         {
17975           ;
17976         }
17977       else
17978         {
17979           errmsg ("parse error '%U'", format_unformat_error, input);
17980           return -99;
17981         }
17982     }
17983
17984   if ((u8) ~ 0 == reid_type)
17985     {
17986       errmsg ("missing params!");
17987       return -99;
17988     }
17989
17990   if (leid_type != reid_type)
17991     {
17992       errmsg ("remote and local EIDs are of different types!");
17993       return -99;
17994     }
17995
17996   M (ONE_ADD_DEL_ADJACENCY, mp);
17997   mp->is_add = is_add;
17998   mp->vni = htonl (vni);
17999   mp->leid_len = leid_len;
18000   mp->reid_len = reid_len;
18001   mp->eid_type = reid_type;
18002
18003   switch (mp->eid_type)
18004     {
18005     case 0:
18006       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18007       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18008       break;
18009     case 1:
18010       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18011       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18012       break;
18013     case 2:
18014       clib_memcpy (mp->leid, leid_mac, 6);
18015       clib_memcpy (mp->reid, reid_mac, 6);
18016       break;
18017     default:
18018       errmsg ("unknown EID type %d!", mp->eid_type);
18019       return 0;
18020     }
18021
18022   /* send it... */
18023   S (mp);
18024
18025   /* Wait for a reply... */
18026   W (ret);
18027   return ret;
18028 }
18029
18030 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18031
18032 uword
18033 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18034 {
18035   u32 *mode = va_arg (*args, u32 *);
18036
18037   if (unformat (input, "lisp"))
18038     *mode = 0;
18039   else if (unformat (input, "vxlan"))
18040     *mode = 1;
18041   else
18042     return 0;
18043
18044   return 1;
18045 }
18046
18047 static int
18048 api_gpe_get_encap_mode (vat_main_t * vam)
18049 {
18050   vl_api_gpe_get_encap_mode_t *mp;
18051   int ret;
18052
18053   /* Construct the API message */
18054   M (GPE_GET_ENCAP_MODE, mp);
18055
18056   /* send it... */
18057   S (mp);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 static int
18065 api_gpe_set_encap_mode (vat_main_t * vam)
18066 {
18067   unformat_input_t *input = vam->input;
18068   vl_api_gpe_set_encap_mode_t *mp;
18069   int ret;
18070   u32 mode = 0;
18071
18072   /* Parse args required to build the message */
18073   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18074     {
18075       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18076         ;
18077       else
18078         break;
18079     }
18080
18081   /* Construct the API message */
18082   M (GPE_SET_ENCAP_MODE, mp);
18083
18084   mp->mode = mode;
18085
18086   /* send it... */
18087   S (mp);
18088
18089   /* Wait for a reply... */
18090   W (ret);
18091   return ret;
18092 }
18093
18094 static int
18095 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18096 {
18097   unformat_input_t *input = vam->input;
18098   vl_api_gpe_add_del_iface_t *mp;
18099   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18100   u32 dp_table = 0, vni = 0;
18101   int ret;
18102
18103   /* Parse args required to build the message */
18104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18105     {
18106       if (unformat (input, "up"))
18107         {
18108           action_set = 1;
18109           is_add = 1;
18110         }
18111       else if (unformat (input, "down"))
18112         {
18113           action_set = 1;
18114           is_add = 0;
18115         }
18116       else if (unformat (input, "table_id %d", &dp_table))
18117         {
18118           dp_table_set = 1;
18119         }
18120       else if (unformat (input, "bd_id %d", &dp_table))
18121         {
18122           dp_table_set = 1;
18123           is_l2 = 1;
18124         }
18125       else if (unformat (input, "vni %d", &vni))
18126         {
18127           vni_set = 1;
18128         }
18129       else
18130         break;
18131     }
18132
18133   if (action_set == 0)
18134     {
18135       errmsg ("Action not set");
18136       return -99;
18137     }
18138   if (dp_table_set == 0 || vni_set == 0)
18139     {
18140       errmsg ("vni and dp_table must be set");
18141       return -99;
18142     }
18143
18144   /* Construct the API message */
18145   M (GPE_ADD_DEL_IFACE, mp);
18146
18147   mp->is_add = is_add;
18148   mp->dp_table = clib_host_to_net_u32 (dp_table);
18149   mp->is_l2 = is_l2;
18150   mp->vni = clib_host_to_net_u32 (vni);
18151
18152   /* send it... */
18153   S (mp);
18154
18155   /* Wait for a reply... */
18156   W (ret);
18157   return ret;
18158 }
18159
18160 static int
18161 api_one_map_register_fallback_threshold (vat_main_t * vam)
18162 {
18163   unformat_input_t *input = vam->input;
18164   vl_api_one_map_register_fallback_threshold_t *mp;
18165   u32 value = 0;
18166   u8 is_set = 0;
18167   int ret;
18168
18169   /* Parse args required to build the message */
18170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18171     {
18172       if (unformat (input, "%u", &value))
18173         is_set = 1;
18174       else
18175         {
18176           clib_warning ("parse error '%U'", format_unformat_error, input);
18177           return -99;
18178         }
18179     }
18180
18181   if (!is_set)
18182     {
18183       errmsg ("fallback threshold value is missing!");
18184       return -99;
18185     }
18186
18187   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18188   mp->value = clib_host_to_net_u32 (value);
18189
18190   /* send it... */
18191   S (mp);
18192
18193   /* Wait for a reply... */
18194   W (ret);
18195   return ret;
18196 }
18197
18198 static int
18199 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18200 {
18201   vl_api_show_one_map_register_fallback_threshold_t *mp;
18202   int ret;
18203
18204   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18205
18206   /* send it... */
18207   S (mp);
18208
18209   /* Wait for a reply... */
18210   W (ret);
18211   return ret;
18212 }
18213
18214 uword
18215 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18216 {
18217   u32 *proto = va_arg (*args, u32 *);
18218
18219   if (unformat (input, "udp"))
18220     *proto = 1;
18221   else if (unformat (input, "api"))
18222     *proto = 2;
18223   else
18224     return 0;
18225
18226   return 1;
18227 }
18228
18229 static int
18230 api_one_set_transport_protocol (vat_main_t * vam)
18231 {
18232   unformat_input_t *input = vam->input;
18233   vl_api_one_set_transport_protocol_t *mp;
18234   u8 is_set = 0;
18235   u32 protocol = 0;
18236   int ret;
18237
18238   /* Parse args required to build the message */
18239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18240     {
18241       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18242         is_set = 1;
18243       else
18244         {
18245           clib_warning ("parse error '%U'", format_unformat_error, input);
18246           return -99;
18247         }
18248     }
18249
18250   if (!is_set)
18251     {
18252       errmsg ("Transport protocol missing!");
18253       return -99;
18254     }
18255
18256   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18257   mp->protocol = (u8) protocol;
18258
18259   /* send it... */
18260   S (mp);
18261
18262   /* Wait for a reply... */
18263   W (ret);
18264   return ret;
18265 }
18266
18267 static int
18268 api_one_get_transport_protocol (vat_main_t * vam)
18269 {
18270   vl_api_one_get_transport_protocol_t *mp;
18271   int ret;
18272
18273   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18274
18275   /* send it... */
18276   S (mp);
18277
18278   /* Wait for a reply... */
18279   W (ret);
18280   return ret;
18281 }
18282
18283 static int
18284 api_one_map_register_set_ttl (vat_main_t * vam)
18285 {
18286   unformat_input_t *input = vam->input;
18287   vl_api_one_map_register_set_ttl_t *mp;
18288   u32 ttl = 0;
18289   u8 is_set = 0;
18290   int ret;
18291
18292   /* Parse args required to build the message */
18293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18294     {
18295       if (unformat (input, "%u", &ttl))
18296         is_set = 1;
18297       else
18298         {
18299           clib_warning ("parse error '%U'", format_unformat_error, input);
18300           return -99;
18301         }
18302     }
18303
18304   if (!is_set)
18305     {
18306       errmsg ("TTL value missing!");
18307       return -99;
18308     }
18309
18310   M (ONE_MAP_REGISTER_SET_TTL, mp);
18311   mp->ttl = clib_host_to_net_u32 (ttl);
18312
18313   /* send it... */
18314   S (mp);
18315
18316   /* Wait for a reply... */
18317   W (ret);
18318   return ret;
18319 }
18320
18321 static int
18322 api_show_one_map_register_ttl (vat_main_t * vam)
18323 {
18324   vl_api_show_one_map_register_ttl_t *mp;
18325   int ret;
18326
18327   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18328
18329   /* send it... */
18330   S (mp);
18331
18332   /* Wait for a reply... */
18333   W (ret);
18334   return ret;
18335 }
18336
18337 /**
18338  * Add/del map request itr rlocs from ONE control plane and updates
18339  *
18340  * @param vam vpp API test context
18341  * @return return code
18342  */
18343 static int
18344 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18345 {
18346   unformat_input_t *input = vam->input;
18347   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18348   u8 *locator_set_name = 0;
18349   u8 locator_set_name_set = 0;
18350   u8 is_add = 1;
18351   int ret;
18352
18353   /* Parse args required to build the message */
18354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18355     {
18356       if (unformat (input, "del"))
18357         {
18358           is_add = 0;
18359         }
18360       else if (unformat (input, "%_%v%_", &locator_set_name))
18361         {
18362           locator_set_name_set = 1;
18363         }
18364       else
18365         {
18366           clib_warning ("parse error '%U'", format_unformat_error, input);
18367           return -99;
18368         }
18369     }
18370
18371   if (is_add && !locator_set_name_set)
18372     {
18373       errmsg ("itr-rloc is not set!");
18374       return -99;
18375     }
18376
18377   if (is_add && vec_len (locator_set_name) > 64)
18378     {
18379       errmsg ("itr-rloc locator-set name too long");
18380       vec_free (locator_set_name);
18381       return -99;
18382     }
18383
18384   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18385   mp->is_add = is_add;
18386   if (is_add)
18387     {
18388       clib_memcpy (mp->locator_set_name, locator_set_name,
18389                    vec_len (locator_set_name));
18390     }
18391   else
18392     {
18393       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18394     }
18395   vec_free (locator_set_name);
18396
18397   /* send it... */
18398   S (mp);
18399
18400   /* Wait for a reply... */
18401   W (ret);
18402   return ret;
18403 }
18404
18405 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18406
18407 static int
18408 api_one_locator_dump (vat_main_t * vam)
18409 {
18410   unformat_input_t *input = vam->input;
18411   vl_api_one_locator_dump_t *mp;
18412   vl_api_control_ping_t *mp_ping;
18413   u8 is_index_set = 0, is_name_set = 0;
18414   u8 *ls_name = 0;
18415   u32 ls_index = ~0;
18416   int ret;
18417
18418   /* Parse args required to build the message */
18419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18420     {
18421       if (unformat (input, "ls_name %_%v%_", &ls_name))
18422         {
18423           is_name_set = 1;
18424         }
18425       else if (unformat (input, "ls_index %d", &ls_index))
18426         {
18427           is_index_set = 1;
18428         }
18429       else
18430         {
18431           errmsg ("parse error '%U'", format_unformat_error, input);
18432           return -99;
18433         }
18434     }
18435
18436   if (!is_index_set && !is_name_set)
18437     {
18438       errmsg ("error: expected one of index or name!");
18439       return -99;
18440     }
18441
18442   if (is_index_set && is_name_set)
18443     {
18444       errmsg ("error: only one param expected!");
18445       return -99;
18446     }
18447
18448   if (vec_len (ls_name) > 62)
18449     {
18450       errmsg ("error: locator set name too long!");
18451       return -99;
18452     }
18453
18454   if (!vam->json_output)
18455     {
18456       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18457     }
18458
18459   M (ONE_LOCATOR_DUMP, mp);
18460   mp->is_index_set = is_index_set;
18461
18462   if (is_index_set)
18463     mp->ls_index = clib_host_to_net_u32 (ls_index);
18464   else
18465     {
18466       vec_add1 (ls_name, 0);
18467       strncpy ((char *) mp->ls_name, (char *) ls_name,
18468                sizeof (mp->ls_name) - 1);
18469     }
18470
18471   /* send it... */
18472   S (mp);
18473
18474   /* Use a control ping for synchronization */
18475   MPING (CONTROL_PING, mp_ping);
18476   S (mp_ping);
18477
18478   /* Wait for a reply... */
18479   W (ret);
18480   return ret;
18481 }
18482
18483 #define api_lisp_locator_dump api_one_locator_dump
18484
18485 static int
18486 api_one_locator_set_dump (vat_main_t * vam)
18487 {
18488   vl_api_one_locator_set_dump_t *mp;
18489   vl_api_control_ping_t *mp_ping;
18490   unformat_input_t *input = vam->input;
18491   u8 filter = 0;
18492   int ret;
18493
18494   /* Parse args required to build the message */
18495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18496     {
18497       if (unformat (input, "local"))
18498         {
18499           filter = 1;
18500         }
18501       else if (unformat (input, "remote"))
18502         {
18503           filter = 2;
18504         }
18505       else
18506         {
18507           errmsg ("parse error '%U'", format_unformat_error, input);
18508           return -99;
18509         }
18510     }
18511
18512   if (!vam->json_output)
18513     {
18514       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18515     }
18516
18517   M (ONE_LOCATOR_SET_DUMP, mp);
18518
18519   mp->filter = filter;
18520
18521   /* send it... */
18522   S (mp);
18523
18524   /* Use a control ping for synchronization */
18525   MPING (CONTROL_PING, mp_ping);
18526   S (mp_ping);
18527
18528   /* Wait for a reply... */
18529   W (ret);
18530   return ret;
18531 }
18532
18533 #define api_lisp_locator_set_dump api_one_locator_set_dump
18534
18535 static int
18536 api_one_eid_table_map_dump (vat_main_t * vam)
18537 {
18538   u8 is_l2 = 0;
18539   u8 mode_set = 0;
18540   unformat_input_t *input = vam->input;
18541   vl_api_one_eid_table_map_dump_t *mp;
18542   vl_api_control_ping_t *mp_ping;
18543   int ret;
18544
18545   /* Parse args required to build the message */
18546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18547     {
18548       if (unformat (input, "l2"))
18549         {
18550           is_l2 = 1;
18551           mode_set = 1;
18552         }
18553       else if (unformat (input, "l3"))
18554         {
18555           is_l2 = 0;
18556           mode_set = 1;
18557         }
18558       else
18559         {
18560           errmsg ("parse error '%U'", format_unformat_error, input);
18561           return -99;
18562         }
18563     }
18564
18565   if (!mode_set)
18566     {
18567       errmsg ("expected one of 'l2' or 'l3' parameter!");
18568       return -99;
18569     }
18570
18571   if (!vam->json_output)
18572     {
18573       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18574     }
18575
18576   M (ONE_EID_TABLE_MAP_DUMP, mp);
18577   mp->is_l2 = is_l2;
18578
18579   /* send it... */
18580   S (mp);
18581
18582   /* Use a control ping for synchronization */
18583   MPING (CONTROL_PING, mp_ping);
18584   S (mp_ping);
18585
18586   /* Wait for a reply... */
18587   W (ret);
18588   return ret;
18589 }
18590
18591 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18592
18593 static int
18594 api_one_eid_table_vni_dump (vat_main_t * vam)
18595 {
18596   vl_api_one_eid_table_vni_dump_t *mp;
18597   vl_api_control_ping_t *mp_ping;
18598   int ret;
18599
18600   if (!vam->json_output)
18601     {
18602       print (vam->ofp, "VNI");
18603     }
18604
18605   M (ONE_EID_TABLE_VNI_DUMP, mp);
18606
18607   /* send it... */
18608   S (mp);
18609
18610   /* Use a control ping for synchronization */
18611   MPING (CONTROL_PING, mp_ping);
18612   S (mp_ping);
18613
18614   /* Wait for a reply... */
18615   W (ret);
18616   return ret;
18617 }
18618
18619 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18620
18621 static int
18622 api_one_eid_table_dump (vat_main_t * vam)
18623 {
18624   unformat_input_t *i = vam->input;
18625   vl_api_one_eid_table_dump_t *mp;
18626   vl_api_control_ping_t *mp_ping;
18627   struct in_addr ip4;
18628   struct in6_addr ip6;
18629   u8 mac[6];
18630   u8 eid_type = ~0, eid_set = 0;
18631   u32 prefix_length = ~0, t, vni = 0;
18632   u8 filter = 0;
18633   int ret;
18634   lisp_nsh_api_t nsh;
18635
18636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18637     {
18638       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18639         {
18640           eid_set = 1;
18641           eid_type = 0;
18642           prefix_length = t;
18643         }
18644       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18645         {
18646           eid_set = 1;
18647           eid_type = 1;
18648           prefix_length = t;
18649         }
18650       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18651         {
18652           eid_set = 1;
18653           eid_type = 2;
18654         }
18655       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18656         {
18657           eid_set = 1;
18658           eid_type = 3;
18659         }
18660       else if (unformat (i, "vni %d", &t))
18661         {
18662           vni = t;
18663         }
18664       else if (unformat (i, "local"))
18665         {
18666           filter = 1;
18667         }
18668       else if (unformat (i, "remote"))
18669         {
18670           filter = 2;
18671         }
18672       else
18673         {
18674           errmsg ("parse error '%U'", format_unformat_error, i);
18675           return -99;
18676         }
18677     }
18678
18679   if (!vam->json_output)
18680     {
18681       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18682              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18683     }
18684
18685   M (ONE_EID_TABLE_DUMP, mp);
18686
18687   mp->filter = filter;
18688   if (eid_set)
18689     {
18690       mp->eid_set = 1;
18691       mp->vni = htonl (vni);
18692       mp->eid_type = eid_type;
18693       switch (eid_type)
18694         {
18695         case 0:
18696           mp->prefix_length = prefix_length;
18697           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18698           break;
18699         case 1:
18700           mp->prefix_length = prefix_length;
18701           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18702           break;
18703         case 2:
18704           clib_memcpy (mp->eid, mac, sizeof (mac));
18705           break;
18706         case 3:
18707           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18708           break;
18709         default:
18710           errmsg ("unknown EID type %d!", eid_type);
18711           return -99;
18712         }
18713     }
18714
18715   /* send it... */
18716   S (mp);
18717
18718   /* Use a control ping for synchronization */
18719   MPING (CONTROL_PING, mp_ping);
18720   S (mp_ping);
18721
18722   /* Wait for a reply... */
18723   W (ret);
18724   return ret;
18725 }
18726
18727 #define api_lisp_eid_table_dump api_one_eid_table_dump
18728
18729 static int
18730 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18731 {
18732   unformat_input_t *i = vam->input;
18733   vl_api_gpe_fwd_entries_get_t *mp;
18734   u8 vni_set = 0;
18735   u32 vni = ~0;
18736   int ret;
18737
18738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18739     {
18740       if (unformat (i, "vni %d", &vni))
18741         {
18742           vni_set = 1;
18743         }
18744       else
18745         {
18746           errmsg ("parse error '%U'", format_unformat_error, i);
18747           return -99;
18748         }
18749     }
18750
18751   if (!vni_set)
18752     {
18753       errmsg ("vni not set!");
18754       return -99;
18755     }
18756
18757   if (!vam->json_output)
18758     {
18759       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18760              "leid", "reid");
18761     }
18762
18763   M (GPE_FWD_ENTRIES_GET, mp);
18764   mp->vni = clib_host_to_net_u32 (vni);
18765
18766   /* send it... */
18767   S (mp);
18768
18769   /* Wait for a reply... */
18770   W (ret);
18771   return ret;
18772 }
18773
18774 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18775 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18776 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18777 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18778 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18779 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18780 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18781 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18782
18783 static int
18784 api_one_adjacencies_get (vat_main_t * vam)
18785 {
18786   unformat_input_t *i = vam->input;
18787   vl_api_one_adjacencies_get_t *mp;
18788   u8 vni_set = 0;
18789   u32 vni = ~0;
18790   int ret;
18791
18792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18793     {
18794       if (unformat (i, "vni %d", &vni))
18795         {
18796           vni_set = 1;
18797         }
18798       else
18799         {
18800           errmsg ("parse error '%U'", format_unformat_error, i);
18801           return -99;
18802         }
18803     }
18804
18805   if (!vni_set)
18806     {
18807       errmsg ("vni not set!");
18808       return -99;
18809     }
18810
18811   if (!vam->json_output)
18812     {
18813       print (vam->ofp, "%s %40s", "leid", "reid");
18814     }
18815
18816   M (ONE_ADJACENCIES_GET, mp);
18817   mp->vni = clib_host_to_net_u32 (vni);
18818
18819   /* send it... */
18820   S (mp);
18821
18822   /* Wait for a reply... */
18823   W (ret);
18824   return ret;
18825 }
18826
18827 #define api_lisp_adjacencies_get api_one_adjacencies_get
18828
18829 static int
18830 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18831 {
18832   unformat_input_t *i = vam->input;
18833   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18834   int ret;
18835   u8 ip_family_set = 0, is_ip4 = 1;
18836
18837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18838     {
18839       if (unformat (i, "ip4"))
18840         {
18841           ip_family_set = 1;
18842           is_ip4 = 1;
18843         }
18844       else if (unformat (i, "ip6"))
18845         {
18846           ip_family_set = 1;
18847           is_ip4 = 0;
18848         }
18849       else
18850         {
18851           errmsg ("parse error '%U'", format_unformat_error, i);
18852           return -99;
18853         }
18854     }
18855
18856   if (!ip_family_set)
18857     {
18858       errmsg ("ip family not set!");
18859       return -99;
18860     }
18861
18862   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18863   mp->is_ip4 = is_ip4;
18864
18865   /* send it... */
18866   S (mp);
18867
18868   /* Wait for a reply... */
18869   W (ret);
18870   return ret;
18871 }
18872
18873 static int
18874 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18875 {
18876   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18877   int ret;
18878
18879   if (!vam->json_output)
18880     {
18881       print (vam->ofp, "VNIs");
18882     }
18883
18884   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18885
18886   /* send it... */
18887   S (mp);
18888
18889   /* Wait for a reply... */
18890   W (ret);
18891   return ret;
18892 }
18893
18894 static int
18895 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18896 {
18897   unformat_input_t *i = vam->input;
18898   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18899   int ret = 0;
18900   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18901   struct in_addr ip4;
18902   struct in6_addr ip6;
18903   u32 table_id = 0, nh_sw_if_index = ~0;
18904
18905   memset (&ip4, 0, sizeof (ip4));
18906   memset (&ip6, 0, sizeof (ip6));
18907
18908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18909     {
18910       if (unformat (i, "del"))
18911         is_add = 0;
18912       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18913                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18914         {
18915           ip_set = 1;
18916           is_ip4 = 1;
18917         }
18918       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18919                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18920         {
18921           ip_set = 1;
18922           is_ip4 = 0;
18923         }
18924       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18925         {
18926           ip_set = 1;
18927           is_ip4 = 1;
18928           nh_sw_if_index = ~0;
18929         }
18930       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18931         {
18932           ip_set = 1;
18933           is_ip4 = 0;
18934           nh_sw_if_index = ~0;
18935         }
18936       else if (unformat (i, "table %d", &table_id))
18937         ;
18938       else
18939         {
18940           errmsg ("parse error '%U'", format_unformat_error, i);
18941           return -99;
18942         }
18943     }
18944
18945   if (!ip_set)
18946     {
18947       errmsg ("nh addr not set!");
18948       return -99;
18949     }
18950
18951   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18952   mp->is_add = is_add;
18953   mp->table_id = clib_host_to_net_u32 (table_id);
18954   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18955   mp->is_ip4 = is_ip4;
18956   if (is_ip4)
18957     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18958   else
18959     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18960
18961   /* send it... */
18962   S (mp);
18963
18964   /* Wait for a reply... */
18965   W (ret);
18966   return ret;
18967 }
18968
18969 static int
18970 api_one_map_server_dump (vat_main_t * vam)
18971 {
18972   vl_api_one_map_server_dump_t *mp;
18973   vl_api_control_ping_t *mp_ping;
18974   int ret;
18975
18976   if (!vam->json_output)
18977     {
18978       print (vam->ofp, "%=20s", "Map server");
18979     }
18980
18981   M (ONE_MAP_SERVER_DUMP, mp);
18982   /* send it... */
18983   S (mp);
18984
18985   /* Use a control ping for synchronization */
18986   MPING (CONTROL_PING, mp_ping);
18987   S (mp_ping);
18988
18989   /* Wait for a reply... */
18990   W (ret);
18991   return ret;
18992 }
18993
18994 #define api_lisp_map_server_dump api_one_map_server_dump
18995
18996 static int
18997 api_one_map_resolver_dump (vat_main_t * vam)
18998 {
18999   vl_api_one_map_resolver_dump_t *mp;
19000   vl_api_control_ping_t *mp_ping;
19001   int ret;
19002
19003   if (!vam->json_output)
19004     {
19005       print (vam->ofp, "%=20s", "Map resolver");
19006     }
19007
19008   M (ONE_MAP_RESOLVER_DUMP, mp);
19009   /* send it... */
19010   S (mp);
19011
19012   /* Use a control ping for synchronization */
19013   MPING (CONTROL_PING, mp_ping);
19014   S (mp_ping);
19015
19016   /* Wait for a reply... */
19017   W (ret);
19018   return ret;
19019 }
19020
19021 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19022
19023 static int
19024 api_one_stats_flush (vat_main_t * vam)
19025 {
19026   vl_api_one_stats_flush_t *mp;
19027   int ret = 0;
19028
19029   M (ONE_STATS_FLUSH, mp);
19030   S (mp);
19031   W (ret);
19032   return ret;
19033 }
19034
19035 static int
19036 api_one_stats_dump (vat_main_t * vam)
19037 {
19038   vl_api_one_stats_dump_t *mp;
19039   vl_api_control_ping_t *mp_ping;
19040   int ret;
19041
19042   M (ONE_STATS_DUMP, mp);
19043   /* send it... */
19044   S (mp);
19045
19046   /* Use a control ping for synchronization */
19047   MPING (CONTROL_PING, mp_ping);
19048   S (mp_ping);
19049
19050   /* Wait for a reply... */
19051   W (ret);
19052   return ret;
19053 }
19054
19055 static int
19056 api_show_one_status (vat_main_t * vam)
19057 {
19058   vl_api_show_one_status_t *mp;
19059   int ret;
19060
19061   if (!vam->json_output)
19062     {
19063       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19064     }
19065
19066   M (SHOW_ONE_STATUS, mp);
19067   /* send it... */
19068   S (mp);
19069   /* Wait for a reply... */
19070   W (ret);
19071   return ret;
19072 }
19073
19074 #define api_show_lisp_status api_show_one_status
19075
19076 static int
19077 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19078 {
19079   vl_api_gpe_fwd_entry_path_dump_t *mp;
19080   vl_api_control_ping_t *mp_ping;
19081   unformat_input_t *i = vam->input;
19082   u32 fwd_entry_index = ~0;
19083   int ret;
19084
19085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19086     {
19087       if (unformat (i, "index %d", &fwd_entry_index))
19088         ;
19089       else
19090         break;
19091     }
19092
19093   if (~0 == fwd_entry_index)
19094     {
19095       errmsg ("no index specified!");
19096       return -99;
19097     }
19098
19099   if (!vam->json_output)
19100     {
19101       print (vam->ofp, "first line");
19102     }
19103
19104   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19105
19106   /* send it... */
19107   S (mp);
19108   /* Use a control ping for synchronization */
19109   MPING (CONTROL_PING, mp_ping);
19110   S (mp_ping);
19111
19112   /* Wait for a reply... */
19113   W (ret);
19114   return ret;
19115 }
19116
19117 static int
19118 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19119 {
19120   vl_api_one_get_map_request_itr_rlocs_t *mp;
19121   int ret;
19122
19123   if (!vam->json_output)
19124     {
19125       print (vam->ofp, "%=20s", "itr-rlocs:");
19126     }
19127
19128   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19129   /* send it... */
19130   S (mp);
19131   /* Wait for a reply... */
19132   W (ret);
19133   return ret;
19134 }
19135
19136 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19137
19138 static int
19139 api_af_packet_create (vat_main_t * vam)
19140 {
19141   unformat_input_t *i = vam->input;
19142   vl_api_af_packet_create_t *mp;
19143   u8 *host_if_name = 0;
19144   u8 hw_addr[6];
19145   u8 random_hw_addr = 1;
19146   int ret;
19147
19148   memset (hw_addr, 0, sizeof (hw_addr));
19149
19150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19151     {
19152       if (unformat (i, "name %s", &host_if_name))
19153         vec_add1 (host_if_name, 0);
19154       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19155         random_hw_addr = 0;
19156       else
19157         break;
19158     }
19159
19160   if (!vec_len (host_if_name))
19161     {
19162       errmsg ("host-interface name must be specified");
19163       return -99;
19164     }
19165
19166   if (vec_len (host_if_name) > 64)
19167     {
19168       errmsg ("host-interface name too long");
19169       return -99;
19170     }
19171
19172   M (AF_PACKET_CREATE, mp);
19173
19174   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19175   clib_memcpy (mp->hw_addr, hw_addr, 6);
19176   mp->use_random_hw_addr = random_hw_addr;
19177   vec_free (host_if_name);
19178
19179   S (mp);
19180
19181   /* *INDENT-OFF* */
19182   W2 (ret,
19183       ({
19184         if (ret == 0)
19185           fprintf (vam->ofp ? vam->ofp : stderr,
19186                    " new sw_if_index = %d\n", vam->sw_if_index);
19187       }));
19188   /* *INDENT-ON* */
19189   return ret;
19190 }
19191
19192 static int
19193 api_af_packet_delete (vat_main_t * vam)
19194 {
19195   unformat_input_t *i = vam->input;
19196   vl_api_af_packet_delete_t *mp;
19197   u8 *host_if_name = 0;
19198   int ret;
19199
19200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19201     {
19202       if (unformat (i, "name %s", &host_if_name))
19203         vec_add1 (host_if_name, 0);
19204       else
19205         break;
19206     }
19207
19208   if (!vec_len (host_if_name))
19209     {
19210       errmsg ("host-interface name must be specified");
19211       return -99;
19212     }
19213
19214   if (vec_len (host_if_name) > 64)
19215     {
19216       errmsg ("host-interface name too long");
19217       return -99;
19218     }
19219
19220   M (AF_PACKET_DELETE, mp);
19221
19222   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19223   vec_free (host_if_name);
19224
19225   S (mp);
19226   W (ret);
19227   return ret;
19228 }
19229
19230 static int
19231 api_policer_add_del (vat_main_t * vam)
19232 {
19233   unformat_input_t *i = vam->input;
19234   vl_api_policer_add_del_t *mp;
19235   u8 is_add = 1;
19236   u8 *name = 0;
19237   u32 cir = 0;
19238   u32 eir = 0;
19239   u64 cb = 0;
19240   u64 eb = 0;
19241   u8 rate_type = 0;
19242   u8 round_type = 0;
19243   u8 type = 0;
19244   u8 color_aware = 0;
19245   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19246   int ret;
19247
19248   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19249   conform_action.dscp = 0;
19250   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19251   exceed_action.dscp = 0;
19252   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19253   violate_action.dscp = 0;
19254
19255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19256     {
19257       if (unformat (i, "del"))
19258         is_add = 0;
19259       else if (unformat (i, "name %s", &name))
19260         vec_add1 (name, 0);
19261       else if (unformat (i, "cir %u", &cir))
19262         ;
19263       else if (unformat (i, "eir %u", &eir))
19264         ;
19265       else if (unformat (i, "cb %u", &cb))
19266         ;
19267       else if (unformat (i, "eb %u", &eb))
19268         ;
19269       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19270                          &rate_type))
19271         ;
19272       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19273                          &round_type))
19274         ;
19275       else if (unformat (i, "type %U", unformat_policer_type, &type))
19276         ;
19277       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19278                          &conform_action))
19279         ;
19280       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19281                          &exceed_action))
19282         ;
19283       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19284                          &violate_action))
19285         ;
19286       else if (unformat (i, "color-aware"))
19287         color_aware = 1;
19288       else
19289         break;
19290     }
19291
19292   if (!vec_len (name))
19293     {
19294       errmsg ("policer name must be specified");
19295       return -99;
19296     }
19297
19298   if (vec_len (name) > 64)
19299     {
19300       errmsg ("policer name too long");
19301       return -99;
19302     }
19303
19304   M (POLICER_ADD_DEL, mp);
19305
19306   clib_memcpy (mp->name, name, vec_len (name));
19307   vec_free (name);
19308   mp->is_add = is_add;
19309   mp->cir = ntohl (cir);
19310   mp->eir = ntohl (eir);
19311   mp->cb = clib_net_to_host_u64 (cb);
19312   mp->eb = clib_net_to_host_u64 (eb);
19313   mp->rate_type = rate_type;
19314   mp->round_type = round_type;
19315   mp->type = type;
19316   mp->conform_action_type = conform_action.action_type;
19317   mp->conform_dscp = conform_action.dscp;
19318   mp->exceed_action_type = exceed_action.action_type;
19319   mp->exceed_dscp = exceed_action.dscp;
19320   mp->violate_action_type = violate_action.action_type;
19321   mp->violate_dscp = violate_action.dscp;
19322   mp->color_aware = color_aware;
19323
19324   S (mp);
19325   W (ret);
19326   return ret;
19327 }
19328
19329 static int
19330 api_policer_dump (vat_main_t * vam)
19331 {
19332   unformat_input_t *i = vam->input;
19333   vl_api_policer_dump_t *mp;
19334   vl_api_control_ping_t *mp_ping;
19335   u8 *match_name = 0;
19336   u8 match_name_valid = 0;
19337   int ret;
19338
19339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19340     {
19341       if (unformat (i, "name %s", &match_name))
19342         {
19343           vec_add1 (match_name, 0);
19344           match_name_valid = 1;
19345         }
19346       else
19347         break;
19348     }
19349
19350   M (POLICER_DUMP, mp);
19351   mp->match_name_valid = match_name_valid;
19352   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19353   vec_free (match_name);
19354   /* send it... */
19355   S (mp);
19356
19357   /* Use a control ping for synchronization */
19358   MPING (CONTROL_PING, mp_ping);
19359   S (mp_ping);
19360
19361   /* Wait for a reply... */
19362   W (ret);
19363   return ret;
19364 }
19365
19366 static int
19367 api_policer_classify_set_interface (vat_main_t * vam)
19368 {
19369   unformat_input_t *i = vam->input;
19370   vl_api_policer_classify_set_interface_t *mp;
19371   u32 sw_if_index;
19372   int sw_if_index_set;
19373   u32 ip4_table_index = ~0;
19374   u32 ip6_table_index = ~0;
19375   u32 l2_table_index = ~0;
19376   u8 is_add = 1;
19377   int ret;
19378
19379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19380     {
19381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19382         sw_if_index_set = 1;
19383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19384         sw_if_index_set = 1;
19385       else if (unformat (i, "del"))
19386         is_add = 0;
19387       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19388         ;
19389       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19390         ;
19391       else if (unformat (i, "l2-table %d", &l2_table_index))
19392         ;
19393       else
19394         {
19395           clib_warning ("parse error '%U'", format_unformat_error, i);
19396           return -99;
19397         }
19398     }
19399
19400   if (sw_if_index_set == 0)
19401     {
19402       errmsg ("missing interface name or sw_if_index");
19403       return -99;
19404     }
19405
19406   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19407
19408   mp->sw_if_index = ntohl (sw_if_index);
19409   mp->ip4_table_index = ntohl (ip4_table_index);
19410   mp->ip6_table_index = ntohl (ip6_table_index);
19411   mp->l2_table_index = ntohl (l2_table_index);
19412   mp->is_add = is_add;
19413
19414   S (mp);
19415   W (ret);
19416   return ret;
19417 }
19418
19419 static int
19420 api_policer_classify_dump (vat_main_t * vam)
19421 {
19422   unformat_input_t *i = vam->input;
19423   vl_api_policer_classify_dump_t *mp;
19424   vl_api_control_ping_t *mp_ping;
19425   u8 type = POLICER_CLASSIFY_N_TABLES;
19426   int ret;
19427
19428   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19429     ;
19430   else
19431     {
19432       errmsg ("classify table type must be specified");
19433       return -99;
19434     }
19435
19436   if (!vam->json_output)
19437     {
19438       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19439     }
19440
19441   M (POLICER_CLASSIFY_DUMP, mp);
19442   mp->type = type;
19443   /* send it... */
19444   S (mp);
19445
19446   /* Use a control ping for synchronization */
19447   MPING (CONTROL_PING, mp_ping);
19448   S (mp_ping);
19449
19450   /* Wait for a reply... */
19451   W (ret);
19452   return ret;
19453 }
19454
19455 static int
19456 api_netmap_create (vat_main_t * vam)
19457 {
19458   unformat_input_t *i = vam->input;
19459   vl_api_netmap_create_t *mp;
19460   u8 *if_name = 0;
19461   u8 hw_addr[6];
19462   u8 random_hw_addr = 1;
19463   u8 is_pipe = 0;
19464   u8 is_master = 0;
19465   int ret;
19466
19467   memset (hw_addr, 0, sizeof (hw_addr));
19468
19469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19470     {
19471       if (unformat (i, "name %s", &if_name))
19472         vec_add1 (if_name, 0);
19473       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19474         random_hw_addr = 0;
19475       else if (unformat (i, "pipe"))
19476         is_pipe = 1;
19477       else if (unformat (i, "master"))
19478         is_master = 1;
19479       else if (unformat (i, "slave"))
19480         is_master = 0;
19481       else
19482         break;
19483     }
19484
19485   if (!vec_len (if_name))
19486     {
19487       errmsg ("interface name must be specified");
19488       return -99;
19489     }
19490
19491   if (vec_len (if_name) > 64)
19492     {
19493       errmsg ("interface name too long");
19494       return -99;
19495     }
19496
19497   M (NETMAP_CREATE, mp);
19498
19499   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19500   clib_memcpy (mp->hw_addr, hw_addr, 6);
19501   mp->use_random_hw_addr = random_hw_addr;
19502   mp->is_pipe = is_pipe;
19503   mp->is_master = is_master;
19504   vec_free (if_name);
19505
19506   S (mp);
19507   W (ret);
19508   return ret;
19509 }
19510
19511 static int
19512 api_netmap_delete (vat_main_t * vam)
19513 {
19514   unformat_input_t *i = vam->input;
19515   vl_api_netmap_delete_t *mp;
19516   u8 *if_name = 0;
19517   int ret;
19518
19519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19520     {
19521       if (unformat (i, "name %s", &if_name))
19522         vec_add1 (if_name, 0);
19523       else
19524         break;
19525     }
19526
19527   if (!vec_len (if_name))
19528     {
19529       errmsg ("interface name must be specified");
19530       return -99;
19531     }
19532
19533   if (vec_len (if_name) > 64)
19534     {
19535       errmsg ("interface name too long");
19536       return -99;
19537     }
19538
19539   M (NETMAP_DELETE, mp);
19540
19541   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19542   vec_free (if_name);
19543
19544   S (mp);
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static void
19550 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19551 {
19552   if (fp->afi == IP46_TYPE_IP6)
19553     print (vam->ofp,
19554            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19555            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19556            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19557            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19558            format_ip6_address, fp->next_hop);
19559   else if (fp->afi == IP46_TYPE_IP4)
19560     print (vam->ofp,
19561            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19562            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19563            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19564            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19565            format_ip4_address, fp->next_hop);
19566 }
19567
19568 static void
19569 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19570                                  vl_api_fib_path2_t * fp)
19571 {
19572   struct in_addr ip4;
19573   struct in6_addr ip6;
19574
19575   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19576   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19577   vat_json_object_add_uint (node, "is_local", fp->is_local);
19578   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19579   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19580   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19581   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19582   if (fp->afi == IP46_TYPE_IP4)
19583     {
19584       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19585       vat_json_object_add_ip4 (node, "next_hop", ip4);
19586     }
19587   else if (fp->afi == IP46_TYPE_IP6)
19588     {
19589       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19590       vat_json_object_add_ip6 (node, "next_hop", ip6);
19591     }
19592 }
19593
19594 static void
19595 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19596 {
19597   vat_main_t *vam = &vat_main;
19598   int count = ntohl (mp->mt_count);
19599   vl_api_fib_path2_t *fp;
19600   i32 i;
19601
19602   print (vam->ofp, "[%d]: sw_if_index %d via:",
19603          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19604   fp = mp->mt_paths;
19605   for (i = 0; i < count; i++)
19606     {
19607       vl_api_mpls_fib_path_print (vam, fp);
19608       fp++;
19609     }
19610
19611   print (vam->ofp, "");
19612 }
19613
19614 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19615 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19616
19617 static void
19618 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19619 {
19620   vat_main_t *vam = &vat_main;
19621   vat_json_node_t *node = NULL;
19622   int count = ntohl (mp->mt_count);
19623   vl_api_fib_path2_t *fp;
19624   i32 i;
19625
19626   if (VAT_JSON_ARRAY != vam->json_tree.type)
19627     {
19628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19629       vat_json_init_array (&vam->json_tree);
19630     }
19631   node = vat_json_array_add (&vam->json_tree);
19632
19633   vat_json_init_object (node);
19634   vat_json_object_add_uint (node, "tunnel_index",
19635                             ntohl (mp->mt_tunnel_index));
19636   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19637
19638   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19639
19640   fp = mp->mt_paths;
19641   for (i = 0; i < count; i++)
19642     {
19643       vl_api_mpls_fib_path_json_print (node, fp);
19644       fp++;
19645     }
19646 }
19647
19648 static int
19649 api_mpls_tunnel_dump (vat_main_t * vam)
19650 {
19651   vl_api_mpls_tunnel_dump_t *mp;
19652   vl_api_control_ping_t *mp_ping;
19653   i32 index = -1;
19654   int ret;
19655
19656   /* Parse args required to build the message */
19657   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19658     {
19659       if (!unformat (vam->input, "tunnel_index %d", &index))
19660         {
19661           index = -1;
19662           break;
19663         }
19664     }
19665
19666   print (vam->ofp, "  tunnel_index %d", index);
19667
19668   M (MPLS_TUNNEL_DUMP, mp);
19669   mp->tunnel_index = htonl (index);
19670   S (mp);
19671
19672   /* Use a control ping for synchronization */
19673   MPING (CONTROL_PING, mp_ping);
19674   S (mp_ping);
19675
19676   W (ret);
19677   return ret;
19678 }
19679
19680 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19681 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19682
19683
19684 static void
19685 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19686 {
19687   vat_main_t *vam = &vat_main;
19688   int count = ntohl (mp->count);
19689   vl_api_fib_path2_t *fp;
19690   int i;
19691
19692   print (vam->ofp,
19693          "table-id %d, label %u, ess_bit %u",
19694          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19695   fp = mp->path;
19696   for (i = 0; i < count; i++)
19697     {
19698       vl_api_mpls_fib_path_print (vam, fp);
19699       fp++;
19700     }
19701 }
19702
19703 static void vl_api_mpls_fib_details_t_handler_json
19704   (vl_api_mpls_fib_details_t * mp)
19705 {
19706   vat_main_t *vam = &vat_main;
19707   int count = ntohl (mp->count);
19708   vat_json_node_t *node = NULL;
19709   vl_api_fib_path2_t *fp;
19710   int i;
19711
19712   if (VAT_JSON_ARRAY != vam->json_tree.type)
19713     {
19714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19715       vat_json_init_array (&vam->json_tree);
19716     }
19717   node = vat_json_array_add (&vam->json_tree);
19718
19719   vat_json_init_object (node);
19720   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19721   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19722   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19723   vat_json_object_add_uint (node, "path_count", count);
19724   fp = mp->path;
19725   for (i = 0; i < count; i++)
19726     {
19727       vl_api_mpls_fib_path_json_print (node, fp);
19728       fp++;
19729     }
19730 }
19731
19732 static int
19733 api_mpls_fib_dump (vat_main_t * vam)
19734 {
19735   vl_api_mpls_fib_dump_t *mp;
19736   vl_api_control_ping_t *mp_ping;
19737   int ret;
19738
19739   M (MPLS_FIB_DUMP, mp);
19740   S (mp);
19741
19742   /* Use a control ping for synchronization */
19743   MPING (CONTROL_PING, mp_ping);
19744   S (mp_ping);
19745
19746   W (ret);
19747   return ret;
19748 }
19749
19750 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19751 #define vl_api_ip_fib_details_t_print vl_noop_handler
19752
19753 static void
19754 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19755 {
19756   vat_main_t *vam = &vat_main;
19757   int count = ntohl (mp->count);
19758   vl_api_fib_path_t *fp;
19759   int i;
19760
19761   print (vam->ofp,
19762          "table-id %d, prefix %U/%d",
19763          ntohl (mp->table_id), format_ip4_address, mp->address,
19764          mp->address_length);
19765   fp = mp->path;
19766   for (i = 0; i < count; i++)
19767     {
19768       if (fp->afi == IP46_TYPE_IP6)
19769         print (vam->ofp,
19770                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19771                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19772                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19773                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19774                format_ip6_address, fp->next_hop);
19775       else if (fp->afi == IP46_TYPE_IP4)
19776         print (vam->ofp,
19777                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19778                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19779                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19780                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19781                format_ip4_address, fp->next_hop);
19782       fp++;
19783     }
19784 }
19785
19786 static void vl_api_ip_fib_details_t_handler_json
19787   (vl_api_ip_fib_details_t * mp)
19788 {
19789   vat_main_t *vam = &vat_main;
19790   int count = ntohl (mp->count);
19791   vat_json_node_t *node = NULL;
19792   struct in_addr ip4;
19793   struct in6_addr ip6;
19794   vl_api_fib_path_t *fp;
19795   int i;
19796
19797   if (VAT_JSON_ARRAY != vam->json_tree.type)
19798     {
19799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19800       vat_json_init_array (&vam->json_tree);
19801     }
19802   node = vat_json_array_add (&vam->json_tree);
19803
19804   vat_json_init_object (node);
19805   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19806   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19807   vat_json_object_add_ip4 (node, "prefix", ip4);
19808   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19809   vat_json_object_add_uint (node, "path_count", count);
19810   fp = mp->path;
19811   for (i = 0; i < count; i++)
19812     {
19813       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19814       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19815       vat_json_object_add_uint (node, "is_local", fp->is_local);
19816       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19817       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19818       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19819       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19820       if (fp->afi == IP46_TYPE_IP4)
19821         {
19822           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19823           vat_json_object_add_ip4 (node, "next_hop", ip4);
19824         }
19825       else if (fp->afi == IP46_TYPE_IP6)
19826         {
19827           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19828           vat_json_object_add_ip6 (node, "next_hop", ip6);
19829         }
19830     }
19831 }
19832
19833 static int
19834 api_ip_fib_dump (vat_main_t * vam)
19835 {
19836   vl_api_ip_fib_dump_t *mp;
19837   vl_api_control_ping_t *mp_ping;
19838   int ret;
19839
19840   M (IP_FIB_DUMP, mp);
19841   S (mp);
19842
19843   /* Use a control ping for synchronization */
19844   MPING (CONTROL_PING, mp_ping);
19845   S (mp_ping);
19846
19847   W (ret);
19848   return ret;
19849 }
19850
19851 static int
19852 api_ip_mfib_dump (vat_main_t * vam)
19853 {
19854   vl_api_ip_mfib_dump_t *mp;
19855   vl_api_control_ping_t *mp_ping;
19856   int ret;
19857
19858   M (IP_MFIB_DUMP, mp);
19859   S (mp);
19860
19861   /* Use a control ping for synchronization */
19862   MPING (CONTROL_PING, mp_ping);
19863   S (mp_ping);
19864
19865   W (ret);
19866   return ret;
19867 }
19868
19869 static void vl_api_ip_neighbor_details_t_handler
19870   (vl_api_ip_neighbor_details_t * mp)
19871 {
19872   vat_main_t *vam = &vat_main;
19873
19874   print (vam->ofp, "%c %U %U",
19875          (mp->is_static) ? 'S' : 'D',
19876          format_ethernet_address, &mp->mac_address,
19877          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19878          &mp->ip_address);
19879 }
19880
19881 static void vl_api_ip_neighbor_details_t_handler_json
19882   (vl_api_ip_neighbor_details_t * mp)
19883 {
19884
19885   vat_main_t *vam = &vat_main;
19886   vat_json_node_t *node;
19887   struct in_addr ip4;
19888   struct in6_addr ip6;
19889
19890   if (VAT_JSON_ARRAY != vam->json_tree.type)
19891     {
19892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19893       vat_json_init_array (&vam->json_tree);
19894     }
19895   node = vat_json_array_add (&vam->json_tree);
19896
19897   vat_json_init_object (node);
19898   vat_json_object_add_string_copy (node, "flag",
19899                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19900                                    "dynamic");
19901
19902   vat_json_object_add_string_copy (node, "link_layer",
19903                                    format (0, "%U", format_ethernet_address,
19904                                            &mp->mac_address));
19905
19906   if (mp->is_ipv6)
19907     {
19908       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19909       vat_json_object_add_ip6 (node, "ip_address", ip6);
19910     }
19911   else
19912     {
19913       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19914       vat_json_object_add_ip4 (node, "ip_address", ip4);
19915     }
19916 }
19917
19918 static int
19919 api_ip_neighbor_dump (vat_main_t * vam)
19920 {
19921   unformat_input_t *i = vam->input;
19922   vl_api_ip_neighbor_dump_t *mp;
19923   vl_api_control_ping_t *mp_ping;
19924   u8 is_ipv6 = 0;
19925   u32 sw_if_index = ~0;
19926   int ret;
19927
19928   /* Parse args required to build the message */
19929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19930     {
19931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19932         ;
19933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19934         ;
19935       else if (unformat (i, "ip6"))
19936         is_ipv6 = 1;
19937       else
19938         break;
19939     }
19940
19941   if (sw_if_index == ~0)
19942     {
19943       errmsg ("missing interface name or sw_if_index");
19944       return -99;
19945     }
19946
19947   M (IP_NEIGHBOR_DUMP, mp);
19948   mp->is_ipv6 = (u8) is_ipv6;
19949   mp->sw_if_index = ntohl (sw_if_index);
19950   S (mp);
19951
19952   /* Use a control ping for synchronization */
19953   MPING (CONTROL_PING, mp_ping);
19954   S (mp_ping);
19955
19956   W (ret);
19957   return ret;
19958 }
19959
19960 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19961 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19962
19963 static void
19964 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19965 {
19966   vat_main_t *vam = &vat_main;
19967   int count = ntohl (mp->count);
19968   vl_api_fib_path_t *fp;
19969   int i;
19970
19971   print (vam->ofp,
19972          "table-id %d, prefix %U/%d",
19973          ntohl (mp->table_id), format_ip6_address, mp->address,
19974          mp->address_length);
19975   fp = mp->path;
19976   for (i = 0; i < count; i++)
19977     {
19978       if (fp->afi == IP46_TYPE_IP6)
19979         print (vam->ofp,
19980                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19981                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19982                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19983                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19984                format_ip6_address, fp->next_hop);
19985       else if (fp->afi == IP46_TYPE_IP4)
19986         print (vam->ofp,
19987                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19988                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19989                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19990                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19991                format_ip4_address, fp->next_hop);
19992       fp++;
19993     }
19994 }
19995
19996 static void vl_api_ip6_fib_details_t_handler_json
19997   (vl_api_ip6_fib_details_t * mp)
19998 {
19999   vat_main_t *vam = &vat_main;
20000   int count = ntohl (mp->count);
20001   vat_json_node_t *node = NULL;
20002   struct in_addr ip4;
20003   struct in6_addr ip6;
20004   vl_api_fib_path_t *fp;
20005   int i;
20006
20007   if (VAT_JSON_ARRAY != vam->json_tree.type)
20008     {
20009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20010       vat_json_init_array (&vam->json_tree);
20011     }
20012   node = vat_json_array_add (&vam->json_tree);
20013
20014   vat_json_init_object (node);
20015   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20016   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20017   vat_json_object_add_ip6 (node, "prefix", ip6);
20018   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20019   vat_json_object_add_uint (node, "path_count", count);
20020   fp = mp->path;
20021   for (i = 0; i < count; i++)
20022     {
20023       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20024       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20025       vat_json_object_add_uint (node, "is_local", fp->is_local);
20026       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20027       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20028       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20029       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20030       if (fp->afi == IP46_TYPE_IP4)
20031         {
20032           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20033           vat_json_object_add_ip4 (node, "next_hop", ip4);
20034         }
20035       else if (fp->afi == IP46_TYPE_IP6)
20036         {
20037           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20038           vat_json_object_add_ip6 (node, "next_hop", ip6);
20039         }
20040     }
20041 }
20042
20043 static int
20044 api_ip6_fib_dump (vat_main_t * vam)
20045 {
20046   vl_api_ip6_fib_dump_t *mp;
20047   vl_api_control_ping_t *mp_ping;
20048   int ret;
20049
20050   M (IP6_FIB_DUMP, mp);
20051   S (mp);
20052
20053   /* Use a control ping for synchronization */
20054   MPING (CONTROL_PING, mp_ping);
20055   S (mp_ping);
20056
20057   W (ret);
20058   return ret;
20059 }
20060
20061 static int
20062 api_ip6_mfib_dump (vat_main_t * vam)
20063 {
20064   vl_api_ip6_mfib_dump_t *mp;
20065   vl_api_control_ping_t *mp_ping;
20066   int ret;
20067
20068   M (IP6_MFIB_DUMP, mp);
20069   S (mp);
20070
20071   /* Use a control ping for synchronization */
20072   MPING (CONTROL_PING, mp_ping);
20073   S (mp_ping);
20074
20075   W (ret);
20076   return ret;
20077 }
20078
20079 int
20080 api_classify_table_ids (vat_main_t * vam)
20081 {
20082   vl_api_classify_table_ids_t *mp;
20083   int ret;
20084
20085   /* Construct the API message */
20086   M (CLASSIFY_TABLE_IDS, mp);
20087   mp->context = 0;
20088
20089   S (mp);
20090   W (ret);
20091   return ret;
20092 }
20093
20094 int
20095 api_classify_table_by_interface (vat_main_t * vam)
20096 {
20097   unformat_input_t *input = vam->input;
20098   vl_api_classify_table_by_interface_t *mp;
20099
20100   u32 sw_if_index = ~0;
20101   int ret;
20102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20103     {
20104       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20105         ;
20106       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20107         ;
20108       else
20109         break;
20110     }
20111   if (sw_if_index == ~0)
20112     {
20113       errmsg ("missing interface name or sw_if_index");
20114       return -99;
20115     }
20116
20117   /* Construct the API message */
20118   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20119   mp->context = 0;
20120   mp->sw_if_index = ntohl (sw_if_index);
20121
20122   S (mp);
20123   W (ret);
20124   return ret;
20125 }
20126
20127 int
20128 api_classify_table_info (vat_main_t * vam)
20129 {
20130   unformat_input_t *input = vam->input;
20131   vl_api_classify_table_info_t *mp;
20132
20133   u32 table_id = ~0;
20134   int ret;
20135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20136     {
20137       if (unformat (input, "table_id %d", &table_id))
20138         ;
20139       else
20140         break;
20141     }
20142   if (table_id == ~0)
20143     {
20144       errmsg ("missing table id");
20145       return -99;
20146     }
20147
20148   /* Construct the API message */
20149   M (CLASSIFY_TABLE_INFO, mp);
20150   mp->context = 0;
20151   mp->table_id = ntohl (table_id);
20152
20153   S (mp);
20154   W (ret);
20155   return ret;
20156 }
20157
20158 int
20159 api_classify_session_dump (vat_main_t * vam)
20160 {
20161   unformat_input_t *input = vam->input;
20162   vl_api_classify_session_dump_t *mp;
20163   vl_api_control_ping_t *mp_ping;
20164
20165   u32 table_id = ~0;
20166   int ret;
20167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20168     {
20169       if (unformat (input, "table_id %d", &table_id))
20170         ;
20171       else
20172         break;
20173     }
20174   if (table_id == ~0)
20175     {
20176       errmsg ("missing table id");
20177       return -99;
20178     }
20179
20180   /* Construct the API message */
20181   M (CLASSIFY_SESSION_DUMP, mp);
20182   mp->context = 0;
20183   mp->table_id = ntohl (table_id);
20184   S (mp);
20185
20186   /* Use a control ping for synchronization */
20187   MPING (CONTROL_PING, mp_ping);
20188   S (mp_ping);
20189
20190   W (ret);
20191   return ret;
20192 }
20193
20194 static void
20195 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20196 {
20197   vat_main_t *vam = &vat_main;
20198
20199   print (vam->ofp, "collector_address %U, collector_port %d, "
20200          "src_address %U, vrf_id %d, path_mtu %u, "
20201          "template_interval %u, udp_checksum %d",
20202          format_ip4_address, mp->collector_address,
20203          ntohs (mp->collector_port),
20204          format_ip4_address, mp->src_address,
20205          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20206          ntohl (mp->template_interval), mp->udp_checksum);
20207
20208   vam->retval = 0;
20209   vam->result_ready = 1;
20210 }
20211
20212 static void
20213   vl_api_ipfix_exporter_details_t_handler_json
20214   (vl_api_ipfix_exporter_details_t * mp)
20215 {
20216   vat_main_t *vam = &vat_main;
20217   vat_json_node_t node;
20218   struct in_addr collector_address;
20219   struct in_addr src_address;
20220
20221   vat_json_init_object (&node);
20222   clib_memcpy (&collector_address, &mp->collector_address,
20223                sizeof (collector_address));
20224   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20225   vat_json_object_add_uint (&node, "collector_port",
20226                             ntohs (mp->collector_port));
20227   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20228   vat_json_object_add_ip4 (&node, "src_address", src_address);
20229   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20230   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20231   vat_json_object_add_uint (&node, "template_interval",
20232                             ntohl (mp->template_interval));
20233   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20234
20235   vat_json_print (vam->ofp, &node);
20236   vat_json_free (&node);
20237   vam->retval = 0;
20238   vam->result_ready = 1;
20239 }
20240
20241 int
20242 api_ipfix_exporter_dump (vat_main_t * vam)
20243 {
20244   vl_api_ipfix_exporter_dump_t *mp;
20245   int ret;
20246
20247   /* Construct the API message */
20248   M (IPFIX_EXPORTER_DUMP, mp);
20249   mp->context = 0;
20250
20251   S (mp);
20252   W (ret);
20253   return ret;
20254 }
20255
20256 static int
20257 api_ipfix_classify_stream_dump (vat_main_t * vam)
20258 {
20259   vl_api_ipfix_classify_stream_dump_t *mp;
20260   int ret;
20261
20262   /* Construct the API message */
20263   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20264   mp->context = 0;
20265
20266   S (mp);
20267   W (ret);
20268   return ret;
20269   /* NOTREACHED */
20270   return 0;
20271 }
20272
20273 static void
20274   vl_api_ipfix_classify_stream_details_t_handler
20275   (vl_api_ipfix_classify_stream_details_t * mp)
20276 {
20277   vat_main_t *vam = &vat_main;
20278   print (vam->ofp, "domain_id %d, src_port %d",
20279          ntohl (mp->domain_id), ntohs (mp->src_port));
20280   vam->retval = 0;
20281   vam->result_ready = 1;
20282 }
20283
20284 static void
20285   vl_api_ipfix_classify_stream_details_t_handler_json
20286   (vl_api_ipfix_classify_stream_details_t * mp)
20287 {
20288   vat_main_t *vam = &vat_main;
20289   vat_json_node_t node;
20290
20291   vat_json_init_object (&node);
20292   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20293   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20294
20295   vat_json_print (vam->ofp, &node);
20296   vat_json_free (&node);
20297   vam->retval = 0;
20298   vam->result_ready = 1;
20299 }
20300
20301 static int
20302 api_ipfix_classify_table_dump (vat_main_t * vam)
20303 {
20304   vl_api_ipfix_classify_table_dump_t *mp;
20305   vl_api_control_ping_t *mp_ping;
20306   int ret;
20307
20308   if (!vam->json_output)
20309     {
20310       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20311              "transport_protocol");
20312     }
20313
20314   /* Construct the API message */
20315   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20316
20317   /* send it... */
20318   S (mp);
20319
20320   /* Use a control ping for synchronization */
20321   MPING (CONTROL_PING, mp_ping);
20322   S (mp_ping);
20323
20324   W (ret);
20325   return ret;
20326 }
20327
20328 static void
20329   vl_api_ipfix_classify_table_details_t_handler
20330   (vl_api_ipfix_classify_table_details_t * mp)
20331 {
20332   vat_main_t *vam = &vat_main;
20333   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20334          mp->transport_protocol);
20335 }
20336
20337 static void
20338   vl_api_ipfix_classify_table_details_t_handler_json
20339   (vl_api_ipfix_classify_table_details_t * mp)
20340 {
20341   vat_json_node_t *node = NULL;
20342   vat_main_t *vam = &vat_main;
20343
20344   if (VAT_JSON_ARRAY != vam->json_tree.type)
20345     {
20346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20347       vat_json_init_array (&vam->json_tree);
20348     }
20349
20350   node = vat_json_array_add (&vam->json_tree);
20351   vat_json_init_object (node);
20352
20353   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20354   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20355   vat_json_object_add_uint (node, "transport_protocol",
20356                             mp->transport_protocol);
20357 }
20358
20359 static int
20360 api_sw_interface_span_enable_disable (vat_main_t * vam)
20361 {
20362   unformat_input_t *i = vam->input;
20363   vl_api_sw_interface_span_enable_disable_t *mp;
20364   u32 src_sw_if_index = ~0;
20365   u32 dst_sw_if_index = ~0;
20366   u8 state = 3;
20367   int ret;
20368   u8 is_l2 = 0;
20369
20370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20371     {
20372       if (unformat
20373           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20374         ;
20375       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20376         ;
20377       else
20378         if (unformat
20379             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20380         ;
20381       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20382         ;
20383       else if (unformat (i, "disable"))
20384         state = 0;
20385       else if (unformat (i, "rx"))
20386         state = 1;
20387       else if (unformat (i, "tx"))
20388         state = 2;
20389       else if (unformat (i, "both"))
20390         state = 3;
20391       else if (unformat (i, "l2"))
20392         is_l2 = 1;
20393       else
20394         break;
20395     }
20396
20397   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20398
20399   mp->sw_if_index_from = htonl (src_sw_if_index);
20400   mp->sw_if_index_to = htonl (dst_sw_if_index);
20401   mp->state = state;
20402   mp->is_l2 = is_l2;
20403
20404   S (mp);
20405   W (ret);
20406   return ret;
20407 }
20408
20409 static void
20410 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20411                                             * mp)
20412 {
20413   vat_main_t *vam = &vat_main;
20414   u8 *sw_if_from_name = 0;
20415   u8 *sw_if_to_name = 0;
20416   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20417   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20418   char *states[] = { "none", "rx", "tx", "both" };
20419   hash_pair_t *p;
20420
20421   /* *INDENT-OFF* */
20422   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20423   ({
20424     if ((u32) p->value[0] == sw_if_index_from)
20425       {
20426         sw_if_from_name = (u8 *)(p->key);
20427         if (sw_if_to_name)
20428           break;
20429       }
20430     if ((u32) p->value[0] == sw_if_index_to)
20431       {
20432         sw_if_to_name = (u8 *)(p->key);
20433         if (sw_if_from_name)
20434           break;
20435       }
20436   }));
20437   /* *INDENT-ON* */
20438   print (vam->ofp, "%20s => %20s (%s)",
20439          sw_if_from_name, sw_if_to_name, states[mp->state]);
20440 }
20441
20442 static void
20443   vl_api_sw_interface_span_details_t_handler_json
20444   (vl_api_sw_interface_span_details_t * mp)
20445 {
20446   vat_main_t *vam = &vat_main;
20447   vat_json_node_t *node = NULL;
20448   u8 *sw_if_from_name = 0;
20449   u8 *sw_if_to_name = 0;
20450   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20451   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20452   hash_pair_t *p;
20453
20454   /* *INDENT-OFF* */
20455   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20456   ({
20457     if ((u32) p->value[0] == sw_if_index_from)
20458       {
20459         sw_if_from_name = (u8 *)(p->key);
20460         if (sw_if_to_name)
20461           break;
20462       }
20463     if ((u32) p->value[0] == sw_if_index_to)
20464       {
20465         sw_if_to_name = (u8 *)(p->key);
20466         if (sw_if_from_name)
20467           break;
20468       }
20469   }));
20470   /* *INDENT-ON* */
20471
20472   if (VAT_JSON_ARRAY != vam->json_tree.type)
20473     {
20474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20475       vat_json_init_array (&vam->json_tree);
20476     }
20477   node = vat_json_array_add (&vam->json_tree);
20478
20479   vat_json_init_object (node);
20480   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20481   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20482   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20483   if (0 != sw_if_to_name)
20484     {
20485       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20486     }
20487   vat_json_object_add_uint (node, "state", mp->state);
20488 }
20489
20490 static int
20491 api_sw_interface_span_dump (vat_main_t * vam)
20492 {
20493   unformat_input_t *input = vam->input;
20494   vl_api_sw_interface_span_dump_t *mp;
20495   vl_api_control_ping_t *mp_ping;
20496   u8 is_l2 = 0;
20497   int ret;
20498
20499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20500     {
20501       if (unformat (input, "l2"))
20502         is_l2 = 1;
20503       else
20504         break;
20505     }
20506
20507   M (SW_INTERFACE_SPAN_DUMP, mp);
20508   mp->is_l2 = is_l2;
20509   S (mp);
20510
20511   /* Use a control ping for synchronization */
20512   MPING (CONTROL_PING, mp_ping);
20513   S (mp_ping);
20514
20515   W (ret);
20516   return ret;
20517 }
20518
20519 int
20520 api_pg_create_interface (vat_main_t * vam)
20521 {
20522   unformat_input_t *input = vam->input;
20523   vl_api_pg_create_interface_t *mp;
20524
20525   u32 if_id = ~0;
20526   int ret;
20527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20528     {
20529       if (unformat (input, "if_id %d", &if_id))
20530         ;
20531       else
20532         break;
20533     }
20534   if (if_id == ~0)
20535     {
20536       errmsg ("missing pg interface index");
20537       return -99;
20538     }
20539
20540   /* Construct the API message */
20541   M (PG_CREATE_INTERFACE, mp);
20542   mp->context = 0;
20543   mp->interface_id = ntohl (if_id);
20544
20545   S (mp);
20546   W (ret);
20547   return ret;
20548 }
20549
20550 int
20551 api_pg_capture (vat_main_t * vam)
20552 {
20553   unformat_input_t *input = vam->input;
20554   vl_api_pg_capture_t *mp;
20555
20556   u32 if_id = ~0;
20557   u8 enable = 1;
20558   u32 count = 1;
20559   u8 pcap_file_set = 0;
20560   u8 *pcap_file = 0;
20561   int ret;
20562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20563     {
20564       if (unformat (input, "if_id %d", &if_id))
20565         ;
20566       else if (unformat (input, "pcap %s", &pcap_file))
20567         pcap_file_set = 1;
20568       else if (unformat (input, "count %d", &count))
20569         ;
20570       else if (unformat (input, "disable"))
20571         enable = 0;
20572       else
20573         break;
20574     }
20575   if (if_id == ~0)
20576     {
20577       errmsg ("missing pg interface index");
20578       return -99;
20579     }
20580   if (pcap_file_set > 0)
20581     {
20582       if (vec_len (pcap_file) > 255)
20583         {
20584           errmsg ("pcap file name is too long");
20585           return -99;
20586         }
20587     }
20588
20589   u32 name_len = vec_len (pcap_file);
20590   /* Construct the API message */
20591   M (PG_CAPTURE, mp);
20592   mp->context = 0;
20593   mp->interface_id = ntohl (if_id);
20594   mp->is_enabled = enable;
20595   mp->count = ntohl (count);
20596   mp->pcap_name_length = ntohl (name_len);
20597   if (pcap_file_set != 0)
20598     {
20599       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20600     }
20601   vec_free (pcap_file);
20602
20603   S (mp);
20604   W (ret);
20605   return ret;
20606 }
20607
20608 int
20609 api_pg_enable_disable (vat_main_t * vam)
20610 {
20611   unformat_input_t *input = vam->input;
20612   vl_api_pg_enable_disable_t *mp;
20613
20614   u8 enable = 1;
20615   u8 stream_name_set = 0;
20616   u8 *stream_name = 0;
20617   int ret;
20618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20619     {
20620       if (unformat (input, "stream %s", &stream_name))
20621         stream_name_set = 1;
20622       else if (unformat (input, "disable"))
20623         enable = 0;
20624       else
20625         break;
20626     }
20627
20628   if (stream_name_set > 0)
20629     {
20630       if (vec_len (stream_name) > 255)
20631         {
20632           errmsg ("stream name too long");
20633           return -99;
20634         }
20635     }
20636
20637   u32 name_len = vec_len (stream_name);
20638   /* Construct the API message */
20639   M (PG_ENABLE_DISABLE, mp);
20640   mp->context = 0;
20641   mp->is_enabled = enable;
20642   if (stream_name_set != 0)
20643     {
20644       mp->stream_name_length = ntohl (name_len);
20645       clib_memcpy (mp->stream_name, stream_name, name_len);
20646     }
20647   vec_free (stream_name);
20648
20649   S (mp);
20650   W (ret);
20651   return ret;
20652 }
20653
20654 int
20655 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20656 {
20657   unformat_input_t *input = vam->input;
20658   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20659
20660   u16 *low_ports = 0;
20661   u16 *high_ports = 0;
20662   u16 this_low;
20663   u16 this_hi;
20664   ip4_address_t ip4_addr;
20665   ip6_address_t ip6_addr;
20666   u32 length;
20667   u32 tmp, tmp2;
20668   u8 prefix_set = 0;
20669   u32 vrf_id = ~0;
20670   u8 is_add = 1;
20671   u8 is_ipv6 = 0;
20672   int ret;
20673
20674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20675     {
20676       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20677         {
20678           prefix_set = 1;
20679         }
20680       else
20681         if (unformat
20682             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20683         {
20684           prefix_set = 1;
20685           is_ipv6 = 1;
20686         }
20687       else if (unformat (input, "vrf %d", &vrf_id))
20688         ;
20689       else if (unformat (input, "del"))
20690         is_add = 0;
20691       else if (unformat (input, "port %d", &tmp))
20692         {
20693           if (tmp == 0 || tmp > 65535)
20694             {
20695               errmsg ("port %d out of range", tmp);
20696               return -99;
20697             }
20698           this_low = tmp;
20699           this_hi = this_low + 1;
20700           vec_add1 (low_ports, this_low);
20701           vec_add1 (high_ports, this_hi);
20702         }
20703       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20704         {
20705           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20706             {
20707               errmsg ("incorrect range parameters");
20708               return -99;
20709             }
20710           this_low = tmp;
20711           /* Note: in debug CLI +1 is added to high before
20712              passing to real fn that does "the work"
20713              (ip_source_and_port_range_check_add_del).
20714              This fn is a wrapper around the binary API fn a
20715              control plane will call, which expects this increment
20716              to have occurred. Hence letting the binary API control
20717              plane fn do the increment for consistency between VAT
20718              and other control planes.
20719            */
20720           this_hi = tmp2;
20721           vec_add1 (low_ports, this_low);
20722           vec_add1 (high_ports, this_hi);
20723         }
20724       else
20725         break;
20726     }
20727
20728   if (prefix_set == 0)
20729     {
20730       errmsg ("<address>/<mask> not specified");
20731       return -99;
20732     }
20733
20734   if (vrf_id == ~0)
20735     {
20736       errmsg ("VRF ID required, not specified");
20737       return -99;
20738     }
20739
20740   if (vrf_id == 0)
20741     {
20742       errmsg
20743         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20744       return -99;
20745     }
20746
20747   if (vec_len (low_ports) == 0)
20748     {
20749       errmsg ("At least one port or port range required");
20750       return -99;
20751     }
20752
20753   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20754
20755   mp->is_add = is_add;
20756
20757   if (is_ipv6)
20758     {
20759       mp->is_ipv6 = 1;
20760       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20761     }
20762   else
20763     {
20764       mp->is_ipv6 = 0;
20765       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20766     }
20767
20768   mp->mask_length = length;
20769   mp->number_of_ranges = vec_len (low_ports);
20770
20771   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20772   vec_free (low_ports);
20773
20774   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20775   vec_free (high_ports);
20776
20777   mp->vrf_id = ntohl (vrf_id);
20778
20779   S (mp);
20780   W (ret);
20781   return ret;
20782 }
20783
20784 int
20785 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20786 {
20787   unformat_input_t *input = vam->input;
20788   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20789   u32 sw_if_index = ~0;
20790   int vrf_set = 0;
20791   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20792   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20793   u8 is_add = 1;
20794   int ret;
20795
20796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20797     {
20798       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20799         ;
20800       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20801         ;
20802       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20803         vrf_set = 1;
20804       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20805         vrf_set = 1;
20806       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20807         vrf_set = 1;
20808       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20809         vrf_set = 1;
20810       else if (unformat (input, "del"))
20811         is_add = 0;
20812       else
20813         break;
20814     }
20815
20816   if (sw_if_index == ~0)
20817     {
20818       errmsg ("Interface required but not specified");
20819       return -99;
20820     }
20821
20822   if (vrf_set == 0)
20823     {
20824       errmsg ("VRF ID required but not specified");
20825       return -99;
20826     }
20827
20828   if (tcp_out_vrf_id == 0
20829       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20830     {
20831       errmsg
20832         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20833       return -99;
20834     }
20835
20836   /* Construct the API message */
20837   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20838
20839   mp->sw_if_index = ntohl (sw_if_index);
20840   mp->is_add = is_add;
20841   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20842   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20843   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20844   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20845
20846   /* send it... */
20847   S (mp);
20848
20849   /* Wait for a reply... */
20850   W (ret);
20851   return ret;
20852 }
20853
20854 static int
20855 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20856 {
20857   unformat_input_t *i = vam->input;
20858   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20859   u32 local_sa_id = 0;
20860   u32 remote_sa_id = 0;
20861   ip4_address_t src_address;
20862   ip4_address_t dst_address;
20863   u8 is_add = 1;
20864   int ret;
20865
20866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20867     {
20868       if (unformat (i, "local_sa %d", &local_sa_id))
20869         ;
20870       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20871         ;
20872       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20873         ;
20874       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20875         ;
20876       else if (unformat (i, "del"))
20877         is_add = 0;
20878       else
20879         {
20880           clib_warning ("parse error '%U'", format_unformat_error, i);
20881           return -99;
20882         }
20883     }
20884
20885   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20886
20887   mp->local_sa_id = ntohl (local_sa_id);
20888   mp->remote_sa_id = ntohl (remote_sa_id);
20889   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20890   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20891   mp->is_add = is_add;
20892
20893   S (mp);
20894   W (ret);
20895   return ret;
20896 }
20897
20898 static int
20899 api_punt (vat_main_t * vam)
20900 {
20901   unformat_input_t *i = vam->input;
20902   vl_api_punt_t *mp;
20903   u32 ipv = ~0;
20904   u32 protocol = ~0;
20905   u32 port = ~0;
20906   int is_add = 1;
20907   int ret;
20908
20909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20910     {
20911       if (unformat (i, "ip %d", &ipv))
20912         ;
20913       else if (unformat (i, "protocol %d", &protocol))
20914         ;
20915       else if (unformat (i, "port %d", &port))
20916         ;
20917       else if (unformat (i, "del"))
20918         is_add = 0;
20919       else
20920         {
20921           clib_warning ("parse error '%U'", format_unformat_error, i);
20922           return -99;
20923         }
20924     }
20925
20926   M (PUNT, mp);
20927
20928   mp->is_add = (u8) is_add;
20929   mp->ipv = (u8) ipv;
20930   mp->l4_protocol = (u8) protocol;
20931   mp->l4_port = htons ((u16) port);
20932
20933   S (mp);
20934   W (ret);
20935   return ret;
20936 }
20937
20938 static void vl_api_ipsec_gre_tunnel_details_t_handler
20939   (vl_api_ipsec_gre_tunnel_details_t * mp)
20940 {
20941   vat_main_t *vam = &vat_main;
20942
20943   print (vam->ofp, "%11d%15U%15U%14d%14d",
20944          ntohl (mp->sw_if_index),
20945          format_ip4_address, &mp->src_address,
20946          format_ip4_address, &mp->dst_address,
20947          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20948 }
20949
20950 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20951   (vl_api_ipsec_gre_tunnel_details_t * mp)
20952 {
20953   vat_main_t *vam = &vat_main;
20954   vat_json_node_t *node = NULL;
20955   struct in_addr ip4;
20956
20957   if (VAT_JSON_ARRAY != vam->json_tree.type)
20958     {
20959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20960       vat_json_init_array (&vam->json_tree);
20961     }
20962   node = vat_json_array_add (&vam->json_tree);
20963
20964   vat_json_init_object (node);
20965   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20966   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20967   vat_json_object_add_ip4 (node, "src_address", ip4);
20968   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20969   vat_json_object_add_ip4 (node, "dst_address", ip4);
20970   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20971   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20972 }
20973
20974 static int
20975 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20976 {
20977   unformat_input_t *i = vam->input;
20978   vl_api_ipsec_gre_tunnel_dump_t *mp;
20979   vl_api_control_ping_t *mp_ping;
20980   u32 sw_if_index;
20981   u8 sw_if_index_set = 0;
20982   int ret;
20983
20984   /* Parse args required to build the message */
20985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20986     {
20987       if (unformat (i, "sw_if_index %d", &sw_if_index))
20988         sw_if_index_set = 1;
20989       else
20990         break;
20991     }
20992
20993   if (sw_if_index_set == 0)
20994     {
20995       sw_if_index = ~0;
20996     }
20997
20998   if (!vam->json_output)
20999     {
21000       print (vam->ofp, "%11s%15s%15s%14s%14s",
21001              "sw_if_index", "src_address", "dst_address",
21002              "local_sa_id", "remote_sa_id");
21003     }
21004
21005   /* Get list of gre-tunnel interfaces */
21006   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21007
21008   mp->sw_if_index = htonl (sw_if_index);
21009
21010   S (mp);
21011
21012   /* Use a control ping for synchronization */
21013   MPING (CONTROL_PING, mp_ping);
21014   S (mp_ping);
21015
21016   W (ret);
21017   return ret;
21018 }
21019
21020 static int
21021 api_delete_subif (vat_main_t * vam)
21022 {
21023   unformat_input_t *i = vam->input;
21024   vl_api_delete_subif_t *mp;
21025   u32 sw_if_index = ~0;
21026   int ret;
21027
21028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21029     {
21030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21031         ;
21032       if (unformat (i, "sw_if_index %d", &sw_if_index))
21033         ;
21034       else
21035         break;
21036     }
21037
21038   if (sw_if_index == ~0)
21039     {
21040       errmsg ("missing sw_if_index");
21041       return -99;
21042     }
21043
21044   /* Construct the API message */
21045   M (DELETE_SUBIF, mp);
21046   mp->sw_if_index = ntohl (sw_if_index);
21047
21048   S (mp);
21049   W (ret);
21050   return ret;
21051 }
21052
21053 #define foreach_pbb_vtr_op      \
21054 _("disable",  L2_VTR_DISABLED)  \
21055 _("pop",  L2_VTR_POP_2)         \
21056 _("push",  L2_VTR_PUSH_2)
21057
21058 static int
21059 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21060 {
21061   unformat_input_t *i = vam->input;
21062   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21063   u32 sw_if_index = ~0, vtr_op = ~0;
21064   u16 outer_tag = ~0;
21065   u8 dmac[6], smac[6];
21066   u8 dmac_set = 0, smac_set = 0;
21067   u16 vlanid = 0;
21068   u32 sid = ~0;
21069   u32 tmp;
21070   int ret;
21071
21072   /* Shut up coverity */
21073   memset (dmac, 0, sizeof (dmac));
21074   memset (smac, 0, sizeof (smac));
21075
21076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21077     {
21078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21079         ;
21080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21081         ;
21082       else if (unformat (i, "vtr_op %d", &vtr_op))
21083         ;
21084 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21085       foreach_pbb_vtr_op
21086 #undef _
21087         else if (unformat (i, "translate_pbb_stag"))
21088         {
21089           if (unformat (i, "%d", &tmp))
21090             {
21091               vtr_op = L2_VTR_TRANSLATE_2_1;
21092               outer_tag = tmp;
21093             }
21094           else
21095             {
21096               errmsg
21097                 ("translate_pbb_stag operation requires outer tag definition");
21098               return -99;
21099             }
21100         }
21101       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21102         dmac_set++;
21103       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21104         smac_set++;
21105       else if (unformat (i, "sid %d", &sid))
21106         ;
21107       else if (unformat (i, "vlanid %d", &tmp))
21108         vlanid = tmp;
21109       else
21110         {
21111           clib_warning ("parse error '%U'", format_unformat_error, i);
21112           return -99;
21113         }
21114     }
21115
21116   if ((sw_if_index == ~0) || (vtr_op == ~0))
21117     {
21118       errmsg ("missing sw_if_index or vtr operation");
21119       return -99;
21120     }
21121   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21122       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21123     {
21124       errmsg
21125         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21126       return -99;
21127     }
21128
21129   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21130   mp->sw_if_index = ntohl (sw_if_index);
21131   mp->vtr_op = ntohl (vtr_op);
21132   mp->outer_tag = ntohs (outer_tag);
21133   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21134   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21135   mp->b_vlanid = ntohs (vlanid);
21136   mp->i_sid = ntohl (sid);
21137
21138   S (mp);
21139   W (ret);
21140   return ret;
21141 }
21142
21143 static int
21144 api_flow_classify_set_interface (vat_main_t * vam)
21145 {
21146   unformat_input_t *i = vam->input;
21147   vl_api_flow_classify_set_interface_t *mp;
21148   u32 sw_if_index;
21149   int sw_if_index_set;
21150   u32 ip4_table_index = ~0;
21151   u32 ip6_table_index = ~0;
21152   u8 is_add = 1;
21153   int ret;
21154
21155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21156     {
21157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21158         sw_if_index_set = 1;
21159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21160         sw_if_index_set = 1;
21161       else if (unformat (i, "del"))
21162         is_add = 0;
21163       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21164         ;
21165       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21166         ;
21167       else
21168         {
21169           clib_warning ("parse error '%U'", format_unformat_error, i);
21170           return -99;
21171         }
21172     }
21173
21174   if (sw_if_index_set == 0)
21175     {
21176       errmsg ("missing interface name or sw_if_index");
21177       return -99;
21178     }
21179
21180   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21181
21182   mp->sw_if_index = ntohl (sw_if_index);
21183   mp->ip4_table_index = ntohl (ip4_table_index);
21184   mp->ip6_table_index = ntohl (ip6_table_index);
21185   mp->is_add = is_add;
21186
21187   S (mp);
21188   W (ret);
21189   return ret;
21190 }
21191
21192 static int
21193 api_flow_classify_dump (vat_main_t * vam)
21194 {
21195   unformat_input_t *i = vam->input;
21196   vl_api_flow_classify_dump_t *mp;
21197   vl_api_control_ping_t *mp_ping;
21198   u8 type = FLOW_CLASSIFY_N_TABLES;
21199   int ret;
21200
21201   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21202     ;
21203   else
21204     {
21205       errmsg ("classify table type must be specified");
21206       return -99;
21207     }
21208
21209   if (!vam->json_output)
21210     {
21211       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21212     }
21213
21214   M (FLOW_CLASSIFY_DUMP, mp);
21215   mp->type = type;
21216   /* send it... */
21217   S (mp);
21218
21219   /* Use a control ping for synchronization */
21220   MPING (CONTROL_PING, mp_ping);
21221   S (mp_ping);
21222
21223   /* Wait for a reply... */
21224   W (ret);
21225   return ret;
21226 }
21227
21228 static int
21229 api_feature_enable_disable (vat_main_t * vam)
21230 {
21231   unformat_input_t *i = vam->input;
21232   vl_api_feature_enable_disable_t *mp;
21233   u8 *arc_name = 0;
21234   u8 *feature_name = 0;
21235   u32 sw_if_index = ~0;
21236   u8 enable = 1;
21237   int ret;
21238
21239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21240     {
21241       if (unformat (i, "arc_name %s", &arc_name))
21242         ;
21243       else if (unformat (i, "feature_name %s", &feature_name))
21244         ;
21245       else
21246         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21247         ;
21248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21249         ;
21250       else if (unformat (i, "disable"))
21251         enable = 0;
21252       else
21253         break;
21254     }
21255
21256   if (arc_name == 0)
21257     {
21258       errmsg ("missing arc name");
21259       return -99;
21260     }
21261   if (vec_len (arc_name) > 63)
21262     {
21263       errmsg ("arc name too long");
21264     }
21265
21266   if (feature_name == 0)
21267     {
21268       errmsg ("missing feature name");
21269       return -99;
21270     }
21271   if (vec_len (feature_name) > 63)
21272     {
21273       errmsg ("feature name too long");
21274     }
21275
21276   if (sw_if_index == ~0)
21277     {
21278       errmsg ("missing interface name or sw_if_index");
21279       return -99;
21280     }
21281
21282   /* Construct the API message */
21283   M (FEATURE_ENABLE_DISABLE, mp);
21284   mp->sw_if_index = ntohl (sw_if_index);
21285   mp->enable = enable;
21286   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21287   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21288   vec_free (arc_name);
21289   vec_free (feature_name);
21290
21291   S (mp);
21292   W (ret);
21293   return ret;
21294 }
21295
21296 static int
21297 api_sw_interface_tag_add_del (vat_main_t * vam)
21298 {
21299   unformat_input_t *i = vam->input;
21300   vl_api_sw_interface_tag_add_del_t *mp;
21301   u32 sw_if_index = ~0;
21302   u8 *tag = 0;
21303   u8 enable = 1;
21304   int ret;
21305
21306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21307     {
21308       if (unformat (i, "tag %s", &tag))
21309         ;
21310       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21311         ;
21312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21313         ;
21314       else if (unformat (i, "del"))
21315         enable = 0;
21316       else
21317         break;
21318     }
21319
21320   if (sw_if_index == ~0)
21321     {
21322       errmsg ("missing interface name or sw_if_index");
21323       return -99;
21324     }
21325
21326   if (enable && (tag == 0))
21327     {
21328       errmsg ("no tag specified");
21329       return -99;
21330     }
21331
21332   /* Construct the API message */
21333   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21334   mp->sw_if_index = ntohl (sw_if_index);
21335   mp->is_add = enable;
21336   if (enable)
21337     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21338   vec_free (tag);
21339
21340   S (mp);
21341   W (ret);
21342   return ret;
21343 }
21344
21345 static void vl_api_l2_xconnect_details_t_handler
21346   (vl_api_l2_xconnect_details_t * mp)
21347 {
21348   vat_main_t *vam = &vat_main;
21349
21350   print (vam->ofp, "%15d%15d",
21351          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21352 }
21353
21354 static void vl_api_l2_xconnect_details_t_handler_json
21355   (vl_api_l2_xconnect_details_t * mp)
21356 {
21357   vat_main_t *vam = &vat_main;
21358   vat_json_node_t *node = NULL;
21359
21360   if (VAT_JSON_ARRAY != vam->json_tree.type)
21361     {
21362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21363       vat_json_init_array (&vam->json_tree);
21364     }
21365   node = vat_json_array_add (&vam->json_tree);
21366
21367   vat_json_init_object (node);
21368   vat_json_object_add_uint (node, "rx_sw_if_index",
21369                             ntohl (mp->rx_sw_if_index));
21370   vat_json_object_add_uint (node, "tx_sw_if_index",
21371                             ntohl (mp->tx_sw_if_index));
21372 }
21373
21374 static int
21375 api_l2_xconnect_dump (vat_main_t * vam)
21376 {
21377   vl_api_l2_xconnect_dump_t *mp;
21378   vl_api_control_ping_t *mp_ping;
21379   int ret;
21380
21381   if (!vam->json_output)
21382     {
21383       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21384     }
21385
21386   M (L2_XCONNECT_DUMP, mp);
21387
21388   S (mp);
21389
21390   /* Use a control ping for synchronization */
21391   MPING (CONTROL_PING, mp_ping);
21392   S (mp_ping);
21393
21394   W (ret);
21395   return ret;
21396 }
21397
21398 static int
21399 api_sw_interface_set_mtu (vat_main_t * vam)
21400 {
21401   unformat_input_t *i = vam->input;
21402   vl_api_sw_interface_set_mtu_t *mp;
21403   u32 sw_if_index = ~0;
21404   u32 mtu = 0;
21405   int ret;
21406
21407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21408     {
21409       if (unformat (i, "mtu %d", &mtu))
21410         ;
21411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21412         ;
21413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21414         ;
21415       else
21416         break;
21417     }
21418
21419   if (sw_if_index == ~0)
21420     {
21421       errmsg ("missing interface name or sw_if_index");
21422       return -99;
21423     }
21424
21425   if (mtu == 0)
21426     {
21427       errmsg ("no mtu specified");
21428       return -99;
21429     }
21430
21431   /* Construct the API message */
21432   M (SW_INTERFACE_SET_MTU, mp);
21433   mp->sw_if_index = ntohl (sw_if_index);
21434   mp->mtu = ntohs ((u16) mtu);
21435
21436   S (mp);
21437   W (ret);
21438   return ret;
21439 }
21440
21441 static int
21442 api_p2p_ethernet_add (vat_main_t * vam)
21443 {
21444   unformat_input_t *i = vam->input;
21445   vl_api_p2p_ethernet_add_t *mp;
21446   u32 parent_if_index = ~0;
21447   u32 sub_id = ~0;
21448   u8 remote_mac[6];
21449   u8 mac_set = 0;
21450   int ret;
21451
21452   memset (remote_mac, 0, sizeof (remote_mac));
21453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21454     {
21455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21456         ;
21457       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21458         ;
21459       else
21460         if (unformat
21461             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21462         mac_set++;
21463       else if (unformat (i, "sub_id %d", &sub_id))
21464         ;
21465       else
21466         {
21467           clib_warning ("parse error '%U'", format_unformat_error, i);
21468           return -99;
21469         }
21470     }
21471
21472   if (parent_if_index == ~0)
21473     {
21474       errmsg ("missing interface name or sw_if_index");
21475       return -99;
21476     }
21477   if (mac_set == 0)
21478     {
21479       errmsg ("missing remote mac address");
21480       return -99;
21481     }
21482   if (sub_id == ~0)
21483     {
21484       errmsg ("missing sub-interface id");
21485       return -99;
21486     }
21487
21488   M (P2P_ETHERNET_ADD, mp);
21489   mp->parent_if_index = ntohl (parent_if_index);
21490   mp->subif_id = ntohl (sub_id);
21491   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21492
21493   S (mp);
21494   W (ret);
21495   return ret;
21496 }
21497
21498 static int
21499 api_p2p_ethernet_del (vat_main_t * vam)
21500 {
21501   unformat_input_t *i = vam->input;
21502   vl_api_p2p_ethernet_del_t *mp;
21503   u32 parent_if_index = ~0;
21504   u8 remote_mac[6];
21505   u8 mac_set = 0;
21506   int ret;
21507
21508   memset (remote_mac, 0, sizeof (remote_mac));
21509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21510     {
21511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21512         ;
21513       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21514         ;
21515       else
21516         if (unformat
21517             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21518         mac_set++;
21519       else
21520         {
21521           clib_warning ("parse error '%U'", format_unformat_error, i);
21522           return -99;
21523         }
21524     }
21525
21526   if (parent_if_index == ~0)
21527     {
21528       errmsg ("missing interface name or sw_if_index");
21529       return -99;
21530     }
21531   if (mac_set == 0)
21532     {
21533       errmsg ("missing remote mac address");
21534       return -99;
21535     }
21536
21537   M (P2P_ETHERNET_DEL, mp);
21538   mp->parent_if_index = ntohl (parent_if_index);
21539   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21540
21541   S (mp);
21542   W (ret);
21543   return ret;
21544 }
21545
21546 static int
21547 api_lldp_config (vat_main_t * vam)
21548 {
21549   unformat_input_t *i = vam->input;
21550   vl_api_lldp_config_t *mp;
21551   int tx_hold = 0;
21552   int tx_interval = 0;
21553   u8 *sys_name = NULL;
21554   int ret;
21555
21556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21557     {
21558       if (unformat (i, "system-name %s", &sys_name))
21559         ;
21560       else if (unformat (i, "tx-hold %d", &tx_hold))
21561         ;
21562       else if (unformat (i, "tx-interval %d", &tx_interval))
21563         ;
21564       else
21565         {
21566           clib_warning ("parse error '%U'", format_unformat_error, i);
21567           return -99;
21568         }
21569     }
21570
21571   vec_add1 (sys_name, 0);
21572
21573   M (LLDP_CONFIG, mp);
21574   mp->tx_hold = htonl (tx_hold);
21575   mp->tx_interval = htonl (tx_interval);
21576   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21577   vec_free (sys_name);
21578
21579   S (mp);
21580   W (ret);
21581   return ret;
21582 }
21583
21584 static int
21585 api_sw_interface_set_lldp (vat_main_t * vam)
21586 {
21587   unformat_input_t *i = vam->input;
21588   vl_api_sw_interface_set_lldp_t *mp;
21589   u32 sw_if_index = ~0;
21590   u32 enable = 1;
21591   u8 *port_desc = NULL, *mgmt_oid = NULL;
21592   ip4_address_t ip4_addr;
21593   ip6_address_t ip6_addr;
21594   int ret;
21595
21596   memset (&ip4_addr, 0, sizeof (ip4_addr));
21597   memset (&ip6_addr, 0, sizeof (ip6_addr));
21598
21599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21600     {
21601       if (unformat (i, "disable"))
21602         enable = 0;
21603       else
21604         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21605         ;
21606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21607         ;
21608       else if (unformat (i, "port-desc %s", &port_desc))
21609         ;
21610       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21611         ;
21612       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21613         ;
21614       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21615         ;
21616       else
21617         break;
21618     }
21619
21620   if (sw_if_index == ~0)
21621     {
21622       errmsg ("missing interface name or sw_if_index");
21623       return -99;
21624     }
21625
21626   /* Construct the API message */
21627   vec_add1 (port_desc, 0);
21628   vec_add1 (mgmt_oid, 0);
21629   M (SW_INTERFACE_SET_LLDP, mp);
21630   mp->sw_if_index = ntohl (sw_if_index);
21631   mp->enable = enable;
21632   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21633   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21634   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21635   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21636   vec_free (port_desc);
21637   vec_free (mgmt_oid);
21638
21639   S (mp);
21640   W (ret);
21641   return ret;
21642 }
21643
21644 static int
21645 api_tcp_configure_src_addresses (vat_main_t * vam)
21646 {
21647   vl_api_tcp_configure_src_addresses_t *mp;
21648   unformat_input_t *i = vam->input;
21649   ip4_address_t v4first, v4last;
21650   ip6_address_t v6first, v6last;
21651   u8 range_set = 0;
21652   u32 vrf_id = 0;
21653   int ret;
21654
21655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21656     {
21657       if (unformat (i, "%U - %U",
21658                     unformat_ip4_address, &v4first,
21659                     unformat_ip4_address, &v4last))
21660         {
21661           if (range_set)
21662             {
21663               errmsg ("one range per message (range already set)");
21664               return -99;
21665             }
21666           range_set = 1;
21667         }
21668       else if (unformat (i, "%U - %U",
21669                          unformat_ip6_address, &v6first,
21670                          unformat_ip6_address, &v6last))
21671         {
21672           if (range_set)
21673             {
21674               errmsg ("one range per message (range already set)");
21675               return -99;
21676             }
21677           range_set = 2;
21678         }
21679       else if (unformat (i, "vrf %d", &vrf_id))
21680         ;
21681       else
21682         break;
21683     }
21684
21685   if (range_set == 0)
21686     {
21687       errmsg ("address range not set");
21688       return -99;
21689     }
21690
21691   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21692   mp->vrf_id = ntohl (vrf_id);
21693   /* ipv6? */
21694   if (range_set == 2)
21695     {
21696       mp->is_ipv6 = 1;
21697       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21698       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21699     }
21700   else
21701     {
21702       mp->is_ipv6 = 0;
21703       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21704       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21705     }
21706   S (mp);
21707   W (ret);
21708   return ret;
21709 }
21710
21711 static void vl_api_app_namespace_add_del_reply_t_handler
21712   (vl_api_app_namespace_add_del_reply_t * mp)
21713 {
21714   vat_main_t *vam = &vat_main;
21715   i32 retval = ntohl (mp->retval);
21716   if (vam->async_mode)
21717     {
21718       vam->async_errors += (retval < 0);
21719     }
21720   else
21721     {
21722       vam->retval = retval;
21723       if (retval == 0)
21724         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21725       vam->result_ready = 1;
21726     }
21727 }
21728
21729 static void vl_api_app_namespace_add_del_reply_t_handler_json
21730   (vl_api_app_namespace_add_del_reply_t * mp)
21731 {
21732   vat_main_t *vam = &vat_main;
21733   vat_json_node_t node;
21734
21735   vat_json_init_object (&node);
21736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21737   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21738
21739   vat_json_print (vam->ofp, &node);
21740   vat_json_free (&node);
21741
21742   vam->retval = ntohl (mp->retval);
21743   vam->result_ready = 1;
21744 }
21745
21746 static int
21747 api_app_namespace_add_del (vat_main_t * vam)
21748 {
21749   vl_api_app_namespace_add_del_t *mp;
21750   unformat_input_t *i = vam->input;
21751   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21752   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21753   u64 secret;
21754   int ret;
21755
21756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21757     {
21758       if (unformat (i, "id %_%v%_", &ns_id))
21759         ;
21760       else if (unformat (i, "secret %lu", &secret))
21761         secret_set = 1;
21762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21763         sw_if_index_set = 1;
21764       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21765         ;
21766       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21767         ;
21768       else
21769         break;
21770     }
21771   if (!ns_id || !secret_set || !sw_if_index_set)
21772     {
21773       errmsg ("namespace id, secret and sw_if_index must be set");
21774       return -99;
21775     }
21776   if (vec_len (ns_id) > 64)
21777     {
21778       errmsg ("namespace id too long");
21779       return -99;
21780     }
21781   M (APP_NAMESPACE_ADD_DEL, mp);
21782
21783   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21784   mp->namespace_id_len = vec_len (ns_id);
21785   mp->secret = clib_host_to_net_u64 (secret);
21786   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21787   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21788   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21789   vec_free (ns_id);
21790   S (mp);
21791   W (ret);
21792   return ret;
21793 }
21794
21795 static int
21796 api_memfd_segment_create (vat_main_t * vam)
21797 {
21798 #if VPP_API_TEST_BUILTIN == 0
21799   unformat_input_t *i = vam->input;
21800   vl_api_memfd_segment_create_t *mp;
21801   u64 size = 64 << 20;
21802   int ret;
21803
21804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21805     {
21806       if (unformat (i, "size %U", unformat_memory_size, &size))
21807         ;
21808       else
21809         break;
21810     }
21811
21812   M (MEMFD_SEGMENT_CREATE, mp);
21813   mp->requested_size = size;
21814   S (mp);
21815   W (ret);
21816   return ret;
21817
21818 #else
21819   errmsg ("memfd_segment_create (builtin) not supported");
21820   return -99;
21821 #endif
21822 }
21823
21824 static int
21825 api_sock_init_shm (vat_main_t * vam)
21826 {
21827 #if VPP_API_TEST_BUILTIN == 0
21828   unformat_input_t *i = vam->input;
21829   vl_api_shm_elem_config_t *config = 0;
21830   u64 size = 64 << 20;
21831   int rv;
21832
21833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21834     {
21835       if (unformat (i, "size %U", unformat_memory_size, &size))
21836         ;
21837       else
21838         break;
21839     }
21840
21841   /* Try customized config to see if it works */
21842   vec_validate (config, 3);
21843   config[0].type = VL_API_VLIB_RING;
21844   config[0].count = 256;
21845   config[0].size = 256;
21846   config[1].type = VL_API_CLIENT_RING;
21847   config[1].count = 256;
21848   config[1].size = 1024;
21849   config[2].type = VL_API_CLIENT_RING;
21850   config[2].count = 8;
21851   config[2].size = 4096;
21852   config[3].type = VL_API_QUEUE;
21853   config[3].count = 256;
21854   config[3].size = sizeof (uword);
21855   rv = vl_socket_client_init_shm (config);
21856   if (!rv)
21857     vam->client_index_invalid = 1;
21858   return rv;
21859 #else
21860   return -99;
21861 #endif
21862 }
21863
21864 static int
21865 api_dns_enable_disable (vat_main_t * vam)
21866 {
21867   unformat_input_t *line_input = vam->input;
21868   vl_api_dns_enable_disable_t *mp;
21869   u8 enable_disable = 1;
21870   int ret;
21871
21872   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21873     {
21874       if (unformat (line_input, "disable"))
21875         enable_disable = 0;
21876       if (unformat (line_input, "enable"))
21877         enable_disable = 1;
21878       else
21879         break;
21880     }
21881
21882   /* Construct the API message */
21883   M (DNS_ENABLE_DISABLE, mp);
21884   mp->enable = enable_disable;
21885
21886   /* send it... */
21887   S (mp);
21888   /* Wait for the reply */
21889   W (ret);
21890   return ret;
21891 }
21892
21893 static int
21894 api_dns_resolve_name (vat_main_t * vam)
21895 {
21896   unformat_input_t *line_input = vam->input;
21897   vl_api_dns_resolve_name_t *mp;
21898   u8 *name = 0;
21899   int ret;
21900
21901   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21902     {
21903       if (unformat (line_input, "%s", &name))
21904         ;
21905       else
21906         break;
21907     }
21908
21909   if (vec_len (name) > 127)
21910     {
21911       errmsg ("name too long");
21912       return -99;
21913     }
21914
21915   /* Construct the API message */
21916   M (DNS_RESOLVE_NAME, mp);
21917   memcpy (mp->name, name, vec_len (name));
21918   vec_free (name);
21919
21920   /* send it... */
21921   S (mp);
21922   /* Wait for the reply */
21923   W (ret);
21924   return ret;
21925 }
21926
21927 static int
21928 api_dns_resolve_ip (vat_main_t * vam)
21929 {
21930   unformat_input_t *line_input = vam->input;
21931   vl_api_dns_resolve_ip_t *mp;
21932   int is_ip6 = -1;
21933   ip4_address_t addr4;
21934   ip6_address_t addr6;
21935   int ret;
21936
21937   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21938     {
21939       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21940         is_ip6 = 1;
21941       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21942         is_ip6 = 0;
21943       else
21944         break;
21945     }
21946
21947   if (is_ip6 == -1)
21948     {
21949       errmsg ("missing address");
21950       return -99;
21951     }
21952
21953   /* Construct the API message */
21954   M (DNS_RESOLVE_IP, mp);
21955   mp->is_ip6 = is_ip6;
21956   if (is_ip6)
21957     memcpy (mp->address, &addr6, sizeof (addr6));
21958   else
21959     memcpy (mp->address, &addr4, sizeof (addr4));
21960
21961   /* send it... */
21962   S (mp);
21963   /* Wait for the reply */
21964   W (ret);
21965   return ret;
21966 }
21967
21968 static int
21969 api_dns_name_server_add_del (vat_main_t * vam)
21970 {
21971   unformat_input_t *i = vam->input;
21972   vl_api_dns_name_server_add_del_t *mp;
21973   u8 is_add = 1;
21974   ip6_address_t ip6_server;
21975   ip4_address_t ip4_server;
21976   int ip6_set = 0;
21977   int ip4_set = 0;
21978   int ret = 0;
21979
21980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21981     {
21982       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21983         ip6_set = 1;
21984       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21985         ip4_set = 1;
21986       else if (unformat (i, "del"))
21987         is_add = 0;
21988       else
21989         {
21990           clib_warning ("parse error '%U'", format_unformat_error, i);
21991           return -99;
21992         }
21993     }
21994
21995   if (ip4_set && ip6_set)
21996     {
21997       errmsg ("Only one server address allowed per message");
21998       return -99;
21999     }
22000   if ((ip4_set + ip6_set) == 0)
22001     {
22002       errmsg ("Server address required");
22003       return -99;
22004     }
22005
22006   /* Construct the API message */
22007   M (DNS_NAME_SERVER_ADD_DEL, mp);
22008
22009   if (ip6_set)
22010     {
22011       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22012       mp->is_ip6 = 1;
22013     }
22014   else
22015     {
22016       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22017       mp->is_ip6 = 0;
22018     }
22019
22020   mp->is_add = is_add;
22021
22022   /* send it... */
22023   S (mp);
22024
22025   /* Wait for a reply, return good/bad news  */
22026   W (ret);
22027   return ret;
22028 }
22029
22030 static void
22031 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22032 {
22033   vat_main_t *vam = &vat_main;
22034
22035   if (mp->is_ip4)
22036     {
22037       print (vam->ofp,
22038              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22039              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22040              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22041              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22042              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22043              clib_net_to_host_u32 (mp->action_index), mp->tag);
22044     }
22045   else
22046     {
22047       print (vam->ofp,
22048              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22049              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22050              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22051              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22052              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22053              clib_net_to_host_u32 (mp->action_index), mp->tag);
22054     }
22055 }
22056
22057 static void
22058 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22059                                              mp)
22060 {
22061   vat_main_t *vam = &vat_main;
22062   vat_json_node_t *node = NULL;
22063   struct in6_addr ip6;
22064   struct in_addr ip4;
22065
22066   if (VAT_JSON_ARRAY != vam->json_tree.type)
22067     {
22068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22069       vat_json_init_array (&vam->json_tree);
22070     }
22071   node = vat_json_array_add (&vam->json_tree);
22072   vat_json_init_object (node);
22073
22074   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22075   vat_json_object_add_uint (node, "appns_index",
22076                             clib_net_to_host_u32 (mp->appns_index));
22077   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22078   vat_json_object_add_uint (node, "scope", mp->scope);
22079   vat_json_object_add_uint (node, "action_index",
22080                             clib_net_to_host_u32 (mp->action_index));
22081   vat_json_object_add_uint (node, "lcl_port",
22082                             clib_net_to_host_u16 (mp->lcl_port));
22083   vat_json_object_add_uint (node, "rmt_port",
22084                             clib_net_to_host_u16 (mp->rmt_port));
22085   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22086   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22087   vat_json_object_add_string_copy (node, "tag", mp->tag);
22088   if (mp->is_ip4)
22089     {
22090       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22091       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22092       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22093       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22094     }
22095   else
22096     {
22097       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22098       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22099       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22100       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22101     }
22102 }
22103
22104 static int
22105 api_session_rule_add_del (vat_main_t * vam)
22106 {
22107   vl_api_session_rule_add_del_t *mp;
22108   unformat_input_t *i = vam->input;
22109   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22110   u32 appns_index = 0, scope = 0;
22111   ip4_address_t lcl_ip4, rmt_ip4;
22112   ip6_address_t lcl_ip6, rmt_ip6;
22113   u8 is_ip4 = 1, conn_set = 0;
22114   u8 is_add = 1, *tag = 0;
22115   int ret;
22116
22117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22118     {
22119       if (unformat (i, "del"))
22120         is_add = 0;
22121       else if (unformat (i, "add"))
22122         ;
22123       else if (unformat (i, "proto tcp"))
22124         proto = 0;
22125       else if (unformat (i, "proto udp"))
22126         proto = 1;
22127       else if (unformat (i, "appns %d", &appns_index))
22128         ;
22129       else if (unformat (i, "scope %d", &scope))
22130         ;
22131       else if (unformat (i, "tag %_%v%_", &tag))
22132         ;
22133       else
22134         if (unformat
22135             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22136              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22137              &rmt_port))
22138         {
22139           is_ip4 = 1;
22140           conn_set = 1;
22141         }
22142       else
22143         if (unformat
22144             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22145              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22146              &rmt_port))
22147         {
22148           is_ip4 = 0;
22149           conn_set = 1;
22150         }
22151       else if (unformat (i, "action %d", &action))
22152         ;
22153       else
22154         break;
22155     }
22156   if (proto == ~0 || !conn_set || action == ~0)
22157     {
22158       errmsg ("transport proto, connection and action must be set");
22159       return -99;
22160     }
22161
22162   if (scope > 3)
22163     {
22164       errmsg ("scope should be 0-3");
22165       return -99;
22166     }
22167
22168   M (SESSION_RULE_ADD_DEL, mp);
22169
22170   mp->is_ip4 = is_ip4;
22171   mp->transport_proto = proto;
22172   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22173   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22174   mp->lcl_plen = lcl_plen;
22175   mp->rmt_plen = rmt_plen;
22176   mp->action_index = clib_host_to_net_u32 (action);
22177   mp->appns_index = clib_host_to_net_u32 (appns_index);
22178   mp->scope = scope;
22179   mp->is_add = is_add;
22180   if (is_ip4)
22181     {
22182       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22183       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22184     }
22185   else
22186     {
22187       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22188       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22189     }
22190   if (tag)
22191     {
22192       clib_memcpy (mp->tag, tag, vec_len (tag));
22193       vec_free (tag);
22194     }
22195
22196   S (mp);
22197   W (ret);
22198   return ret;
22199 }
22200
22201 static int
22202 api_session_rules_dump (vat_main_t * vam)
22203 {
22204   vl_api_session_rules_dump_t *mp;
22205   vl_api_control_ping_t *mp_ping;
22206   int ret;
22207
22208   if (!vam->json_output)
22209     {
22210       print (vam->ofp, "%=20s", "Session Rules");
22211     }
22212
22213   M (SESSION_RULES_DUMP, mp);
22214   /* send it... */
22215   S (mp);
22216
22217   /* Use a control ping for synchronization */
22218   MPING (CONTROL_PING, mp_ping);
22219   S (mp_ping);
22220
22221   /* Wait for a reply... */
22222   W (ret);
22223   return ret;
22224 }
22225
22226 static int
22227 api_ip_container_proxy_add_del (vat_main_t * vam)
22228 {
22229   vl_api_ip_container_proxy_add_del_t *mp;
22230   unformat_input_t *i = vam->input;
22231   u32 plen = ~0, sw_if_index = ~0;
22232   ip4_address_t ip4;
22233   ip6_address_t ip6;
22234   u8 is_ip4 = 1;
22235   u8 is_add = 1;
22236   int ret;
22237
22238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22239     {
22240       if (unformat (i, "del"))
22241         is_add = 0;
22242       else if (unformat (i, "add"))
22243         ;
22244       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22245         {
22246           is_ip4 = 1;
22247           plen = 32;
22248         }
22249       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22250         {
22251           is_ip4 = 0;
22252           plen = 128;
22253         }
22254       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22255         ;
22256       else
22257         break;
22258     }
22259   if (sw_if_index == ~0 || plen == ~0)
22260     {
22261       errmsg ("address and sw_if_index must be set");
22262       return -99;
22263     }
22264
22265   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22266
22267   mp->is_ip4 = is_ip4;
22268   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22269   mp->plen = plen;
22270   mp->is_add = is_add;
22271   if (is_ip4)
22272     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22273   else
22274     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22275
22276   S (mp);
22277   W (ret);
22278   return ret;
22279 }
22280
22281 static int
22282 q_or_quit (vat_main_t * vam)
22283 {
22284 #if VPP_API_TEST_BUILTIN == 0
22285   longjmp (vam->jump_buf, 1);
22286 #endif
22287   return 0;                     /* not so much */
22288 }
22289
22290 static int
22291 q (vat_main_t * vam)
22292 {
22293   return q_or_quit (vam);
22294 }
22295
22296 static int
22297 quit (vat_main_t * vam)
22298 {
22299   return q_or_quit (vam);
22300 }
22301
22302 static int
22303 comment (vat_main_t * vam)
22304 {
22305   return 0;
22306 }
22307
22308 static int
22309 cmd_cmp (void *a1, void *a2)
22310 {
22311   u8 **c1 = a1;
22312   u8 **c2 = a2;
22313
22314   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22315 }
22316
22317 static int
22318 help (vat_main_t * vam)
22319 {
22320   u8 **cmds = 0;
22321   u8 *name = 0;
22322   hash_pair_t *p;
22323   unformat_input_t *i = vam->input;
22324   int j;
22325
22326   if (unformat (i, "%s", &name))
22327     {
22328       uword *hs;
22329
22330       vec_add1 (name, 0);
22331
22332       hs = hash_get_mem (vam->help_by_name, name);
22333       if (hs)
22334         print (vam->ofp, "usage: %s %s", name, hs[0]);
22335       else
22336         print (vam->ofp, "No such msg / command '%s'", name);
22337       vec_free (name);
22338       return 0;
22339     }
22340
22341   print (vam->ofp, "Help is available for the following:");
22342
22343     /* *INDENT-OFF* */
22344     hash_foreach_pair (p, vam->function_by_name,
22345     ({
22346       vec_add1 (cmds, (u8 *)(p->key));
22347     }));
22348     /* *INDENT-ON* */
22349
22350   vec_sort_with_function (cmds, cmd_cmp);
22351
22352   for (j = 0; j < vec_len (cmds); j++)
22353     print (vam->ofp, "%s", cmds[j]);
22354
22355   vec_free (cmds);
22356   return 0;
22357 }
22358
22359 static int
22360 set (vat_main_t * vam)
22361 {
22362   u8 *name = 0, *value = 0;
22363   unformat_input_t *i = vam->input;
22364
22365   if (unformat (i, "%s", &name))
22366     {
22367       /* The input buffer is a vector, not a string. */
22368       value = vec_dup (i->buffer);
22369       vec_delete (value, i->index, 0);
22370       /* Almost certainly has a trailing newline */
22371       if (value[vec_len (value) - 1] == '\n')
22372         value[vec_len (value) - 1] = 0;
22373       /* Make sure it's a proper string, one way or the other */
22374       vec_add1 (value, 0);
22375       (void) clib_macro_set_value (&vam->macro_main,
22376                                    (char *) name, (char *) value);
22377     }
22378   else
22379     errmsg ("usage: set <name> <value>");
22380
22381   vec_free (name);
22382   vec_free (value);
22383   return 0;
22384 }
22385
22386 static int
22387 unset (vat_main_t * vam)
22388 {
22389   u8 *name = 0;
22390
22391   if (unformat (vam->input, "%s", &name))
22392     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22393       errmsg ("unset: %s wasn't set", name);
22394   vec_free (name);
22395   return 0;
22396 }
22397
22398 typedef struct
22399 {
22400   u8 *name;
22401   u8 *value;
22402 } macro_sort_t;
22403
22404
22405 static int
22406 macro_sort_cmp (void *a1, void *a2)
22407 {
22408   macro_sort_t *s1 = a1;
22409   macro_sort_t *s2 = a2;
22410
22411   return strcmp ((char *) (s1->name), (char *) (s2->name));
22412 }
22413
22414 static int
22415 dump_macro_table (vat_main_t * vam)
22416 {
22417   macro_sort_t *sort_me = 0, *sm;
22418   int i;
22419   hash_pair_t *p;
22420
22421     /* *INDENT-OFF* */
22422     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22423     ({
22424       vec_add2 (sort_me, sm, 1);
22425       sm->name = (u8 *)(p->key);
22426       sm->value = (u8 *) (p->value[0]);
22427     }));
22428     /* *INDENT-ON* */
22429
22430   vec_sort_with_function (sort_me, macro_sort_cmp);
22431
22432   if (vec_len (sort_me))
22433     print (vam->ofp, "%-15s%s", "Name", "Value");
22434   else
22435     print (vam->ofp, "The macro table is empty...");
22436
22437   for (i = 0; i < vec_len (sort_me); i++)
22438     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22439   return 0;
22440 }
22441
22442 static int
22443 dump_node_table (vat_main_t * vam)
22444 {
22445   int i, j;
22446   vlib_node_t *node, *next_node;
22447
22448   if (vec_len (vam->graph_nodes) == 0)
22449     {
22450       print (vam->ofp, "Node table empty, issue get_node_graph...");
22451       return 0;
22452     }
22453
22454   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22455     {
22456       node = vam->graph_nodes[i];
22457       print (vam->ofp, "[%d] %s", i, node->name);
22458       for (j = 0; j < vec_len (node->next_nodes); j++)
22459         {
22460           if (node->next_nodes[j] != ~0)
22461             {
22462               next_node = vam->graph_nodes[node->next_nodes[j]];
22463               print (vam->ofp, "  [%d] %s", j, next_node->name);
22464             }
22465         }
22466     }
22467   return 0;
22468 }
22469
22470 static int
22471 value_sort_cmp (void *a1, void *a2)
22472 {
22473   name_sort_t *n1 = a1;
22474   name_sort_t *n2 = a2;
22475
22476   if (n1->value < n2->value)
22477     return -1;
22478   if (n1->value > n2->value)
22479     return 1;
22480   return 0;
22481 }
22482
22483
22484 static int
22485 dump_msg_api_table (vat_main_t * vam)
22486 {
22487   api_main_t *am = &api_main;
22488   name_sort_t *nses = 0, *ns;
22489   hash_pair_t *hp;
22490   int i;
22491
22492   /* *INDENT-OFF* */
22493   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22494   ({
22495     vec_add2 (nses, ns, 1);
22496     ns->name = (u8 *)(hp->key);
22497     ns->value = (u32) hp->value[0];
22498   }));
22499   /* *INDENT-ON* */
22500
22501   vec_sort_with_function (nses, value_sort_cmp);
22502
22503   for (i = 0; i < vec_len (nses); i++)
22504     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22505   vec_free (nses);
22506   return 0;
22507 }
22508
22509 static int
22510 get_msg_id (vat_main_t * vam)
22511 {
22512   u8 *name_and_crc;
22513   u32 message_index;
22514
22515   if (unformat (vam->input, "%s", &name_and_crc))
22516     {
22517       message_index = vl_msg_api_get_msg_index (name_and_crc);
22518       if (message_index == ~0)
22519         {
22520           print (vam->ofp, " '%s' not found", name_and_crc);
22521           return 0;
22522         }
22523       print (vam->ofp, " '%s' has message index %d",
22524              name_and_crc, message_index);
22525       return 0;
22526     }
22527   errmsg ("name_and_crc required...");
22528   return 0;
22529 }
22530
22531 static int
22532 search_node_table (vat_main_t * vam)
22533 {
22534   unformat_input_t *line_input = vam->input;
22535   u8 *node_to_find;
22536   int j;
22537   vlib_node_t *node, *next_node;
22538   uword *p;
22539
22540   if (vam->graph_node_index_by_name == 0)
22541     {
22542       print (vam->ofp, "Node table empty, issue get_node_graph...");
22543       return 0;
22544     }
22545
22546   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22547     {
22548       if (unformat (line_input, "%s", &node_to_find))
22549         {
22550           vec_add1 (node_to_find, 0);
22551           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22552           if (p == 0)
22553             {
22554               print (vam->ofp, "%s not found...", node_to_find);
22555               goto out;
22556             }
22557           node = vam->graph_nodes[p[0]];
22558           print (vam->ofp, "[%d] %s", p[0], node->name);
22559           for (j = 0; j < vec_len (node->next_nodes); j++)
22560             {
22561               if (node->next_nodes[j] != ~0)
22562                 {
22563                   next_node = vam->graph_nodes[node->next_nodes[j]];
22564                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22565                 }
22566             }
22567         }
22568
22569       else
22570         {
22571           clib_warning ("parse error '%U'", format_unformat_error,
22572                         line_input);
22573           return -99;
22574         }
22575
22576     out:
22577       vec_free (node_to_find);
22578
22579     }
22580
22581   return 0;
22582 }
22583
22584
22585 static int
22586 script (vat_main_t * vam)
22587 {
22588 #if (VPP_API_TEST_BUILTIN==0)
22589   u8 *s = 0;
22590   char *save_current_file;
22591   unformat_input_t save_input;
22592   jmp_buf save_jump_buf;
22593   u32 save_line_number;
22594
22595   FILE *new_fp, *save_ifp;
22596
22597   if (unformat (vam->input, "%s", &s))
22598     {
22599       new_fp = fopen ((char *) s, "r");
22600       if (new_fp == 0)
22601         {
22602           errmsg ("Couldn't open script file %s", s);
22603           vec_free (s);
22604           return -99;
22605         }
22606     }
22607   else
22608     {
22609       errmsg ("Missing script name");
22610       return -99;
22611     }
22612
22613   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22614   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22615   save_ifp = vam->ifp;
22616   save_line_number = vam->input_line_number;
22617   save_current_file = (char *) vam->current_file;
22618
22619   vam->input_line_number = 0;
22620   vam->ifp = new_fp;
22621   vam->current_file = s;
22622   do_one_file (vam);
22623
22624   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22625   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22626   vam->ifp = save_ifp;
22627   vam->input_line_number = save_line_number;
22628   vam->current_file = (u8 *) save_current_file;
22629   vec_free (s);
22630
22631   return 0;
22632 #else
22633   clib_warning ("use the exec command...");
22634   return -99;
22635 #endif
22636 }
22637
22638 static int
22639 echo (vat_main_t * vam)
22640 {
22641   print (vam->ofp, "%v", vam->input->buffer);
22642   return 0;
22643 }
22644
22645 /* List of API message constructors, CLI names map to api_xxx */
22646 #define foreach_vpe_api_msg                                             \
22647 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22648 _(sw_interface_dump,"")                                                 \
22649 _(sw_interface_set_flags,                                               \
22650   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22651 _(sw_interface_add_del_address,                                         \
22652   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22653 _(sw_interface_set_rx_mode,                                             \
22654   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22655 _(sw_interface_set_table,                                               \
22656   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22657 _(sw_interface_set_mpls_enable,                                         \
22658   "<intfc> | sw_if_index [disable | dis]")                              \
22659 _(sw_interface_set_vpath,                                               \
22660   "<intfc> | sw_if_index <id> enable | disable")                        \
22661 _(sw_interface_set_vxlan_bypass,                                        \
22662   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22663 _(sw_interface_set_geneve_bypass,                                       \
22664   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22665 _(sw_interface_set_l2_xconnect,                                         \
22666   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22667   "enable | disable")                                                   \
22668 _(sw_interface_set_l2_bridge,                                           \
22669   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22670   "[shg <split-horizon-group>] [bvi]\n"                                 \
22671   "enable | disable")                                                   \
22672 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22673 _(bridge_domain_add_del,                                                \
22674   "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") \
22675 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22676 _(l2fib_add_del,                                                        \
22677   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22678 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22679 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22680 _(l2_flags,                                                             \
22681   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22682 _(bridge_flags,                                                         \
22683   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22684 _(tap_connect,                                                          \
22685   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22686 _(tap_modify,                                                           \
22687   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22688 _(tap_delete,                                                           \
22689   "<vpp-if-name> | sw_if_index <id>")                                   \
22690 _(sw_interface_tap_dump, "")                                            \
22691 _(tap_create_v2,                                                        \
22692   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22693 _(tap_delete_v2,                                                        \
22694   "<vpp-if-name> | sw_if_index <id>")                                   \
22695 _(sw_interface_tap_v2_dump, "")                                         \
22696 _(ip_table_add_del,                                                     \
22697   "table-id <n> [ipv6]\n")                                              \
22698 _(ip_add_del_route,                                                     \
22699   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22700   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22701   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22702   "[multipath] [count <n>]")                                            \
22703 _(ip_mroute_add_del,                                                    \
22704   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22705   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22706 _(mpls_table_add_del,                                                   \
22707   "table-id <n>\n")                                                     \
22708 _(mpls_route_add_del,                                                   \
22709   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22710   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22711   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22712   "[multipath] [count <n>]")                                            \
22713 _(mpls_ip_bind_unbind,                                                  \
22714   "<label> <addr/len>")                                                 \
22715 _(mpls_tunnel_add_del,                                                  \
22716   " via <addr> [table-id <n>]\n"                                        \
22717   "sw_if_index <id>] [l2]  [del]")                                      \
22718 _(bier_table_add_del,                                                   \
22719   "<label> <sub-domain> <set> <bsl> [del]")                             \
22720 _(bier_route_add_del,                                                   \
22721   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22722   "[<intfc> | sw_if_index <id>]"                                        \
22723   "[weight <n>] [del] [multipath]")                                     \
22724 _(proxy_arp_add_del,                                                    \
22725   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22726 _(proxy_arp_intfc_enable_disable,                                       \
22727   "<intfc> | sw_if_index <id> enable | disable")                        \
22728 _(sw_interface_set_unnumbered,                                          \
22729   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22730 _(ip_neighbor_add_del,                                                  \
22731   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22732   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22733 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22734 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22735   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22736   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22737   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22738 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22739 _(reset_fib, "vrf <n> [ipv6]")                                          \
22740 _(dhcp_proxy_config,                                                    \
22741   "svr <v46-address> src <v46-address>\n"                               \
22742    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22743 _(dhcp_proxy_set_vss,                                                   \
22744   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22745 _(dhcp_proxy_dump, "ip6")                                               \
22746 _(dhcp_client_config,                                                   \
22747   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22748 _(set_ip_flow_hash,                                                     \
22749   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22750 _(sw_interface_ip6_enable_disable,                                      \
22751   "<intfc> | sw_if_index <id> enable | disable")                        \
22752 _(sw_interface_ip6_set_link_local_address,                              \
22753   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22754 _(ip6nd_proxy_add_del,                                                  \
22755   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22756 _(ip6nd_proxy_dump, "")                                                 \
22757 _(sw_interface_ip6nd_ra_prefix,                                         \
22758   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22759   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22760   "[nolink] [isno]")                                                    \
22761 _(sw_interface_ip6nd_ra_config,                                         \
22762   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22763   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22764   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22765 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22766 _(l2_patch_add_del,                                                     \
22767   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22768   "enable | disable")                                                   \
22769 _(sr_localsid_add_del,                                                  \
22770   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22771   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22772 _(classify_add_del_table,                                               \
22773   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22774   " [del] [del-chain] mask <mask-value>\n"                              \
22775   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22776   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22777 _(classify_add_del_session,                                             \
22778   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22779   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22780   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22781   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22782 _(classify_set_interface_ip_table,                                      \
22783   "<intfc> | sw_if_index <nn> table <nn>")                              \
22784 _(classify_set_interface_l2_tables,                                     \
22785   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22786   "  [other-table <nn>]")                                               \
22787 _(get_node_index, "node <node-name")                                    \
22788 _(add_node_next, "node <node-name> next <next-node-name>")              \
22789 _(l2tpv3_create_tunnel,                                                 \
22790   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22791   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22792   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22793 _(l2tpv3_set_tunnel_cookies,                                            \
22794   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22795   "[new_remote_cookie <nn>]\n")                                         \
22796 _(l2tpv3_interface_enable_disable,                                      \
22797   "<intfc> | sw_if_index <nn> enable | disable")                        \
22798 _(l2tpv3_set_lookup_key,                                                \
22799   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22800 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22801 _(vxlan_add_del_tunnel,                                                 \
22802   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22803   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22804   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22805 _(geneve_add_del_tunnel,                                                \
22806   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22807   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22808   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22809 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22810 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22811 _(gre_add_del_tunnel,                                                   \
22812   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22813 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22814 _(l2_fib_clear_table, "")                                               \
22815 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22816 _(l2_interface_vlan_tag_rewrite,                                        \
22817   "<intfc> | sw_if_index <nn> \n"                                       \
22818   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22819   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22820 _(create_vhost_user_if,                                                 \
22821         "socket <filename> [server] [renumber <dev_instance>] "         \
22822         "[mac <mac_address>]")                                          \
22823 _(modify_vhost_user_if,                                                 \
22824         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22825         "[server] [renumber <dev_instance>]")                           \
22826 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22827 _(sw_interface_vhost_user_dump, "")                                     \
22828 _(show_version, "")                                                     \
22829 _(vxlan_gpe_add_del_tunnel,                                             \
22830   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22831   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22832   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22833   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22834 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22835 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22836 _(interface_name_renumber,                                              \
22837   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22838 _(input_acl_set_interface,                                              \
22839   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22840   "  [l2-table <nn>] [del]")                                            \
22841 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22842 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22843 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22844 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22845 _(ip_dump, "ipv4 | ipv6")                                               \
22846 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22847 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22848   "  spid_id <n> ")                                                     \
22849 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22850   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22851   "  integ_alg <alg> integ_key <hex>")                                  \
22852 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22853   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22854   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22855   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22856 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22857 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22858   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22859   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22860   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22861 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22862 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22863   "  <alg> <hex>\n")                                                    \
22864 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22865 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22866 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22867   "(auth_data 0x<data> | auth_data <data>)")                            \
22868 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22869   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22870 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22871   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22872   "(local|remote)")                                                     \
22873 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22874 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22875 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22876 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22877 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22878 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22879 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22880 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22881 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22882 _(delete_loopback,"sw_if_index <nn>")                                   \
22883 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22884 _(map_add_domain,                                                       \
22885   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22886   "ip6-src <ip6addr> "                                                  \
22887   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22888 _(map_del_domain, "index <n>")                                          \
22889 _(map_add_del_rule,                                                     \
22890   "index <n> psid <n> dst <ip6addr> [del]")                             \
22891 _(map_domain_dump, "")                                                  \
22892 _(map_rule_dump, "index <map-domain>")                                  \
22893 _(want_interface_events,  "enable|disable")                             \
22894 _(want_stats,"enable|disable")                                          \
22895 _(get_first_msg_id, "client <name>")                                    \
22896 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22897 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22898   "fib-id <nn> [ip4][ip6][default]")                                    \
22899 _(get_node_graph, " ")                                                  \
22900 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22901 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22902 _(ioam_disable, "")                                                     \
22903 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22904                             " sw_if_index <sw_if_index> p <priority> "  \
22905                             "w <weight>] [del]")                        \
22906 _(one_add_del_locator, "locator-set <locator_name> "                    \
22907                         "iface <intf> | sw_if_index <sw_if_index> "     \
22908                         "p <priority> w <weight> [del]")                \
22909 _(one_add_del_local_eid,"vni <vni> eid "                                \
22910                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22911                          "locator-set <locator_name> [del]"             \
22912                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22913 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22914 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22915 _(one_enable_disable, "enable|disable")                                 \
22916 _(one_map_register_enable_disable, "enable|disable")                    \
22917 _(one_map_register_fallback_threshold, "<value>")                       \
22918 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22919 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22920                                "[seid <seid>] "                         \
22921                                "rloc <locator> p <prio> "               \
22922                                "w <weight> [rloc <loc> ... ] "          \
22923                                "action <action> [del-all]")             \
22924 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22925                           "<local-eid>")                                \
22926 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22927 _(one_use_petr, "ip-address> | disable")                                \
22928 _(one_map_request_mode, "src-dst|dst-only")                             \
22929 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22930 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22931 _(one_locator_set_dump, "[local | remote]")                             \
22932 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22933 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22934                        "[local] | [remote]")                            \
22935 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22936 _(one_ndp_bd_get, "")                                                   \
22937 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22938 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22939 _(one_l2_arp_bd_get, "")                                                \
22940 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22941 _(one_stats_enable_disable, "enable|disalbe")                           \
22942 _(show_one_stats_enable_disable, "")                                    \
22943 _(one_eid_table_vni_dump, "")                                           \
22944 _(one_eid_table_map_dump, "l2|l3")                                      \
22945 _(one_map_resolver_dump, "")                                            \
22946 _(one_map_server_dump, "")                                              \
22947 _(one_adjacencies_get, "vni <vni>")                                     \
22948 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22949 _(show_one_rloc_probe_state, "")                                        \
22950 _(show_one_map_register_state, "")                                      \
22951 _(show_one_status, "")                                                  \
22952 _(one_stats_dump, "")                                                   \
22953 _(one_stats_flush, "")                                                  \
22954 _(one_get_map_request_itr_rlocs, "")                                    \
22955 _(one_map_register_set_ttl, "<ttl>")                                    \
22956 _(one_set_transport_protocol, "udp|api")                                \
22957 _(one_get_transport_protocol, "")                                       \
22958 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22959 _(one_show_xtr_mode, "")                                                \
22960 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22961 _(one_show_pitr_mode, "")                                               \
22962 _(one_enable_disable_petr_mode, "enable|disable")                       \
22963 _(one_show_petr_mode, "")                                               \
22964 _(show_one_nsh_mapping, "")                                             \
22965 _(show_one_pitr, "")                                                    \
22966 _(show_one_use_petr, "")                                                \
22967 _(show_one_map_request_mode, "")                                        \
22968 _(show_one_map_register_ttl, "")                                        \
22969 _(show_one_map_register_fallback_threshold, "")                         \
22970 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22971                             " sw_if_index <sw_if_index> p <priority> "  \
22972                             "w <weight>] [del]")                        \
22973 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22974                         "iface <intf> | sw_if_index <sw_if_index> "     \
22975                         "p <priority> w <weight> [del]")                \
22976 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22977                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22978                          "locator-set <locator_name> [del]"             \
22979                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22980 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22981 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22982 _(lisp_enable_disable, "enable|disable")                                \
22983 _(lisp_map_register_enable_disable, "enable|disable")                   \
22984 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22985 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22986                                "[seid <seid>] "                         \
22987                                "rloc <locator> p <prio> "               \
22988                                "w <weight> [rloc <loc> ... ] "          \
22989                                "action <action> [del-all]")             \
22990 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22991                           "<local-eid>")                                \
22992 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22993 _(lisp_use_petr, "<ip-address> | disable")                              \
22994 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22995 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22996 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22997 _(lisp_locator_set_dump, "[local | remote]")                            \
22998 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22999 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23000                        "[local] | [remote]")                            \
23001 _(lisp_eid_table_vni_dump, "")                                          \
23002 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23003 _(lisp_map_resolver_dump, "")                                           \
23004 _(lisp_map_server_dump, "")                                             \
23005 _(lisp_adjacencies_get, "vni <vni>")                                    \
23006 _(gpe_fwd_entry_vnis_get, "")                                           \
23007 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23008 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23009                                 "[table <table-id>]")                   \
23010 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23011 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23012 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23013 _(gpe_get_encap_mode, "")                                               \
23014 _(lisp_gpe_add_del_iface, "up|down")                                    \
23015 _(lisp_gpe_enable_disable, "enable|disable")                            \
23016 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23017   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23018 _(show_lisp_rloc_probe_state, "")                                       \
23019 _(show_lisp_map_register_state, "")                                     \
23020 _(show_lisp_status, "")                                                 \
23021 _(lisp_get_map_request_itr_rlocs, "")                                   \
23022 _(show_lisp_pitr, "")                                                   \
23023 _(show_lisp_use_petr, "")                                               \
23024 _(show_lisp_map_request_mode, "")                                       \
23025 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23026 _(af_packet_delete, "name <host interface name>")                       \
23027 _(policer_add_del, "name <policer name> <params> [del]")                \
23028 _(policer_dump, "[name <policer name>]")                                \
23029 _(policer_classify_set_interface,                                       \
23030   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23031   "  [l2-table <nn>] [del]")                                            \
23032 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23033 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23034     "[master|slave]")                                                   \
23035 _(netmap_delete, "name <interface name>")                               \
23036 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23037 _(mpls_fib_dump, "")                                                    \
23038 _(classify_table_ids, "")                                               \
23039 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23040 _(classify_table_info, "table_id <nn>")                                 \
23041 _(classify_session_dump, "table_id <nn>")                               \
23042 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23043     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23044     "[template_interval <nn>] [udp_checksum]")                          \
23045 _(ipfix_exporter_dump, "")                                              \
23046 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23047 _(ipfix_classify_stream_dump, "")                                       \
23048 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23049 _(ipfix_classify_table_dump, "")                                        \
23050 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23051 _(sw_interface_span_dump, "[l2]")                                           \
23052 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23053 _(pg_create_interface, "if_id <nn>")                                    \
23054 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23055 _(pg_enable_disable, "[stream <id>] disable")                           \
23056 _(ip_source_and_port_range_check_add_del,                               \
23057   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23058 _(ip_source_and_port_range_check_interface_add_del,                     \
23059   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23060   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23061 _(ipsec_gre_add_del_tunnel,                                             \
23062   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23063 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23064 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23065 _(l2_interface_pbb_tag_rewrite,                                         \
23066   "<intfc> | sw_if_index <nn> \n"                                       \
23067   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23068   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23069 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23070 _(flow_classify_set_interface,                                          \
23071   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23072 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23073 _(ip_fib_dump, "")                                                      \
23074 _(ip_mfib_dump, "")                                                     \
23075 _(ip6_fib_dump, "")                                                     \
23076 _(ip6_mfib_dump, "")                                                    \
23077 _(feature_enable_disable, "arc_name <arc_name> "                        \
23078   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23079 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23080 "[disable]")                                                            \
23081 _(l2_xconnect_dump, "")                                                 \
23082 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23083 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23084 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23085 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23086 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23087 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23088 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23089   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23090 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23091 _(memfd_segment_create,"size <nnn>")                                    \
23092 _(sock_init_shm, "size <nnn>")                                          \
23093 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23094 _(dns_enable_disable, "[enable][disable]")                              \
23095 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23096 _(dns_resolve_name, "<hostname>")                                       \
23097 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23098 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23099 _(dns_resolve_name, "<hostname>")                                       \
23100 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23101   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23102 _(session_rules_dump, "")                                               \
23103 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23104
23105 /* List of command functions, CLI names map directly to functions */
23106 #define foreach_cli_function                                    \
23107 _(comment, "usage: comment <ignore-rest-of-line>")              \
23108 _(dump_interface_table, "usage: dump_interface_table")          \
23109 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23110 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23111 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23112 _(dump_stats_table, "usage: dump_stats_table")                  \
23113 _(dump_macro_table, "usage: dump_macro_table ")                 \
23114 _(dump_node_table, "usage: dump_node_table")                    \
23115 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23116 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23117 _(echo, "usage: echo <message>")                                \
23118 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23119 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23120 _(help, "usage: help")                                          \
23121 _(q, "usage: quit")                                             \
23122 _(quit, "usage: quit")                                          \
23123 _(search_node_table, "usage: search_node_table <name>...")      \
23124 _(set, "usage: set <variable-name> <value>")                    \
23125 _(script, "usage: script <file-name>")                          \
23126 _(unset, "usage: unset <variable-name>")
23127 #define _(N,n)                                  \
23128     static void vl_api_##n##_t_handler_uni      \
23129     (vl_api_##n##_t * mp)                       \
23130     {                                           \
23131         vat_main_t * vam = &vat_main;           \
23132         if (vam->json_output) {                 \
23133             vl_api_##n##_t_handler_json(mp);    \
23134         } else {                                \
23135             vl_api_##n##_t_handler(mp);         \
23136         }                                       \
23137     }
23138 foreach_vpe_api_reply_msg;
23139 #if VPP_API_TEST_BUILTIN == 0
23140 foreach_standalone_reply_msg;
23141 #endif
23142 #undef _
23143
23144 void
23145 vat_api_hookup (vat_main_t * vam)
23146 {
23147 #define _(N,n)                                                  \
23148     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23149                            vl_api_##n##_t_handler_uni,          \
23150                            vl_noop_handler,                     \
23151                            vl_api_##n##_t_endian,               \
23152                            vl_api_##n##_t_print,                \
23153                            sizeof(vl_api_##n##_t), 1);
23154   foreach_vpe_api_reply_msg;
23155 #if VPP_API_TEST_BUILTIN == 0
23156   foreach_standalone_reply_msg;
23157 #endif
23158 #undef _
23159
23160 #if (VPP_API_TEST_BUILTIN==0)
23161   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23162
23163   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23164
23165   vam->function_by_name = hash_create_string (0, sizeof (uword));
23166
23167   vam->help_by_name = hash_create_string (0, sizeof (uword));
23168 #endif
23169
23170   /* API messages we can send */
23171 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23172   foreach_vpe_api_msg;
23173 #undef _
23174
23175   /* Help strings */
23176 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23177   foreach_vpe_api_msg;
23178 #undef _
23179
23180   /* CLI functions */
23181 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23182   foreach_cli_function;
23183 #undef _
23184
23185   /* Help strings */
23186 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23187   foreach_cli_function;
23188 #undef _
23189 }
23190
23191 #if VPP_API_TEST_BUILTIN
23192 static clib_error_t *
23193 vat_api_hookup_shim (vlib_main_t * vm)
23194 {
23195   vat_api_hookup (&vat_main);
23196   return 0;
23197 }
23198
23199 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23200 #endif
23201
23202 /*
23203  * fd.io coding-style-patch-verification: ON
23204  *
23205  * Local Variables:
23206  * eval: (c-set-style "gnu")
23207  * End:
23208  */