ipsec: allow null/null for crypto/integ algorithms pair
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/in_out_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
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  action %d \n",
1353               i + 1, ntohl (mac->sw_if_index),
1354               format_ethernet_address, mac->mac_addr, mac->action);
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
1780 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   i32 retval = ntohl (mp->retval);
1784
1785   if (vam->async_mode)
1786     {
1787       vam->async_errors += (retval < 0);
1788     }
1789   else
1790     {
1791       vam->retval = retval;
1792       vam->sw_if_index = ntohl (mp->sw_if_index);
1793       vam->result_ready = 1;
1794     }
1795 }
1796
1797 static void vl_api_bond_create_reply_t_handler_json
1798   (vl_api_bond_create_reply_t * mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   vat_json_node_t node;
1802
1803   vat_json_init_object (&node);
1804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1806
1807   vat_json_print (vam->ofp, &node);
1808   vat_json_free (&node);
1809
1810   vam->retval = ntohl (mp->retval);
1811   vam->result_ready = 1;
1812 }
1813
1814 static void
1815 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   i32 retval = ntohl (mp->retval);
1819
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       vam->retval = retval;
1827       vam->result_ready = 1;
1828     }
1829 }
1830
1831 static void vl_api_bond_delete_reply_t_handler_json
1832   (vl_api_bond_delete_reply_t * mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   vat_json_node_t node;
1836
1837   vat_json_init_object (&node);
1838   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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
1848 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851   i32 retval = ntohl (mp->retval);
1852
1853   if (vam->async_mode)
1854     {
1855       vam->async_errors += (retval < 0);
1856     }
1857   else
1858     {
1859       vam->retval = retval;
1860       vam->result_ready = 1;
1861     }
1862 }
1863
1864 static void vl_api_bond_enslave_reply_t_handler_json
1865   (vl_api_bond_enslave_reply_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   vat_json_node_t node;
1869
1870   vat_json_init_object (&node);
1871   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 static void
1881 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1882                                           mp)
1883 {
1884   vat_main_t *vam = &vat_main;
1885   i32 retval = ntohl (mp->retval);
1886
1887   if (vam->async_mode)
1888     {
1889       vam->async_errors += (retval < 0);
1890     }
1891   else
1892     {
1893       vam->retval = retval;
1894       vam->result_ready = 1;
1895     }
1896 }
1897
1898 static void vl_api_bond_detach_slave_reply_t_handler_json
1899   (vl_api_bond_detach_slave_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   vat_json_node_t node;
1903
1904   vat_json_init_object (&node);
1905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1906
1907   vat_json_print (vam->ofp, &node);
1908   vat_json_free (&node);
1909
1910   vam->retval = ntohl (mp->retval);
1911   vam->result_ready = 1;
1912 }
1913
1914 static void vl_api_sw_interface_bond_details_t_handler
1915   (vl_api_sw_interface_bond_details_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918
1919   print (vam->ofp,
1920          "%-16s %-12d %-12U %-13U %-14u %-14u",
1921          mp->interface_name, ntohl (mp->sw_if_index),
1922          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1923          ntohl (mp->active_slaves), ntohl (mp->slaves));
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler_json
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t *node = NULL;
1931
1932   if (VAT_JSON_ARRAY != vam->json_tree.type)
1933     {
1934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1935       vat_json_init_array (&vam->json_tree);
1936     }
1937   node = vat_json_array_add (&vam->json_tree);
1938
1939   vat_json_init_object (node);
1940   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1941   vat_json_object_add_string_copy (node, "interface_name",
1942                                    mp->interface_name);
1943   vat_json_object_add_uint (node, "mode", mp->mode);
1944   vat_json_object_add_uint (node, "load_balance", mp->lb);
1945   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1946   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1947 }
1948
1949 static int
1950 api_sw_interface_bond_dump (vat_main_t * vam)
1951 {
1952   vl_api_sw_interface_bond_dump_t *mp;
1953   vl_api_control_ping_t *mp_ping;
1954   int ret;
1955
1956   print (vam->ofp,
1957          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1958          "interface name", "sw_if_index", "mode", "load balance",
1959          "active slaves", "slaves");
1960
1961   /* Get list of bond interfaces */
1962   M (SW_INTERFACE_BOND_DUMP, mp);
1963   S (mp);
1964
1965   /* Use a control ping for synchronization */
1966   MPING (CONTROL_PING, mp_ping);
1967   S (mp_ping);
1968
1969   W (ret);
1970   return ret;
1971 }
1972
1973 static void vl_api_sw_interface_slave_details_t_handler
1974   (vl_api_sw_interface_slave_details_t * mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977
1978   print (vam->ofp,
1979          "%-25s %-12d %-12d %d", mp->interface_name,
1980          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1981 }
1982
1983 static void vl_api_sw_interface_slave_details_t_handler_json
1984   (vl_api_sw_interface_slave_details_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t *node = NULL;
1988
1989   if (VAT_JSON_ARRAY != vam->json_tree.type)
1990     {
1991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1992       vat_json_init_array (&vam->json_tree);
1993     }
1994   node = vat_json_array_add (&vam->json_tree);
1995
1996   vat_json_init_object (node);
1997   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1998   vat_json_object_add_string_copy (node, "interface_name",
1999                                    mp->interface_name);
2000   vat_json_object_add_uint (node, "passive", mp->is_passive);
2001   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2002 }
2003
2004 static int
2005 api_sw_interface_slave_dump (vat_main_t * vam)
2006 {
2007   unformat_input_t *i = vam->input;
2008   vl_api_sw_interface_slave_dump_t *mp;
2009   vl_api_control_ping_t *mp_ping;
2010   u32 sw_if_index = ~0;
2011   u8 sw_if_index_set = 0;
2012   int ret;
2013
2014   /* Parse args required to build the message */
2015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2016     {
2017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2018         sw_if_index_set = 1;
2019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2020         sw_if_index_set = 1;
2021       else
2022         break;
2023     }
2024
2025   if (sw_if_index_set == 0)
2026     {
2027       errmsg ("missing vpp interface name. ");
2028       return -99;
2029     }
2030
2031   print (vam->ofp,
2032          "\n%-25s %-12s %-12s %s",
2033          "slave interface name", "sw_if_index", "passive", "long_timeout");
2034
2035   /* Get list of bond interfaces */
2036   M (SW_INTERFACE_SLAVE_DUMP, mp);
2037   mp->sw_if_index = ntohl (sw_if_index);
2038   S (mp);
2039
2040   /* Use a control ping for synchronization */
2041   MPING (CONTROL_PING, mp_ping);
2042   S (mp_ping);
2043
2044   W (ret);
2045   return ret;
2046 }
2047
2048 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2049   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   i32 retval = ntohl (mp->retval);
2053   if (vam->async_mode)
2054     {
2055       vam->async_errors += (retval < 0);
2056     }
2057   else
2058     {
2059       vam->retval = retval;
2060       vam->result_ready = 1;
2061     }
2062 }
2063
2064 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2065   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2066 {
2067   vat_main_t *vam = &vat_main;
2068   vat_json_node_t node;
2069
2070   vat_json_init_object (&node);
2071   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2072   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2073                             ntohl (mp->sw_if_index));
2074
2075   vat_json_print (vam->ofp, &node);
2076   vat_json_free (&node);
2077
2078   vam->retval = ntohl (mp->retval);
2079   vam->result_ready = 1;
2080 }
2081
2082 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2083   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2084 {
2085   vat_main_t *vam = &vat_main;
2086   i32 retval = ntohl (mp->retval);
2087   if (vam->async_mode)
2088     {
2089       vam->async_errors += (retval < 0);
2090     }
2091   else
2092     {
2093       vam->retval = retval;
2094       vam->sw_if_index = ntohl (mp->sw_if_index);
2095       vam->result_ready = 1;
2096     }
2097 }
2098
2099 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2100   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2101 {
2102   vat_main_t *vam = &vat_main;
2103   vat_json_node_t node;
2104
2105   vat_json_init_object (&node);
2106   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2107   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2108
2109   vat_json_print (vam->ofp, &node);
2110   vat_json_free (&node);
2111
2112   vam->retval = ntohl (mp->retval);
2113   vam->result_ready = 1;
2114 }
2115
2116 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2117   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2118 {
2119   vat_main_t *vam = &vat_main;
2120   i32 retval = ntohl (mp->retval);
2121   if (vam->async_mode)
2122     {
2123       vam->async_errors += (retval < 0);
2124     }
2125   else
2126     {
2127       vam->retval = retval;
2128       vam->result_ready = 1;
2129     }
2130 }
2131
2132 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2133   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2134 {
2135   vat_main_t *vam = &vat_main;
2136   vat_json_node_t node;
2137
2138   vat_json_init_object (&node);
2139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2140   vat_json_object_add_uint (&node, "fwd_entry_index",
2141                             clib_net_to_host_u32 (mp->fwd_entry_index));
2142
2143   vat_json_print (vam->ofp, &node);
2144   vat_json_free (&node);
2145
2146   vam->retval = ntohl (mp->retval);
2147   vam->result_ready = 1;
2148 }
2149
2150 u8 *
2151 format_lisp_transport_protocol (u8 * s, va_list * args)
2152 {
2153   u32 proto = va_arg (*args, u32);
2154
2155   switch (proto)
2156     {
2157     case 1:
2158       return format (s, "udp");
2159     case 2:
2160       return format (s, "api");
2161     default:
2162       return 0;
2163     }
2164   return 0;
2165 }
2166
2167 static void vl_api_one_get_transport_protocol_reply_t_handler
2168   (vl_api_one_get_transport_protocol_reply_t * mp)
2169 {
2170   vat_main_t *vam = &vat_main;
2171   i32 retval = ntohl (mp->retval);
2172   if (vam->async_mode)
2173     {
2174       vam->async_errors += (retval < 0);
2175     }
2176   else
2177     {
2178       u32 proto = mp->protocol;
2179       print (vam->ofp, "Transport protocol: %U",
2180              format_lisp_transport_protocol, proto);
2181       vam->retval = retval;
2182       vam->result_ready = 1;
2183     }
2184 }
2185
2186 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2187   (vl_api_one_get_transport_protocol_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   vat_json_node_t node;
2191   u8 *s;
2192
2193   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2194   vec_add1 (s, 0);
2195
2196   vat_json_init_object (&node);
2197   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2198   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2199
2200   vec_free (s);
2201   vat_json_print (vam->ofp, &node);
2202   vat_json_free (&node);
2203
2204   vam->retval = ntohl (mp->retval);
2205   vam->result_ready = 1;
2206 }
2207
2208 static void vl_api_one_add_del_locator_set_reply_t_handler
2209   (vl_api_one_add_del_locator_set_reply_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   i32 retval = ntohl (mp->retval);
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2225   (vl_api_one_add_del_locator_set_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2233
2234   vat_json_print (vam->ofp, &node);
2235   vat_json_free (&node);
2236
2237   vam->retval = ntohl (mp->retval);
2238   vam->result_ready = 1;
2239 }
2240
2241 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2242   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   i32 retval = ntohl (mp->retval);
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->sw_if_index = ntohl (mp->sw_if_index);
2254       vam->result_ready = 1;
2255     }
2256   vam->regenerate_interface_table = 1;
2257 }
2258
2259 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2260   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   vat_json_node_t node;
2264
2265   vat_json_init_object (&node);
2266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2267   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2277   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   i32 retval = ntohl (mp->retval);
2281   if (vam->async_mode)
2282     {
2283       vam->async_errors += (retval < 0);
2284     }
2285   else
2286     {
2287       vam->retval = retval;
2288       vam->sw_if_index = ntohl (mp->sw_if_index);
2289       vam->result_ready = 1;
2290     }
2291 }
2292
2293 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2294   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2295 {
2296   vat_main_t *vam = &vat_main;
2297   vat_json_node_t node;
2298
2299   vat_json_init_object (&node);
2300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2301   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2311   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   i32 retval = ntohl (mp->retval);
2315   if (vam->async_mode)
2316     {
2317       vam->async_errors += (retval < 0);
2318     }
2319   else
2320     {
2321       vam->retval = retval;
2322       vam->sw_if_index = ntohl (mp->sw_if_index);
2323       vam->result_ready = 1;
2324     }
2325   vam->regenerate_interface_table = 1;
2326 }
2327
2328 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2329   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2330 {
2331   vat_main_t *vam = &vat_main;
2332   vat_json_node_t node;
2333
2334   vat_json_init_object (&node);
2335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2336   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2337
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void vl_api_gre_add_del_tunnel_reply_t_handler
2346   (vl_api_gre_add_del_tunnel_reply_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   i32 retval = ntohl (mp->retval);
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->sw_if_index = ntohl (mp->sw_if_index);
2358       vam->result_ready = 1;
2359     }
2360 }
2361
2362 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2363   (vl_api_gre_add_del_tunnel_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t node;
2367
2368   vat_json_init_object (&node);
2369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2370   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2371
2372   vat_json_print (vam->ofp, &node);
2373   vat_json_free (&node);
2374
2375   vam->retval = ntohl (mp->retval);
2376   vam->result_ready = 1;
2377 }
2378
2379 static void vl_api_create_vhost_user_if_reply_t_handler
2380   (vl_api_create_vhost_user_if_reply_t * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   i32 retval = ntohl (mp->retval);
2384   if (vam->async_mode)
2385     {
2386       vam->async_errors += (retval < 0);
2387     }
2388   else
2389     {
2390       vam->retval = retval;
2391       vam->sw_if_index = ntohl (mp->sw_if_index);
2392       vam->result_ready = 1;
2393     }
2394   vam->regenerate_interface_table = 1;
2395 }
2396
2397 static void vl_api_create_vhost_user_if_reply_t_handler_json
2398   (vl_api_create_vhost_user_if_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   vat_json_node_t node;
2402
2403   vat_json_init_object (&node);
2404   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2405   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static clib_error_t *
2415 receive_fd_msg (int socket_fd, int *my_fd)
2416 {
2417   char msgbuf[16];
2418   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2419   struct msghdr mh = { 0 };
2420   struct iovec iov[1];
2421   ssize_t size;
2422   struct ucred *cr = 0;
2423   struct cmsghdr *cmsg;
2424   pid_t pid __attribute__ ((unused));
2425   uid_t uid __attribute__ ((unused));
2426   gid_t gid __attribute__ ((unused));
2427
2428   iov[0].iov_base = msgbuf;
2429   iov[0].iov_len = 5;
2430   mh.msg_iov = iov;
2431   mh.msg_iovlen = 1;
2432   mh.msg_control = ctl;
2433   mh.msg_controllen = sizeof (ctl);
2434
2435   memset (ctl, 0, sizeof (ctl));
2436
2437   /* receive the incoming message */
2438   size = recvmsg (socket_fd, &mh, 0);
2439   if (size != 5)
2440     {
2441       return (size == 0) ? clib_error_return (0, "disconnected") :
2442         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2443                                 socket_fd);
2444     }
2445
2446   cmsg = CMSG_FIRSTHDR (&mh);
2447   while (cmsg)
2448     {
2449       if (cmsg->cmsg_level == SOL_SOCKET)
2450         {
2451           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2452             {
2453               cr = (struct ucred *) CMSG_DATA (cmsg);
2454               uid = cr->uid;
2455               gid = cr->gid;
2456               pid = cr->pid;
2457             }
2458           else if (cmsg->cmsg_type == SCM_RIGHTS)
2459             {
2460               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2461             }
2462         }
2463       cmsg = CMSG_NXTHDR (&mh, cmsg);
2464     }
2465   return 0;
2466 }
2467
2468 static void vl_api_memfd_segment_create_reply_t_handler
2469   (vl_api_memfd_segment_create_reply_t * mp)
2470 {
2471   /* Dont bother in the builtin version */
2472 #if VPP_API_TEST_BUILTIN == 0
2473   vat_main_t *vam = &vat_main;
2474   api_main_t *am = &api_main;
2475   socket_client_main_t *scm = vam->socket_client_main;
2476   int my_fd = -1;
2477   clib_error_t *error;
2478   ssvm_private_t memfd;
2479   i32 retval = ntohl (mp->retval);
2480
2481   if (retval == 0)
2482     {
2483       error = receive_fd_msg (scm->socket_fd, &my_fd);
2484       if (error)
2485         {
2486           retval = -99;
2487           goto out;
2488         }
2489
2490       memset (&memfd, 0, sizeof (memfd));
2491       memfd.fd = my_fd;
2492
2493       vam->client_index_invalid = 1;
2494
2495       /* Note: this closes memfd.fd */
2496       retval = ssvm_slave_init_memfd (&memfd);
2497       if (retval)
2498         clib_warning ("WARNING: segment map returned %d", retval);
2499
2500       /* Pivot to the memory client segment that vpp just created */
2501
2502       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2503
2504       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2505
2506       vl_client_install_client_message_handlers ();
2507
2508       vl_client_connect_to_vlib_no_map ("pvt",
2509                                         "vpp_api_test(p)",
2510                                         32 /* input_queue_length */ );
2511       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2512
2513       vl_socket_client_enable_disable (0 /* disable socket */ );
2514     }
2515
2516 out:
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->result_ready = 1;
2525     }
2526 #endif
2527 }
2528
2529 static void vl_api_memfd_segment_create_reply_t_handler_json
2530   (vl_api_memfd_segment_create_reply_t * mp)
2531 {
2532   clib_warning ("no");
2533 }
2534
2535 static void vl_api_dns_resolve_name_reply_t_handler
2536   (vl_api_dns_resolve_name_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   i32 retval = ntohl (mp->retval);
2540   if (vam->async_mode)
2541     {
2542       vam->async_errors += (retval < 0);
2543     }
2544   else
2545     {
2546       vam->retval = retval;
2547       vam->result_ready = 1;
2548
2549       if (retval == 0)
2550         {
2551           if (mp->ip4_set)
2552             clib_warning ("ip4 address %U", format_ip4_address,
2553                           (ip4_address_t *) mp->ip4_address);
2554           if (mp->ip6_set)
2555             clib_warning ("ip6 address %U", format_ip6_address,
2556                           (ip6_address_t *) mp->ip6_address);
2557         }
2558       else
2559         clib_warning ("retval %d", retval);
2560     }
2561 }
2562
2563 static void vl_api_dns_resolve_name_reply_t_handler_json
2564   (vl_api_dns_resolve_name_reply_t * mp)
2565 {
2566   clib_warning ("not implemented");
2567 }
2568
2569 static void vl_api_dns_resolve_ip_reply_t_handler
2570   (vl_api_dns_resolve_ip_reply_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   i32 retval = ntohl (mp->retval);
2574   if (vam->async_mode)
2575     {
2576       vam->async_errors += (retval < 0);
2577     }
2578   else
2579     {
2580       vam->retval = retval;
2581       vam->result_ready = 1;
2582
2583       if (retval == 0)
2584         {
2585           clib_warning ("canonical name %s", mp->name);
2586         }
2587       else
2588         clib_warning ("retval %d", retval);
2589     }
2590 }
2591
2592 static void vl_api_dns_resolve_ip_reply_t_handler_json
2593   (vl_api_dns_resolve_ip_reply_t * mp)
2594 {
2595   clib_warning ("not implemented");
2596 }
2597
2598
2599 static void vl_api_ip_address_details_t_handler
2600   (vl_api_ip_address_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   static ip_address_details_t empty_ip_address_details = { {0} };
2604   ip_address_details_t *address = NULL;
2605   ip_details_t *current_ip_details = NULL;
2606   ip_details_t *details = NULL;
2607
2608   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2609
2610   if (!details || vam->current_sw_if_index >= vec_len (details)
2611       || !details[vam->current_sw_if_index].present)
2612     {
2613       errmsg ("ip address details arrived but not stored");
2614       errmsg ("ip_dump should be called first");
2615       return;
2616     }
2617
2618   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2619
2620 #define addresses (current_ip_details->addr)
2621
2622   vec_validate_init_empty (addresses, vec_len (addresses),
2623                            empty_ip_address_details);
2624
2625   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2626
2627   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2628   address->prefix_length = mp->prefix_length;
2629 #undef addresses
2630 }
2631
2632 static void vl_api_ip_address_details_t_handler_json
2633   (vl_api_ip_address_details_t * mp)
2634 {
2635   vat_main_t *vam = &vat_main;
2636   vat_json_node_t *node = NULL;
2637   struct in6_addr ip6;
2638   struct in_addr ip4;
2639
2640   if (VAT_JSON_ARRAY != vam->json_tree.type)
2641     {
2642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2643       vat_json_init_array (&vam->json_tree);
2644     }
2645   node = vat_json_array_add (&vam->json_tree);
2646
2647   vat_json_init_object (node);
2648   if (vam->is_ipv6)
2649     {
2650       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2651       vat_json_object_add_ip6 (node, "ip", ip6);
2652     }
2653   else
2654     {
2655       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2656       vat_json_object_add_ip4 (node, "ip", ip4);
2657     }
2658   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2659 }
2660
2661 static void
2662 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2663 {
2664   vat_main_t *vam = &vat_main;
2665   static ip_details_t empty_ip_details = { 0 };
2666   ip_details_t *ip = NULL;
2667   u32 sw_if_index = ~0;
2668
2669   sw_if_index = ntohl (mp->sw_if_index);
2670
2671   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2672                            sw_if_index, empty_ip_details);
2673
2674   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2675                          sw_if_index);
2676
2677   ip->present = 1;
2678 }
2679
2680 static void
2681 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2682 {
2683   vat_main_t *vam = &vat_main;
2684
2685   if (VAT_JSON_ARRAY != vam->json_tree.type)
2686     {
2687       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2688       vat_json_init_array (&vam->json_tree);
2689     }
2690   vat_json_array_add_uint (&vam->json_tree,
2691                            clib_net_to_host_u32 (mp->sw_if_index));
2692 }
2693
2694 static void vl_api_map_domain_details_t_handler_json
2695   (vl_api_map_domain_details_t * mp)
2696 {
2697   vat_json_node_t *node = NULL;
2698   vat_main_t *vam = &vat_main;
2699   struct in6_addr ip6;
2700   struct in_addr ip4;
2701
2702   if (VAT_JSON_ARRAY != vam->json_tree.type)
2703     {
2704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2705       vat_json_init_array (&vam->json_tree);
2706     }
2707
2708   node = vat_json_array_add (&vam->json_tree);
2709   vat_json_init_object (node);
2710
2711   vat_json_object_add_uint (node, "domain_index",
2712                             clib_net_to_host_u32 (mp->domain_index));
2713   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2714   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2715   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2716   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2717   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2718   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2719   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2720   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2721   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2722   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2723   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2724   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2725   vat_json_object_add_uint (node, "flags", mp->flags);
2726   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2727   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2728 }
2729
2730 static void vl_api_map_domain_details_t_handler
2731   (vl_api_map_domain_details_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734
2735   if (mp->is_translation)
2736     {
2737       print (vam->ofp,
2738              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2739              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2740              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2741              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2742              clib_net_to_host_u32 (mp->domain_index));
2743     }
2744   else
2745     {
2746       print (vam->ofp,
2747              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2748              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2749              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2750              format_ip6_address, mp->ip6_src,
2751              clib_net_to_host_u32 (mp->domain_index));
2752     }
2753   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2754          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2755          mp->is_translation ? "map-t" : "");
2756 }
2757
2758 static void vl_api_map_rule_details_t_handler_json
2759   (vl_api_map_rule_details_t * mp)
2760 {
2761   struct in6_addr ip6;
2762   vat_json_node_t *node = NULL;
2763   vat_main_t *vam = &vat_main;
2764
2765   if (VAT_JSON_ARRAY != vam->json_tree.type)
2766     {
2767       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2768       vat_json_init_array (&vam->json_tree);
2769     }
2770
2771   node = vat_json_array_add (&vam->json_tree);
2772   vat_json_init_object (node);
2773
2774   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2775   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2776   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2777 }
2778
2779 static void
2780 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2784          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2785 }
2786
2787 static void
2788 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2789 {
2790   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2791           "router_addr %U host_mac %U",
2792           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2793           format_ip4_address, &mp->host_address,
2794           format_ip4_address, &mp->router_address,
2795           format_ethernet_address, mp->host_mac);
2796 }
2797
2798 static void vl_api_dhcp_compl_event_t_handler_json
2799   (vl_api_dhcp_compl_event_t * mp)
2800 {
2801   /* JSON output not supported */
2802 }
2803
2804 static void
2805 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2806                               u32 counter)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   static u64 default_counter = 0;
2810
2811   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2812                            NULL);
2813   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2814                            sw_if_index, default_counter);
2815   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2816 }
2817
2818 static void
2819 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2820                                 interface_counter_t counter)
2821 {
2822   vat_main_t *vam = &vat_main;
2823   static interface_counter_t default_counter = { 0, };
2824
2825   vec_validate_init_empty (vam->combined_interface_counters,
2826                            vnet_counter_type, NULL);
2827   vec_validate_init_empty (vam->combined_interface_counters
2828                            [vnet_counter_type], sw_if_index, default_counter);
2829   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2830 }
2831
2832 static void vl_api_vnet_interface_simple_counters_t_handler
2833   (vl_api_vnet_interface_simple_counters_t * mp)
2834 {
2835   /* not supported */
2836 }
2837
2838 static void vl_api_vnet_interface_combined_counters_t_handler
2839   (vl_api_vnet_interface_combined_counters_t * mp)
2840 {
2841   /* not supported */
2842 }
2843
2844 static void vl_api_vnet_interface_simple_counters_t_handler_json
2845   (vl_api_vnet_interface_simple_counters_t * mp)
2846 {
2847   u64 *v_packets;
2848   u64 packets;
2849   u32 count;
2850   u32 first_sw_if_index;
2851   int i;
2852
2853   count = ntohl (mp->count);
2854   first_sw_if_index = ntohl (mp->first_sw_if_index);
2855
2856   v_packets = (u64 *) & mp->data;
2857   for (i = 0; i < count; i++)
2858     {
2859       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2860       set_simple_interface_counter (mp->vnet_counter_type,
2861                                     first_sw_if_index + i, packets);
2862       v_packets++;
2863     }
2864 }
2865
2866 static void vl_api_vnet_interface_combined_counters_t_handler_json
2867   (vl_api_vnet_interface_combined_counters_t * mp)
2868 {
2869   interface_counter_t counter;
2870   vlib_counter_t *v;
2871   u32 first_sw_if_index;
2872   int i;
2873   u32 count;
2874
2875   count = ntohl (mp->count);
2876   first_sw_if_index = ntohl (mp->first_sw_if_index);
2877
2878   v = (vlib_counter_t *) & mp->data;
2879   for (i = 0; i < count; i++)
2880     {
2881       counter.packets =
2882         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2883       counter.bytes =
2884         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2885       set_combined_interface_counter (mp->vnet_counter_type,
2886                                       first_sw_if_index + i, counter);
2887       v++;
2888     }
2889 }
2890
2891 static u32
2892 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2893 {
2894   vat_main_t *vam = &vat_main;
2895   u32 i;
2896
2897   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2898     {
2899       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2900         {
2901           return i;
2902         }
2903     }
2904   return ~0;
2905 }
2906
2907 static u32
2908 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2909 {
2910   vat_main_t *vam = &vat_main;
2911   u32 i;
2912
2913   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2914     {
2915       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2916         {
2917           return i;
2918         }
2919     }
2920   return ~0;
2921 }
2922
2923 static void vl_api_vnet_ip4_fib_counters_t_handler
2924   (vl_api_vnet_ip4_fib_counters_t * mp)
2925 {
2926   /* not supported */
2927 }
2928
2929 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2930   (vl_api_vnet_ip4_fib_counters_t * mp)
2931 {
2932   vat_main_t *vam = &vat_main;
2933   vl_api_ip4_fib_counter_t *v;
2934   ip4_fib_counter_t *counter;
2935   struct in_addr ip4;
2936   u32 vrf_id;
2937   u32 vrf_index;
2938   u32 count;
2939   int i;
2940
2941   vrf_id = ntohl (mp->vrf_id);
2942   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2943   if (~0 == vrf_index)
2944     {
2945       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2946       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2947       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2948       vec_validate (vam->ip4_fib_counters, vrf_index);
2949       vam->ip4_fib_counters[vrf_index] = NULL;
2950     }
2951
2952   vec_free (vam->ip4_fib_counters[vrf_index]);
2953   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2954   count = ntohl (mp->count);
2955   for (i = 0; i < count; i++)
2956     {
2957       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2958       counter = &vam->ip4_fib_counters[vrf_index][i];
2959       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2960       counter->address = ip4;
2961       counter->address_length = v->address_length;
2962       counter->packets = clib_net_to_host_u64 (v->packets);
2963       counter->bytes = clib_net_to_host_u64 (v->bytes);
2964       v++;
2965     }
2966 }
2967
2968 static void vl_api_vnet_ip4_nbr_counters_t_handler
2969   (vl_api_vnet_ip4_nbr_counters_t * mp)
2970 {
2971   /* not supported */
2972 }
2973
2974 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2975   (vl_api_vnet_ip4_nbr_counters_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978   vl_api_ip4_nbr_counter_t *v;
2979   ip4_nbr_counter_t *counter;
2980   u32 sw_if_index;
2981   u32 count;
2982   int i;
2983
2984   sw_if_index = ntohl (mp->sw_if_index);
2985   count = ntohl (mp->count);
2986   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2987
2988   if (mp->begin)
2989     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2990
2991   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2992   for (i = 0; i < count; i++)
2993     {
2994       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2995       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2996       counter->address.s_addr = v->address;
2997       counter->packets = clib_net_to_host_u64 (v->packets);
2998       counter->bytes = clib_net_to_host_u64 (v->bytes);
2999       counter->linkt = v->link_type;
3000       v++;
3001     }
3002 }
3003
3004 static void vl_api_vnet_ip6_fib_counters_t_handler
3005   (vl_api_vnet_ip6_fib_counters_t * mp)
3006 {
3007   /* not supported */
3008 }
3009
3010 static void vl_api_vnet_ip6_fib_counters_t_handler_json
3011   (vl_api_vnet_ip6_fib_counters_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vl_api_ip6_fib_counter_t *v;
3015   ip6_fib_counter_t *counter;
3016   struct in6_addr ip6;
3017   u32 vrf_id;
3018   u32 vrf_index;
3019   u32 count;
3020   int i;
3021
3022   vrf_id = ntohl (mp->vrf_id);
3023   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
3024   if (~0 == vrf_index)
3025     {
3026       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
3027       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
3028       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
3029       vec_validate (vam->ip6_fib_counters, vrf_index);
3030       vam->ip6_fib_counters[vrf_index] = NULL;
3031     }
3032
3033   vec_free (vam->ip6_fib_counters[vrf_index]);
3034   v = (vl_api_ip6_fib_counter_t *) & mp->c;
3035   count = ntohl (mp->count);
3036   for (i = 0; i < count; i++)
3037     {
3038       vec_validate (vam->ip6_fib_counters[vrf_index], i);
3039       counter = &vam->ip6_fib_counters[vrf_index][i];
3040       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3041       counter->address = ip6;
3042       counter->address_length = v->address_length;
3043       counter->packets = clib_net_to_host_u64 (v->packets);
3044       counter->bytes = clib_net_to_host_u64 (v->bytes);
3045       v++;
3046     }
3047 }
3048
3049 static void vl_api_vnet_ip6_nbr_counters_t_handler
3050   (vl_api_vnet_ip6_nbr_counters_t * mp)
3051 {
3052   /* not supported */
3053 }
3054
3055 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
3056   (vl_api_vnet_ip6_nbr_counters_t * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vl_api_ip6_nbr_counter_t *v;
3060   ip6_nbr_counter_t *counter;
3061   struct in6_addr ip6;
3062   u32 sw_if_index;
3063   u32 count;
3064   int i;
3065
3066   sw_if_index = ntohl (mp->sw_if_index);
3067   count = ntohl (mp->count);
3068   vec_validate (vam->ip6_nbr_counters, sw_if_index);
3069
3070   if (mp->begin)
3071     vec_free (vam->ip6_nbr_counters[sw_if_index]);
3072
3073   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
3074   for (i = 0; i < count; i++)
3075     {
3076       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
3077       counter = &vam->ip6_nbr_counters[sw_if_index][i];
3078       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3079       counter->address = ip6;
3080       counter->packets = clib_net_to_host_u64 (v->packets);
3081       counter->bytes = clib_net_to_host_u64 (v->bytes);
3082       v++;
3083     }
3084 }
3085
3086 static void vl_api_get_first_msg_id_reply_t_handler
3087   (vl_api_get_first_msg_id_reply_t * mp)
3088 {
3089   vat_main_t *vam = &vat_main;
3090   i32 retval = ntohl (mp->retval);
3091
3092   if (vam->async_mode)
3093     {
3094       vam->async_errors += (retval < 0);
3095     }
3096   else
3097     {
3098       vam->retval = retval;
3099       vam->result_ready = 1;
3100     }
3101   if (retval >= 0)
3102     {
3103       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3104     }
3105 }
3106
3107 static void vl_api_get_first_msg_id_reply_t_handler_json
3108   (vl_api_get_first_msg_id_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   vat_json_node_t node;
3112
3113   vat_json_init_object (&node);
3114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3115   vat_json_object_add_uint (&node, "first_msg_id",
3116                             (uint) ntohs (mp->first_msg_id));
3117
3118   vat_json_print (vam->ofp, &node);
3119   vat_json_free (&node);
3120
3121   vam->retval = ntohl (mp->retval);
3122   vam->result_ready = 1;
3123 }
3124
3125 static void vl_api_get_node_graph_reply_t_handler
3126   (vl_api_get_node_graph_reply_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   api_main_t *am = &api_main;
3130   i32 retval = ntohl (mp->retval);
3131   u8 *pvt_copy, *reply;
3132   void *oldheap;
3133   vlib_node_t *node;
3134   int i;
3135
3136   if (vam->async_mode)
3137     {
3138       vam->async_errors += (retval < 0);
3139     }
3140   else
3141     {
3142       vam->retval = retval;
3143       vam->result_ready = 1;
3144     }
3145
3146   /* "Should never happen..." */
3147   if (retval != 0)
3148     return;
3149
3150   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3151   pvt_copy = vec_dup (reply);
3152
3153   /* Toss the shared-memory original... */
3154   pthread_mutex_lock (&am->vlib_rp->mutex);
3155   oldheap = svm_push_data_heap (am->vlib_rp);
3156
3157   vec_free (reply);
3158
3159   svm_pop_heap (oldheap);
3160   pthread_mutex_unlock (&am->vlib_rp->mutex);
3161
3162   if (vam->graph_nodes)
3163     {
3164       hash_free (vam->graph_node_index_by_name);
3165
3166       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3167         {
3168           node = vam->graph_nodes[i];
3169           vec_free (node->name);
3170           vec_free (node->next_nodes);
3171           vec_free (node);
3172         }
3173       vec_free (vam->graph_nodes);
3174     }
3175
3176   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3177   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3178   vec_free (pvt_copy);
3179
3180   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3181     {
3182       node = vam->graph_nodes[i];
3183       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3184     }
3185 }
3186
3187 static void vl_api_get_node_graph_reply_t_handler_json
3188   (vl_api_get_node_graph_reply_t * mp)
3189 {
3190   vat_main_t *vam = &vat_main;
3191   api_main_t *am = &api_main;
3192   void *oldheap;
3193   vat_json_node_t node;
3194   u8 *reply;
3195
3196   /* $$$$ make this real? */
3197   vat_json_init_object (&node);
3198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3199   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3200
3201   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3202
3203   /* Toss the shared-memory original... */
3204   pthread_mutex_lock (&am->vlib_rp->mutex);
3205   oldheap = svm_push_data_heap (am->vlib_rp);
3206
3207   vec_free (reply);
3208
3209   svm_pop_heap (oldheap);
3210   pthread_mutex_unlock (&am->vlib_rp->mutex);
3211
3212   vat_json_print (vam->ofp, &node);
3213   vat_json_free (&node);
3214
3215   vam->retval = ntohl (mp->retval);
3216   vam->result_ready = 1;
3217 }
3218
3219 static void
3220 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3221 {
3222   vat_main_t *vam = &vat_main;
3223   u8 *s = 0;
3224
3225   if (mp->local)
3226     {
3227       s = format (s, "%=16d%=16d%=16d",
3228                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3229     }
3230   else
3231     {
3232       s = format (s, "%=16U%=16d%=16d",
3233                   mp->is_ipv6 ? format_ip6_address :
3234                   format_ip4_address,
3235                   mp->ip_address, mp->priority, mp->weight);
3236     }
3237
3238   print (vam->ofp, "%v", s);
3239   vec_free (s);
3240 }
3241
3242 static void
3243 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t *node = NULL;
3247   struct in6_addr ip6;
3248   struct in_addr ip4;
3249
3250   if (VAT_JSON_ARRAY != vam->json_tree.type)
3251     {
3252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3253       vat_json_init_array (&vam->json_tree);
3254     }
3255   node = vat_json_array_add (&vam->json_tree);
3256   vat_json_init_object (node);
3257
3258   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3259   vat_json_object_add_uint (node, "priority", mp->priority);
3260   vat_json_object_add_uint (node, "weight", mp->weight);
3261
3262   if (mp->local)
3263     vat_json_object_add_uint (node, "sw_if_index",
3264                               clib_net_to_host_u32 (mp->sw_if_index));
3265   else
3266     {
3267       if (mp->is_ipv6)
3268         {
3269           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3270           vat_json_object_add_ip6 (node, "address", ip6);
3271         }
3272       else
3273         {
3274           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3275           vat_json_object_add_ip4 (node, "address", ip4);
3276         }
3277     }
3278 }
3279
3280 static void
3281 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3282                                           mp)
3283 {
3284   vat_main_t *vam = &vat_main;
3285   u8 *ls_name = 0;
3286
3287   ls_name = format (0, "%s", mp->ls_name);
3288
3289   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3290          ls_name);
3291   vec_free (ls_name);
3292 }
3293
3294 static void
3295   vl_api_one_locator_set_details_t_handler_json
3296   (vl_api_one_locator_set_details_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   vat_json_node_t *node = 0;
3300   u8 *ls_name = 0;
3301
3302   ls_name = format (0, "%s", mp->ls_name);
3303   vec_add1 (ls_name, 0);
3304
3305   if (VAT_JSON_ARRAY != vam->json_tree.type)
3306     {
3307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3308       vat_json_init_array (&vam->json_tree);
3309     }
3310   node = vat_json_array_add (&vam->json_tree);
3311
3312   vat_json_init_object (node);
3313   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3314   vat_json_object_add_uint (node, "ls_index",
3315                             clib_net_to_host_u32 (mp->ls_index));
3316   vec_free (ls_name);
3317 }
3318
3319 typedef struct
3320 {
3321   u32 spi;
3322   u8 si;
3323 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3324
3325 uword
3326 unformat_nsh_address (unformat_input_t * input, va_list * args)
3327 {
3328   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3329   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3330 }
3331
3332 u8 *
3333 format_nsh_address_vat (u8 * s, va_list * args)
3334 {
3335   nsh_t *a = va_arg (*args, nsh_t *);
3336   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3337 }
3338
3339 static u8 *
3340 format_lisp_flat_eid (u8 * s, va_list * args)
3341 {
3342   u32 type = va_arg (*args, u32);
3343   u8 *eid = va_arg (*args, u8 *);
3344   u32 eid_len = va_arg (*args, u32);
3345
3346   switch (type)
3347     {
3348     case 0:
3349       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3350     case 1:
3351       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3352     case 2:
3353       return format (s, "%U", format_ethernet_address, eid);
3354     case 3:
3355       return format (s, "%U", format_nsh_address_vat, eid);
3356     }
3357   return 0;
3358 }
3359
3360 static u8 *
3361 format_lisp_eid_vat (u8 * s, va_list * args)
3362 {
3363   u32 type = va_arg (*args, u32);
3364   u8 *eid = va_arg (*args, u8 *);
3365   u32 eid_len = va_arg (*args, u32);
3366   u8 *seid = va_arg (*args, u8 *);
3367   u32 seid_len = va_arg (*args, u32);
3368   u32 is_src_dst = va_arg (*args, u32);
3369
3370   if (is_src_dst)
3371     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3372
3373   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3374
3375   return s;
3376 }
3377
3378 static void
3379 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382   u8 *s = 0, *eid = 0;
3383
3384   if (~0 == mp->locator_set_index)
3385     s = format (0, "action: %d", mp->action);
3386   else
3387     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3388
3389   eid = format (0, "%U", format_lisp_eid_vat,
3390                 mp->eid_type,
3391                 mp->eid,
3392                 mp->eid_prefix_len,
3393                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3394   vec_add1 (eid, 0);
3395
3396   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3397          clib_net_to_host_u32 (mp->vni),
3398          eid,
3399          mp->is_local ? "local" : "remote",
3400          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3401          clib_net_to_host_u16 (mp->key_id), mp->key);
3402
3403   vec_free (s);
3404   vec_free (eid);
3405 }
3406
3407 static void
3408 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3409                                              * mp)
3410 {
3411   vat_main_t *vam = &vat_main;
3412   vat_json_node_t *node = 0;
3413   u8 *eid = 0;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   if (~0 == mp->locator_set_index)
3424     vat_json_object_add_uint (node, "action", mp->action);
3425   else
3426     vat_json_object_add_uint (node, "locator_set_index",
3427                               clib_net_to_host_u32 (mp->locator_set_index));
3428
3429   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3430   if (mp->eid_type == 3)
3431     {
3432       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3433       vat_json_init_object (nsh_json);
3434       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3435       vat_json_object_add_uint (nsh_json, "spi",
3436                                 clib_net_to_host_u32 (nsh->spi));
3437       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3438     }
3439   else
3440     {
3441       eid = format (0, "%U", format_lisp_eid_vat,
3442                     mp->eid_type,
3443                     mp->eid,
3444                     mp->eid_prefix_len,
3445                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3446       vec_add1 (eid, 0);
3447       vat_json_object_add_string_copy (node, "eid", eid);
3448       vec_free (eid);
3449     }
3450   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3451   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3452   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3453
3454   if (mp->key_id)
3455     {
3456       vat_json_object_add_uint (node, "key_id",
3457                                 clib_net_to_host_u16 (mp->key_id));
3458       vat_json_object_add_string_copy (node, "key", mp->key);
3459     }
3460 }
3461
3462 static void
3463 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u8 *seid = 0, *deid = 0;
3467   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3468
3469   deid = format (0, "%U", format_lisp_eid_vat,
3470                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3471
3472   seid = format (0, "%U", format_lisp_eid_vat,
3473                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3474
3475   vec_add1 (deid, 0);
3476   vec_add1 (seid, 0);
3477
3478   if (mp->is_ip4)
3479     format_ip_address_fcn = format_ip4_address;
3480   else
3481     format_ip_address_fcn = format_ip6_address;
3482
3483
3484   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3485          clib_net_to_host_u32 (mp->vni),
3486          seid, deid,
3487          format_ip_address_fcn, mp->lloc,
3488          format_ip_address_fcn, mp->rloc,
3489          clib_net_to_host_u32 (mp->pkt_count),
3490          clib_net_to_host_u32 (mp->bytes));
3491
3492   vec_free (deid);
3493   vec_free (seid);
3494 }
3495
3496 static void
3497 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3498 {
3499   struct in6_addr ip6;
3500   struct in_addr ip4;
3501   vat_main_t *vam = &vat_main;
3502   vat_json_node_t *node = 0;
3503   u8 *deid = 0, *seid = 0;
3504
3505   if (VAT_JSON_ARRAY != vam->json_tree.type)
3506     {
3507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3508       vat_json_init_array (&vam->json_tree);
3509     }
3510   node = vat_json_array_add (&vam->json_tree);
3511
3512   vat_json_init_object (node);
3513   deid = format (0, "%U", format_lisp_eid_vat,
3514                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3515
3516   seid = format (0, "%U", format_lisp_eid_vat,
3517                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3518
3519   vec_add1 (deid, 0);
3520   vec_add1 (seid, 0);
3521
3522   vat_json_object_add_string_copy (node, "seid", seid);
3523   vat_json_object_add_string_copy (node, "deid", deid);
3524   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3525
3526   if (mp->is_ip4)
3527     {
3528       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3529       vat_json_object_add_ip4 (node, "lloc", ip4);
3530       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3531       vat_json_object_add_ip4 (node, "rloc", ip4);
3532     }
3533   else
3534     {
3535       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3536       vat_json_object_add_ip6 (node, "lloc", ip6);
3537       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3538       vat_json_object_add_ip6 (node, "rloc", ip6);
3539     }
3540   vat_json_object_add_uint (node, "pkt_count",
3541                             clib_net_to_host_u32 (mp->pkt_count));
3542   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3543
3544   vec_free (deid);
3545   vec_free (seid);
3546 }
3547
3548 static void
3549   vl_api_one_eid_table_map_details_t_handler
3550   (vl_api_one_eid_table_map_details_t * mp)
3551 {
3552   vat_main_t *vam = &vat_main;
3553
3554   u8 *line = format (0, "%=10d%=10d",
3555                      clib_net_to_host_u32 (mp->vni),
3556                      clib_net_to_host_u32 (mp->dp_table));
3557   print (vam->ofp, "%v", line);
3558   vec_free (line);
3559 }
3560
3561 static void
3562   vl_api_one_eid_table_map_details_t_handler_json
3563   (vl_api_one_eid_table_map_details_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   vat_json_node_t *node = NULL;
3567
3568   if (VAT_JSON_ARRAY != vam->json_tree.type)
3569     {
3570       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3571       vat_json_init_array (&vam->json_tree);
3572     }
3573   node = vat_json_array_add (&vam->json_tree);
3574   vat_json_init_object (node);
3575   vat_json_object_add_uint (node, "dp_table",
3576                             clib_net_to_host_u32 (mp->dp_table));
3577   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3578 }
3579
3580 static void
3581   vl_api_one_eid_table_vni_details_t_handler
3582   (vl_api_one_eid_table_vni_details_t * mp)
3583 {
3584   vat_main_t *vam = &vat_main;
3585
3586   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3587   print (vam->ofp, "%v", line);
3588   vec_free (line);
3589 }
3590
3591 static void
3592   vl_api_one_eid_table_vni_details_t_handler_json
3593   (vl_api_one_eid_table_vni_details_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   vat_json_node_t *node = NULL;
3597
3598   if (VAT_JSON_ARRAY != vam->json_tree.type)
3599     {
3600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3601       vat_json_init_array (&vam->json_tree);
3602     }
3603   node = vat_json_array_add (&vam->json_tree);
3604   vat_json_init_object (node);
3605   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3606 }
3607
3608 static void
3609   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3610   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3616   print (vam->ofp, "fallback threshold value: %d", mp->value);
3617
3618   vam->retval = retval;
3619   vam->result_ready = 1;
3620 }
3621
3622 static void
3623   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3624   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627   vat_json_node_t _node, *node = &_node;
3628   int retval = clib_net_to_host_u32 (mp->retval);
3629
3630   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3631   vat_json_init_object (node);
3632   vat_json_object_add_uint (node, "value", mp->value);
3633
3634   vat_json_print (vam->ofp, node);
3635   vat_json_free (node);
3636
3637   vam->retval = retval;
3638   vam->result_ready = 1;
3639 }
3640
3641 static void
3642   vl_api_show_one_map_register_state_reply_t_handler
3643   (vl_api_show_one_map_register_state_reply_t * mp)
3644 {
3645   vat_main_t *vam = &vat_main;
3646   int retval = clib_net_to_host_u32 (mp->retval);
3647
3648   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3649
3650   vam->retval = retval;
3651   vam->result_ready = 1;
3652 }
3653
3654 static void
3655   vl_api_show_one_map_register_state_reply_t_handler_json
3656   (vl_api_show_one_map_register_state_reply_t * mp)
3657 {
3658   vat_main_t *vam = &vat_main;
3659   vat_json_node_t _node, *node = &_node;
3660   int retval = clib_net_to_host_u32 (mp->retval);
3661
3662   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3663
3664   vat_json_init_object (node);
3665   vat_json_object_add_string_copy (node, "state", s);
3666
3667   vat_json_print (vam->ofp, node);
3668   vat_json_free (node);
3669
3670   vam->retval = retval;
3671   vam->result_ready = 1;
3672   vec_free (s);
3673 }
3674
3675 static void
3676   vl_api_show_one_rloc_probe_state_reply_t_handler
3677   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   int retval = clib_net_to_host_u32 (mp->retval);
3681
3682   if (retval)
3683     goto end;
3684
3685   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3686 end:
3687   vam->retval = retval;
3688   vam->result_ready = 1;
3689 }
3690
3691 static void
3692   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3693   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3694 {
3695   vat_main_t *vam = &vat_main;
3696   vat_json_node_t _node, *node = &_node;
3697   int retval = clib_net_to_host_u32 (mp->retval);
3698
3699   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3700   vat_json_init_object (node);
3701   vat_json_object_add_string_copy (node, "state", s);
3702
3703   vat_json_print (vam->ofp, node);
3704   vat_json_free (node);
3705
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708   vec_free (s);
3709 }
3710
3711 static void
3712   vl_api_show_one_stats_enable_disable_reply_t_handler
3713   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717
3718   if (retval)
3719     goto end;
3720
3721   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3722 end:
3723   vam->retval = retval;
3724   vam->result_ready = 1;
3725 }
3726
3727 static void
3728   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3729   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3730 {
3731   vat_main_t *vam = &vat_main;
3732   vat_json_node_t _node, *node = &_node;
3733   int retval = clib_net_to_host_u32 (mp->retval);
3734
3735   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3736   vat_json_init_object (node);
3737   vat_json_object_add_string_copy (node, "state", s);
3738
3739   vat_json_print (vam->ofp, node);
3740   vat_json_free (node);
3741
3742   vam->retval = retval;
3743   vam->result_ready = 1;
3744   vec_free (s);
3745 }
3746
3747 static void
3748 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3749 {
3750   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3751   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3752   e->vni = clib_net_to_host_u32 (e->vni);
3753 }
3754
3755 static void
3756   gpe_fwd_entries_get_reply_t_net_to_host
3757   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3758 {
3759   u32 i;
3760
3761   mp->count = clib_net_to_host_u32 (mp->count);
3762   for (i = 0; i < mp->count; i++)
3763     {
3764       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3765     }
3766 }
3767
3768 static u8 *
3769 format_gpe_encap_mode (u8 * s, va_list * args)
3770 {
3771   u32 mode = va_arg (*args, u32);
3772
3773   switch (mode)
3774     {
3775     case 0:
3776       return format (s, "lisp");
3777     case 1:
3778       return format (s, "vxlan");
3779     }
3780   return 0;
3781 }
3782
3783 static void
3784   vl_api_gpe_get_encap_mode_reply_t_handler
3785   (vl_api_gpe_get_encap_mode_reply_t * mp)
3786 {
3787   vat_main_t *vam = &vat_main;
3788
3789   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3790   vam->retval = ntohl (mp->retval);
3791   vam->result_ready = 1;
3792 }
3793
3794 static void
3795   vl_api_gpe_get_encap_mode_reply_t_handler_json
3796   (vl_api_gpe_get_encap_mode_reply_t * mp)
3797 {
3798   vat_main_t *vam = &vat_main;
3799   vat_json_node_t node;
3800
3801   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3802   vec_add1 (encap_mode, 0);
3803
3804   vat_json_init_object (&node);
3805   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3806
3807   vec_free (encap_mode);
3808   vat_json_print (vam->ofp, &node);
3809   vat_json_free (&node);
3810
3811   vam->retval = ntohl (mp->retval);
3812   vam->result_ready = 1;
3813 }
3814
3815 static void
3816   vl_api_gpe_fwd_entry_path_details_t_handler
3817   (vl_api_gpe_fwd_entry_path_details_t * mp)
3818 {
3819   vat_main_t *vam = &vat_main;
3820   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3821
3822   if (mp->lcl_loc.is_ip4)
3823     format_ip_address_fcn = format_ip4_address;
3824   else
3825     format_ip_address_fcn = format_ip6_address;
3826
3827   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3828          format_ip_address_fcn, &mp->lcl_loc,
3829          format_ip_address_fcn, &mp->rmt_loc);
3830 }
3831
3832 static void
3833 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3834 {
3835   struct in6_addr ip6;
3836   struct in_addr ip4;
3837
3838   if (loc->is_ip4)
3839     {
3840       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3841       vat_json_object_add_ip4 (n, "address", ip4);
3842     }
3843   else
3844     {
3845       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3846       vat_json_object_add_ip6 (n, "address", ip6);
3847     }
3848   vat_json_object_add_uint (n, "weight", loc->weight);
3849 }
3850
3851 static void
3852   vl_api_gpe_fwd_entry_path_details_t_handler_json
3853   (vl_api_gpe_fwd_entry_path_details_t * mp)
3854 {
3855   vat_main_t *vam = &vat_main;
3856   vat_json_node_t *node = NULL;
3857   vat_json_node_t *loc_node;
3858
3859   if (VAT_JSON_ARRAY != vam->json_tree.type)
3860     {
3861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3862       vat_json_init_array (&vam->json_tree);
3863     }
3864   node = vat_json_array_add (&vam->json_tree);
3865   vat_json_init_object (node);
3866
3867   loc_node = vat_json_object_add (node, "local_locator");
3868   vat_json_init_object (loc_node);
3869   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3870
3871   loc_node = vat_json_object_add (node, "remote_locator");
3872   vat_json_init_object (loc_node);
3873   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entries_get_reply_t_handler
3878   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   u32 i;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_gpe_fwd_entry_t *e;
3884
3885   if (retval)
3886     goto end;
3887
3888   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3889
3890   for (i = 0; i < mp->count; i++)
3891     {
3892       e = &mp->entries[i];
3893       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3894              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3895              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3896     }
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3905   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3906 {
3907   u8 *s = 0;
3908   vat_main_t *vam = &vat_main;
3909   vat_json_node_t *e = 0, root;
3910   u32 i;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912   vl_api_gpe_fwd_entry_t *fwd;
3913
3914   if (retval)
3915     goto end;
3916
3917   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3918   vat_json_init_array (&root);
3919
3920   for (i = 0; i < mp->count; i++)
3921     {
3922       e = vat_json_array_add (&root);
3923       fwd = &mp->entries[i];
3924
3925       vat_json_init_object (e);
3926       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3927       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3928       vat_json_object_add_int (e, "vni", fwd->vni);
3929       vat_json_object_add_int (e, "action", fwd->action);
3930
3931       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3932                   fwd->leid_prefix_len);
3933       vec_add1 (s, 0);
3934       vat_json_object_add_string_copy (e, "leid", s);
3935       vec_free (s);
3936
3937       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3938                   fwd->reid_prefix_len);
3939       vec_add1 (s, 0);
3940       vat_json_object_add_string_copy (e, "reid", s);
3941       vec_free (s);
3942     }
3943
3944   vat_json_print (vam->ofp, &root);
3945   vat_json_free (&root);
3946
3947 end:
3948   vam->retval = retval;
3949   vam->result_ready = 1;
3950 }
3951
3952 static void
3953   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3954   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3955 {
3956   vat_main_t *vam = &vat_main;
3957   u32 i, n;
3958   int retval = clib_net_to_host_u32 (mp->retval);
3959   vl_api_gpe_native_fwd_rpath_t *r;
3960
3961   if (retval)
3962     goto end;
3963
3964   n = clib_net_to_host_u32 (mp->count);
3965
3966   for (i = 0; i < n; i++)
3967     {
3968       r = &mp->entries[i];
3969       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3970              clib_net_to_host_u32 (r->fib_index),
3971              clib_net_to_host_u32 (r->nh_sw_if_index),
3972              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3973     }
3974
3975 end:
3976   vam->retval = retval;
3977   vam->result_ready = 1;
3978 }
3979
3980 static void
3981   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3982   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   vat_json_node_t root, *e;
3986   u32 i, n;
3987   int retval = clib_net_to_host_u32 (mp->retval);
3988   vl_api_gpe_native_fwd_rpath_t *r;
3989   u8 *s;
3990
3991   if (retval)
3992     goto end;
3993
3994   n = clib_net_to_host_u32 (mp->count);
3995   vat_json_init_array (&root);
3996
3997   for (i = 0; i < n; i++)
3998     {
3999       e = vat_json_array_add (&root);
4000       vat_json_init_object (e);
4001       r = &mp->entries[i];
4002       s =
4003         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
4004                 r->nh_addr);
4005       vec_add1 (s, 0);
4006       vat_json_object_add_string_copy (e, "ip4", s);
4007       vec_free (s);
4008
4009       vat_json_object_add_uint (e, "fib_index",
4010                                 clib_net_to_host_u32 (r->fib_index));
4011       vat_json_object_add_uint (e, "nh_sw_if_index",
4012                                 clib_net_to_host_u32 (r->nh_sw_if_index));
4013     }
4014
4015   vat_json_print (vam->ofp, &root);
4016   vat_json_free (&root);
4017
4018 end:
4019   vam->retval = retval;
4020   vam->result_ready = 1;
4021 }
4022
4023 static void
4024   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
4025   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028   u32 i, n;
4029   int retval = clib_net_to_host_u32 (mp->retval);
4030
4031   if (retval)
4032     goto end;
4033
4034   n = clib_net_to_host_u32 (mp->count);
4035
4036   for (i = 0; i < n; i++)
4037     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
4038
4039 end:
4040   vam->retval = retval;
4041   vam->result_ready = 1;
4042 }
4043
4044 static void
4045   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
4046   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
4047 {
4048   vat_main_t *vam = &vat_main;
4049   vat_json_node_t root;
4050   u32 i, n;
4051   int retval = clib_net_to_host_u32 (mp->retval);
4052
4053   if (retval)
4054     goto end;
4055
4056   n = clib_net_to_host_u32 (mp->count);
4057   vat_json_init_array (&root);
4058
4059   for (i = 0; i < n; i++)
4060     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
4061
4062   vat_json_print (vam->ofp, &root);
4063   vat_json_free (&root);
4064
4065 end:
4066   vam->retval = retval;
4067   vam->result_ready = 1;
4068 }
4069
4070 static void
4071   vl_api_one_ndp_entries_get_reply_t_handler
4072   (vl_api_one_ndp_entries_get_reply_t * mp)
4073 {
4074   vat_main_t *vam = &vat_main;
4075   u32 i, n;
4076   int retval = clib_net_to_host_u32 (mp->retval);
4077
4078   if (retval)
4079     goto end;
4080
4081   n = clib_net_to_host_u32 (mp->count);
4082
4083   for (i = 0; i < n; i++)
4084     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4085            format_ethernet_address, mp->entries[i].mac);
4086
4087 end:
4088   vam->retval = retval;
4089   vam->result_ready = 1;
4090 }
4091
4092 static void
4093   vl_api_one_ndp_entries_get_reply_t_handler_json
4094   (vl_api_one_ndp_entries_get_reply_t * mp)
4095 {
4096   u8 *s = 0;
4097   vat_main_t *vam = &vat_main;
4098   vat_json_node_t *e = 0, root;
4099   u32 i, n;
4100   int retval = clib_net_to_host_u32 (mp->retval);
4101   vl_api_one_ndp_entry_t *arp_entry;
4102
4103   if (retval)
4104     goto end;
4105
4106   n = clib_net_to_host_u32 (mp->count);
4107   vat_json_init_array (&root);
4108
4109   for (i = 0; i < n; i++)
4110     {
4111       e = vat_json_array_add (&root);
4112       arp_entry = &mp->entries[i];
4113
4114       vat_json_init_object (e);
4115       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4116       vec_add1 (s, 0);
4117
4118       vat_json_object_add_string_copy (e, "mac", s);
4119       vec_free (s);
4120
4121       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4122       vec_add1 (s, 0);
4123       vat_json_object_add_string_copy (e, "ip6", s);
4124       vec_free (s);
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_l2_arp_entries_get_reply_t_handler
4137   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142
4143   if (retval)
4144     goto end;
4145
4146   n = clib_net_to_host_u32 (mp->count);
4147
4148   for (i = 0; i < n; i++)
4149     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4150            format_ethernet_address, mp->entries[i].mac);
4151
4152 end:
4153   vam->retval = retval;
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4159   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4160 {
4161   u8 *s = 0;
4162   vat_main_t *vam = &vat_main;
4163   vat_json_node_t *e = 0, root;
4164   u32 i, n;
4165   int retval = clib_net_to_host_u32 (mp->retval);
4166   vl_api_one_l2_arp_entry_t *arp_entry;
4167
4168   if (retval)
4169     goto end;
4170
4171   n = clib_net_to_host_u32 (mp->count);
4172   vat_json_init_array (&root);
4173
4174   for (i = 0; i < n; i++)
4175     {
4176       e = vat_json_array_add (&root);
4177       arp_entry = &mp->entries[i];
4178
4179       vat_json_init_object (e);
4180       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4181       vec_add1 (s, 0);
4182
4183       vat_json_object_add_string_copy (e, "mac", s);
4184       vec_free (s);
4185
4186       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "ip4", s);
4189       vec_free (s);
4190     }
4191
4192   vat_json_print (vam->ofp, &root);
4193   vat_json_free (&root);
4194
4195 end:
4196   vam->retval = retval;
4197   vam->result_ready = 1;
4198 }
4199
4200 static void
4201 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4202 {
4203   vat_main_t *vam = &vat_main;
4204   u32 i, n;
4205   int retval = clib_net_to_host_u32 (mp->retval);
4206
4207   if (retval)
4208     goto end;
4209
4210   n = clib_net_to_host_u32 (mp->count);
4211
4212   for (i = 0; i < n; i++)
4213     {
4214       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4215     }
4216
4217 end:
4218   vam->retval = retval;
4219   vam->result_ready = 1;
4220 }
4221
4222 static void
4223   vl_api_one_ndp_bd_get_reply_t_handler_json
4224   (vl_api_one_ndp_bd_get_reply_t * mp)
4225 {
4226   vat_main_t *vam = &vat_main;
4227   vat_json_node_t root;
4228   u32 i, n;
4229   int retval = clib_net_to_host_u32 (mp->retval);
4230
4231   if (retval)
4232     goto end;
4233
4234   n = clib_net_to_host_u32 (mp->count);
4235   vat_json_init_array (&root);
4236
4237   for (i = 0; i < n; i++)
4238     {
4239       vat_json_array_add_uint (&root,
4240                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4241     }
4242
4243   vat_json_print (vam->ofp, &root);
4244   vat_json_free (&root);
4245
4246 end:
4247   vam->retval = retval;
4248   vam->result_ready = 1;
4249 }
4250
4251 static void
4252   vl_api_one_l2_arp_bd_get_reply_t_handler
4253   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4254 {
4255   vat_main_t *vam = &vat_main;
4256   u32 i, n;
4257   int retval = clib_net_to_host_u32 (mp->retval);
4258
4259   if (retval)
4260     goto end;
4261
4262   n = clib_net_to_host_u32 (mp->count);
4263
4264   for (i = 0; i < n; i++)
4265     {
4266       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4267     }
4268
4269 end:
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4276   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t root;
4280   u32 i, n;
4281   int retval = clib_net_to_host_u32 (mp->retval);
4282
4283   if (retval)
4284     goto end;
4285
4286   n = clib_net_to_host_u32 (mp->count);
4287   vat_json_init_array (&root);
4288
4289   for (i = 0; i < n; i++)
4290     {
4291       vat_json_array_add_uint (&root,
4292                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4293     }
4294
4295   vat_json_print (vam->ofp, &root);
4296   vat_json_free (&root);
4297
4298 end:
4299   vam->retval = retval;
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_one_adjacencies_get_reply_t_handler
4305   (vl_api_one_adjacencies_get_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   u32 i, n;
4309   int retval = clib_net_to_host_u32 (mp->retval);
4310   vl_api_one_adjacency_t *a;
4311
4312   if (retval)
4313     goto end;
4314
4315   n = clib_net_to_host_u32 (mp->count);
4316
4317   for (i = 0; i < n; i++)
4318     {
4319       a = &mp->adjacencies[i];
4320       print (vam->ofp, "%U %40U",
4321              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4322              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4323     }
4324
4325 end:
4326   vam->retval = retval;
4327   vam->result_ready = 1;
4328 }
4329
4330 static void
4331   vl_api_one_adjacencies_get_reply_t_handler_json
4332   (vl_api_one_adjacencies_get_reply_t * mp)
4333 {
4334   u8 *s = 0;
4335   vat_main_t *vam = &vat_main;
4336   vat_json_node_t *e = 0, root;
4337   u32 i, n;
4338   int retval = clib_net_to_host_u32 (mp->retval);
4339   vl_api_one_adjacency_t *a;
4340
4341   if (retval)
4342     goto end;
4343
4344   n = clib_net_to_host_u32 (mp->count);
4345   vat_json_init_array (&root);
4346
4347   for (i = 0; i < n; i++)
4348     {
4349       e = vat_json_array_add (&root);
4350       a = &mp->adjacencies[i];
4351
4352       vat_json_init_object (e);
4353       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4354                   a->leid_prefix_len);
4355       vec_add1 (s, 0);
4356       vat_json_object_add_string_copy (e, "leid", s);
4357       vec_free (s);
4358
4359       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4360                   a->reid_prefix_len);
4361       vec_add1 (s, 0);
4362       vat_json_object_add_string_copy (e, "reid", s);
4363       vec_free (s);
4364     }
4365
4366   vat_json_print (vam->ofp, &root);
4367   vat_json_free (&root);
4368
4369 end:
4370   vam->retval = retval;
4371   vam->result_ready = 1;
4372 }
4373
4374 static void
4375 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378
4379   print (vam->ofp, "%=20U",
4380          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4381          mp->ip_address);
4382 }
4383
4384 static void
4385   vl_api_one_map_server_details_t_handler_json
4386   (vl_api_one_map_server_details_t * mp)
4387 {
4388   vat_main_t *vam = &vat_main;
4389   vat_json_node_t *node = NULL;
4390   struct in6_addr ip6;
4391   struct in_addr ip4;
4392
4393   if (VAT_JSON_ARRAY != vam->json_tree.type)
4394     {
4395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4396       vat_json_init_array (&vam->json_tree);
4397     }
4398   node = vat_json_array_add (&vam->json_tree);
4399
4400   vat_json_init_object (node);
4401   if (mp->is_ipv6)
4402     {
4403       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4404       vat_json_object_add_ip6 (node, "map-server", ip6);
4405     }
4406   else
4407     {
4408       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4409       vat_json_object_add_ip4 (node, "map-server", ip4);
4410     }
4411 }
4412
4413 static void
4414 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4415                                            * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418
4419   print (vam->ofp, "%=20U",
4420          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4421          mp->ip_address);
4422 }
4423
4424 static void
4425   vl_api_one_map_resolver_details_t_handler_json
4426   (vl_api_one_map_resolver_details_t * mp)
4427 {
4428   vat_main_t *vam = &vat_main;
4429   vat_json_node_t *node = NULL;
4430   struct in6_addr ip6;
4431   struct in_addr ip4;
4432
4433   if (VAT_JSON_ARRAY != vam->json_tree.type)
4434     {
4435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4436       vat_json_init_array (&vam->json_tree);
4437     }
4438   node = vat_json_array_add (&vam->json_tree);
4439
4440   vat_json_init_object (node);
4441   if (mp->is_ipv6)
4442     {
4443       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4444       vat_json_object_add_ip6 (node, "map resolver", ip6);
4445     }
4446   else
4447     {
4448       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4449       vat_json_object_add_ip4 (node, "map resolver", ip4);
4450     }
4451 }
4452
4453 static void
4454 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4455 {
4456   vat_main_t *vam = &vat_main;
4457   i32 retval = ntohl (mp->retval);
4458
4459   if (0 <= retval)
4460     {
4461       print (vam->ofp, "feature: %s\ngpe: %s",
4462              mp->feature_status ? "enabled" : "disabled",
4463              mp->gpe_status ? "enabled" : "disabled");
4464     }
4465
4466   vam->retval = retval;
4467   vam->result_ready = 1;
4468 }
4469
4470 static void
4471   vl_api_show_one_status_reply_t_handler_json
4472   (vl_api_show_one_status_reply_t * mp)
4473 {
4474   vat_main_t *vam = &vat_main;
4475   vat_json_node_t node;
4476   u8 *gpe_status = NULL;
4477   u8 *feature_status = NULL;
4478
4479   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4480   feature_status = format (0, "%s",
4481                            mp->feature_status ? "enabled" : "disabled");
4482   vec_add1 (gpe_status, 0);
4483   vec_add1 (feature_status, 0);
4484
4485   vat_json_init_object (&node);
4486   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4487   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4488
4489   vec_free (gpe_status);
4490   vec_free (feature_status);
4491
4492   vat_json_print (vam->ofp, &node);
4493   vat_json_free (&node);
4494
4495   vam->retval = ntohl (mp->retval);
4496   vam->result_ready = 1;
4497 }
4498
4499 static void
4500   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4501   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   i32 retval = ntohl (mp->retval);
4505
4506   if (retval >= 0)
4507     {
4508       print (vam->ofp, "%=20s", mp->locator_set_name);
4509     }
4510
4511   vam->retval = retval;
4512   vam->result_ready = 1;
4513 }
4514
4515 static void
4516   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4517   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   vat_json_node_t *node = NULL;
4521
4522   if (VAT_JSON_ARRAY != vam->json_tree.type)
4523     {
4524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4525       vat_json_init_array (&vam->json_tree);
4526     }
4527   node = vat_json_array_add (&vam->json_tree);
4528
4529   vat_json_init_object (node);
4530   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4531
4532   vat_json_print (vam->ofp, node);
4533   vat_json_free (node);
4534
4535   vam->retval = ntohl (mp->retval);
4536   vam->result_ready = 1;
4537 }
4538
4539 static u8 *
4540 format_lisp_map_request_mode (u8 * s, va_list * args)
4541 {
4542   u32 mode = va_arg (*args, u32);
4543
4544   switch (mode)
4545     {
4546     case 0:
4547       return format (0, "dst-only");
4548     case 1:
4549       return format (0, "src-dst");
4550     }
4551   return 0;
4552 }
4553
4554 static void
4555   vl_api_show_one_map_request_mode_reply_t_handler
4556   (vl_api_show_one_map_request_mode_reply_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   i32 retval = ntohl (mp->retval);
4560
4561   if (0 <= retval)
4562     {
4563       u32 mode = mp->mode;
4564       print (vam->ofp, "map_request_mode: %U",
4565              format_lisp_map_request_mode, mode);
4566     }
4567
4568   vam->retval = retval;
4569   vam->result_ready = 1;
4570 }
4571
4572 static void
4573   vl_api_show_one_map_request_mode_reply_t_handler_json
4574   (vl_api_show_one_map_request_mode_reply_t * mp)
4575 {
4576   vat_main_t *vam = &vat_main;
4577   vat_json_node_t node;
4578   u8 *s = 0;
4579   u32 mode;
4580
4581   mode = mp->mode;
4582   s = format (0, "%U", format_lisp_map_request_mode, mode);
4583   vec_add1 (s, 0);
4584
4585   vat_json_init_object (&node);
4586   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4587   vat_json_print (vam->ofp, &node);
4588   vat_json_free (&node);
4589
4590   vec_free (s);
4591   vam->retval = ntohl (mp->retval);
4592   vam->result_ready = 1;
4593 }
4594
4595 static void
4596   vl_api_one_show_xtr_mode_reply_t_handler
4597   (vl_api_one_show_xtr_mode_reply_t * mp)
4598 {
4599   vat_main_t *vam = &vat_main;
4600   i32 retval = ntohl (mp->retval);
4601
4602   if (0 <= retval)
4603     {
4604       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4605     }
4606
4607   vam->retval = retval;
4608   vam->result_ready = 1;
4609 }
4610
4611 static void
4612   vl_api_one_show_xtr_mode_reply_t_handler_json
4613   (vl_api_one_show_xtr_mode_reply_t * mp)
4614 {
4615   vat_main_t *vam = &vat_main;
4616   vat_json_node_t node;
4617   u8 *status = 0;
4618
4619   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4620   vec_add1 (status, 0);
4621
4622   vat_json_init_object (&node);
4623   vat_json_object_add_string_copy (&node, "status", status);
4624
4625   vec_free (status);
4626
4627   vat_json_print (vam->ofp, &node);
4628   vat_json_free (&node);
4629
4630   vam->retval = ntohl (mp->retval);
4631   vam->result_ready = 1;
4632 }
4633
4634 static void
4635   vl_api_one_show_pitr_mode_reply_t_handler
4636   (vl_api_one_show_pitr_mode_reply_t * mp)
4637 {
4638   vat_main_t *vam = &vat_main;
4639   i32 retval = ntohl (mp->retval);
4640
4641   if (0 <= retval)
4642     {
4643       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4644     }
4645
4646   vam->retval = retval;
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_one_show_pitr_mode_reply_t_handler_json
4652   (vl_api_one_show_pitr_mode_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   vat_json_node_t node;
4656   u8 *status = 0;
4657
4658   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4659   vec_add1 (status, 0);
4660
4661   vat_json_init_object (&node);
4662   vat_json_object_add_string_copy (&node, "status", status);
4663
4664   vec_free (status);
4665
4666   vat_json_print (vam->ofp, &node);
4667   vat_json_free (&node);
4668
4669   vam->retval = ntohl (mp->retval);
4670   vam->result_ready = 1;
4671 }
4672
4673 static void
4674   vl_api_one_show_petr_mode_reply_t_handler
4675   (vl_api_one_show_petr_mode_reply_t * mp)
4676 {
4677   vat_main_t *vam = &vat_main;
4678   i32 retval = ntohl (mp->retval);
4679
4680   if (0 <= retval)
4681     {
4682       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4683     }
4684
4685   vam->retval = retval;
4686   vam->result_ready = 1;
4687 }
4688
4689 static void
4690   vl_api_one_show_petr_mode_reply_t_handler_json
4691   (vl_api_one_show_petr_mode_reply_t * mp)
4692 {
4693   vat_main_t *vam = &vat_main;
4694   vat_json_node_t node;
4695   u8 *status = 0;
4696
4697   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4698   vec_add1 (status, 0);
4699
4700   vat_json_init_object (&node);
4701   vat_json_object_add_string_copy (&node, "status", status);
4702
4703   vec_free (status);
4704
4705   vat_json_print (vam->ofp, &node);
4706   vat_json_free (&node);
4707
4708   vam->retval = ntohl (mp->retval);
4709   vam->result_ready = 1;
4710 }
4711
4712 static void
4713   vl_api_show_one_use_petr_reply_t_handler
4714   (vl_api_show_one_use_petr_reply_t * mp)
4715 {
4716   vat_main_t *vam = &vat_main;
4717   i32 retval = ntohl (mp->retval);
4718
4719   if (0 <= retval)
4720     {
4721       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4722       if (mp->status)
4723         {
4724           print (vam->ofp, "Proxy-ETR address; %U",
4725                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4726                  mp->address);
4727         }
4728     }
4729
4730   vam->retval = retval;
4731   vam->result_ready = 1;
4732 }
4733
4734 static void
4735   vl_api_show_one_use_petr_reply_t_handler_json
4736   (vl_api_show_one_use_petr_reply_t * mp)
4737 {
4738   vat_main_t *vam = &vat_main;
4739   vat_json_node_t node;
4740   u8 *status = 0;
4741   struct in_addr ip4;
4742   struct in6_addr ip6;
4743
4744   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4745   vec_add1 (status, 0);
4746
4747   vat_json_init_object (&node);
4748   vat_json_object_add_string_copy (&node, "status", status);
4749   if (mp->status)
4750     {
4751       if (mp->is_ip4)
4752         {
4753           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4754           vat_json_object_add_ip6 (&node, "address", ip6);
4755         }
4756       else
4757         {
4758           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4759           vat_json_object_add_ip4 (&node, "address", ip4);
4760         }
4761     }
4762
4763   vec_free (status);
4764
4765   vat_json_print (vam->ofp, &node);
4766   vat_json_free (&node);
4767
4768   vam->retval = ntohl (mp->retval);
4769   vam->result_ready = 1;
4770 }
4771
4772 static void
4773   vl_api_show_one_nsh_mapping_reply_t_handler
4774   (vl_api_show_one_nsh_mapping_reply_t * mp)
4775 {
4776   vat_main_t *vam = &vat_main;
4777   i32 retval = ntohl (mp->retval);
4778
4779   if (0 <= retval)
4780     {
4781       print (vam->ofp, "%-20s%-16s",
4782              mp->is_set ? "set" : "not-set",
4783              mp->is_set ? (char *) mp->locator_set_name : "");
4784     }
4785
4786   vam->retval = retval;
4787   vam->result_ready = 1;
4788 }
4789
4790 static void
4791   vl_api_show_one_nsh_mapping_reply_t_handler_json
4792   (vl_api_show_one_nsh_mapping_reply_t * mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   vat_json_node_t node;
4796   u8 *status = 0;
4797
4798   status = format (0, "%s", mp->is_set ? "yes" : "no");
4799   vec_add1 (status, 0);
4800
4801   vat_json_init_object (&node);
4802   vat_json_object_add_string_copy (&node, "is_set", status);
4803   if (mp->is_set)
4804     {
4805       vat_json_object_add_string_copy (&node, "locator_set",
4806                                        mp->locator_set_name);
4807     }
4808
4809   vec_free (status);
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 static void
4819   vl_api_show_one_map_register_ttl_reply_t_handler
4820   (vl_api_show_one_map_register_ttl_reply_t * mp)
4821 {
4822   vat_main_t *vam = &vat_main;
4823   i32 retval = ntohl (mp->retval);
4824
4825   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4826
4827   if (0 <= retval)
4828     {
4829       print (vam->ofp, "ttl: %u", mp->ttl);
4830     }
4831
4832   vam->retval = retval;
4833   vam->result_ready = 1;
4834 }
4835
4836 static void
4837   vl_api_show_one_map_register_ttl_reply_t_handler_json
4838   (vl_api_show_one_map_register_ttl_reply_t * mp)
4839 {
4840   vat_main_t *vam = &vat_main;
4841   vat_json_node_t node;
4842
4843   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4844   vat_json_init_object (&node);
4845   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4846
4847   vat_json_print (vam->ofp, &node);
4848   vat_json_free (&node);
4849
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void
4855 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   i32 retval = ntohl (mp->retval);
4859
4860   if (0 <= retval)
4861     {
4862       print (vam->ofp, "%-20s%-16s",
4863              mp->status ? "enabled" : "disabled",
4864              mp->status ? (char *) mp->locator_set_name : "");
4865     }
4866
4867   vam->retval = retval;
4868   vam->result_ready = 1;
4869 }
4870
4871 static void
4872 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876   u8 *status = 0;
4877
4878   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4879   vec_add1 (status, 0);
4880
4881   vat_json_init_object (&node);
4882   vat_json_object_add_string_copy (&node, "status", status);
4883   if (mp->status)
4884     {
4885       vat_json_object_add_string_copy (&node, "locator_set",
4886                                        mp->locator_set_name);
4887     }
4888
4889   vec_free (status);
4890
4891   vat_json_print (vam->ofp, &node);
4892   vat_json_free (&node);
4893
4894   vam->retval = ntohl (mp->retval);
4895   vam->result_ready = 1;
4896 }
4897
4898 static u8 *
4899 format_policer_type (u8 * s, va_list * va)
4900 {
4901   u32 i = va_arg (*va, u32);
4902
4903   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4904     s = format (s, "1r2c");
4905   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4906     s = format (s, "1r3c");
4907   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4908     s = format (s, "2r3c-2698");
4909   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4910     s = format (s, "2r3c-4115");
4911   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4912     s = format (s, "2r3c-mef5cf1");
4913   else
4914     s = format (s, "ILLEGAL");
4915   return s;
4916 }
4917
4918 static u8 *
4919 format_policer_rate_type (u8 * s, va_list * va)
4920 {
4921   u32 i = va_arg (*va, u32);
4922
4923   if (i == SSE2_QOS_RATE_KBPS)
4924     s = format (s, "kbps");
4925   else if (i == SSE2_QOS_RATE_PPS)
4926     s = format (s, "pps");
4927   else
4928     s = format (s, "ILLEGAL");
4929   return s;
4930 }
4931
4932 static u8 *
4933 format_policer_round_type (u8 * s, va_list * va)
4934 {
4935   u32 i = va_arg (*va, u32);
4936
4937   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4938     s = format (s, "closest");
4939   else if (i == SSE2_QOS_ROUND_TO_UP)
4940     s = format (s, "up");
4941   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4942     s = format (s, "down");
4943   else
4944     s = format (s, "ILLEGAL");
4945   return s;
4946 }
4947
4948 static u8 *
4949 format_policer_action_type (u8 * s, va_list * va)
4950 {
4951   u32 i = va_arg (*va, u32);
4952
4953   if (i == SSE2_QOS_ACTION_DROP)
4954     s = format (s, "drop");
4955   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4956     s = format (s, "transmit");
4957   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4958     s = format (s, "mark-and-transmit");
4959   else
4960     s = format (s, "ILLEGAL");
4961   return s;
4962 }
4963
4964 static u8 *
4965 format_dscp (u8 * s, va_list * va)
4966 {
4967   u32 i = va_arg (*va, u32);
4968   char *t = 0;
4969
4970   switch (i)
4971     {
4972 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4973       foreach_vnet_dscp
4974 #undef _
4975     default:
4976       return format (s, "ILLEGAL");
4977     }
4978   s = format (s, "%s", t);
4979   return s;
4980 }
4981
4982 static void
4983 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4984 {
4985   vat_main_t *vam = &vat_main;
4986   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4987
4988   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4989     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4990   else
4991     conform_dscp_str = format (0, "");
4992
4993   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4994     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4995   else
4996     exceed_dscp_str = format (0, "");
4997
4998   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4999     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5000   else
5001     violate_dscp_str = format (0, "");
5002
5003   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
5004          "rate type %U, round type %U, %s rate, %s color-aware, "
5005          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
5006          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
5007          "conform action %U%s, exceed action %U%s, violate action %U%s",
5008          mp->name,
5009          format_policer_type, mp->type,
5010          ntohl (mp->cir),
5011          ntohl (mp->eir),
5012          clib_net_to_host_u64 (mp->cb),
5013          clib_net_to_host_u64 (mp->eb),
5014          format_policer_rate_type, mp->rate_type,
5015          format_policer_round_type, mp->round_type,
5016          mp->single_rate ? "single" : "dual",
5017          mp->color_aware ? "is" : "not",
5018          ntohl (mp->cir_tokens_per_period),
5019          ntohl (mp->pir_tokens_per_period),
5020          ntohl (mp->scale),
5021          ntohl (mp->current_limit),
5022          ntohl (mp->current_bucket),
5023          ntohl (mp->extended_limit),
5024          ntohl (mp->extended_bucket),
5025          clib_net_to_host_u64 (mp->last_update_time),
5026          format_policer_action_type, mp->conform_action_type,
5027          conform_dscp_str,
5028          format_policer_action_type, mp->exceed_action_type,
5029          exceed_dscp_str,
5030          format_policer_action_type, mp->violate_action_type,
5031          violate_dscp_str);
5032
5033   vec_free (conform_dscp_str);
5034   vec_free (exceed_dscp_str);
5035   vec_free (violate_dscp_str);
5036 }
5037
5038 static void vl_api_policer_details_t_handler_json
5039   (vl_api_policer_details_t * mp)
5040 {
5041   vat_main_t *vam = &vat_main;
5042   vat_json_node_t *node;
5043   u8 *rate_type_str, *round_type_str, *type_str;
5044   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
5045
5046   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
5047   round_type_str =
5048     format (0, "%U", format_policer_round_type, mp->round_type);
5049   type_str = format (0, "%U", format_policer_type, mp->type);
5050   conform_action_str = format (0, "%U", format_policer_action_type,
5051                                mp->conform_action_type);
5052   exceed_action_str = format (0, "%U", format_policer_action_type,
5053                               mp->exceed_action_type);
5054   violate_action_str = format (0, "%U", format_policer_action_type,
5055                                mp->violate_action_type);
5056
5057   if (VAT_JSON_ARRAY != vam->json_tree.type)
5058     {
5059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5060       vat_json_init_array (&vam->json_tree);
5061     }
5062   node = vat_json_array_add (&vam->json_tree);
5063
5064   vat_json_init_object (node);
5065   vat_json_object_add_string_copy (node, "name", mp->name);
5066   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
5067   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
5068   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
5069   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
5070   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
5071   vat_json_object_add_string_copy (node, "round_type", round_type_str);
5072   vat_json_object_add_string_copy (node, "type", type_str);
5073   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
5074   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5075   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5076   vat_json_object_add_uint (node, "cir_tokens_per_period",
5077                             ntohl (mp->cir_tokens_per_period));
5078   vat_json_object_add_uint (node, "eir_tokens_per_period",
5079                             ntohl (mp->pir_tokens_per_period));
5080   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5081   vat_json_object_add_uint (node, "current_bucket",
5082                             ntohl (mp->current_bucket));
5083   vat_json_object_add_uint (node, "extended_limit",
5084                             ntohl (mp->extended_limit));
5085   vat_json_object_add_uint (node, "extended_bucket",
5086                             ntohl (mp->extended_bucket));
5087   vat_json_object_add_uint (node, "last_update_time",
5088                             ntohl (mp->last_update_time));
5089   vat_json_object_add_string_copy (node, "conform_action",
5090                                    conform_action_str);
5091   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5092     {
5093       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5094       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5095       vec_free (dscp_str);
5096     }
5097   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5098   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5099     {
5100       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5101       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5102       vec_free (dscp_str);
5103     }
5104   vat_json_object_add_string_copy (node, "violate_action",
5105                                    violate_action_str);
5106   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5107     {
5108       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5109       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5110       vec_free (dscp_str);
5111     }
5112
5113   vec_free (rate_type_str);
5114   vec_free (round_type_str);
5115   vec_free (type_str);
5116   vec_free (conform_action_str);
5117   vec_free (exceed_action_str);
5118   vec_free (violate_action_str);
5119 }
5120
5121 static void
5122 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5123                                            mp)
5124 {
5125   vat_main_t *vam = &vat_main;
5126   int i, count = ntohl (mp->count);
5127
5128   if (count > 0)
5129     print (vam->ofp, "classify table ids (%d) : ", count);
5130   for (i = 0; i < count; i++)
5131     {
5132       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5133       print (vam->ofp, (i < count - 1) ? "," : "");
5134     }
5135   vam->retval = ntohl (mp->retval);
5136   vam->result_ready = 1;
5137 }
5138
5139 static void
5140   vl_api_classify_table_ids_reply_t_handler_json
5141   (vl_api_classify_table_ids_reply_t * mp)
5142 {
5143   vat_main_t *vam = &vat_main;
5144   int i, count = ntohl (mp->count);
5145
5146   if (count > 0)
5147     {
5148       vat_json_node_t node;
5149
5150       vat_json_init_object (&node);
5151       for (i = 0; i < count; i++)
5152         {
5153           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5154         }
5155       vat_json_print (vam->ofp, &node);
5156       vat_json_free (&node);
5157     }
5158   vam->retval = ntohl (mp->retval);
5159   vam->result_ready = 1;
5160 }
5161
5162 static void
5163   vl_api_classify_table_by_interface_reply_t_handler
5164   (vl_api_classify_table_by_interface_reply_t * mp)
5165 {
5166   vat_main_t *vam = &vat_main;
5167   u32 table_id;
5168
5169   table_id = ntohl (mp->l2_table_id);
5170   if (table_id != ~0)
5171     print (vam->ofp, "l2 table id : %d", table_id);
5172   else
5173     print (vam->ofp, "l2 table id : No input ACL tables configured");
5174   table_id = ntohl (mp->ip4_table_id);
5175   if (table_id != ~0)
5176     print (vam->ofp, "ip4 table id : %d", table_id);
5177   else
5178     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5179   table_id = ntohl (mp->ip6_table_id);
5180   if (table_id != ~0)
5181     print (vam->ofp, "ip6 table id : %d", table_id);
5182   else
5183     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5184   vam->retval = ntohl (mp->retval);
5185   vam->result_ready = 1;
5186 }
5187
5188 static void
5189   vl_api_classify_table_by_interface_reply_t_handler_json
5190   (vl_api_classify_table_by_interface_reply_t * mp)
5191 {
5192   vat_main_t *vam = &vat_main;
5193   vat_json_node_t node;
5194
5195   vat_json_init_object (&node);
5196
5197   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5198   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5199   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5200
5201   vat_json_print (vam->ofp, &node);
5202   vat_json_free (&node);
5203
5204   vam->retval = ntohl (mp->retval);
5205   vam->result_ready = 1;
5206 }
5207
5208 static void vl_api_policer_add_del_reply_t_handler
5209   (vl_api_policer_add_del_reply_t * mp)
5210 {
5211   vat_main_t *vam = &vat_main;
5212   i32 retval = ntohl (mp->retval);
5213   if (vam->async_mode)
5214     {
5215       vam->async_errors += (retval < 0);
5216     }
5217   else
5218     {
5219       vam->retval = retval;
5220       vam->result_ready = 1;
5221       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5222         /*
5223          * Note: this is just barely thread-safe, depends on
5224          * the main thread spinning waiting for an answer...
5225          */
5226         errmsg ("policer index %d", ntohl (mp->policer_index));
5227     }
5228 }
5229
5230 static void vl_api_policer_add_del_reply_t_handler_json
5231   (vl_api_policer_add_del_reply_t * mp)
5232 {
5233   vat_main_t *vam = &vat_main;
5234   vat_json_node_t node;
5235
5236   vat_json_init_object (&node);
5237   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5238   vat_json_object_add_uint (&node, "policer_index",
5239                             ntohl (mp->policer_index));
5240
5241   vat_json_print (vam->ofp, &node);
5242   vat_json_free (&node);
5243
5244   vam->retval = ntohl (mp->retval);
5245   vam->result_ready = 1;
5246 }
5247
5248 /* Format hex dump. */
5249 u8 *
5250 format_hex_bytes (u8 * s, va_list * va)
5251 {
5252   u8 *bytes = va_arg (*va, u8 *);
5253   int n_bytes = va_arg (*va, int);
5254   uword i;
5255
5256   /* Print short or long form depending on byte count. */
5257   uword short_form = n_bytes <= 32;
5258   u32 indent = format_get_indent (s);
5259
5260   if (n_bytes == 0)
5261     return s;
5262
5263   for (i = 0; i < n_bytes; i++)
5264     {
5265       if (!short_form && (i % 32) == 0)
5266         s = format (s, "%08x: ", i);
5267       s = format (s, "%02x", bytes[i]);
5268       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5269         s = format (s, "\n%U", format_white_space, indent);
5270     }
5271
5272   return s;
5273 }
5274
5275 static void
5276 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5277                                             * mp)
5278 {
5279   vat_main_t *vam = &vat_main;
5280   i32 retval = ntohl (mp->retval);
5281   if (retval == 0)
5282     {
5283       print (vam->ofp, "classify table info :");
5284       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5285              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5286              ntohl (mp->miss_next_index));
5287       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5288              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5289              ntohl (mp->match_n_vectors));
5290       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5291              ntohl (mp->mask_length));
5292     }
5293   vam->retval = retval;
5294   vam->result_ready = 1;
5295 }
5296
5297 static void
5298   vl_api_classify_table_info_reply_t_handler_json
5299   (vl_api_classify_table_info_reply_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t node;
5303
5304   i32 retval = ntohl (mp->retval);
5305   if (retval == 0)
5306     {
5307       vat_json_init_object (&node);
5308
5309       vat_json_object_add_int (&node, "sessions",
5310                                ntohl (mp->active_sessions));
5311       vat_json_object_add_int (&node, "nexttbl",
5312                                ntohl (mp->next_table_index));
5313       vat_json_object_add_int (&node, "nextnode",
5314                                ntohl (mp->miss_next_index));
5315       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5316       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5317       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5318       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5319                       ntohl (mp->mask_length), 0);
5320       vat_json_object_add_string_copy (&node, "mask", s);
5321
5322       vat_json_print (vam->ofp, &node);
5323       vat_json_free (&node);
5324     }
5325   vam->retval = ntohl (mp->retval);
5326   vam->result_ready = 1;
5327 }
5328
5329 static void
5330 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5331                                            mp)
5332 {
5333   vat_main_t *vam = &vat_main;
5334
5335   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5336          ntohl (mp->hit_next_index), ntohl (mp->advance),
5337          ntohl (mp->opaque_index));
5338   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5339          ntohl (mp->match_length));
5340 }
5341
5342 static void
5343   vl_api_classify_session_details_t_handler_json
5344   (vl_api_classify_session_details_t * mp)
5345 {
5346   vat_main_t *vam = &vat_main;
5347   vat_json_node_t *node = NULL;
5348
5349   if (VAT_JSON_ARRAY != vam->json_tree.type)
5350     {
5351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5352       vat_json_init_array (&vam->json_tree);
5353     }
5354   node = vat_json_array_add (&vam->json_tree);
5355
5356   vat_json_init_object (node);
5357   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5358   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5359   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5360   u8 *s =
5361     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5362             0);
5363   vat_json_object_add_string_copy (node, "match", s);
5364 }
5365
5366 static void vl_api_pg_create_interface_reply_t_handler
5367   (vl_api_pg_create_interface_reply_t * mp)
5368 {
5369   vat_main_t *vam = &vat_main;
5370
5371   vam->retval = ntohl (mp->retval);
5372   vam->result_ready = 1;
5373 }
5374
5375 static void vl_api_pg_create_interface_reply_t_handler_json
5376   (vl_api_pg_create_interface_reply_t * mp)
5377 {
5378   vat_main_t *vam = &vat_main;
5379   vat_json_node_t node;
5380
5381   i32 retval = ntohl (mp->retval);
5382   if (retval == 0)
5383     {
5384       vat_json_init_object (&node);
5385
5386       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5387
5388       vat_json_print (vam->ofp, &node);
5389       vat_json_free (&node);
5390     }
5391   vam->retval = ntohl (mp->retval);
5392   vam->result_ready = 1;
5393 }
5394
5395 static void vl_api_policer_classify_details_t_handler
5396   (vl_api_policer_classify_details_t * mp)
5397 {
5398   vat_main_t *vam = &vat_main;
5399
5400   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5401          ntohl (mp->table_index));
5402 }
5403
5404 static void vl_api_policer_classify_details_t_handler_json
5405   (vl_api_policer_classify_details_t * mp)
5406 {
5407   vat_main_t *vam = &vat_main;
5408   vat_json_node_t *node;
5409
5410   if (VAT_JSON_ARRAY != vam->json_tree.type)
5411     {
5412       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5413       vat_json_init_array (&vam->json_tree);
5414     }
5415   node = vat_json_array_add (&vam->json_tree);
5416
5417   vat_json_init_object (node);
5418   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5419   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5420 }
5421
5422 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5423   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5424 {
5425   vat_main_t *vam = &vat_main;
5426   i32 retval = ntohl (mp->retval);
5427   if (vam->async_mode)
5428     {
5429       vam->async_errors += (retval < 0);
5430     }
5431   else
5432     {
5433       vam->retval = retval;
5434       vam->sw_if_index = ntohl (mp->sw_if_index);
5435       vam->result_ready = 1;
5436     }
5437   vam->regenerate_interface_table = 1;
5438 }
5439
5440 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5441   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5442 {
5443   vat_main_t *vam = &vat_main;
5444   vat_json_node_t node;
5445
5446   vat_json_init_object (&node);
5447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5448   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5449
5450   vat_json_print (vam->ofp, &node);
5451   vat_json_free (&node);
5452
5453   vam->retval = ntohl (mp->retval);
5454   vam->result_ready = 1;
5455 }
5456
5457 static void vl_api_flow_classify_details_t_handler
5458   (vl_api_flow_classify_details_t * mp)
5459 {
5460   vat_main_t *vam = &vat_main;
5461
5462   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5463          ntohl (mp->table_index));
5464 }
5465
5466 static void vl_api_flow_classify_details_t_handler_json
5467   (vl_api_flow_classify_details_t * mp)
5468 {
5469   vat_main_t *vam = &vat_main;
5470   vat_json_node_t *node;
5471
5472   if (VAT_JSON_ARRAY != vam->json_tree.type)
5473     {
5474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5475       vat_json_init_array (&vam->json_tree);
5476     }
5477   node = vat_json_array_add (&vam->json_tree);
5478
5479   vat_json_init_object (node);
5480   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5481   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5482 }
5483
5484 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5485 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5486 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5487 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5488 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5489 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5490 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5491 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5492 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5493 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5494 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5495 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5496 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5497 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5498 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5499 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5500 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5501 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5502 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5503 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5504 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5505 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5506
5507 /*
5508  * Generate boilerplate reply handlers, which
5509  * dig the return value out of the xxx_reply_t API message,
5510  * stick it into vam->retval, and set vam->result_ready
5511  *
5512  * Could also do this by pointing N message decode slots at
5513  * a single function, but that could break in subtle ways.
5514  */
5515
5516 #define foreach_standard_reply_retval_handler           \
5517 _(sw_interface_set_flags_reply)                         \
5518 _(sw_interface_add_del_address_reply)                   \
5519 _(sw_interface_set_rx_mode_reply)                       \
5520 _(sw_interface_set_table_reply)                         \
5521 _(sw_interface_set_mpls_enable_reply)                   \
5522 _(sw_interface_set_vpath_reply)                         \
5523 _(sw_interface_set_vxlan_bypass_reply)                  \
5524 _(sw_interface_set_geneve_bypass_reply)                 \
5525 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5526 _(sw_interface_set_l2_bridge_reply)                     \
5527 _(bridge_domain_add_del_reply)                          \
5528 _(sw_interface_set_l2_xconnect_reply)                   \
5529 _(l2fib_add_del_reply)                                  \
5530 _(l2fib_flush_int_reply)                                \
5531 _(l2fib_flush_bd_reply)                                 \
5532 _(ip_add_del_route_reply)                               \
5533 _(ip_table_add_del_reply)                               \
5534 _(ip_mroute_add_del_reply)                              \
5535 _(mpls_route_add_del_reply)                             \
5536 _(mpls_table_add_del_reply)                             \
5537 _(mpls_ip_bind_unbind_reply)                            \
5538 _(bier_route_add_del_reply)                             \
5539 _(bier_table_add_del_reply)                             \
5540 _(proxy_arp_add_del_reply)                              \
5541 _(proxy_arp_intfc_enable_disable_reply)                 \
5542 _(sw_interface_set_unnumbered_reply)                    \
5543 _(ip_neighbor_add_del_reply)                            \
5544 _(oam_add_del_reply)                                    \
5545 _(reset_fib_reply)                                      \
5546 _(dhcp_proxy_config_reply)                              \
5547 _(dhcp_proxy_set_vss_reply)                             \
5548 _(dhcp_client_config_reply)                             \
5549 _(set_ip_flow_hash_reply)                               \
5550 _(sw_interface_ip6_enable_disable_reply)                \
5551 _(sw_interface_ip6_set_link_local_address_reply)        \
5552 _(ip6nd_proxy_add_del_reply)                            \
5553 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5554 _(sw_interface_ip6nd_ra_config_reply)                   \
5555 _(set_arp_neighbor_limit_reply)                         \
5556 _(l2_patch_add_del_reply)                               \
5557 _(sr_policy_add_reply)                                  \
5558 _(sr_policy_mod_reply)                                  \
5559 _(sr_policy_del_reply)                                  \
5560 _(sr_localsid_add_del_reply)                            \
5561 _(sr_steering_add_del_reply)                            \
5562 _(classify_add_del_session_reply)                       \
5563 _(classify_set_interface_ip_table_reply)                \
5564 _(classify_set_interface_l2_tables_reply)               \
5565 _(l2tpv3_set_tunnel_cookies_reply)                      \
5566 _(l2tpv3_interface_enable_disable_reply)                \
5567 _(l2tpv3_set_lookup_key_reply)                          \
5568 _(l2_fib_clear_table_reply)                             \
5569 _(l2_interface_efp_filter_reply)                        \
5570 _(l2_interface_vlan_tag_rewrite_reply)                  \
5571 _(modify_vhost_user_if_reply)                           \
5572 _(delete_vhost_user_if_reply)                           \
5573 _(ip_probe_neighbor_reply)                              \
5574 _(want_ip4_arp_events_reply)                            \
5575 _(want_ip6_nd_events_reply)                             \
5576 _(want_l2_macs_events_reply)                            \
5577 _(input_acl_set_interface_reply)                        \
5578 _(ipsec_spd_add_del_reply)                              \
5579 _(ipsec_interface_add_del_spd_reply)                    \
5580 _(ipsec_spd_add_del_entry_reply)                        \
5581 _(ipsec_sad_add_del_entry_reply)                        \
5582 _(ipsec_sa_set_key_reply)                               \
5583 _(ipsec_tunnel_if_add_del_reply)                        \
5584 _(ipsec_tunnel_if_set_key_reply)                        \
5585 _(ipsec_tunnel_if_set_sa_reply)                         \
5586 _(ikev2_profile_add_del_reply)                          \
5587 _(ikev2_profile_set_auth_reply)                         \
5588 _(ikev2_profile_set_id_reply)                           \
5589 _(ikev2_profile_set_ts_reply)                           \
5590 _(ikev2_set_local_key_reply)                            \
5591 _(ikev2_set_responder_reply)                            \
5592 _(ikev2_set_ike_transforms_reply)                       \
5593 _(ikev2_set_esp_transforms_reply)                       \
5594 _(ikev2_set_sa_lifetime_reply)                          \
5595 _(ikev2_initiate_sa_init_reply)                         \
5596 _(ikev2_initiate_del_ike_sa_reply)                      \
5597 _(ikev2_initiate_del_child_sa_reply)                    \
5598 _(ikev2_initiate_rekey_child_sa_reply)                  \
5599 _(delete_loopback_reply)                                \
5600 _(bd_ip_mac_add_del_reply)                              \
5601 _(map_del_domain_reply)                                 \
5602 _(map_add_del_rule_reply)                               \
5603 _(want_interface_events_reply)                          \
5604 _(want_stats_reply)                                     \
5605 _(cop_interface_enable_disable_reply)                   \
5606 _(cop_whitelist_enable_disable_reply)                   \
5607 _(sw_interface_clear_stats_reply)                       \
5608 _(ioam_enable_reply)                                    \
5609 _(ioam_disable_reply)                                   \
5610 _(one_add_del_locator_reply)                            \
5611 _(one_add_del_local_eid_reply)                          \
5612 _(one_add_del_remote_mapping_reply)                     \
5613 _(one_add_del_adjacency_reply)                          \
5614 _(one_add_del_map_resolver_reply)                       \
5615 _(one_add_del_map_server_reply)                         \
5616 _(one_enable_disable_reply)                             \
5617 _(one_rloc_probe_enable_disable_reply)                  \
5618 _(one_map_register_enable_disable_reply)                \
5619 _(one_map_register_set_ttl_reply)                       \
5620 _(one_set_transport_protocol_reply)                     \
5621 _(one_map_register_fallback_threshold_reply)            \
5622 _(one_pitr_set_locator_set_reply)                       \
5623 _(one_map_request_mode_reply)                           \
5624 _(one_add_del_map_request_itr_rlocs_reply)              \
5625 _(one_eid_table_add_del_map_reply)                      \
5626 _(one_use_petr_reply)                                   \
5627 _(one_stats_enable_disable_reply)                       \
5628 _(one_add_del_l2_arp_entry_reply)                       \
5629 _(one_add_del_ndp_entry_reply)                          \
5630 _(one_stats_flush_reply)                                \
5631 _(one_enable_disable_xtr_mode_reply)                    \
5632 _(one_enable_disable_pitr_mode_reply)                   \
5633 _(one_enable_disable_petr_mode_reply)                   \
5634 _(gpe_enable_disable_reply)                             \
5635 _(gpe_set_encap_mode_reply)                             \
5636 _(gpe_add_del_iface_reply)                              \
5637 _(gpe_add_del_native_fwd_rpath_reply)                   \
5638 _(af_packet_delete_reply)                               \
5639 _(policer_classify_set_interface_reply)                 \
5640 _(netmap_create_reply)                                  \
5641 _(netmap_delete_reply)                                  \
5642 _(set_ipfix_exporter_reply)                             \
5643 _(set_ipfix_classify_stream_reply)                      \
5644 _(ipfix_classify_table_add_del_reply)                   \
5645 _(flow_classify_set_interface_reply)                    \
5646 _(sw_interface_span_enable_disable_reply)               \
5647 _(pg_capture_reply)                                     \
5648 _(pg_enable_disable_reply)                              \
5649 _(ip_source_and_port_range_check_add_del_reply)         \
5650 _(ip_source_and_port_range_check_interface_add_del_reply)\
5651 _(delete_subif_reply)                                   \
5652 _(l2_interface_pbb_tag_rewrite_reply)                   \
5653 _(punt_reply)                                           \
5654 _(feature_enable_disable_reply)                         \
5655 _(sw_interface_tag_add_del_reply)                       \
5656 _(sw_interface_set_mtu_reply)                           \
5657 _(p2p_ethernet_add_reply)                               \
5658 _(p2p_ethernet_del_reply)                               \
5659 _(lldp_config_reply)                                    \
5660 _(sw_interface_set_lldp_reply)                          \
5661 _(tcp_configure_src_addresses_reply)                    \
5662 _(dns_enable_disable_reply)                             \
5663 _(dns_name_server_add_del_reply)                        \
5664 _(session_rule_add_del_reply)                           \
5665 _(ip_container_proxy_add_del_reply)                     \
5666 _(output_acl_set_interface_reply)                       \
5667 _(qos_record_enable_disable_reply)
5668
5669 #define _(n)                                    \
5670     static void vl_api_##n##_t_handler          \
5671     (vl_api_##n##_t * mp)                       \
5672     {                                           \
5673         vat_main_t * vam = &vat_main;           \
5674         i32 retval = ntohl(mp->retval);         \
5675         if (vam->async_mode) {                  \
5676             vam->async_errors += (retval < 0);  \
5677         } else {                                \
5678             vam->retval = retval;               \
5679             vam->result_ready = 1;              \
5680         }                                       \
5681     }
5682 foreach_standard_reply_retval_handler;
5683 #undef _
5684
5685 #define _(n)                                    \
5686     static void vl_api_##n##_t_handler_json     \
5687     (vl_api_##n##_t * mp)                       \
5688     {                                           \
5689         vat_main_t * vam = &vat_main;           \
5690         vat_json_node_t node;                   \
5691         vat_json_init_object(&node);            \
5692         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5693         vat_json_print(vam->ofp, &node);        \
5694         vam->retval = ntohl(mp->retval);        \
5695         vam->result_ready = 1;                  \
5696     }
5697 foreach_standard_reply_retval_handler;
5698 #undef _
5699
5700 /*
5701  * Table of message reply handlers, must include boilerplate handlers
5702  * we just generated
5703  */
5704
5705 #define foreach_vpe_api_reply_msg                                       \
5706 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5707 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5708 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5709 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5710 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5711 _(CLI_REPLY, cli_reply)                                                 \
5712 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5713 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5714   sw_interface_add_del_address_reply)                                   \
5715 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5716 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5717 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5718 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5719 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5720 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5721 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5722 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5723   sw_interface_set_l2_xconnect_reply)                                   \
5724 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5725   sw_interface_set_l2_bridge_reply)                                     \
5726 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5727 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5728 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5729 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5730 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5731 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5732 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5733 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5734 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5735 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5736 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5737 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5738 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5739 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5740 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5741 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5742 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5743 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5744 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5745 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5746 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5747 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5748 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5749 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5750 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5751 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5752 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5753 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5754 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5755 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5756 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5757   proxy_arp_intfc_enable_disable_reply)                                 \
5758 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5759 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5760   sw_interface_set_unnumbered_reply)                                    \
5761 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5762 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5763 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5764 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5765 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5766 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5767 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5768 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5769 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5770 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5771 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5772   sw_interface_ip6_enable_disable_reply)                                \
5773 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5774   sw_interface_ip6_set_link_local_address_reply)                        \
5775 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5776 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5777 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5778   sw_interface_ip6nd_ra_prefix_reply)                                   \
5779 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5780   sw_interface_ip6nd_ra_config_reply)                                   \
5781 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5782 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5783 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5784 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5785 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5786 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5787 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5788 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5789 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5790 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5791 classify_set_interface_ip_table_reply)                                  \
5792 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5793   classify_set_interface_l2_tables_reply)                               \
5794 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5795 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5796 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5797 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5798 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5799   l2tpv3_interface_enable_disable_reply)                                \
5800 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5801 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5802 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5803 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5804 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5805 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5806 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5807 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5808 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5809 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5810 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5811 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5812 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5813 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5814 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5815 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5816 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5817 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5818 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5819 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5820 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5821 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5822 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5823 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5824 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5825 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5826 _(L2_MACS_EVENT, l2_macs_event)                                         \
5827 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5828 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5829 _(IP_DETAILS, ip_details)                                               \
5830 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5831 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5832 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5833 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5834 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5835 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5836 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5837 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5838 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5839 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5840 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5841 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5842 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5843 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5844 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5845 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5846 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5847 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5848 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5849 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5850 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5851 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5852 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5853 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5854 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5855 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5856 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5857 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5858 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5859 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5860 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5861 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5862 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5863 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5864 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5865 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5866 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5867 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5868 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5869 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5870 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5871 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5872 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5873 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5874 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5875 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5876 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5877 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5878   one_map_register_enable_disable_reply)                                \
5879 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5880 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5881 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5882 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5883   one_map_register_fallback_threshold_reply)                            \
5884 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5885   one_rloc_probe_enable_disable_reply)                                  \
5886 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5887 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5888 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5889 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5890 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5891 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5892 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5893 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5894 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5895 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5896 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5897 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5898 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5899 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5900 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5901 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5902   show_one_stats_enable_disable_reply)                                  \
5903 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5904 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5905 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5906 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5907 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5908 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5909 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5910 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5911   one_enable_disable_pitr_mode_reply)                                   \
5912 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5913   one_enable_disable_petr_mode_reply)                                   \
5914 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5915 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5916 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5917 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5918 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5919 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5920 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5921 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5922 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5923 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5924 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5925 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5926   gpe_add_del_native_fwd_rpath_reply)                                   \
5927 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5928   gpe_fwd_entry_path_details)                                           \
5929 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5930 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5931   one_add_del_map_request_itr_rlocs_reply)                              \
5932 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5933   one_get_map_request_itr_rlocs_reply)                                  \
5934 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5935 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5936 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5937 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5938 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5939 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5940   show_one_map_register_state_reply)                                    \
5941 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5942 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5943   show_one_map_register_fallback_threshold_reply)                       \
5944 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5945 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5946 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5947 _(POLICER_DETAILS, policer_details)                                     \
5948 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5949 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5950 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5951 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5952 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5953 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5954 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5955 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5956 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5957 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5958 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5959 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5960 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5961 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5962 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5963 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5964 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5965 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5966 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5967 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5968 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5969 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5970 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5971 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5972 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5973  ip_source_and_port_range_check_add_del_reply)                          \
5974 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5975  ip_source_and_port_range_check_interface_add_del_reply)                \
5976 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5977 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5978 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5979 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5980 _(PUNT_REPLY, punt_reply)                                               \
5981 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5982 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5983 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5984 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5985 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5986 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5987 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5988 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5989 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5990 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5991 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5992 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5993 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5994 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5995 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5996 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5997 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5998 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5999 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
6000 _(SESSION_RULES_DETAILS, session_rules_details)                         \
6001 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
6002 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
6003 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
6004
6005 #define foreach_standalone_reply_msg                                    \
6006 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
6007 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
6008 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
6009 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
6010 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
6011 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
6012 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
6013 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
6014
6015 typedef struct
6016 {
6017   u8 *name;
6018   u32 value;
6019 } name_sort_t;
6020
6021
6022 #define STR_VTR_OP_CASE(op)     \
6023     case L2_VTR_ ## op:         \
6024         return "" # op;
6025
6026 static const char *
6027 str_vtr_op (u32 vtr_op)
6028 {
6029   switch (vtr_op)
6030     {
6031       STR_VTR_OP_CASE (DISABLED);
6032       STR_VTR_OP_CASE (PUSH_1);
6033       STR_VTR_OP_CASE (PUSH_2);
6034       STR_VTR_OP_CASE (POP_1);
6035       STR_VTR_OP_CASE (POP_2);
6036       STR_VTR_OP_CASE (TRANSLATE_1_1);
6037       STR_VTR_OP_CASE (TRANSLATE_1_2);
6038       STR_VTR_OP_CASE (TRANSLATE_2_1);
6039       STR_VTR_OP_CASE (TRANSLATE_2_2);
6040     }
6041
6042   return "UNKNOWN";
6043 }
6044
6045 static int
6046 dump_sub_interface_table (vat_main_t * vam)
6047 {
6048   const sw_interface_subif_t *sub = NULL;
6049
6050   if (vam->json_output)
6051     {
6052       clib_warning
6053         ("JSON output supported only for VPE API calls and dump_stats_table");
6054       return -99;
6055     }
6056
6057   print (vam->ofp,
6058          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
6059          "Interface", "sw_if_index",
6060          "sub id", "dot1ad", "tags", "outer id",
6061          "inner id", "exact", "default", "outer any", "inner any");
6062
6063   vec_foreach (sub, vam->sw_if_subif_table)
6064   {
6065     print (vam->ofp,
6066            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
6067            sub->interface_name,
6068            sub->sw_if_index,
6069            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
6070            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6071            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6072            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6073     if (sub->vtr_op != L2_VTR_DISABLED)
6074       {
6075         print (vam->ofp,
6076                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6077                "tag1: %d tag2: %d ]",
6078                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6079                sub->vtr_tag1, sub->vtr_tag2);
6080       }
6081   }
6082
6083   return 0;
6084 }
6085
6086 static int
6087 name_sort_cmp (void *a1, void *a2)
6088 {
6089   name_sort_t *n1 = a1;
6090   name_sort_t *n2 = a2;
6091
6092   return strcmp ((char *) n1->name, (char *) n2->name);
6093 }
6094
6095 static int
6096 dump_interface_table (vat_main_t * vam)
6097 {
6098   hash_pair_t *p;
6099   name_sort_t *nses = 0, *ns;
6100
6101   if (vam->json_output)
6102     {
6103       clib_warning
6104         ("JSON output supported only for VPE API calls and dump_stats_table");
6105       return -99;
6106     }
6107
6108   /* *INDENT-OFF* */
6109   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6110   ({
6111     vec_add2 (nses, ns, 1);
6112     ns->name = (u8 *)(p->key);
6113     ns->value = (u32) p->value[0];
6114   }));
6115   /* *INDENT-ON* */
6116
6117   vec_sort_with_function (nses, name_sort_cmp);
6118
6119   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6120   vec_foreach (ns, nses)
6121   {
6122     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6123   }
6124   vec_free (nses);
6125   return 0;
6126 }
6127
6128 static int
6129 dump_ip_table (vat_main_t * vam, int is_ipv6)
6130 {
6131   const ip_details_t *det = NULL;
6132   const ip_address_details_t *address = NULL;
6133   u32 i = ~0;
6134
6135   print (vam->ofp, "%-12s", "sw_if_index");
6136
6137   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6138   {
6139     i++;
6140     if (!det->present)
6141       {
6142         continue;
6143       }
6144     print (vam->ofp, "%-12d", i);
6145     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6146     if (!det->addr)
6147       {
6148         continue;
6149       }
6150     vec_foreach (address, det->addr)
6151     {
6152       print (vam->ofp,
6153              "            %-30U%-13d",
6154              is_ipv6 ? format_ip6_address : format_ip4_address,
6155              address->ip, address->prefix_length);
6156     }
6157   }
6158
6159   return 0;
6160 }
6161
6162 static int
6163 dump_ipv4_table (vat_main_t * vam)
6164 {
6165   if (vam->json_output)
6166     {
6167       clib_warning
6168         ("JSON output supported only for VPE API calls and dump_stats_table");
6169       return -99;
6170     }
6171
6172   return dump_ip_table (vam, 0);
6173 }
6174
6175 static int
6176 dump_ipv6_table (vat_main_t * vam)
6177 {
6178   if (vam->json_output)
6179     {
6180       clib_warning
6181         ("JSON output supported only for VPE API calls and dump_stats_table");
6182       return -99;
6183     }
6184
6185   return dump_ip_table (vam, 1);
6186 }
6187
6188 static char *
6189 counter_type_to_str (u8 counter_type, u8 is_combined)
6190 {
6191   if (!is_combined)
6192     {
6193       switch (counter_type)
6194         {
6195         case VNET_INTERFACE_COUNTER_DROP:
6196           return "drop";
6197         case VNET_INTERFACE_COUNTER_PUNT:
6198           return "punt";
6199         case VNET_INTERFACE_COUNTER_IP4:
6200           return "ip4";
6201         case VNET_INTERFACE_COUNTER_IP6:
6202           return "ip6";
6203         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6204           return "rx-no-buf";
6205         case VNET_INTERFACE_COUNTER_RX_MISS:
6206           return "rx-miss";
6207         case VNET_INTERFACE_COUNTER_RX_ERROR:
6208           return "rx-error";
6209         case VNET_INTERFACE_COUNTER_TX_ERROR:
6210           return "tx-error";
6211         default:
6212           return "INVALID-COUNTER-TYPE";
6213         }
6214     }
6215   else
6216     {
6217       switch (counter_type)
6218         {
6219         case VNET_INTERFACE_COUNTER_RX:
6220           return "rx";
6221         case VNET_INTERFACE_COUNTER_TX:
6222           return "tx";
6223         default:
6224           return "INVALID-COUNTER-TYPE";
6225         }
6226     }
6227 }
6228
6229 static int
6230 dump_stats_table (vat_main_t * vam)
6231 {
6232   vat_json_node_t node;
6233   vat_json_node_t *msg_array;
6234   vat_json_node_t *msg;
6235   vat_json_node_t *counter_array;
6236   vat_json_node_t *counter;
6237   interface_counter_t c;
6238   u64 packets;
6239   ip4_fib_counter_t *c4;
6240   ip6_fib_counter_t *c6;
6241   ip4_nbr_counter_t *n4;
6242   ip6_nbr_counter_t *n6;
6243   int i, j;
6244
6245   if (!vam->json_output)
6246     {
6247       clib_warning ("dump_stats_table supported only in JSON format");
6248       return -99;
6249     }
6250
6251   vat_json_init_object (&node);
6252
6253   /* interface counters */
6254   msg_array = vat_json_object_add (&node, "interface_counters");
6255   vat_json_init_array (msg_array);
6256   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6257     {
6258       msg = vat_json_array_add (msg_array);
6259       vat_json_init_object (msg);
6260       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6261                                        (u8 *) counter_type_to_str (i, 0));
6262       vat_json_object_add_int (msg, "is_combined", 0);
6263       counter_array = vat_json_object_add (msg, "data");
6264       vat_json_init_array (counter_array);
6265       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6266         {
6267           packets = vam->simple_interface_counters[i][j];
6268           vat_json_array_add_uint (counter_array, packets);
6269         }
6270     }
6271   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6272     {
6273       msg = vat_json_array_add (msg_array);
6274       vat_json_init_object (msg);
6275       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6276                                        (u8 *) counter_type_to_str (i, 1));
6277       vat_json_object_add_int (msg, "is_combined", 1);
6278       counter_array = vat_json_object_add (msg, "data");
6279       vat_json_init_array (counter_array);
6280       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6281         {
6282           c = vam->combined_interface_counters[i][j];
6283           counter = vat_json_array_add (counter_array);
6284           vat_json_init_object (counter);
6285           vat_json_object_add_uint (counter, "packets", c.packets);
6286           vat_json_object_add_uint (counter, "bytes", c.bytes);
6287         }
6288     }
6289
6290   /* ip4 fib counters */
6291   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6292   vat_json_init_array (msg_array);
6293   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6294     {
6295       msg = vat_json_array_add (msg_array);
6296       vat_json_init_object (msg);
6297       vat_json_object_add_uint (msg, "vrf_id",
6298                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6299       counter_array = vat_json_object_add (msg, "c");
6300       vat_json_init_array (counter_array);
6301       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6302         {
6303           counter = vat_json_array_add (counter_array);
6304           vat_json_init_object (counter);
6305           c4 = &vam->ip4_fib_counters[i][j];
6306           vat_json_object_add_ip4 (counter, "address", c4->address);
6307           vat_json_object_add_uint (counter, "address_length",
6308                                     c4->address_length);
6309           vat_json_object_add_uint (counter, "packets", c4->packets);
6310           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6311         }
6312     }
6313
6314   /* ip6 fib counters */
6315   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6316   vat_json_init_array (msg_array);
6317   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6318     {
6319       msg = vat_json_array_add (msg_array);
6320       vat_json_init_object (msg);
6321       vat_json_object_add_uint (msg, "vrf_id",
6322                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6323       counter_array = vat_json_object_add (msg, "c");
6324       vat_json_init_array (counter_array);
6325       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6326         {
6327           counter = vat_json_array_add (counter_array);
6328           vat_json_init_object (counter);
6329           c6 = &vam->ip6_fib_counters[i][j];
6330           vat_json_object_add_ip6 (counter, "address", c6->address);
6331           vat_json_object_add_uint (counter, "address_length",
6332                                     c6->address_length);
6333           vat_json_object_add_uint (counter, "packets", c6->packets);
6334           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6335         }
6336     }
6337
6338   /* ip4 nbr counters */
6339   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6340   vat_json_init_array (msg_array);
6341   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6342     {
6343       msg = vat_json_array_add (msg_array);
6344       vat_json_init_object (msg);
6345       vat_json_object_add_uint (msg, "sw_if_index", i);
6346       counter_array = vat_json_object_add (msg, "c");
6347       vat_json_init_array (counter_array);
6348       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6349         {
6350           counter = vat_json_array_add (counter_array);
6351           vat_json_init_object (counter);
6352           n4 = &vam->ip4_nbr_counters[i][j];
6353           vat_json_object_add_ip4 (counter, "address", n4->address);
6354           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6355           vat_json_object_add_uint (counter, "packets", n4->packets);
6356           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6357         }
6358     }
6359
6360   /* ip6 nbr counters */
6361   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6362   vat_json_init_array (msg_array);
6363   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6364     {
6365       msg = vat_json_array_add (msg_array);
6366       vat_json_init_object (msg);
6367       vat_json_object_add_uint (msg, "sw_if_index", i);
6368       counter_array = vat_json_object_add (msg, "c");
6369       vat_json_init_array (counter_array);
6370       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6371         {
6372           counter = vat_json_array_add (counter_array);
6373           vat_json_init_object (counter);
6374           n6 = &vam->ip6_nbr_counters[i][j];
6375           vat_json_object_add_ip6 (counter, "address", n6->address);
6376           vat_json_object_add_uint (counter, "packets", n6->packets);
6377           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6378         }
6379     }
6380
6381   vat_json_print (vam->ofp, &node);
6382   vat_json_free (&node);
6383
6384   return 0;
6385 }
6386
6387 /*
6388  * Pass CLI buffers directly in the CLI_INBAND API message,
6389  * instead of an additional shared memory area.
6390  */
6391 static int
6392 exec_inband (vat_main_t * vam)
6393 {
6394   vl_api_cli_inband_t *mp;
6395   unformat_input_t *i = vam->input;
6396   int ret;
6397
6398   if (vec_len (i->buffer) == 0)
6399     return -1;
6400
6401   if (vam->exec_mode == 0 && unformat (i, "mode"))
6402     {
6403       vam->exec_mode = 1;
6404       return 0;
6405     }
6406   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6407     {
6408       vam->exec_mode = 0;
6409       return 0;
6410     }
6411
6412   /*
6413    * In order for the CLI command to work, it
6414    * must be a vector ending in \n, not a C-string ending
6415    * in \n\0.
6416    */
6417   u32 len = vec_len (vam->input->buffer);
6418   M2 (CLI_INBAND, mp, len);
6419   clib_memcpy (mp->cmd, vam->input->buffer, len);
6420   mp->length = htonl (len);
6421
6422   S (mp);
6423   W (ret);
6424   /* json responses may or may not include a useful reply... */
6425   if (vec_len (vam->cmd_reply))
6426     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6427   return ret;
6428 }
6429
6430 int
6431 exec (vat_main_t * vam)
6432 {
6433   return exec_inband (vam);
6434 }
6435
6436 static int
6437 api_create_loopback (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_create_loopback_t *mp;
6441   vl_api_create_loopback_instance_t *mp_lbi;
6442   u8 mac_address[6];
6443   u8 mac_set = 0;
6444   u8 is_specified = 0;
6445   u32 user_instance = 0;
6446   int ret;
6447
6448   memset (mac_address, 0, sizeof (mac_address));
6449
6450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6451     {
6452       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6453         mac_set = 1;
6454       if (unformat (i, "instance %d", &user_instance))
6455         is_specified = 1;
6456       else
6457         break;
6458     }
6459
6460   if (is_specified)
6461     {
6462       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6463       mp_lbi->is_specified = is_specified;
6464       if (is_specified)
6465         mp_lbi->user_instance = htonl (user_instance);
6466       if (mac_set)
6467         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6468       S (mp_lbi);
6469     }
6470   else
6471     {
6472       /* Construct the API message */
6473       M (CREATE_LOOPBACK, mp);
6474       if (mac_set)
6475         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6476       S (mp);
6477     }
6478
6479   W (ret);
6480   return ret;
6481 }
6482
6483 static int
6484 api_delete_loopback (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_delete_loopback_t *mp;
6488   u32 sw_if_index = ~0;
6489   int ret;
6490
6491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6492     {
6493       if (unformat (i, "sw_if_index %d", &sw_if_index))
6494         ;
6495       else
6496         break;
6497     }
6498
6499   if (sw_if_index == ~0)
6500     {
6501       errmsg ("missing sw_if_index");
6502       return -99;
6503     }
6504
6505   /* Construct the API message */
6506   M (DELETE_LOOPBACK, mp);
6507   mp->sw_if_index = ntohl (sw_if_index);
6508
6509   S (mp);
6510   W (ret);
6511   return ret;
6512 }
6513
6514 static int
6515 api_want_stats (vat_main_t * vam)
6516 {
6517   unformat_input_t *i = vam->input;
6518   vl_api_want_stats_t *mp;
6519   int enable = -1;
6520   int ret;
6521
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "enable"))
6525         enable = 1;
6526       else if (unformat (i, "disable"))
6527         enable = 0;
6528       else
6529         break;
6530     }
6531
6532   if (enable == -1)
6533     {
6534       errmsg ("missing enable|disable");
6535       return -99;
6536     }
6537
6538   M (WANT_STATS, mp);
6539   mp->enable_disable = enable;
6540
6541   S (mp);
6542   W (ret);
6543   return ret;
6544 }
6545
6546 static int
6547 api_want_interface_events (vat_main_t * vam)
6548 {
6549   unformat_input_t *i = vam->input;
6550   vl_api_want_interface_events_t *mp;
6551   int enable = -1;
6552   int ret;
6553
6554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6555     {
6556       if (unformat (i, "enable"))
6557         enable = 1;
6558       else if (unformat (i, "disable"))
6559         enable = 0;
6560       else
6561         break;
6562     }
6563
6564   if (enable == -1)
6565     {
6566       errmsg ("missing enable|disable");
6567       return -99;
6568     }
6569
6570   M (WANT_INTERFACE_EVENTS, mp);
6571   mp->enable_disable = enable;
6572
6573   vam->interface_event_display = enable;
6574
6575   S (mp);
6576   W (ret);
6577   return ret;
6578 }
6579
6580
6581 /* Note: non-static, called once to set up the initial intfc table */
6582 int
6583 api_sw_interface_dump (vat_main_t * vam)
6584 {
6585   vl_api_sw_interface_dump_t *mp;
6586   vl_api_control_ping_t *mp_ping;
6587   hash_pair_t *p;
6588   name_sort_t *nses = 0, *ns;
6589   sw_interface_subif_t *sub = NULL;
6590   int ret;
6591
6592   /* Toss the old name table */
6593   /* *INDENT-OFF* */
6594   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6595   ({
6596     vec_add2 (nses, ns, 1);
6597     ns->name = (u8 *)(p->key);
6598     ns->value = (u32) p->value[0];
6599   }));
6600   /* *INDENT-ON* */
6601
6602   hash_free (vam->sw_if_index_by_interface_name);
6603
6604   vec_foreach (ns, nses) vec_free (ns->name);
6605
6606   vec_free (nses);
6607
6608   vec_foreach (sub, vam->sw_if_subif_table)
6609   {
6610     vec_free (sub->interface_name);
6611   }
6612   vec_free (vam->sw_if_subif_table);
6613
6614   /* recreate the interface name hash table */
6615   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6616
6617   /*
6618    * Ask for all interface names. Otherwise, the epic catalog of
6619    * name filters becomes ridiculously long, and vat ends up needing
6620    * to be taught about new interface types.
6621    */
6622   M (SW_INTERFACE_DUMP, mp);
6623   S (mp);
6624
6625   /* Use a control ping for synchronization */
6626   MPING (CONTROL_PING, mp_ping);
6627   S (mp_ping);
6628
6629   W (ret);
6630   return ret;
6631 }
6632
6633 static int
6634 api_sw_interface_set_flags (vat_main_t * vam)
6635 {
6636   unformat_input_t *i = vam->input;
6637   vl_api_sw_interface_set_flags_t *mp;
6638   u32 sw_if_index;
6639   u8 sw_if_index_set = 0;
6640   u8 admin_up = 0;
6641   int ret;
6642
6643   /* Parse args required to build the message */
6644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6645     {
6646       if (unformat (i, "admin-up"))
6647         admin_up = 1;
6648       else if (unformat (i, "admin-down"))
6649         admin_up = 0;
6650       else
6651         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6652         sw_if_index_set = 1;
6653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6654         sw_if_index_set = 1;
6655       else
6656         break;
6657     }
6658
6659   if (sw_if_index_set == 0)
6660     {
6661       errmsg ("missing interface name or sw_if_index");
6662       return -99;
6663     }
6664
6665   /* Construct the API message */
6666   M (SW_INTERFACE_SET_FLAGS, mp);
6667   mp->sw_if_index = ntohl (sw_if_index);
6668   mp->admin_up_down = admin_up;
6669
6670   /* send it... */
6671   S (mp);
6672
6673   /* Wait for a reply, return the good/bad news... */
6674   W (ret);
6675   return ret;
6676 }
6677
6678 static int
6679 api_sw_interface_set_rx_mode (vat_main_t * vam)
6680 {
6681   unformat_input_t *i = vam->input;
6682   vl_api_sw_interface_set_rx_mode_t *mp;
6683   u32 sw_if_index;
6684   u8 sw_if_index_set = 0;
6685   int ret;
6686   u8 queue_id_valid = 0;
6687   u32 queue_id;
6688   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "queue %d", &queue_id))
6694         queue_id_valid = 1;
6695       else if (unformat (i, "polling"))
6696         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6697       else if (unformat (i, "interrupt"))
6698         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6699       else if (unformat (i, "adaptive"))
6700         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6701       else
6702         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6705         sw_if_index_set = 1;
6706       else
6707         break;
6708     }
6709
6710   if (sw_if_index_set == 0)
6711     {
6712       errmsg ("missing interface name or sw_if_index");
6713       return -99;
6714     }
6715   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6716     {
6717       errmsg ("missing rx-mode");
6718       return -99;
6719     }
6720
6721   /* Construct the API message */
6722   M (SW_INTERFACE_SET_RX_MODE, mp);
6723   mp->sw_if_index = ntohl (sw_if_index);
6724   mp->mode = mode;
6725   mp->queue_id_valid = queue_id_valid;
6726   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6727
6728   /* send it... */
6729   S (mp);
6730
6731   /* Wait for a reply, return the good/bad news... */
6732   W (ret);
6733   return ret;
6734 }
6735
6736 static int
6737 api_sw_interface_clear_stats (vat_main_t * vam)
6738 {
6739   unformat_input_t *i = vam->input;
6740   vl_api_sw_interface_clear_stats_t *mp;
6741   u32 sw_if_index;
6742   u8 sw_if_index_set = 0;
6743   int ret;
6744
6745   /* Parse args required to build the message */
6746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6747     {
6748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6749         sw_if_index_set = 1;
6750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6751         sw_if_index_set = 1;
6752       else
6753         break;
6754     }
6755
6756   /* Construct the API message */
6757   M (SW_INTERFACE_CLEAR_STATS, mp);
6758
6759   if (sw_if_index_set == 1)
6760     mp->sw_if_index = ntohl (sw_if_index);
6761   else
6762     mp->sw_if_index = ~0;
6763
6764   /* send it... */
6765   S (mp);
6766
6767   /* Wait for a reply, return the good/bad news... */
6768   W (ret);
6769   return ret;
6770 }
6771
6772 static int
6773 api_sw_interface_add_del_address (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_sw_interface_add_del_address_t *mp;
6777   u32 sw_if_index;
6778   u8 sw_if_index_set = 0;
6779   u8 is_add = 1, del_all = 0;
6780   u32 address_length = 0;
6781   u8 v4_address_set = 0;
6782   u8 v6_address_set = 0;
6783   ip4_address_t v4address;
6784   ip6_address_t v6address;
6785   int ret;
6786
6787   /* Parse args required to build the message */
6788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789     {
6790       if (unformat (i, "del-all"))
6791         del_all = 1;
6792       else if (unformat (i, "del"))
6793         is_add = 0;
6794       else
6795         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "%U/%d",
6800                          unformat_ip4_address, &v4address, &address_length))
6801         v4_address_set = 1;
6802       else if (unformat (i, "%U/%d",
6803                          unformat_ip6_address, &v6address, &address_length))
6804         v6_address_set = 1;
6805       else
6806         break;
6807     }
6808
6809   if (sw_if_index_set == 0)
6810     {
6811       errmsg ("missing interface name or sw_if_index");
6812       return -99;
6813     }
6814   if (v4_address_set && v6_address_set)
6815     {
6816       errmsg ("both v4 and v6 addresses set");
6817       return -99;
6818     }
6819   if (!v4_address_set && !v6_address_set && !del_all)
6820     {
6821       errmsg ("no addresses set");
6822       return -99;
6823     }
6824
6825   /* Construct the API message */
6826   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6827
6828   mp->sw_if_index = ntohl (sw_if_index);
6829   mp->is_add = is_add;
6830   mp->del_all = del_all;
6831   if (v6_address_set)
6832     {
6833       mp->is_ipv6 = 1;
6834       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6835     }
6836   else
6837     {
6838       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6839     }
6840   mp->address_length = address_length;
6841
6842   /* send it... */
6843   S (mp);
6844
6845   /* Wait for a reply, return good/bad news  */
6846   W (ret);
6847   return ret;
6848 }
6849
6850 static int
6851 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6852 {
6853   unformat_input_t *i = vam->input;
6854   vl_api_sw_interface_set_mpls_enable_t *mp;
6855   u32 sw_if_index;
6856   u8 sw_if_index_set = 0;
6857   u8 enable = 1;
6858   int ret;
6859
6860   /* Parse args required to build the message */
6861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6862     {
6863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6864         sw_if_index_set = 1;
6865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "disable"))
6868         enable = 0;
6869       else if (unformat (i, "dis"))
6870         enable = 0;
6871       else
6872         break;
6873     }
6874
6875   if (sw_if_index_set == 0)
6876     {
6877       errmsg ("missing interface name or sw_if_index");
6878       return -99;
6879     }
6880
6881   /* Construct the API message */
6882   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6883
6884   mp->sw_if_index = ntohl (sw_if_index);
6885   mp->enable = enable;
6886
6887   /* send it... */
6888   S (mp);
6889
6890   /* Wait for a reply... */
6891   W (ret);
6892   return ret;
6893 }
6894
6895 static int
6896 api_sw_interface_set_table (vat_main_t * vam)
6897 {
6898   unformat_input_t *i = vam->input;
6899   vl_api_sw_interface_set_table_t *mp;
6900   u32 sw_if_index, vrf_id = 0;
6901   u8 sw_if_index_set = 0;
6902   u8 is_ipv6 = 0;
6903   int ret;
6904
6905   /* Parse args required to build the message */
6906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907     {
6908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6909         sw_if_index_set = 1;
6910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6911         sw_if_index_set = 1;
6912       else if (unformat (i, "vrf %d", &vrf_id))
6913         ;
6914       else if (unformat (i, "ipv6"))
6915         is_ipv6 = 1;
6916       else
6917         break;
6918     }
6919
6920   if (sw_if_index_set == 0)
6921     {
6922       errmsg ("missing interface name or sw_if_index");
6923       return -99;
6924     }
6925
6926   /* Construct the API message */
6927   M (SW_INTERFACE_SET_TABLE, mp);
6928
6929   mp->sw_if_index = ntohl (sw_if_index);
6930   mp->is_ipv6 = is_ipv6;
6931   mp->vrf_id = ntohl (vrf_id);
6932
6933   /* send it... */
6934   S (mp);
6935
6936   /* Wait for a reply... */
6937   W (ret);
6938   return ret;
6939 }
6940
6941 static void vl_api_sw_interface_get_table_reply_t_handler
6942   (vl_api_sw_interface_get_table_reply_t * mp)
6943 {
6944   vat_main_t *vam = &vat_main;
6945
6946   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6947
6948   vam->retval = ntohl (mp->retval);
6949   vam->result_ready = 1;
6950
6951 }
6952
6953 static void vl_api_sw_interface_get_table_reply_t_handler_json
6954   (vl_api_sw_interface_get_table_reply_t * mp)
6955 {
6956   vat_main_t *vam = &vat_main;
6957   vat_json_node_t node;
6958
6959   vat_json_init_object (&node);
6960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6961   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6962
6963   vat_json_print (vam->ofp, &node);
6964   vat_json_free (&node);
6965
6966   vam->retval = ntohl (mp->retval);
6967   vam->result_ready = 1;
6968 }
6969
6970 static int
6971 api_sw_interface_get_table (vat_main_t * vam)
6972 {
6973   unformat_input_t *i = vam->input;
6974   vl_api_sw_interface_get_table_t *mp;
6975   u32 sw_if_index;
6976   u8 sw_if_index_set = 0;
6977   u8 is_ipv6 = 0;
6978   int ret;
6979
6980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6981     {
6982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6983         sw_if_index_set = 1;
6984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6985         sw_if_index_set = 1;
6986       else if (unformat (i, "ipv6"))
6987         is_ipv6 = 1;
6988       else
6989         break;
6990     }
6991
6992   if (sw_if_index_set == 0)
6993     {
6994       errmsg ("missing interface name or sw_if_index");
6995       return -99;
6996     }
6997
6998   M (SW_INTERFACE_GET_TABLE, mp);
6999   mp->sw_if_index = htonl (sw_if_index);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S (mp);
7003   W (ret);
7004   return ret;
7005 }
7006
7007 static int
7008 api_sw_interface_set_vpath (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_sw_interface_set_vpath_t *mp;
7012   u32 sw_if_index = 0;
7013   u8 sw_if_index_set = 0;
7014   u8 is_enable = 0;
7015   int ret;
7016
7017   /* Parse args required to build the message */
7018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7019     {
7020       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7021         sw_if_index_set = 1;
7022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7023         sw_if_index_set = 1;
7024       else if (unformat (i, "enable"))
7025         is_enable = 1;
7026       else if (unformat (i, "disable"))
7027         is_enable = 0;
7028       else
7029         break;
7030     }
7031
7032   if (sw_if_index_set == 0)
7033     {
7034       errmsg ("missing interface name or sw_if_index");
7035       return -99;
7036     }
7037
7038   /* Construct the API message */
7039   M (SW_INTERFACE_SET_VPATH, mp);
7040
7041   mp->sw_if_index = ntohl (sw_if_index);
7042   mp->enable = is_enable;
7043
7044   /* send it... */
7045   S (mp);
7046
7047   /* Wait for a reply... */
7048   W (ret);
7049   return ret;
7050 }
7051
7052 static int
7053 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7054 {
7055   unformat_input_t *i = vam->input;
7056   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7057   u32 sw_if_index = 0;
7058   u8 sw_if_index_set = 0;
7059   u8 is_enable = 1;
7060   u8 is_ipv6 = 0;
7061   int ret;
7062
7063   /* Parse args required to build the message */
7064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7065     {
7066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7067         sw_if_index_set = 1;
7068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7069         sw_if_index_set = 1;
7070       else if (unformat (i, "enable"))
7071         is_enable = 1;
7072       else if (unformat (i, "disable"))
7073         is_enable = 0;
7074       else if (unformat (i, "ip4"))
7075         is_ipv6 = 0;
7076       else if (unformat (i, "ip6"))
7077         is_ipv6 = 1;
7078       else
7079         break;
7080     }
7081
7082   if (sw_if_index_set == 0)
7083     {
7084       errmsg ("missing interface name or sw_if_index");
7085       return -99;
7086     }
7087
7088   /* Construct the API message */
7089   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7090
7091   mp->sw_if_index = ntohl (sw_if_index);
7092   mp->enable = is_enable;
7093   mp->is_ipv6 = is_ipv6;
7094
7095   /* send it... */
7096   S (mp);
7097
7098   /* Wait for a reply... */
7099   W (ret);
7100   return ret;
7101 }
7102
7103 static int
7104 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_sw_interface_set_geneve_bypass_t *mp;
7108   u32 sw_if_index = 0;
7109   u8 sw_if_index_set = 0;
7110   u8 is_enable = 1;
7111   u8 is_ipv6 = 0;
7112   int ret;
7113
7114   /* Parse args required to build the message */
7115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7116     {
7117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7118         sw_if_index_set = 1;
7119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7120         sw_if_index_set = 1;
7121       else if (unformat (i, "enable"))
7122         is_enable = 1;
7123       else if (unformat (i, "disable"))
7124         is_enable = 0;
7125       else if (unformat (i, "ip4"))
7126         is_ipv6 = 0;
7127       else if (unformat (i, "ip6"))
7128         is_ipv6 = 1;
7129       else
7130         break;
7131     }
7132
7133   if (sw_if_index_set == 0)
7134     {
7135       errmsg ("missing interface name or sw_if_index");
7136       return -99;
7137     }
7138
7139   /* Construct the API message */
7140   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7141
7142   mp->sw_if_index = ntohl (sw_if_index);
7143   mp->enable = is_enable;
7144   mp->is_ipv6 = is_ipv6;
7145
7146   /* send it... */
7147   S (mp);
7148
7149   /* Wait for a reply... */
7150   W (ret);
7151   return ret;
7152 }
7153
7154 static int
7155 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7156 {
7157   unformat_input_t *i = vam->input;
7158   vl_api_sw_interface_set_l2_xconnect_t *mp;
7159   u32 rx_sw_if_index;
7160   u8 rx_sw_if_index_set = 0;
7161   u32 tx_sw_if_index;
7162   u8 tx_sw_if_index_set = 0;
7163   u8 enable = 1;
7164   int ret;
7165
7166   /* Parse args required to build the message */
7167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7168     {
7169       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7170         rx_sw_if_index_set = 1;
7171       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7172         tx_sw_if_index_set = 1;
7173       else if (unformat (i, "rx"))
7174         {
7175           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7176             {
7177               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7178                             &rx_sw_if_index))
7179                 rx_sw_if_index_set = 1;
7180             }
7181           else
7182             break;
7183         }
7184       else if (unformat (i, "tx"))
7185         {
7186           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7187             {
7188               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7189                             &tx_sw_if_index))
7190                 tx_sw_if_index_set = 1;
7191             }
7192           else
7193             break;
7194         }
7195       else if (unformat (i, "enable"))
7196         enable = 1;
7197       else if (unformat (i, "disable"))
7198         enable = 0;
7199       else
7200         break;
7201     }
7202
7203   if (rx_sw_if_index_set == 0)
7204     {
7205       errmsg ("missing rx interface name or rx_sw_if_index");
7206       return -99;
7207     }
7208
7209   if (enable && (tx_sw_if_index_set == 0))
7210     {
7211       errmsg ("missing tx interface name or tx_sw_if_index");
7212       return -99;
7213     }
7214
7215   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7216
7217   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7218   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7219   mp->enable = enable;
7220
7221   S (mp);
7222   W (ret);
7223   return ret;
7224 }
7225
7226 static int
7227 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7228 {
7229   unformat_input_t *i = vam->input;
7230   vl_api_sw_interface_set_l2_bridge_t *mp;
7231   u32 rx_sw_if_index;
7232   u8 rx_sw_if_index_set = 0;
7233   u32 bd_id;
7234   u8 bd_id_set = 0;
7235   u8 bvi = 0;
7236   u32 shg = 0;
7237   u8 enable = 1;
7238   int ret;
7239
7240   /* Parse args required to build the message */
7241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7242     {
7243       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7244         rx_sw_if_index_set = 1;
7245       else if (unformat (i, "bd_id %d", &bd_id))
7246         bd_id_set = 1;
7247       else
7248         if (unformat
7249             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7250         rx_sw_if_index_set = 1;
7251       else if (unformat (i, "shg %d", &shg))
7252         ;
7253       else if (unformat (i, "bvi"))
7254         bvi = 1;
7255       else if (unformat (i, "enable"))
7256         enable = 1;
7257       else if (unformat (i, "disable"))
7258         enable = 0;
7259       else
7260         break;
7261     }
7262
7263   if (rx_sw_if_index_set == 0)
7264     {
7265       errmsg ("missing rx interface name or sw_if_index");
7266       return -99;
7267     }
7268
7269   if (enable && (bd_id_set == 0))
7270     {
7271       errmsg ("missing bridge domain");
7272       return -99;
7273     }
7274
7275   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7276
7277   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7278   mp->bd_id = ntohl (bd_id);
7279   mp->shg = (u8) shg;
7280   mp->bvi = bvi;
7281   mp->enable = enable;
7282
7283   S (mp);
7284   W (ret);
7285   return ret;
7286 }
7287
7288 static int
7289 api_bridge_domain_dump (vat_main_t * vam)
7290 {
7291   unformat_input_t *i = vam->input;
7292   vl_api_bridge_domain_dump_t *mp;
7293   vl_api_control_ping_t *mp_ping;
7294   u32 bd_id = ~0;
7295   int ret;
7296
7297   /* Parse args required to build the message */
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "bd_id %d", &bd_id))
7301         ;
7302       else
7303         break;
7304     }
7305
7306   M (BRIDGE_DOMAIN_DUMP, mp);
7307   mp->bd_id = ntohl (bd_id);
7308   S (mp);
7309
7310   /* Use a control ping for synchronization */
7311   MPING (CONTROL_PING, mp_ping);
7312   S (mp_ping);
7313
7314   W (ret);
7315   return ret;
7316 }
7317
7318 static int
7319 api_bridge_domain_add_del (vat_main_t * vam)
7320 {
7321   unformat_input_t *i = vam->input;
7322   vl_api_bridge_domain_add_del_t *mp;
7323   u32 bd_id = ~0;
7324   u8 is_add = 1;
7325   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7326   u8 *bd_tag = NULL;
7327   u32 mac_age = 0;
7328   int ret;
7329
7330   /* Parse args required to build the message */
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "bd_id %d", &bd_id))
7334         ;
7335       else if (unformat (i, "flood %d", &flood))
7336         ;
7337       else if (unformat (i, "uu-flood %d", &uu_flood))
7338         ;
7339       else if (unformat (i, "forward %d", &forward))
7340         ;
7341       else if (unformat (i, "learn %d", &learn))
7342         ;
7343       else if (unformat (i, "arp-term %d", &arp_term))
7344         ;
7345       else if (unformat (i, "mac-age %d", &mac_age))
7346         ;
7347       else if (unformat (i, "bd-tag %s", &bd_tag))
7348         ;
7349       else if (unformat (i, "del"))
7350         {
7351           is_add = 0;
7352           flood = uu_flood = forward = learn = 0;
7353         }
7354       else
7355         break;
7356     }
7357
7358   if (bd_id == ~0)
7359     {
7360       errmsg ("missing bridge domain");
7361       ret = -99;
7362       goto done;
7363     }
7364
7365   if (mac_age > 255)
7366     {
7367       errmsg ("mac age must be less than 256 ");
7368       ret = -99;
7369       goto done;
7370     }
7371
7372   if ((bd_tag) && (vec_len (bd_tag) > 63))
7373     {
7374       errmsg ("bd-tag cannot be longer than 63");
7375       ret = -99;
7376       goto done;
7377     }
7378
7379   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7380
7381   mp->bd_id = ntohl (bd_id);
7382   mp->flood = flood;
7383   mp->uu_flood = uu_flood;
7384   mp->forward = forward;
7385   mp->learn = learn;
7386   mp->arp_term = arp_term;
7387   mp->is_add = is_add;
7388   mp->mac_age = (u8) mac_age;
7389   if (bd_tag)
7390     {
7391       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7392       mp->bd_tag[vec_len (bd_tag)] = 0;
7393     }
7394   S (mp);
7395   W (ret);
7396
7397 done:
7398   vec_free (bd_tag);
7399   return ret;
7400 }
7401
7402 static int
7403 api_l2fib_flush_bd (vat_main_t * vam)
7404 {
7405   unformat_input_t *i = vam->input;
7406   vl_api_l2fib_flush_bd_t *mp;
7407   u32 bd_id = ~0;
7408   int ret;
7409
7410   /* Parse args required to build the message */
7411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7412     {
7413       if (unformat (i, "bd_id %d", &bd_id));
7414       else
7415         break;
7416     }
7417
7418   if (bd_id == ~0)
7419     {
7420       errmsg ("missing bridge domain");
7421       return -99;
7422     }
7423
7424   M (L2FIB_FLUSH_BD, mp);
7425
7426   mp->bd_id = htonl (bd_id);
7427
7428   S (mp);
7429   W (ret);
7430   return ret;
7431 }
7432
7433 static int
7434 api_l2fib_flush_int (vat_main_t * vam)
7435 {
7436   unformat_input_t *i = vam->input;
7437   vl_api_l2fib_flush_int_t *mp;
7438   u32 sw_if_index = ~0;
7439   int ret;
7440
7441   /* Parse args required to build the message */
7442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7443     {
7444       if (unformat (i, "sw_if_index %d", &sw_if_index));
7445       else
7446         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7447       else
7448         break;
7449     }
7450
7451   if (sw_if_index == ~0)
7452     {
7453       errmsg ("missing interface name or sw_if_index");
7454       return -99;
7455     }
7456
7457   M (L2FIB_FLUSH_INT, mp);
7458
7459   mp->sw_if_index = ntohl (sw_if_index);
7460
7461   S (mp);
7462   W (ret);
7463   return ret;
7464 }
7465
7466 static int
7467 api_l2fib_add_del (vat_main_t * vam)
7468 {
7469   unformat_input_t *i = vam->input;
7470   vl_api_l2fib_add_del_t *mp;
7471   f64 timeout;
7472   u8 mac[6] = { 0 };
7473   u8 mac_set = 0;
7474   u32 bd_id;
7475   u8 bd_id_set = 0;
7476   u32 sw_if_index = ~0;
7477   u8 sw_if_index_set = 0;
7478   u8 is_add = 1;
7479   u8 static_mac = 0;
7480   u8 filter_mac = 0;
7481   u8 bvi_mac = 0;
7482   int count = 1;
7483   f64 before = 0;
7484   int j;
7485
7486   /* Parse args required to build the message */
7487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7488     {
7489       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7490         mac_set = 1;
7491       else if (unformat (i, "bd_id %d", &bd_id))
7492         bd_id_set = 1;
7493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7494         sw_if_index_set = 1;
7495       else if (unformat (i, "sw_if"))
7496         {
7497           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498             {
7499               if (unformat
7500                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7501                 sw_if_index_set = 1;
7502             }
7503           else
7504             break;
7505         }
7506       else if (unformat (i, "static"))
7507         static_mac = 1;
7508       else if (unformat (i, "filter"))
7509         {
7510           filter_mac = 1;
7511           static_mac = 1;
7512         }
7513       else if (unformat (i, "bvi"))
7514         {
7515           bvi_mac = 1;
7516           static_mac = 1;
7517         }
7518       else if (unformat (i, "del"))
7519         is_add = 0;
7520       else if (unformat (i, "count %d", &count))
7521         ;
7522       else
7523         break;
7524     }
7525
7526   if (mac_set == 0)
7527     {
7528       errmsg ("missing mac address");
7529       return -99;
7530     }
7531
7532   if (bd_id_set == 0)
7533     {
7534       errmsg ("missing bridge domain");
7535       return -99;
7536     }
7537
7538   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7539     {
7540       errmsg ("missing interface name or sw_if_index");
7541       return -99;
7542     }
7543
7544   if (count > 1)
7545     {
7546       /* Turn on async mode */
7547       vam->async_mode = 1;
7548       vam->async_errors = 0;
7549       before = vat_time_now (vam);
7550     }
7551
7552   for (j = 0; j < count; j++)
7553     {
7554       M (L2FIB_ADD_DEL, mp);
7555
7556       clib_memcpy (mp->mac, mac, 6);
7557       mp->bd_id = ntohl (bd_id);
7558       mp->is_add = is_add;
7559
7560       if (is_add)
7561         {
7562           mp->sw_if_index = ntohl (sw_if_index);
7563           mp->static_mac = static_mac;
7564           mp->filter_mac = filter_mac;
7565           mp->bvi_mac = bvi_mac;
7566         }
7567       increment_mac_address (mac);
7568       /* send it... */
7569       S (mp);
7570     }
7571
7572   if (count > 1)
7573     {
7574       vl_api_control_ping_t *mp_ping;
7575       f64 after;
7576
7577       /* Shut off async mode */
7578       vam->async_mode = 0;
7579
7580       MPING (CONTROL_PING, mp_ping);
7581       S (mp_ping);
7582
7583       timeout = vat_time_now (vam) + 1.0;
7584       while (vat_time_now (vam) < timeout)
7585         if (vam->result_ready == 1)
7586           goto out;
7587       vam->retval = -99;
7588
7589     out:
7590       if (vam->retval == -99)
7591         errmsg ("timeout");
7592
7593       if (vam->async_errors > 0)
7594         {
7595           errmsg ("%d asynchronous errors", vam->async_errors);
7596           vam->retval = -98;
7597         }
7598       vam->async_errors = 0;
7599       after = vat_time_now (vam);
7600
7601       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7602              count, after - before, count / (after - before));
7603     }
7604   else
7605     {
7606       int ret;
7607
7608       /* Wait for a reply... */
7609       W (ret);
7610       return ret;
7611     }
7612   /* Return the good/bad news */
7613   return (vam->retval);
7614 }
7615
7616 static int
7617 api_bridge_domain_set_mac_age (vat_main_t * vam)
7618 {
7619   unformat_input_t *i = vam->input;
7620   vl_api_bridge_domain_set_mac_age_t *mp;
7621   u32 bd_id = ~0;
7622   u32 mac_age = 0;
7623   int ret;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "bd_id %d", &bd_id));
7629       else if (unformat (i, "mac-age %d", &mac_age));
7630       else
7631         break;
7632     }
7633
7634   if (bd_id == ~0)
7635     {
7636       errmsg ("missing bridge domain");
7637       return -99;
7638     }
7639
7640   if (mac_age > 255)
7641     {
7642       errmsg ("mac age must be less than 256 ");
7643       return -99;
7644     }
7645
7646   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7647
7648   mp->bd_id = htonl (bd_id);
7649   mp->mac_age = (u8) mac_age;
7650
7651   S (mp);
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_l2_flags (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_l2_flags_t *mp;
7661   u32 sw_if_index;
7662   u32 flags = 0;
7663   u8 sw_if_index_set = 0;
7664   u8 is_set = 0;
7665   int ret;
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "sw_if_index %d", &sw_if_index))
7671         sw_if_index_set = 1;
7672       else if (unformat (i, "sw_if"))
7673         {
7674           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675             {
7676               if (unformat
7677                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7678                 sw_if_index_set = 1;
7679             }
7680           else
7681             break;
7682         }
7683       else if (unformat (i, "learn"))
7684         flags |= L2_LEARN;
7685       else if (unformat (i, "forward"))
7686         flags |= L2_FWD;
7687       else if (unformat (i, "flood"))
7688         flags |= L2_FLOOD;
7689       else if (unformat (i, "uu-flood"))
7690         flags |= L2_UU_FLOOD;
7691       else if (unformat (i, "arp-term"))
7692         flags |= L2_ARP_TERM;
7693       else if (unformat (i, "off"))
7694         is_set = 0;
7695       else if (unformat (i, "disable"))
7696         is_set = 0;
7697       else
7698         break;
7699     }
7700
7701   if (sw_if_index_set == 0)
7702     {
7703       errmsg ("missing interface name or sw_if_index");
7704       return -99;
7705     }
7706
7707   M (L2_FLAGS, mp);
7708
7709   mp->sw_if_index = ntohl (sw_if_index);
7710   mp->feature_bitmap = ntohl (flags);
7711   mp->is_set = is_set;
7712
7713   S (mp);
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_bridge_flags (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_bridge_flags_t *mp;
7723   u32 bd_id;
7724   u8 bd_id_set = 0;
7725   u8 is_set = 1;
7726   u32 flags = 0;
7727   int ret;
7728
7729   /* Parse args required to build the message */
7730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7731     {
7732       if (unformat (i, "bd_id %d", &bd_id))
7733         bd_id_set = 1;
7734       else if (unformat (i, "learn"))
7735         flags |= L2_LEARN;
7736       else if (unformat (i, "forward"))
7737         flags |= L2_FWD;
7738       else if (unformat (i, "flood"))
7739         flags |= L2_FLOOD;
7740       else if (unformat (i, "uu-flood"))
7741         flags |= L2_UU_FLOOD;
7742       else if (unformat (i, "arp-term"))
7743         flags |= L2_ARP_TERM;
7744       else if (unformat (i, "off"))
7745         is_set = 0;
7746       else if (unformat (i, "disable"))
7747         is_set = 0;
7748       else
7749         break;
7750     }
7751
7752   if (bd_id_set == 0)
7753     {
7754       errmsg ("missing bridge domain");
7755       return -99;
7756     }
7757
7758   M (BRIDGE_FLAGS, mp);
7759
7760   mp->bd_id = ntohl (bd_id);
7761   mp->feature_bitmap = ntohl (flags);
7762   mp->is_set = is_set;
7763
7764   S (mp);
7765   W (ret);
7766   return ret;
7767 }
7768
7769 static int
7770 api_bd_ip_mac_add_del (vat_main_t * vam)
7771 {
7772   unformat_input_t *i = vam->input;
7773   vl_api_bd_ip_mac_add_del_t *mp;
7774   u32 bd_id;
7775   u8 is_ipv6 = 0;
7776   u8 is_add = 1;
7777   u8 bd_id_set = 0;
7778   u8 ip_set = 0;
7779   u8 mac_set = 0;
7780   ip4_address_t v4addr;
7781   ip6_address_t v6addr;
7782   u8 macaddr[6];
7783   int ret;
7784
7785
7786   /* Parse args required to build the message */
7787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7788     {
7789       if (unformat (i, "bd_id %d", &bd_id))
7790         {
7791           bd_id_set++;
7792         }
7793       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7794         {
7795           ip_set++;
7796         }
7797       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7798         {
7799           ip_set++;
7800           is_ipv6++;
7801         }
7802       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7803         {
7804           mac_set++;
7805         }
7806       else if (unformat (i, "del"))
7807         is_add = 0;
7808       else
7809         break;
7810     }
7811
7812   if (bd_id_set == 0)
7813     {
7814       errmsg ("missing bridge domain");
7815       return -99;
7816     }
7817   else if (ip_set == 0)
7818     {
7819       errmsg ("missing IP address");
7820       return -99;
7821     }
7822   else if (mac_set == 0)
7823     {
7824       errmsg ("missing MAC address");
7825       return -99;
7826     }
7827
7828   M (BD_IP_MAC_ADD_DEL, mp);
7829
7830   mp->bd_id = ntohl (bd_id);
7831   mp->is_ipv6 = is_ipv6;
7832   mp->is_add = is_add;
7833   if (is_ipv6)
7834     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7835   else
7836     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7837   clib_memcpy (mp->mac_address, macaddr, 6);
7838   S (mp);
7839   W (ret);
7840   return ret;
7841 }
7842
7843 static int
7844 api_tap_connect (vat_main_t * vam)
7845 {
7846   unformat_input_t *i = vam->input;
7847   vl_api_tap_connect_t *mp;
7848   u8 mac_address[6];
7849   u8 random_mac = 1;
7850   u8 name_set = 0;
7851   u8 *tap_name;
7852   u8 *tag = 0;
7853   ip4_address_t ip4_address;
7854   u32 ip4_mask_width;
7855   int ip4_address_set = 0;
7856   ip6_address_t ip6_address;
7857   u32 ip6_mask_width;
7858   int ip6_address_set = 0;
7859   int ret;
7860
7861   memset (mac_address, 0, sizeof (mac_address));
7862
7863   /* Parse args required to build the message */
7864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7865     {
7866       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7867         {
7868           random_mac = 0;
7869         }
7870       else if (unformat (i, "random-mac"))
7871         random_mac = 1;
7872       else if (unformat (i, "tapname %s", &tap_name))
7873         name_set = 1;
7874       else if (unformat (i, "tag %s", &tag))
7875         ;
7876       else if (unformat (i, "address %U/%d",
7877                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7878         ip4_address_set = 1;
7879       else if (unformat (i, "address %U/%d",
7880                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7881         ip6_address_set = 1;
7882       else
7883         break;
7884     }
7885
7886   if (name_set == 0)
7887     {
7888       errmsg ("missing tap name");
7889       return -99;
7890     }
7891   if (vec_len (tap_name) > 63)
7892     {
7893       errmsg ("tap name too long");
7894       return -99;
7895     }
7896   vec_add1 (tap_name, 0);
7897
7898   if (vec_len (tag) > 63)
7899     {
7900       errmsg ("tag too long");
7901       return -99;
7902     }
7903
7904   /* Construct the API message */
7905   M (TAP_CONNECT, mp);
7906
7907   mp->use_random_mac = random_mac;
7908   clib_memcpy (mp->mac_address, mac_address, 6);
7909   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7910   if (tag)
7911     clib_memcpy (mp->tag, tag, vec_len (tag));
7912
7913   if (ip4_address_set)
7914     {
7915       mp->ip4_address_set = 1;
7916       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7917       mp->ip4_mask_width = ip4_mask_width;
7918     }
7919   if (ip6_address_set)
7920     {
7921       mp->ip6_address_set = 1;
7922       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7923       mp->ip6_mask_width = ip6_mask_width;
7924     }
7925
7926   vec_free (tap_name);
7927   vec_free (tag);
7928
7929   /* send it... */
7930   S (mp);
7931
7932   /* Wait for a reply... */
7933   W (ret);
7934   return ret;
7935 }
7936
7937 static int
7938 api_tap_modify (vat_main_t * vam)
7939 {
7940   unformat_input_t *i = vam->input;
7941   vl_api_tap_modify_t *mp;
7942   u8 mac_address[6];
7943   u8 random_mac = 1;
7944   u8 name_set = 0;
7945   u8 *tap_name;
7946   u32 sw_if_index = ~0;
7947   u8 sw_if_index_set = 0;
7948   int ret;
7949
7950   memset (mac_address, 0, sizeof (mac_address));
7951
7952   /* Parse args required to build the message */
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7956         sw_if_index_set = 1;
7957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7958         sw_if_index_set = 1;
7959       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7960         {
7961           random_mac = 0;
7962         }
7963       else if (unformat (i, "random-mac"))
7964         random_mac = 1;
7965       else if (unformat (i, "tapname %s", &tap_name))
7966         name_set = 1;
7967       else
7968         break;
7969     }
7970
7971   if (sw_if_index_set == 0)
7972     {
7973       errmsg ("missing vpp interface name");
7974       return -99;
7975     }
7976   if (name_set == 0)
7977     {
7978       errmsg ("missing tap name");
7979       return -99;
7980     }
7981   if (vec_len (tap_name) > 63)
7982     {
7983       errmsg ("tap name too long");
7984     }
7985   vec_add1 (tap_name, 0);
7986
7987   /* Construct the API message */
7988   M (TAP_MODIFY, mp);
7989
7990   mp->use_random_mac = random_mac;
7991   mp->sw_if_index = ntohl (sw_if_index);
7992   clib_memcpy (mp->mac_address, mac_address, 6);
7993   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7994   vec_free (tap_name);
7995
7996   /* send it... */
7997   S (mp);
7998
7999   /* Wait for a reply... */
8000   W (ret);
8001   return ret;
8002 }
8003
8004 static int
8005 api_tap_delete (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_tap_delete_t *mp;
8009   u32 sw_if_index = ~0;
8010   u8 sw_if_index_set = 0;
8011   int ret;
8012
8013   /* Parse args required to build the message */
8014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8017         sw_if_index_set = 1;
8018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8019         sw_if_index_set = 1;
8020       else
8021         break;
8022     }
8023
8024   if (sw_if_index_set == 0)
8025     {
8026       errmsg ("missing vpp interface name");
8027       return -99;
8028     }
8029
8030   /* Construct the API message */
8031   M (TAP_DELETE, mp);
8032
8033   mp->sw_if_index = ntohl (sw_if_index);
8034
8035   /* send it... */
8036   S (mp);
8037
8038   /* Wait for a reply... */
8039   W (ret);
8040   return ret;
8041 }
8042
8043 static int
8044 api_tap_create_v2 (vat_main_t * vam)
8045 {
8046   unformat_input_t *i = vam->input;
8047   vl_api_tap_create_v2_t *mp;
8048   u8 mac_address[6];
8049   u8 random_mac = 1;
8050   u32 id = ~0;
8051   u8 *host_if_name = 0;
8052   u8 *host_ns = 0;
8053   u8 host_mac_addr[6];
8054   u8 host_mac_addr_set = 0;
8055   u8 *host_bridge = 0;
8056   ip4_address_t host_ip4_addr;
8057   ip4_address_t host_ip4_gw;
8058   u8 host_ip4_gw_set = 0;
8059   u32 host_ip4_prefix_len = 0;
8060   ip6_address_t host_ip6_addr;
8061   ip6_address_t host_ip6_gw;
8062   u8 host_ip6_gw_set = 0;
8063   u32 host_ip6_prefix_len = 0;
8064   int ret;
8065   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8066
8067   memset (mac_address, 0, sizeof (mac_address));
8068
8069   /* Parse args required to build the message */
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8073         {
8074           random_mac = 0;
8075         }
8076       else if (unformat (i, "id %u", &id))
8077         ;
8078       else if (unformat (i, "host-if-name %s", &host_if_name))
8079         ;
8080       else if (unformat (i, "host-ns %s", &host_ns))
8081         ;
8082       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8083                          host_mac_addr))
8084         host_mac_addr_set = 1;
8085       else if (unformat (i, "host-bridge %s", &host_bridge))
8086         ;
8087       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8088                          &host_ip4_addr, &host_ip4_prefix_len))
8089         ;
8090       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8091                          &host_ip6_addr, &host_ip6_prefix_len))
8092         ;
8093       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8094                          &host_ip4_gw))
8095         host_ip4_gw_set = 1;
8096       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8097                          &host_ip6_gw))
8098         host_ip6_gw_set = 1;
8099       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8100         ;
8101       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8102         ;
8103       else
8104         break;
8105     }
8106
8107   if (vec_len (host_if_name) > 63)
8108     {
8109       errmsg ("tap name too long. ");
8110       return -99;
8111     }
8112   if (vec_len (host_ns) > 63)
8113     {
8114       errmsg ("host name space too long. ");
8115       return -99;
8116     }
8117   if (vec_len (host_bridge) > 63)
8118     {
8119       errmsg ("host bridge name too long. ");
8120       return -99;
8121     }
8122   if (host_ip4_prefix_len > 32)
8123     {
8124       errmsg ("host ip4 prefix length not valid. ");
8125       return -99;
8126     }
8127   if (host_ip6_prefix_len > 128)
8128     {
8129       errmsg ("host ip6 prefix length not valid. ");
8130       return -99;
8131     }
8132   if (!is_pow2 (rx_ring_sz))
8133     {
8134       errmsg ("rx ring size must be power of 2. ");
8135       return -99;
8136     }
8137   if (rx_ring_sz > 32768)
8138     {
8139       errmsg ("rx ring size must be 32768 or lower. ");
8140       return -99;
8141     }
8142   if (!is_pow2 (tx_ring_sz))
8143     {
8144       errmsg ("tx ring size must be power of 2. ");
8145       return -99;
8146     }
8147   if (tx_ring_sz > 32768)
8148     {
8149       errmsg ("tx ring size must be 32768 or lower. ");
8150       return -99;
8151     }
8152
8153   /* Construct the API message */
8154   M (TAP_CREATE_V2, mp);
8155
8156   mp->use_random_mac = random_mac;
8157
8158   mp->id = ntohl (id);
8159   mp->host_namespace_set = host_ns != 0;
8160   mp->host_bridge_set = host_bridge != 0;
8161   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8162   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8163   mp->rx_ring_sz = ntohs (rx_ring_sz);
8164   mp->tx_ring_sz = ntohs (tx_ring_sz);
8165
8166   if (random_mac == 0)
8167     clib_memcpy (mp->mac_address, mac_address, 6);
8168   if (host_mac_addr_set)
8169     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8170   if (host_if_name)
8171     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8172   if (host_ns)
8173     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8174   if (host_bridge)
8175     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8176   if (host_ip4_prefix_len)
8177     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8178   if (host_ip4_prefix_len)
8179     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8180   if (host_ip4_gw_set)
8181     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8182   if (host_ip6_gw_set)
8183     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8184
8185   vec_free (host_ns);
8186   vec_free (host_if_name);
8187   vec_free (host_bridge);
8188
8189   /* send it... */
8190   S (mp);
8191
8192   /* Wait for a reply... */
8193   W (ret);
8194   return ret;
8195 }
8196
8197 static int
8198 api_tap_delete_v2 (vat_main_t * vam)
8199 {
8200   unformat_input_t *i = vam->input;
8201   vl_api_tap_delete_v2_t *mp;
8202   u32 sw_if_index = ~0;
8203   u8 sw_if_index_set = 0;
8204   int ret;
8205
8206   /* Parse args required to build the message */
8207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8208     {
8209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8210         sw_if_index_set = 1;
8211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8212         sw_if_index_set = 1;
8213       else
8214         break;
8215     }
8216
8217   if (sw_if_index_set == 0)
8218     {
8219       errmsg ("missing vpp interface name. ");
8220       return -99;
8221     }
8222
8223   /* Construct the API message */
8224   M (TAP_DELETE_V2, mp);
8225
8226   mp->sw_if_index = ntohl (sw_if_index);
8227
8228   /* send it... */
8229   S (mp);
8230
8231   /* Wait for a reply... */
8232   W (ret);
8233   return ret;
8234 }
8235
8236 static int
8237 api_bond_create (vat_main_t * vam)
8238 {
8239   unformat_input_t *i = vam->input;
8240   vl_api_bond_create_t *mp;
8241   u8 mac_address[6];
8242   u8 custom_mac = 0;
8243   int ret;
8244   u8 mode;
8245   u8 lb;
8246   u8 mode_is_set = 0;
8247
8248   memset (mac_address, 0, sizeof (mac_address));
8249   lb = BOND_LB_L2;
8250
8251   /* Parse args required to build the message */
8252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8253     {
8254       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8255         mode_is_set = 1;
8256       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8257                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8258         ;
8259       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8260                          mac_address))
8261         custom_mac = 1;
8262       else
8263         break;
8264     }
8265
8266   if (mode_is_set == 0)
8267     {
8268       errmsg ("Missing bond mode. ");
8269       return -99;
8270     }
8271
8272   /* Construct the API message */
8273   M (BOND_CREATE, mp);
8274
8275   mp->use_custom_mac = custom_mac;
8276
8277   mp->mode = mode;
8278   mp->lb = lb;
8279
8280   if (custom_mac)
8281     clib_memcpy (mp->mac_address, mac_address, 6);
8282
8283   /* send it... */
8284   S (mp);
8285
8286   /* Wait for a reply... */
8287   W (ret);
8288   return ret;
8289 }
8290
8291 static int
8292 api_bond_delete (vat_main_t * vam)
8293 {
8294   unformat_input_t *i = vam->input;
8295   vl_api_bond_delete_t *mp;
8296   u32 sw_if_index = ~0;
8297   u8 sw_if_index_set = 0;
8298   int ret;
8299
8300   /* Parse args required to build the message */
8301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8302     {
8303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8304         sw_if_index_set = 1;
8305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8306         sw_if_index_set = 1;
8307       else
8308         break;
8309     }
8310
8311   if (sw_if_index_set == 0)
8312     {
8313       errmsg ("missing vpp interface name. ");
8314       return -99;
8315     }
8316
8317   /* Construct the API message */
8318   M (BOND_DELETE, mp);
8319
8320   mp->sw_if_index = ntohl (sw_if_index);
8321
8322   /* send it... */
8323   S (mp);
8324
8325   /* Wait for a reply... */
8326   W (ret);
8327   return ret;
8328 }
8329
8330 static int
8331 api_bond_enslave (vat_main_t * vam)
8332 {
8333   unformat_input_t *i = vam->input;
8334   vl_api_bond_enslave_t *mp;
8335   u32 bond_sw_if_index;
8336   int ret;
8337   u8 is_passive;
8338   u8 is_long_timeout;
8339   u32 bond_sw_if_index_is_set = 0;
8340   u32 sw_if_index;
8341   u8 sw_if_index_is_set = 0;
8342
8343   /* Parse args required to build the message */
8344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8345     {
8346       if (unformat (i, "sw_if_index %d", &sw_if_index))
8347         sw_if_index_is_set = 1;
8348       else if (unformat (i, "bond %u", &bond_sw_if_index))
8349         bond_sw_if_index_is_set = 1;
8350       else if (unformat (i, "passive %d", &is_passive))
8351         ;
8352       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8353         ;
8354       else
8355         break;
8356     }
8357
8358   if (bond_sw_if_index_is_set == 0)
8359     {
8360       errmsg ("Missing bond sw_if_index. ");
8361       return -99;
8362     }
8363   if (sw_if_index_is_set == 0)
8364     {
8365       errmsg ("Missing slave sw_if_index. ");
8366       return -99;
8367     }
8368
8369   /* Construct the API message */
8370   M (BOND_ENSLAVE, mp);
8371
8372   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8373   mp->sw_if_index = ntohl (sw_if_index);
8374   mp->is_long_timeout = is_long_timeout;
8375   mp->is_passive = is_passive;
8376
8377   /* send it... */
8378   S (mp);
8379
8380   /* Wait for a reply... */
8381   W (ret);
8382   return ret;
8383 }
8384
8385 static int
8386 api_bond_detach_slave (vat_main_t * vam)
8387 {
8388   unformat_input_t *i = vam->input;
8389   vl_api_bond_detach_slave_t *mp;
8390   u32 sw_if_index = ~0;
8391   u8 sw_if_index_set = 0;
8392   int ret;
8393
8394   /* Parse args required to build the message */
8395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8398         sw_if_index_set = 1;
8399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8400         sw_if_index_set = 1;
8401       else
8402         break;
8403     }
8404
8405   if (sw_if_index_set == 0)
8406     {
8407       errmsg ("missing vpp interface name. ");
8408       return -99;
8409     }
8410
8411   /* Construct the API message */
8412   M (BOND_DETACH_SLAVE, mp);
8413
8414   mp->sw_if_index = ntohl (sw_if_index);
8415
8416   /* send it... */
8417   S (mp);
8418
8419   /* Wait for a reply... */
8420   W (ret);
8421   return ret;
8422 }
8423
8424 static int
8425 api_ip_table_add_del (vat_main_t * vam)
8426 {
8427   unformat_input_t *i = vam->input;
8428   vl_api_ip_table_add_del_t *mp;
8429   u32 table_id = ~0;
8430   u8 is_ipv6 = 0;
8431   u8 is_add = 1;
8432   int ret = 0;
8433
8434   /* Parse args required to build the message */
8435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (i, "ipv6"))
8438         is_ipv6 = 1;
8439       else if (unformat (i, "del"))
8440         is_add = 0;
8441       else if (unformat (i, "add"))
8442         is_add = 1;
8443       else if (unformat (i, "table %d", &table_id))
8444         ;
8445       else
8446         {
8447           clib_warning ("parse error '%U'", format_unformat_error, i);
8448           return -99;
8449         }
8450     }
8451
8452   if (~0 == table_id)
8453     {
8454       errmsg ("missing table-ID");
8455       return -99;
8456     }
8457
8458   /* Construct the API message */
8459   M (IP_TABLE_ADD_DEL, mp);
8460
8461   mp->table_id = ntohl (table_id);
8462   mp->is_ipv6 = is_ipv6;
8463   mp->is_add = is_add;
8464
8465   /* send it... */
8466   S (mp);
8467
8468   /* Wait for a reply... */
8469   W (ret);
8470
8471   return ret;
8472 }
8473
8474 static int
8475 api_ip_add_del_route (vat_main_t * vam)
8476 {
8477   unformat_input_t *i = vam->input;
8478   vl_api_ip_add_del_route_t *mp;
8479   u32 sw_if_index = ~0, vrf_id = 0;
8480   u8 is_ipv6 = 0;
8481   u8 is_local = 0, is_drop = 0;
8482   u8 is_unreach = 0, is_prohibit = 0;
8483   u8 is_add = 1;
8484   u32 next_hop_weight = 1;
8485   u8 is_multipath = 0;
8486   u8 address_set = 0;
8487   u8 address_length_set = 0;
8488   u32 next_hop_table_id = 0;
8489   u32 resolve_attempts = 0;
8490   u32 dst_address_length = 0;
8491   u8 next_hop_set = 0;
8492   ip4_address_t v4_dst_address, v4_next_hop_address;
8493   ip6_address_t v6_dst_address, v6_next_hop_address;
8494   int count = 1;
8495   int j;
8496   f64 before = 0;
8497   u32 random_add_del = 0;
8498   u32 *random_vector = 0;
8499   uword *random_hash;
8500   u32 random_seed = 0xdeaddabe;
8501   u32 classify_table_index = ~0;
8502   u8 is_classify = 0;
8503   u8 resolve_host = 0, resolve_attached = 0;
8504   mpls_label_t *next_hop_out_label_stack = NULL;
8505   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8506   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8507
8508   /* Parse args required to build the message */
8509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8510     {
8511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8512         ;
8513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8514         ;
8515       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8516         {
8517           address_set = 1;
8518           is_ipv6 = 0;
8519         }
8520       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8521         {
8522           address_set = 1;
8523           is_ipv6 = 1;
8524         }
8525       else if (unformat (i, "/%d", &dst_address_length))
8526         {
8527           address_length_set = 1;
8528         }
8529
8530       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8531                                          &v4_next_hop_address))
8532         {
8533           next_hop_set = 1;
8534         }
8535       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8536                                          &v6_next_hop_address))
8537         {
8538           next_hop_set = 1;
8539         }
8540       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8541         ;
8542       else if (unformat (i, "weight %d", &next_hop_weight))
8543         ;
8544       else if (unformat (i, "drop"))
8545         {
8546           is_drop = 1;
8547         }
8548       else if (unformat (i, "null-send-unreach"))
8549         {
8550           is_unreach = 1;
8551         }
8552       else if (unformat (i, "null-send-prohibit"))
8553         {
8554           is_prohibit = 1;
8555         }
8556       else if (unformat (i, "local"))
8557         {
8558           is_local = 1;
8559         }
8560       else if (unformat (i, "classify %d", &classify_table_index))
8561         {
8562           is_classify = 1;
8563         }
8564       else if (unformat (i, "del"))
8565         is_add = 0;
8566       else if (unformat (i, "add"))
8567         is_add = 1;
8568       else if (unformat (i, "resolve-via-host"))
8569         resolve_host = 1;
8570       else if (unformat (i, "resolve-via-attached"))
8571         resolve_attached = 1;
8572       else if (unformat (i, "multipath"))
8573         is_multipath = 1;
8574       else if (unformat (i, "vrf %d", &vrf_id))
8575         ;
8576       else if (unformat (i, "count %d", &count))
8577         ;
8578       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8579         ;
8580       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8581         ;
8582       else if (unformat (i, "out-label %d", &next_hop_out_label))
8583         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8584       else if (unformat (i, "via-label %d", &next_hop_via_label))
8585         ;
8586       else if (unformat (i, "random"))
8587         random_add_del = 1;
8588       else if (unformat (i, "seed %d", &random_seed))
8589         ;
8590       else
8591         {
8592           clib_warning ("parse error '%U'", format_unformat_error, i);
8593           return -99;
8594         }
8595     }
8596
8597   if (!next_hop_set && !is_drop && !is_local &&
8598       !is_classify && !is_unreach && !is_prohibit &&
8599       MPLS_LABEL_INVALID == next_hop_via_label)
8600     {
8601       errmsg
8602         ("next hop / local / drop / unreach / prohibit / classify not set");
8603       return -99;
8604     }
8605
8606   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8607     {
8608       errmsg ("next hop and next-hop via label set");
8609       return -99;
8610     }
8611   if (address_set == 0)
8612     {
8613       errmsg ("missing addresses");
8614       return -99;
8615     }
8616
8617   if (address_length_set == 0)
8618     {
8619       errmsg ("missing address length");
8620       return -99;
8621     }
8622
8623   /* Generate a pile of unique, random routes */
8624   if (random_add_del)
8625     {
8626       u32 this_random_address;
8627       random_hash = hash_create (count, sizeof (uword));
8628
8629       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8630       for (j = 0; j <= count; j++)
8631         {
8632           do
8633             {
8634               this_random_address = random_u32 (&random_seed);
8635               this_random_address =
8636                 clib_host_to_net_u32 (this_random_address);
8637             }
8638           while (hash_get (random_hash, this_random_address));
8639           vec_add1 (random_vector, this_random_address);
8640           hash_set (random_hash, this_random_address, 1);
8641         }
8642       hash_free (random_hash);
8643       v4_dst_address.as_u32 = random_vector[0];
8644     }
8645
8646   if (count > 1)
8647     {
8648       /* Turn on async mode */
8649       vam->async_mode = 1;
8650       vam->async_errors = 0;
8651       before = vat_time_now (vam);
8652     }
8653
8654   for (j = 0; j < count; j++)
8655     {
8656       /* Construct the API message */
8657       M2 (IP_ADD_DEL_ROUTE, mp,
8658           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8659
8660       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8661       mp->table_id = ntohl (vrf_id);
8662
8663       mp->is_add = is_add;
8664       mp->is_drop = is_drop;
8665       mp->is_unreach = is_unreach;
8666       mp->is_prohibit = is_prohibit;
8667       mp->is_ipv6 = is_ipv6;
8668       mp->is_local = is_local;
8669       mp->is_classify = is_classify;
8670       mp->is_multipath = is_multipath;
8671       mp->is_resolve_host = resolve_host;
8672       mp->is_resolve_attached = resolve_attached;
8673       mp->next_hop_weight = next_hop_weight;
8674       mp->dst_address_length = dst_address_length;
8675       mp->next_hop_table_id = ntohl (next_hop_table_id);
8676       mp->classify_table_index = ntohl (classify_table_index);
8677       mp->next_hop_via_label = ntohl (next_hop_via_label);
8678       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8679       if (0 != mp->next_hop_n_out_labels)
8680         {
8681           memcpy (mp->next_hop_out_label_stack,
8682                   next_hop_out_label_stack,
8683                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8684           vec_free (next_hop_out_label_stack);
8685         }
8686
8687       if (is_ipv6)
8688         {
8689           clib_memcpy (mp->dst_address, &v6_dst_address,
8690                        sizeof (v6_dst_address));
8691           if (next_hop_set)
8692             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8693                          sizeof (v6_next_hop_address));
8694           increment_v6_address (&v6_dst_address);
8695         }
8696       else
8697         {
8698           clib_memcpy (mp->dst_address, &v4_dst_address,
8699                        sizeof (v4_dst_address));
8700           if (next_hop_set)
8701             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8702                          sizeof (v4_next_hop_address));
8703           if (random_add_del)
8704             v4_dst_address.as_u32 = random_vector[j + 1];
8705           else
8706             increment_v4_address (&v4_dst_address);
8707         }
8708       /* send it... */
8709       S (mp);
8710       /* If we receive SIGTERM, stop now... */
8711       if (vam->do_exit)
8712         break;
8713     }
8714
8715   /* When testing multiple add/del ops, use a control-ping to sync */
8716   if (count > 1)
8717     {
8718       vl_api_control_ping_t *mp_ping;
8719       f64 after;
8720       f64 timeout;
8721
8722       /* Shut off async mode */
8723       vam->async_mode = 0;
8724
8725       MPING (CONTROL_PING, mp_ping);
8726       S (mp_ping);
8727
8728       timeout = vat_time_now (vam) + 1.0;
8729       while (vat_time_now (vam) < timeout)
8730         if (vam->result_ready == 1)
8731           goto out;
8732       vam->retval = -99;
8733
8734     out:
8735       if (vam->retval == -99)
8736         errmsg ("timeout");
8737
8738       if (vam->async_errors > 0)
8739         {
8740           errmsg ("%d asynchronous errors", vam->async_errors);
8741           vam->retval = -98;
8742         }
8743       vam->async_errors = 0;
8744       after = vat_time_now (vam);
8745
8746       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8747       if (j > 0)
8748         count = j;
8749
8750       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8751              count, after - before, count / (after - before));
8752     }
8753   else
8754     {
8755       int ret;
8756
8757       /* Wait for a reply... */
8758       W (ret);
8759       return ret;
8760     }
8761
8762   /* Return the good/bad news */
8763   return (vam->retval);
8764 }
8765
8766 static int
8767 api_ip_mroute_add_del (vat_main_t * vam)
8768 {
8769   unformat_input_t *i = vam->input;
8770   vl_api_ip_mroute_add_del_t *mp;
8771   u32 sw_if_index = ~0, vrf_id = 0;
8772   u8 is_ipv6 = 0;
8773   u8 is_local = 0;
8774   u8 is_add = 1;
8775   u8 address_set = 0;
8776   u32 grp_address_length = 0;
8777   ip4_address_t v4_grp_address, v4_src_address;
8778   ip6_address_t v6_grp_address, v6_src_address;
8779   mfib_itf_flags_t iflags = 0;
8780   mfib_entry_flags_t eflags = 0;
8781   int ret;
8782
8783   /* Parse args required to build the message */
8784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8785     {
8786       if (unformat (i, "sw_if_index %d", &sw_if_index))
8787         ;
8788       else if (unformat (i, "%U %U",
8789                          unformat_ip4_address, &v4_src_address,
8790                          unformat_ip4_address, &v4_grp_address))
8791         {
8792           grp_address_length = 64;
8793           address_set = 1;
8794           is_ipv6 = 0;
8795         }
8796       else if (unformat (i, "%U %U",
8797                          unformat_ip6_address, &v6_src_address,
8798                          unformat_ip6_address, &v6_grp_address))
8799         {
8800           grp_address_length = 256;
8801           address_set = 1;
8802           is_ipv6 = 1;
8803         }
8804       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8805         {
8806           memset (&v4_src_address, 0, sizeof (v4_src_address));
8807           grp_address_length = 32;
8808           address_set = 1;
8809           is_ipv6 = 0;
8810         }
8811       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8812         {
8813           memset (&v6_src_address, 0, sizeof (v6_src_address));
8814           grp_address_length = 128;
8815           address_set = 1;
8816           is_ipv6 = 1;
8817         }
8818       else if (unformat (i, "/%d", &grp_address_length))
8819         ;
8820       else if (unformat (i, "local"))
8821         {
8822           is_local = 1;
8823         }
8824       else if (unformat (i, "del"))
8825         is_add = 0;
8826       else if (unformat (i, "add"))
8827         is_add = 1;
8828       else if (unformat (i, "vrf %d", &vrf_id))
8829         ;
8830       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8831         ;
8832       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8833         ;
8834       else
8835         {
8836           clib_warning ("parse error '%U'", format_unformat_error, i);
8837           return -99;
8838         }
8839     }
8840
8841   if (address_set == 0)
8842     {
8843       errmsg ("missing addresses\n");
8844       return -99;
8845     }
8846
8847   /* Construct the API message */
8848   M (IP_MROUTE_ADD_DEL, mp);
8849
8850   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8851   mp->table_id = ntohl (vrf_id);
8852
8853   mp->is_add = is_add;
8854   mp->is_ipv6 = is_ipv6;
8855   mp->is_local = is_local;
8856   mp->itf_flags = ntohl (iflags);
8857   mp->entry_flags = ntohl (eflags);
8858   mp->grp_address_length = grp_address_length;
8859   mp->grp_address_length = ntohs (mp->grp_address_length);
8860
8861   if (is_ipv6)
8862     {
8863       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8864       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8865     }
8866   else
8867     {
8868       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8869       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8870
8871     }
8872
8873   /* send it... */
8874   S (mp);
8875   /* Wait for a reply... */
8876   W (ret);
8877   return ret;
8878 }
8879
8880 static int
8881 api_mpls_table_add_del (vat_main_t * vam)
8882 {
8883   unformat_input_t *i = vam->input;
8884   vl_api_mpls_table_add_del_t *mp;
8885   u32 table_id = ~0;
8886   u8 is_add = 1;
8887   int ret = 0;
8888
8889   /* Parse args required to build the message */
8890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8891     {
8892       if (unformat (i, "table %d", &table_id))
8893         ;
8894       else if (unformat (i, "del"))
8895         is_add = 0;
8896       else if (unformat (i, "add"))
8897         is_add = 1;
8898       else
8899         {
8900           clib_warning ("parse error '%U'", format_unformat_error, i);
8901           return -99;
8902         }
8903     }
8904
8905   if (~0 == table_id)
8906     {
8907       errmsg ("missing table-ID");
8908       return -99;
8909     }
8910
8911   /* Construct the API message */
8912   M (MPLS_TABLE_ADD_DEL, mp);
8913
8914   mp->mt_table_id = ntohl (table_id);
8915   mp->mt_is_add = is_add;
8916
8917   /* send it... */
8918   S (mp);
8919
8920   /* Wait for a reply... */
8921   W (ret);
8922
8923   return ret;
8924 }
8925
8926 static int
8927 api_mpls_route_add_del (vat_main_t * vam)
8928 {
8929   unformat_input_t *i = vam->input;
8930   vl_api_mpls_route_add_del_t *mp;
8931   u32 sw_if_index = ~0, table_id = 0;
8932   u8 is_add = 1;
8933   u32 next_hop_weight = 1;
8934   u8 is_multipath = 0;
8935   u32 next_hop_table_id = 0;
8936   u8 next_hop_set = 0;
8937   ip4_address_t v4_next_hop_address = {
8938     .as_u32 = 0,
8939   };
8940   ip6_address_t v6_next_hop_address = { {0} };
8941   int count = 1;
8942   int j;
8943   f64 before = 0;
8944   u32 classify_table_index = ~0;
8945   u8 is_classify = 0;
8946   u8 resolve_host = 0, resolve_attached = 0;
8947   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8948   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8949   mpls_label_t *next_hop_out_label_stack = NULL;
8950   mpls_label_t local_label = MPLS_LABEL_INVALID;
8951   u8 is_eos = 0;
8952   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8953
8954   /* Parse args required to build the message */
8955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8956     {
8957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8958         ;
8959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8960         ;
8961       else if (unformat (i, "%d", &local_label))
8962         ;
8963       else if (unformat (i, "eos"))
8964         is_eos = 1;
8965       else if (unformat (i, "non-eos"))
8966         is_eos = 0;
8967       else if (unformat (i, "via %U", unformat_ip4_address,
8968                          &v4_next_hop_address))
8969         {
8970           next_hop_set = 1;
8971           next_hop_proto = DPO_PROTO_IP4;
8972         }
8973       else if (unformat (i, "via %U", unformat_ip6_address,
8974                          &v6_next_hop_address))
8975         {
8976           next_hop_set = 1;
8977           next_hop_proto = DPO_PROTO_IP6;
8978         }
8979       else if (unformat (i, "weight %d", &next_hop_weight))
8980         ;
8981       else if (unformat (i, "classify %d", &classify_table_index))
8982         {
8983           is_classify = 1;
8984         }
8985       else if (unformat (i, "del"))
8986         is_add = 0;
8987       else if (unformat (i, "add"))
8988         is_add = 1;
8989       else if (unformat (i, "resolve-via-host"))
8990         resolve_host = 1;
8991       else if (unformat (i, "resolve-via-attached"))
8992         resolve_attached = 1;
8993       else if (unformat (i, "multipath"))
8994         is_multipath = 1;
8995       else if (unformat (i, "count %d", &count))
8996         ;
8997       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8998         {
8999           next_hop_set = 1;
9000           next_hop_proto = DPO_PROTO_IP4;
9001         }
9002       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
9003         {
9004           next_hop_set = 1;
9005           next_hop_proto = DPO_PROTO_IP6;
9006         }
9007       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9008         ;
9009       else if (unformat (i, "via-label %d", &next_hop_via_label))
9010         ;
9011       else if (unformat (i, "out-label %d", &next_hop_out_label))
9012         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
9013       else
9014         {
9015           clib_warning ("parse error '%U'", format_unformat_error, i);
9016           return -99;
9017         }
9018     }
9019
9020   if (!next_hop_set && !is_classify)
9021     {
9022       errmsg ("next hop / classify not set");
9023       return -99;
9024     }
9025
9026   if (MPLS_LABEL_INVALID == local_label)
9027     {
9028       errmsg ("missing label");
9029       return -99;
9030     }
9031
9032   if (count > 1)
9033     {
9034       /* Turn on async mode */
9035       vam->async_mode = 1;
9036       vam->async_errors = 0;
9037       before = vat_time_now (vam);
9038     }
9039
9040   for (j = 0; j < count; j++)
9041     {
9042       /* Construct the API message */
9043       M2 (MPLS_ROUTE_ADD_DEL, mp,
9044           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
9045
9046       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9047       mp->mr_table_id = ntohl (table_id);
9048
9049       mp->mr_is_add = is_add;
9050       mp->mr_next_hop_proto = next_hop_proto;
9051       mp->mr_is_classify = is_classify;
9052       mp->mr_is_multipath = is_multipath;
9053       mp->mr_is_resolve_host = resolve_host;
9054       mp->mr_is_resolve_attached = resolve_attached;
9055       mp->mr_next_hop_weight = next_hop_weight;
9056       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9057       mp->mr_classify_table_index = ntohl (classify_table_index);
9058       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9059       mp->mr_label = ntohl (local_label);
9060       mp->mr_eos = is_eos;
9061
9062       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9063       if (0 != mp->mr_next_hop_n_out_labels)
9064         {
9065           memcpy (mp->mr_next_hop_out_label_stack,
9066                   next_hop_out_label_stack,
9067                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
9068           vec_free (next_hop_out_label_stack);
9069         }
9070
9071       if (next_hop_set)
9072         {
9073           if (DPO_PROTO_IP4 == next_hop_proto)
9074             {
9075               clib_memcpy (mp->mr_next_hop,
9076                            &v4_next_hop_address,
9077                            sizeof (v4_next_hop_address));
9078             }
9079           else if (DPO_PROTO_IP6 == next_hop_proto)
9080
9081             {
9082               clib_memcpy (mp->mr_next_hop,
9083                            &v6_next_hop_address,
9084                            sizeof (v6_next_hop_address));
9085             }
9086         }
9087       local_label++;
9088
9089       /* send it... */
9090       S (mp);
9091       /* If we receive SIGTERM, stop now... */
9092       if (vam->do_exit)
9093         break;
9094     }
9095
9096   /* When testing multiple add/del ops, use a control-ping to sync */
9097   if (count > 1)
9098     {
9099       vl_api_control_ping_t *mp_ping;
9100       f64 after;
9101       f64 timeout;
9102
9103       /* Shut off async mode */
9104       vam->async_mode = 0;
9105
9106       MPING (CONTROL_PING, mp_ping);
9107       S (mp_ping);
9108
9109       timeout = vat_time_now (vam) + 1.0;
9110       while (vat_time_now (vam) < timeout)
9111         if (vam->result_ready == 1)
9112           goto out;
9113       vam->retval = -99;
9114
9115     out:
9116       if (vam->retval == -99)
9117         errmsg ("timeout");
9118
9119       if (vam->async_errors > 0)
9120         {
9121           errmsg ("%d asynchronous errors", vam->async_errors);
9122           vam->retval = -98;
9123         }
9124       vam->async_errors = 0;
9125       after = vat_time_now (vam);
9126
9127       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9128       if (j > 0)
9129         count = j;
9130
9131       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9132              count, after - before, count / (after - before));
9133     }
9134   else
9135     {
9136       int ret;
9137
9138       /* Wait for a reply... */
9139       W (ret);
9140       return ret;
9141     }
9142
9143   /* Return the good/bad news */
9144   return (vam->retval);
9145 }
9146
9147 static int
9148 api_mpls_ip_bind_unbind (vat_main_t * vam)
9149 {
9150   unformat_input_t *i = vam->input;
9151   vl_api_mpls_ip_bind_unbind_t *mp;
9152   u32 ip_table_id = 0;
9153   u8 is_bind = 1;
9154   u8 is_ip4 = 1;
9155   ip4_address_t v4_address;
9156   ip6_address_t v6_address;
9157   u32 address_length;
9158   u8 address_set = 0;
9159   mpls_label_t local_label = MPLS_LABEL_INVALID;
9160   int ret;
9161
9162   /* Parse args required to build the message */
9163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9164     {
9165       if (unformat (i, "%U/%d", unformat_ip4_address,
9166                     &v4_address, &address_length))
9167         {
9168           is_ip4 = 1;
9169           address_set = 1;
9170         }
9171       else if (unformat (i, "%U/%d", unformat_ip6_address,
9172                          &v6_address, &address_length))
9173         {
9174           is_ip4 = 0;
9175           address_set = 1;
9176         }
9177       else if (unformat (i, "%d", &local_label))
9178         ;
9179       else if (unformat (i, "table-id %d", &ip_table_id))
9180         ;
9181       else if (unformat (i, "unbind"))
9182         is_bind = 0;
9183       else if (unformat (i, "bind"))
9184         is_bind = 1;
9185       else
9186         {
9187           clib_warning ("parse error '%U'", format_unformat_error, i);
9188           return -99;
9189         }
9190     }
9191
9192   if (!address_set)
9193     {
9194       errmsg ("IP addres not set");
9195       return -99;
9196     }
9197
9198   if (MPLS_LABEL_INVALID == local_label)
9199     {
9200       errmsg ("missing label");
9201       return -99;
9202     }
9203
9204   /* Construct the API message */
9205   M (MPLS_IP_BIND_UNBIND, mp);
9206
9207   mp->mb_is_bind = is_bind;
9208   mp->mb_is_ip4 = is_ip4;
9209   mp->mb_ip_table_id = ntohl (ip_table_id);
9210   mp->mb_mpls_table_id = 0;
9211   mp->mb_label = ntohl (local_label);
9212   mp->mb_address_length = address_length;
9213
9214   if (is_ip4)
9215     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9216   else
9217     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9218
9219   /* send it... */
9220   S (mp);
9221
9222   /* Wait for a reply... */
9223   W (ret);
9224   return ret;
9225 }
9226
9227 static int
9228 api_bier_table_add_del (vat_main_t * vam)
9229 {
9230   unformat_input_t *i = vam->input;
9231   vl_api_bier_table_add_del_t *mp;
9232   u8 is_add = 1;
9233   u32 set = 0, sub_domain = 0, hdr_len = 3;
9234   mpls_label_t local_label = MPLS_LABEL_INVALID;
9235   int ret;
9236
9237   /* Parse args required to build the message */
9238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9239     {
9240       if (unformat (i, "sub-domain %d", &sub_domain))
9241         ;
9242       else if (unformat (i, "set %d", &set))
9243         ;
9244       else if (unformat (i, "label %d", &local_label))
9245         ;
9246       else if (unformat (i, "hdr-len %d", &hdr_len))
9247         ;
9248       else if (unformat (i, "add"))
9249         is_add = 1;
9250       else if (unformat (i, "del"))
9251         is_add = 0;
9252       else
9253         {
9254           clib_warning ("parse error '%U'", format_unformat_error, i);
9255           return -99;
9256         }
9257     }
9258
9259   if (MPLS_LABEL_INVALID == local_label)
9260     {
9261       errmsg ("missing label\n");
9262       return -99;
9263     }
9264
9265   /* Construct the API message */
9266   M (BIER_TABLE_ADD_DEL, mp);
9267
9268   mp->bt_is_add = is_add;
9269   mp->bt_label = ntohl (local_label);
9270   mp->bt_tbl_id.bt_set = set;
9271   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9272   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9273
9274   /* send it... */
9275   S (mp);
9276
9277   /* Wait for a reply... */
9278   W (ret);
9279
9280   return (ret);
9281 }
9282
9283 static int
9284 api_bier_route_add_del (vat_main_t * vam)
9285 {
9286   unformat_input_t *i = vam->input;
9287   vl_api_bier_route_add_del_t *mp;
9288   u8 is_add = 1;
9289   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9290   ip4_address_t v4_next_hop_address;
9291   ip6_address_t v6_next_hop_address;
9292   u8 next_hop_set = 0;
9293   u8 next_hop_proto_is_ip4 = 1;
9294   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9295   int ret;
9296
9297   /* Parse args required to build the message */
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9301         {
9302           next_hop_proto_is_ip4 = 1;
9303           next_hop_set = 1;
9304         }
9305       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9306         {
9307           next_hop_proto_is_ip4 = 0;
9308           next_hop_set = 1;
9309         }
9310       if (unformat (i, "sub-domain %d", &sub_domain))
9311         ;
9312       else if (unformat (i, "set %d", &set))
9313         ;
9314       else if (unformat (i, "hdr-len %d", &hdr_len))
9315         ;
9316       else if (unformat (i, "bp %d", &bp))
9317         ;
9318       else if (unformat (i, "add"))
9319         is_add = 1;
9320       else if (unformat (i, "del"))
9321         is_add = 0;
9322       else if (unformat (i, "out-label %d", &next_hop_out_label))
9323         ;
9324       else
9325         {
9326           clib_warning ("parse error '%U'", format_unformat_error, i);
9327           return -99;
9328         }
9329     }
9330
9331   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9332     {
9333       errmsg ("next hop / label set\n");
9334       return -99;
9335     }
9336   if (0 == bp)
9337     {
9338       errmsg ("bit=position not set\n");
9339       return -99;
9340     }
9341
9342   /* Construct the API message */
9343   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9344
9345   mp->br_is_add = is_add;
9346   mp->br_tbl_id.bt_set = set;
9347   mp->br_tbl_id.bt_sub_domain = sub_domain;
9348   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9349   mp->br_bp = ntohs (bp);
9350   mp->br_n_paths = 1;
9351   mp->br_paths[0].n_labels = 1;
9352   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9353   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9354
9355   if (next_hop_proto_is_ip4)
9356     {
9357       clib_memcpy (mp->br_paths[0].next_hop,
9358                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9359     }
9360   else
9361     {
9362       clib_memcpy (mp->br_paths[0].next_hop,
9363                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9364     }
9365
9366   /* send it... */
9367   S (mp);
9368
9369   /* Wait for a reply... */
9370   W (ret);
9371
9372   return (ret);
9373 }
9374
9375 static int
9376 api_proxy_arp_add_del (vat_main_t * vam)
9377 {
9378   unformat_input_t *i = vam->input;
9379   vl_api_proxy_arp_add_del_t *mp;
9380   u32 vrf_id = 0;
9381   u8 is_add = 1;
9382   ip4_address_t lo, hi;
9383   u8 range_set = 0;
9384   int ret;
9385
9386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (i, "vrf %d", &vrf_id))
9389         ;
9390       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9391                          unformat_ip4_address, &hi))
9392         range_set = 1;
9393       else if (unformat (i, "del"))
9394         is_add = 0;
9395       else
9396         {
9397           clib_warning ("parse error '%U'", format_unformat_error, i);
9398           return -99;
9399         }
9400     }
9401
9402   if (range_set == 0)
9403     {
9404       errmsg ("address range not set");
9405       return -99;
9406     }
9407
9408   M (PROXY_ARP_ADD_DEL, mp);
9409
9410   mp->vrf_id = ntohl (vrf_id);
9411   mp->is_add = is_add;
9412   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
9413   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
9414
9415   S (mp);
9416   W (ret);
9417   return ret;
9418 }
9419
9420 static int
9421 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9422 {
9423   unformat_input_t *i = vam->input;
9424   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9425   u32 sw_if_index;
9426   u8 enable = 1;
9427   u8 sw_if_index_set = 0;
9428   int ret;
9429
9430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9433         sw_if_index_set = 1;
9434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9435         sw_if_index_set = 1;
9436       else if (unformat (i, "enable"))
9437         enable = 1;
9438       else if (unformat (i, "disable"))
9439         enable = 0;
9440       else
9441         {
9442           clib_warning ("parse error '%U'", format_unformat_error, i);
9443           return -99;
9444         }
9445     }
9446
9447   if (sw_if_index_set == 0)
9448     {
9449       errmsg ("missing interface name or sw_if_index");
9450       return -99;
9451     }
9452
9453   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9454
9455   mp->sw_if_index = ntohl (sw_if_index);
9456   mp->enable_disable = enable;
9457
9458   S (mp);
9459   W (ret);
9460   return ret;
9461 }
9462
9463 static int
9464 api_mpls_tunnel_add_del (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_mpls_tunnel_add_del_t *mp;
9468
9469   u8 is_add = 1;
9470   u8 l2_only = 0;
9471   u32 sw_if_index = ~0;
9472   u32 next_hop_sw_if_index = ~0;
9473   u32 next_hop_proto_is_ip4 = 1;
9474
9475   u32 next_hop_table_id = 0;
9476   ip4_address_t v4_next_hop_address = {
9477     .as_u32 = 0,
9478   };
9479   ip6_address_t v6_next_hop_address = { {0} };
9480   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9481   int ret;
9482
9483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (i, "add"))
9486         is_add = 1;
9487       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9488         is_add = 0;
9489       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9490         ;
9491       else if (unformat (i, "via %U",
9492                          unformat_ip4_address, &v4_next_hop_address))
9493         {
9494           next_hop_proto_is_ip4 = 1;
9495         }
9496       else if (unformat (i, "via %U",
9497                          unformat_ip6_address, &v6_next_hop_address))
9498         {
9499           next_hop_proto_is_ip4 = 0;
9500         }
9501       else if (unformat (i, "l2-only"))
9502         l2_only = 1;
9503       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9504         ;
9505       else if (unformat (i, "out-label %d", &next_hop_out_label))
9506         vec_add1 (labels, ntohl (next_hop_out_label));
9507       else
9508         {
9509           clib_warning ("parse error '%U'", format_unformat_error, i);
9510           return -99;
9511         }
9512     }
9513
9514   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9515
9516   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9517   mp->mt_sw_if_index = ntohl (sw_if_index);
9518   mp->mt_is_add = is_add;
9519   mp->mt_l2_only = l2_only;
9520   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9521   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9522
9523   mp->mt_next_hop_n_out_labels = vec_len (labels);
9524
9525   if (0 != mp->mt_next_hop_n_out_labels)
9526     {
9527       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9528                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9529       vec_free (labels);
9530     }
9531
9532   if (next_hop_proto_is_ip4)
9533     {
9534       clib_memcpy (mp->mt_next_hop,
9535                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9536     }
9537   else
9538     {
9539       clib_memcpy (mp->mt_next_hop,
9540                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9541     }
9542
9543   S (mp);
9544   W (ret);
9545   return ret;
9546 }
9547
9548 static int
9549 api_sw_interface_set_unnumbered (vat_main_t * vam)
9550 {
9551   unformat_input_t *i = vam->input;
9552   vl_api_sw_interface_set_unnumbered_t *mp;
9553   u32 sw_if_index;
9554   u32 unnum_sw_index = ~0;
9555   u8 is_add = 1;
9556   u8 sw_if_index_set = 0;
9557   int ret;
9558
9559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9562         sw_if_index_set = 1;
9563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9564         sw_if_index_set = 1;
9565       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9566         ;
9567       else if (unformat (i, "del"))
9568         is_add = 0;
9569       else
9570         {
9571           clib_warning ("parse error '%U'", format_unformat_error, i);
9572           return -99;
9573         }
9574     }
9575
9576   if (sw_if_index_set == 0)
9577     {
9578       errmsg ("missing interface name or sw_if_index");
9579       return -99;
9580     }
9581
9582   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9583
9584   mp->sw_if_index = ntohl (sw_if_index);
9585   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9586   mp->is_add = is_add;
9587
9588   S (mp);
9589   W (ret);
9590   return ret;
9591 }
9592
9593 static int
9594 api_ip_neighbor_add_del (vat_main_t * vam)
9595 {
9596   unformat_input_t *i = vam->input;
9597   vl_api_ip_neighbor_add_del_t *mp;
9598   u32 sw_if_index;
9599   u8 sw_if_index_set = 0;
9600   u8 is_add = 1;
9601   u8 is_static = 0;
9602   u8 is_no_fib_entry = 0;
9603   u8 mac_address[6];
9604   u8 mac_set = 0;
9605   u8 v4_address_set = 0;
9606   u8 v6_address_set = 0;
9607   ip4_address_t v4address;
9608   ip6_address_t v6address;
9609   int ret;
9610
9611   memset (mac_address, 0, sizeof (mac_address));
9612
9613   /* Parse args required to build the message */
9614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9615     {
9616       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9617         {
9618           mac_set = 1;
9619         }
9620       else if (unformat (i, "del"))
9621         is_add = 0;
9622       else
9623         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9624         sw_if_index_set = 1;
9625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9626         sw_if_index_set = 1;
9627       else if (unformat (i, "is_static"))
9628         is_static = 1;
9629       else if (unformat (i, "no-fib-entry"))
9630         is_no_fib_entry = 1;
9631       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9632         v4_address_set = 1;
9633       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9634         v6_address_set = 1;
9635       else
9636         {
9637           clib_warning ("parse error '%U'", format_unformat_error, i);
9638           return -99;
9639         }
9640     }
9641
9642   if (sw_if_index_set == 0)
9643     {
9644       errmsg ("missing interface name or sw_if_index");
9645       return -99;
9646     }
9647   if (v4_address_set && v6_address_set)
9648     {
9649       errmsg ("both v4 and v6 addresses set");
9650       return -99;
9651     }
9652   if (!v4_address_set && !v6_address_set)
9653     {
9654       errmsg ("no address set");
9655       return -99;
9656     }
9657
9658   /* Construct the API message */
9659   M (IP_NEIGHBOR_ADD_DEL, mp);
9660
9661   mp->sw_if_index = ntohl (sw_if_index);
9662   mp->is_add = is_add;
9663   mp->is_static = is_static;
9664   mp->is_no_adj_fib = is_no_fib_entry;
9665   if (mac_set)
9666     clib_memcpy (mp->mac_address, mac_address, 6);
9667   if (v6_address_set)
9668     {
9669       mp->is_ipv6 = 1;
9670       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9671     }
9672   else
9673     {
9674       /* mp->is_ipv6 = 0; via memset in M macro above */
9675       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9676     }
9677
9678   /* send it... */
9679   S (mp);
9680
9681   /* Wait for a reply, return good/bad news  */
9682   W (ret);
9683   return ret;
9684 }
9685
9686 static int
9687 api_create_vlan_subif (vat_main_t * vam)
9688 {
9689   unformat_input_t *i = vam->input;
9690   vl_api_create_vlan_subif_t *mp;
9691   u32 sw_if_index;
9692   u8 sw_if_index_set = 0;
9693   u32 vlan_id;
9694   u8 vlan_id_set = 0;
9695   int ret;
9696
9697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (i, "sw_if_index %d", &sw_if_index))
9700         sw_if_index_set = 1;
9701       else
9702         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9703         sw_if_index_set = 1;
9704       else if (unformat (i, "vlan %d", &vlan_id))
9705         vlan_id_set = 1;
9706       else
9707         {
9708           clib_warning ("parse error '%U'", format_unformat_error, i);
9709           return -99;
9710         }
9711     }
9712
9713   if (sw_if_index_set == 0)
9714     {
9715       errmsg ("missing interface name or sw_if_index");
9716       return -99;
9717     }
9718
9719   if (vlan_id_set == 0)
9720     {
9721       errmsg ("missing vlan_id");
9722       return -99;
9723     }
9724   M (CREATE_VLAN_SUBIF, mp);
9725
9726   mp->sw_if_index = ntohl (sw_if_index);
9727   mp->vlan_id = ntohl (vlan_id);
9728
9729   S (mp);
9730   W (ret);
9731   return ret;
9732 }
9733
9734 #define foreach_create_subif_bit                \
9735 _(no_tags)                                      \
9736 _(one_tag)                                      \
9737 _(two_tags)                                     \
9738 _(dot1ad)                                       \
9739 _(exact_match)                                  \
9740 _(default_sub)                                  \
9741 _(outer_vlan_id_any)                            \
9742 _(inner_vlan_id_any)
9743
9744 static int
9745 api_create_subif (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_create_subif_t *mp;
9749   u32 sw_if_index;
9750   u8 sw_if_index_set = 0;
9751   u32 sub_id;
9752   u8 sub_id_set = 0;
9753   u32 no_tags = 0;
9754   u32 one_tag = 0;
9755   u32 two_tags = 0;
9756   u32 dot1ad = 0;
9757   u32 exact_match = 0;
9758   u32 default_sub = 0;
9759   u32 outer_vlan_id_any = 0;
9760   u32 inner_vlan_id_any = 0;
9761   u32 tmp;
9762   u16 outer_vlan_id = 0;
9763   u16 inner_vlan_id = 0;
9764   int ret;
9765
9766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9767     {
9768       if (unformat (i, "sw_if_index %d", &sw_if_index))
9769         sw_if_index_set = 1;
9770       else
9771         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9772         sw_if_index_set = 1;
9773       else if (unformat (i, "sub_id %d", &sub_id))
9774         sub_id_set = 1;
9775       else if (unformat (i, "outer_vlan_id %d", &tmp))
9776         outer_vlan_id = tmp;
9777       else if (unformat (i, "inner_vlan_id %d", &tmp))
9778         inner_vlan_id = tmp;
9779
9780 #define _(a) else if (unformat (i, #a)) a = 1 ;
9781       foreach_create_subif_bit
9782 #undef _
9783         else
9784         {
9785           clib_warning ("parse error '%U'", format_unformat_error, i);
9786           return -99;
9787         }
9788     }
9789
9790   if (sw_if_index_set == 0)
9791     {
9792       errmsg ("missing interface name or sw_if_index");
9793       return -99;
9794     }
9795
9796   if (sub_id_set == 0)
9797     {
9798       errmsg ("missing sub_id");
9799       return -99;
9800     }
9801   M (CREATE_SUBIF, mp);
9802
9803   mp->sw_if_index = ntohl (sw_if_index);
9804   mp->sub_id = ntohl (sub_id);
9805
9806 #define _(a) mp->a = a;
9807   foreach_create_subif_bit;
9808 #undef _
9809
9810   mp->outer_vlan_id = ntohs (outer_vlan_id);
9811   mp->inner_vlan_id = ntohs (inner_vlan_id);
9812
9813   S (mp);
9814   W (ret);
9815   return ret;
9816 }
9817
9818 static int
9819 api_oam_add_del (vat_main_t * vam)
9820 {
9821   unformat_input_t *i = vam->input;
9822   vl_api_oam_add_del_t *mp;
9823   u32 vrf_id = 0;
9824   u8 is_add = 1;
9825   ip4_address_t src, dst;
9826   u8 src_set = 0;
9827   u8 dst_set = 0;
9828   int ret;
9829
9830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9831     {
9832       if (unformat (i, "vrf %d", &vrf_id))
9833         ;
9834       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9835         src_set = 1;
9836       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9837         dst_set = 1;
9838       else if (unformat (i, "del"))
9839         is_add = 0;
9840       else
9841         {
9842           clib_warning ("parse error '%U'", format_unformat_error, i);
9843           return -99;
9844         }
9845     }
9846
9847   if (src_set == 0)
9848     {
9849       errmsg ("missing src addr");
9850       return -99;
9851     }
9852
9853   if (dst_set == 0)
9854     {
9855       errmsg ("missing dst addr");
9856       return -99;
9857     }
9858
9859   M (OAM_ADD_DEL, mp);
9860
9861   mp->vrf_id = ntohl (vrf_id);
9862   mp->is_add = is_add;
9863   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9864   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9865
9866   S (mp);
9867   W (ret);
9868   return ret;
9869 }
9870
9871 static int
9872 api_reset_fib (vat_main_t * vam)
9873 {
9874   unformat_input_t *i = vam->input;
9875   vl_api_reset_fib_t *mp;
9876   u32 vrf_id = 0;
9877   u8 is_ipv6 = 0;
9878   u8 vrf_id_set = 0;
9879
9880   int ret;
9881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9882     {
9883       if (unformat (i, "vrf %d", &vrf_id))
9884         vrf_id_set = 1;
9885       else if (unformat (i, "ipv6"))
9886         is_ipv6 = 1;
9887       else
9888         {
9889           clib_warning ("parse error '%U'", format_unformat_error, i);
9890           return -99;
9891         }
9892     }
9893
9894   if (vrf_id_set == 0)
9895     {
9896       errmsg ("missing vrf id");
9897       return -99;
9898     }
9899
9900   M (RESET_FIB, mp);
9901
9902   mp->vrf_id = ntohl (vrf_id);
9903   mp->is_ipv6 = is_ipv6;
9904
9905   S (mp);
9906   W (ret);
9907   return ret;
9908 }
9909
9910 static int
9911 api_dhcp_proxy_config (vat_main_t * vam)
9912 {
9913   unformat_input_t *i = vam->input;
9914   vl_api_dhcp_proxy_config_t *mp;
9915   u32 rx_vrf_id = 0;
9916   u32 server_vrf_id = 0;
9917   u8 is_add = 1;
9918   u8 v4_address_set = 0;
9919   u8 v6_address_set = 0;
9920   ip4_address_t v4address;
9921   ip6_address_t v6address;
9922   u8 v4_src_address_set = 0;
9923   u8 v6_src_address_set = 0;
9924   ip4_address_t v4srcaddress;
9925   ip6_address_t v6srcaddress;
9926   int ret;
9927
9928   /* Parse args required to build the message */
9929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9930     {
9931       if (unformat (i, "del"))
9932         is_add = 0;
9933       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9934         ;
9935       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9936         ;
9937       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9938         v4_address_set = 1;
9939       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9940         v6_address_set = 1;
9941       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9942         v4_src_address_set = 1;
9943       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9944         v6_src_address_set = 1;
9945       else
9946         break;
9947     }
9948
9949   if (v4_address_set && v6_address_set)
9950     {
9951       errmsg ("both v4 and v6 server addresses set");
9952       return -99;
9953     }
9954   if (!v4_address_set && !v6_address_set)
9955     {
9956       errmsg ("no server addresses set");
9957       return -99;
9958     }
9959
9960   if (v4_src_address_set && v6_src_address_set)
9961     {
9962       errmsg ("both v4 and v6  src addresses set");
9963       return -99;
9964     }
9965   if (!v4_src_address_set && !v6_src_address_set)
9966     {
9967       errmsg ("no src addresses set");
9968       return -99;
9969     }
9970
9971   if (!(v4_src_address_set && v4_address_set) &&
9972       !(v6_src_address_set && v6_address_set))
9973     {
9974       errmsg ("no matching server and src addresses set");
9975       return -99;
9976     }
9977
9978   /* Construct the API message */
9979   M (DHCP_PROXY_CONFIG, mp);
9980
9981   mp->is_add = is_add;
9982   mp->rx_vrf_id = ntohl (rx_vrf_id);
9983   mp->server_vrf_id = ntohl (server_vrf_id);
9984   if (v6_address_set)
9985     {
9986       mp->is_ipv6 = 1;
9987       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9988       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9989     }
9990   else
9991     {
9992       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9993       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9994     }
9995
9996   /* send it... */
9997   S (mp);
9998
9999   /* Wait for a reply, return good/bad news  */
10000   W (ret);
10001   return ret;
10002 }
10003
10004 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10005 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10006
10007 static void
10008 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10009 {
10010   vat_main_t *vam = &vat_main;
10011   u32 i, count = mp->count;
10012   vl_api_dhcp_server_t *s;
10013
10014   if (mp->is_ipv6)
10015     print (vam->ofp,
10016            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10017            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10018            ntohl (mp->rx_vrf_id),
10019            format_ip6_address, mp->dhcp_src_address,
10020            mp->vss_type, mp->vss_vpn_ascii_id,
10021            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10022   else
10023     print (vam->ofp,
10024            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10025            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10026            ntohl (mp->rx_vrf_id),
10027            format_ip4_address, mp->dhcp_src_address,
10028            mp->vss_type, mp->vss_vpn_ascii_id,
10029            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10030
10031   for (i = 0; i < count; i++)
10032     {
10033       s = &mp->servers[i];
10034
10035       if (mp->is_ipv6)
10036         print (vam->ofp,
10037                " Server Table-ID %d, Server Address %U",
10038                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10039       else
10040         print (vam->ofp,
10041                " Server Table-ID %d, Server Address %U",
10042                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10043     }
10044 }
10045
10046 static void vl_api_dhcp_proxy_details_t_handler_json
10047   (vl_api_dhcp_proxy_details_t * mp)
10048 {
10049   vat_main_t *vam = &vat_main;
10050   vat_json_node_t *node = NULL;
10051   u32 i, count = mp->count;
10052   struct in_addr ip4;
10053   struct in6_addr ip6;
10054   vl_api_dhcp_server_t *s;
10055
10056   if (VAT_JSON_ARRAY != vam->json_tree.type)
10057     {
10058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10059       vat_json_init_array (&vam->json_tree);
10060     }
10061   node = vat_json_array_add (&vam->json_tree);
10062
10063   vat_json_init_object (node);
10064   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10065   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10066                              sizeof (mp->vss_type));
10067   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10068                                    mp->vss_vpn_ascii_id);
10069   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10070   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10071
10072   if (mp->is_ipv6)
10073     {
10074       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10075       vat_json_object_add_ip6 (node, "src_address", ip6);
10076     }
10077   else
10078     {
10079       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10080       vat_json_object_add_ip4 (node, "src_address", ip4);
10081     }
10082
10083   for (i = 0; i < count; i++)
10084     {
10085       s = &mp->servers[i];
10086
10087       vat_json_object_add_uint (node, "server-table-id",
10088                                 ntohl (s->server_vrf_id));
10089
10090       if (mp->is_ipv6)
10091         {
10092           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10093           vat_json_object_add_ip4 (node, "src_address", ip4);
10094         }
10095       else
10096         {
10097           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10098           vat_json_object_add_ip6 (node, "server_address", ip6);
10099         }
10100     }
10101 }
10102
10103 static int
10104 api_dhcp_proxy_dump (vat_main_t * vam)
10105 {
10106   unformat_input_t *i = vam->input;
10107   vl_api_control_ping_t *mp_ping;
10108   vl_api_dhcp_proxy_dump_t *mp;
10109   u8 is_ipv6 = 0;
10110   int ret;
10111
10112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10113     {
10114       if (unformat (i, "ipv6"))
10115         is_ipv6 = 1;
10116       else
10117         {
10118           clib_warning ("parse error '%U'", format_unformat_error, i);
10119           return -99;
10120         }
10121     }
10122
10123   M (DHCP_PROXY_DUMP, mp);
10124
10125   mp->is_ip6 = is_ipv6;
10126   S (mp);
10127
10128   /* Use a control ping for synchronization */
10129   MPING (CONTROL_PING, mp_ping);
10130   S (mp_ping);
10131
10132   W (ret);
10133   return ret;
10134 }
10135
10136 static int
10137 api_dhcp_proxy_set_vss (vat_main_t * vam)
10138 {
10139   unformat_input_t *i = vam->input;
10140   vl_api_dhcp_proxy_set_vss_t *mp;
10141   u8 is_ipv6 = 0;
10142   u8 is_add = 1;
10143   u32 tbl_id = ~0;
10144   u8 vss_type = VSS_TYPE_DEFAULT;
10145   u8 *vpn_ascii_id = 0;
10146   u32 oui = 0;
10147   u32 fib_id = 0;
10148   int ret;
10149
10150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (i, "tbl_id %d", &tbl_id))
10153         ;
10154       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10155         vss_type = VSS_TYPE_ASCII;
10156       else if (unformat (i, "fib_id %d", &fib_id))
10157         vss_type = VSS_TYPE_VPN_ID;
10158       else if (unformat (i, "oui %d", &oui))
10159         vss_type = VSS_TYPE_VPN_ID;
10160       else if (unformat (i, "ipv6"))
10161         is_ipv6 = 1;
10162       else if (unformat (i, "del"))
10163         is_add = 0;
10164       else
10165         break;
10166     }
10167
10168   if (tbl_id == ~0)
10169     {
10170       errmsg ("missing tbl_id ");
10171       vec_free (vpn_ascii_id);
10172       return -99;
10173     }
10174
10175   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10176     {
10177       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10178       vec_free (vpn_ascii_id);
10179       return -99;
10180     }
10181
10182   M (DHCP_PROXY_SET_VSS, mp);
10183   mp->tbl_id = ntohl (tbl_id);
10184   mp->vss_type = vss_type;
10185   if (vpn_ascii_id)
10186     {
10187       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10188       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10189     }
10190   mp->vpn_index = ntohl (fib_id);
10191   mp->oui = ntohl (oui);
10192   mp->is_ipv6 = is_ipv6;
10193   mp->is_add = is_add;
10194
10195   S (mp);
10196   W (ret);
10197
10198   vec_free (vpn_ascii_id);
10199   return ret;
10200 }
10201
10202 static int
10203 api_dhcp_client_config (vat_main_t * vam)
10204 {
10205   unformat_input_t *i = vam->input;
10206   vl_api_dhcp_client_config_t *mp;
10207   u32 sw_if_index;
10208   u8 sw_if_index_set = 0;
10209   u8 is_add = 1;
10210   u8 *hostname = 0;
10211   u8 disable_event = 0;
10212   int ret;
10213
10214   /* Parse args required to build the message */
10215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (i, "del"))
10218         is_add = 0;
10219       else
10220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10221         sw_if_index_set = 1;
10222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10223         sw_if_index_set = 1;
10224       else if (unformat (i, "hostname %s", &hostname))
10225         ;
10226       else if (unformat (i, "disable_event"))
10227         disable_event = 1;
10228       else
10229         break;
10230     }
10231
10232   if (sw_if_index_set == 0)
10233     {
10234       errmsg ("missing interface name or sw_if_index");
10235       return -99;
10236     }
10237
10238   if (vec_len (hostname) > 63)
10239     {
10240       errmsg ("hostname too long");
10241     }
10242   vec_add1 (hostname, 0);
10243
10244   /* Construct the API message */
10245   M (DHCP_CLIENT_CONFIG, mp);
10246
10247   mp->sw_if_index = htonl (sw_if_index);
10248   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10249   vec_free (hostname);
10250   mp->is_add = is_add;
10251   mp->want_dhcp_event = disable_event ? 0 : 1;
10252   mp->pid = htonl (getpid ());
10253
10254   /* send it... */
10255   S (mp);
10256
10257   /* Wait for a reply, return good/bad news  */
10258   W (ret);
10259   return ret;
10260 }
10261
10262 static int
10263 api_set_ip_flow_hash (vat_main_t * vam)
10264 {
10265   unformat_input_t *i = vam->input;
10266   vl_api_set_ip_flow_hash_t *mp;
10267   u32 vrf_id = 0;
10268   u8 is_ipv6 = 0;
10269   u8 vrf_id_set = 0;
10270   u8 src = 0;
10271   u8 dst = 0;
10272   u8 sport = 0;
10273   u8 dport = 0;
10274   u8 proto = 0;
10275   u8 reverse = 0;
10276   int ret;
10277
10278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (i, "vrf %d", &vrf_id))
10281         vrf_id_set = 1;
10282       else if (unformat (i, "ipv6"))
10283         is_ipv6 = 1;
10284       else if (unformat (i, "src"))
10285         src = 1;
10286       else if (unformat (i, "dst"))
10287         dst = 1;
10288       else if (unformat (i, "sport"))
10289         sport = 1;
10290       else if (unformat (i, "dport"))
10291         dport = 1;
10292       else if (unformat (i, "proto"))
10293         proto = 1;
10294       else if (unformat (i, "reverse"))
10295         reverse = 1;
10296
10297       else
10298         {
10299           clib_warning ("parse error '%U'", format_unformat_error, i);
10300           return -99;
10301         }
10302     }
10303
10304   if (vrf_id_set == 0)
10305     {
10306       errmsg ("missing vrf id");
10307       return -99;
10308     }
10309
10310   M (SET_IP_FLOW_HASH, mp);
10311   mp->src = src;
10312   mp->dst = dst;
10313   mp->sport = sport;
10314   mp->dport = dport;
10315   mp->proto = proto;
10316   mp->reverse = reverse;
10317   mp->vrf_id = ntohl (vrf_id);
10318   mp->is_ipv6 = is_ipv6;
10319
10320   S (mp);
10321   W (ret);
10322   return ret;
10323 }
10324
10325 static int
10326 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10327 {
10328   unformat_input_t *i = vam->input;
10329   vl_api_sw_interface_ip6_enable_disable_t *mp;
10330   u32 sw_if_index;
10331   u8 sw_if_index_set = 0;
10332   u8 enable = 0;
10333   int ret;
10334
10335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10338         sw_if_index_set = 1;
10339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10340         sw_if_index_set = 1;
10341       else if (unformat (i, "enable"))
10342         enable = 1;
10343       else if (unformat (i, "disable"))
10344         enable = 0;
10345       else
10346         {
10347           clib_warning ("parse error '%U'", format_unformat_error, i);
10348           return -99;
10349         }
10350     }
10351
10352   if (sw_if_index_set == 0)
10353     {
10354       errmsg ("missing interface name or sw_if_index");
10355       return -99;
10356     }
10357
10358   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10359
10360   mp->sw_if_index = ntohl (sw_if_index);
10361   mp->enable = enable;
10362
10363   S (mp);
10364   W (ret);
10365   return ret;
10366 }
10367
10368 static int
10369 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10370 {
10371   unformat_input_t *i = vam->input;
10372   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10373   u32 sw_if_index;
10374   u8 sw_if_index_set = 0;
10375   u8 v6_address_set = 0;
10376   ip6_address_t v6address;
10377   int ret;
10378
10379   /* Parse args required to build the message */
10380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10381     {
10382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10383         sw_if_index_set = 1;
10384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10385         sw_if_index_set = 1;
10386       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10387         v6_address_set = 1;
10388       else
10389         break;
10390     }
10391
10392   if (sw_if_index_set == 0)
10393     {
10394       errmsg ("missing interface name or sw_if_index");
10395       return -99;
10396     }
10397   if (!v6_address_set)
10398     {
10399       errmsg ("no address set");
10400       return -99;
10401     }
10402
10403   /* Construct the API message */
10404   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10405
10406   mp->sw_if_index = ntohl (sw_if_index);
10407   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10408
10409   /* send it... */
10410   S (mp);
10411
10412   /* Wait for a reply, return good/bad news  */
10413   W (ret);
10414   return ret;
10415 }
10416
10417 static int
10418 api_ip6nd_proxy_add_del (vat_main_t * vam)
10419 {
10420   unformat_input_t *i = vam->input;
10421   vl_api_ip6nd_proxy_add_del_t *mp;
10422   u32 sw_if_index = ~0;
10423   u8 v6_address_set = 0;
10424   ip6_address_t v6address;
10425   u8 is_del = 0;
10426   int ret;
10427
10428   /* Parse args required to build the message */
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10432         ;
10433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10434         ;
10435       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10436         v6_address_set = 1;
10437       if (unformat (i, "del"))
10438         is_del = 1;
10439       else
10440         {
10441           clib_warning ("parse error '%U'", format_unformat_error, i);
10442           return -99;
10443         }
10444     }
10445
10446   if (sw_if_index == ~0)
10447     {
10448       errmsg ("missing interface name or sw_if_index");
10449       return -99;
10450     }
10451   if (!v6_address_set)
10452     {
10453       errmsg ("no address set");
10454       return -99;
10455     }
10456
10457   /* Construct the API message */
10458   M (IP6ND_PROXY_ADD_DEL, mp);
10459
10460   mp->is_del = is_del;
10461   mp->sw_if_index = ntohl (sw_if_index);
10462   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10463
10464   /* send it... */
10465   S (mp);
10466
10467   /* Wait for a reply, return good/bad news  */
10468   W (ret);
10469   return ret;
10470 }
10471
10472 static int
10473 api_ip6nd_proxy_dump (vat_main_t * vam)
10474 {
10475   vl_api_ip6nd_proxy_dump_t *mp;
10476   vl_api_control_ping_t *mp_ping;
10477   int ret;
10478
10479   M (IP6ND_PROXY_DUMP, mp);
10480
10481   S (mp);
10482
10483   /* Use a control ping for synchronization */
10484   MPING (CONTROL_PING, mp_ping);
10485   S (mp_ping);
10486
10487   W (ret);
10488   return ret;
10489 }
10490
10491 static void vl_api_ip6nd_proxy_details_t_handler
10492   (vl_api_ip6nd_proxy_details_t * mp)
10493 {
10494   vat_main_t *vam = &vat_main;
10495
10496   print (vam->ofp, "host %U sw_if_index %d",
10497          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10498 }
10499
10500 static void vl_api_ip6nd_proxy_details_t_handler_json
10501   (vl_api_ip6nd_proxy_details_t * mp)
10502 {
10503   vat_main_t *vam = &vat_main;
10504   struct in6_addr ip6;
10505   vat_json_node_t *node = NULL;
10506
10507   if (VAT_JSON_ARRAY != vam->json_tree.type)
10508     {
10509       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10510       vat_json_init_array (&vam->json_tree);
10511     }
10512   node = vat_json_array_add (&vam->json_tree);
10513
10514   vat_json_init_object (node);
10515   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10516
10517   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10518   vat_json_object_add_ip6 (node, "host", ip6);
10519 }
10520
10521 static int
10522 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10523 {
10524   unformat_input_t *i = vam->input;
10525   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10526   u32 sw_if_index;
10527   u8 sw_if_index_set = 0;
10528   u32 address_length = 0;
10529   u8 v6_address_set = 0;
10530   ip6_address_t v6address;
10531   u8 use_default = 0;
10532   u8 no_advertise = 0;
10533   u8 off_link = 0;
10534   u8 no_autoconfig = 0;
10535   u8 no_onlink = 0;
10536   u8 is_no = 0;
10537   u32 val_lifetime = 0;
10538   u32 pref_lifetime = 0;
10539   int ret;
10540
10541   /* Parse args required to build the message */
10542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10543     {
10544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10545         sw_if_index_set = 1;
10546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10547         sw_if_index_set = 1;
10548       else if (unformat (i, "%U/%d",
10549                          unformat_ip6_address, &v6address, &address_length))
10550         v6_address_set = 1;
10551       else if (unformat (i, "val_life %d", &val_lifetime))
10552         ;
10553       else if (unformat (i, "pref_life %d", &pref_lifetime))
10554         ;
10555       else if (unformat (i, "def"))
10556         use_default = 1;
10557       else if (unformat (i, "noadv"))
10558         no_advertise = 1;
10559       else if (unformat (i, "offl"))
10560         off_link = 1;
10561       else if (unformat (i, "noauto"))
10562         no_autoconfig = 1;
10563       else if (unformat (i, "nolink"))
10564         no_onlink = 1;
10565       else if (unformat (i, "isno"))
10566         is_no = 1;
10567       else
10568         {
10569           clib_warning ("parse error '%U'", format_unformat_error, i);
10570           return -99;
10571         }
10572     }
10573
10574   if (sw_if_index_set == 0)
10575     {
10576       errmsg ("missing interface name or sw_if_index");
10577       return -99;
10578     }
10579   if (!v6_address_set)
10580     {
10581       errmsg ("no address set");
10582       return -99;
10583     }
10584
10585   /* Construct the API message */
10586   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10587
10588   mp->sw_if_index = ntohl (sw_if_index);
10589   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10590   mp->address_length = address_length;
10591   mp->use_default = use_default;
10592   mp->no_advertise = no_advertise;
10593   mp->off_link = off_link;
10594   mp->no_autoconfig = no_autoconfig;
10595   mp->no_onlink = no_onlink;
10596   mp->is_no = is_no;
10597   mp->val_lifetime = ntohl (val_lifetime);
10598   mp->pref_lifetime = ntohl (pref_lifetime);
10599
10600   /* send it... */
10601   S (mp);
10602
10603   /* Wait for a reply, return good/bad news  */
10604   W (ret);
10605   return ret;
10606 }
10607
10608 static int
10609 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10610 {
10611   unformat_input_t *i = vam->input;
10612   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10613   u32 sw_if_index;
10614   u8 sw_if_index_set = 0;
10615   u8 suppress = 0;
10616   u8 managed = 0;
10617   u8 other = 0;
10618   u8 ll_option = 0;
10619   u8 send_unicast = 0;
10620   u8 cease = 0;
10621   u8 is_no = 0;
10622   u8 default_router = 0;
10623   u32 max_interval = 0;
10624   u32 min_interval = 0;
10625   u32 lifetime = 0;
10626   u32 initial_count = 0;
10627   u32 initial_interval = 0;
10628   int ret;
10629
10630
10631   /* Parse args required to build the message */
10632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10633     {
10634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10635         sw_if_index_set = 1;
10636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10637         sw_if_index_set = 1;
10638       else if (unformat (i, "maxint %d", &max_interval))
10639         ;
10640       else if (unformat (i, "minint %d", &min_interval))
10641         ;
10642       else if (unformat (i, "life %d", &lifetime))
10643         ;
10644       else if (unformat (i, "count %d", &initial_count))
10645         ;
10646       else if (unformat (i, "interval %d", &initial_interval))
10647         ;
10648       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10649         suppress = 1;
10650       else if (unformat (i, "managed"))
10651         managed = 1;
10652       else if (unformat (i, "other"))
10653         other = 1;
10654       else if (unformat (i, "ll"))
10655         ll_option = 1;
10656       else if (unformat (i, "send"))
10657         send_unicast = 1;
10658       else if (unformat (i, "cease"))
10659         cease = 1;
10660       else if (unformat (i, "isno"))
10661         is_no = 1;
10662       else if (unformat (i, "def"))
10663         default_router = 1;
10664       else
10665         {
10666           clib_warning ("parse error '%U'", format_unformat_error, i);
10667           return -99;
10668         }
10669     }
10670
10671   if (sw_if_index_set == 0)
10672     {
10673       errmsg ("missing interface name or sw_if_index");
10674       return -99;
10675     }
10676
10677   /* Construct the API message */
10678   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10679
10680   mp->sw_if_index = ntohl (sw_if_index);
10681   mp->max_interval = ntohl (max_interval);
10682   mp->min_interval = ntohl (min_interval);
10683   mp->lifetime = ntohl (lifetime);
10684   mp->initial_count = ntohl (initial_count);
10685   mp->initial_interval = ntohl (initial_interval);
10686   mp->suppress = suppress;
10687   mp->managed = managed;
10688   mp->other = other;
10689   mp->ll_option = ll_option;
10690   mp->send_unicast = send_unicast;
10691   mp->cease = cease;
10692   mp->is_no = is_no;
10693   mp->default_router = default_router;
10694
10695   /* send it... */
10696   S (mp);
10697
10698   /* Wait for a reply, return good/bad news  */
10699   W (ret);
10700   return ret;
10701 }
10702
10703 static int
10704 api_set_arp_neighbor_limit (vat_main_t * vam)
10705 {
10706   unformat_input_t *i = vam->input;
10707   vl_api_set_arp_neighbor_limit_t *mp;
10708   u32 arp_nbr_limit;
10709   u8 limit_set = 0;
10710   u8 is_ipv6 = 0;
10711   int ret;
10712
10713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10714     {
10715       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10716         limit_set = 1;
10717       else if (unformat (i, "ipv6"))
10718         is_ipv6 = 1;
10719       else
10720         {
10721           clib_warning ("parse error '%U'", format_unformat_error, i);
10722           return -99;
10723         }
10724     }
10725
10726   if (limit_set == 0)
10727     {
10728       errmsg ("missing limit value");
10729       return -99;
10730     }
10731
10732   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10733
10734   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10735   mp->is_ipv6 = is_ipv6;
10736
10737   S (mp);
10738   W (ret);
10739   return ret;
10740 }
10741
10742 static int
10743 api_l2_patch_add_del (vat_main_t * vam)
10744 {
10745   unformat_input_t *i = vam->input;
10746   vl_api_l2_patch_add_del_t *mp;
10747   u32 rx_sw_if_index;
10748   u8 rx_sw_if_index_set = 0;
10749   u32 tx_sw_if_index;
10750   u8 tx_sw_if_index_set = 0;
10751   u8 is_add = 1;
10752   int ret;
10753
10754   /* Parse args required to build the message */
10755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10758         rx_sw_if_index_set = 1;
10759       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10760         tx_sw_if_index_set = 1;
10761       else if (unformat (i, "rx"))
10762         {
10763           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10764             {
10765               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10766                             &rx_sw_if_index))
10767                 rx_sw_if_index_set = 1;
10768             }
10769           else
10770             break;
10771         }
10772       else if (unformat (i, "tx"))
10773         {
10774           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10775             {
10776               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10777                             &tx_sw_if_index))
10778                 tx_sw_if_index_set = 1;
10779             }
10780           else
10781             break;
10782         }
10783       else if (unformat (i, "del"))
10784         is_add = 0;
10785       else
10786         break;
10787     }
10788
10789   if (rx_sw_if_index_set == 0)
10790     {
10791       errmsg ("missing rx interface name or rx_sw_if_index");
10792       return -99;
10793     }
10794
10795   if (tx_sw_if_index_set == 0)
10796     {
10797       errmsg ("missing tx interface name or tx_sw_if_index");
10798       return -99;
10799     }
10800
10801   M (L2_PATCH_ADD_DEL, mp);
10802
10803   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10804   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10805   mp->is_add = is_add;
10806
10807   S (mp);
10808   W (ret);
10809   return ret;
10810 }
10811
10812 u8 is_del;
10813 u8 localsid_addr[16];
10814 u8 end_psp;
10815 u8 behavior;
10816 u32 sw_if_index;
10817 u32 vlan_index;
10818 u32 fib_table;
10819 u8 nh_addr[16];
10820
10821 static int
10822 api_sr_localsid_add_del (vat_main_t * vam)
10823 {
10824   unformat_input_t *i = vam->input;
10825   vl_api_sr_localsid_add_del_t *mp;
10826
10827   u8 is_del;
10828   ip6_address_t localsid;
10829   u8 end_psp = 0;
10830   u8 behavior = ~0;
10831   u32 sw_if_index;
10832   u32 fib_table = ~(u32) 0;
10833   ip6_address_t next_hop;
10834
10835   bool nexthop_set = 0;
10836
10837   int ret;
10838
10839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (unformat (i, "del"))
10842         is_del = 1;
10843       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10844       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10845         nexthop_set = 1;
10846       else if (unformat (i, "behavior %u", &behavior));
10847       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10848       else if (unformat (i, "fib-table %u", &fib_table));
10849       else if (unformat (i, "end.psp %u", &behavior));
10850       else
10851         break;
10852     }
10853
10854   M (SR_LOCALSID_ADD_DEL, mp);
10855
10856   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10857   if (nexthop_set)
10858     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10859   mp->behavior = behavior;
10860   mp->sw_if_index = ntohl (sw_if_index);
10861   mp->fib_table = ntohl (fib_table);
10862   mp->end_psp = end_psp;
10863   mp->is_del = is_del;
10864
10865   S (mp);
10866   W (ret);
10867   return ret;
10868 }
10869
10870 static int
10871 api_ioam_enable (vat_main_t * vam)
10872 {
10873   unformat_input_t *input = vam->input;
10874   vl_api_ioam_enable_t *mp;
10875   u32 id = 0;
10876   int has_trace_option = 0;
10877   int has_pot_option = 0;
10878   int has_seqno_option = 0;
10879   int has_analyse_option = 0;
10880   int ret;
10881
10882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10883     {
10884       if (unformat (input, "trace"))
10885         has_trace_option = 1;
10886       else if (unformat (input, "pot"))
10887         has_pot_option = 1;
10888       else if (unformat (input, "seqno"))
10889         has_seqno_option = 1;
10890       else if (unformat (input, "analyse"))
10891         has_analyse_option = 1;
10892       else
10893         break;
10894     }
10895   M (IOAM_ENABLE, mp);
10896   mp->id = htons (id);
10897   mp->seqno = has_seqno_option;
10898   mp->analyse = has_analyse_option;
10899   mp->pot_enable = has_pot_option;
10900   mp->trace_enable = has_trace_option;
10901
10902   S (mp);
10903   W (ret);
10904   return ret;
10905 }
10906
10907
10908 static int
10909 api_ioam_disable (vat_main_t * vam)
10910 {
10911   vl_api_ioam_disable_t *mp;
10912   int ret;
10913
10914   M (IOAM_DISABLE, mp);
10915   S (mp);
10916   W (ret);
10917   return ret;
10918 }
10919
10920 #define foreach_tcp_proto_field                 \
10921 _(src_port)                                     \
10922 _(dst_port)
10923
10924 #define foreach_udp_proto_field                 \
10925 _(src_port)                                     \
10926 _(dst_port)
10927
10928 #define foreach_ip4_proto_field                 \
10929 _(src_address)                                  \
10930 _(dst_address)                                  \
10931 _(tos)                                          \
10932 _(length)                                       \
10933 _(fragment_id)                                  \
10934 _(ttl)                                          \
10935 _(protocol)                                     \
10936 _(checksum)
10937
10938 typedef struct
10939 {
10940   u16 src_port, dst_port;
10941 } tcpudp_header_t;
10942
10943 #if VPP_API_TEST_BUILTIN == 0
10944 uword
10945 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10946 {
10947   u8 **maskp = va_arg (*args, u8 **);
10948   u8 *mask = 0;
10949   u8 found_something = 0;
10950   tcp_header_t *tcp;
10951
10952 #define _(a) u8 a=0;
10953   foreach_tcp_proto_field;
10954 #undef _
10955
10956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10957     {
10958       if (0);
10959 #define _(a) else if (unformat (input, #a)) a=1;
10960       foreach_tcp_proto_field
10961 #undef _
10962         else
10963         break;
10964     }
10965
10966 #define _(a) found_something += a;
10967   foreach_tcp_proto_field;
10968 #undef _
10969
10970   if (found_something == 0)
10971     return 0;
10972
10973   vec_validate (mask, sizeof (*tcp) - 1);
10974
10975   tcp = (tcp_header_t *) mask;
10976
10977 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10978   foreach_tcp_proto_field;
10979 #undef _
10980
10981   *maskp = mask;
10982   return 1;
10983 }
10984
10985 uword
10986 unformat_udp_mask (unformat_input_t * input, va_list * args)
10987 {
10988   u8 **maskp = va_arg (*args, u8 **);
10989   u8 *mask = 0;
10990   u8 found_something = 0;
10991   udp_header_t *udp;
10992
10993 #define _(a) u8 a=0;
10994   foreach_udp_proto_field;
10995 #undef _
10996
10997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10998     {
10999       if (0);
11000 #define _(a) else if (unformat (input, #a)) a=1;
11001       foreach_udp_proto_field
11002 #undef _
11003         else
11004         break;
11005     }
11006
11007 #define _(a) found_something += a;
11008   foreach_udp_proto_field;
11009 #undef _
11010
11011   if (found_something == 0)
11012     return 0;
11013
11014   vec_validate (mask, sizeof (*udp) - 1);
11015
11016   udp = (udp_header_t *) mask;
11017
11018 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11019   foreach_udp_proto_field;
11020 #undef _
11021
11022   *maskp = mask;
11023   return 1;
11024 }
11025
11026 uword
11027 unformat_l4_mask (unformat_input_t * input, va_list * args)
11028 {
11029   u8 **maskp = va_arg (*args, u8 **);
11030   u16 src_port = 0, dst_port = 0;
11031   tcpudp_header_t *tcpudp;
11032
11033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11034     {
11035       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11036         return 1;
11037       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11038         return 1;
11039       else if (unformat (input, "src_port"))
11040         src_port = 0xFFFF;
11041       else if (unformat (input, "dst_port"))
11042         dst_port = 0xFFFF;
11043       else
11044         return 0;
11045     }
11046
11047   if (!src_port && !dst_port)
11048     return 0;
11049
11050   u8 *mask = 0;
11051   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11052
11053   tcpudp = (tcpudp_header_t *) mask;
11054   tcpudp->src_port = src_port;
11055   tcpudp->dst_port = dst_port;
11056
11057   *maskp = mask;
11058
11059   return 1;
11060 }
11061
11062 uword
11063 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11064 {
11065   u8 **maskp = va_arg (*args, u8 **);
11066   u8 *mask = 0;
11067   u8 found_something = 0;
11068   ip4_header_t *ip;
11069
11070 #define _(a) u8 a=0;
11071   foreach_ip4_proto_field;
11072 #undef _
11073   u8 version = 0;
11074   u8 hdr_length = 0;
11075
11076
11077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11078     {
11079       if (unformat (input, "version"))
11080         version = 1;
11081       else if (unformat (input, "hdr_length"))
11082         hdr_length = 1;
11083       else if (unformat (input, "src"))
11084         src_address = 1;
11085       else if (unformat (input, "dst"))
11086         dst_address = 1;
11087       else if (unformat (input, "proto"))
11088         protocol = 1;
11089
11090 #define _(a) else if (unformat (input, #a)) a=1;
11091       foreach_ip4_proto_field
11092 #undef _
11093         else
11094         break;
11095     }
11096
11097 #define _(a) found_something += a;
11098   foreach_ip4_proto_field;
11099 #undef _
11100
11101   if (found_something == 0)
11102     return 0;
11103
11104   vec_validate (mask, sizeof (*ip) - 1);
11105
11106   ip = (ip4_header_t *) mask;
11107
11108 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11109   foreach_ip4_proto_field;
11110 #undef _
11111
11112   ip->ip_version_and_header_length = 0;
11113
11114   if (version)
11115     ip->ip_version_and_header_length |= 0xF0;
11116
11117   if (hdr_length)
11118     ip->ip_version_and_header_length |= 0x0F;
11119
11120   *maskp = mask;
11121   return 1;
11122 }
11123
11124 #define foreach_ip6_proto_field                 \
11125 _(src_address)                                  \
11126 _(dst_address)                                  \
11127 _(payload_length)                               \
11128 _(hop_limit)                                    \
11129 _(protocol)
11130
11131 uword
11132 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11133 {
11134   u8 **maskp = va_arg (*args, u8 **);
11135   u8 *mask = 0;
11136   u8 found_something = 0;
11137   ip6_header_t *ip;
11138   u32 ip_version_traffic_class_and_flow_label;
11139
11140 #define _(a) u8 a=0;
11141   foreach_ip6_proto_field;
11142 #undef _
11143   u8 version = 0;
11144   u8 traffic_class = 0;
11145   u8 flow_label = 0;
11146
11147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11148     {
11149       if (unformat (input, "version"))
11150         version = 1;
11151       else if (unformat (input, "traffic-class"))
11152         traffic_class = 1;
11153       else if (unformat (input, "flow-label"))
11154         flow_label = 1;
11155       else if (unformat (input, "src"))
11156         src_address = 1;
11157       else if (unformat (input, "dst"))
11158         dst_address = 1;
11159       else if (unformat (input, "proto"))
11160         protocol = 1;
11161
11162 #define _(a) else if (unformat (input, #a)) a=1;
11163       foreach_ip6_proto_field
11164 #undef _
11165         else
11166         break;
11167     }
11168
11169 #define _(a) found_something += a;
11170   foreach_ip6_proto_field;
11171 #undef _
11172
11173   if (found_something == 0)
11174     return 0;
11175
11176   vec_validate (mask, sizeof (*ip) - 1);
11177
11178   ip = (ip6_header_t *) mask;
11179
11180 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11181   foreach_ip6_proto_field;
11182 #undef _
11183
11184   ip_version_traffic_class_and_flow_label = 0;
11185
11186   if (version)
11187     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11188
11189   if (traffic_class)
11190     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11191
11192   if (flow_label)
11193     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11194
11195   ip->ip_version_traffic_class_and_flow_label =
11196     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11197
11198   *maskp = mask;
11199   return 1;
11200 }
11201
11202 uword
11203 unformat_l3_mask (unformat_input_t * input, va_list * args)
11204 {
11205   u8 **maskp = va_arg (*args, u8 **);
11206
11207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11208     {
11209       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11210         return 1;
11211       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11212         return 1;
11213       else
11214         break;
11215     }
11216   return 0;
11217 }
11218
11219 uword
11220 unformat_l2_mask (unformat_input_t * input, va_list * args)
11221 {
11222   u8 **maskp = va_arg (*args, u8 **);
11223   u8 *mask = 0;
11224   u8 src = 0;
11225   u8 dst = 0;
11226   u8 proto = 0;
11227   u8 tag1 = 0;
11228   u8 tag2 = 0;
11229   u8 ignore_tag1 = 0;
11230   u8 ignore_tag2 = 0;
11231   u8 cos1 = 0;
11232   u8 cos2 = 0;
11233   u8 dot1q = 0;
11234   u8 dot1ad = 0;
11235   int len = 14;
11236
11237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (input, "src"))
11240         src = 1;
11241       else if (unformat (input, "dst"))
11242         dst = 1;
11243       else if (unformat (input, "proto"))
11244         proto = 1;
11245       else if (unformat (input, "tag1"))
11246         tag1 = 1;
11247       else if (unformat (input, "tag2"))
11248         tag2 = 1;
11249       else if (unformat (input, "ignore-tag1"))
11250         ignore_tag1 = 1;
11251       else if (unformat (input, "ignore-tag2"))
11252         ignore_tag2 = 1;
11253       else if (unformat (input, "cos1"))
11254         cos1 = 1;
11255       else if (unformat (input, "cos2"))
11256         cos2 = 1;
11257       else if (unformat (input, "dot1q"))
11258         dot1q = 1;
11259       else if (unformat (input, "dot1ad"))
11260         dot1ad = 1;
11261       else
11262         break;
11263     }
11264   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11265        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11266     return 0;
11267
11268   if (tag1 || ignore_tag1 || cos1 || dot1q)
11269     len = 18;
11270   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11271     len = 22;
11272
11273   vec_validate (mask, len - 1);
11274
11275   if (dst)
11276     memset (mask, 0xff, 6);
11277
11278   if (src)
11279     memset (mask + 6, 0xff, 6);
11280
11281   if (tag2 || dot1ad)
11282     {
11283       /* inner vlan tag */
11284       if (tag2)
11285         {
11286           mask[19] = 0xff;
11287           mask[18] = 0x0f;
11288         }
11289       if (cos2)
11290         mask[18] |= 0xe0;
11291       if (proto)
11292         mask[21] = mask[20] = 0xff;
11293       if (tag1)
11294         {
11295           mask[15] = 0xff;
11296           mask[14] = 0x0f;
11297         }
11298       if (cos1)
11299         mask[14] |= 0xe0;
11300       *maskp = mask;
11301       return 1;
11302     }
11303   if (tag1 | dot1q)
11304     {
11305       if (tag1)
11306         {
11307           mask[15] = 0xff;
11308           mask[14] = 0x0f;
11309         }
11310       if (cos1)
11311         mask[14] |= 0xe0;
11312       if (proto)
11313         mask[16] = mask[17] = 0xff;
11314
11315       *maskp = mask;
11316       return 1;
11317     }
11318   if (cos2)
11319     mask[18] |= 0xe0;
11320   if (cos1)
11321     mask[14] |= 0xe0;
11322   if (proto)
11323     mask[12] = mask[13] = 0xff;
11324
11325   *maskp = mask;
11326   return 1;
11327 }
11328
11329 uword
11330 unformat_classify_mask (unformat_input_t * input, va_list * args)
11331 {
11332   u8 **maskp = va_arg (*args, u8 **);
11333   u32 *skipp = va_arg (*args, u32 *);
11334   u32 *matchp = va_arg (*args, u32 *);
11335   u32 match;
11336   u8 *mask = 0;
11337   u8 *l2 = 0;
11338   u8 *l3 = 0;
11339   u8 *l4 = 0;
11340   int i;
11341
11342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11343     {
11344       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11345         ;
11346       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11347         ;
11348       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11349         ;
11350       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11351         ;
11352       else
11353         break;
11354     }
11355
11356   if (l4 && !l3)
11357     {
11358       vec_free (mask);
11359       vec_free (l2);
11360       vec_free (l4);
11361       return 0;
11362     }
11363
11364   if (mask || l2 || l3 || l4)
11365     {
11366       if (l2 || l3 || l4)
11367         {
11368           /* "With a free Ethernet header in every package" */
11369           if (l2 == 0)
11370             vec_validate (l2, 13);
11371           mask = l2;
11372           if (vec_len (l3))
11373             {
11374               vec_append (mask, l3);
11375               vec_free (l3);
11376             }
11377           if (vec_len (l4))
11378             {
11379               vec_append (mask, l4);
11380               vec_free (l4);
11381             }
11382         }
11383
11384       /* Scan forward looking for the first significant mask octet */
11385       for (i = 0; i < vec_len (mask); i++)
11386         if (mask[i])
11387           break;
11388
11389       /* compute (skip, match) params */
11390       *skipp = i / sizeof (u32x4);
11391       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11392
11393       /* Pad mask to an even multiple of the vector size */
11394       while (vec_len (mask) % sizeof (u32x4))
11395         vec_add1 (mask, 0);
11396
11397       match = vec_len (mask) / sizeof (u32x4);
11398
11399       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11400         {
11401           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11402           if (*tmp || *(tmp + 1))
11403             break;
11404           match--;
11405         }
11406       if (match == 0)
11407         clib_warning ("BUG: match 0");
11408
11409       _vec_len (mask) = match * sizeof (u32x4);
11410
11411       *matchp = match;
11412       *maskp = mask;
11413
11414       return 1;
11415     }
11416
11417   return 0;
11418 }
11419 #endif /* VPP_API_TEST_BUILTIN */
11420
11421 #define foreach_l2_next                         \
11422 _(drop, DROP)                                   \
11423 _(ethernet, ETHERNET_INPUT)                     \
11424 _(ip4, IP4_INPUT)                               \
11425 _(ip6, IP6_INPUT)
11426
11427 uword
11428 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11429 {
11430   u32 *miss_next_indexp = va_arg (*args, u32 *);
11431   u32 next_index = 0;
11432   u32 tmp;
11433
11434 #define _(n,N) \
11435   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11436   foreach_l2_next;
11437 #undef _
11438
11439   if (unformat (input, "%d", &tmp))
11440     {
11441       next_index = tmp;
11442       goto out;
11443     }
11444
11445   return 0;
11446
11447 out:
11448   *miss_next_indexp = next_index;
11449   return 1;
11450 }
11451
11452 #define foreach_ip_next                         \
11453 _(drop, DROP)                                   \
11454 _(local, LOCAL)                                 \
11455 _(rewrite, REWRITE)
11456
11457 uword
11458 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11459 {
11460   u32 *miss_next_indexp = va_arg (*args, u32 *);
11461   u32 next_index = 0;
11462   u32 tmp;
11463
11464 #define _(n,N) \
11465   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11466   foreach_ip_next;
11467 #undef _
11468
11469   if (unformat (input, "%d", &tmp))
11470     {
11471       next_index = tmp;
11472       goto out;
11473     }
11474
11475   return 0;
11476
11477 out:
11478   *miss_next_indexp = next_index;
11479   return 1;
11480 }
11481
11482 #define foreach_acl_next                        \
11483 _(deny, DENY)
11484
11485 uword
11486 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11487 {
11488   u32 *miss_next_indexp = va_arg (*args, u32 *);
11489   u32 next_index = 0;
11490   u32 tmp;
11491
11492 #define _(n,N) \
11493   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11494   foreach_acl_next;
11495 #undef _
11496
11497   if (unformat (input, "permit"))
11498     {
11499       next_index = ~0;
11500       goto out;
11501     }
11502   else if (unformat (input, "%d", &tmp))
11503     {
11504       next_index = tmp;
11505       goto out;
11506     }
11507
11508   return 0;
11509
11510 out:
11511   *miss_next_indexp = next_index;
11512   return 1;
11513 }
11514
11515 uword
11516 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11517 {
11518   u32 *r = va_arg (*args, u32 *);
11519
11520   if (unformat (input, "conform-color"))
11521     *r = POLICE_CONFORM;
11522   else if (unformat (input, "exceed-color"))
11523     *r = POLICE_EXCEED;
11524   else
11525     return 0;
11526
11527   return 1;
11528 }
11529
11530 static int
11531 api_classify_add_del_table (vat_main_t * vam)
11532 {
11533   unformat_input_t *i = vam->input;
11534   vl_api_classify_add_del_table_t *mp;
11535
11536   u32 nbuckets = 2;
11537   u32 skip = ~0;
11538   u32 match = ~0;
11539   int is_add = 1;
11540   int del_chain = 0;
11541   u32 table_index = ~0;
11542   u32 next_table_index = ~0;
11543   u32 miss_next_index = ~0;
11544   u32 memory_size = 32 << 20;
11545   u8 *mask = 0;
11546   u32 current_data_flag = 0;
11547   int current_data_offset = 0;
11548   int ret;
11549
11550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11551     {
11552       if (unformat (i, "del"))
11553         is_add = 0;
11554       else if (unformat (i, "del-chain"))
11555         {
11556           is_add = 0;
11557           del_chain = 1;
11558         }
11559       else if (unformat (i, "buckets %d", &nbuckets))
11560         ;
11561       else if (unformat (i, "memory_size %d", &memory_size))
11562         ;
11563       else if (unformat (i, "skip %d", &skip))
11564         ;
11565       else if (unformat (i, "match %d", &match))
11566         ;
11567       else if (unformat (i, "table %d", &table_index))
11568         ;
11569       else if (unformat (i, "mask %U", unformat_classify_mask,
11570                          &mask, &skip, &match))
11571         ;
11572       else if (unformat (i, "next-table %d", &next_table_index))
11573         ;
11574       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11575                          &miss_next_index))
11576         ;
11577       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11578                          &miss_next_index))
11579         ;
11580       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11581                          &miss_next_index))
11582         ;
11583       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11584         ;
11585       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11586         ;
11587       else
11588         break;
11589     }
11590
11591   if (is_add && mask == 0)
11592     {
11593       errmsg ("Mask required");
11594       return -99;
11595     }
11596
11597   if (is_add && skip == ~0)
11598     {
11599       errmsg ("skip count required");
11600       return -99;
11601     }
11602
11603   if (is_add && match == ~0)
11604     {
11605       errmsg ("match count required");
11606       return -99;
11607     }
11608
11609   if (!is_add && table_index == ~0)
11610     {
11611       errmsg ("table index required for delete");
11612       return -99;
11613     }
11614
11615   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11616
11617   mp->is_add = is_add;
11618   mp->del_chain = del_chain;
11619   mp->table_index = ntohl (table_index);
11620   mp->nbuckets = ntohl (nbuckets);
11621   mp->memory_size = ntohl (memory_size);
11622   mp->skip_n_vectors = ntohl (skip);
11623   mp->match_n_vectors = ntohl (match);
11624   mp->next_table_index = ntohl (next_table_index);
11625   mp->miss_next_index = ntohl (miss_next_index);
11626   mp->current_data_flag = ntohl (current_data_flag);
11627   mp->current_data_offset = ntohl (current_data_offset);
11628   clib_memcpy (mp->mask, mask, vec_len (mask));
11629
11630   vec_free (mask);
11631
11632   S (mp);
11633   W (ret);
11634   return ret;
11635 }
11636
11637 #if VPP_API_TEST_BUILTIN == 0
11638 uword
11639 unformat_l4_match (unformat_input_t * input, va_list * args)
11640 {
11641   u8 **matchp = va_arg (*args, u8 **);
11642
11643   u8 *proto_header = 0;
11644   int src_port = 0;
11645   int dst_port = 0;
11646
11647   tcpudp_header_t h;
11648
11649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11650     {
11651       if (unformat (input, "src_port %d", &src_port))
11652         ;
11653       else if (unformat (input, "dst_port %d", &dst_port))
11654         ;
11655       else
11656         return 0;
11657     }
11658
11659   h.src_port = clib_host_to_net_u16 (src_port);
11660   h.dst_port = clib_host_to_net_u16 (dst_port);
11661   vec_validate (proto_header, sizeof (h) - 1);
11662   memcpy (proto_header, &h, sizeof (h));
11663
11664   *matchp = proto_header;
11665
11666   return 1;
11667 }
11668
11669 uword
11670 unformat_ip4_match (unformat_input_t * input, va_list * args)
11671 {
11672   u8 **matchp = va_arg (*args, u8 **);
11673   u8 *match = 0;
11674   ip4_header_t *ip;
11675   int version = 0;
11676   u32 version_val;
11677   int hdr_length = 0;
11678   u32 hdr_length_val;
11679   int src = 0, dst = 0;
11680   ip4_address_t src_val, dst_val;
11681   int proto = 0;
11682   u32 proto_val;
11683   int tos = 0;
11684   u32 tos_val;
11685   int length = 0;
11686   u32 length_val;
11687   int fragment_id = 0;
11688   u32 fragment_id_val;
11689   int ttl = 0;
11690   int ttl_val;
11691   int checksum = 0;
11692   u32 checksum_val;
11693
11694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11695     {
11696       if (unformat (input, "version %d", &version_val))
11697         version = 1;
11698       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11699         hdr_length = 1;
11700       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11701         src = 1;
11702       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11703         dst = 1;
11704       else if (unformat (input, "proto %d", &proto_val))
11705         proto = 1;
11706       else if (unformat (input, "tos %d", &tos_val))
11707         tos = 1;
11708       else if (unformat (input, "length %d", &length_val))
11709         length = 1;
11710       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11711         fragment_id = 1;
11712       else if (unformat (input, "ttl %d", &ttl_val))
11713         ttl = 1;
11714       else if (unformat (input, "checksum %d", &checksum_val))
11715         checksum = 1;
11716       else
11717         break;
11718     }
11719
11720   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11721       + ttl + checksum == 0)
11722     return 0;
11723
11724   /*
11725    * Aligned because we use the real comparison functions
11726    */
11727   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11728
11729   ip = (ip4_header_t *) match;
11730
11731   /* These are realistically matched in practice */
11732   if (src)
11733     ip->src_address.as_u32 = src_val.as_u32;
11734
11735   if (dst)
11736     ip->dst_address.as_u32 = dst_val.as_u32;
11737
11738   if (proto)
11739     ip->protocol = proto_val;
11740
11741
11742   /* These are not, but they're included for completeness */
11743   if (version)
11744     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11745
11746   if (hdr_length)
11747     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11748
11749   if (tos)
11750     ip->tos = tos_val;
11751
11752   if (length)
11753     ip->length = clib_host_to_net_u16 (length_val);
11754
11755   if (ttl)
11756     ip->ttl = ttl_val;
11757
11758   if (checksum)
11759     ip->checksum = clib_host_to_net_u16 (checksum_val);
11760
11761   *matchp = match;
11762   return 1;
11763 }
11764
11765 uword
11766 unformat_ip6_match (unformat_input_t * input, va_list * args)
11767 {
11768   u8 **matchp = va_arg (*args, u8 **);
11769   u8 *match = 0;
11770   ip6_header_t *ip;
11771   int version = 0;
11772   u32 version_val;
11773   u8 traffic_class = 0;
11774   u32 traffic_class_val = 0;
11775   u8 flow_label = 0;
11776   u8 flow_label_val;
11777   int src = 0, dst = 0;
11778   ip6_address_t src_val, dst_val;
11779   int proto = 0;
11780   u32 proto_val;
11781   int payload_length = 0;
11782   u32 payload_length_val;
11783   int hop_limit = 0;
11784   int hop_limit_val;
11785   u32 ip_version_traffic_class_and_flow_label;
11786
11787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (input, "version %d", &version_val))
11790         version = 1;
11791       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11792         traffic_class = 1;
11793       else if (unformat (input, "flow_label %d", &flow_label_val))
11794         flow_label = 1;
11795       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11796         src = 1;
11797       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11798         dst = 1;
11799       else if (unformat (input, "proto %d", &proto_val))
11800         proto = 1;
11801       else if (unformat (input, "payload_length %d", &payload_length_val))
11802         payload_length = 1;
11803       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11804         hop_limit = 1;
11805       else
11806         break;
11807     }
11808
11809   if (version + traffic_class + flow_label + src + dst + proto +
11810       payload_length + hop_limit == 0)
11811     return 0;
11812
11813   /*
11814    * Aligned because we use the real comparison functions
11815    */
11816   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11817
11818   ip = (ip6_header_t *) match;
11819
11820   if (src)
11821     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11822
11823   if (dst)
11824     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11825
11826   if (proto)
11827     ip->protocol = proto_val;
11828
11829   ip_version_traffic_class_and_flow_label = 0;
11830
11831   if (version)
11832     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11833
11834   if (traffic_class)
11835     ip_version_traffic_class_and_flow_label |=
11836       (traffic_class_val & 0xFF) << 20;
11837
11838   if (flow_label)
11839     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11840
11841   ip->ip_version_traffic_class_and_flow_label =
11842     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11843
11844   if (payload_length)
11845     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11846
11847   if (hop_limit)
11848     ip->hop_limit = hop_limit_val;
11849
11850   *matchp = match;
11851   return 1;
11852 }
11853
11854 uword
11855 unformat_l3_match (unformat_input_t * input, va_list * args)
11856 {
11857   u8 **matchp = va_arg (*args, u8 **);
11858
11859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11862         return 1;
11863       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11864         return 1;
11865       else
11866         break;
11867     }
11868   return 0;
11869 }
11870
11871 uword
11872 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11873 {
11874   u8 *tagp = va_arg (*args, u8 *);
11875   u32 tag;
11876
11877   if (unformat (input, "%d", &tag))
11878     {
11879       tagp[0] = (tag >> 8) & 0x0F;
11880       tagp[1] = tag & 0xFF;
11881       return 1;
11882     }
11883
11884   return 0;
11885 }
11886
11887 uword
11888 unformat_l2_match (unformat_input_t * input, va_list * args)
11889 {
11890   u8 **matchp = va_arg (*args, u8 **);
11891   u8 *match = 0;
11892   u8 src = 0;
11893   u8 src_val[6];
11894   u8 dst = 0;
11895   u8 dst_val[6];
11896   u8 proto = 0;
11897   u16 proto_val;
11898   u8 tag1 = 0;
11899   u8 tag1_val[2];
11900   u8 tag2 = 0;
11901   u8 tag2_val[2];
11902   int len = 14;
11903   u8 ignore_tag1 = 0;
11904   u8 ignore_tag2 = 0;
11905   u8 cos1 = 0;
11906   u8 cos2 = 0;
11907   u32 cos1_val = 0;
11908   u32 cos2_val = 0;
11909
11910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11911     {
11912       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11913         src = 1;
11914       else
11915         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11916         dst = 1;
11917       else if (unformat (input, "proto %U",
11918                          unformat_ethernet_type_host_byte_order, &proto_val))
11919         proto = 1;
11920       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11921         tag1 = 1;
11922       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11923         tag2 = 1;
11924       else if (unformat (input, "ignore-tag1"))
11925         ignore_tag1 = 1;
11926       else if (unformat (input, "ignore-tag2"))
11927         ignore_tag2 = 1;
11928       else if (unformat (input, "cos1 %d", &cos1_val))
11929         cos1 = 1;
11930       else if (unformat (input, "cos2 %d", &cos2_val))
11931         cos2 = 1;
11932       else
11933         break;
11934     }
11935   if ((src + dst + proto + tag1 + tag2 +
11936        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11937     return 0;
11938
11939   if (tag1 || ignore_tag1 || cos1)
11940     len = 18;
11941   if (tag2 || ignore_tag2 || cos2)
11942     len = 22;
11943
11944   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11945
11946   if (dst)
11947     clib_memcpy (match, dst_val, 6);
11948
11949   if (src)
11950     clib_memcpy (match + 6, src_val, 6);
11951
11952   if (tag2)
11953     {
11954       /* inner vlan tag */
11955       match[19] = tag2_val[1];
11956       match[18] = tag2_val[0];
11957       if (cos2)
11958         match[18] |= (cos2_val & 0x7) << 5;
11959       if (proto)
11960         {
11961           match[21] = proto_val & 0xff;
11962           match[20] = proto_val >> 8;
11963         }
11964       if (tag1)
11965         {
11966           match[15] = tag1_val[1];
11967           match[14] = tag1_val[0];
11968         }
11969       if (cos1)
11970         match[14] |= (cos1_val & 0x7) << 5;
11971       *matchp = match;
11972       return 1;
11973     }
11974   if (tag1)
11975     {
11976       match[15] = tag1_val[1];
11977       match[14] = tag1_val[0];
11978       if (proto)
11979         {
11980           match[17] = proto_val & 0xff;
11981           match[16] = proto_val >> 8;
11982         }
11983       if (cos1)
11984         match[14] |= (cos1_val & 0x7) << 5;
11985
11986       *matchp = match;
11987       return 1;
11988     }
11989   if (cos2)
11990     match[18] |= (cos2_val & 0x7) << 5;
11991   if (cos1)
11992     match[14] |= (cos1_val & 0x7) << 5;
11993   if (proto)
11994     {
11995       match[13] = proto_val & 0xff;
11996       match[12] = proto_val >> 8;
11997     }
11998
11999   *matchp = match;
12000   return 1;
12001 }
12002
12003 uword
12004 unformat_qos_source (unformat_input_t * input, va_list * args)
12005 {
12006   int *qs = va_arg (*args, int *);
12007
12008   if (unformat (input, "ip"))
12009     *qs = QOS_SOURCE_IP;
12010   else if (unformat (input, "mpls"))
12011     *qs = QOS_SOURCE_MPLS;
12012   else if (unformat (input, "ext"))
12013     *qs = QOS_SOURCE_EXT;
12014   else if (unformat (input, "vlan"))
12015     *qs = QOS_SOURCE_VLAN;
12016   else
12017     return 0;
12018
12019   return 1;
12020 }
12021 #endif
12022
12023 uword
12024 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12025 {
12026   u8 **matchp = va_arg (*args, u8 **);
12027   u32 skip_n_vectors = va_arg (*args, u32);
12028   u32 match_n_vectors = va_arg (*args, u32);
12029
12030   u8 *match = 0;
12031   u8 *l2 = 0;
12032   u8 *l3 = 0;
12033   u8 *l4 = 0;
12034
12035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12036     {
12037       if (unformat (input, "hex %U", unformat_hex_string, &match))
12038         ;
12039       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12040         ;
12041       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12042         ;
12043       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12044         ;
12045       else
12046         break;
12047     }
12048
12049   if (l4 && !l3)
12050     {
12051       vec_free (match);
12052       vec_free (l2);
12053       vec_free (l4);
12054       return 0;
12055     }
12056
12057   if (match || l2 || l3 || l4)
12058     {
12059       if (l2 || l3 || l4)
12060         {
12061           /* "Win a free Ethernet header in every packet" */
12062           if (l2 == 0)
12063             vec_validate_aligned (l2, 13, sizeof (u32x4));
12064           match = l2;
12065           if (vec_len (l3))
12066             {
12067               vec_append_aligned (match, l3, sizeof (u32x4));
12068               vec_free (l3);
12069             }
12070           if (vec_len (l4))
12071             {
12072               vec_append_aligned (match, l4, sizeof (u32x4));
12073               vec_free (l4);
12074             }
12075         }
12076
12077       /* Make sure the vector is big enough even if key is all 0's */
12078       vec_validate_aligned
12079         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12080          sizeof (u32x4));
12081
12082       /* Set size, include skipped vectors */
12083       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12084
12085       *matchp = match;
12086
12087       return 1;
12088     }
12089
12090   return 0;
12091 }
12092
12093 static int
12094 api_classify_add_del_session (vat_main_t * vam)
12095 {
12096   unformat_input_t *i = vam->input;
12097   vl_api_classify_add_del_session_t *mp;
12098   int is_add = 1;
12099   u32 table_index = ~0;
12100   u32 hit_next_index = ~0;
12101   u32 opaque_index = ~0;
12102   u8 *match = 0;
12103   i32 advance = 0;
12104   u32 skip_n_vectors = 0;
12105   u32 match_n_vectors = 0;
12106   u32 action = 0;
12107   u32 metadata = 0;
12108   int ret;
12109
12110   /*
12111    * Warning: you have to supply skip_n and match_n
12112    * because the API client cant simply look at the classify
12113    * table object.
12114    */
12115
12116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12117     {
12118       if (unformat (i, "del"))
12119         is_add = 0;
12120       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12121                          &hit_next_index))
12122         ;
12123       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12124                          &hit_next_index))
12125         ;
12126       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12127                          &hit_next_index))
12128         ;
12129       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12130         ;
12131       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12132         ;
12133       else if (unformat (i, "opaque-index %d", &opaque_index))
12134         ;
12135       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12136         ;
12137       else if (unformat (i, "match_n %d", &match_n_vectors))
12138         ;
12139       else if (unformat (i, "match %U", api_unformat_classify_match,
12140                          &match, skip_n_vectors, match_n_vectors))
12141         ;
12142       else if (unformat (i, "advance %d", &advance))
12143         ;
12144       else if (unformat (i, "table-index %d", &table_index))
12145         ;
12146       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12147         action = 1;
12148       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12149         action = 2;
12150       else if (unformat (i, "action %d", &action))
12151         ;
12152       else if (unformat (i, "metadata %d", &metadata))
12153         ;
12154       else
12155         break;
12156     }
12157
12158   if (table_index == ~0)
12159     {
12160       errmsg ("Table index required");
12161       return -99;
12162     }
12163
12164   if (is_add && match == 0)
12165     {
12166       errmsg ("Match value required");
12167       return -99;
12168     }
12169
12170   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12171
12172   mp->is_add = is_add;
12173   mp->table_index = ntohl (table_index);
12174   mp->hit_next_index = ntohl (hit_next_index);
12175   mp->opaque_index = ntohl (opaque_index);
12176   mp->advance = ntohl (advance);
12177   mp->action = action;
12178   mp->metadata = ntohl (metadata);
12179   clib_memcpy (mp->match, match, vec_len (match));
12180   vec_free (match);
12181
12182   S (mp);
12183   W (ret);
12184   return ret;
12185 }
12186
12187 static int
12188 api_classify_set_interface_ip_table (vat_main_t * vam)
12189 {
12190   unformat_input_t *i = vam->input;
12191   vl_api_classify_set_interface_ip_table_t *mp;
12192   u32 sw_if_index;
12193   int sw_if_index_set;
12194   u32 table_index = ~0;
12195   u8 is_ipv6 = 0;
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, "table %d", &table_index))
12205         ;
12206       else
12207         {
12208           clib_warning ("parse error '%U'", format_unformat_error, i);
12209           return -99;
12210         }
12211     }
12212
12213   if (sw_if_index_set == 0)
12214     {
12215       errmsg ("missing interface name or sw_if_index");
12216       return -99;
12217     }
12218
12219
12220   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12221
12222   mp->sw_if_index = ntohl (sw_if_index);
12223   mp->table_index = ntohl (table_index);
12224   mp->is_ipv6 = is_ipv6;
12225
12226   S (mp);
12227   W (ret);
12228   return ret;
12229 }
12230
12231 static int
12232 api_classify_set_interface_l2_tables (vat_main_t * vam)
12233 {
12234   unformat_input_t *i = vam->input;
12235   vl_api_classify_set_interface_l2_tables_t *mp;
12236   u32 sw_if_index;
12237   int sw_if_index_set;
12238   u32 ip4_table_index = ~0;
12239   u32 ip6_table_index = ~0;
12240   u32 other_table_index = ~0;
12241   u32 is_input = 1;
12242   int ret;
12243
12244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12245     {
12246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12247         sw_if_index_set = 1;
12248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12249         sw_if_index_set = 1;
12250       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12251         ;
12252       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12253         ;
12254       else if (unformat (i, "other-table %d", &other_table_index))
12255         ;
12256       else if (unformat (i, "is-input %d", &is_input))
12257         ;
12258       else
12259         {
12260           clib_warning ("parse error '%U'", format_unformat_error, i);
12261           return -99;
12262         }
12263     }
12264
12265   if (sw_if_index_set == 0)
12266     {
12267       errmsg ("missing interface name or sw_if_index");
12268       return -99;
12269     }
12270
12271
12272   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12273
12274   mp->sw_if_index = ntohl (sw_if_index);
12275   mp->ip4_table_index = ntohl (ip4_table_index);
12276   mp->ip6_table_index = ntohl (ip6_table_index);
12277   mp->other_table_index = ntohl (other_table_index);
12278   mp->is_input = (u8) is_input;
12279
12280   S (mp);
12281   W (ret);
12282   return ret;
12283 }
12284
12285 static int
12286 api_set_ipfix_exporter (vat_main_t * vam)
12287 {
12288   unformat_input_t *i = vam->input;
12289   vl_api_set_ipfix_exporter_t *mp;
12290   ip4_address_t collector_address;
12291   u8 collector_address_set = 0;
12292   u32 collector_port = ~0;
12293   ip4_address_t src_address;
12294   u8 src_address_set = 0;
12295   u32 vrf_id = ~0;
12296   u32 path_mtu = ~0;
12297   u32 template_interval = ~0;
12298   u8 udp_checksum = 0;
12299   int ret;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "collector_address %U", unformat_ip4_address,
12304                     &collector_address))
12305         collector_address_set = 1;
12306       else if (unformat (i, "collector_port %d", &collector_port))
12307         ;
12308       else if (unformat (i, "src_address %U", unformat_ip4_address,
12309                          &src_address))
12310         src_address_set = 1;
12311       else if (unformat (i, "vrf_id %d", &vrf_id))
12312         ;
12313       else if (unformat (i, "path_mtu %d", &path_mtu))
12314         ;
12315       else if (unformat (i, "template_interval %d", &template_interval))
12316         ;
12317       else if (unformat (i, "udp_checksum"))
12318         udp_checksum = 1;
12319       else
12320         break;
12321     }
12322
12323   if (collector_address_set == 0)
12324     {
12325       errmsg ("collector_address required");
12326       return -99;
12327     }
12328
12329   if (src_address_set == 0)
12330     {
12331       errmsg ("src_address required");
12332       return -99;
12333     }
12334
12335   M (SET_IPFIX_EXPORTER, mp);
12336
12337   memcpy (mp->collector_address, collector_address.data,
12338           sizeof (collector_address.data));
12339   mp->collector_port = htons ((u16) collector_port);
12340   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12341   mp->vrf_id = htonl (vrf_id);
12342   mp->path_mtu = htonl (path_mtu);
12343   mp->template_interval = htonl (template_interval);
12344   mp->udp_checksum = udp_checksum;
12345
12346   S (mp);
12347   W (ret);
12348   return ret;
12349 }
12350
12351 static int
12352 api_set_ipfix_classify_stream (vat_main_t * vam)
12353 {
12354   unformat_input_t *i = vam->input;
12355   vl_api_set_ipfix_classify_stream_t *mp;
12356   u32 domain_id = 0;
12357   u32 src_port = UDP_DST_PORT_ipfix;
12358   int ret;
12359
12360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12361     {
12362       if (unformat (i, "domain %d", &domain_id))
12363         ;
12364       else if (unformat (i, "src_port %d", &src_port))
12365         ;
12366       else
12367         {
12368           errmsg ("unknown input `%U'", format_unformat_error, i);
12369           return -99;
12370         }
12371     }
12372
12373   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12374
12375   mp->domain_id = htonl (domain_id);
12376   mp->src_port = htons ((u16) src_port);
12377
12378   S (mp);
12379   W (ret);
12380   return ret;
12381 }
12382
12383 static int
12384 api_ipfix_classify_table_add_del (vat_main_t * vam)
12385 {
12386   unformat_input_t *i = vam->input;
12387   vl_api_ipfix_classify_table_add_del_t *mp;
12388   int is_add = -1;
12389   u32 classify_table_index = ~0;
12390   u8 ip_version = 0;
12391   u8 transport_protocol = 255;
12392   int ret;
12393
12394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12395     {
12396       if (unformat (i, "add"))
12397         is_add = 1;
12398       else if (unformat (i, "del"))
12399         is_add = 0;
12400       else if (unformat (i, "table %d", &classify_table_index))
12401         ;
12402       else if (unformat (i, "ip4"))
12403         ip_version = 4;
12404       else if (unformat (i, "ip6"))
12405         ip_version = 6;
12406       else if (unformat (i, "tcp"))
12407         transport_protocol = 6;
12408       else if (unformat (i, "udp"))
12409         transport_protocol = 17;
12410       else
12411         {
12412           errmsg ("unknown input `%U'", format_unformat_error, i);
12413           return -99;
12414         }
12415     }
12416
12417   if (is_add == -1)
12418     {
12419       errmsg ("expecting: add|del");
12420       return -99;
12421     }
12422   if (classify_table_index == ~0)
12423     {
12424       errmsg ("classifier table not specified");
12425       return -99;
12426     }
12427   if (ip_version == 0)
12428     {
12429       errmsg ("IP version not specified");
12430       return -99;
12431     }
12432
12433   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12434
12435   mp->is_add = is_add;
12436   mp->table_id = htonl (classify_table_index);
12437   mp->ip_version = ip_version;
12438   mp->transport_protocol = transport_protocol;
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445 static int
12446 api_get_node_index (vat_main_t * vam)
12447 {
12448   unformat_input_t *i = vam->input;
12449   vl_api_get_node_index_t *mp;
12450   u8 *name = 0;
12451   int ret;
12452
12453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12454     {
12455       if (unformat (i, "node %s", &name))
12456         ;
12457       else
12458         break;
12459     }
12460   if (name == 0)
12461     {
12462       errmsg ("node name required");
12463       return -99;
12464     }
12465   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12466     {
12467       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12468       return -99;
12469     }
12470
12471   M (GET_NODE_INDEX, mp);
12472   clib_memcpy (mp->node_name, name, vec_len (name));
12473   vec_free (name);
12474
12475   S (mp);
12476   W (ret);
12477   return ret;
12478 }
12479
12480 static int
12481 api_get_next_index (vat_main_t * vam)
12482 {
12483   unformat_input_t *i = vam->input;
12484   vl_api_get_next_index_t *mp;
12485   u8 *node_name = 0, *next_node_name = 0;
12486   int ret;
12487
12488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12489     {
12490       if (unformat (i, "node-name %s", &node_name))
12491         ;
12492       else if (unformat (i, "next-node-name %s", &next_node_name))
12493         break;
12494     }
12495
12496   if (node_name == 0)
12497     {
12498       errmsg ("node name required");
12499       return -99;
12500     }
12501   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12502     {
12503       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12504       return -99;
12505     }
12506
12507   if (next_node_name == 0)
12508     {
12509       errmsg ("next node name required");
12510       return -99;
12511     }
12512   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12513     {
12514       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12515       return -99;
12516     }
12517
12518   M (GET_NEXT_INDEX, mp);
12519   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12520   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12521   vec_free (node_name);
12522   vec_free (next_node_name);
12523
12524   S (mp);
12525   W (ret);
12526   return ret;
12527 }
12528
12529 static int
12530 api_add_node_next (vat_main_t * vam)
12531 {
12532   unformat_input_t *i = vam->input;
12533   vl_api_add_node_next_t *mp;
12534   u8 *name = 0;
12535   u8 *next = 0;
12536   int ret;
12537
12538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12539     {
12540       if (unformat (i, "node %s", &name))
12541         ;
12542       else if (unformat (i, "next %s", &next))
12543         ;
12544       else
12545         break;
12546     }
12547   if (name == 0)
12548     {
12549       errmsg ("node name required");
12550       return -99;
12551     }
12552   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12553     {
12554       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12555       return -99;
12556     }
12557   if (next == 0)
12558     {
12559       errmsg ("next node required");
12560       return -99;
12561     }
12562   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12563     {
12564       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12565       return -99;
12566     }
12567
12568   M (ADD_NODE_NEXT, mp);
12569   clib_memcpy (mp->node_name, name, vec_len (name));
12570   clib_memcpy (mp->next_name, next, vec_len (next));
12571   vec_free (name);
12572   vec_free (next);
12573
12574   S (mp);
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static int
12580 api_l2tpv3_create_tunnel (vat_main_t * vam)
12581 {
12582   unformat_input_t *i = vam->input;
12583   ip6_address_t client_address, our_address;
12584   int client_address_set = 0;
12585   int our_address_set = 0;
12586   u32 local_session_id = 0;
12587   u32 remote_session_id = 0;
12588   u64 local_cookie = 0;
12589   u64 remote_cookie = 0;
12590   u8 l2_sublayer_present = 0;
12591   vl_api_l2tpv3_create_tunnel_t *mp;
12592   int ret;
12593
12594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12595     {
12596       if (unformat (i, "client_address %U", unformat_ip6_address,
12597                     &client_address))
12598         client_address_set = 1;
12599       else if (unformat (i, "our_address %U", unformat_ip6_address,
12600                          &our_address))
12601         our_address_set = 1;
12602       else if (unformat (i, "local_session_id %d", &local_session_id))
12603         ;
12604       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12605         ;
12606       else if (unformat (i, "local_cookie %lld", &local_cookie))
12607         ;
12608       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12609         ;
12610       else if (unformat (i, "l2-sublayer-present"))
12611         l2_sublayer_present = 1;
12612       else
12613         break;
12614     }
12615
12616   if (client_address_set == 0)
12617     {
12618       errmsg ("client_address required");
12619       return -99;
12620     }
12621
12622   if (our_address_set == 0)
12623     {
12624       errmsg ("our_address required");
12625       return -99;
12626     }
12627
12628   M (L2TPV3_CREATE_TUNNEL, mp);
12629
12630   clib_memcpy (mp->client_address, client_address.as_u8,
12631                sizeof (mp->client_address));
12632
12633   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12634
12635   mp->local_session_id = ntohl (local_session_id);
12636   mp->remote_session_id = ntohl (remote_session_id);
12637   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12638   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12639   mp->l2_sublayer_present = l2_sublayer_present;
12640   mp->is_ipv6 = 1;
12641
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static int
12648 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12649 {
12650   unformat_input_t *i = vam->input;
12651   u32 sw_if_index;
12652   u8 sw_if_index_set = 0;
12653   u64 new_local_cookie = 0;
12654   u64 new_remote_cookie = 0;
12655   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12656   int ret;
12657
12658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12659     {
12660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12661         sw_if_index_set = 1;
12662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12663         sw_if_index_set = 1;
12664       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12665         ;
12666       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12667         ;
12668       else
12669         break;
12670     }
12671
12672   if (sw_if_index_set == 0)
12673     {
12674       errmsg ("missing interface name or sw_if_index");
12675       return -99;
12676     }
12677
12678   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12679
12680   mp->sw_if_index = ntohl (sw_if_index);
12681   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12682   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12683
12684   S (mp);
12685   W (ret);
12686   return ret;
12687 }
12688
12689 static int
12690 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12691 {
12692   unformat_input_t *i = vam->input;
12693   vl_api_l2tpv3_interface_enable_disable_t *mp;
12694   u32 sw_if_index;
12695   u8 sw_if_index_set = 0;
12696   u8 enable_disable = 1;
12697   int ret;
12698
12699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12702         sw_if_index_set = 1;
12703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12704         sw_if_index_set = 1;
12705       else if (unformat (i, "enable"))
12706         enable_disable = 1;
12707       else if (unformat (i, "disable"))
12708         enable_disable = 0;
12709       else
12710         break;
12711     }
12712
12713   if (sw_if_index_set == 0)
12714     {
12715       errmsg ("missing interface name or sw_if_index");
12716       return -99;
12717     }
12718
12719   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12720
12721   mp->sw_if_index = ntohl (sw_if_index);
12722   mp->enable_disable = enable_disable;
12723
12724   S (mp);
12725   W (ret);
12726   return ret;
12727 }
12728
12729 static int
12730 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12731 {
12732   unformat_input_t *i = vam->input;
12733   vl_api_l2tpv3_set_lookup_key_t *mp;
12734   u8 key = ~0;
12735   int ret;
12736
12737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12738     {
12739       if (unformat (i, "lookup_v6_src"))
12740         key = L2T_LOOKUP_SRC_ADDRESS;
12741       else if (unformat (i, "lookup_v6_dst"))
12742         key = L2T_LOOKUP_DST_ADDRESS;
12743       else if (unformat (i, "lookup_session_id"))
12744         key = L2T_LOOKUP_SESSION_ID;
12745       else
12746         break;
12747     }
12748
12749   if (key == (u8) ~ 0)
12750     {
12751       errmsg ("l2tp session lookup key unset");
12752       return -99;
12753     }
12754
12755   M (L2TPV3_SET_LOOKUP_KEY, mp);
12756
12757   mp->key = key;
12758
12759   S (mp);
12760   W (ret);
12761   return ret;
12762 }
12763
12764 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12765   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12766 {
12767   vat_main_t *vam = &vat_main;
12768
12769   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12770          format_ip6_address, mp->our_address,
12771          format_ip6_address, mp->client_address,
12772          clib_net_to_host_u32 (mp->sw_if_index));
12773
12774   print (vam->ofp,
12775          "   local cookies %016llx %016llx remote cookie %016llx",
12776          clib_net_to_host_u64 (mp->local_cookie[0]),
12777          clib_net_to_host_u64 (mp->local_cookie[1]),
12778          clib_net_to_host_u64 (mp->remote_cookie));
12779
12780   print (vam->ofp, "   local session-id %d remote session-id %d",
12781          clib_net_to_host_u32 (mp->local_session_id),
12782          clib_net_to_host_u32 (mp->remote_session_id));
12783
12784   print (vam->ofp, "   l2 specific sublayer %s\n",
12785          mp->l2_sublayer_present ? "preset" : "absent");
12786
12787 }
12788
12789 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12790   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12791 {
12792   vat_main_t *vam = &vat_main;
12793   vat_json_node_t *node = NULL;
12794   struct in6_addr addr;
12795
12796   if (VAT_JSON_ARRAY != vam->json_tree.type)
12797     {
12798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12799       vat_json_init_array (&vam->json_tree);
12800     }
12801   node = vat_json_array_add (&vam->json_tree);
12802
12803   vat_json_init_object (node);
12804
12805   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12806   vat_json_object_add_ip6 (node, "our_address", addr);
12807   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12808   vat_json_object_add_ip6 (node, "client_address", addr);
12809
12810   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12811   vat_json_init_array (lc);
12812   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12813   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12814   vat_json_object_add_uint (node, "remote_cookie",
12815                             clib_net_to_host_u64 (mp->remote_cookie));
12816
12817   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12818   vat_json_object_add_uint (node, "local_session_id",
12819                             clib_net_to_host_u32 (mp->local_session_id));
12820   vat_json_object_add_uint (node, "remote_session_id",
12821                             clib_net_to_host_u32 (mp->remote_session_id));
12822   vat_json_object_add_string_copy (node, "l2_sublayer",
12823                                    mp->l2_sublayer_present ? (u8 *) "present"
12824                                    : (u8 *) "absent");
12825 }
12826
12827 static int
12828 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12829 {
12830   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12831   vl_api_control_ping_t *mp_ping;
12832   int ret;
12833
12834   /* Get list of l2tpv3-tunnel interfaces */
12835   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12836   S (mp);
12837
12838   /* Use a control ping for synchronization */
12839   MPING (CONTROL_PING, mp_ping);
12840   S (mp_ping);
12841
12842   W (ret);
12843   return ret;
12844 }
12845
12846
12847 static void vl_api_sw_interface_tap_details_t_handler
12848   (vl_api_sw_interface_tap_details_t * mp)
12849 {
12850   vat_main_t *vam = &vat_main;
12851
12852   print (vam->ofp, "%-16s %d",
12853          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12854 }
12855
12856 static void vl_api_sw_interface_tap_details_t_handler_json
12857   (vl_api_sw_interface_tap_details_t * mp)
12858 {
12859   vat_main_t *vam = &vat_main;
12860   vat_json_node_t *node = NULL;
12861
12862   if (VAT_JSON_ARRAY != vam->json_tree.type)
12863     {
12864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12865       vat_json_init_array (&vam->json_tree);
12866     }
12867   node = vat_json_array_add (&vam->json_tree);
12868
12869   vat_json_init_object (node);
12870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12871   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12872 }
12873
12874 static int
12875 api_sw_interface_tap_dump (vat_main_t * vam)
12876 {
12877   vl_api_sw_interface_tap_dump_t *mp;
12878   vl_api_control_ping_t *mp_ping;
12879   int ret;
12880
12881   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12882   /* Get list of tap interfaces */
12883   M (SW_INTERFACE_TAP_DUMP, mp);
12884   S (mp);
12885
12886   /* Use a control ping for synchronization */
12887   MPING (CONTROL_PING, mp_ping);
12888   S (mp_ping);
12889
12890   W (ret);
12891   return ret;
12892 }
12893
12894 static void vl_api_sw_interface_tap_v2_details_t_handler
12895   (vl_api_sw_interface_tap_v2_details_t * mp)
12896 {
12897   vat_main_t *vam = &vat_main;
12898
12899   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12900                     mp->host_ip4_prefix_len);
12901   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12902                     mp->host_ip6_prefix_len);
12903
12904   print (vam->ofp,
12905          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12906          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12907          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12908          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12909          mp->host_bridge, ip4, ip6);
12910
12911   vec_free (ip4);
12912   vec_free (ip6);
12913 }
12914
12915 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12916   (vl_api_sw_interface_tap_v2_details_t * mp)
12917 {
12918   vat_main_t *vam = &vat_main;
12919   vat_json_node_t *node = NULL;
12920
12921   if (VAT_JSON_ARRAY != vam->json_tree.type)
12922     {
12923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12924       vat_json_init_array (&vam->json_tree);
12925     }
12926   node = vat_json_array_add (&vam->json_tree);
12927
12928   vat_json_init_object (node);
12929   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12930   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12931   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12932   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12933   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12934   vat_json_object_add_string_copy (node, "host_mac_addr",
12935                                    format (0, "%U", format_ethernet_address,
12936                                            &mp->host_mac_addr));
12937   vat_json_object_add_string_copy (node, "host_namespace",
12938                                    mp->host_namespace);
12939   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12940   vat_json_object_add_string_copy (node, "host_ip4_addr",
12941                                    format (0, "%U/%d", format_ip4_address,
12942                                            mp->host_ip4_addr,
12943                                            mp->host_ip4_prefix_len));
12944   vat_json_object_add_string_copy (node, "host_ip6_addr",
12945                                    format (0, "%U/%d", format_ip6_address,
12946                                            mp->host_ip6_addr,
12947                                            mp->host_ip6_prefix_len));
12948
12949 }
12950
12951 static int
12952 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12953 {
12954   vl_api_sw_interface_tap_v2_dump_t *mp;
12955   vl_api_control_ping_t *mp_ping;
12956   int ret;
12957
12958   print (vam->ofp,
12959          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12960          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12961          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12962          "host_ip6_addr");
12963
12964   /* Get list of tap interfaces */
12965   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12966   S (mp);
12967
12968   /* Use a control ping for synchronization */
12969   MPING (CONTROL_PING, mp_ping);
12970   S (mp_ping);
12971
12972   W (ret);
12973   return ret;
12974 }
12975
12976 static uword unformat_vxlan_decap_next
12977   (unformat_input_t * input, va_list * args)
12978 {
12979   u32 *result = va_arg (*args, u32 *);
12980   u32 tmp;
12981
12982   if (unformat (input, "l2"))
12983     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12984   else if (unformat (input, "%d", &tmp))
12985     *result = tmp;
12986   else
12987     return 0;
12988   return 1;
12989 }
12990
12991 static int
12992 api_vxlan_add_del_tunnel (vat_main_t * vam)
12993 {
12994   unformat_input_t *line_input = vam->input;
12995   vl_api_vxlan_add_del_tunnel_t *mp;
12996   ip46_address_t src, dst;
12997   u8 is_add = 1;
12998   u8 ipv4_set = 0, ipv6_set = 0;
12999   u8 src_set = 0;
13000   u8 dst_set = 0;
13001   u8 grp_set = 0;
13002   u32 instance = ~0;
13003   u32 mcast_sw_if_index = ~0;
13004   u32 encap_vrf_id = 0;
13005   u32 decap_next_index = ~0;
13006   u32 vni = 0;
13007   int ret;
13008
13009   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13010   memset (&src, 0, sizeof src);
13011   memset (&dst, 0, sizeof dst);
13012
13013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13014     {
13015       if (unformat (line_input, "del"))
13016         is_add = 0;
13017       else if (unformat (line_input, "instance %d", &instance))
13018         ;
13019       else
13020         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13021         {
13022           ipv4_set = 1;
13023           src_set = 1;
13024         }
13025       else
13026         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13027         {
13028           ipv4_set = 1;
13029           dst_set = 1;
13030         }
13031       else
13032         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13033         {
13034           ipv6_set = 1;
13035           src_set = 1;
13036         }
13037       else
13038         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13039         {
13040           ipv6_set = 1;
13041           dst_set = 1;
13042         }
13043       else if (unformat (line_input, "group %U %U",
13044                          unformat_ip4_address, &dst.ip4,
13045                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13046         {
13047           grp_set = dst_set = 1;
13048           ipv4_set = 1;
13049         }
13050       else if (unformat (line_input, "group %U",
13051                          unformat_ip4_address, &dst.ip4))
13052         {
13053           grp_set = dst_set = 1;
13054           ipv4_set = 1;
13055         }
13056       else if (unformat (line_input, "group %U %U",
13057                          unformat_ip6_address, &dst.ip6,
13058                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13059         {
13060           grp_set = dst_set = 1;
13061           ipv6_set = 1;
13062         }
13063       else if (unformat (line_input, "group %U",
13064                          unformat_ip6_address, &dst.ip6))
13065         {
13066           grp_set = dst_set = 1;
13067           ipv6_set = 1;
13068         }
13069       else
13070         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13071         ;
13072       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13073         ;
13074       else if (unformat (line_input, "decap-next %U",
13075                          unformat_vxlan_decap_next, &decap_next_index))
13076         ;
13077       else if (unformat (line_input, "vni %d", &vni))
13078         ;
13079       else
13080         {
13081           errmsg ("parse error '%U'", format_unformat_error, line_input);
13082           return -99;
13083         }
13084     }
13085
13086   if (src_set == 0)
13087     {
13088       errmsg ("tunnel src address not specified");
13089       return -99;
13090     }
13091   if (dst_set == 0)
13092     {
13093       errmsg ("tunnel dst address not specified");
13094       return -99;
13095     }
13096
13097   if (grp_set && !ip46_address_is_multicast (&dst))
13098     {
13099       errmsg ("tunnel group address not multicast");
13100       return -99;
13101     }
13102   if (grp_set && mcast_sw_if_index == ~0)
13103     {
13104       errmsg ("tunnel nonexistent multicast device");
13105       return -99;
13106     }
13107   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13108     {
13109       errmsg ("tunnel dst address must be unicast");
13110       return -99;
13111     }
13112
13113
13114   if (ipv4_set && ipv6_set)
13115     {
13116       errmsg ("both IPv4 and IPv6 addresses specified");
13117       return -99;
13118     }
13119
13120   if ((vni == 0) || (vni >> 24))
13121     {
13122       errmsg ("vni not specified or out of range");
13123       return -99;
13124     }
13125
13126   M (VXLAN_ADD_DEL_TUNNEL, mp);
13127
13128   if (ipv6_set)
13129     {
13130       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13131       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13132     }
13133   else
13134     {
13135       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13136       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13137     }
13138
13139   mp->instance = htonl (instance);
13140   mp->encap_vrf_id = ntohl (encap_vrf_id);
13141   mp->decap_next_index = ntohl (decap_next_index);
13142   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13143   mp->vni = ntohl (vni);
13144   mp->is_add = is_add;
13145   mp->is_ipv6 = ipv6_set;
13146
13147   S (mp);
13148   W (ret);
13149   return ret;
13150 }
13151
13152 static void vl_api_vxlan_tunnel_details_t_handler
13153   (vl_api_vxlan_tunnel_details_t * mp)
13154 {
13155   vat_main_t *vam = &vat_main;
13156   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13157   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13158
13159   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13160          ntohl (mp->sw_if_index),
13161          ntohl (mp->instance),
13162          format_ip46_address, &src, IP46_TYPE_ANY,
13163          format_ip46_address, &dst, IP46_TYPE_ANY,
13164          ntohl (mp->encap_vrf_id),
13165          ntohl (mp->decap_next_index), ntohl (mp->vni),
13166          ntohl (mp->mcast_sw_if_index));
13167 }
13168
13169 static void vl_api_vxlan_tunnel_details_t_handler_json
13170   (vl_api_vxlan_tunnel_details_t * mp)
13171 {
13172   vat_main_t *vam = &vat_main;
13173   vat_json_node_t *node = NULL;
13174
13175   if (VAT_JSON_ARRAY != vam->json_tree.type)
13176     {
13177       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13178       vat_json_init_array (&vam->json_tree);
13179     }
13180   node = vat_json_array_add (&vam->json_tree);
13181
13182   vat_json_init_object (node);
13183   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13184
13185   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13186
13187   if (mp->is_ipv6)
13188     {
13189       struct in6_addr ip6;
13190
13191       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13192       vat_json_object_add_ip6 (node, "src_address", ip6);
13193       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13194       vat_json_object_add_ip6 (node, "dst_address", ip6);
13195     }
13196   else
13197     {
13198       struct in_addr ip4;
13199
13200       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13201       vat_json_object_add_ip4 (node, "src_address", ip4);
13202       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13203       vat_json_object_add_ip4 (node, "dst_address", ip4);
13204     }
13205   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13206   vat_json_object_add_uint (node, "decap_next_index",
13207                             ntohl (mp->decap_next_index));
13208   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13209   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13210   vat_json_object_add_uint (node, "mcast_sw_if_index",
13211                             ntohl (mp->mcast_sw_if_index));
13212 }
13213
13214 static int
13215 api_vxlan_tunnel_dump (vat_main_t * vam)
13216 {
13217   unformat_input_t *i = vam->input;
13218   vl_api_vxlan_tunnel_dump_t *mp;
13219   vl_api_control_ping_t *mp_ping;
13220   u32 sw_if_index;
13221   u8 sw_if_index_set = 0;
13222   int ret;
13223
13224   /* Parse args required to build the message */
13225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13226     {
13227       if (unformat (i, "sw_if_index %d", &sw_if_index))
13228         sw_if_index_set = 1;
13229       else
13230         break;
13231     }
13232
13233   if (sw_if_index_set == 0)
13234     {
13235       sw_if_index = ~0;
13236     }
13237
13238   if (!vam->json_output)
13239     {
13240       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13241              "sw_if_index", "instance", "src_address", "dst_address",
13242              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13243     }
13244
13245   /* Get list of vxlan-tunnel interfaces */
13246   M (VXLAN_TUNNEL_DUMP, mp);
13247
13248   mp->sw_if_index = htonl (sw_if_index);
13249
13250   S (mp);
13251
13252   /* Use a control ping for synchronization */
13253   MPING (CONTROL_PING, mp_ping);
13254   S (mp_ping);
13255
13256   W (ret);
13257   return ret;
13258 }
13259
13260 static uword unformat_geneve_decap_next
13261   (unformat_input_t * input, va_list * args)
13262 {
13263   u32 *result = va_arg (*args, u32 *);
13264   u32 tmp;
13265
13266   if (unformat (input, "l2"))
13267     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13268   else if (unformat (input, "%d", &tmp))
13269     *result = tmp;
13270   else
13271     return 0;
13272   return 1;
13273 }
13274
13275 static int
13276 api_geneve_add_del_tunnel (vat_main_t * vam)
13277 {
13278   unformat_input_t *line_input = vam->input;
13279   vl_api_geneve_add_del_tunnel_t *mp;
13280   ip46_address_t src, dst;
13281   u8 is_add = 1;
13282   u8 ipv4_set = 0, ipv6_set = 0;
13283   u8 src_set = 0;
13284   u8 dst_set = 0;
13285   u8 grp_set = 0;
13286   u32 mcast_sw_if_index = ~0;
13287   u32 encap_vrf_id = 0;
13288   u32 decap_next_index = ~0;
13289   u32 vni = 0;
13290   int ret;
13291
13292   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13293   memset (&src, 0, sizeof src);
13294   memset (&dst, 0, sizeof dst);
13295
13296   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (line_input, "del"))
13299         is_add = 0;
13300       else
13301         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13302         {
13303           ipv4_set = 1;
13304           src_set = 1;
13305         }
13306       else
13307         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13308         {
13309           ipv4_set = 1;
13310           dst_set = 1;
13311         }
13312       else
13313         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13314         {
13315           ipv6_set = 1;
13316           src_set = 1;
13317         }
13318       else
13319         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13320         {
13321           ipv6_set = 1;
13322           dst_set = 1;
13323         }
13324       else if (unformat (line_input, "group %U %U",
13325                          unformat_ip4_address, &dst.ip4,
13326                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13327         {
13328           grp_set = dst_set = 1;
13329           ipv4_set = 1;
13330         }
13331       else if (unformat (line_input, "group %U",
13332                          unformat_ip4_address, &dst.ip4))
13333         {
13334           grp_set = dst_set = 1;
13335           ipv4_set = 1;
13336         }
13337       else if (unformat (line_input, "group %U %U",
13338                          unformat_ip6_address, &dst.ip6,
13339                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13340         {
13341           grp_set = dst_set = 1;
13342           ipv6_set = 1;
13343         }
13344       else if (unformat (line_input, "group %U",
13345                          unformat_ip6_address, &dst.ip6))
13346         {
13347           grp_set = dst_set = 1;
13348           ipv6_set = 1;
13349         }
13350       else
13351         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13352         ;
13353       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13354         ;
13355       else if (unformat (line_input, "decap-next %U",
13356                          unformat_geneve_decap_next, &decap_next_index))
13357         ;
13358       else if (unformat (line_input, "vni %d", &vni))
13359         ;
13360       else
13361         {
13362           errmsg ("parse error '%U'", format_unformat_error, line_input);
13363           return -99;
13364         }
13365     }
13366
13367   if (src_set == 0)
13368     {
13369       errmsg ("tunnel src address not specified");
13370       return -99;
13371     }
13372   if (dst_set == 0)
13373     {
13374       errmsg ("tunnel dst address not specified");
13375       return -99;
13376     }
13377
13378   if (grp_set && !ip46_address_is_multicast (&dst))
13379     {
13380       errmsg ("tunnel group address not multicast");
13381       return -99;
13382     }
13383   if (grp_set && mcast_sw_if_index == ~0)
13384     {
13385       errmsg ("tunnel nonexistent multicast device");
13386       return -99;
13387     }
13388   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13389     {
13390       errmsg ("tunnel dst address must be unicast");
13391       return -99;
13392     }
13393
13394
13395   if (ipv4_set && ipv6_set)
13396     {
13397       errmsg ("both IPv4 and IPv6 addresses specified");
13398       return -99;
13399     }
13400
13401   if ((vni == 0) || (vni >> 24))
13402     {
13403       errmsg ("vni not specified or out of range");
13404       return -99;
13405     }
13406
13407   M (GENEVE_ADD_DEL_TUNNEL, mp);
13408
13409   if (ipv6_set)
13410     {
13411       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13412       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13413     }
13414   else
13415     {
13416       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13417       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13418     }
13419   mp->encap_vrf_id = ntohl (encap_vrf_id);
13420   mp->decap_next_index = ntohl (decap_next_index);
13421   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13422   mp->vni = ntohl (vni);
13423   mp->is_add = is_add;
13424   mp->is_ipv6 = ipv6_set;
13425
13426   S (mp);
13427   W (ret);
13428   return ret;
13429 }
13430
13431 static void vl_api_geneve_tunnel_details_t_handler
13432   (vl_api_geneve_tunnel_details_t * mp)
13433 {
13434   vat_main_t *vam = &vat_main;
13435   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13436   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13437
13438   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13439          ntohl (mp->sw_if_index),
13440          format_ip46_address, &src, IP46_TYPE_ANY,
13441          format_ip46_address, &dst, IP46_TYPE_ANY,
13442          ntohl (mp->encap_vrf_id),
13443          ntohl (mp->decap_next_index), ntohl (mp->vni),
13444          ntohl (mp->mcast_sw_if_index));
13445 }
13446
13447 static void vl_api_geneve_tunnel_details_t_handler_json
13448   (vl_api_geneve_tunnel_details_t * mp)
13449 {
13450   vat_main_t *vam = &vat_main;
13451   vat_json_node_t *node = NULL;
13452
13453   if (VAT_JSON_ARRAY != vam->json_tree.type)
13454     {
13455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13456       vat_json_init_array (&vam->json_tree);
13457     }
13458   node = vat_json_array_add (&vam->json_tree);
13459
13460   vat_json_init_object (node);
13461   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13462   if (mp->is_ipv6)
13463     {
13464       struct in6_addr ip6;
13465
13466       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13467       vat_json_object_add_ip6 (node, "src_address", ip6);
13468       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13469       vat_json_object_add_ip6 (node, "dst_address", ip6);
13470     }
13471   else
13472     {
13473       struct in_addr ip4;
13474
13475       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13476       vat_json_object_add_ip4 (node, "src_address", ip4);
13477       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13478       vat_json_object_add_ip4 (node, "dst_address", ip4);
13479     }
13480   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13481   vat_json_object_add_uint (node, "decap_next_index",
13482                             ntohl (mp->decap_next_index));
13483   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13484   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13485   vat_json_object_add_uint (node, "mcast_sw_if_index",
13486                             ntohl (mp->mcast_sw_if_index));
13487 }
13488
13489 static int
13490 api_geneve_tunnel_dump (vat_main_t * vam)
13491 {
13492   unformat_input_t *i = vam->input;
13493   vl_api_geneve_tunnel_dump_t *mp;
13494   vl_api_control_ping_t *mp_ping;
13495   u32 sw_if_index;
13496   u8 sw_if_index_set = 0;
13497   int ret;
13498
13499   /* Parse args required to build the message */
13500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13501     {
13502       if (unformat (i, "sw_if_index %d", &sw_if_index))
13503         sw_if_index_set = 1;
13504       else
13505         break;
13506     }
13507
13508   if (sw_if_index_set == 0)
13509     {
13510       sw_if_index = ~0;
13511     }
13512
13513   if (!vam->json_output)
13514     {
13515       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13516              "sw_if_index", "local_address", "remote_address",
13517              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13518     }
13519
13520   /* Get list of geneve-tunnel interfaces */
13521   M (GENEVE_TUNNEL_DUMP, mp);
13522
13523   mp->sw_if_index = htonl (sw_if_index);
13524
13525   S (mp);
13526
13527   /* Use a control ping for synchronization */
13528   M (CONTROL_PING, mp_ping);
13529   S (mp_ping);
13530
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static int
13536 api_gre_add_del_tunnel (vat_main_t * vam)
13537 {
13538   unformat_input_t *line_input = vam->input;
13539   vl_api_gre_add_del_tunnel_t *mp;
13540   ip4_address_t src4, dst4;
13541   ip6_address_t src6, dst6;
13542   u8 is_add = 1;
13543   u8 ipv4_set = 0;
13544   u8 ipv6_set = 0;
13545   u8 t_type = GRE_TUNNEL_TYPE_L3;
13546   u8 src_set = 0;
13547   u8 dst_set = 0;
13548   u32 outer_fib_id = 0;
13549   u32 session_id = 0;
13550   u32 instance = ~0;
13551   int ret;
13552
13553   memset (&src4, 0, sizeof src4);
13554   memset (&dst4, 0, sizeof dst4);
13555   memset (&src6, 0, sizeof src6);
13556   memset (&dst6, 0, sizeof dst6);
13557
13558   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13559     {
13560       if (unformat (line_input, "del"))
13561         is_add = 0;
13562       else if (unformat (line_input, "instance %d", &instance))
13563         ;
13564       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13565         {
13566           src_set = 1;
13567           ipv4_set = 1;
13568         }
13569       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13570         {
13571           dst_set = 1;
13572           ipv4_set = 1;
13573         }
13574       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13575         {
13576           src_set = 1;
13577           ipv6_set = 1;
13578         }
13579       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13580         {
13581           dst_set = 1;
13582           ipv6_set = 1;
13583         }
13584       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13585         ;
13586       else if (unformat (line_input, "teb"))
13587         t_type = GRE_TUNNEL_TYPE_TEB;
13588       else if (unformat (line_input, "erspan %d", &session_id))
13589         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13590       else
13591         {
13592           errmsg ("parse error '%U'", format_unformat_error, line_input);
13593           return -99;
13594         }
13595     }
13596
13597   if (src_set == 0)
13598     {
13599       errmsg ("tunnel src address not specified");
13600       return -99;
13601     }
13602   if (dst_set == 0)
13603     {
13604       errmsg ("tunnel dst address not specified");
13605       return -99;
13606     }
13607   if (ipv4_set && ipv6_set)
13608     {
13609       errmsg ("both IPv4 and IPv6 addresses specified");
13610       return -99;
13611     }
13612
13613
13614   M (GRE_ADD_DEL_TUNNEL, mp);
13615
13616   if (ipv4_set)
13617     {
13618       clib_memcpy (&mp->src_address, &src4, 4);
13619       clib_memcpy (&mp->dst_address, &dst4, 4);
13620     }
13621   else
13622     {
13623       clib_memcpy (&mp->src_address, &src6, 16);
13624       clib_memcpy (&mp->dst_address, &dst6, 16);
13625     }
13626   mp->instance = htonl (instance);
13627   mp->outer_fib_id = htonl (outer_fib_id);
13628   mp->is_add = is_add;
13629   mp->session_id = htons ((u16) session_id);
13630   mp->tunnel_type = t_type;
13631   mp->is_ipv6 = ipv6_set;
13632
13633   S (mp);
13634   W (ret);
13635   return ret;
13636 }
13637
13638 static void vl_api_gre_tunnel_details_t_handler
13639   (vl_api_gre_tunnel_details_t * mp)
13640 {
13641   vat_main_t *vam = &vat_main;
13642   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13643   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13644
13645   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13646          ntohl (mp->sw_if_index),
13647          ntohl (mp->instance),
13648          format_ip46_address, &src, IP46_TYPE_ANY,
13649          format_ip46_address, &dst, IP46_TYPE_ANY,
13650          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13651 }
13652
13653 static void vl_api_gre_tunnel_details_t_handler_json
13654   (vl_api_gre_tunnel_details_t * mp)
13655 {
13656   vat_main_t *vam = &vat_main;
13657   vat_json_node_t *node = NULL;
13658   struct in_addr ip4;
13659   struct in6_addr ip6;
13660
13661   if (VAT_JSON_ARRAY != vam->json_tree.type)
13662     {
13663       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13664       vat_json_init_array (&vam->json_tree);
13665     }
13666   node = vat_json_array_add (&vam->json_tree);
13667
13668   vat_json_init_object (node);
13669   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13670   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13671   if (!mp->is_ipv6)
13672     {
13673       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13674       vat_json_object_add_ip4 (node, "src_address", ip4);
13675       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13676       vat_json_object_add_ip4 (node, "dst_address", ip4);
13677     }
13678   else
13679     {
13680       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13681       vat_json_object_add_ip6 (node, "src_address", ip6);
13682       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13683       vat_json_object_add_ip6 (node, "dst_address", ip6);
13684     }
13685   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13686   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13687   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13688   vat_json_object_add_uint (node, "session_id", mp->session_id);
13689 }
13690
13691 static int
13692 api_gre_tunnel_dump (vat_main_t * vam)
13693 {
13694   unformat_input_t *i = vam->input;
13695   vl_api_gre_tunnel_dump_t *mp;
13696   vl_api_control_ping_t *mp_ping;
13697   u32 sw_if_index;
13698   u8 sw_if_index_set = 0;
13699   int ret;
13700
13701   /* Parse args required to build the message */
13702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13703     {
13704       if (unformat (i, "sw_if_index %d", &sw_if_index))
13705         sw_if_index_set = 1;
13706       else
13707         break;
13708     }
13709
13710   if (sw_if_index_set == 0)
13711     {
13712       sw_if_index = ~0;
13713     }
13714
13715   if (!vam->json_output)
13716     {
13717       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13718              "sw_if_index", "instance", "src_address", "dst_address",
13719              "tunnel_type", "outer_fib_id", "session_id");
13720     }
13721
13722   /* Get list of gre-tunnel interfaces */
13723   M (GRE_TUNNEL_DUMP, mp);
13724
13725   mp->sw_if_index = htonl (sw_if_index);
13726
13727   S (mp);
13728
13729   /* Use a control ping for synchronization */
13730   MPING (CONTROL_PING, mp_ping);
13731   S (mp_ping);
13732
13733   W (ret);
13734   return ret;
13735 }
13736
13737 static int
13738 api_l2_fib_clear_table (vat_main_t * vam)
13739 {
13740 //  unformat_input_t * i = vam->input;
13741   vl_api_l2_fib_clear_table_t *mp;
13742   int ret;
13743
13744   M (L2_FIB_CLEAR_TABLE, mp);
13745
13746   S (mp);
13747   W (ret);
13748   return ret;
13749 }
13750
13751 static int
13752 api_l2_interface_efp_filter (vat_main_t * vam)
13753 {
13754   unformat_input_t *i = vam->input;
13755   vl_api_l2_interface_efp_filter_t *mp;
13756   u32 sw_if_index;
13757   u8 enable = 1;
13758   u8 sw_if_index_set = 0;
13759   int ret;
13760
13761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13762     {
13763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13764         sw_if_index_set = 1;
13765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13766         sw_if_index_set = 1;
13767       else if (unformat (i, "enable"))
13768         enable = 1;
13769       else if (unformat (i, "disable"))
13770         enable = 0;
13771       else
13772         {
13773           clib_warning ("parse error '%U'", format_unformat_error, i);
13774           return -99;
13775         }
13776     }
13777
13778   if (sw_if_index_set == 0)
13779     {
13780       errmsg ("missing sw_if_index");
13781       return -99;
13782     }
13783
13784   M (L2_INTERFACE_EFP_FILTER, mp);
13785
13786   mp->sw_if_index = ntohl (sw_if_index);
13787   mp->enable_disable = enable;
13788
13789   S (mp);
13790   W (ret);
13791   return ret;
13792 }
13793
13794 #define foreach_vtr_op                          \
13795 _("disable",  L2_VTR_DISABLED)                  \
13796 _("push-1",  L2_VTR_PUSH_1)                     \
13797 _("push-2",  L2_VTR_PUSH_2)                     \
13798 _("pop-1",  L2_VTR_POP_1)                       \
13799 _("pop-2",  L2_VTR_POP_2)                       \
13800 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13801 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13802 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13803 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13804
13805 static int
13806 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13807 {
13808   unformat_input_t *i = vam->input;
13809   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13810   u32 sw_if_index;
13811   u8 sw_if_index_set = 0;
13812   u8 vtr_op_set = 0;
13813   u32 vtr_op = 0;
13814   u32 push_dot1q = 1;
13815   u32 tag1 = ~0;
13816   u32 tag2 = ~0;
13817   int ret;
13818
13819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13820     {
13821       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13822         sw_if_index_set = 1;
13823       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13824         sw_if_index_set = 1;
13825       else if (unformat (i, "vtr_op %d", &vtr_op))
13826         vtr_op_set = 1;
13827 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13828       foreach_vtr_op
13829 #undef _
13830         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13831         ;
13832       else if (unformat (i, "tag1 %d", &tag1))
13833         ;
13834       else if (unformat (i, "tag2 %d", &tag2))
13835         ;
13836       else
13837         {
13838           clib_warning ("parse error '%U'", format_unformat_error, i);
13839           return -99;
13840         }
13841     }
13842
13843   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13844     {
13845       errmsg ("missing vtr operation or sw_if_index");
13846       return -99;
13847     }
13848
13849   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13850   mp->sw_if_index = ntohl (sw_if_index);
13851   mp->vtr_op = ntohl (vtr_op);
13852   mp->push_dot1q = ntohl (push_dot1q);
13853   mp->tag1 = ntohl (tag1);
13854   mp->tag2 = ntohl (tag2);
13855
13856   S (mp);
13857   W (ret);
13858   return ret;
13859 }
13860
13861 static int
13862 api_create_vhost_user_if (vat_main_t * vam)
13863 {
13864   unformat_input_t *i = vam->input;
13865   vl_api_create_vhost_user_if_t *mp;
13866   u8 *file_name;
13867   u8 is_server = 0;
13868   u8 file_name_set = 0;
13869   u32 custom_dev_instance = ~0;
13870   u8 hwaddr[6];
13871   u8 use_custom_mac = 0;
13872   u8 *tag = 0;
13873   int ret;
13874
13875   /* Shut up coverity */
13876   memset (hwaddr, 0, sizeof (hwaddr));
13877
13878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13879     {
13880       if (unformat (i, "socket %s", &file_name))
13881         {
13882           file_name_set = 1;
13883         }
13884       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13885         ;
13886       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13887         use_custom_mac = 1;
13888       else if (unformat (i, "server"))
13889         is_server = 1;
13890       else if (unformat (i, "tag %s", &tag))
13891         ;
13892       else
13893         break;
13894     }
13895
13896   if (file_name_set == 0)
13897     {
13898       errmsg ("missing socket file name");
13899       return -99;
13900     }
13901
13902   if (vec_len (file_name) > 255)
13903     {
13904       errmsg ("socket file name too long");
13905       return -99;
13906     }
13907   vec_add1 (file_name, 0);
13908
13909   M (CREATE_VHOST_USER_IF, mp);
13910
13911   mp->is_server = is_server;
13912   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13913   vec_free (file_name);
13914   if (custom_dev_instance != ~0)
13915     {
13916       mp->renumber = 1;
13917       mp->custom_dev_instance = ntohl (custom_dev_instance);
13918     }
13919   mp->use_custom_mac = use_custom_mac;
13920   clib_memcpy (mp->mac_address, hwaddr, 6);
13921   if (tag)
13922     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13923   vec_free (tag);
13924
13925   S (mp);
13926   W (ret);
13927   return ret;
13928 }
13929
13930 static int
13931 api_modify_vhost_user_if (vat_main_t * vam)
13932 {
13933   unformat_input_t *i = vam->input;
13934   vl_api_modify_vhost_user_if_t *mp;
13935   u8 *file_name;
13936   u8 is_server = 0;
13937   u8 file_name_set = 0;
13938   u32 custom_dev_instance = ~0;
13939   u8 sw_if_index_set = 0;
13940   u32 sw_if_index = (u32) ~ 0;
13941   int ret;
13942
13943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13944     {
13945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13946         sw_if_index_set = 1;
13947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13948         sw_if_index_set = 1;
13949       else if (unformat (i, "socket %s", &file_name))
13950         {
13951           file_name_set = 1;
13952         }
13953       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13954         ;
13955       else if (unformat (i, "server"))
13956         is_server = 1;
13957       else
13958         break;
13959     }
13960
13961   if (sw_if_index_set == 0)
13962     {
13963       errmsg ("missing sw_if_index or interface name");
13964       return -99;
13965     }
13966
13967   if (file_name_set == 0)
13968     {
13969       errmsg ("missing socket file name");
13970       return -99;
13971     }
13972
13973   if (vec_len (file_name) > 255)
13974     {
13975       errmsg ("socket file name too long");
13976       return -99;
13977     }
13978   vec_add1 (file_name, 0);
13979
13980   M (MODIFY_VHOST_USER_IF, mp);
13981
13982   mp->sw_if_index = ntohl (sw_if_index);
13983   mp->is_server = is_server;
13984   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13985   vec_free (file_name);
13986   if (custom_dev_instance != ~0)
13987     {
13988       mp->renumber = 1;
13989       mp->custom_dev_instance = ntohl (custom_dev_instance);
13990     }
13991
13992   S (mp);
13993   W (ret);
13994   return ret;
13995 }
13996
13997 static int
13998 api_delete_vhost_user_if (vat_main_t * vam)
13999 {
14000   unformat_input_t *i = vam->input;
14001   vl_api_delete_vhost_user_if_t *mp;
14002   u32 sw_if_index = ~0;
14003   u8 sw_if_index_set = 0;
14004   int ret;
14005
14006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14009         sw_if_index_set = 1;
14010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14011         sw_if_index_set = 1;
14012       else
14013         break;
14014     }
14015
14016   if (sw_if_index_set == 0)
14017     {
14018       errmsg ("missing sw_if_index or interface name");
14019       return -99;
14020     }
14021
14022
14023   M (DELETE_VHOST_USER_IF, mp);
14024
14025   mp->sw_if_index = ntohl (sw_if_index);
14026
14027   S (mp);
14028   W (ret);
14029   return ret;
14030 }
14031
14032 static void vl_api_sw_interface_vhost_user_details_t_handler
14033   (vl_api_sw_interface_vhost_user_details_t * mp)
14034 {
14035   vat_main_t *vam = &vat_main;
14036
14037   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14038          (char *) mp->interface_name,
14039          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14040          clib_net_to_host_u64 (mp->features), mp->is_server,
14041          ntohl (mp->num_regions), (char *) mp->sock_filename);
14042   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14043 }
14044
14045 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14046   (vl_api_sw_interface_vhost_user_details_t * mp)
14047 {
14048   vat_main_t *vam = &vat_main;
14049   vat_json_node_t *node = NULL;
14050
14051   if (VAT_JSON_ARRAY != vam->json_tree.type)
14052     {
14053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14054       vat_json_init_array (&vam->json_tree);
14055     }
14056   node = vat_json_array_add (&vam->json_tree);
14057
14058   vat_json_init_object (node);
14059   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14060   vat_json_object_add_string_copy (node, "interface_name",
14061                                    mp->interface_name);
14062   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14063                             ntohl (mp->virtio_net_hdr_sz));
14064   vat_json_object_add_uint (node, "features",
14065                             clib_net_to_host_u64 (mp->features));
14066   vat_json_object_add_uint (node, "is_server", mp->is_server);
14067   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14068   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14069   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14070 }
14071
14072 static int
14073 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14074 {
14075   vl_api_sw_interface_vhost_user_dump_t *mp;
14076   vl_api_control_ping_t *mp_ping;
14077   int ret;
14078   print (vam->ofp,
14079          "Interface name            idx hdr_sz features server regions filename");
14080
14081   /* Get list of vhost-user interfaces */
14082   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14083   S (mp);
14084
14085   /* Use a control ping for synchronization */
14086   MPING (CONTROL_PING, mp_ping);
14087   S (mp_ping);
14088
14089   W (ret);
14090   return ret;
14091 }
14092
14093 static int
14094 api_show_version (vat_main_t * vam)
14095 {
14096   vl_api_show_version_t *mp;
14097   int ret;
14098
14099   M (SHOW_VERSION, mp);
14100
14101   S (mp);
14102   W (ret);
14103   return ret;
14104 }
14105
14106
14107 static int
14108 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14109 {
14110   unformat_input_t *line_input = vam->input;
14111   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14112   ip4_address_t local4, remote4;
14113   ip6_address_t local6, remote6;
14114   u8 is_add = 1;
14115   u8 ipv4_set = 0, ipv6_set = 0;
14116   u8 local_set = 0;
14117   u8 remote_set = 0;
14118   u8 grp_set = 0;
14119   u32 mcast_sw_if_index = ~0;
14120   u32 encap_vrf_id = 0;
14121   u32 decap_vrf_id = 0;
14122   u8 protocol = ~0;
14123   u32 vni;
14124   u8 vni_set = 0;
14125   int ret;
14126
14127   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14128   memset (&local4, 0, sizeof local4);
14129   memset (&remote4, 0, sizeof remote4);
14130   memset (&local6, 0, sizeof local6);
14131   memset (&remote6, 0, sizeof remote6);
14132
14133   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14134     {
14135       if (unformat (line_input, "del"))
14136         is_add = 0;
14137       else if (unformat (line_input, "local %U",
14138                          unformat_ip4_address, &local4))
14139         {
14140           local_set = 1;
14141           ipv4_set = 1;
14142         }
14143       else if (unformat (line_input, "remote %U",
14144                          unformat_ip4_address, &remote4))
14145         {
14146           remote_set = 1;
14147           ipv4_set = 1;
14148         }
14149       else if (unformat (line_input, "local %U",
14150                          unformat_ip6_address, &local6))
14151         {
14152           local_set = 1;
14153           ipv6_set = 1;
14154         }
14155       else if (unformat (line_input, "remote %U",
14156                          unformat_ip6_address, &remote6))
14157         {
14158           remote_set = 1;
14159           ipv6_set = 1;
14160         }
14161       else if (unformat (line_input, "group %U %U",
14162                          unformat_ip4_address, &remote4,
14163                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14164         {
14165           grp_set = remote_set = 1;
14166           ipv4_set = 1;
14167         }
14168       else if (unformat (line_input, "group %U",
14169                          unformat_ip4_address, &remote4))
14170         {
14171           grp_set = remote_set = 1;
14172           ipv4_set = 1;
14173         }
14174       else if (unformat (line_input, "group %U %U",
14175                          unformat_ip6_address, &remote6,
14176                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14177         {
14178           grp_set = remote_set = 1;
14179           ipv6_set = 1;
14180         }
14181       else if (unformat (line_input, "group %U",
14182                          unformat_ip6_address, &remote6))
14183         {
14184           grp_set = remote_set = 1;
14185           ipv6_set = 1;
14186         }
14187       else
14188         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14189         ;
14190       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14191         ;
14192       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14193         ;
14194       else if (unformat (line_input, "vni %d", &vni))
14195         vni_set = 1;
14196       else if (unformat (line_input, "next-ip4"))
14197         protocol = 1;
14198       else if (unformat (line_input, "next-ip6"))
14199         protocol = 2;
14200       else if (unformat (line_input, "next-ethernet"))
14201         protocol = 3;
14202       else if (unformat (line_input, "next-nsh"))
14203         protocol = 4;
14204       else
14205         {
14206           errmsg ("parse error '%U'", format_unformat_error, line_input);
14207           return -99;
14208         }
14209     }
14210
14211   if (local_set == 0)
14212     {
14213       errmsg ("tunnel local address not specified");
14214       return -99;
14215     }
14216   if (remote_set == 0)
14217     {
14218       errmsg ("tunnel remote address not specified");
14219       return -99;
14220     }
14221   if (grp_set && mcast_sw_if_index == ~0)
14222     {
14223       errmsg ("tunnel nonexistent multicast device");
14224       return -99;
14225     }
14226   if (ipv4_set && ipv6_set)
14227     {
14228       errmsg ("both IPv4 and IPv6 addresses specified");
14229       return -99;
14230     }
14231
14232   if (vni_set == 0)
14233     {
14234       errmsg ("vni not specified");
14235       return -99;
14236     }
14237
14238   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14239
14240
14241   if (ipv6_set)
14242     {
14243       clib_memcpy (&mp->local, &local6, sizeof (local6));
14244       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14245     }
14246   else
14247     {
14248       clib_memcpy (&mp->local, &local4, sizeof (local4));
14249       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14250     }
14251
14252   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14253   mp->encap_vrf_id = ntohl (encap_vrf_id);
14254   mp->decap_vrf_id = ntohl (decap_vrf_id);
14255   mp->protocol = protocol;
14256   mp->vni = ntohl (vni);
14257   mp->is_add = is_add;
14258   mp->is_ipv6 = ipv6_set;
14259
14260   S (mp);
14261   W (ret);
14262   return ret;
14263 }
14264
14265 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14266   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14267 {
14268   vat_main_t *vam = &vat_main;
14269   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14270   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14271
14272   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14273          ntohl (mp->sw_if_index),
14274          format_ip46_address, &local, IP46_TYPE_ANY,
14275          format_ip46_address, &remote, IP46_TYPE_ANY,
14276          ntohl (mp->vni), mp->protocol,
14277          ntohl (mp->mcast_sw_if_index),
14278          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14279 }
14280
14281
14282 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14283   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14284 {
14285   vat_main_t *vam = &vat_main;
14286   vat_json_node_t *node = NULL;
14287   struct in_addr ip4;
14288   struct in6_addr ip6;
14289
14290   if (VAT_JSON_ARRAY != vam->json_tree.type)
14291     {
14292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14293       vat_json_init_array (&vam->json_tree);
14294     }
14295   node = vat_json_array_add (&vam->json_tree);
14296
14297   vat_json_init_object (node);
14298   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14299   if (mp->is_ipv6)
14300     {
14301       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14302       vat_json_object_add_ip6 (node, "local", ip6);
14303       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14304       vat_json_object_add_ip6 (node, "remote", ip6);
14305     }
14306   else
14307     {
14308       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14309       vat_json_object_add_ip4 (node, "local", ip4);
14310       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14311       vat_json_object_add_ip4 (node, "remote", ip4);
14312     }
14313   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14314   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14315   vat_json_object_add_uint (node, "mcast_sw_if_index",
14316                             ntohl (mp->mcast_sw_if_index));
14317   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14318   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14319   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14320 }
14321
14322 static int
14323 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14324 {
14325   unformat_input_t *i = vam->input;
14326   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14327   vl_api_control_ping_t *mp_ping;
14328   u32 sw_if_index;
14329   u8 sw_if_index_set = 0;
14330   int ret;
14331
14332   /* Parse args required to build the message */
14333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14334     {
14335       if (unformat (i, "sw_if_index %d", &sw_if_index))
14336         sw_if_index_set = 1;
14337       else
14338         break;
14339     }
14340
14341   if (sw_if_index_set == 0)
14342     {
14343       sw_if_index = ~0;
14344     }
14345
14346   if (!vam->json_output)
14347     {
14348       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14349              "sw_if_index", "local", "remote", "vni",
14350              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14351     }
14352
14353   /* Get list of vxlan-tunnel interfaces */
14354   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14355
14356   mp->sw_if_index = htonl (sw_if_index);
14357
14358   S (mp);
14359
14360   /* Use a control ping for synchronization */
14361   MPING (CONTROL_PING, mp_ping);
14362   S (mp_ping);
14363
14364   W (ret);
14365   return ret;
14366 }
14367
14368 static void vl_api_l2_fib_table_details_t_handler
14369   (vl_api_l2_fib_table_details_t * mp)
14370 {
14371   vat_main_t *vam = &vat_main;
14372
14373   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14374          "       %d       %d     %d",
14375          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14376          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14377          mp->bvi_mac);
14378 }
14379
14380 static void vl_api_l2_fib_table_details_t_handler_json
14381   (vl_api_l2_fib_table_details_t * mp)
14382 {
14383   vat_main_t *vam = &vat_main;
14384   vat_json_node_t *node = NULL;
14385
14386   if (VAT_JSON_ARRAY != vam->json_tree.type)
14387     {
14388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14389       vat_json_init_array (&vam->json_tree);
14390     }
14391   node = vat_json_array_add (&vam->json_tree);
14392
14393   vat_json_init_object (node);
14394   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14395   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14396   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14397   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14398   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14399   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14400 }
14401
14402 static int
14403 api_l2_fib_table_dump (vat_main_t * vam)
14404 {
14405   unformat_input_t *i = vam->input;
14406   vl_api_l2_fib_table_dump_t *mp;
14407   vl_api_control_ping_t *mp_ping;
14408   u32 bd_id;
14409   u8 bd_id_set = 0;
14410   int ret;
14411
14412   /* Parse args required to build the message */
14413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14414     {
14415       if (unformat (i, "bd_id %d", &bd_id))
14416         bd_id_set = 1;
14417       else
14418         break;
14419     }
14420
14421   if (bd_id_set == 0)
14422     {
14423       errmsg ("missing bridge domain");
14424       return -99;
14425     }
14426
14427   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14428
14429   /* Get list of l2 fib entries */
14430   M (L2_FIB_TABLE_DUMP, mp);
14431
14432   mp->bd_id = ntohl (bd_id);
14433   S (mp);
14434
14435   /* Use a control ping for synchronization */
14436   MPING (CONTROL_PING, mp_ping);
14437   S (mp_ping);
14438
14439   W (ret);
14440   return ret;
14441 }
14442
14443
14444 static int
14445 api_interface_name_renumber (vat_main_t * vam)
14446 {
14447   unformat_input_t *line_input = vam->input;
14448   vl_api_interface_name_renumber_t *mp;
14449   u32 sw_if_index = ~0;
14450   u32 new_show_dev_instance = ~0;
14451   int ret;
14452
14453   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14454     {
14455       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14456                     &sw_if_index))
14457         ;
14458       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14459         ;
14460       else if (unformat (line_input, "new_show_dev_instance %d",
14461                          &new_show_dev_instance))
14462         ;
14463       else
14464         break;
14465     }
14466
14467   if (sw_if_index == ~0)
14468     {
14469       errmsg ("missing interface name or sw_if_index");
14470       return -99;
14471     }
14472
14473   if (new_show_dev_instance == ~0)
14474     {
14475       errmsg ("missing new_show_dev_instance");
14476       return -99;
14477     }
14478
14479   M (INTERFACE_NAME_RENUMBER, mp);
14480
14481   mp->sw_if_index = ntohl (sw_if_index);
14482   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14483
14484   S (mp);
14485   W (ret);
14486   return ret;
14487 }
14488
14489 static int
14490 api_ip_probe_neighbor (vat_main_t * vam)
14491 {
14492   unformat_input_t *i = vam->input;
14493   vl_api_ip_probe_neighbor_t *mp;
14494   u8 int_set = 0;
14495   u8 adr_set = 0;
14496   u8 is_ipv6 = 0;
14497   u8 dst_adr[16];
14498   u32 sw_if_index;
14499   int ret;
14500
14501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14502     {
14503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14504         int_set = 1;
14505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14506         int_set = 1;
14507       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14508         adr_set = 1;
14509       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14510         {
14511           adr_set = 1;
14512           is_ipv6 = 1;
14513         }
14514       else
14515         break;
14516     }
14517
14518   if (int_set == 0)
14519     {
14520       errmsg ("missing interface");
14521       return -99;
14522     }
14523
14524   if (adr_set == 0)
14525     {
14526       errmsg ("missing addresses");
14527       return -99;
14528     }
14529
14530   M (IP_PROBE_NEIGHBOR, mp);
14531
14532   mp->sw_if_index = ntohl (sw_if_index);
14533   mp->is_ipv6 = is_ipv6;
14534   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14535
14536   S (mp);
14537   W (ret);
14538   return ret;
14539 }
14540
14541 static int
14542 api_want_ip4_arp_events (vat_main_t * vam)
14543 {
14544   unformat_input_t *line_input = vam->input;
14545   vl_api_want_ip4_arp_events_t *mp;
14546   ip4_address_t address;
14547   int address_set = 0;
14548   u32 enable_disable = 1;
14549   int ret;
14550
14551   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14552     {
14553       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14554         address_set = 1;
14555       else if (unformat (line_input, "del"))
14556         enable_disable = 0;
14557       else
14558         break;
14559     }
14560
14561   if (address_set == 0)
14562     {
14563       errmsg ("missing addresses");
14564       return -99;
14565     }
14566
14567   M (WANT_IP4_ARP_EVENTS, mp);
14568   mp->enable_disable = enable_disable;
14569   mp->pid = htonl (getpid ());
14570   mp->address = address.as_u32;
14571
14572   S (mp);
14573   W (ret);
14574   return ret;
14575 }
14576
14577 static int
14578 api_want_ip6_nd_events (vat_main_t * vam)
14579 {
14580   unformat_input_t *line_input = vam->input;
14581   vl_api_want_ip6_nd_events_t *mp;
14582   ip6_address_t address;
14583   int address_set = 0;
14584   u32 enable_disable = 1;
14585   int ret;
14586
14587   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14588     {
14589       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14590         address_set = 1;
14591       else if (unformat (line_input, "del"))
14592         enable_disable = 0;
14593       else
14594         break;
14595     }
14596
14597   if (address_set == 0)
14598     {
14599       errmsg ("missing addresses");
14600       return -99;
14601     }
14602
14603   M (WANT_IP6_ND_EVENTS, mp);
14604   mp->enable_disable = enable_disable;
14605   mp->pid = htonl (getpid ());
14606   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14607
14608   S (mp);
14609   W (ret);
14610   return ret;
14611 }
14612
14613 static int
14614 api_want_l2_macs_events (vat_main_t * vam)
14615 {
14616   unformat_input_t *line_input = vam->input;
14617   vl_api_want_l2_macs_events_t *mp;
14618   u8 enable_disable = 1;
14619   u32 scan_delay = 0;
14620   u32 max_macs_in_event = 0;
14621   u32 learn_limit = 0;
14622   int ret;
14623
14624   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (line_input, "learn-limit %d", &learn_limit))
14627         ;
14628       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14629         ;
14630       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14631         ;
14632       else if (unformat (line_input, "disable"))
14633         enable_disable = 0;
14634       else
14635         break;
14636     }
14637
14638   M (WANT_L2_MACS_EVENTS, mp);
14639   mp->enable_disable = enable_disable;
14640   mp->pid = htonl (getpid ());
14641   mp->learn_limit = htonl (learn_limit);
14642   mp->scan_delay = (u8) scan_delay;
14643   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14644   S (mp);
14645   W (ret);
14646   return ret;
14647 }
14648
14649 static int
14650 api_input_acl_set_interface (vat_main_t * vam)
14651 {
14652   unformat_input_t *i = vam->input;
14653   vl_api_input_acl_set_interface_t *mp;
14654   u32 sw_if_index;
14655   int sw_if_index_set;
14656   u32 ip4_table_index = ~0;
14657   u32 ip6_table_index = ~0;
14658   u32 l2_table_index = ~0;
14659   u8 is_add = 1;
14660   int ret;
14661
14662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14665         sw_if_index_set = 1;
14666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14667         sw_if_index_set = 1;
14668       else if (unformat (i, "del"))
14669         is_add = 0;
14670       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14671         ;
14672       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14673         ;
14674       else if (unformat (i, "l2-table %d", &l2_table_index))
14675         ;
14676       else
14677         {
14678           clib_warning ("parse error '%U'", format_unformat_error, i);
14679           return -99;
14680         }
14681     }
14682
14683   if (sw_if_index_set == 0)
14684     {
14685       errmsg ("missing interface name or sw_if_index");
14686       return -99;
14687     }
14688
14689   M (INPUT_ACL_SET_INTERFACE, mp);
14690
14691   mp->sw_if_index = ntohl (sw_if_index);
14692   mp->ip4_table_index = ntohl (ip4_table_index);
14693   mp->ip6_table_index = ntohl (ip6_table_index);
14694   mp->l2_table_index = ntohl (l2_table_index);
14695   mp->is_add = is_add;
14696
14697   S (mp);
14698   W (ret);
14699   return ret;
14700 }
14701
14702 static int
14703 api_output_acl_set_interface (vat_main_t * vam)
14704 {
14705   unformat_input_t *i = vam->input;
14706   vl_api_output_acl_set_interface_t *mp;
14707   u32 sw_if_index;
14708   int sw_if_index_set;
14709   u32 ip4_table_index = ~0;
14710   u32 ip6_table_index = ~0;
14711   u32 l2_table_index = ~0;
14712   u8 is_add = 1;
14713   int ret;
14714
14715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14718         sw_if_index_set = 1;
14719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14720         sw_if_index_set = 1;
14721       else if (unformat (i, "del"))
14722         is_add = 0;
14723       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14724         ;
14725       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14726         ;
14727       else if (unformat (i, "l2-table %d", &l2_table_index))
14728         ;
14729       else
14730         {
14731           clib_warning ("parse error '%U'", format_unformat_error, i);
14732           return -99;
14733         }
14734     }
14735
14736   if (sw_if_index_set == 0)
14737     {
14738       errmsg ("missing interface name or sw_if_index");
14739       return -99;
14740     }
14741
14742   M (OUTPUT_ACL_SET_INTERFACE, mp);
14743
14744   mp->sw_if_index = ntohl (sw_if_index);
14745   mp->ip4_table_index = ntohl (ip4_table_index);
14746   mp->ip6_table_index = ntohl (ip6_table_index);
14747   mp->l2_table_index = ntohl (l2_table_index);
14748   mp->is_add = is_add;
14749
14750   S (mp);
14751   W (ret);
14752   return ret;
14753 }
14754
14755 static int
14756 api_ip_address_dump (vat_main_t * vam)
14757 {
14758   unformat_input_t *i = vam->input;
14759   vl_api_ip_address_dump_t *mp;
14760   vl_api_control_ping_t *mp_ping;
14761   u32 sw_if_index = ~0;
14762   u8 sw_if_index_set = 0;
14763   u8 ipv4_set = 0;
14764   u8 ipv6_set = 0;
14765   int ret;
14766
14767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14768     {
14769       if (unformat (i, "sw_if_index %d", &sw_if_index))
14770         sw_if_index_set = 1;
14771       else
14772         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14773         sw_if_index_set = 1;
14774       else if (unformat (i, "ipv4"))
14775         ipv4_set = 1;
14776       else if (unformat (i, "ipv6"))
14777         ipv6_set = 1;
14778       else
14779         break;
14780     }
14781
14782   if (ipv4_set && ipv6_set)
14783     {
14784       errmsg ("ipv4 and ipv6 flags cannot be both set");
14785       return -99;
14786     }
14787
14788   if ((!ipv4_set) && (!ipv6_set))
14789     {
14790       errmsg ("no ipv4 nor ipv6 flag set");
14791       return -99;
14792     }
14793
14794   if (sw_if_index_set == 0)
14795     {
14796       errmsg ("missing interface name or sw_if_index");
14797       return -99;
14798     }
14799
14800   vam->current_sw_if_index = sw_if_index;
14801   vam->is_ipv6 = ipv6_set;
14802
14803   M (IP_ADDRESS_DUMP, mp);
14804   mp->sw_if_index = ntohl (sw_if_index);
14805   mp->is_ipv6 = ipv6_set;
14806   S (mp);
14807
14808   /* Use a control ping for synchronization */
14809   MPING (CONTROL_PING, mp_ping);
14810   S (mp_ping);
14811
14812   W (ret);
14813   return ret;
14814 }
14815
14816 static int
14817 api_ip_dump (vat_main_t * vam)
14818 {
14819   vl_api_ip_dump_t *mp;
14820   vl_api_control_ping_t *mp_ping;
14821   unformat_input_t *in = vam->input;
14822   int ipv4_set = 0;
14823   int ipv6_set = 0;
14824   int is_ipv6;
14825   int i;
14826   int ret;
14827
14828   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (in, "ipv4"))
14831         ipv4_set = 1;
14832       else if (unformat (in, "ipv6"))
14833         ipv6_set = 1;
14834       else
14835         break;
14836     }
14837
14838   if (ipv4_set && ipv6_set)
14839     {
14840       errmsg ("ipv4 and ipv6 flags cannot be both set");
14841       return -99;
14842     }
14843
14844   if ((!ipv4_set) && (!ipv6_set))
14845     {
14846       errmsg ("no ipv4 nor ipv6 flag set");
14847       return -99;
14848     }
14849
14850   is_ipv6 = ipv6_set;
14851   vam->is_ipv6 = is_ipv6;
14852
14853   /* free old data */
14854   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14855     {
14856       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14857     }
14858   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14859
14860   M (IP_DUMP, mp);
14861   mp->is_ipv6 = ipv6_set;
14862   S (mp);
14863
14864   /* Use a control ping for synchronization */
14865   MPING (CONTROL_PING, mp_ping);
14866   S (mp_ping);
14867
14868   W (ret);
14869   return ret;
14870 }
14871
14872 static int
14873 api_ipsec_spd_add_del (vat_main_t * vam)
14874 {
14875   unformat_input_t *i = vam->input;
14876   vl_api_ipsec_spd_add_del_t *mp;
14877   u32 spd_id = ~0;
14878   u8 is_add = 1;
14879   int ret;
14880
14881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14882     {
14883       if (unformat (i, "spd_id %d", &spd_id))
14884         ;
14885       else if (unformat (i, "del"))
14886         is_add = 0;
14887       else
14888         {
14889           clib_warning ("parse error '%U'", format_unformat_error, i);
14890           return -99;
14891         }
14892     }
14893   if (spd_id == ~0)
14894     {
14895       errmsg ("spd_id must be set");
14896       return -99;
14897     }
14898
14899   M (IPSEC_SPD_ADD_DEL, mp);
14900
14901   mp->spd_id = ntohl (spd_id);
14902   mp->is_add = is_add;
14903
14904   S (mp);
14905   W (ret);
14906   return ret;
14907 }
14908
14909 static int
14910 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14911 {
14912   unformat_input_t *i = vam->input;
14913   vl_api_ipsec_interface_add_del_spd_t *mp;
14914   u32 sw_if_index;
14915   u8 sw_if_index_set = 0;
14916   u32 spd_id = (u32) ~ 0;
14917   u8 is_add = 1;
14918   int ret;
14919
14920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14921     {
14922       if (unformat (i, "del"))
14923         is_add = 0;
14924       else if (unformat (i, "spd_id %d", &spd_id))
14925         ;
14926       else
14927         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14928         sw_if_index_set = 1;
14929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14930         sw_if_index_set = 1;
14931       else
14932         {
14933           clib_warning ("parse error '%U'", format_unformat_error, i);
14934           return -99;
14935         }
14936
14937     }
14938
14939   if (spd_id == (u32) ~ 0)
14940     {
14941       errmsg ("spd_id must be set");
14942       return -99;
14943     }
14944
14945   if (sw_if_index_set == 0)
14946     {
14947       errmsg ("missing interface name or sw_if_index");
14948       return -99;
14949     }
14950
14951   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14952
14953   mp->spd_id = ntohl (spd_id);
14954   mp->sw_if_index = ntohl (sw_if_index);
14955   mp->is_add = is_add;
14956
14957   S (mp);
14958   W (ret);
14959   return ret;
14960 }
14961
14962 static int
14963 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14964 {
14965   unformat_input_t *i = vam->input;
14966   vl_api_ipsec_spd_add_del_entry_t *mp;
14967   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14968   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14969   i32 priority = 0;
14970   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14971   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14972   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14973   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14974   int ret;
14975
14976   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14977   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14978   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14979   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14980   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14981   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14982
14983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (i, "del"))
14986         is_add = 0;
14987       if (unformat (i, "outbound"))
14988         is_outbound = 1;
14989       if (unformat (i, "inbound"))
14990         is_outbound = 0;
14991       else if (unformat (i, "spd_id %d", &spd_id))
14992         ;
14993       else if (unformat (i, "sa_id %d", &sa_id))
14994         ;
14995       else if (unformat (i, "priority %d", &priority))
14996         ;
14997       else if (unformat (i, "protocol %d", &protocol))
14998         ;
14999       else if (unformat (i, "lport_start %d", &lport_start))
15000         ;
15001       else if (unformat (i, "lport_stop %d", &lport_stop))
15002         ;
15003       else if (unformat (i, "rport_start %d", &rport_start))
15004         ;
15005       else if (unformat (i, "rport_stop %d", &rport_stop))
15006         ;
15007       else
15008         if (unformat
15009             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15010         {
15011           is_ipv6 = 0;
15012           is_ip_any = 0;
15013         }
15014       else
15015         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15016         {
15017           is_ipv6 = 0;
15018           is_ip_any = 0;
15019         }
15020       else
15021         if (unformat
15022             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15023         {
15024           is_ipv6 = 0;
15025           is_ip_any = 0;
15026         }
15027       else
15028         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15029         {
15030           is_ipv6 = 0;
15031           is_ip_any = 0;
15032         }
15033       else
15034         if (unformat
15035             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15036         {
15037           is_ipv6 = 1;
15038           is_ip_any = 0;
15039         }
15040       else
15041         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15042         {
15043           is_ipv6 = 1;
15044           is_ip_any = 0;
15045         }
15046       else
15047         if (unformat
15048             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15049         {
15050           is_ipv6 = 1;
15051           is_ip_any = 0;
15052         }
15053       else
15054         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15055         {
15056           is_ipv6 = 1;
15057           is_ip_any = 0;
15058         }
15059       else
15060         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15061         {
15062           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15063             {
15064               clib_warning ("unsupported action: 'resolve'");
15065               return -99;
15066             }
15067         }
15068       else
15069         {
15070           clib_warning ("parse error '%U'", format_unformat_error, i);
15071           return -99;
15072         }
15073
15074     }
15075
15076   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15077
15078   mp->spd_id = ntohl (spd_id);
15079   mp->priority = ntohl (priority);
15080   mp->is_outbound = is_outbound;
15081
15082   mp->is_ipv6 = is_ipv6;
15083   if (is_ipv6 || is_ip_any)
15084     {
15085       clib_memcpy (mp->remote_address_start, &raddr6_start,
15086                    sizeof (ip6_address_t));
15087       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15088                    sizeof (ip6_address_t));
15089       clib_memcpy (mp->local_address_start, &laddr6_start,
15090                    sizeof (ip6_address_t));
15091       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15092                    sizeof (ip6_address_t));
15093     }
15094   else
15095     {
15096       clib_memcpy (mp->remote_address_start, &raddr4_start,
15097                    sizeof (ip4_address_t));
15098       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15099                    sizeof (ip4_address_t));
15100       clib_memcpy (mp->local_address_start, &laddr4_start,
15101                    sizeof (ip4_address_t));
15102       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15103                    sizeof (ip4_address_t));
15104     }
15105   mp->protocol = (u8) protocol;
15106   mp->local_port_start = ntohs ((u16) lport_start);
15107   mp->local_port_stop = ntohs ((u16) lport_stop);
15108   mp->remote_port_start = ntohs ((u16) rport_start);
15109   mp->remote_port_stop = ntohs ((u16) rport_stop);
15110   mp->policy = (u8) policy;
15111   mp->sa_id = ntohl (sa_id);
15112   mp->is_add = is_add;
15113   mp->is_ip_any = is_ip_any;
15114   S (mp);
15115   W (ret);
15116   return ret;
15117 }
15118
15119 static int
15120 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15121 {
15122   unformat_input_t *i = vam->input;
15123   vl_api_ipsec_sad_add_del_entry_t *mp;
15124   u32 sad_id = 0, spi = 0;
15125   u8 *ck = 0, *ik = 0;
15126   u8 is_add = 1;
15127
15128   u8 protocol = IPSEC_PROTOCOL_AH;
15129   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15130   u32 crypto_alg = 0, integ_alg = 0;
15131   ip4_address_t tun_src4;
15132   ip4_address_t tun_dst4;
15133   ip6_address_t tun_src6;
15134   ip6_address_t tun_dst6;
15135   int ret;
15136
15137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15138     {
15139       if (unformat (i, "del"))
15140         is_add = 0;
15141       else if (unformat (i, "sad_id %d", &sad_id))
15142         ;
15143       else if (unformat (i, "spi %d", &spi))
15144         ;
15145       else if (unformat (i, "esp"))
15146         protocol = IPSEC_PROTOCOL_ESP;
15147       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15148         {
15149           is_tunnel = 1;
15150           is_tunnel_ipv6 = 0;
15151         }
15152       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15153         {
15154           is_tunnel = 1;
15155           is_tunnel_ipv6 = 0;
15156         }
15157       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15158         {
15159           is_tunnel = 1;
15160           is_tunnel_ipv6 = 1;
15161         }
15162       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15163         {
15164           is_tunnel = 1;
15165           is_tunnel_ipv6 = 1;
15166         }
15167       else
15168         if (unformat
15169             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15170         {
15171           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15172               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15173             {
15174               clib_warning ("unsupported crypto-alg: '%U'",
15175                             format_ipsec_crypto_alg, crypto_alg);
15176               return -99;
15177             }
15178         }
15179       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15180         ;
15181       else
15182         if (unformat
15183             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15184         {
15185           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15186               integ_alg >= IPSEC_INTEG_N_ALG)
15187             {
15188               clib_warning ("unsupported integ-alg: '%U'",
15189                             format_ipsec_integ_alg, integ_alg);
15190               return -99;
15191             }
15192         }
15193       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15194         ;
15195       else
15196         {
15197           clib_warning ("parse error '%U'", format_unformat_error, i);
15198           return -99;
15199         }
15200
15201     }
15202
15203   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15204
15205   mp->sad_id = ntohl (sad_id);
15206   mp->is_add = is_add;
15207   mp->protocol = protocol;
15208   mp->spi = ntohl (spi);
15209   mp->is_tunnel = is_tunnel;
15210   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15211   mp->crypto_algorithm = crypto_alg;
15212   mp->integrity_algorithm = integ_alg;
15213   mp->crypto_key_length = vec_len (ck);
15214   mp->integrity_key_length = vec_len (ik);
15215
15216   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15217     mp->crypto_key_length = sizeof (mp->crypto_key);
15218
15219   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15220     mp->integrity_key_length = sizeof (mp->integrity_key);
15221
15222   if (ck)
15223     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15224   if (ik)
15225     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15226
15227   if (is_tunnel)
15228     {
15229       if (is_tunnel_ipv6)
15230         {
15231           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15232                        sizeof (ip6_address_t));
15233           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15234                        sizeof (ip6_address_t));
15235         }
15236       else
15237         {
15238           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15239                        sizeof (ip4_address_t));
15240           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15241                        sizeof (ip4_address_t));
15242         }
15243     }
15244
15245   S (mp);
15246   W (ret);
15247   return ret;
15248 }
15249
15250 static int
15251 api_ipsec_sa_set_key (vat_main_t * vam)
15252 {
15253   unformat_input_t *i = vam->input;
15254   vl_api_ipsec_sa_set_key_t *mp;
15255   u32 sa_id;
15256   u8 *ck = 0, *ik = 0;
15257   int ret;
15258
15259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15260     {
15261       if (unformat (i, "sa_id %d", &sa_id))
15262         ;
15263       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15264         ;
15265       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15266         ;
15267       else
15268         {
15269           clib_warning ("parse error '%U'", format_unformat_error, i);
15270           return -99;
15271         }
15272     }
15273
15274   M (IPSEC_SA_SET_KEY, mp);
15275
15276   mp->sa_id = ntohl (sa_id);
15277   mp->crypto_key_length = vec_len (ck);
15278   mp->integrity_key_length = vec_len (ik);
15279
15280   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15281     mp->crypto_key_length = sizeof (mp->crypto_key);
15282
15283   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15284     mp->integrity_key_length = sizeof (mp->integrity_key);
15285
15286   if (ck)
15287     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15288   if (ik)
15289     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15290
15291   S (mp);
15292   W (ret);
15293   return ret;
15294 }
15295
15296 static int
15297 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15298 {
15299   unformat_input_t *i = vam->input;
15300   vl_api_ipsec_tunnel_if_add_del_t *mp;
15301   u32 local_spi = 0, remote_spi = 0;
15302   u32 crypto_alg = 0, integ_alg = 0;
15303   u8 *lck = NULL, *rck = NULL;
15304   u8 *lik = NULL, *rik = NULL;
15305   ip4_address_t local_ip = { {0} };
15306   ip4_address_t remote_ip = { {0} };
15307   u8 is_add = 1;
15308   u8 esn = 0;
15309   u8 anti_replay = 0;
15310   u8 renumber = 0;
15311   u32 instance = ~0;
15312   int ret;
15313
15314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15315     {
15316       if (unformat (i, "del"))
15317         is_add = 0;
15318       else if (unformat (i, "esn"))
15319         esn = 1;
15320       else if (unformat (i, "anti_replay"))
15321         anti_replay = 1;
15322       else if (unformat (i, "local_spi %d", &local_spi))
15323         ;
15324       else if (unformat (i, "remote_spi %d", &remote_spi))
15325         ;
15326       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15327         ;
15328       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15329         ;
15330       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15331         ;
15332       else
15333         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15334         ;
15335       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15336         ;
15337       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15338         ;
15339       else
15340         if (unformat
15341             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15342         {
15343           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15344               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15345             {
15346               errmsg ("unsupported crypto-alg: '%U'\n",
15347                       format_ipsec_crypto_alg, crypto_alg);
15348               return -99;
15349             }
15350         }
15351       else
15352         if (unformat
15353             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15354         {
15355           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15356               integ_alg >= IPSEC_INTEG_N_ALG)
15357             {
15358               errmsg ("unsupported integ-alg: '%U'\n",
15359                       format_ipsec_integ_alg, integ_alg);
15360               return -99;
15361             }
15362         }
15363       else if (unformat (i, "instance %u", &instance))
15364         renumber = 1;
15365       else
15366         {
15367           errmsg ("parse error '%U'\n", format_unformat_error, i);
15368           return -99;
15369         }
15370     }
15371
15372   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15373
15374   mp->is_add = is_add;
15375   mp->esn = esn;
15376   mp->anti_replay = anti_replay;
15377
15378   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15379   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15380
15381   mp->local_spi = htonl (local_spi);
15382   mp->remote_spi = htonl (remote_spi);
15383   mp->crypto_alg = (u8) crypto_alg;
15384
15385   mp->local_crypto_key_len = 0;
15386   if (lck)
15387     {
15388       mp->local_crypto_key_len = vec_len (lck);
15389       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15390         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15391       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15392     }
15393
15394   mp->remote_crypto_key_len = 0;
15395   if (rck)
15396     {
15397       mp->remote_crypto_key_len = vec_len (rck);
15398       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15399         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15400       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15401     }
15402
15403   mp->integ_alg = (u8) integ_alg;
15404
15405   mp->local_integ_key_len = 0;
15406   if (lik)
15407     {
15408       mp->local_integ_key_len = vec_len (lik);
15409       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15410         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15411       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15412     }
15413
15414   mp->remote_integ_key_len = 0;
15415   if (rik)
15416     {
15417       mp->remote_integ_key_len = vec_len (rik);
15418       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15419         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15420       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15421     }
15422
15423   if (renumber)
15424     {
15425       mp->renumber = renumber;
15426       mp->show_instance = ntohl (instance);
15427     }
15428
15429   S (mp);
15430   W (ret);
15431   return ret;
15432 }
15433
15434 static void
15435 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15436 {
15437   vat_main_t *vam = &vat_main;
15438
15439   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15440          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15441          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15442          "tunnel_src_addr %U tunnel_dst_addr %U "
15443          "salt %u seq_outbound %lu last_seq_inbound %lu "
15444          "replay_window %lu total_data_size %lu\n",
15445          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15446          mp->protocol,
15447          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15448          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15449          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15450          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15451          mp->tunnel_src_addr,
15452          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15453          mp->tunnel_dst_addr,
15454          ntohl (mp->salt),
15455          clib_net_to_host_u64 (mp->seq_outbound),
15456          clib_net_to_host_u64 (mp->last_seq_inbound),
15457          clib_net_to_host_u64 (mp->replay_window),
15458          clib_net_to_host_u64 (mp->total_data_size));
15459 }
15460
15461 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15462 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15463
15464 static void vl_api_ipsec_sa_details_t_handler_json
15465   (vl_api_ipsec_sa_details_t * mp)
15466 {
15467   vat_main_t *vam = &vat_main;
15468   vat_json_node_t *node = NULL;
15469   struct in_addr src_ip4, dst_ip4;
15470   struct in6_addr src_ip6, dst_ip6;
15471
15472   if (VAT_JSON_ARRAY != vam->json_tree.type)
15473     {
15474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15475       vat_json_init_array (&vam->json_tree);
15476     }
15477   node = vat_json_array_add (&vam->json_tree);
15478
15479   vat_json_init_object (node);
15480   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15482   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15483   vat_json_object_add_uint (node, "proto", mp->protocol);
15484   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15485   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15486   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15487   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15488   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15489   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15490   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15491                              mp->crypto_key_len);
15492   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15493                              mp->integ_key_len);
15494   if (mp->is_tunnel_ip6)
15495     {
15496       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15497       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15498       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15499       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15500     }
15501   else
15502     {
15503       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15504       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15505       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15506       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15507     }
15508   vat_json_object_add_uint (node, "replay_window",
15509                             clib_net_to_host_u64 (mp->replay_window));
15510   vat_json_object_add_uint (node, "total_data_size",
15511                             clib_net_to_host_u64 (mp->total_data_size));
15512
15513 }
15514
15515 static int
15516 api_ipsec_sa_dump (vat_main_t * vam)
15517 {
15518   unformat_input_t *i = vam->input;
15519   vl_api_ipsec_sa_dump_t *mp;
15520   vl_api_control_ping_t *mp_ping;
15521   u32 sa_id = ~0;
15522   int ret;
15523
15524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15525     {
15526       if (unformat (i, "sa_id %d", &sa_id))
15527         ;
15528       else
15529         {
15530           clib_warning ("parse error '%U'", format_unformat_error, i);
15531           return -99;
15532         }
15533     }
15534
15535   M (IPSEC_SA_DUMP, mp);
15536
15537   mp->sa_id = ntohl (sa_id);
15538
15539   S (mp);
15540
15541   /* Use a control ping for synchronization */
15542   M (CONTROL_PING, mp_ping);
15543   S (mp_ping);
15544
15545   W (ret);
15546   return ret;
15547 }
15548
15549 static int
15550 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15551 {
15552   unformat_input_t *i = vam->input;
15553   vl_api_ipsec_tunnel_if_set_key_t *mp;
15554   u32 sw_if_index = ~0;
15555   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15556   u8 *key = 0;
15557   u32 alg = ~0;
15558   int ret;
15559
15560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15561     {
15562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15563         ;
15564       else
15565         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15566         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15567       else
15568         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15569         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15570       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15571         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15572       else
15573         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15574         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15575       else if (unformat (i, "%U", unformat_hex_string, &key))
15576         ;
15577       else
15578         {
15579           clib_warning ("parse error '%U'", format_unformat_error, i);
15580           return -99;
15581         }
15582     }
15583
15584   if (sw_if_index == ~0)
15585     {
15586       errmsg ("interface must be specified");
15587       return -99;
15588     }
15589
15590   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15591     {
15592       errmsg ("key type must be specified");
15593       return -99;
15594     }
15595
15596   if (alg == ~0)
15597     {
15598       errmsg ("algorithm must be specified");
15599       return -99;
15600     }
15601
15602   if (vec_len (key) == 0)
15603     {
15604       errmsg ("key must be specified");
15605       return -99;
15606     }
15607
15608   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15609
15610   mp->sw_if_index = htonl (sw_if_index);
15611   mp->alg = alg;
15612   mp->key_type = key_type;
15613   mp->key_len = vec_len (key);
15614   clib_memcpy (mp->key, key, vec_len (key));
15615
15616   S (mp);
15617   W (ret);
15618
15619   return ret;
15620 }
15621
15622 static int
15623 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15624 {
15625   unformat_input_t *i = vam->input;
15626   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15627   u32 sw_if_index = ~0;
15628   u32 sa_id = ~0;
15629   u8 is_outbound = (u8) ~ 0;
15630   int ret;
15631
15632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15633     {
15634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15635         ;
15636       else if (unformat (i, "sa_id %d", &sa_id))
15637         ;
15638       else if (unformat (i, "outbound"))
15639         is_outbound = 1;
15640       else if (unformat (i, "inbound"))
15641         is_outbound = 0;
15642       else
15643         {
15644           clib_warning ("parse error '%U'", format_unformat_error, i);
15645           return -99;
15646         }
15647     }
15648
15649   if (sw_if_index == ~0)
15650     {
15651       errmsg ("interface must be specified");
15652       return -99;
15653     }
15654
15655   if (sa_id == ~0)
15656     {
15657       errmsg ("SA ID must be specified");
15658       return -99;
15659     }
15660
15661   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15662
15663   mp->sw_if_index = htonl (sw_if_index);
15664   mp->sa_id = htonl (sa_id);
15665   mp->is_outbound = is_outbound;
15666
15667   S (mp);
15668   W (ret);
15669
15670   return ret;
15671 }
15672
15673 static int
15674 api_ikev2_profile_add_del (vat_main_t * vam)
15675 {
15676   unformat_input_t *i = vam->input;
15677   vl_api_ikev2_profile_add_del_t *mp;
15678   u8 is_add = 1;
15679   u8 *name = 0;
15680   int ret;
15681
15682   const char *valid_chars = "a-zA-Z0-9_";
15683
15684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15685     {
15686       if (unformat (i, "del"))
15687         is_add = 0;
15688       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15689         vec_add1 (name, 0);
15690       else
15691         {
15692           errmsg ("parse error '%U'", format_unformat_error, i);
15693           return -99;
15694         }
15695     }
15696
15697   if (!vec_len (name))
15698     {
15699       errmsg ("profile name must be specified");
15700       return -99;
15701     }
15702
15703   if (vec_len (name) > 64)
15704     {
15705       errmsg ("profile name too long");
15706       return -99;
15707     }
15708
15709   M (IKEV2_PROFILE_ADD_DEL, mp);
15710
15711   clib_memcpy (mp->name, name, vec_len (name));
15712   mp->is_add = is_add;
15713   vec_free (name);
15714
15715   S (mp);
15716   W (ret);
15717   return ret;
15718 }
15719
15720 static int
15721 api_ikev2_profile_set_auth (vat_main_t * vam)
15722 {
15723   unformat_input_t *i = vam->input;
15724   vl_api_ikev2_profile_set_auth_t *mp;
15725   u8 *name = 0;
15726   u8 *data = 0;
15727   u32 auth_method = 0;
15728   u8 is_hex = 0;
15729   int ret;
15730
15731   const char *valid_chars = "a-zA-Z0-9_";
15732
15733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15734     {
15735       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15736         vec_add1 (name, 0);
15737       else if (unformat (i, "auth_method %U",
15738                          unformat_ikev2_auth_method, &auth_method))
15739         ;
15740       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15741         is_hex = 1;
15742       else if (unformat (i, "auth_data %v", &data))
15743         ;
15744       else
15745         {
15746           errmsg ("parse error '%U'", format_unformat_error, i);
15747           return -99;
15748         }
15749     }
15750
15751   if (!vec_len (name))
15752     {
15753       errmsg ("profile name must be specified");
15754       return -99;
15755     }
15756
15757   if (vec_len (name) > 64)
15758     {
15759       errmsg ("profile name too long");
15760       return -99;
15761     }
15762
15763   if (!vec_len (data))
15764     {
15765       errmsg ("auth_data must be specified");
15766       return -99;
15767     }
15768
15769   if (!auth_method)
15770     {
15771       errmsg ("auth_method must be specified");
15772       return -99;
15773     }
15774
15775   M (IKEV2_PROFILE_SET_AUTH, mp);
15776
15777   mp->is_hex = is_hex;
15778   mp->auth_method = (u8) auth_method;
15779   mp->data_len = vec_len (data);
15780   clib_memcpy (mp->name, name, vec_len (name));
15781   clib_memcpy (mp->data, data, vec_len (data));
15782   vec_free (name);
15783   vec_free (data);
15784
15785   S (mp);
15786   W (ret);
15787   return ret;
15788 }
15789
15790 static int
15791 api_ikev2_profile_set_id (vat_main_t * vam)
15792 {
15793   unformat_input_t *i = vam->input;
15794   vl_api_ikev2_profile_set_id_t *mp;
15795   u8 *name = 0;
15796   u8 *data = 0;
15797   u8 is_local = 0;
15798   u32 id_type = 0;
15799   ip4_address_t ip4;
15800   int ret;
15801
15802   const char *valid_chars = "a-zA-Z0-9_";
15803
15804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15805     {
15806       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15807         vec_add1 (name, 0);
15808       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15809         ;
15810       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15811         {
15812           data = vec_new (u8, 4);
15813           clib_memcpy (data, ip4.as_u8, 4);
15814         }
15815       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15816         ;
15817       else if (unformat (i, "id_data %v", &data))
15818         ;
15819       else if (unformat (i, "local"))
15820         is_local = 1;
15821       else if (unformat (i, "remote"))
15822         is_local = 0;
15823       else
15824         {
15825           errmsg ("parse error '%U'", format_unformat_error, i);
15826           return -99;
15827         }
15828     }
15829
15830   if (!vec_len (name))
15831     {
15832       errmsg ("profile name must be specified");
15833       return -99;
15834     }
15835
15836   if (vec_len (name) > 64)
15837     {
15838       errmsg ("profile name too long");
15839       return -99;
15840     }
15841
15842   if (!vec_len (data))
15843     {
15844       errmsg ("id_data must be specified");
15845       return -99;
15846     }
15847
15848   if (!id_type)
15849     {
15850       errmsg ("id_type must be specified");
15851       return -99;
15852     }
15853
15854   M (IKEV2_PROFILE_SET_ID, mp);
15855
15856   mp->is_local = is_local;
15857   mp->id_type = (u8) id_type;
15858   mp->data_len = vec_len (data);
15859   clib_memcpy (mp->name, name, vec_len (name));
15860   clib_memcpy (mp->data, data, vec_len (data));
15861   vec_free (name);
15862   vec_free (data);
15863
15864   S (mp);
15865   W (ret);
15866   return ret;
15867 }
15868
15869 static int
15870 api_ikev2_profile_set_ts (vat_main_t * vam)
15871 {
15872   unformat_input_t *i = vam->input;
15873   vl_api_ikev2_profile_set_ts_t *mp;
15874   u8 *name = 0;
15875   u8 is_local = 0;
15876   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15877   ip4_address_t start_addr, end_addr;
15878
15879   const char *valid_chars = "a-zA-Z0-9_";
15880   int ret;
15881
15882   start_addr.as_u32 = 0;
15883   end_addr.as_u32 = (u32) ~ 0;
15884
15885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15886     {
15887       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15888         vec_add1 (name, 0);
15889       else if (unformat (i, "protocol %d", &proto))
15890         ;
15891       else if (unformat (i, "start_port %d", &start_port))
15892         ;
15893       else if (unformat (i, "end_port %d", &end_port))
15894         ;
15895       else
15896         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15897         ;
15898       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15899         ;
15900       else if (unformat (i, "local"))
15901         is_local = 1;
15902       else if (unformat (i, "remote"))
15903         is_local = 0;
15904       else
15905         {
15906           errmsg ("parse error '%U'", format_unformat_error, i);
15907           return -99;
15908         }
15909     }
15910
15911   if (!vec_len (name))
15912     {
15913       errmsg ("profile name must be specified");
15914       return -99;
15915     }
15916
15917   if (vec_len (name) > 64)
15918     {
15919       errmsg ("profile name too long");
15920       return -99;
15921     }
15922
15923   M (IKEV2_PROFILE_SET_TS, mp);
15924
15925   mp->is_local = is_local;
15926   mp->proto = (u8) proto;
15927   mp->start_port = (u16) start_port;
15928   mp->end_port = (u16) end_port;
15929   mp->start_addr = start_addr.as_u32;
15930   mp->end_addr = end_addr.as_u32;
15931   clib_memcpy (mp->name, name, vec_len (name));
15932   vec_free (name);
15933
15934   S (mp);
15935   W (ret);
15936   return ret;
15937 }
15938
15939 static int
15940 api_ikev2_set_local_key (vat_main_t * vam)
15941 {
15942   unformat_input_t *i = vam->input;
15943   vl_api_ikev2_set_local_key_t *mp;
15944   u8 *file = 0;
15945   int ret;
15946
15947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15948     {
15949       if (unformat (i, "file %v", &file))
15950         vec_add1 (file, 0);
15951       else
15952         {
15953           errmsg ("parse error '%U'", format_unformat_error, i);
15954           return -99;
15955         }
15956     }
15957
15958   if (!vec_len (file))
15959     {
15960       errmsg ("RSA key file must be specified");
15961       return -99;
15962     }
15963
15964   if (vec_len (file) > 256)
15965     {
15966       errmsg ("file name too long");
15967       return -99;
15968     }
15969
15970   M (IKEV2_SET_LOCAL_KEY, mp);
15971
15972   clib_memcpy (mp->key_file, file, vec_len (file));
15973   vec_free (file);
15974
15975   S (mp);
15976   W (ret);
15977   return ret;
15978 }
15979
15980 static int
15981 api_ikev2_set_responder (vat_main_t * vam)
15982 {
15983   unformat_input_t *i = vam->input;
15984   vl_api_ikev2_set_responder_t *mp;
15985   int ret;
15986   u8 *name = 0;
15987   u32 sw_if_index = ~0;
15988   ip4_address_t address;
15989
15990   const char *valid_chars = "a-zA-Z0-9_";
15991
15992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15993     {
15994       if (unformat
15995           (i, "%U interface %d address %U", unformat_token, valid_chars,
15996            &name, &sw_if_index, unformat_ip4_address, &address))
15997         vec_add1 (name, 0);
15998       else
15999         {
16000           errmsg ("parse error '%U'", format_unformat_error, i);
16001           return -99;
16002         }
16003     }
16004
16005   if (!vec_len (name))
16006     {
16007       errmsg ("profile name must be specified");
16008       return -99;
16009     }
16010
16011   if (vec_len (name) > 64)
16012     {
16013       errmsg ("profile name too long");
16014       return -99;
16015     }
16016
16017   M (IKEV2_SET_RESPONDER, mp);
16018
16019   clib_memcpy (mp->name, name, vec_len (name));
16020   vec_free (name);
16021
16022   mp->sw_if_index = sw_if_index;
16023   clib_memcpy (mp->address, &address, sizeof (address));
16024
16025   S (mp);
16026   W (ret);
16027   return ret;
16028 }
16029
16030 static int
16031 api_ikev2_set_ike_transforms (vat_main_t * vam)
16032 {
16033   unformat_input_t *i = vam->input;
16034   vl_api_ikev2_set_ike_transforms_t *mp;
16035   int ret;
16036   u8 *name = 0;
16037   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16038
16039   const char *valid_chars = "a-zA-Z0-9_";
16040
16041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16042     {
16043       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16044                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16045         vec_add1 (name, 0);
16046       else
16047         {
16048           errmsg ("parse error '%U'", format_unformat_error, i);
16049           return -99;
16050         }
16051     }
16052
16053   if (!vec_len (name))
16054     {
16055       errmsg ("profile name must be specified");
16056       return -99;
16057     }
16058
16059   if (vec_len (name) > 64)
16060     {
16061       errmsg ("profile name too long");
16062       return -99;
16063     }
16064
16065   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16066
16067   clib_memcpy (mp->name, name, vec_len (name));
16068   vec_free (name);
16069   mp->crypto_alg = crypto_alg;
16070   mp->crypto_key_size = crypto_key_size;
16071   mp->integ_alg = integ_alg;
16072   mp->dh_group = dh_group;
16073
16074   S (mp);
16075   W (ret);
16076   return ret;
16077 }
16078
16079
16080 static int
16081 api_ikev2_set_esp_transforms (vat_main_t * vam)
16082 {
16083   unformat_input_t *i = vam->input;
16084   vl_api_ikev2_set_esp_transforms_t *mp;
16085   int ret;
16086   u8 *name = 0;
16087   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16088
16089   const char *valid_chars = "a-zA-Z0-9_";
16090
16091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16092     {
16093       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16094                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16095         vec_add1 (name, 0);
16096       else
16097         {
16098           errmsg ("parse error '%U'", format_unformat_error, i);
16099           return -99;
16100         }
16101     }
16102
16103   if (!vec_len (name))
16104     {
16105       errmsg ("profile name must be specified");
16106       return -99;
16107     }
16108
16109   if (vec_len (name) > 64)
16110     {
16111       errmsg ("profile name too long");
16112       return -99;
16113     }
16114
16115   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16116
16117   clib_memcpy (mp->name, name, vec_len (name));
16118   vec_free (name);
16119   mp->crypto_alg = crypto_alg;
16120   mp->crypto_key_size = crypto_key_size;
16121   mp->integ_alg = integ_alg;
16122   mp->dh_group = dh_group;
16123
16124   S (mp);
16125   W (ret);
16126   return ret;
16127 }
16128
16129 static int
16130 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16131 {
16132   unformat_input_t *i = vam->input;
16133   vl_api_ikev2_set_sa_lifetime_t *mp;
16134   int ret;
16135   u8 *name = 0;
16136   u64 lifetime, lifetime_maxdata;
16137   u32 lifetime_jitter, handover;
16138
16139   const char *valid_chars = "a-zA-Z0-9_";
16140
16141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16142     {
16143       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16144                     &lifetime, &lifetime_jitter, &handover,
16145                     &lifetime_maxdata))
16146         vec_add1 (name, 0);
16147       else
16148         {
16149           errmsg ("parse error '%U'", format_unformat_error, i);
16150           return -99;
16151         }
16152     }
16153
16154   if (!vec_len (name))
16155     {
16156       errmsg ("profile name must be specified");
16157       return -99;
16158     }
16159
16160   if (vec_len (name) > 64)
16161     {
16162       errmsg ("profile name too long");
16163       return -99;
16164     }
16165
16166   M (IKEV2_SET_SA_LIFETIME, mp);
16167
16168   clib_memcpy (mp->name, name, vec_len (name));
16169   vec_free (name);
16170   mp->lifetime = lifetime;
16171   mp->lifetime_jitter = lifetime_jitter;
16172   mp->handover = handover;
16173   mp->lifetime_maxdata = lifetime_maxdata;
16174
16175   S (mp);
16176   W (ret);
16177   return ret;
16178 }
16179
16180 static int
16181 api_ikev2_initiate_sa_init (vat_main_t * vam)
16182 {
16183   unformat_input_t *i = vam->input;
16184   vl_api_ikev2_initiate_sa_init_t *mp;
16185   int ret;
16186   u8 *name = 0;
16187
16188   const char *valid_chars = "a-zA-Z0-9_";
16189
16190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16191     {
16192       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16193         vec_add1 (name, 0);
16194       else
16195         {
16196           errmsg ("parse error '%U'", format_unformat_error, i);
16197           return -99;
16198         }
16199     }
16200
16201   if (!vec_len (name))
16202     {
16203       errmsg ("profile name must be specified");
16204       return -99;
16205     }
16206
16207   if (vec_len (name) > 64)
16208     {
16209       errmsg ("profile name too long");
16210       return -99;
16211     }
16212
16213   M (IKEV2_INITIATE_SA_INIT, mp);
16214
16215   clib_memcpy (mp->name, name, vec_len (name));
16216   vec_free (name);
16217
16218   S (mp);
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16225 {
16226   unformat_input_t *i = vam->input;
16227   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16228   int ret;
16229   u64 ispi;
16230
16231
16232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (i, "%lx", &ispi))
16235         ;
16236       else
16237         {
16238           errmsg ("parse error '%U'", format_unformat_error, i);
16239           return -99;
16240         }
16241     }
16242
16243   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16244
16245   mp->ispi = ispi;
16246
16247   S (mp);
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static int
16253 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16254 {
16255   unformat_input_t *i = vam->input;
16256   vl_api_ikev2_initiate_del_child_sa_t *mp;
16257   int ret;
16258   u32 ispi;
16259
16260
16261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (i, "%x", &ispi))
16264         ;
16265       else
16266         {
16267           errmsg ("parse error '%U'", format_unformat_error, i);
16268           return -99;
16269         }
16270     }
16271
16272   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16273
16274   mp->ispi = ispi;
16275
16276   S (mp);
16277   W (ret);
16278   return ret;
16279 }
16280
16281 static int
16282 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16283 {
16284   unformat_input_t *i = vam->input;
16285   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16286   int ret;
16287   u32 ispi;
16288
16289
16290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16291     {
16292       if (unformat (i, "%x", &ispi))
16293         ;
16294       else
16295         {
16296           errmsg ("parse error '%U'", format_unformat_error, i);
16297           return -99;
16298         }
16299     }
16300
16301   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16302
16303   mp->ispi = ispi;
16304
16305   S (mp);
16306   W (ret);
16307   return ret;
16308 }
16309
16310 /*
16311  * MAP
16312  */
16313 static int
16314 api_map_add_domain (vat_main_t * vam)
16315 {
16316   unformat_input_t *i = vam->input;
16317   vl_api_map_add_domain_t *mp;
16318
16319   ip4_address_t ip4_prefix;
16320   ip6_address_t ip6_prefix;
16321   ip6_address_t ip6_src;
16322   u32 num_m_args = 0;
16323   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16324     0, psid_length = 0;
16325   u8 is_translation = 0;
16326   u32 mtu = 0;
16327   u32 ip6_src_len = 128;
16328   int ret;
16329
16330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16331     {
16332       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16333                     &ip4_prefix, &ip4_prefix_len))
16334         num_m_args++;
16335       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16336                          &ip6_prefix, &ip6_prefix_len))
16337         num_m_args++;
16338       else
16339         if (unformat
16340             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16341              &ip6_src_len))
16342         num_m_args++;
16343       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16344         num_m_args++;
16345       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16346         num_m_args++;
16347       else if (unformat (i, "psid-offset %d", &psid_offset))
16348         num_m_args++;
16349       else if (unformat (i, "psid-len %d", &psid_length))
16350         num_m_args++;
16351       else if (unformat (i, "mtu %d", &mtu))
16352         num_m_args++;
16353       else if (unformat (i, "map-t"))
16354         is_translation = 1;
16355       else
16356         {
16357           clib_warning ("parse error '%U'", format_unformat_error, i);
16358           return -99;
16359         }
16360     }
16361
16362   if (num_m_args < 3)
16363     {
16364       errmsg ("mandatory argument(s) missing");
16365       return -99;
16366     }
16367
16368   /* Construct the API message */
16369   M (MAP_ADD_DOMAIN, mp);
16370
16371   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16372   mp->ip4_prefix_len = ip4_prefix_len;
16373
16374   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16375   mp->ip6_prefix_len = ip6_prefix_len;
16376
16377   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16378   mp->ip6_src_prefix_len = ip6_src_len;
16379
16380   mp->ea_bits_len = ea_bits_len;
16381   mp->psid_offset = psid_offset;
16382   mp->psid_length = psid_length;
16383   mp->is_translation = is_translation;
16384   mp->mtu = htons (mtu);
16385
16386   /* send it... */
16387   S (mp);
16388
16389   /* Wait for a reply, return good/bad news  */
16390   W (ret);
16391   return ret;
16392 }
16393
16394 static int
16395 api_map_del_domain (vat_main_t * vam)
16396 {
16397   unformat_input_t *i = vam->input;
16398   vl_api_map_del_domain_t *mp;
16399
16400   u32 num_m_args = 0;
16401   u32 index;
16402   int ret;
16403
16404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16405     {
16406       if (unformat (i, "index %d", &index))
16407         num_m_args++;
16408       else
16409         {
16410           clib_warning ("parse error '%U'", format_unformat_error, i);
16411           return -99;
16412         }
16413     }
16414
16415   if (num_m_args != 1)
16416     {
16417       errmsg ("mandatory argument(s) missing");
16418       return -99;
16419     }
16420
16421   /* Construct the API message */
16422   M (MAP_DEL_DOMAIN, mp);
16423
16424   mp->index = ntohl (index);
16425
16426   /* send it... */
16427   S (mp);
16428
16429   /* Wait for a reply, return good/bad news  */
16430   W (ret);
16431   return ret;
16432 }
16433
16434 static int
16435 api_map_add_del_rule (vat_main_t * vam)
16436 {
16437   unformat_input_t *i = vam->input;
16438   vl_api_map_add_del_rule_t *mp;
16439   u8 is_add = 1;
16440   ip6_address_t ip6_dst;
16441   u32 num_m_args = 0, index, psid = 0;
16442   int ret;
16443
16444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16445     {
16446       if (unformat (i, "index %d", &index))
16447         num_m_args++;
16448       else if (unformat (i, "psid %d", &psid))
16449         num_m_args++;
16450       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16451         num_m_args++;
16452       else if (unformat (i, "del"))
16453         {
16454           is_add = 0;
16455         }
16456       else
16457         {
16458           clib_warning ("parse error '%U'", format_unformat_error, i);
16459           return -99;
16460         }
16461     }
16462
16463   /* Construct the API message */
16464   M (MAP_ADD_DEL_RULE, mp);
16465
16466   mp->index = ntohl (index);
16467   mp->is_add = is_add;
16468   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16469   mp->psid = ntohs (psid);
16470
16471   /* send it... */
16472   S (mp);
16473
16474   /* Wait for a reply, return good/bad news  */
16475   W (ret);
16476   return ret;
16477 }
16478
16479 static int
16480 api_map_domain_dump (vat_main_t * vam)
16481 {
16482   vl_api_map_domain_dump_t *mp;
16483   vl_api_control_ping_t *mp_ping;
16484   int ret;
16485
16486   /* Construct the API message */
16487   M (MAP_DOMAIN_DUMP, mp);
16488
16489   /* send it... */
16490   S (mp);
16491
16492   /* Use a control ping for synchronization */
16493   MPING (CONTROL_PING, mp_ping);
16494   S (mp_ping);
16495
16496   W (ret);
16497   return ret;
16498 }
16499
16500 static int
16501 api_map_rule_dump (vat_main_t * vam)
16502 {
16503   unformat_input_t *i = vam->input;
16504   vl_api_map_rule_dump_t *mp;
16505   vl_api_control_ping_t *mp_ping;
16506   u32 domain_index = ~0;
16507   int ret;
16508
16509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16510     {
16511       if (unformat (i, "index %u", &domain_index))
16512         ;
16513       else
16514         break;
16515     }
16516
16517   if (domain_index == ~0)
16518     {
16519       clib_warning ("parse error: domain index expected");
16520       return -99;
16521     }
16522
16523   /* Construct the API message */
16524   M (MAP_RULE_DUMP, mp);
16525
16526   mp->domain_index = htonl (domain_index);
16527
16528   /* send it... */
16529   S (mp);
16530
16531   /* Use a control ping for synchronization */
16532   MPING (CONTROL_PING, mp_ping);
16533   S (mp_ping);
16534
16535   W (ret);
16536   return ret;
16537 }
16538
16539 static void vl_api_map_add_domain_reply_t_handler
16540   (vl_api_map_add_domain_reply_t * mp)
16541 {
16542   vat_main_t *vam = &vat_main;
16543   i32 retval = ntohl (mp->retval);
16544
16545   if (vam->async_mode)
16546     {
16547       vam->async_errors += (retval < 0);
16548     }
16549   else
16550     {
16551       vam->retval = retval;
16552       vam->result_ready = 1;
16553     }
16554 }
16555
16556 static void vl_api_map_add_domain_reply_t_handler_json
16557   (vl_api_map_add_domain_reply_t * mp)
16558 {
16559   vat_main_t *vam = &vat_main;
16560   vat_json_node_t node;
16561
16562   vat_json_init_object (&node);
16563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16564   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16565
16566   vat_json_print (vam->ofp, &node);
16567   vat_json_free (&node);
16568
16569   vam->retval = ntohl (mp->retval);
16570   vam->result_ready = 1;
16571 }
16572
16573 static int
16574 api_get_first_msg_id (vat_main_t * vam)
16575 {
16576   vl_api_get_first_msg_id_t *mp;
16577   unformat_input_t *i = vam->input;
16578   u8 *name;
16579   u8 name_set = 0;
16580   int ret;
16581
16582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16583     {
16584       if (unformat (i, "client %s", &name))
16585         name_set = 1;
16586       else
16587         break;
16588     }
16589
16590   if (name_set == 0)
16591     {
16592       errmsg ("missing client name");
16593       return -99;
16594     }
16595   vec_add1 (name, 0);
16596
16597   if (vec_len (name) > 63)
16598     {
16599       errmsg ("client name too long");
16600       return -99;
16601     }
16602
16603   M (GET_FIRST_MSG_ID, mp);
16604   clib_memcpy (mp->name, name, vec_len (name));
16605   S (mp);
16606   W (ret);
16607   return ret;
16608 }
16609
16610 static int
16611 api_cop_interface_enable_disable (vat_main_t * vam)
16612 {
16613   unformat_input_t *line_input = vam->input;
16614   vl_api_cop_interface_enable_disable_t *mp;
16615   u32 sw_if_index = ~0;
16616   u8 enable_disable = 1;
16617   int ret;
16618
16619   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16620     {
16621       if (unformat (line_input, "disable"))
16622         enable_disable = 0;
16623       if (unformat (line_input, "enable"))
16624         enable_disable = 1;
16625       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16626                          vam, &sw_if_index))
16627         ;
16628       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16629         ;
16630       else
16631         break;
16632     }
16633
16634   if (sw_if_index == ~0)
16635     {
16636       errmsg ("missing interface name or sw_if_index");
16637       return -99;
16638     }
16639
16640   /* Construct the API message */
16641   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16642   mp->sw_if_index = ntohl (sw_if_index);
16643   mp->enable_disable = enable_disable;
16644
16645   /* send it... */
16646   S (mp);
16647   /* Wait for the reply */
16648   W (ret);
16649   return ret;
16650 }
16651
16652 static int
16653 api_cop_whitelist_enable_disable (vat_main_t * vam)
16654 {
16655   unformat_input_t *line_input = vam->input;
16656   vl_api_cop_whitelist_enable_disable_t *mp;
16657   u32 sw_if_index = ~0;
16658   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16659   u32 fib_id = 0;
16660   int ret;
16661
16662   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16663     {
16664       if (unformat (line_input, "ip4"))
16665         ip4 = 1;
16666       else if (unformat (line_input, "ip6"))
16667         ip6 = 1;
16668       else if (unformat (line_input, "default"))
16669         default_cop = 1;
16670       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16671                          vam, &sw_if_index))
16672         ;
16673       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16674         ;
16675       else if (unformat (line_input, "fib-id %d", &fib_id))
16676         ;
16677       else
16678         break;
16679     }
16680
16681   if (sw_if_index == ~0)
16682     {
16683       errmsg ("missing interface name or sw_if_index");
16684       return -99;
16685     }
16686
16687   /* Construct the API message */
16688   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16689   mp->sw_if_index = ntohl (sw_if_index);
16690   mp->fib_id = ntohl (fib_id);
16691   mp->ip4 = ip4;
16692   mp->ip6 = ip6;
16693   mp->default_cop = default_cop;
16694
16695   /* send it... */
16696   S (mp);
16697   /* Wait for the reply */
16698   W (ret);
16699   return ret;
16700 }
16701
16702 static int
16703 api_get_node_graph (vat_main_t * vam)
16704 {
16705   vl_api_get_node_graph_t *mp;
16706   int ret;
16707
16708   M (GET_NODE_GRAPH, mp);
16709
16710   /* send it... */
16711   S (mp);
16712   /* Wait for the reply */
16713   W (ret);
16714   return ret;
16715 }
16716
16717 /* *INDENT-OFF* */
16718 /** Used for parsing LISP eids */
16719 typedef CLIB_PACKED(struct{
16720   u8 addr[16];   /**< eid address */
16721   u32 len;       /**< prefix length if IP */
16722   u8 type;      /**< type of eid */
16723 }) lisp_eid_vat_t;
16724 /* *INDENT-ON* */
16725
16726 static uword
16727 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16728 {
16729   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16730
16731   memset (a, 0, sizeof (a[0]));
16732
16733   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16734     {
16735       a->type = 0;              /* ipv4 type */
16736     }
16737   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16738     {
16739       a->type = 1;              /* ipv6 type */
16740     }
16741   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16742     {
16743       a->type = 2;              /* mac type */
16744     }
16745   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16746     {
16747       a->type = 3;              /* NSH type */
16748       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16749       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16750     }
16751   else
16752     {
16753       return 0;
16754     }
16755
16756   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16757     {
16758       return 0;
16759     }
16760
16761   return 1;
16762 }
16763
16764 static int
16765 lisp_eid_size_vat (u8 type)
16766 {
16767   switch (type)
16768     {
16769     case 0:
16770       return 4;
16771     case 1:
16772       return 16;
16773     case 2:
16774       return 6;
16775     case 3:
16776       return 5;
16777     }
16778   return 0;
16779 }
16780
16781 static void
16782 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16783 {
16784   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16785 }
16786
16787 static int
16788 api_one_add_del_locator_set (vat_main_t * vam)
16789 {
16790   unformat_input_t *input = vam->input;
16791   vl_api_one_add_del_locator_set_t *mp;
16792   u8 is_add = 1;
16793   u8 *locator_set_name = NULL;
16794   u8 locator_set_name_set = 0;
16795   vl_api_local_locator_t locator, *locators = 0;
16796   u32 sw_if_index, priority, weight;
16797   u32 data_len = 0;
16798
16799   int ret;
16800   /* Parse args required to build the message */
16801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16802     {
16803       if (unformat (input, "del"))
16804         {
16805           is_add = 0;
16806         }
16807       else if (unformat (input, "locator-set %s", &locator_set_name))
16808         {
16809           locator_set_name_set = 1;
16810         }
16811       else if (unformat (input, "sw_if_index %u p %u w %u",
16812                          &sw_if_index, &priority, &weight))
16813         {
16814           locator.sw_if_index = htonl (sw_if_index);
16815           locator.priority = priority;
16816           locator.weight = weight;
16817           vec_add1 (locators, locator);
16818         }
16819       else
16820         if (unformat
16821             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16822              &sw_if_index, &priority, &weight))
16823         {
16824           locator.sw_if_index = htonl (sw_if_index);
16825           locator.priority = priority;
16826           locator.weight = weight;
16827           vec_add1 (locators, locator);
16828         }
16829       else
16830         break;
16831     }
16832
16833   if (locator_set_name_set == 0)
16834     {
16835       errmsg ("missing locator-set name");
16836       vec_free (locators);
16837       return -99;
16838     }
16839
16840   if (vec_len (locator_set_name) > 64)
16841     {
16842       errmsg ("locator-set name too long");
16843       vec_free (locator_set_name);
16844       vec_free (locators);
16845       return -99;
16846     }
16847   vec_add1 (locator_set_name, 0);
16848
16849   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16850
16851   /* Construct the API message */
16852   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16853
16854   mp->is_add = is_add;
16855   clib_memcpy (mp->locator_set_name, locator_set_name,
16856                vec_len (locator_set_name));
16857   vec_free (locator_set_name);
16858
16859   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16860   if (locators)
16861     clib_memcpy (mp->locators, locators, data_len);
16862   vec_free (locators);
16863
16864   /* send it... */
16865   S (mp);
16866
16867   /* Wait for a reply... */
16868   W (ret);
16869   return ret;
16870 }
16871
16872 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16873
16874 static int
16875 api_one_add_del_locator (vat_main_t * vam)
16876 {
16877   unformat_input_t *input = vam->input;
16878   vl_api_one_add_del_locator_t *mp;
16879   u32 tmp_if_index = ~0;
16880   u32 sw_if_index = ~0;
16881   u8 sw_if_index_set = 0;
16882   u8 sw_if_index_if_name_set = 0;
16883   u32 priority = ~0;
16884   u8 priority_set = 0;
16885   u32 weight = ~0;
16886   u8 weight_set = 0;
16887   u8 is_add = 1;
16888   u8 *locator_set_name = NULL;
16889   u8 locator_set_name_set = 0;
16890   int ret;
16891
16892   /* Parse args required to build the message */
16893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16894     {
16895       if (unformat (input, "del"))
16896         {
16897           is_add = 0;
16898         }
16899       else if (unformat (input, "locator-set %s", &locator_set_name))
16900         {
16901           locator_set_name_set = 1;
16902         }
16903       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16904                          &tmp_if_index))
16905         {
16906           sw_if_index_if_name_set = 1;
16907           sw_if_index = tmp_if_index;
16908         }
16909       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16910         {
16911           sw_if_index_set = 1;
16912           sw_if_index = tmp_if_index;
16913         }
16914       else if (unformat (input, "p %d", &priority))
16915         {
16916           priority_set = 1;
16917         }
16918       else if (unformat (input, "w %d", &weight))
16919         {
16920           weight_set = 1;
16921         }
16922       else
16923         break;
16924     }
16925
16926   if (locator_set_name_set == 0)
16927     {
16928       errmsg ("missing locator-set name");
16929       return -99;
16930     }
16931
16932   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16933     {
16934       errmsg ("missing sw_if_index");
16935       vec_free (locator_set_name);
16936       return -99;
16937     }
16938
16939   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16940     {
16941       errmsg ("cannot use both params interface name and sw_if_index");
16942       vec_free (locator_set_name);
16943       return -99;
16944     }
16945
16946   if (priority_set == 0)
16947     {
16948       errmsg ("missing locator-set priority");
16949       vec_free (locator_set_name);
16950       return -99;
16951     }
16952
16953   if (weight_set == 0)
16954     {
16955       errmsg ("missing locator-set weight");
16956       vec_free (locator_set_name);
16957       return -99;
16958     }
16959
16960   if (vec_len (locator_set_name) > 64)
16961     {
16962       errmsg ("locator-set name too long");
16963       vec_free (locator_set_name);
16964       return -99;
16965     }
16966   vec_add1 (locator_set_name, 0);
16967
16968   /* Construct the API message */
16969   M (ONE_ADD_DEL_LOCATOR, mp);
16970
16971   mp->is_add = is_add;
16972   mp->sw_if_index = ntohl (sw_if_index);
16973   mp->priority = priority;
16974   mp->weight = weight;
16975   clib_memcpy (mp->locator_set_name, locator_set_name,
16976                vec_len (locator_set_name));
16977   vec_free (locator_set_name);
16978
16979   /* send it... */
16980   S (mp);
16981
16982   /* Wait for a reply... */
16983   W (ret);
16984   return ret;
16985 }
16986
16987 #define api_lisp_add_del_locator api_one_add_del_locator
16988
16989 uword
16990 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16991 {
16992   u32 *key_id = va_arg (*args, u32 *);
16993   u8 *s = 0;
16994
16995   if (unformat (input, "%s", &s))
16996     {
16997       if (!strcmp ((char *) s, "sha1"))
16998         key_id[0] = HMAC_SHA_1_96;
16999       else if (!strcmp ((char *) s, "sha256"))
17000         key_id[0] = HMAC_SHA_256_128;
17001       else
17002         {
17003           clib_warning ("invalid key_id: '%s'", s);
17004           key_id[0] = HMAC_NO_KEY;
17005         }
17006     }
17007   else
17008     return 0;
17009
17010   vec_free (s);
17011   return 1;
17012 }
17013
17014 static int
17015 api_one_add_del_local_eid (vat_main_t * vam)
17016 {
17017   unformat_input_t *input = vam->input;
17018   vl_api_one_add_del_local_eid_t *mp;
17019   u8 is_add = 1;
17020   u8 eid_set = 0;
17021   lisp_eid_vat_t _eid, *eid = &_eid;
17022   u8 *locator_set_name = 0;
17023   u8 locator_set_name_set = 0;
17024   u32 vni = 0;
17025   u16 key_id = 0;
17026   u8 *key = 0;
17027   int ret;
17028
17029   /* Parse args required to build the message */
17030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17031     {
17032       if (unformat (input, "del"))
17033         {
17034           is_add = 0;
17035         }
17036       else if (unformat (input, "vni %d", &vni))
17037         {
17038           ;
17039         }
17040       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17041         {
17042           eid_set = 1;
17043         }
17044       else if (unformat (input, "locator-set %s", &locator_set_name))
17045         {
17046           locator_set_name_set = 1;
17047         }
17048       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17049         ;
17050       else if (unformat (input, "secret-key %_%v%_", &key))
17051         ;
17052       else
17053         break;
17054     }
17055
17056   if (locator_set_name_set == 0)
17057     {
17058       errmsg ("missing locator-set name");
17059       return -99;
17060     }
17061
17062   if (0 == eid_set)
17063     {
17064       errmsg ("EID address not set!");
17065       vec_free (locator_set_name);
17066       return -99;
17067     }
17068
17069   if (key && (0 == key_id))
17070     {
17071       errmsg ("invalid key_id!");
17072       return -99;
17073     }
17074
17075   if (vec_len (key) > 64)
17076     {
17077       errmsg ("key too long");
17078       vec_free (key);
17079       return -99;
17080     }
17081
17082   if (vec_len (locator_set_name) > 64)
17083     {
17084       errmsg ("locator-set name too long");
17085       vec_free (locator_set_name);
17086       return -99;
17087     }
17088   vec_add1 (locator_set_name, 0);
17089
17090   /* Construct the API message */
17091   M (ONE_ADD_DEL_LOCAL_EID, mp);
17092
17093   mp->is_add = is_add;
17094   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17095   mp->eid_type = eid->type;
17096   mp->prefix_len = eid->len;
17097   mp->vni = clib_host_to_net_u32 (vni);
17098   mp->key_id = clib_host_to_net_u16 (key_id);
17099   clib_memcpy (mp->locator_set_name, locator_set_name,
17100                vec_len (locator_set_name));
17101   clib_memcpy (mp->key, key, vec_len (key));
17102
17103   vec_free (locator_set_name);
17104   vec_free (key);
17105
17106   /* send it... */
17107   S (mp);
17108
17109   /* Wait for a reply... */
17110   W (ret);
17111   return ret;
17112 }
17113
17114 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17115
17116 static int
17117 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17118 {
17119   u32 dp_table = 0, vni = 0;;
17120   unformat_input_t *input = vam->input;
17121   vl_api_gpe_add_del_fwd_entry_t *mp;
17122   u8 is_add = 1;
17123   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17124   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17125   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17126   u32 action = ~0, w;
17127   ip4_address_t rmt_rloc4, lcl_rloc4;
17128   ip6_address_t rmt_rloc6, lcl_rloc6;
17129   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17130   int ret;
17131
17132   memset (&rloc, 0, sizeof (rloc));
17133
17134   /* Parse args required to build the message */
17135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17136     {
17137       if (unformat (input, "del"))
17138         is_add = 0;
17139       else if (unformat (input, "add"))
17140         is_add = 1;
17141       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17142         {
17143           rmt_eid_set = 1;
17144         }
17145       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17146         {
17147           lcl_eid_set = 1;
17148         }
17149       else if (unformat (input, "vrf %d", &dp_table))
17150         ;
17151       else if (unformat (input, "bd %d", &dp_table))
17152         ;
17153       else if (unformat (input, "vni %d", &vni))
17154         ;
17155       else if (unformat (input, "w %d", &w))
17156         {
17157           if (!curr_rloc)
17158             {
17159               errmsg ("No RLOC configured for setting priority/weight!");
17160               return -99;
17161             }
17162           curr_rloc->weight = w;
17163         }
17164       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17165                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17166         {
17167           rloc.is_ip4 = 1;
17168
17169           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17170           rloc.weight = 0;
17171           vec_add1 (lcl_locs, rloc);
17172
17173           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17174           vec_add1 (rmt_locs, rloc);
17175           /* weight saved in rmt loc */
17176           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17177         }
17178       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17179                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17180         {
17181           rloc.is_ip4 = 0;
17182           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17183           rloc.weight = 0;
17184           vec_add1 (lcl_locs, rloc);
17185
17186           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17187           vec_add1 (rmt_locs, rloc);
17188           /* weight saved in rmt loc */
17189           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17190         }
17191       else if (unformat (input, "action %d", &action))
17192         {
17193           ;
17194         }
17195       else
17196         {
17197           clib_warning ("parse error '%U'", format_unformat_error, input);
17198           return -99;
17199         }
17200     }
17201
17202   if (!rmt_eid_set)
17203     {
17204       errmsg ("remote eid addresses not set");
17205       return -99;
17206     }
17207
17208   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17209     {
17210       errmsg ("eid types don't match");
17211       return -99;
17212     }
17213
17214   if (0 == rmt_locs && (u32) ~ 0 == action)
17215     {
17216       errmsg ("action not set for negative mapping");
17217       return -99;
17218     }
17219
17220   /* Construct the API message */
17221   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17222       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17223
17224   mp->is_add = is_add;
17225   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17226   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17227   mp->eid_type = rmt_eid->type;
17228   mp->dp_table = clib_host_to_net_u32 (dp_table);
17229   mp->vni = clib_host_to_net_u32 (vni);
17230   mp->rmt_len = rmt_eid->len;
17231   mp->lcl_len = lcl_eid->len;
17232   mp->action = action;
17233
17234   if (0 != rmt_locs && 0 != lcl_locs)
17235     {
17236       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17237       clib_memcpy (mp->locs, lcl_locs,
17238                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17239
17240       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17241       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17242                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17243     }
17244   vec_free (lcl_locs);
17245   vec_free (rmt_locs);
17246
17247   /* send it... */
17248   S (mp);
17249
17250   /* Wait for a reply... */
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static int
17256 api_one_add_del_map_server (vat_main_t * vam)
17257 {
17258   unformat_input_t *input = vam->input;
17259   vl_api_one_add_del_map_server_t *mp;
17260   u8 is_add = 1;
17261   u8 ipv4_set = 0;
17262   u8 ipv6_set = 0;
17263   ip4_address_t ipv4;
17264   ip6_address_t ipv6;
17265   int ret;
17266
17267   /* Parse args required to build the message */
17268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17269     {
17270       if (unformat (input, "del"))
17271         {
17272           is_add = 0;
17273         }
17274       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17275         {
17276           ipv4_set = 1;
17277         }
17278       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17279         {
17280           ipv6_set = 1;
17281         }
17282       else
17283         break;
17284     }
17285
17286   if (ipv4_set && ipv6_set)
17287     {
17288       errmsg ("both eid v4 and v6 addresses set");
17289       return -99;
17290     }
17291
17292   if (!ipv4_set && !ipv6_set)
17293     {
17294       errmsg ("eid addresses not set");
17295       return -99;
17296     }
17297
17298   /* Construct the API message */
17299   M (ONE_ADD_DEL_MAP_SERVER, mp);
17300
17301   mp->is_add = is_add;
17302   if (ipv6_set)
17303     {
17304       mp->is_ipv6 = 1;
17305       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17306     }
17307   else
17308     {
17309       mp->is_ipv6 = 0;
17310       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17311     }
17312
17313   /* send it... */
17314   S (mp);
17315
17316   /* Wait for a reply... */
17317   W (ret);
17318   return ret;
17319 }
17320
17321 #define api_lisp_add_del_map_server api_one_add_del_map_server
17322
17323 static int
17324 api_one_add_del_map_resolver (vat_main_t * vam)
17325 {
17326   unformat_input_t *input = vam->input;
17327   vl_api_one_add_del_map_resolver_t *mp;
17328   u8 is_add = 1;
17329   u8 ipv4_set = 0;
17330   u8 ipv6_set = 0;
17331   ip4_address_t ipv4;
17332   ip6_address_t ipv6;
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, "del"))
17339         {
17340           is_add = 0;
17341         }
17342       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17343         {
17344           ipv4_set = 1;
17345         }
17346       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17347         {
17348           ipv6_set = 1;
17349         }
17350       else
17351         break;
17352     }
17353
17354   if (ipv4_set && ipv6_set)
17355     {
17356       errmsg ("both eid v4 and v6 addresses set");
17357       return -99;
17358     }
17359
17360   if (!ipv4_set && !ipv6_set)
17361     {
17362       errmsg ("eid addresses not set");
17363       return -99;
17364     }
17365
17366   /* Construct the API message */
17367   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17368
17369   mp->is_add = is_add;
17370   if (ipv6_set)
17371     {
17372       mp->is_ipv6 = 1;
17373       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17374     }
17375   else
17376     {
17377       mp->is_ipv6 = 0;
17378       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17379     }
17380
17381   /* send it... */
17382   S (mp);
17383
17384   /* Wait for a reply... */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17390
17391 static int
17392 api_lisp_gpe_enable_disable (vat_main_t * vam)
17393 {
17394   unformat_input_t *input = vam->input;
17395   vl_api_gpe_enable_disable_t *mp;
17396   u8 is_set = 0;
17397   u8 is_en = 1;
17398   int ret;
17399
17400   /* Parse args required to build the message */
17401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17402     {
17403       if (unformat (input, "enable"))
17404         {
17405           is_set = 1;
17406           is_en = 1;
17407         }
17408       else if (unformat (input, "disable"))
17409         {
17410           is_set = 1;
17411           is_en = 0;
17412         }
17413       else
17414         break;
17415     }
17416
17417   if (is_set == 0)
17418     {
17419       errmsg ("Value not set");
17420       return -99;
17421     }
17422
17423   /* Construct the API message */
17424   M (GPE_ENABLE_DISABLE, mp);
17425
17426   mp->is_en = is_en;
17427
17428   /* send it... */
17429   S (mp);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17438 {
17439   unformat_input_t *input = vam->input;
17440   vl_api_one_rloc_probe_enable_disable_t *mp;
17441   u8 is_set = 0;
17442   u8 is_en = 0;
17443   int ret;
17444
17445   /* Parse args required to build the message */
17446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17447     {
17448       if (unformat (input, "enable"))
17449         {
17450           is_set = 1;
17451           is_en = 1;
17452         }
17453       else if (unformat (input, "disable"))
17454         is_set = 1;
17455       else
17456         break;
17457     }
17458
17459   if (!is_set)
17460     {
17461       errmsg ("Value not set");
17462       return -99;
17463     }
17464
17465   /* Construct the API message */
17466   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17467
17468   mp->is_enabled = is_en;
17469
17470   /* send it... */
17471   S (mp);
17472
17473   /* Wait for a reply... */
17474   W (ret);
17475   return ret;
17476 }
17477
17478 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17479
17480 static int
17481 api_one_map_register_enable_disable (vat_main_t * vam)
17482 {
17483   unformat_input_t *input = vam->input;
17484   vl_api_one_map_register_enable_disable_t *mp;
17485   u8 is_set = 0;
17486   u8 is_en = 0;
17487   int ret;
17488
17489   /* Parse args required to build the message */
17490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17491     {
17492       if (unformat (input, "enable"))
17493         {
17494           is_set = 1;
17495           is_en = 1;
17496         }
17497       else if (unformat (input, "disable"))
17498         is_set = 1;
17499       else
17500         break;
17501     }
17502
17503   if (!is_set)
17504     {
17505       errmsg ("Value not set");
17506       return -99;
17507     }
17508
17509   /* Construct the API message */
17510   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17511
17512   mp->is_enabled = is_en;
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17523
17524 static int
17525 api_one_enable_disable (vat_main_t * vam)
17526 {
17527   unformat_input_t *input = vam->input;
17528   vl_api_one_enable_disable_t *mp;
17529   u8 is_set = 0;
17530   u8 is_en = 0;
17531   int ret;
17532
17533   /* Parse args required to build the message */
17534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17535     {
17536       if (unformat (input, "enable"))
17537         {
17538           is_set = 1;
17539           is_en = 1;
17540         }
17541       else if (unformat (input, "disable"))
17542         {
17543           is_set = 1;
17544         }
17545       else
17546         break;
17547     }
17548
17549   if (!is_set)
17550     {
17551       errmsg ("Value not set");
17552       return -99;
17553     }
17554
17555   /* Construct the API message */
17556   M (ONE_ENABLE_DISABLE, mp);
17557
17558   mp->is_en = is_en;
17559
17560   /* send it... */
17561   S (mp);
17562
17563   /* Wait for a reply... */
17564   W (ret);
17565   return ret;
17566 }
17567
17568 #define api_lisp_enable_disable api_one_enable_disable
17569
17570 static int
17571 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17572 {
17573   unformat_input_t *input = vam->input;
17574   vl_api_one_enable_disable_xtr_mode_t *mp;
17575   u8 is_set = 0;
17576   u8 is_en = 0;
17577   int ret;
17578
17579   /* Parse args required to build the message */
17580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17581     {
17582       if (unformat (input, "enable"))
17583         {
17584           is_set = 1;
17585           is_en = 1;
17586         }
17587       else if (unformat (input, "disable"))
17588         {
17589           is_set = 1;
17590         }
17591       else
17592         break;
17593     }
17594
17595   if (!is_set)
17596     {
17597       errmsg ("Value not set");
17598       return -99;
17599     }
17600
17601   /* Construct the API message */
17602   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17603
17604   mp->is_en = is_en;
17605
17606   /* send it... */
17607   S (mp);
17608
17609   /* Wait for a reply... */
17610   W (ret);
17611   return ret;
17612 }
17613
17614 static int
17615 api_one_show_xtr_mode (vat_main_t * vam)
17616 {
17617   vl_api_one_show_xtr_mode_t *mp;
17618   int ret;
17619
17620   /* Construct the API message */
17621   M (ONE_SHOW_XTR_MODE, mp);
17622
17623   /* send it... */
17624   S (mp);
17625
17626   /* Wait for a reply... */
17627   W (ret);
17628   return ret;
17629 }
17630
17631 static int
17632 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17633 {
17634   unformat_input_t *input = vam->input;
17635   vl_api_one_enable_disable_pitr_mode_t *mp;
17636   u8 is_set = 0;
17637   u8 is_en = 0;
17638   int ret;
17639
17640   /* Parse args required to build the message */
17641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17642     {
17643       if (unformat (input, "enable"))
17644         {
17645           is_set = 1;
17646           is_en = 1;
17647         }
17648       else if (unformat (input, "disable"))
17649         {
17650           is_set = 1;
17651         }
17652       else
17653         break;
17654     }
17655
17656   if (!is_set)
17657     {
17658       errmsg ("Value not set");
17659       return -99;
17660     }
17661
17662   /* Construct the API message */
17663   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17664
17665   mp->is_en = is_en;
17666
17667   /* send it... */
17668   S (mp);
17669
17670   /* Wait for a reply... */
17671   W (ret);
17672   return ret;
17673 }
17674
17675 static int
17676 api_one_show_pitr_mode (vat_main_t * vam)
17677 {
17678   vl_api_one_show_pitr_mode_t *mp;
17679   int ret;
17680
17681   /* Construct the API message */
17682   M (ONE_SHOW_PITR_MODE, mp);
17683
17684   /* send it... */
17685   S (mp);
17686
17687   /* Wait for a reply... */
17688   W (ret);
17689   return ret;
17690 }
17691
17692 static int
17693 api_one_enable_disable_petr_mode (vat_main_t * vam)
17694 {
17695   unformat_input_t *input = vam->input;
17696   vl_api_one_enable_disable_petr_mode_t *mp;
17697   u8 is_set = 0;
17698   u8 is_en = 0;
17699   int ret;
17700
17701   /* Parse args required to build the message */
17702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17703     {
17704       if (unformat (input, "enable"))
17705         {
17706           is_set = 1;
17707           is_en = 1;
17708         }
17709       else if (unformat (input, "disable"))
17710         {
17711           is_set = 1;
17712         }
17713       else
17714         break;
17715     }
17716
17717   if (!is_set)
17718     {
17719       errmsg ("Value not set");
17720       return -99;
17721     }
17722
17723   /* Construct the API message */
17724   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17725
17726   mp->is_en = is_en;
17727
17728   /* send it... */
17729   S (mp);
17730
17731   /* Wait for a reply... */
17732   W (ret);
17733   return ret;
17734 }
17735
17736 static int
17737 api_one_show_petr_mode (vat_main_t * vam)
17738 {
17739   vl_api_one_show_petr_mode_t *mp;
17740   int ret;
17741
17742   /* Construct the API message */
17743   M (ONE_SHOW_PETR_MODE, mp);
17744
17745   /* send it... */
17746   S (mp);
17747
17748   /* Wait for a reply... */
17749   W (ret);
17750   return ret;
17751 }
17752
17753 static int
17754 api_show_one_map_register_state (vat_main_t * vam)
17755 {
17756   vl_api_show_one_map_register_state_t *mp;
17757   int ret;
17758
17759   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17760
17761   /* send */
17762   S (mp);
17763
17764   /* wait for reply */
17765   W (ret);
17766   return ret;
17767 }
17768
17769 #define api_show_lisp_map_register_state api_show_one_map_register_state
17770
17771 static int
17772 api_show_one_rloc_probe_state (vat_main_t * vam)
17773 {
17774   vl_api_show_one_rloc_probe_state_t *mp;
17775   int ret;
17776
17777   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17778
17779   /* send */
17780   S (mp);
17781
17782   /* wait for reply */
17783   W (ret);
17784   return ret;
17785 }
17786
17787 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17788
17789 static int
17790 api_one_add_del_ndp_entry (vat_main_t * vam)
17791 {
17792   vl_api_one_add_del_ndp_entry_t *mp;
17793   unformat_input_t *input = vam->input;
17794   u8 is_add = 1;
17795   u8 mac_set = 0;
17796   u8 bd_set = 0;
17797   u8 ip_set = 0;
17798   u8 mac[6] = { 0, };
17799   u8 ip6[16] = { 0, };
17800   u32 bd = ~0;
17801   int ret;
17802
17803   /* Parse args required to build the message */
17804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17805     {
17806       if (unformat (input, "del"))
17807         is_add = 0;
17808       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17809         mac_set = 1;
17810       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17811         ip_set = 1;
17812       else if (unformat (input, "bd %d", &bd))
17813         bd_set = 1;
17814       else
17815         {
17816           errmsg ("parse error '%U'", format_unformat_error, input);
17817           return -99;
17818         }
17819     }
17820
17821   if (!bd_set || !ip_set || (!mac_set && is_add))
17822     {
17823       errmsg ("Missing BD, IP or MAC!");
17824       return -99;
17825     }
17826
17827   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17828   mp->is_add = is_add;
17829   clib_memcpy (mp->mac, mac, 6);
17830   mp->bd = clib_host_to_net_u32 (bd);
17831   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17832
17833   /* send */
17834   S (mp);
17835
17836   /* wait for reply */
17837   W (ret);
17838   return ret;
17839 }
17840
17841 static int
17842 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17843 {
17844   vl_api_one_add_del_l2_arp_entry_t *mp;
17845   unformat_input_t *input = vam->input;
17846   u8 is_add = 1;
17847   u8 mac_set = 0;
17848   u8 bd_set = 0;
17849   u8 ip_set = 0;
17850   u8 mac[6] = { 0, };
17851   u32 ip4 = 0, bd = ~0;
17852   int ret;
17853
17854   /* Parse args required to build the message */
17855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17856     {
17857       if (unformat (input, "del"))
17858         is_add = 0;
17859       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17860         mac_set = 1;
17861       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17862         ip_set = 1;
17863       else if (unformat (input, "bd %d", &bd))
17864         bd_set = 1;
17865       else
17866         {
17867           errmsg ("parse error '%U'", format_unformat_error, input);
17868           return -99;
17869         }
17870     }
17871
17872   if (!bd_set || !ip_set || (!mac_set && is_add))
17873     {
17874       errmsg ("Missing BD, IP or MAC!");
17875       return -99;
17876     }
17877
17878   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17879   mp->is_add = is_add;
17880   clib_memcpy (mp->mac, mac, 6);
17881   mp->bd = clib_host_to_net_u32 (bd);
17882   mp->ip4 = ip4;
17883
17884   /* send */
17885   S (mp);
17886
17887   /* wait for reply */
17888   W (ret);
17889   return ret;
17890 }
17891
17892 static int
17893 api_one_ndp_bd_get (vat_main_t * vam)
17894 {
17895   vl_api_one_ndp_bd_get_t *mp;
17896   int ret;
17897
17898   M (ONE_NDP_BD_GET, mp);
17899
17900   /* send */
17901   S (mp);
17902
17903   /* wait for reply */
17904   W (ret);
17905   return ret;
17906 }
17907
17908 static int
17909 api_one_ndp_entries_get (vat_main_t * vam)
17910 {
17911   vl_api_one_ndp_entries_get_t *mp;
17912   unformat_input_t *input = vam->input;
17913   u8 bd_set = 0;
17914   u32 bd = ~0;
17915   int ret;
17916
17917   /* Parse args required to build the message */
17918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17919     {
17920       if (unformat (input, "bd %d", &bd))
17921         bd_set = 1;
17922       else
17923         {
17924           errmsg ("parse error '%U'", format_unformat_error, input);
17925           return -99;
17926         }
17927     }
17928
17929   if (!bd_set)
17930     {
17931       errmsg ("Expected bridge domain!");
17932       return -99;
17933     }
17934
17935   M (ONE_NDP_ENTRIES_GET, mp);
17936   mp->bd = clib_host_to_net_u32 (bd);
17937
17938   /* send */
17939   S (mp);
17940
17941   /* wait for reply */
17942   W (ret);
17943   return ret;
17944 }
17945
17946 static int
17947 api_one_l2_arp_bd_get (vat_main_t * vam)
17948 {
17949   vl_api_one_l2_arp_bd_get_t *mp;
17950   int ret;
17951
17952   M (ONE_L2_ARP_BD_GET, mp);
17953
17954   /* send */
17955   S (mp);
17956
17957   /* wait for reply */
17958   W (ret);
17959   return ret;
17960 }
17961
17962 static int
17963 api_one_l2_arp_entries_get (vat_main_t * vam)
17964 {
17965   vl_api_one_l2_arp_entries_get_t *mp;
17966   unformat_input_t *input = vam->input;
17967   u8 bd_set = 0;
17968   u32 bd = ~0;
17969   int ret;
17970
17971   /* Parse args required to build the message */
17972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17973     {
17974       if (unformat (input, "bd %d", &bd))
17975         bd_set = 1;
17976       else
17977         {
17978           errmsg ("parse error '%U'", format_unformat_error, input);
17979           return -99;
17980         }
17981     }
17982
17983   if (!bd_set)
17984     {
17985       errmsg ("Expected bridge domain!");
17986       return -99;
17987     }
17988
17989   M (ONE_L2_ARP_ENTRIES_GET, mp);
17990   mp->bd = clib_host_to_net_u32 (bd);
17991
17992   /* send */
17993   S (mp);
17994
17995   /* wait for reply */
17996   W (ret);
17997   return ret;
17998 }
17999
18000 static int
18001 api_one_stats_enable_disable (vat_main_t * vam)
18002 {
18003   vl_api_one_stats_enable_disable_t *mp;
18004   unformat_input_t *input = vam->input;
18005   u8 is_set = 0;
18006   u8 is_en = 0;
18007   int ret;
18008
18009   /* Parse args required to build the message */
18010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18011     {
18012       if (unformat (input, "enable"))
18013         {
18014           is_set = 1;
18015           is_en = 1;
18016         }
18017       else if (unformat (input, "disable"))
18018         {
18019           is_set = 1;
18020         }
18021       else
18022         break;
18023     }
18024
18025   if (!is_set)
18026     {
18027       errmsg ("Value not set");
18028       return -99;
18029     }
18030
18031   M (ONE_STATS_ENABLE_DISABLE, mp);
18032   mp->is_en = is_en;
18033
18034   /* send */
18035   S (mp);
18036
18037   /* wait for reply */
18038   W (ret);
18039   return ret;
18040 }
18041
18042 static int
18043 api_show_one_stats_enable_disable (vat_main_t * vam)
18044 {
18045   vl_api_show_one_stats_enable_disable_t *mp;
18046   int ret;
18047
18048   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18049
18050   /* send */
18051   S (mp);
18052
18053   /* wait for reply */
18054   W (ret);
18055   return ret;
18056 }
18057
18058 static int
18059 api_show_one_map_request_mode (vat_main_t * vam)
18060 {
18061   vl_api_show_one_map_request_mode_t *mp;
18062   int ret;
18063
18064   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18065
18066   /* send */
18067   S (mp);
18068
18069   /* wait for reply */
18070   W (ret);
18071   return ret;
18072 }
18073
18074 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18075
18076 static int
18077 api_one_map_request_mode (vat_main_t * vam)
18078 {
18079   unformat_input_t *input = vam->input;
18080   vl_api_one_map_request_mode_t *mp;
18081   u8 mode = 0;
18082   int ret;
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "dst-only"))
18088         mode = 0;
18089       else if (unformat (input, "src-dst"))
18090         mode = 1;
18091       else
18092         {
18093           errmsg ("parse error '%U'", format_unformat_error, input);
18094           return -99;
18095         }
18096     }
18097
18098   M (ONE_MAP_REQUEST_MODE, mp);
18099
18100   mp->mode = mode;
18101
18102   /* send */
18103   S (mp);
18104
18105   /* wait for reply */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 #define api_lisp_map_request_mode api_one_map_request_mode
18111
18112 /**
18113  * Enable/disable ONE proxy ITR.
18114  *
18115  * @param vam vpp API test context
18116  * @return return code
18117  */
18118 static int
18119 api_one_pitr_set_locator_set (vat_main_t * vam)
18120 {
18121   u8 ls_name_set = 0;
18122   unformat_input_t *input = vam->input;
18123   vl_api_one_pitr_set_locator_set_t *mp;
18124   u8 is_add = 1;
18125   u8 *ls_name = 0;
18126   int ret;
18127
18128   /* Parse args required to build the message */
18129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18130     {
18131       if (unformat (input, "del"))
18132         is_add = 0;
18133       else if (unformat (input, "locator-set %s", &ls_name))
18134         ls_name_set = 1;
18135       else
18136         {
18137           errmsg ("parse error '%U'", format_unformat_error, input);
18138           return -99;
18139         }
18140     }
18141
18142   if (!ls_name_set)
18143     {
18144       errmsg ("locator-set name not set!");
18145       return -99;
18146     }
18147
18148   M (ONE_PITR_SET_LOCATOR_SET, mp);
18149
18150   mp->is_add = is_add;
18151   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18152   vec_free (ls_name);
18153
18154   /* send */
18155   S (mp);
18156
18157   /* wait for reply */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18163
18164 static int
18165 api_one_nsh_set_locator_set (vat_main_t * vam)
18166 {
18167   u8 ls_name_set = 0;
18168   unformat_input_t *input = vam->input;
18169   vl_api_one_nsh_set_locator_set_t *mp;
18170   u8 is_add = 1;
18171   u8 *ls_name = 0;
18172   int ret;
18173
18174   /* Parse args required to build the message */
18175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18176     {
18177       if (unformat (input, "del"))
18178         is_add = 0;
18179       else if (unformat (input, "ls %s", &ls_name))
18180         ls_name_set = 1;
18181       else
18182         {
18183           errmsg ("parse error '%U'", format_unformat_error, input);
18184           return -99;
18185         }
18186     }
18187
18188   if (!ls_name_set && is_add)
18189     {
18190       errmsg ("locator-set name not set!");
18191       return -99;
18192     }
18193
18194   M (ONE_NSH_SET_LOCATOR_SET, mp);
18195
18196   mp->is_add = is_add;
18197   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18198   vec_free (ls_name);
18199
18200   /* send */
18201   S (mp);
18202
18203   /* wait for reply */
18204   W (ret);
18205   return ret;
18206 }
18207
18208 static int
18209 api_show_one_pitr (vat_main_t * vam)
18210 {
18211   vl_api_show_one_pitr_t *mp;
18212   int ret;
18213
18214   if (!vam->json_output)
18215     {
18216       print (vam->ofp, "%=20s", "lisp status:");
18217     }
18218
18219   M (SHOW_ONE_PITR, mp);
18220   /* send it... */
18221   S (mp);
18222
18223   /* Wait for a reply... */
18224   W (ret);
18225   return ret;
18226 }
18227
18228 #define api_show_lisp_pitr api_show_one_pitr
18229
18230 static int
18231 api_one_use_petr (vat_main_t * vam)
18232 {
18233   unformat_input_t *input = vam->input;
18234   vl_api_one_use_petr_t *mp;
18235   u8 is_add = 0;
18236   ip_address_t ip;
18237   int ret;
18238
18239   memset (&ip, 0, sizeof (ip));
18240
18241   /* Parse args required to build the message */
18242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18243     {
18244       if (unformat (input, "disable"))
18245         is_add = 0;
18246       else
18247         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18248         {
18249           is_add = 1;
18250           ip_addr_version (&ip) = IP4;
18251         }
18252       else
18253         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18254         {
18255           is_add = 1;
18256           ip_addr_version (&ip) = IP6;
18257         }
18258       else
18259         {
18260           errmsg ("parse error '%U'", format_unformat_error, input);
18261           return -99;
18262         }
18263     }
18264
18265   M (ONE_USE_PETR, mp);
18266
18267   mp->is_add = is_add;
18268   if (is_add)
18269     {
18270       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18271       if (mp->is_ip4)
18272         clib_memcpy (mp->address, &ip, 4);
18273       else
18274         clib_memcpy (mp->address, &ip, 16);
18275     }
18276
18277   /* send */
18278   S (mp);
18279
18280   /* wait for reply */
18281   W (ret);
18282   return ret;
18283 }
18284
18285 #define api_lisp_use_petr api_one_use_petr
18286
18287 static int
18288 api_show_one_nsh_mapping (vat_main_t * vam)
18289 {
18290   vl_api_show_one_use_petr_t *mp;
18291   int ret;
18292
18293   if (!vam->json_output)
18294     {
18295       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18296     }
18297
18298   M (SHOW_ONE_NSH_MAPPING, mp);
18299   /* send it... */
18300   S (mp);
18301
18302   /* Wait for a reply... */
18303   W (ret);
18304   return ret;
18305 }
18306
18307 static int
18308 api_show_one_use_petr (vat_main_t * vam)
18309 {
18310   vl_api_show_one_use_petr_t *mp;
18311   int ret;
18312
18313   if (!vam->json_output)
18314     {
18315       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18316     }
18317
18318   M (SHOW_ONE_USE_PETR, mp);
18319   /* send it... */
18320   S (mp);
18321
18322   /* Wait for a reply... */
18323   W (ret);
18324   return ret;
18325 }
18326
18327 #define api_show_lisp_use_petr api_show_one_use_petr
18328
18329 /**
18330  * Add/delete mapping between vni and vrf
18331  */
18332 static int
18333 api_one_eid_table_add_del_map (vat_main_t * vam)
18334 {
18335   unformat_input_t *input = vam->input;
18336   vl_api_one_eid_table_add_del_map_t *mp;
18337   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18338   u32 vni, vrf, bd_index;
18339   int ret;
18340
18341   /* Parse args required to build the message */
18342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18343     {
18344       if (unformat (input, "del"))
18345         is_add = 0;
18346       else if (unformat (input, "vrf %d", &vrf))
18347         vrf_set = 1;
18348       else if (unformat (input, "bd_index %d", &bd_index))
18349         bd_index_set = 1;
18350       else if (unformat (input, "vni %d", &vni))
18351         vni_set = 1;
18352       else
18353         break;
18354     }
18355
18356   if (!vni_set || (!vrf_set && !bd_index_set))
18357     {
18358       errmsg ("missing arguments!");
18359       return -99;
18360     }
18361
18362   if (vrf_set && bd_index_set)
18363     {
18364       errmsg ("error: both vrf and bd entered!");
18365       return -99;
18366     }
18367
18368   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18369
18370   mp->is_add = is_add;
18371   mp->vni = htonl (vni);
18372   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18373   mp->is_l2 = bd_index_set;
18374
18375   /* send */
18376   S (mp);
18377
18378   /* wait for reply */
18379   W (ret);
18380   return ret;
18381 }
18382
18383 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18384
18385 uword
18386 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18387 {
18388   u32 *action = va_arg (*args, u32 *);
18389   u8 *s = 0;
18390
18391   if (unformat (input, "%s", &s))
18392     {
18393       if (!strcmp ((char *) s, "no-action"))
18394         action[0] = 0;
18395       else if (!strcmp ((char *) s, "natively-forward"))
18396         action[0] = 1;
18397       else if (!strcmp ((char *) s, "send-map-request"))
18398         action[0] = 2;
18399       else if (!strcmp ((char *) s, "drop"))
18400         action[0] = 3;
18401       else
18402         {
18403           clib_warning ("invalid action: '%s'", s);
18404           action[0] = 3;
18405         }
18406     }
18407   else
18408     return 0;
18409
18410   vec_free (s);
18411   return 1;
18412 }
18413
18414 /**
18415  * Add/del remote mapping to/from ONE control plane
18416  *
18417  * @param vam vpp API test context
18418  * @return return code
18419  */
18420 static int
18421 api_one_add_del_remote_mapping (vat_main_t * vam)
18422 {
18423   unformat_input_t *input = vam->input;
18424   vl_api_one_add_del_remote_mapping_t *mp;
18425   u32 vni = 0;
18426   lisp_eid_vat_t _eid, *eid = &_eid;
18427   lisp_eid_vat_t _seid, *seid = &_seid;
18428   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18429   u32 action = ~0, p, w, data_len;
18430   ip4_address_t rloc4;
18431   ip6_address_t rloc6;
18432   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18433   int ret;
18434
18435   memset (&rloc, 0, sizeof (rloc));
18436
18437   /* Parse args required to build the message */
18438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18439     {
18440       if (unformat (input, "del-all"))
18441         {
18442           del_all = 1;
18443         }
18444       else if (unformat (input, "del"))
18445         {
18446           is_add = 0;
18447         }
18448       else if (unformat (input, "add"))
18449         {
18450           is_add = 1;
18451         }
18452       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18453         {
18454           eid_set = 1;
18455         }
18456       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18457         {
18458           seid_set = 1;
18459         }
18460       else if (unformat (input, "vni %d", &vni))
18461         {
18462           ;
18463         }
18464       else if (unformat (input, "p %d w %d", &p, &w))
18465         {
18466           if (!curr_rloc)
18467             {
18468               errmsg ("No RLOC configured for setting priority/weight!");
18469               return -99;
18470             }
18471           curr_rloc->priority = p;
18472           curr_rloc->weight = w;
18473         }
18474       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18475         {
18476           rloc.is_ip4 = 1;
18477           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18478           vec_add1 (rlocs, rloc);
18479           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18480         }
18481       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18482         {
18483           rloc.is_ip4 = 0;
18484           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18485           vec_add1 (rlocs, rloc);
18486           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18487         }
18488       else if (unformat (input, "action %U",
18489                          unformat_negative_mapping_action, &action))
18490         {
18491           ;
18492         }
18493       else
18494         {
18495           clib_warning ("parse error '%U'", format_unformat_error, input);
18496           return -99;
18497         }
18498     }
18499
18500   if (0 == eid_set)
18501     {
18502       errmsg ("missing params!");
18503       return -99;
18504     }
18505
18506   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18507     {
18508       errmsg ("no action set for negative map-reply!");
18509       return -99;
18510     }
18511
18512   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18513
18514   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18515   mp->is_add = is_add;
18516   mp->vni = htonl (vni);
18517   mp->action = (u8) action;
18518   mp->is_src_dst = seid_set;
18519   mp->eid_len = eid->len;
18520   mp->seid_len = seid->len;
18521   mp->del_all = del_all;
18522   mp->eid_type = eid->type;
18523   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18524   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18525
18526   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18527   clib_memcpy (mp->rlocs, rlocs, data_len);
18528   vec_free (rlocs);
18529
18530   /* send it... */
18531   S (mp);
18532
18533   /* Wait for a reply... */
18534   W (ret);
18535   return ret;
18536 }
18537
18538 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18539
18540 /**
18541  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18542  * forwarding entries in data-plane accordingly.
18543  *
18544  * @param vam vpp API test context
18545  * @return return code
18546  */
18547 static int
18548 api_one_add_del_adjacency (vat_main_t * vam)
18549 {
18550   unformat_input_t *input = vam->input;
18551   vl_api_one_add_del_adjacency_t *mp;
18552   u32 vni = 0;
18553   ip4_address_t leid4, reid4;
18554   ip6_address_t leid6, reid6;
18555   u8 reid_mac[6] = { 0 };
18556   u8 leid_mac[6] = { 0 };
18557   u8 reid_type, leid_type;
18558   u32 leid_len = 0, reid_len = 0, len;
18559   u8 is_add = 1;
18560   int ret;
18561
18562   leid_type = reid_type = (u8) ~ 0;
18563
18564   /* Parse args required to build the message */
18565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18566     {
18567       if (unformat (input, "del"))
18568         {
18569           is_add = 0;
18570         }
18571       else if (unformat (input, "add"))
18572         {
18573           is_add = 1;
18574         }
18575       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18576                          &reid4, &len))
18577         {
18578           reid_type = 0;        /* ipv4 */
18579           reid_len = len;
18580         }
18581       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18582                          &reid6, &len))
18583         {
18584           reid_type = 1;        /* ipv6 */
18585           reid_len = len;
18586         }
18587       else if (unformat (input, "reid %U", unformat_ethernet_address,
18588                          reid_mac))
18589         {
18590           reid_type = 2;        /* mac */
18591         }
18592       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18593                          &leid4, &len))
18594         {
18595           leid_type = 0;        /* ipv4 */
18596           leid_len = len;
18597         }
18598       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18599                          &leid6, &len))
18600         {
18601           leid_type = 1;        /* ipv6 */
18602           leid_len = len;
18603         }
18604       else if (unformat (input, "leid %U", unformat_ethernet_address,
18605                          leid_mac))
18606         {
18607           leid_type = 2;        /* mac */
18608         }
18609       else if (unformat (input, "vni %d", &vni))
18610         {
18611           ;
18612         }
18613       else
18614         {
18615           errmsg ("parse error '%U'", format_unformat_error, input);
18616           return -99;
18617         }
18618     }
18619
18620   if ((u8) ~ 0 == reid_type)
18621     {
18622       errmsg ("missing params!");
18623       return -99;
18624     }
18625
18626   if (leid_type != reid_type)
18627     {
18628       errmsg ("remote and local EIDs are of different types!");
18629       return -99;
18630     }
18631
18632   M (ONE_ADD_DEL_ADJACENCY, mp);
18633   mp->is_add = is_add;
18634   mp->vni = htonl (vni);
18635   mp->leid_len = leid_len;
18636   mp->reid_len = reid_len;
18637   mp->eid_type = reid_type;
18638
18639   switch (mp->eid_type)
18640     {
18641     case 0:
18642       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18643       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18644       break;
18645     case 1:
18646       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18647       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18648       break;
18649     case 2:
18650       clib_memcpy (mp->leid, leid_mac, 6);
18651       clib_memcpy (mp->reid, reid_mac, 6);
18652       break;
18653     default:
18654       errmsg ("unknown EID type %d!", mp->eid_type);
18655       return 0;
18656     }
18657
18658   /* send it... */
18659   S (mp);
18660
18661   /* Wait for a reply... */
18662   W (ret);
18663   return ret;
18664 }
18665
18666 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18667
18668 uword
18669 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18670 {
18671   u32 *mode = va_arg (*args, u32 *);
18672
18673   if (unformat (input, "lisp"))
18674     *mode = 0;
18675   else if (unformat (input, "vxlan"))
18676     *mode = 1;
18677   else
18678     return 0;
18679
18680   return 1;
18681 }
18682
18683 static int
18684 api_gpe_get_encap_mode (vat_main_t * vam)
18685 {
18686   vl_api_gpe_get_encap_mode_t *mp;
18687   int ret;
18688
18689   /* Construct the API message */
18690   M (GPE_GET_ENCAP_MODE, mp);
18691
18692   /* send it... */
18693   S (mp);
18694
18695   /* Wait for a reply... */
18696   W (ret);
18697   return ret;
18698 }
18699
18700 static int
18701 api_gpe_set_encap_mode (vat_main_t * vam)
18702 {
18703   unformat_input_t *input = vam->input;
18704   vl_api_gpe_set_encap_mode_t *mp;
18705   int ret;
18706   u32 mode = 0;
18707
18708   /* Parse args required to build the message */
18709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18710     {
18711       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18712         ;
18713       else
18714         break;
18715     }
18716
18717   /* Construct the API message */
18718   M (GPE_SET_ENCAP_MODE, mp);
18719
18720   mp->mode = mode;
18721
18722   /* send it... */
18723   S (mp);
18724
18725   /* Wait for a reply... */
18726   W (ret);
18727   return ret;
18728 }
18729
18730 static int
18731 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18732 {
18733   unformat_input_t *input = vam->input;
18734   vl_api_gpe_add_del_iface_t *mp;
18735   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18736   u32 dp_table = 0, vni = 0;
18737   int ret;
18738
18739   /* Parse args required to build the message */
18740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18741     {
18742       if (unformat (input, "up"))
18743         {
18744           action_set = 1;
18745           is_add = 1;
18746         }
18747       else if (unformat (input, "down"))
18748         {
18749           action_set = 1;
18750           is_add = 0;
18751         }
18752       else if (unformat (input, "table_id %d", &dp_table))
18753         {
18754           dp_table_set = 1;
18755         }
18756       else if (unformat (input, "bd_id %d", &dp_table))
18757         {
18758           dp_table_set = 1;
18759           is_l2 = 1;
18760         }
18761       else if (unformat (input, "vni %d", &vni))
18762         {
18763           vni_set = 1;
18764         }
18765       else
18766         break;
18767     }
18768
18769   if (action_set == 0)
18770     {
18771       errmsg ("Action not set");
18772       return -99;
18773     }
18774   if (dp_table_set == 0 || vni_set == 0)
18775     {
18776       errmsg ("vni and dp_table must be set");
18777       return -99;
18778     }
18779
18780   /* Construct the API message */
18781   M (GPE_ADD_DEL_IFACE, mp);
18782
18783   mp->is_add = is_add;
18784   mp->dp_table = clib_host_to_net_u32 (dp_table);
18785   mp->is_l2 = is_l2;
18786   mp->vni = clib_host_to_net_u32 (vni);
18787
18788   /* send it... */
18789   S (mp);
18790
18791   /* Wait for a reply... */
18792   W (ret);
18793   return ret;
18794 }
18795
18796 static int
18797 api_one_map_register_fallback_threshold (vat_main_t * vam)
18798 {
18799   unformat_input_t *input = vam->input;
18800   vl_api_one_map_register_fallback_threshold_t *mp;
18801   u32 value = 0;
18802   u8 is_set = 0;
18803   int ret;
18804
18805   /* Parse args required to build the message */
18806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18807     {
18808       if (unformat (input, "%u", &value))
18809         is_set = 1;
18810       else
18811         {
18812           clib_warning ("parse error '%U'", format_unformat_error, input);
18813           return -99;
18814         }
18815     }
18816
18817   if (!is_set)
18818     {
18819       errmsg ("fallback threshold value is missing!");
18820       return -99;
18821     }
18822
18823   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18824   mp->value = clib_host_to_net_u32 (value);
18825
18826   /* send it... */
18827   S (mp);
18828
18829   /* Wait for a reply... */
18830   W (ret);
18831   return ret;
18832 }
18833
18834 static int
18835 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18836 {
18837   vl_api_show_one_map_register_fallback_threshold_t *mp;
18838   int ret;
18839
18840   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18841
18842   /* send it... */
18843   S (mp);
18844
18845   /* Wait for a reply... */
18846   W (ret);
18847   return ret;
18848 }
18849
18850 uword
18851 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18852 {
18853   u32 *proto = va_arg (*args, u32 *);
18854
18855   if (unformat (input, "udp"))
18856     *proto = 1;
18857   else if (unformat (input, "api"))
18858     *proto = 2;
18859   else
18860     return 0;
18861
18862   return 1;
18863 }
18864
18865 static int
18866 api_one_set_transport_protocol (vat_main_t * vam)
18867 {
18868   unformat_input_t *input = vam->input;
18869   vl_api_one_set_transport_protocol_t *mp;
18870   u8 is_set = 0;
18871   u32 protocol = 0;
18872   int ret;
18873
18874   /* Parse args required to build the message */
18875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18876     {
18877       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18878         is_set = 1;
18879       else
18880         {
18881           clib_warning ("parse error '%U'", format_unformat_error, input);
18882           return -99;
18883         }
18884     }
18885
18886   if (!is_set)
18887     {
18888       errmsg ("Transport protocol missing!");
18889       return -99;
18890     }
18891
18892   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18893   mp->protocol = (u8) protocol;
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 static int
18904 api_one_get_transport_protocol (vat_main_t * vam)
18905 {
18906   vl_api_one_get_transport_protocol_t *mp;
18907   int ret;
18908
18909   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18910
18911   /* send it... */
18912   S (mp);
18913
18914   /* Wait for a reply... */
18915   W (ret);
18916   return ret;
18917 }
18918
18919 static int
18920 api_one_map_register_set_ttl (vat_main_t * vam)
18921 {
18922   unformat_input_t *input = vam->input;
18923   vl_api_one_map_register_set_ttl_t *mp;
18924   u32 ttl = 0;
18925   u8 is_set = 0;
18926   int ret;
18927
18928   /* Parse args required to build the message */
18929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18930     {
18931       if (unformat (input, "%u", &ttl))
18932         is_set = 1;
18933       else
18934         {
18935           clib_warning ("parse error '%U'", format_unformat_error, input);
18936           return -99;
18937         }
18938     }
18939
18940   if (!is_set)
18941     {
18942       errmsg ("TTL value missing!");
18943       return -99;
18944     }
18945
18946   M (ONE_MAP_REGISTER_SET_TTL, mp);
18947   mp->ttl = clib_host_to_net_u32 (ttl);
18948
18949   /* send it... */
18950   S (mp);
18951
18952   /* Wait for a reply... */
18953   W (ret);
18954   return ret;
18955 }
18956
18957 static int
18958 api_show_one_map_register_ttl (vat_main_t * vam)
18959 {
18960   vl_api_show_one_map_register_ttl_t *mp;
18961   int ret;
18962
18963   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18964
18965   /* send it... */
18966   S (mp);
18967
18968   /* Wait for a reply... */
18969   W (ret);
18970   return ret;
18971 }
18972
18973 /**
18974  * Add/del map request itr rlocs from ONE control plane and updates
18975  *
18976  * @param vam vpp API test context
18977  * @return return code
18978  */
18979 static int
18980 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18981 {
18982   unformat_input_t *input = vam->input;
18983   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18984   u8 *locator_set_name = 0;
18985   u8 locator_set_name_set = 0;
18986   u8 is_add = 1;
18987   int ret;
18988
18989   /* Parse args required to build the message */
18990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18991     {
18992       if (unformat (input, "del"))
18993         {
18994           is_add = 0;
18995         }
18996       else if (unformat (input, "%_%v%_", &locator_set_name))
18997         {
18998           locator_set_name_set = 1;
18999         }
19000       else
19001         {
19002           clib_warning ("parse error '%U'", format_unformat_error, input);
19003           return -99;
19004         }
19005     }
19006
19007   if (is_add && !locator_set_name_set)
19008     {
19009       errmsg ("itr-rloc is not set!");
19010       return -99;
19011     }
19012
19013   if (is_add && vec_len (locator_set_name) > 64)
19014     {
19015       errmsg ("itr-rloc locator-set name too long");
19016       vec_free (locator_set_name);
19017       return -99;
19018     }
19019
19020   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19021   mp->is_add = is_add;
19022   if (is_add)
19023     {
19024       clib_memcpy (mp->locator_set_name, locator_set_name,
19025                    vec_len (locator_set_name));
19026     }
19027   else
19028     {
19029       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19030     }
19031   vec_free (locator_set_name);
19032
19033   /* send it... */
19034   S (mp);
19035
19036   /* Wait for a reply... */
19037   W (ret);
19038   return ret;
19039 }
19040
19041 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19042
19043 static int
19044 api_one_locator_dump (vat_main_t * vam)
19045 {
19046   unformat_input_t *input = vam->input;
19047   vl_api_one_locator_dump_t *mp;
19048   vl_api_control_ping_t *mp_ping;
19049   u8 is_index_set = 0, is_name_set = 0;
19050   u8 *ls_name = 0;
19051   u32 ls_index = ~0;
19052   int ret;
19053
19054   /* Parse args required to build the message */
19055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19056     {
19057       if (unformat (input, "ls_name %_%v%_", &ls_name))
19058         {
19059           is_name_set = 1;
19060         }
19061       else if (unformat (input, "ls_index %d", &ls_index))
19062         {
19063           is_index_set = 1;
19064         }
19065       else
19066         {
19067           errmsg ("parse error '%U'", format_unformat_error, input);
19068           return -99;
19069         }
19070     }
19071
19072   if (!is_index_set && !is_name_set)
19073     {
19074       errmsg ("error: expected one of index or name!");
19075       return -99;
19076     }
19077
19078   if (is_index_set && is_name_set)
19079     {
19080       errmsg ("error: only one param expected!");
19081       return -99;
19082     }
19083
19084   if (vec_len (ls_name) > 62)
19085     {
19086       errmsg ("error: locator set name too long!");
19087       return -99;
19088     }
19089
19090   if (!vam->json_output)
19091     {
19092       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19093     }
19094
19095   M (ONE_LOCATOR_DUMP, mp);
19096   mp->is_index_set = is_index_set;
19097
19098   if (is_index_set)
19099     mp->ls_index = clib_host_to_net_u32 (ls_index);
19100   else
19101     {
19102       vec_add1 (ls_name, 0);
19103       strncpy ((char *) mp->ls_name, (char *) ls_name,
19104                sizeof (mp->ls_name) - 1);
19105     }
19106
19107   /* send it... */
19108   S (mp);
19109
19110   /* Use a control ping for synchronization */
19111   MPING (CONTROL_PING, mp_ping);
19112   S (mp_ping);
19113
19114   /* Wait for a reply... */
19115   W (ret);
19116   return ret;
19117 }
19118
19119 #define api_lisp_locator_dump api_one_locator_dump
19120
19121 static int
19122 api_one_locator_set_dump (vat_main_t * vam)
19123 {
19124   vl_api_one_locator_set_dump_t *mp;
19125   vl_api_control_ping_t *mp_ping;
19126   unformat_input_t *input = vam->input;
19127   u8 filter = 0;
19128   int ret;
19129
19130   /* Parse args required to build the message */
19131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19132     {
19133       if (unformat (input, "local"))
19134         {
19135           filter = 1;
19136         }
19137       else if (unformat (input, "remote"))
19138         {
19139           filter = 2;
19140         }
19141       else
19142         {
19143           errmsg ("parse error '%U'", format_unformat_error, input);
19144           return -99;
19145         }
19146     }
19147
19148   if (!vam->json_output)
19149     {
19150       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19151     }
19152
19153   M (ONE_LOCATOR_SET_DUMP, mp);
19154
19155   mp->filter = filter;
19156
19157   /* send it... */
19158   S (mp);
19159
19160   /* Use a control ping for synchronization */
19161   MPING (CONTROL_PING, mp_ping);
19162   S (mp_ping);
19163
19164   /* Wait for a reply... */
19165   W (ret);
19166   return ret;
19167 }
19168
19169 #define api_lisp_locator_set_dump api_one_locator_set_dump
19170
19171 static int
19172 api_one_eid_table_map_dump (vat_main_t * vam)
19173 {
19174   u8 is_l2 = 0;
19175   u8 mode_set = 0;
19176   unformat_input_t *input = vam->input;
19177   vl_api_one_eid_table_map_dump_t *mp;
19178   vl_api_control_ping_t *mp_ping;
19179   int ret;
19180
19181   /* Parse args required to build the message */
19182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19183     {
19184       if (unformat (input, "l2"))
19185         {
19186           is_l2 = 1;
19187           mode_set = 1;
19188         }
19189       else if (unformat (input, "l3"))
19190         {
19191           is_l2 = 0;
19192           mode_set = 1;
19193         }
19194       else
19195         {
19196           errmsg ("parse error '%U'", format_unformat_error, input);
19197           return -99;
19198         }
19199     }
19200
19201   if (!mode_set)
19202     {
19203       errmsg ("expected one of 'l2' or 'l3' parameter!");
19204       return -99;
19205     }
19206
19207   if (!vam->json_output)
19208     {
19209       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19210     }
19211
19212   M (ONE_EID_TABLE_MAP_DUMP, mp);
19213   mp->is_l2 = is_l2;
19214
19215   /* send it... */
19216   S (mp);
19217
19218   /* Use a control ping for synchronization */
19219   MPING (CONTROL_PING, mp_ping);
19220   S (mp_ping);
19221
19222   /* Wait for a reply... */
19223   W (ret);
19224   return ret;
19225 }
19226
19227 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19228
19229 static int
19230 api_one_eid_table_vni_dump (vat_main_t * vam)
19231 {
19232   vl_api_one_eid_table_vni_dump_t *mp;
19233   vl_api_control_ping_t *mp_ping;
19234   int ret;
19235
19236   if (!vam->json_output)
19237     {
19238       print (vam->ofp, "VNI");
19239     }
19240
19241   M (ONE_EID_TABLE_VNI_DUMP, mp);
19242
19243   /* send it... */
19244   S (mp);
19245
19246   /* Use a control ping for synchronization */
19247   MPING (CONTROL_PING, mp_ping);
19248   S (mp_ping);
19249
19250   /* Wait for a reply... */
19251   W (ret);
19252   return ret;
19253 }
19254
19255 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19256
19257 static int
19258 api_one_eid_table_dump (vat_main_t * vam)
19259 {
19260   unformat_input_t *i = vam->input;
19261   vl_api_one_eid_table_dump_t *mp;
19262   vl_api_control_ping_t *mp_ping;
19263   struct in_addr ip4;
19264   struct in6_addr ip6;
19265   u8 mac[6];
19266   u8 eid_type = ~0, eid_set = 0;
19267   u32 prefix_length = ~0, t, vni = 0;
19268   u8 filter = 0;
19269   int ret;
19270   lisp_nsh_api_t nsh;
19271
19272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19273     {
19274       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19275         {
19276           eid_set = 1;
19277           eid_type = 0;
19278           prefix_length = t;
19279         }
19280       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19281         {
19282           eid_set = 1;
19283           eid_type = 1;
19284           prefix_length = t;
19285         }
19286       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19287         {
19288           eid_set = 1;
19289           eid_type = 2;
19290         }
19291       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19292         {
19293           eid_set = 1;
19294           eid_type = 3;
19295         }
19296       else if (unformat (i, "vni %d", &t))
19297         {
19298           vni = t;
19299         }
19300       else if (unformat (i, "local"))
19301         {
19302           filter = 1;
19303         }
19304       else if (unformat (i, "remote"))
19305         {
19306           filter = 2;
19307         }
19308       else
19309         {
19310           errmsg ("parse error '%U'", format_unformat_error, i);
19311           return -99;
19312         }
19313     }
19314
19315   if (!vam->json_output)
19316     {
19317       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19318              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19319     }
19320
19321   M (ONE_EID_TABLE_DUMP, mp);
19322
19323   mp->filter = filter;
19324   if (eid_set)
19325     {
19326       mp->eid_set = 1;
19327       mp->vni = htonl (vni);
19328       mp->eid_type = eid_type;
19329       switch (eid_type)
19330         {
19331         case 0:
19332           mp->prefix_length = prefix_length;
19333           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19334           break;
19335         case 1:
19336           mp->prefix_length = prefix_length;
19337           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19338           break;
19339         case 2:
19340           clib_memcpy (mp->eid, mac, sizeof (mac));
19341           break;
19342         case 3:
19343           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19344           break;
19345         default:
19346           errmsg ("unknown EID type %d!", eid_type);
19347           return -99;
19348         }
19349     }
19350
19351   /* send it... */
19352   S (mp);
19353
19354   /* Use a control ping for synchronization */
19355   MPING (CONTROL_PING, mp_ping);
19356   S (mp_ping);
19357
19358   /* Wait for a reply... */
19359   W (ret);
19360   return ret;
19361 }
19362
19363 #define api_lisp_eid_table_dump api_one_eid_table_dump
19364
19365 static int
19366 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19367 {
19368   unformat_input_t *i = vam->input;
19369   vl_api_gpe_fwd_entries_get_t *mp;
19370   u8 vni_set = 0;
19371   u32 vni = ~0;
19372   int ret;
19373
19374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19375     {
19376       if (unformat (i, "vni %d", &vni))
19377         {
19378           vni_set = 1;
19379         }
19380       else
19381         {
19382           errmsg ("parse error '%U'", format_unformat_error, i);
19383           return -99;
19384         }
19385     }
19386
19387   if (!vni_set)
19388     {
19389       errmsg ("vni not set!");
19390       return -99;
19391     }
19392
19393   if (!vam->json_output)
19394     {
19395       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19396              "leid", "reid");
19397     }
19398
19399   M (GPE_FWD_ENTRIES_GET, mp);
19400   mp->vni = clib_host_to_net_u32 (vni);
19401
19402   /* send it... */
19403   S (mp);
19404
19405   /* Wait for a reply... */
19406   W (ret);
19407   return ret;
19408 }
19409
19410 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19411 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19412 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19413 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19414 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19415 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19416 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19417 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19418
19419 static int
19420 api_one_adjacencies_get (vat_main_t * vam)
19421 {
19422   unformat_input_t *i = vam->input;
19423   vl_api_one_adjacencies_get_t *mp;
19424   u8 vni_set = 0;
19425   u32 vni = ~0;
19426   int ret;
19427
19428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19429     {
19430       if (unformat (i, "vni %d", &vni))
19431         {
19432           vni_set = 1;
19433         }
19434       else
19435         {
19436           errmsg ("parse error '%U'", format_unformat_error, i);
19437           return -99;
19438         }
19439     }
19440
19441   if (!vni_set)
19442     {
19443       errmsg ("vni not set!");
19444       return -99;
19445     }
19446
19447   if (!vam->json_output)
19448     {
19449       print (vam->ofp, "%s %40s", "leid", "reid");
19450     }
19451
19452   M (ONE_ADJACENCIES_GET, mp);
19453   mp->vni = clib_host_to_net_u32 (vni);
19454
19455   /* send it... */
19456   S (mp);
19457
19458   /* Wait for a reply... */
19459   W (ret);
19460   return ret;
19461 }
19462
19463 #define api_lisp_adjacencies_get api_one_adjacencies_get
19464
19465 static int
19466 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19467 {
19468   unformat_input_t *i = vam->input;
19469   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19470   int ret;
19471   u8 ip_family_set = 0, is_ip4 = 1;
19472
19473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19474     {
19475       if (unformat (i, "ip4"))
19476         {
19477           ip_family_set = 1;
19478           is_ip4 = 1;
19479         }
19480       else if (unformat (i, "ip6"))
19481         {
19482           ip_family_set = 1;
19483           is_ip4 = 0;
19484         }
19485       else
19486         {
19487           errmsg ("parse error '%U'", format_unformat_error, i);
19488           return -99;
19489         }
19490     }
19491
19492   if (!ip_family_set)
19493     {
19494       errmsg ("ip family not set!");
19495       return -99;
19496     }
19497
19498   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19499   mp->is_ip4 = is_ip4;
19500
19501   /* send it... */
19502   S (mp);
19503
19504   /* Wait for a reply... */
19505   W (ret);
19506   return ret;
19507 }
19508
19509 static int
19510 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19511 {
19512   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19513   int ret;
19514
19515   if (!vam->json_output)
19516     {
19517       print (vam->ofp, "VNIs");
19518     }
19519
19520   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19521
19522   /* send it... */
19523   S (mp);
19524
19525   /* Wait for a reply... */
19526   W (ret);
19527   return ret;
19528 }
19529
19530 static int
19531 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19532 {
19533   unformat_input_t *i = vam->input;
19534   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19535   int ret = 0;
19536   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19537   struct in_addr ip4;
19538   struct in6_addr ip6;
19539   u32 table_id = 0, nh_sw_if_index = ~0;
19540
19541   memset (&ip4, 0, sizeof (ip4));
19542   memset (&ip6, 0, sizeof (ip6));
19543
19544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19545     {
19546       if (unformat (i, "del"))
19547         is_add = 0;
19548       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19549                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19550         {
19551           ip_set = 1;
19552           is_ip4 = 1;
19553         }
19554       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19555                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19556         {
19557           ip_set = 1;
19558           is_ip4 = 0;
19559         }
19560       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19561         {
19562           ip_set = 1;
19563           is_ip4 = 1;
19564           nh_sw_if_index = ~0;
19565         }
19566       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19567         {
19568           ip_set = 1;
19569           is_ip4 = 0;
19570           nh_sw_if_index = ~0;
19571         }
19572       else if (unformat (i, "table %d", &table_id))
19573         ;
19574       else
19575         {
19576           errmsg ("parse error '%U'", format_unformat_error, i);
19577           return -99;
19578         }
19579     }
19580
19581   if (!ip_set)
19582     {
19583       errmsg ("nh addr not set!");
19584       return -99;
19585     }
19586
19587   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19588   mp->is_add = is_add;
19589   mp->table_id = clib_host_to_net_u32 (table_id);
19590   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19591   mp->is_ip4 = is_ip4;
19592   if (is_ip4)
19593     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19594   else
19595     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19596
19597   /* send it... */
19598   S (mp);
19599
19600   /* Wait for a reply... */
19601   W (ret);
19602   return ret;
19603 }
19604
19605 static int
19606 api_one_map_server_dump (vat_main_t * vam)
19607 {
19608   vl_api_one_map_server_dump_t *mp;
19609   vl_api_control_ping_t *mp_ping;
19610   int ret;
19611
19612   if (!vam->json_output)
19613     {
19614       print (vam->ofp, "%=20s", "Map server");
19615     }
19616
19617   M (ONE_MAP_SERVER_DUMP, mp);
19618   /* send it... */
19619   S (mp);
19620
19621   /* Use a control ping for synchronization */
19622   MPING (CONTROL_PING, mp_ping);
19623   S (mp_ping);
19624
19625   /* Wait for a reply... */
19626   W (ret);
19627   return ret;
19628 }
19629
19630 #define api_lisp_map_server_dump api_one_map_server_dump
19631
19632 static int
19633 api_one_map_resolver_dump (vat_main_t * vam)
19634 {
19635   vl_api_one_map_resolver_dump_t *mp;
19636   vl_api_control_ping_t *mp_ping;
19637   int ret;
19638
19639   if (!vam->json_output)
19640     {
19641       print (vam->ofp, "%=20s", "Map resolver");
19642     }
19643
19644   M (ONE_MAP_RESOLVER_DUMP, mp);
19645   /* send it... */
19646   S (mp);
19647
19648   /* Use a control ping for synchronization */
19649   MPING (CONTROL_PING, mp_ping);
19650   S (mp_ping);
19651
19652   /* Wait for a reply... */
19653   W (ret);
19654   return ret;
19655 }
19656
19657 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19658
19659 static int
19660 api_one_stats_flush (vat_main_t * vam)
19661 {
19662   vl_api_one_stats_flush_t *mp;
19663   int ret = 0;
19664
19665   M (ONE_STATS_FLUSH, mp);
19666   S (mp);
19667   W (ret);
19668   return ret;
19669 }
19670
19671 static int
19672 api_one_stats_dump (vat_main_t * vam)
19673 {
19674   vl_api_one_stats_dump_t *mp;
19675   vl_api_control_ping_t *mp_ping;
19676   int ret;
19677
19678   M (ONE_STATS_DUMP, mp);
19679   /* send it... */
19680   S (mp);
19681
19682   /* Use a control ping for synchronization */
19683   MPING (CONTROL_PING, mp_ping);
19684   S (mp_ping);
19685
19686   /* Wait for a reply... */
19687   W (ret);
19688   return ret;
19689 }
19690
19691 static int
19692 api_show_one_status (vat_main_t * vam)
19693 {
19694   vl_api_show_one_status_t *mp;
19695   int ret;
19696
19697   if (!vam->json_output)
19698     {
19699       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19700     }
19701
19702   M (SHOW_ONE_STATUS, mp);
19703   /* send it... */
19704   S (mp);
19705   /* Wait for a reply... */
19706   W (ret);
19707   return ret;
19708 }
19709
19710 #define api_show_lisp_status api_show_one_status
19711
19712 static int
19713 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19714 {
19715   vl_api_gpe_fwd_entry_path_dump_t *mp;
19716   vl_api_control_ping_t *mp_ping;
19717   unformat_input_t *i = vam->input;
19718   u32 fwd_entry_index = ~0;
19719   int ret;
19720
19721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19722     {
19723       if (unformat (i, "index %d", &fwd_entry_index))
19724         ;
19725       else
19726         break;
19727     }
19728
19729   if (~0 == fwd_entry_index)
19730     {
19731       errmsg ("no index specified!");
19732       return -99;
19733     }
19734
19735   if (!vam->json_output)
19736     {
19737       print (vam->ofp, "first line");
19738     }
19739
19740   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19741
19742   /* send it... */
19743   S (mp);
19744   /* Use a control ping for synchronization */
19745   MPING (CONTROL_PING, mp_ping);
19746   S (mp_ping);
19747
19748   /* Wait for a reply... */
19749   W (ret);
19750   return ret;
19751 }
19752
19753 static int
19754 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19755 {
19756   vl_api_one_get_map_request_itr_rlocs_t *mp;
19757   int ret;
19758
19759   if (!vam->json_output)
19760     {
19761       print (vam->ofp, "%=20s", "itr-rlocs:");
19762     }
19763
19764   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19765   /* send it... */
19766   S (mp);
19767   /* Wait for a reply... */
19768   W (ret);
19769   return ret;
19770 }
19771
19772 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19773
19774 static int
19775 api_af_packet_create (vat_main_t * vam)
19776 {
19777   unformat_input_t *i = vam->input;
19778   vl_api_af_packet_create_t *mp;
19779   u8 *host_if_name = 0;
19780   u8 hw_addr[6];
19781   u8 random_hw_addr = 1;
19782   int ret;
19783
19784   memset (hw_addr, 0, sizeof (hw_addr));
19785
19786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19787     {
19788       if (unformat (i, "name %s", &host_if_name))
19789         vec_add1 (host_if_name, 0);
19790       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19791         random_hw_addr = 0;
19792       else
19793         break;
19794     }
19795
19796   if (!vec_len (host_if_name))
19797     {
19798       errmsg ("host-interface name must be specified");
19799       return -99;
19800     }
19801
19802   if (vec_len (host_if_name) > 64)
19803     {
19804       errmsg ("host-interface name too long");
19805       return -99;
19806     }
19807
19808   M (AF_PACKET_CREATE, mp);
19809
19810   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19811   clib_memcpy (mp->hw_addr, hw_addr, 6);
19812   mp->use_random_hw_addr = random_hw_addr;
19813   vec_free (host_if_name);
19814
19815   S (mp);
19816
19817   /* *INDENT-OFF* */
19818   W2 (ret,
19819       ({
19820         if (ret == 0)
19821           fprintf (vam->ofp ? vam->ofp : stderr,
19822                    " new sw_if_index = %d\n", vam->sw_if_index);
19823       }));
19824   /* *INDENT-ON* */
19825   return ret;
19826 }
19827
19828 static int
19829 api_af_packet_delete (vat_main_t * vam)
19830 {
19831   unformat_input_t *i = vam->input;
19832   vl_api_af_packet_delete_t *mp;
19833   u8 *host_if_name = 0;
19834   int ret;
19835
19836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19837     {
19838       if (unformat (i, "name %s", &host_if_name))
19839         vec_add1 (host_if_name, 0);
19840       else
19841         break;
19842     }
19843
19844   if (!vec_len (host_if_name))
19845     {
19846       errmsg ("host-interface name must be specified");
19847       return -99;
19848     }
19849
19850   if (vec_len (host_if_name) > 64)
19851     {
19852       errmsg ("host-interface name too long");
19853       return -99;
19854     }
19855
19856   M (AF_PACKET_DELETE, mp);
19857
19858   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19859   vec_free (host_if_name);
19860
19861   S (mp);
19862   W (ret);
19863   return ret;
19864 }
19865
19866 static int
19867 api_policer_add_del (vat_main_t * vam)
19868 {
19869   unformat_input_t *i = vam->input;
19870   vl_api_policer_add_del_t *mp;
19871   u8 is_add = 1;
19872   u8 *name = 0;
19873   u32 cir = 0;
19874   u32 eir = 0;
19875   u64 cb = 0;
19876   u64 eb = 0;
19877   u8 rate_type = 0;
19878   u8 round_type = 0;
19879   u8 type = 0;
19880   u8 color_aware = 0;
19881   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19882   int ret;
19883
19884   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19885   conform_action.dscp = 0;
19886   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19887   exceed_action.dscp = 0;
19888   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19889   violate_action.dscp = 0;
19890
19891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19892     {
19893       if (unformat (i, "del"))
19894         is_add = 0;
19895       else if (unformat (i, "name %s", &name))
19896         vec_add1 (name, 0);
19897       else if (unformat (i, "cir %u", &cir))
19898         ;
19899       else if (unformat (i, "eir %u", &eir))
19900         ;
19901       else if (unformat (i, "cb %u", &cb))
19902         ;
19903       else if (unformat (i, "eb %u", &eb))
19904         ;
19905       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19906                          &rate_type))
19907         ;
19908       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19909                          &round_type))
19910         ;
19911       else if (unformat (i, "type %U", unformat_policer_type, &type))
19912         ;
19913       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19914                          &conform_action))
19915         ;
19916       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19917                          &exceed_action))
19918         ;
19919       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19920                          &violate_action))
19921         ;
19922       else if (unformat (i, "color-aware"))
19923         color_aware = 1;
19924       else
19925         break;
19926     }
19927
19928   if (!vec_len (name))
19929     {
19930       errmsg ("policer name must be specified");
19931       return -99;
19932     }
19933
19934   if (vec_len (name) > 64)
19935     {
19936       errmsg ("policer name too long");
19937       return -99;
19938     }
19939
19940   M (POLICER_ADD_DEL, mp);
19941
19942   clib_memcpy (mp->name, name, vec_len (name));
19943   vec_free (name);
19944   mp->is_add = is_add;
19945   mp->cir = ntohl (cir);
19946   mp->eir = ntohl (eir);
19947   mp->cb = clib_net_to_host_u64 (cb);
19948   mp->eb = clib_net_to_host_u64 (eb);
19949   mp->rate_type = rate_type;
19950   mp->round_type = round_type;
19951   mp->type = type;
19952   mp->conform_action_type = conform_action.action_type;
19953   mp->conform_dscp = conform_action.dscp;
19954   mp->exceed_action_type = exceed_action.action_type;
19955   mp->exceed_dscp = exceed_action.dscp;
19956   mp->violate_action_type = violate_action.action_type;
19957   mp->violate_dscp = violate_action.dscp;
19958   mp->color_aware = color_aware;
19959
19960   S (mp);
19961   W (ret);
19962   return ret;
19963 }
19964
19965 static int
19966 api_policer_dump (vat_main_t * vam)
19967 {
19968   unformat_input_t *i = vam->input;
19969   vl_api_policer_dump_t *mp;
19970   vl_api_control_ping_t *mp_ping;
19971   u8 *match_name = 0;
19972   u8 match_name_valid = 0;
19973   int ret;
19974
19975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19976     {
19977       if (unformat (i, "name %s", &match_name))
19978         {
19979           vec_add1 (match_name, 0);
19980           match_name_valid = 1;
19981         }
19982       else
19983         break;
19984     }
19985
19986   M (POLICER_DUMP, mp);
19987   mp->match_name_valid = match_name_valid;
19988   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19989   vec_free (match_name);
19990   /* send it... */
19991   S (mp);
19992
19993   /* Use a control ping for synchronization */
19994   MPING (CONTROL_PING, mp_ping);
19995   S (mp_ping);
19996
19997   /* Wait for a reply... */
19998   W (ret);
19999   return ret;
20000 }
20001
20002 static int
20003 api_policer_classify_set_interface (vat_main_t * vam)
20004 {
20005   unformat_input_t *i = vam->input;
20006   vl_api_policer_classify_set_interface_t *mp;
20007   u32 sw_if_index;
20008   int sw_if_index_set;
20009   u32 ip4_table_index = ~0;
20010   u32 ip6_table_index = ~0;
20011   u32 l2_table_index = ~0;
20012   u8 is_add = 1;
20013   int ret;
20014
20015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20016     {
20017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20018         sw_if_index_set = 1;
20019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20020         sw_if_index_set = 1;
20021       else if (unformat (i, "del"))
20022         is_add = 0;
20023       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20024         ;
20025       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20026         ;
20027       else if (unformat (i, "l2-table %d", &l2_table_index))
20028         ;
20029       else
20030         {
20031           clib_warning ("parse error '%U'", format_unformat_error, i);
20032           return -99;
20033         }
20034     }
20035
20036   if (sw_if_index_set == 0)
20037     {
20038       errmsg ("missing interface name or sw_if_index");
20039       return -99;
20040     }
20041
20042   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20043
20044   mp->sw_if_index = ntohl (sw_if_index);
20045   mp->ip4_table_index = ntohl (ip4_table_index);
20046   mp->ip6_table_index = ntohl (ip6_table_index);
20047   mp->l2_table_index = ntohl (l2_table_index);
20048   mp->is_add = is_add;
20049
20050   S (mp);
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_policer_classify_dump (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_policer_classify_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   u8 type = POLICER_CLASSIFY_N_TABLES;
20062   int ret;
20063
20064   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20065     ;
20066   else
20067     {
20068       errmsg ("classify table type must be specified");
20069       return -99;
20070     }
20071
20072   if (!vam->json_output)
20073     {
20074       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20075     }
20076
20077   M (POLICER_CLASSIFY_DUMP, mp);
20078   mp->type = type;
20079   /* send it... */
20080   S (mp);
20081
20082   /* Use a control ping for synchronization */
20083   MPING (CONTROL_PING, mp_ping);
20084   S (mp_ping);
20085
20086   /* Wait for a reply... */
20087   W (ret);
20088   return ret;
20089 }
20090
20091 static int
20092 api_netmap_create (vat_main_t * vam)
20093 {
20094   unformat_input_t *i = vam->input;
20095   vl_api_netmap_create_t *mp;
20096   u8 *if_name = 0;
20097   u8 hw_addr[6];
20098   u8 random_hw_addr = 1;
20099   u8 is_pipe = 0;
20100   u8 is_master = 0;
20101   int ret;
20102
20103   memset (hw_addr, 0, sizeof (hw_addr));
20104
20105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20106     {
20107       if (unformat (i, "name %s", &if_name))
20108         vec_add1 (if_name, 0);
20109       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20110         random_hw_addr = 0;
20111       else if (unformat (i, "pipe"))
20112         is_pipe = 1;
20113       else if (unformat (i, "master"))
20114         is_master = 1;
20115       else if (unformat (i, "slave"))
20116         is_master = 0;
20117       else
20118         break;
20119     }
20120
20121   if (!vec_len (if_name))
20122     {
20123       errmsg ("interface name must be specified");
20124       return -99;
20125     }
20126
20127   if (vec_len (if_name) > 64)
20128     {
20129       errmsg ("interface name too long");
20130       return -99;
20131     }
20132
20133   M (NETMAP_CREATE, mp);
20134
20135   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20136   clib_memcpy (mp->hw_addr, hw_addr, 6);
20137   mp->use_random_hw_addr = random_hw_addr;
20138   mp->is_pipe = is_pipe;
20139   mp->is_master = is_master;
20140   vec_free (if_name);
20141
20142   S (mp);
20143   W (ret);
20144   return ret;
20145 }
20146
20147 static int
20148 api_netmap_delete (vat_main_t * vam)
20149 {
20150   unformat_input_t *i = vam->input;
20151   vl_api_netmap_delete_t *mp;
20152   u8 *if_name = 0;
20153   int ret;
20154
20155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20156     {
20157       if (unformat (i, "name %s", &if_name))
20158         vec_add1 (if_name, 0);
20159       else
20160         break;
20161     }
20162
20163   if (!vec_len (if_name))
20164     {
20165       errmsg ("interface name must be specified");
20166       return -99;
20167     }
20168
20169   if (vec_len (if_name) > 64)
20170     {
20171       errmsg ("interface name too long");
20172       return -99;
20173     }
20174
20175   M (NETMAP_DELETE, mp);
20176
20177   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20178   vec_free (if_name);
20179
20180   S (mp);
20181   W (ret);
20182   return ret;
20183 }
20184
20185 static void
20186 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20187 {
20188   if (fp->afi == IP46_TYPE_IP6)
20189     print (vam->ofp,
20190            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20191            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20192            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20193            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20194            format_ip6_address, fp->next_hop);
20195   else if (fp->afi == IP46_TYPE_IP4)
20196     print (vam->ofp,
20197            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20198            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20199            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20200            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20201            format_ip4_address, fp->next_hop);
20202 }
20203
20204 static void
20205 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20206                                  vl_api_fib_path_t * fp)
20207 {
20208   struct in_addr ip4;
20209   struct in6_addr ip6;
20210
20211   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20212   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20213   vat_json_object_add_uint (node, "is_local", fp->is_local);
20214   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20215   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20216   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20217   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20218   if (fp->afi == IP46_TYPE_IP4)
20219     {
20220       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20221       vat_json_object_add_ip4 (node, "next_hop", ip4);
20222     }
20223   else if (fp->afi == IP46_TYPE_IP6)
20224     {
20225       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20226       vat_json_object_add_ip6 (node, "next_hop", ip6);
20227     }
20228 }
20229
20230 static void
20231 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20232 {
20233   vat_main_t *vam = &vat_main;
20234   int count = ntohl (mp->mt_count);
20235   vl_api_fib_path_t *fp;
20236   i32 i;
20237
20238   print (vam->ofp, "[%d]: sw_if_index %d via:",
20239          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20240   fp = mp->mt_paths;
20241   for (i = 0; i < count; i++)
20242     {
20243       vl_api_mpls_fib_path_print (vam, fp);
20244       fp++;
20245     }
20246
20247   print (vam->ofp, "");
20248 }
20249
20250 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20251 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20252
20253 static void
20254 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20255 {
20256   vat_main_t *vam = &vat_main;
20257   vat_json_node_t *node = NULL;
20258   int count = ntohl (mp->mt_count);
20259   vl_api_fib_path_t *fp;
20260   i32 i;
20261
20262   if (VAT_JSON_ARRAY != vam->json_tree.type)
20263     {
20264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20265       vat_json_init_array (&vam->json_tree);
20266     }
20267   node = vat_json_array_add (&vam->json_tree);
20268
20269   vat_json_init_object (node);
20270   vat_json_object_add_uint (node, "tunnel_index",
20271                             ntohl (mp->mt_tunnel_index));
20272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20273
20274   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20275
20276   fp = mp->mt_paths;
20277   for (i = 0; i < count; i++)
20278     {
20279       vl_api_mpls_fib_path_json_print (node, fp);
20280       fp++;
20281     }
20282 }
20283
20284 static int
20285 api_mpls_tunnel_dump (vat_main_t * vam)
20286 {
20287   vl_api_mpls_tunnel_dump_t *mp;
20288   vl_api_control_ping_t *mp_ping;
20289   i32 index = -1;
20290   int ret;
20291
20292   /* Parse args required to build the message */
20293   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20294     {
20295       if (!unformat (vam->input, "tunnel_index %d", &index))
20296         {
20297           index = -1;
20298           break;
20299         }
20300     }
20301
20302   print (vam->ofp, "  tunnel_index %d", index);
20303
20304   M (MPLS_TUNNEL_DUMP, mp);
20305   mp->tunnel_index = htonl (index);
20306   S (mp);
20307
20308   /* Use a control ping for synchronization */
20309   MPING (CONTROL_PING, mp_ping);
20310   S (mp_ping);
20311
20312   W (ret);
20313   return ret;
20314 }
20315
20316 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20317 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20318
20319
20320 static void
20321 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20322 {
20323   vat_main_t *vam = &vat_main;
20324   int count = ntohl (mp->count);
20325   vl_api_fib_path_t *fp;
20326   int i;
20327
20328   print (vam->ofp,
20329          "table-id %d, label %u, ess_bit %u",
20330          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20331   fp = mp->path;
20332   for (i = 0; i < count; i++)
20333     {
20334       vl_api_mpls_fib_path_print (vam, fp);
20335       fp++;
20336     }
20337 }
20338
20339 static void vl_api_mpls_fib_details_t_handler_json
20340   (vl_api_mpls_fib_details_t * mp)
20341 {
20342   vat_main_t *vam = &vat_main;
20343   int count = ntohl (mp->count);
20344   vat_json_node_t *node = NULL;
20345   vl_api_fib_path_t *fp;
20346   int i;
20347
20348   if (VAT_JSON_ARRAY != vam->json_tree.type)
20349     {
20350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20351       vat_json_init_array (&vam->json_tree);
20352     }
20353   node = vat_json_array_add (&vam->json_tree);
20354
20355   vat_json_init_object (node);
20356   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20357   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20358   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20359   vat_json_object_add_uint (node, "path_count", count);
20360   fp = mp->path;
20361   for (i = 0; i < count; i++)
20362     {
20363       vl_api_mpls_fib_path_json_print (node, fp);
20364       fp++;
20365     }
20366 }
20367
20368 static int
20369 api_mpls_fib_dump (vat_main_t * vam)
20370 {
20371   vl_api_mpls_fib_dump_t *mp;
20372   vl_api_control_ping_t *mp_ping;
20373   int ret;
20374
20375   M (MPLS_FIB_DUMP, mp);
20376   S (mp);
20377
20378   /* Use a control ping for synchronization */
20379   MPING (CONTROL_PING, mp_ping);
20380   S (mp_ping);
20381
20382   W (ret);
20383   return ret;
20384 }
20385
20386 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20387 #define vl_api_ip_fib_details_t_print vl_noop_handler
20388
20389 static void
20390 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20391 {
20392   vat_main_t *vam = &vat_main;
20393   int count = ntohl (mp->count);
20394   vl_api_fib_path_t *fp;
20395   int i;
20396
20397   print (vam->ofp,
20398          "table-id %d, prefix %U/%d",
20399          ntohl (mp->table_id), format_ip4_address, mp->address,
20400          mp->address_length);
20401   fp = mp->path;
20402   for (i = 0; i < count; i++)
20403     {
20404       if (fp->afi == IP46_TYPE_IP6)
20405         print (vam->ofp,
20406                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20407                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20408                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20409                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20410                format_ip6_address, fp->next_hop);
20411       else if (fp->afi == IP46_TYPE_IP4)
20412         print (vam->ofp,
20413                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20414                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20415                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20416                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20417                format_ip4_address, fp->next_hop);
20418       fp++;
20419     }
20420 }
20421
20422 static void vl_api_ip_fib_details_t_handler_json
20423   (vl_api_ip_fib_details_t * mp)
20424 {
20425   vat_main_t *vam = &vat_main;
20426   int count = ntohl (mp->count);
20427   vat_json_node_t *node = NULL;
20428   struct in_addr ip4;
20429   struct in6_addr ip6;
20430   vl_api_fib_path_t *fp;
20431   int i;
20432
20433   if (VAT_JSON_ARRAY != vam->json_tree.type)
20434     {
20435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20436       vat_json_init_array (&vam->json_tree);
20437     }
20438   node = vat_json_array_add (&vam->json_tree);
20439
20440   vat_json_init_object (node);
20441   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20442   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20443   vat_json_object_add_ip4 (node, "prefix", ip4);
20444   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20445   vat_json_object_add_uint (node, "path_count", count);
20446   fp = mp->path;
20447   for (i = 0; i < count; i++)
20448     {
20449       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20450       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20451       vat_json_object_add_uint (node, "is_local", fp->is_local);
20452       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20453       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20454       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20455       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20456       if (fp->afi == IP46_TYPE_IP4)
20457         {
20458           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20459           vat_json_object_add_ip4 (node, "next_hop", ip4);
20460         }
20461       else if (fp->afi == IP46_TYPE_IP6)
20462         {
20463           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20464           vat_json_object_add_ip6 (node, "next_hop", ip6);
20465         }
20466     }
20467 }
20468
20469 static int
20470 api_ip_fib_dump (vat_main_t * vam)
20471 {
20472   vl_api_ip_fib_dump_t *mp;
20473   vl_api_control_ping_t *mp_ping;
20474   int ret;
20475
20476   M (IP_FIB_DUMP, mp);
20477   S (mp);
20478
20479   /* Use a control ping for synchronization */
20480   MPING (CONTROL_PING, mp_ping);
20481   S (mp_ping);
20482
20483   W (ret);
20484   return ret;
20485 }
20486
20487 static int
20488 api_ip_mfib_dump (vat_main_t * vam)
20489 {
20490   vl_api_ip_mfib_dump_t *mp;
20491   vl_api_control_ping_t *mp_ping;
20492   int ret;
20493
20494   M (IP_MFIB_DUMP, mp);
20495   S (mp);
20496
20497   /* Use a control ping for synchronization */
20498   MPING (CONTROL_PING, mp_ping);
20499   S (mp_ping);
20500
20501   W (ret);
20502   return ret;
20503 }
20504
20505 static void vl_api_ip_neighbor_details_t_handler
20506   (vl_api_ip_neighbor_details_t * mp)
20507 {
20508   vat_main_t *vam = &vat_main;
20509
20510   print (vam->ofp, "%c %U %U",
20511          (mp->is_static) ? 'S' : 'D',
20512          format_ethernet_address, &mp->mac_address,
20513          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20514          &mp->ip_address);
20515 }
20516
20517 static void vl_api_ip_neighbor_details_t_handler_json
20518   (vl_api_ip_neighbor_details_t * mp)
20519 {
20520
20521   vat_main_t *vam = &vat_main;
20522   vat_json_node_t *node;
20523   struct in_addr ip4;
20524   struct in6_addr ip6;
20525
20526   if (VAT_JSON_ARRAY != vam->json_tree.type)
20527     {
20528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20529       vat_json_init_array (&vam->json_tree);
20530     }
20531   node = vat_json_array_add (&vam->json_tree);
20532
20533   vat_json_init_object (node);
20534   vat_json_object_add_string_copy (node, "flag",
20535                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20536                                    "dynamic");
20537
20538   vat_json_object_add_string_copy (node, "link_layer",
20539                                    format (0, "%U", format_ethernet_address,
20540                                            &mp->mac_address));
20541
20542   if (mp->is_ipv6)
20543     {
20544       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20545       vat_json_object_add_ip6 (node, "ip_address", ip6);
20546     }
20547   else
20548     {
20549       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20550       vat_json_object_add_ip4 (node, "ip_address", ip4);
20551     }
20552 }
20553
20554 static int
20555 api_ip_neighbor_dump (vat_main_t * vam)
20556 {
20557   unformat_input_t *i = vam->input;
20558   vl_api_ip_neighbor_dump_t *mp;
20559   vl_api_control_ping_t *mp_ping;
20560   u8 is_ipv6 = 0;
20561   u32 sw_if_index = ~0;
20562   int ret;
20563
20564   /* Parse args required to build the message */
20565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20566     {
20567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20568         ;
20569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20570         ;
20571       else if (unformat (i, "ip6"))
20572         is_ipv6 = 1;
20573       else
20574         break;
20575     }
20576
20577   if (sw_if_index == ~0)
20578     {
20579       errmsg ("missing interface name or sw_if_index");
20580       return -99;
20581     }
20582
20583   M (IP_NEIGHBOR_DUMP, mp);
20584   mp->is_ipv6 = (u8) is_ipv6;
20585   mp->sw_if_index = ntohl (sw_if_index);
20586   S (mp);
20587
20588   /* Use a control ping for synchronization */
20589   MPING (CONTROL_PING, mp_ping);
20590   S (mp_ping);
20591
20592   W (ret);
20593   return ret;
20594 }
20595
20596 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20597 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20598
20599 static void
20600 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20601 {
20602   vat_main_t *vam = &vat_main;
20603   int count = ntohl (mp->count);
20604   vl_api_fib_path_t *fp;
20605   int i;
20606
20607   print (vam->ofp,
20608          "table-id %d, prefix %U/%d",
20609          ntohl (mp->table_id), format_ip6_address, mp->address,
20610          mp->address_length);
20611   fp = mp->path;
20612   for (i = 0; i < count; i++)
20613     {
20614       if (fp->afi == IP46_TYPE_IP6)
20615         print (vam->ofp,
20616                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20617                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20618                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20619                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20620                format_ip6_address, fp->next_hop);
20621       else if (fp->afi == IP46_TYPE_IP4)
20622         print (vam->ofp,
20623                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20624                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20625                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20626                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20627                format_ip4_address, fp->next_hop);
20628       fp++;
20629     }
20630 }
20631
20632 static void vl_api_ip6_fib_details_t_handler_json
20633   (vl_api_ip6_fib_details_t * mp)
20634 {
20635   vat_main_t *vam = &vat_main;
20636   int count = ntohl (mp->count);
20637   vat_json_node_t *node = NULL;
20638   struct in_addr ip4;
20639   struct in6_addr ip6;
20640   vl_api_fib_path_t *fp;
20641   int i;
20642
20643   if (VAT_JSON_ARRAY != vam->json_tree.type)
20644     {
20645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20646       vat_json_init_array (&vam->json_tree);
20647     }
20648   node = vat_json_array_add (&vam->json_tree);
20649
20650   vat_json_init_object (node);
20651   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20652   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20653   vat_json_object_add_ip6 (node, "prefix", ip6);
20654   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20655   vat_json_object_add_uint (node, "path_count", count);
20656   fp = mp->path;
20657   for (i = 0; i < count; i++)
20658     {
20659       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20660       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20661       vat_json_object_add_uint (node, "is_local", fp->is_local);
20662       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20663       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20664       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20665       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20666       if (fp->afi == IP46_TYPE_IP4)
20667         {
20668           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20669           vat_json_object_add_ip4 (node, "next_hop", ip4);
20670         }
20671       else if (fp->afi == IP46_TYPE_IP6)
20672         {
20673           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20674           vat_json_object_add_ip6 (node, "next_hop", ip6);
20675         }
20676     }
20677 }
20678
20679 static int
20680 api_ip6_fib_dump (vat_main_t * vam)
20681 {
20682   vl_api_ip6_fib_dump_t *mp;
20683   vl_api_control_ping_t *mp_ping;
20684   int ret;
20685
20686   M (IP6_FIB_DUMP, mp);
20687   S (mp);
20688
20689   /* Use a control ping for synchronization */
20690   MPING (CONTROL_PING, mp_ping);
20691   S (mp_ping);
20692
20693   W (ret);
20694   return ret;
20695 }
20696
20697 static int
20698 api_ip6_mfib_dump (vat_main_t * vam)
20699 {
20700   vl_api_ip6_mfib_dump_t *mp;
20701   vl_api_control_ping_t *mp_ping;
20702   int ret;
20703
20704   M (IP6_MFIB_DUMP, mp);
20705   S (mp);
20706
20707   /* Use a control ping for synchronization */
20708   MPING (CONTROL_PING, mp_ping);
20709   S (mp_ping);
20710
20711   W (ret);
20712   return ret;
20713 }
20714
20715 int
20716 api_classify_table_ids (vat_main_t * vam)
20717 {
20718   vl_api_classify_table_ids_t *mp;
20719   int ret;
20720
20721   /* Construct the API message */
20722   M (CLASSIFY_TABLE_IDS, mp);
20723   mp->context = 0;
20724
20725   S (mp);
20726   W (ret);
20727   return ret;
20728 }
20729
20730 int
20731 api_classify_table_by_interface (vat_main_t * vam)
20732 {
20733   unformat_input_t *input = vam->input;
20734   vl_api_classify_table_by_interface_t *mp;
20735
20736   u32 sw_if_index = ~0;
20737   int ret;
20738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20739     {
20740       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20741         ;
20742       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20743         ;
20744       else
20745         break;
20746     }
20747   if (sw_if_index == ~0)
20748     {
20749       errmsg ("missing interface name or sw_if_index");
20750       return -99;
20751     }
20752
20753   /* Construct the API message */
20754   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20755   mp->context = 0;
20756   mp->sw_if_index = ntohl (sw_if_index);
20757
20758   S (mp);
20759   W (ret);
20760   return ret;
20761 }
20762
20763 int
20764 api_classify_table_info (vat_main_t * vam)
20765 {
20766   unformat_input_t *input = vam->input;
20767   vl_api_classify_table_info_t *mp;
20768
20769   u32 table_id = ~0;
20770   int ret;
20771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20772     {
20773       if (unformat (input, "table_id %d", &table_id))
20774         ;
20775       else
20776         break;
20777     }
20778   if (table_id == ~0)
20779     {
20780       errmsg ("missing table id");
20781       return -99;
20782     }
20783
20784   /* Construct the API message */
20785   M (CLASSIFY_TABLE_INFO, mp);
20786   mp->context = 0;
20787   mp->table_id = ntohl (table_id);
20788
20789   S (mp);
20790   W (ret);
20791   return ret;
20792 }
20793
20794 int
20795 api_classify_session_dump (vat_main_t * vam)
20796 {
20797   unformat_input_t *input = vam->input;
20798   vl_api_classify_session_dump_t *mp;
20799   vl_api_control_ping_t *mp_ping;
20800
20801   u32 table_id = ~0;
20802   int ret;
20803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20804     {
20805       if (unformat (input, "table_id %d", &table_id))
20806         ;
20807       else
20808         break;
20809     }
20810   if (table_id == ~0)
20811     {
20812       errmsg ("missing table id");
20813       return -99;
20814     }
20815
20816   /* Construct the API message */
20817   M (CLASSIFY_SESSION_DUMP, mp);
20818   mp->context = 0;
20819   mp->table_id = ntohl (table_id);
20820   S (mp);
20821
20822   /* Use a control ping for synchronization */
20823   MPING (CONTROL_PING, mp_ping);
20824   S (mp_ping);
20825
20826   W (ret);
20827   return ret;
20828 }
20829
20830 static void
20831 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20832 {
20833   vat_main_t *vam = &vat_main;
20834
20835   print (vam->ofp, "collector_address %U, collector_port %d, "
20836          "src_address %U, vrf_id %d, path_mtu %u, "
20837          "template_interval %u, udp_checksum %d",
20838          format_ip4_address, mp->collector_address,
20839          ntohs (mp->collector_port),
20840          format_ip4_address, mp->src_address,
20841          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20842          ntohl (mp->template_interval), mp->udp_checksum);
20843
20844   vam->retval = 0;
20845   vam->result_ready = 1;
20846 }
20847
20848 static void
20849   vl_api_ipfix_exporter_details_t_handler_json
20850   (vl_api_ipfix_exporter_details_t * mp)
20851 {
20852   vat_main_t *vam = &vat_main;
20853   vat_json_node_t node;
20854   struct in_addr collector_address;
20855   struct in_addr src_address;
20856
20857   vat_json_init_object (&node);
20858   clib_memcpy (&collector_address, &mp->collector_address,
20859                sizeof (collector_address));
20860   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20861   vat_json_object_add_uint (&node, "collector_port",
20862                             ntohs (mp->collector_port));
20863   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20864   vat_json_object_add_ip4 (&node, "src_address", src_address);
20865   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20866   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20867   vat_json_object_add_uint (&node, "template_interval",
20868                             ntohl (mp->template_interval));
20869   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20870
20871   vat_json_print (vam->ofp, &node);
20872   vat_json_free (&node);
20873   vam->retval = 0;
20874   vam->result_ready = 1;
20875 }
20876
20877 int
20878 api_ipfix_exporter_dump (vat_main_t * vam)
20879 {
20880   vl_api_ipfix_exporter_dump_t *mp;
20881   int ret;
20882
20883   /* Construct the API message */
20884   M (IPFIX_EXPORTER_DUMP, mp);
20885   mp->context = 0;
20886
20887   S (mp);
20888   W (ret);
20889   return ret;
20890 }
20891
20892 static int
20893 api_ipfix_classify_stream_dump (vat_main_t * vam)
20894 {
20895   vl_api_ipfix_classify_stream_dump_t *mp;
20896   int ret;
20897
20898   /* Construct the API message */
20899   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20900   mp->context = 0;
20901
20902   S (mp);
20903   W (ret);
20904   return ret;
20905   /* NOTREACHED */
20906   return 0;
20907 }
20908
20909 static void
20910   vl_api_ipfix_classify_stream_details_t_handler
20911   (vl_api_ipfix_classify_stream_details_t * mp)
20912 {
20913   vat_main_t *vam = &vat_main;
20914   print (vam->ofp, "domain_id %d, src_port %d",
20915          ntohl (mp->domain_id), ntohs (mp->src_port));
20916   vam->retval = 0;
20917   vam->result_ready = 1;
20918 }
20919
20920 static void
20921   vl_api_ipfix_classify_stream_details_t_handler_json
20922   (vl_api_ipfix_classify_stream_details_t * mp)
20923 {
20924   vat_main_t *vam = &vat_main;
20925   vat_json_node_t node;
20926
20927   vat_json_init_object (&node);
20928   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20929   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20930
20931   vat_json_print (vam->ofp, &node);
20932   vat_json_free (&node);
20933   vam->retval = 0;
20934   vam->result_ready = 1;
20935 }
20936
20937 static int
20938 api_ipfix_classify_table_dump (vat_main_t * vam)
20939 {
20940   vl_api_ipfix_classify_table_dump_t *mp;
20941   vl_api_control_ping_t *mp_ping;
20942   int ret;
20943
20944   if (!vam->json_output)
20945     {
20946       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20947              "transport_protocol");
20948     }
20949
20950   /* Construct the API message */
20951   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20952
20953   /* send it... */
20954   S (mp);
20955
20956   /* Use a control ping for synchronization */
20957   MPING (CONTROL_PING, mp_ping);
20958   S (mp_ping);
20959
20960   W (ret);
20961   return ret;
20962 }
20963
20964 static void
20965   vl_api_ipfix_classify_table_details_t_handler
20966   (vl_api_ipfix_classify_table_details_t * mp)
20967 {
20968   vat_main_t *vam = &vat_main;
20969   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20970          mp->transport_protocol);
20971 }
20972
20973 static void
20974   vl_api_ipfix_classify_table_details_t_handler_json
20975   (vl_api_ipfix_classify_table_details_t * mp)
20976 {
20977   vat_json_node_t *node = NULL;
20978   vat_main_t *vam = &vat_main;
20979
20980   if (VAT_JSON_ARRAY != vam->json_tree.type)
20981     {
20982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20983       vat_json_init_array (&vam->json_tree);
20984     }
20985
20986   node = vat_json_array_add (&vam->json_tree);
20987   vat_json_init_object (node);
20988
20989   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20990   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20991   vat_json_object_add_uint (node, "transport_protocol",
20992                             mp->transport_protocol);
20993 }
20994
20995 static int
20996 api_sw_interface_span_enable_disable (vat_main_t * vam)
20997 {
20998   unformat_input_t *i = vam->input;
20999   vl_api_sw_interface_span_enable_disable_t *mp;
21000   u32 src_sw_if_index = ~0;
21001   u32 dst_sw_if_index = ~0;
21002   u8 state = 3;
21003   int ret;
21004   u8 is_l2 = 0;
21005
21006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21007     {
21008       if (unformat
21009           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21010         ;
21011       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21012         ;
21013       else
21014         if (unformat
21015             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21016         ;
21017       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21018         ;
21019       else if (unformat (i, "disable"))
21020         state = 0;
21021       else if (unformat (i, "rx"))
21022         state = 1;
21023       else if (unformat (i, "tx"))
21024         state = 2;
21025       else if (unformat (i, "both"))
21026         state = 3;
21027       else if (unformat (i, "l2"))
21028         is_l2 = 1;
21029       else
21030         break;
21031     }
21032
21033   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21034
21035   mp->sw_if_index_from = htonl (src_sw_if_index);
21036   mp->sw_if_index_to = htonl (dst_sw_if_index);
21037   mp->state = state;
21038   mp->is_l2 = is_l2;
21039
21040   S (mp);
21041   W (ret);
21042   return ret;
21043 }
21044
21045 static void
21046 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21047                                             * mp)
21048 {
21049   vat_main_t *vam = &vat_main;
21050   u8 *sw_if_from_name = 0;
21051   u8 *sw_if_to_name = 0;
21052   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21053   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21054   char *states[] = { "none", "rx", "tx", "both" };
21055   hash_pair_t *p;
21056
21057   /* *INDENT-OFF* */
21058   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21059   ({
21060     if ((u32) p->value[0] == sw_if_index_from)
21061       {
21062         sw_if_from_name = (u8 *)(p->key);
21063         if (sw_if_to_name)
21064           break;
21065       }
21066     if ((u32) p->value[0] == sw_if_index_to)
21067       {
21068         sw_if_to_name = (u8 *)(p->key);
21069         if (sw_if_from_name)
21070           break;
21071       }
21072   }));
21073   /* *INDENT-ON* */
21074   print (vam->ofp, "%20s => %20s (%s) %s",
21075          sw_if_from_name, sw_if_to_name, states[mp->state],
21076          mp->is_l2 ? "l2" : "device");
21077 }
21078
21079 static void
21080   vl_api_sw_interface_span_details_t_handler_json
21081   (vl_api_sw_interface_span_details_t * mp)
21082 {
21083   vat_main_t *vam = &vat_main;
21084   vat_json_node_t *node = NULL;
21085   u8 *sw_if_from_name = 0;
21086   u8 *sw_if_to_name = 0;
21087   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21088   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21089   hash_pair_t *p;
21090
21091   /* *INDENT-OFF* */
21092   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21093   ({
21094     if ((u32) p->value[0] == sw_if_index_from)
21095       {
21096         sw_if_from_name = (u8 *)(p->key);
21097         if (sw_if_to_name)
21098           break;
21099       }
21100     if ((u32) p->value[0] == sw_if_index_to)
21101       {
21102         sw_if_to_name = (u8 *)(p->key);
21103         if (sw_if_from_name)
21104           break;
21105       }
21106   }));
21107   /* *INDENT-ON* */
21108
21109   if (VAT_JSON_ARRAY != vam->json_tree.type)
21110     {
21111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21112       vat_json_init_array (&vam->json_tree);
21113     }
21114   node = vat_json_array_add (&vam->json_tree);
21115
21116   vat_json_init_object (node);
21117   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21118   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21119   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21120   if (0 != sw_if_to_name)
21121     {
21122       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21123     }
21124   vat_json_object_add_uint (node, "state", mp->state);
21125   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21126 }
21127
21128 static int
21129 api_sw_interface_span_dump (vat_main_t * vam)
21130 {
21131   unformat_input_t *input = vam->input;
21132   vl_api_sw_interface_span_dump_t *mp;
21133   vl_api_control_ping_t *mp_ping;
21134   u8 is_l2 = 0;
21135   int ret;
21136
21137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21138     {
21139       if (unformat (input, "l2"))
21140         is_l2 = 1;
21141       else
21142         break;
21143     }
21144
21145   M (SW_INTERFACE_SPAN_DUMP, mp);
21146   mp->is_l2 = is_l2;
21147   S (mp);
21148
21149   /* Use a control ping for synchronization */
21150   MPING (CONTROL_PING, mp_ping);
21151   S (mp_ping);
21152
21153   W (ret);
21154   return ret;
21155 }
21156
21157 int
21158 api_pg_create_interface (vat_main_t * vam)
21159 {
21160   unformat_input_t *input = vam->input;
21161   vl_api_pg_create_interface_t *mp;
21162
21163   u32 if_id = ~0;
21164   int ret;
21165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21166     {
21167       if (unformat (input, "if_id %d", &if_id))
21168         ;
21169       else
21170         break;
21171     }
21172   if (if_id == ~0)
21173     {
21174       errmsg ("missing pg interface index");
21175       return -99;
21176     }
21177
21178   /* Construct the API message */
21179   M (PG_CREATE_INTERFACE, mp);
21180   mp->context = 0;
21181   mp->interface_id = ntohl (if_id);
21182
21183   S (mp);
21184   W (ret);
21185   return ret;
21186 }
21187
21188 int
21189 api_pg_capture (vat_main_t * vam)
21190 {
21191   unformat_input_t *input = vam->input;
21192   vl_api_pg_capture_t *mp;
21193
21194   u32 if_id = ~0;
21195   u8 enable = 1;
21196   u32 count = 1;
21197   u8 pcap_file_set = 0;
21198   u8 *pcap_file = 0;
21199   int ret;
21200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21201     {
21202       if (unformat (input, "if_id %d", &if_id))
21203         ;
21204       else if (unformat (input, "pcap %s", &pcap_file))
21205         pcap_file_set = 1;
21206       else if (unformat (input, "count %d", &count))
21207         ;
21208       else if (unformat (input, "disable"))
21209         enable = 0;
21210       else
21211         break;
21212     }
21213   if (if_id == ~0)
21214     {
21215       errmsg ("missing pg interface index");
21216       return -99;
21217     }
21218   if (pcap_file_set > 0)
21219     {
21220       if (vec_len (pcap_file) > 255)
21221         {
21222           errmsg ("pcap file name is too long");
21223           return -99;
21224         }
21225     }
21226
21227   u32 name_len = vec_len (pcap_file);
21228   /* Construct the API message */
21229   M (PG_CAPTURE, mp);
21230   mp->context = 0;
21231   mp->interface_id = ntohl (if_id);
21232   mp->is_enabled = enable;
21233   mp->count = ntohl (count);
21234   mp->pcap_name_length = ntohl (name_len);
21235   if (pcap_file_set != 0)
21236     {
21237       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21238     }
21239   vec_free (pcap_file);
21240
21241   S (mp);
21242   W (ret);
21243   return ret;
21244 }
21245
21246 int
21247 api_pg_enable_disable (vat_main_t * vam)
21248 {
21249   unformat_input_t *input = vam->input;
21250   vl_api_pg_enable_disable_t *mp;
21251
21252   u8 enable = 1;
21253   u8 stream_name_set = 0;
21254   u8 *stream_name = 0;
21255   int ret;
21256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21257     {
21258       if (unformat (input, "stream %s", &stream_name))
21259         stream_name_set = 1;
21260       else if (unformat (input, "disable"))
21261         enable = 0;
21262       else
21263         break;
21264     }
21265
21266   if (stream_name_set > 0)
21267     {
21268       if (vec_len (stream_name) > 255)
21269         {
21270           errmsg ("stream name too long");
21271           return -99;
21272         }
21273     }
21274
21275   u32 name_len = vec_len (stream_name);
21276   /* Construct the API message */
21277   M (PG_ENABLE_DISABLE, mp);
21278   mp->context = 0;
21279   mp->is_enabled = enable;
21280   if (stream_name_set != 0)
21281     {
21282       mp->stream_name_length = ntohl (name_len);
21283       clib_memcpy (mp->stream_name, stream_name, name_len);
21284     }
21285   vec_free (stream_name);
21286
21287   S (mp);
21288   W (ret);
21289   return ret;
21290 }
21291
21292 int
21293 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21294 {
21295   unformat_input_t *input = vam->input;
21296   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21297
21298   u16 *low_ports = 0;
21299   u16 *high_ports = 0;
21300   u16 this_low;
21301   u16 this_hi;
21302   ip4_address_t ip4_addr;
21303   ip6_address_t ip6_addr;
21304   u32 length;
21305   u32 tmp, tmp2;
21306   u8 prefix_set = 0;
21307   u32 vrf_id = ~0;
21308   u8 is_add = 1;
21309   u8 is_ipv6 = 0;
21310   int ret;
21311
21312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21313     {
21314       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21315         {
21316           prefix_set = 1;
21317         }
21318       else
21319         if (unformat
21320             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21321         {
21322           prefix_set = 1;
21323           is_ipv6 = 1;
21324         }
21325       else if (unformat (input, "vrf %d", &vrf_id))
21326         ;
21327       else if (unformat (input, "del"))
21328         is_add = 0;
21329       else if (unformat (input, "port %d", &tmp))
21330         {
21331           if (tmp == 0 || tmp > 65535)
21332             {
21333               errmsg ("port %d out of range", tmp);
21334               return -99;
21335             }
21336           this_low = tmp;
21337           this_hi = this_low + 1;
21338           vec_add1 (low_ports, this_low);
21339           vec_add1 (high_ports, this_hi);
21340         }
21341       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21342         {
21343           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21344             {
21345               errmsg ("incorrect range parameters");
21346               return -99;
21347             }
21348           this_low = tmp;
21349           /* Note: in debug CLI +1 is added to high before
21350              passing to real fn that does "the work"
21351              (ip_source_and_port_range_check_add_del).
21352              This fn is a wrapper around the binary API fn a
21353              control plane will call, which expects this increment
21354              to have occurred. Hence letting the binary API control
21355              plane fn do the increment for consistency between VAT
21356              and other control planes.
21357            */
21358           this_hi = tmp2;
21359           vec_add1 (low_ports, this_low);
21360           vec_add1 (high_ports, this_hi);
21361         }
21362       else
21363         break;
21364     }
21365
21366   if (prefix_set == 0)
21367     {
21368       errmsg ("<address>/<mask> not specified");
21369       return -99;
21370     }
21371
21372   if (vrf_id == ~0)
21373     {
21374       errmsg ("VRF ID required, not specified");
21375       return -99;
21376     }
21377
21378   if (vrf_id == 0)
21379     {
21380       errmsg
21381         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21382       return -99;
21383     }
21384
21385   if (vec_len (low_ports) == 0)
21386     {
21387       errmsg ("At least one port or port range required");
21388       return -99;
21389     }
21390
21391   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21392
21393   mp->is_add = is_add;
21394
21395   if (is_ipv6)
21396     {
21397       mp->is_ipv6 = 1;
21398       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21399     }
21400   else
21401     {
21402       mp->is_ipv6 = 0;
21403       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21404     }
21405
21406   mp->mask_length = length;
21407   mp->number_of_ranges = vec_len (low_ports);
21408
21409   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21410   vec_free (low_ports);
21411
21412   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21413   vec_free (high_ports);
21414
21415   mp->vrf_id = ntohl (vrf_id);
21416
21417   S (mp);
21418   W (ret);
21419   return ret;
21420 }
21421
21422 int
21423 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21424 {
21425   unformat_input_t *input = vam->input;
21426   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21427   u32 sw_if_index = ~0;
21428   int vrf_set = 0;
21429   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21430   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21431   u8 is_add = 1;
21432   int ret;
21433
21434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21435     {
21436       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21437         ;
21438       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21439         ;
21440       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21441         vrf_set = 1;
21442       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21443         vrf_set = 1;
21444       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21445         vrf_set = 1;
21446       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21447         vrf_set = 1;
21448       else if (unformat (input, "del"))
21449         is_add = 0;
21450       else
21451         break;
21452     }
21453
21454   if (sw_if_index == ~0)
21455     {
21456       errmsg ("Interface required but not specified");
21457       return -99;
21458     }
21459
21460   if (vrf_set == 0)
21461     {
21462       errmsg ("VRF ID required but not specified");
21463       return -99;
21464     }
21465
21466   if (tcp_out_vrf_id == 0
21467       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21468     {
21469       errmsg
21470         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21471       return -99;
21472     }
21473
21474   /* Construct the API message */
21475   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21476
21477   mp->sw_if_index = ntohl (sw_if_index);
21478   mp->is_add = is_add;
21479   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21480   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21481   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21482   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21483
21484   /* send it... */
21485   S (mp);
21486
21487   /* Wait for a reply... */
21488   W (ret);
21489   return ret;
21490 }
21491
21492 static int
21493 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21494 {
21495   unformat_input_t *i = vam->input;
21496   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21497   u32 local_sa_id = 0;
21498   u32 remote_sa_id = 0;
21499   ip4_address_t src_address;
21500   ip4_address_t dst_address;
21501   u8 is_add = 1;
21502   int ret;
21503
21504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21505     {
21506       if (unformat (i, "local_sa %d", &local_sa_id))
21507         ;
21508       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21509         ;
21510       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21511         ;
21512       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21513         ;
21514       else if (unformat (i, "del"))
21515         is_add = 0;
21516       else
21517         {
21518           clib_warning ("parse error '%U'", format_unformat_error, i);
21519           return -99;
21520         }
21521     }
21522
21523   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21524
21525   mp->local_sa_id = ntohl (local_sa_id);
21526   mp->remote_sa_id = ntohl (remote_sa_id);
21527   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21528   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21529   mp->is_add = is_add;
21530
21531   S (mp);
21532   W (ret);
21533   return ret;
21534 }
21535
21536 static int
21537 api_punt (vat_main_t * vam)
21538 {
21539   unformat_input_t *i = vam->input;
21540   vl_api_punt_t *mp;
21541   u32 ipv = ~0;
21542   u32 protocol = ~0;
21543   u32 port = ~0;
21544   int is_add = 1;
21545   int ret;
21546
21547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21548     {
21549       if (unformat (i, "ip %d", &ipv))
21550         ;
21551       else if (unformat (i, "protocol %d", &protocol))
21552         ;
21553       else if (unformat (i, "port %d", &port))
21554         ;
21555       else if (unformat (i, "del"))
21556         is_add = 0;
21557       else
21558         {
21559           clib_warning ("parse error '%U'", format_unformat_error, i);
21560           return -99;
21561         }
21562     }
21563
21564   M (PUNT, mp);
21565
21566   mp->is_add = (u8) is_add;
21567   mp->ipv = (u8) ipv;
21568   mp->l4_protocol = (u8) protocol;
21569   mp->l4_port = htons ((u16) port);
21570
21571   S (mp);
21572   W (ret);
21573   return ret;
21574 }
21575
21576 static void vl_api_ipsec_gre_tunnel_details_t_handler
21577   (vl_api_ipsec_gre_tunnel_details_t * mp)
21578 {
21579   vat_main_t *vam = &vat_main;
21580
21581   print (vam->ofp, "%11d%15U%15U%14d%14d",
21582          ntohl (mp->sw_if_index),
21583          format_ip4_address, &mp->src_address,
21584          format_ip4_address, &mp->dst_address,
21585          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21586 }
21587
21588 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21589   (vl_api_ipsec_gre_tunnel_details_t * mp)
21590 {
21591   vat_main_t *vam = &vat_main;
21592   vat_json_node_t *node = NULL;
21593   struct in_addr ip4;
21594
21595   if (VAT_JSON_ARRAY != vam->json_tree.type)
21596     {
21597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21598       vat_json_init_array (&vam->json_tree);
21599     }
21600   node = vat_json_array_add (&vam->json_tree);
21601
21602   vat_json_init_object (node);
21603   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21604   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21605   vat_json_object_add_ip4 (node, "src_address", ip4);
21606   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21607   vat_json_object_add_ip4 (node, "dst_address", ip4);
21608   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21609   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21610 }
21611
21612 static int
21613 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21614 {
21615   unformat_input_t *i = vam->input;
21616   vl_api_ipsec_gre_tunnel_dump_t *mp;
21617   vl_api_control_ping_t *mp_ping;
21618   u32 sw_if_index;
21619   u8 sw_if_index_set = 0;
21620   int ret;
21621
21622   /* Parse args required to build the message */
21623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21624     {
21625       if (unformat (i, "sw_if_index %d", &sw_if_index))
21626         sw_if_index_set = 1;
21627       else
21628         break;
21629     }
21630
21631   if (sw_if_index_set == 0)
21632     {
21633       sw_if_index = ~0;
21634     }
21635
21636   if (!vam->json_output)
21637     {
21638       print (vam->ofp, "%11s%15s%15s%14s%14s",
21639              "sw_if_index", "src_address", "dst_address",
21640              "local_sa_id", "remote_sa_id");
21641     }
21642
21643   /* Get list of gre-tunnel interfaces */
21644   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21645
21646   mp->sw_if_index = htonl (sw_if_index);
21647
21648   S (mp);
21649
21650   /* Use a control ping for synchronization */
21651   MPING (CONTROL_PING, mp_ping);
21652   S (mp_ping);
21653
21654   W (ret);
21655   return ret;
21656 }
21657
21658 static int
21659 api_delete_subif (vat_main_t * vam)
21660 {
21661   unformat_input_t *i = vam->input;
21662   vl_api_delete_subif_t *mp;
21663   u32 sw_if_index = ~0;
21664   int ret;
21665
21666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21667     {
21668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21669         ;
21670       if (unformat (i, "sw_if_index %d", &sw_if_index))
21671         ;
21672       else
21673         break;
21674     }
21675
21676   if (sw_if_index == ~0)
21677     {
21678       errmsg ("missing sw_if_index");
21679       return -99;
21680     }
21681
21682   /* Construct the API message */
21683   M (DELETE_SUBIF, mp);
21684   mp->sw_if_index = ntohl (sw_if_index);
21685
21686   S (mp);
21687   W (ret);
21688   return ret;
21689 }
21690
21691 #define foreach_pbb_vtr_op      \
21692 _("disable",  L2_VTR_DISABLED)  \
21693 _("pop",  L2_VTR_POP_2)         \
21694 _("push",  L2_VTR_PUSH_2)
21695
21696 static int
21697 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21698 {
21699   unformat_input_t *i = vam->input;
21700   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21701   u32 sw_if_index = ~0, vtr_op = ~0;
21702   u16 outer_tag = ~0;
21703   u8 dmac[6], smac[6];
21704   u8 dmac_set = 0, smac_set = 0;
21705   u16 vlanid = 0;
21706   u32 sid = ~0;
21707   u32 tmp;
21708   int ret;
21709
21710   /* Shut up coverity */
21711   memset (dmac, 0, sizeof (dmac));
21712   memset (smac, 0, sizeof (smac));
21713
21714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21715     {
21716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21717         ;
21718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21719         ;
21720       else if (unformat (i, "vtr_op %d", &vtr_op))
21721         ;
21722 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21723       foreach_pbb_vtr_op
21724 #undef _
21725         else if (unformat (i, "translate_pbb_stag"))
21726         {
21727           if (unformat (i, "%d", &tmp))
21728             {
21729               vtr_op = L2_VTR_TRANSLATE_2_1;
21730               outer_tag = tmp;
21731             }
21732           else
21733             {
21734               errmsg
21735                 ("translate_pbb_stag operation requires outer tag definition");
21736               return -99;
21737             }
21738         }
21739       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21740         dmac_set++;
21741       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21742         smac_set++;
21743       else if (unformat (i, "sid %d", &sid))
21744         ;
21745       else if (unformat (i, "vlanid %d", &tmp))
21746         vlanid = tmp;
21747       else
21748         {
21749           clib_warning ("parse error '%U'", format_unformat_error, i);
21750           return -99;
21751         }
21752     }
21753
21754   if ((sw_if_index == ~0) || (vtr_op == ~0))
21755     {
21756       errmsg ("missing sw_if_index or vtr operation");
21757       return -99;
21758     }
21759   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21760       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21761     {
21762       errmsg
21763         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21764       return -99;
21765     }
21766
21767   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21768   mp->sw_if_index = ntohl (sw_if_index);
21769   mp->vtr_op = ntohl (vtr_op);
21770   mp->outer_tag = ntohs (outer_tag);
21771   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21772   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21773   mp->b_vlanid = ntohs (vlanid);
21774   mp->i_sid = ntohl (sid);
21775
21776   S (mp);
21777   W (ret);
21778   return ret;
21779 }
21780
21781 static int
21782 api_flow_classify_set_interface (vat_main_t * vam)
21783 {
21784   unformat_input_t *i = vam->input;
21785   vl_api_flow_classify_set_interface_t *mp;
21786   u32 sw_if_index;
21787   int sw_if_index_set;
21788   u32 ip4_table_index = ~0;
21789   u32 ip6_table_index = ~0;
21790   u8 is_add = 1;
21791   int ret;
21792
21793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21794     {
21795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21796         sw_if_index_set = 1;
21797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21798         sw_if_index_set = 1;
21799       else if (unformat (i, "del"))
21800         is_add = 0;
21801       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21802         ;
21803       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21804         ;
21805       else
21806         {
21807           clib_warning ("parse error '%U'", format_unformat_error, i);
21808           return -99;
21809         }
21810     }
21811
21812   if (sw_if_index_set == 0)
21813     {
21814       errmsg ("missing interface name or sw_if_index");
21815       return -99;
21816     }
21817
21818   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21819
21820   mp->sw_if_index = ntohl (sw_if_index);
21821   mp->ip4_table_index = ntohl (ip4_table_index);
21822   mp->ip6_table_index = ntohl (ip6_table_index);
21823   mp->is_add = is_add;
21824
21825   S (mp);
21826   W (ret);
21827   return ret;
21828 }
21829
21830 static int
21831 api_flow_classify_dump (vat_main_t * vam)
21832 {
21833   unformat_input_t *i = vam->input;
21834   vl_api_flow_classify_dump_t *mp;
21835   vl_api_control_ping_t *mp_ping;
21836   u8 type = FLOW_CLASSIFY_N_TABLES;
21837   int ret;
21838
21839   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21840     ;
21841   else
21842     {
21843       errmsg ("classify table type must be specified");
21844       return -99;
21845     }
21846
21847   if (!vam->json_output)
21848     {
21849       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21850     }
21851
21852   M (FLOW_CLASSIFY_DUMP, mp);
21853   mp->type = type;
21854   /* send it... */
21855   S (mp);
21856
21857   /* Use a control ping for synchronization */
21858   MPING (CONTROL_PING, mp_ping);
21859   S (mp_ping);
21860
21861   /* Wait for a reply... */
21862   W (ret);
21863   return ret;
21864 }
21865
21866 static int
21867 api_feature_enable_disable (vat_main_t * vam)
21868 {
21869   unformat_input_t *i = vam->input;
21870   vl_api_feature_enable_disable_t *mp;
21871   u8 *arc_name = 0;
21872   u8 *feature_name = 0;
21873   u32 sw_if_index = ~0;
21874   u8 enable = 1;
21875   int ret;
21876
21877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21878     {
21879       if (unformat (i, "arc_name %s", &arc_name))
21880         ;
21881       else if (unformat (i, "feature_name %s", &feature_name))
21882         ;
21883       else
21884         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21885         ;
21886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21887         ;
21888       else if (unformat (i, "disable"))
21889         enable = 0;
21890       else
21891         break;
21892     }
21893
21894   if (arc_name == 0)
21895     {
21896       errmsg ("missing arc name");
21897       return -99;
21898     }
21899   if (vec_len (arc_name) > 63)
21900     {
21901       errmsg ("arc name too long");
21902     }
21903
21904   if (feature_name == 0)
21905     {
21906       errmsg ("missing feature name");
21907       return -99;
21908     }
21909   if (vec_len (feature_name) > 63)
21910     {
21911       errmsg ("feature name too long");
21912     }
21913
21914   if (sw_if_index == ~0)
21915     {
21916       errmsg ("missing interface name or sw_if_index");
21917       return -99;
21918     }
21919
21920   /* Construct the API message */
21921   M (FEATURE_ENABLE_DISABLE, mp);
21922   mp->sw_if_index = ntohl (sw_if_index);
21923   mp->enable = enable;
21924   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21925   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21926   vec_free (arc_name);
21927   vec_free (feature_name);
21928
21929   S (mp);
21930   W (ret);
21931   return ret;
21932 }
21933
21934 static int
21935 api_sw_interface_tag_add_del (vat_main_t * vam)
21936 {
21937   unformat_input_t *i = vam->input;
21938   vl_api_sw_interface_tag_add_del_t *mp;
21939   u32 sw_if_index = ~0;
21940   u8 *tag = 0;
21941   u8 enable = 1;
21942   int ret;
21943
21944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21945     {
21946       if (unformat (i, "tag %s", &tag))
21947         ;
21948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21949         ;
21950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21951         ;
21952       else if (unformat (i, "del"))
21953         enable = 0;
21954       else
21955         break;
21956     }
21957
21958   if (sw_if_index == ~0)
21959     {
21960       errmsg ("missing interface name or sw_if_index");
21961       return -99;
21962     }
21963
21964   if (enable && (tag == 0))
21965     {
21966       errmsg ("no tag specified");
21967       return -99;
21968     }
21969
21970   /* Construct the API message */
21971   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21972   mp->sw_if_index = ntohl (sw_if_index);
21973   mp->is_add = enable;
21974   if (enable)
21975     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21976   vec_free (tag);
21977
21978   S (mp);
21979   W (ret);
21980   return ret;
21981 }
21982
21983 static void vl_api_l2_xconnect_details_t_handler
21984   (vl_api_l2_xconnect_details_t * mp)
21985 {
21986   vat_main_t *vam = &vat_main;
21987
21988   print (vam->ofp, "%15d%15d",
21989          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21990 }
21991
21992 static void vl_api_l2_xconnect_details_t_handler_json
21993   (vl_api_l2_xconnect_details_t * mp)
21994 {
21995   vat_main_t *vam = &vat_main;
21996   vat_json_node_t *node = NULL;
21997
21998   if (VAT_JSON_ARRAY != vam->json_tree.type)
21999     {
22000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22001       vat_json_init_array (&vam->json_tree);
22002     }
22003   node = vat_json_array_add (&vam->json_tree);
22004
22005   vat_json_init_object (node);
22006   vat_json_object_add_uint (node, "rx_sw_if_index",
22007                             ntohl (mp->rx_sw_if_index));
22008   vat_json_object_add_uint (node, "tx_sw_if_index",
22009                             ntohl (mp->tx_sw_if_index));
22010 }
22011
22012 static int
22013 api_l2_xconnect_dump (vat_main_t * vam)
22014 {
22015   vl_api_l2_xconnect_dump_t *mp;
22016   vl_api_control_ping_t *mp_ping;
22017   int ret;
22018
22019   if (!vam->json_output)
22020     {
22021       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22022     }
22023
22024   M (L2_XCONNECT_DUMP, mp);
22025
22026   S (mp);
22027
22028   /* Use a control ping for synchronization */
22029   MPING (CONTROL_PING, mp_ping);
22030   S (mp_ping);
22031
22032   W (ret);
22033   return ret;
22034 }
22035
22036 static int
22037 api_sw_interface_set_mtu (vat_main_t * vam)
22038 {
22039   unformat_input_t *i = vam->input;
22040   vl_api_sw_interface_set_mtu_t *mp;
22041   u32 sw_if_index = ~0;
22042   u32 mtu = 0;
22043   int ret;
22044
22045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22046     {
22047       if (unformat (i, "mtu %d", &mtu))
22048         ;
22049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22050         ;
22051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22052         ;
22053       else
22054         break;
22055     }
22056
22057   if (sw_if_index == ~0)
22058     {
22059       errmsg ("missing interface name or sw_if_index");
22060       return -99;
22061     }
22062
22063   if (mtu == 0)
22064     {
22065       errmsg ("no mtu specified");
22066       return -99;
22067     }
22068
22069   /* Construct the API message */
22070   M (SW_INTERFACE_SET_MTU, mp);
22071   mp->sw_if_index = ntohl (sw_if_index);
22072   mp->mtu = ntohs ((u16) mtu);
22073
22074   S (mp);
22075   W (ret);
22076   return ret;
22077 }
22078
22079 static int
22080 api_p2p_ethernet_add (vat_main_t * vam)
22081 {
22082   unformat_input_t *i = vam->input;
22083   vl_api_p2p_ethernet_add_t *mp;
22084   u32 parent_if_index = ~0;
22085   u32 sub_id = ~0;
22086   u8 remote_mac[6];
22087   u8 mac_set = 0;
22088   int ret;
22089
22090   memset (remote_mac, 0, sizeof (remote_mac));
22091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22092     {
22093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22094         ;
22095       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22096         ;
22097       else
22098         if (unformat
22099             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22100         mac_set++;
22101       else if (unformat (i, "sub_id %d", &sub_id))
22102         ;
22103       else
22104         {
22105           clib_warning ("parse error '%U'", format_unformat_error, i);
22106           return -99;
22107         }
22108     }
22109
22110   if (parent_if_index == ~0)
22111     {
22112       errmsg ("missing interface name or sw_if_index");
22113       return -99;
22114     }
22115   if (mac_set == 0)
22116     {
22117       errmsg ("missing remote mac address");
22118       return -99;
22119     }
22120   if (sub_id == ~0)
22121     {
22122       errmsg ("missing sub-interface id");
22123       return -99;
22124     }
22125
22126   M (P2P_ETHERNET_ADD, mp);
22127   mp->parent_if_index = ntohl (parent_if_index);
22128   mp->subif_id = ntohl (sub_id);
22129   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22130
22131   S (mp);
22132   W (ret);
22133   return ret;
22134 }
22135
22136 static int
22137 api_p2p_ethernet_del (vat_main_t * vam)
22138 {
22139   unformat_input_t *i = vam->input;
22140   vl_api_p2p_ethernet_del_t *mp;
22141   u32 parent_if_index = ~0;
22142   u8 remote_mac[6];
22143   u8 mac_set = 0;
22144   int ret;
22145
22146   memset (remote_mac, 0, sizeof (remote_mac));
22147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22148     {
22149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22150         ;
22151       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22152         ;
22153       else
22154         if (unformat
22155             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22156         mac_set++;
22157       else
22158         {
22159           clib_warning ("parse error '%U'", format_unformat_error, i);
22160           return -99;
22161         }
22162     }
22163
22164   if (parent_if_index == ~0)
22165     {
22166       errmsg ("missing interface name or sw_if_index");
22167       return -99;
22168     }
22169   if (mac_set == 0)
22170     {
22171       errmsg ("missing remote mac address");
22172       return -99;
22173     }
22174
22175   M (P2P_ETHERNET_DEL, mp);
22176   mp->parent_if_index = ntohl (parent_if_index);
22177   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22178
22179   S (mp);
22180   W (ret);
22181   return ret;
22182 }
22183
22184 static int
22185 api_lldp_config (vat_main_t * vam)
22186 {
22187   unformat_input_t *i = vam->input;
22188   vl_api_lldp_config_t *mp;
22189   int tx_hold = 0;
22190   int tx_interval = 0;
22191   u8 *sys_name = NULL;
22192   int ret;
22193
22194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22195     {
22196       if (unformat (i, "system-name %s", &sys_name))
22197         ;
22198       else if (unformat (i, "tx-hold %d", &tx_hold))
22199         ;
22200       else if (unformat (i, "tx-interval %d", &tx_interval))
22201         ;
22202       else
22203         {
22204           clib_warning ("parse error '%U'", format_unformat_error, i);
22205           return -99;
22206         }
22207     }
22208
22209   vec_add1 (sys_name, 0);
22210
22211   M (LLDP_CONFIG, mp);
22212   mp->tx_hold = htonl (tx_hold);
22213   mp->tx_interval = htonl (tx_interval);
22214   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22215   vec_free (sys_name);
22216
22217   S (mp);
22218   W (ret);
22219   return ret;
22220 }
22221
22222 static int
22223 api_sw_interface_set_lldp (vat_main_t * vam)
22224 {
22225   unformat_input_t *i = vam->input;
22226   vl_api_sw_interface_set_lldp_t *mp;
22227   u32 sw_if_index = ~0;
22228   u32 enable = 1;
22229   u8 *port_desc = NULL, *mgmt_oid = NULL;
22230   ip4_address_t ip4_addr;
22231   ip6_address_t ip6_addr;
22232   int ret;
22233
22234   memset (&ip4_addr, 0, sizeof (ip4_addr));
22235   memset (&ip6_addr, 0, sizeof (ip6_addr));
22236
22237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22238     {
22239       if (unformat (i, "disable"))
22240         enable = 0;
22241       else
22242         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22243         ;
22244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22245         ;
22246       else if (unformat (i, "port-desc %s", &port_desc))
22247         ;
22248       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22249         ;
22250       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22251         ;
22252       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22253         ;
22254       else
22255         break;
22256     }
22257
22258   if (sw_if_index == ~0)
22259     {
22260       errmsg ("missing interface name or sw_if_index");
22261       return -99;
22262     }
22263
22264   /* Construct the API message */
22265   vec_add1 (port_desc, 0);
22266   vec_add1 (mgmt_oid, 0);
22267   M (SW_INTERFACE_SET_LLDP, mp);
22268   mp->sw_if_index = ntohl (sw_if_index);
22269   mp->enable = enable;
22270   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22271   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22272   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22273   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22274   vec_free (port_desc);
22275   vec_free (mgmt_oid);
22276
22277   S (mp);
22278   W (ret);
22279   return ret;
22280 }
22281
22282 static int
22283 api_tcp_configure_src_addresses (vat_main_t * vam)
22284 {
22285   vl_api_tcp_configure_src_addresses_t *mp;
22286   unformat_input_t *i = vam->input;
22287   ip4_address_t v4first, v4last;
22288   ip6_address_t v6first, v6last;
22289   u8 range_set = 0;
22290   u32 vrf_id = 0;
22291   int ret;
22292
22293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22294     {
22295       if (unformat (i, "%U - %U",
22296                     unformat_ip4_address, &v4first,
22297                     unformat_ip4_address, &v4last))
22298         {
22299           if (range_set)
22300             {
22301               errmsg ("one range per message (range already set)");
22302               return -99;
22303             }
22304           range_set = 1;
22305         }
22306       else if (unformat (i, "%U - %U",
22307                          unformat_ip6_address, &v6first,
22308                          unformat_ip6_address, &v6last))
22309         {
22310           if (range_set)
22311             {
22312               errmsg ("one range per message (range already set)");
22313               return -99;
22314             }
22315           range_set = 2;
22316         }
22317       else if (unformat (i, "vrf %d", &vrf_id))
22318         ;
22319       else
22320         break;
22321     }
22322
22323   if (range_set == 0)
22324     {
22325       errmsg ("address range not set");
22326       return -99;
22327     }
22328
22329   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22330   mp->vrf_id = ntohl (vrf_id);
22331   /* ipv6? */
22332   if (range_set == 2)
22333     {
22334       mp->is_ipv6 = 1;
22335       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22336       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22337     }
22338   else
22339     {
22340       mp->is_ipv6 = 0;
22341       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22342       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22343     }
22344   S (mp);
22345   W (ret);
22346   return ret;
22347 }
22348
22349 static void vl_api_app_namespace_add_del_reply_t_handler
22350   (vl_api_app_namespace_add_del_reply_t * mp)
22351 {
22352   vat_main_t *vam = &vat_main;
22353   i32 retval = ntohl (mp->retval);
22354   if (vam->async_mode)
22355     {
22356       vam->async_errors += (retval < 0);
22357     }
22358   else
22359     {
22360       vam->retval = retval;
22361       if (retval == 0)
22362         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22363       vam->result_ready = 1;
22364     }
22365 }
22366
22367 static void vl_api_app_namespace_add_del_reply_t_handler_json
22368   (vl_api_app_namespace_add_del_reply_t * mp)
22369 {
22370   vat_main_t *vam = &vat_main;
22371   vat_json_node_t node;
22372
22373   vat_json_init_object (&node);
22374   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22375   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22376
22377   vat_json_print (vam->ofp, &node);
22378   vat_json_free (&node);
22379
22380   vam->retval = ntohl (mp->retval);
22381   vam->result_ready = 1;
22382 }
22383
22384 static int
22385 api_app_namespace_add_del (vat_main_t * vam)
22386 {
22387   vl_api_app_namespace_add_del_t *mp;
22388   unformat_input_t *i = vam->input;
22389   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22390   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22391   u64 secret;
22392   int ret;
22393
22394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22395     {
22396       if (unformat (i, "id %_%v%_", &ns_id))
22397         ;
22398       else if (unformat (i, "secret %lu", &secret))
22399         secret_set = 1;
22400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22401         sw_if_index_set = 1;
22402       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22403         ;
22404       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22405         ;
22406       else
22407         break;
22408     }
22409   if (!ns_id || !secret_set || !sw_if_index_set)
22410     {
22411       errmsg ("namespace id, secret and sw_if_index must be set");
22412       return -99;
22413     }
22414   if (vec_len (ns_id) > 64)
22415     {
22416       errmsg ("namespace id too long");
22417       return -99;
22418     }
22419   M (APP_NAMESPACE_ADD_DEL, mp);
22420
22421   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22422   mp->namespace_id_len = vec_len (ns_id);
22423   mp->secret = clib_host_to_net_u64 (secret);
22424   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22425   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22426   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22427   vec_free (ns_id);
22428   S (mp);
22429   W (ret);
22430   return ret;
22431 }
22432
22433 static int
22434 api_memfd_segment_create (vat_main_t * vam)
22435 {
22436 #if VPP_API_TEST_BUILTIN == 0
22437   unformat_input_t *i = vam->input;
22438   vl_api_memfd_segment_create_t *mp;
22439   u64 size = 64 << 20;
22440   int ret;
22441
22442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22443     {
22444       if (unformat (i, "size %U", unformat_memory_size, &size))
22445         ;
22446       else
22447         break;
22448     }
22449
22450   M (MEMFD_SEGMENT_CREATE, mp);
22451   mp->requested_size = size;
22452   S (mp);
22453   W (ret);
22454   return ret;
22455
22456 #else
22457   errmsg ("memfd_segment_create (builtin) not supported");
22458   return -99;
22459 #endif
22460 }
22461
22462 static int
22463 api_sock_init_shm (vat_main_t * vam)
22464 {
22465 #if VPP_API_TEST_BUILTIN == 0
22466   unformat_input_t *i = vam->input;
22467   vl_api_shm_elem_config_t *config = 0;
22468   u64 size = 64 << 20;
22469   int rv;
22470
22471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22472     {
22473       if (unformat (i, "size %U", unformat_memory_size, &size))
22474         ;
22475       else
22476         break;
22477     }
22478
22479   /* Try customized config to see if it works */
22480   vec_validate (config, 3);
22481   config[0].type = VL_API_VLIB_RING;
22482   config[0].count = 256;
22483   config[0].size = 256;
22484   config[1].type = VL_API_CLIENT_RING;
22485   config[1].count = 256;
22486   config[1].size = 1024;
22487   config[2].type = VL_API_CLIENT_RING;
22488   config[2].count = 8;
22489   config[2].size = 4096;
22490   config[3].type = VL_API_QUEUE;
22491   config[3].count = 256;
22492   config[3].size = sizeof (uword);
22493   rv = vl_socket_client_init_shm (config);
22494   if (!rv)
22495     vam->client_index_invalid = 1;
22496   return rv;
22497 #else
22498   return -99;
22499 #endif
22500 }
22501
22502 static int
22503 api_dns_enable_disable (vat_main_t * vam)
22504 {
22505   unformat_input_t *line_input = vam->input;
22506   vl_api_dns_enable_disable_t *mp;
22507   u8 enable_disable = 1;
22508   int ret;
22509
22510   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22511     {
22512       if (unformat (line_input, "disable"))
22513         enable_disable = 0;
22514       if (unformat (line_input, "enable"))
22515         enable_disable = 1;
22516       else
22517         break;
22518     }
22519
22520   /* Construct the API message */
22521   M (DNS_ENABLE_DISABLE, mp);
22522   mp->enable = enable_disable;
22523
22524   /* send it... */
22525   S (mp);
22526   /* Wait for the reply */
22527   W (ret);
22528   return ret;
22529 }
22530
22531 static int
22532 api_dns_resolve_name (vat_main_t * vam)
22533 {
22534   unformat_input_t *line_input = vam->input;
22535   vl_api_dns_resolve_name_t *mp;
22536   u8 *name = 0;
22537   int ret;
22538
22539   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22540     {
22541       if (unformat (line_input, "%s", &name))
22542         ;
22543       else
22544         break;
22545     }
22546
22547   if (vec_len (name) > 127)
22548     {
22549       errmsg ("name too long");
22550       return -99;
22551     }
22552
22553   /* Construct the API message */
22554   M (DNS_RESOLVE_NAME, mp);
22555   memcpy (mp->name, name, vec_len (name));
22556   vec_free (name);
22557
22558   /* send it... */
22559   S (mp);
22560   /* Wait for the reply */
22561   W (ret);
22562   return ret;
22563 }
22564
22565 static int
22566 api_dns_resolve_ip (vat_main_t * vam)
22567 {
22568   unformat_input_t *line_input = vam->input;
22569   vl_api_dns_resolve_ip_t *mp;
22570   int is_ip6 = -1;
22571   ip4_address_t addr4;
22572   ip6_address_t addr6;
22573   int ret;
22574
22575   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22576     {
22577       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22578         is_ip6 = 1;
22579       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22580         is_ip6 = 0;
22581       else
22582         break;
22583     }
22584
22585   if (is_ip6 == -1)
22586     {
22587       errmsg ("missing address");
22588       return -99;
22589     }
22590
22591   /* Construct the API message */
22592   M (DNS_RESOLVE_IP, mp);
22593   mp->is_ip6 = is_ip6;
22594   if (is_ip6)
22595     memcpy (mp->address, &addr6, sizeof (addr6));
22596   else
22597     memcpy (mp->address, &addr4, sizeof (addr4));
22598
22599   /* send it... */
22600   S (mp);
22601   /* Wait for the reply */
22602   W (ret);
22603   return ret;
22604 }
22605
22606 static int
22607 api_dns_name_server_add_del (vat_main_t * vam)
22608 {
22609   unformat_input_t *i = vam->input;
22610   vl_api_dns_name_server_add_del_t *mp;
22611   u8 is_add = 1;
22612   ip6_address_t ip6_server;
22613   ip4_address_t ip4_server;
22614   int ip6_set = 0;
22615   int ip4_set = 0;
22616   int ret = 0;
22617
22618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22619     {
22620       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22621         ip6_set = 1;
22622       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22623         ip4_set = 1;
22624       else if (unformat (i, "del"))
22625         is_add = 0;
22626       else
22627         {
22628           clib_warning ("parse error '%U'", format_unformat_error, i);
22629           return -99;
22630         }
22631     }
22632
22633   if (ip4_set && ip6_set)
22634     {
22635       errmsg ("Only one server address allowed per message");
22636       return -99;
22637     }
22638   if ((ip4_set + ip6_set) == 0)
22639     {
22640       errmsg ("Server address required");
22641       return -99;
22642     }
22643
22644   /* Construct the API message */
22645   M (DNS_NAME_SERVER_ADD_DEL, mp);
22646
22647   if (ip6_set)
22648     {
22649       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22650       mp->is_ip6 = 1;
22651     }
22652   else
22653     {
22654       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22655       mp->is_ip6 = 0;
22656     }
22657
22658   mp->is_add = is_add;
22659
22660   /* send it... */
22661   S (mp);
22662
22663   /* Wait for a reply, return good/bad news  */
22664   W (ret);
22665   return ret;
22666 }
22667
22668 static void
22669 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22670 {
22671   vat_main_t *vam = &vat_main;
22672
22673   if (mp->is_ip4)
22674     {
22675       print (vam->ofp,
22676              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22677              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22678              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22679              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22680              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22681              clib_net_to_host_u32 (mp->action_index), mp->tag);
22682     }
22683   else
22684     {
22685       print (vam->ofp,
22686              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22687              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22688              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22689              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22690              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22691              clib_net_to_host_u32 (mp->action_index), mp->tag);
22692     }
22693 }
22694
22695 static void
22696 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22697                                              mp)
22698 {
22699   vat_main_t *vam = &vat_main;
22700   vat_json_node_t *node = NULL;
22701   struct in6_addr ip6;
22702   struct in_addr ip4;
22703
22704   if (VAT_JSON_ARRAY != vam->json_tree.type)
22705     {
22706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22707       vat_json_init_array (&vam->json_tree);
22708     }
22709   node = vat_json_array_add (&vam->json_tree);
22710   vat_json_init_object (node);
22711
22712   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22713   vat_json_object_add_uint (node, "appns_index",
22714                             clib_net_to_host_u32 (mp->appns_index));
22715   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22716   vat_json_object_add_uint (node, "scope", mp->scope);
22717   vat_json_object_add_uint (node, "action_index",
22718                             clib_net_to_host_u32 (mp->action_index));
22719   vat_json_object_add_uint (node, "lcl_port",
22720                             clib_net_to_host_u16 (mp->lcl_port));
22721   vat_json_object_add_uint (node, "rmt_port",
22722                             clib_net_to_host_u16 (mp->rmt_port));
22723   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22724   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22725   vat_json_object_add_string_copy (node, "tag", mp->tag);
22726   if (mp->is_ip4)
22727     {
22728       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22729       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22730       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22731       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22732     }
22733   else
22734     {
22735       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22736       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22737       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22738       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22739     }
22740 }
22741
22742 static int
22743 api_session_rule_add_del (vat_main_t * vam)
22744 {
22745   vl_api_session_rule_add_del_t *mp;
22746   unformat_input_t *i = vam->input;
22747   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22748   u32 appns_index = 0, scope = 0;
22749   ip4_address_t lcl_ip4, rmt_ip4;
22750   ip6_address_t lcl_ip6, rmt_ip6;
22751   u8 is_ip4 = 1, conn_set = 0;
22752   u8 is_add = 1, *tag = 0;
22753   int ret;
22754
22755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22756     {
22757       if (unformat (i, "del"))
22758         is_add = 0;
22759       else if (unformat (i, "add"))
22760         ;
22761       else if (unformat (i, "proto tcp"))
22762         proto = 0;
22763       else if (unformat (i, "proto udp"))
22764         proto = 1;
22765       else if (unformat (i, "appns %d", &appns_index))
22766         ;
22767       else if (unformat (i, "scope %d", &scope))
22768         ;
22769       else if (unformat (i, "tag %_%v%_", &tag))
22770         ;
22771       else
22772         if (unformat
22773             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22774              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22775              &rmt_port))
22776         {
22777           is_ip4 = 1;
22778           conn_set = 1;
22779         }
22780       else
22781         if (unformat
22782             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22783              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22784              &rmt_port))
22785         {
22786           is_ip4 = 0;
22787           conn_set = 1;
22788         }
22789       else if (unformat (i, "action %d", &action))
22790         ;
22791       else
22792         break;
22793     }
22794   if (proto == ~0 || !conn_set || action == ~0)
22795     {
22796       errmsg ("transport proto, connection and action must be set");
22797       return -99;
22798     }
22799
22800   if (scope > 3)
22801     {
22802       errmsg ("scope should be 0-3");
22803       return -99;
22804     }
22805
22806   M (SESSION_RULE_ADD_DEL, mp);
22807
22808   mp->is_ip4 = is_ip4;
22809   mp->transport_proto = proto;
22810   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22811   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22812   mp->lcl_plen = lcl_plen;
22813   mp->rmt_plen = rmt_plen;
22814   mp->action_index = clib_host_to_net_u32 (action);
22815   mp->appns_index = clib_host_to_net_u32 (appns_index);
22816   mp->scope = scope;
22817   mp->is_add = is_add;
22818   if (is_ip4)
22819     {
22820       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22821       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22822     }
22823   else
22824     {
22825       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22826       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22827     }
22828   if (tag)
22829     {
22830       clib_memcpy (mp->tag, tag, vec_len (tag));
22831       vec_free (tag);
22832     }
22833
22834   S (mp);
22835   W (ret);
22836   return ret;
22837 }
22838
22839 static int
22840 api_session_rules_dump (vat_main_t * vam)
22841 {
22842   vl_api_session_rules_dump_t *mp;
22843   vl_api_control_ping_t *mp_ping;
22844   int ret;
22845
22846   if (!vam->json_output)
22847     {
22848       print (vam->ofp, "%=20s", "Session Rules");
22849     }
22850
22851   M (SESSION_RULES_DUMP, mp);
22852   /* send it... */
22853   S (mp);
22854
22855   /* Use a control ping for synchronization */
22856   MPING (CONTROL_PING, mp_ping);
22857   S (mp_ping);
22858
22859   /* Wait for a reply... */
22860   W (ret);
22861   return ret;
22862 }
22863
22864 static int
22865 api_ip_container_proxy_add_del (vat_main_t * vam)
22866 {
22867   vl_api_ip_container_proxy_add_del_t *mp;
22868   unformat_input_t *i = vam->input;
22869   u32 plen = ~0, sw_if_index = ~0;
22870   ip4_address_t ip4;
22871   ip6_address_t ip6;
22872   u8 is_ip4 = 1;
22873   u8 is_add = 1;
22874   int ret;
22875
22876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22877     {
22878       if (unformat (i, "del"))
22879         is_add = 0;
22880       else if (unformat (i, "add"))
22881         ;
22882       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22883         {
22884           is_ip4 = 1;
22885           plen = 32;
22886         }
22887       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22888         {
22889           is_ip4 = 0;
22890           plen = 128;
22891         }
22892       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22893         ;
22894       else
22895         break;
22896     }
22897   if (sw_if_index == ~0 || plen == ~0)
22898     {
22899       errmsg ("address and sw_if_index must be set");
22900       return -99;
22901     }
22902
22903   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22904
22905   mp->is_ip4 = is_ip4;
22906   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22907   mp->plen = plen;
22908   mp->is_add = is_add;
22909   if (is_ip4)
22910     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22911   else
22912     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22913
22914   S (mp);
22915   W (ret);
22916   return ret;
22917 }
22918
22919 static int
22920 api_qos_record_enable_disable (vat_main_t * vam)
22921 {
22922   unformat_input_t *i = vam->input;
22923   vl_api_qos_record_enable_disable_t *mp;
22924   u32 sw_if_index, qs = 0xff;
22925   u8 sw_if_index_set = 0;
22926   u8 enable = 1;
22927   int ret;
22928
22929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22930     {
22931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22932         sw_if_index_set = 1;
22933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22934         sw_if_index_set = 1;
22935       else if (unformat (i, "%U", unformat_qos_source, &qs))
22936         ;
22937       else if (unformat (i, "disable"))
22938         enable = 0;
22939       else
22940         {
22941           clib_warning ("parse error '%U'", format_unformat_error, i);
22942           return -99;
22943         }
22944     }
22945
22946   if (sw_if_index_set == 0)
22947     {
22948       errmsg ("missing interface name or sw_if_index");
22949       return -99;
22950     }
22951   if (qs == 0xff)
22952     {
22953       errmsg ("input location must be specified");
22954       return -99;
22955     }
22956
22957   M (QOS_RECORD_ENABLE_DISABLE, mp);
22958
22959   mp->sw_if_index = ntohl (sw_if_index);
22960   mp->input_source = qs;
22961   mp->enable = enable;
22962
22963   S (mp);
22964   W (ret);
22965   return ret;
22966 }
22967
22968 static int
22969 q_or_quit (vat_main_t * vam)
22970 {
22971 #if VPP_API_TEST_BUILTIN == 0
22972   longjmp (vam->jump_buf, 1);
22973 #endif
22974   return 0;                     /* not so much */
22975 }
22976
22977 static int
22978 q (vat_main_t * vam)
22979 {
22980   return q_or_quit (vam);
22981 }
22982
22983 static int
22984 quit (vat_main_t * vam)
22985 {
22986   return q_or_quit (vam);
22987 }
22988
22989 static int
22990 comment (vat_main_t * vam)
22991 {
22992   return 0;
22993 }
22994
22995 static int
22996 cmd_cmp (void *a1, void *a2)
22997 {
22998   u8 **c1 = a1;
22999   u8 **c2 = a2;
23000
23001   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23002 }
23003
23004 static int
23005 help (vat_main_t * vam)
23006 {
23007   u8 **cmds = 0;
23008   u8 *name = 0;
23009   hash_pair_t *p;
23010   unformat_input_t *i = vam->input;
23011   int j;
23012
23013   if (unformat (i, "%s", &name))
23014     {
23015       uword *hs;
23016
23017       vec_add1 (name, 0);
23018
23019       hs = hash_get_mem (vam->help_by_name, name);
23020       if (hs)
23021         print (vam->ofp, "usage: %s %s", name, hs[0]);
23022       else
23023         print (vam->ofp, "No such msg / command '%s'", name);
23024       vec_free (name);
23025       return 0;
23026     }
23027
23028   print (vam->ofp, "Help is available for the following:");
23029
23030     /* *INDENT-OFF* */
23031     hash_foreach_pair (p, vam->function_by_name,
23032     ({
23033       vec_add1 (cmds, (u8 *)(p->key));
23034     }));
23035     /* *INDENT-ON* */
23036
23037   vec_sort_with_function (cmds, cmd_cmp);
23038
23039   for (j = 0; j < vec_len (cmds); j++)
23040     print (vam->ofp, "%s", cmds[j]);
23041
23042   vec_free (cmds);
23043   return 0;
23044 }
23045
23046 static int
23047 set (vat_main_t * vam)
23048 {
23049   u8 *name = 0, *value = 0;
23050   unformat_input_t *i = vam->input;
23051
23052   if (unformat (i, "%s", &name))
23053     {
23054       /* The input buffer is a vector, not a string. */
23055       value = vec_dup (i->buffer);
23056       vec_delete (value, i->index, 0);
23057       /* Almost certainly has a trailing newline */
23058       if (value[vec_len (value) - 1] == '\n')
23059         value[vec_len (value) - 1] = 0;
23060       /* Make sure it's a proper string, one way or the other */
23061       vec_add1 (value, 0);
23062       (void) clib_macro_set_value (&vam->macro_main,
23063                                    (char *) name, (char *) value);
23064     }
23065   else
23066     errmsg ("usage: set <name> <value>");
23067
23068   vec_free (name);
23069   vec_free (value);
23070   return 0;
23071 }
23072
23073 static int
23074 unset (vat_main_t * vam)
23075 {
23076   u8 *name = 0;
23077
23078   if (unformat (vam->input, "%s", &name))
23079     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23080       errmsg ("unset: %s wasn't set", name);
23081   vec_free (name);
23082   return 0;
23083 }
23084
23085 typedef struct
23086 {
23087   u8 *name;
23088   u8 *value;
23089 } macro_sort_t;
23090
23091
23092 static int
23093 macro_sort_cmp (void *a1, void *a2)
23094 {
23095   macro_sort_t *s1 = a1;
23096   macro_sort_t *s2 = a2;
23097
23098   return strcmp ((char *) (s1->name), (char *) (s2->name));
23099 }
23100
23101 static int
23102 dump_macro_table (vat_main_t * vam)
23103 {
23104   macro_sort_t *sort_me = 0, *sm;
23105   int i;
23106   hash_pair_t *p;
23107
23108     /* *INDENT-OFF* */
23109     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23110     ({
23111       vec_add2 (sort_me, sm, 1);
23112       sm->name = (u8 *)(p->key);
23113       sm->value = (u8 *) (p->value[0]);
23114     }));
23115     /* *INDENT-ON* */
23116
23117   vec_sort_with_function (sort_me, macro_sort_cmp);
23118
23119   if (vec_len (sort_me))
23120     print (vam->ofp, "%-15s%s", "Name", "Value");
23121   else
23122     print (vam->ofp, "The macro table is empty...");
23123
23124   for (i = 0; i < vec_len (sort_me); i++)
23125     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23126   return 0;
23127 }
23128
23129 static int
23130 dump_node_table (vat_main_t * vam)
23131 {
23132   int i, j;
23133   vlib_node_t *node, *next_node;
23134
23135   if (vec_len (vam->graph_nodes) == 0)
23136     {
23137       print (vam->ofp, "Node table empty, issue get_node_graph...");
23138       return 0;
23139     }
23140
23141   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23142     {
23143       node = vam->graph_nodes[i];
23144       print (vam->ofp, "[%d] %s", i, node->name);
23145       for (j = 0; j < vec_len (node->next_nodes); j++)
23146         {
23147           if (node->next_nodes[j] != ~0)
23148             {
23149               next_node = vam->graph_nodes[node->next_nodes[j]];
23150               print (vam->ofp, "  [%d] %s", j, next_node->name);
23151             }
23152         }
23153     }
23154   return 0;
23155 }
23156
23157 static int
23158 value_sort_cmp (void *a1, void *a2)
23159 {
23160   name_sort_t *n1 = a1;
23161   name_sort_t *n2 = a2;
23162
23163   if (n1->value < n2->value)
23164     return -1;
23165   if (n1->value > n2->value)
23166     return 1;
23167   return 0;
23168 }
23169
23170
23171 static int
23172 dump_msg_api_table (vat_main_t * vam)
23173 {
23174   api_main_t *am = &api_main;
23175   name_sort_t *nses = 0, *ns;
23176   hash_pair_t *hp;
23177   int i;
23178
23179   /* *INDENT-OFF* */
23180   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23181   ({
23182     vec_add2 (nses, ns, 1);
23183     ns->name = (u8 *)(hp->key);
23184     ns->value = (u32) hp->value[0];
23185   }));
23186   /* *INDENT-ON* */
23187
23188   vec_sort_with_function (nses, value_sort_cmp);
23189
23190   for (i = 0; i < vec_len (nses); i++)
23191     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23192   vec_free (nses);
23193   return 0;
23194 }
23195
23196 static int
23197 get_msg_id (vat_main_t * vam)
23198 {
23199   u8 *name_and_crc;
23200   u32 message_index;
23201
23202   if (unformat (vam->input, "%s", &name_and_crc))
23203     {
23204       message_index = vl_msg_api_get_msg_index (name_and_crc);
23205       if (message_index == ~0)
23206         {
23207           print (vam->ofp, " '%s' not found", name_and_crc);
23208           return 0;
23209         }
23210       print (vam->ofp, " '%s' has message index %d",
23211              name_and_crc, message_index);
23212       return 0;
23213     }
23214   errmsg ("name_and_crc required...");
23215   return 0;
23216 }
23217
23218 static int
23219 search_node_table (vat_main_t * vam)
23220 {
23221   unformat_input_t *line_input = vam->input;
23222   u8 *node_to_find;
23223   int j;
23224   vlib_node_t *node, *next_node;
23225   uword *p;
23226
23227   if (vam->graph_node_index_by_name == 0)
23228     {
23229       print (vam->ofp, "Node table empty, issue get_node_graph...");
23230       return 0;
23231     }
23232
23233   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23234     {
23235       if (unformat (line_input, "%s", &node_to_find))
23236         {
23237           vec_add1 (node_to_find, 0);
23238           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23239           if (p == 0)
23240             {
23241               print (vam->ofp, "%s not found...", node_to_find);
23242               goto out;
23243             }
23244           node = vam->graph_nodes[p[0]];
23245           print (vam->ofp, "[%d] %s", p[0], node->name);
23246           for (j = 0; j < vec_len (node->next_nodes); j++)
23247             {
23248               if (node->next_nodes[j] != ~0)
23249                 {
23250                   next_node = vam->graph_nodes[node->next_nodes[j]];
23251                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23252                 }
23253             }
23254         }
23255
23256       else
23257         {
23258           clib_warning ("parse error '%U'", format_unformat_error,
23259                         line_input);
23260           return -99;
23261         }
23262
23263     out:
23264       vec_free (node_to_find);
23265
23266     }
23267
23268   return 0;
23269 }
23270
23271
23272 static int
23273 script (vat_main_t * vam)
23274 {
23275 #if (VPP_API_TEST_BUILTIN==0)
23276   u8 *s = 0;
23277   char *save_current_file;
23278   unformat_input_t save_input;
23279   jmp_buf save_jump_buf;
23280   u32 save_line_number;
23281
23282   FILE *new_fp, *save_ifp;
23283
23284   if (unformat (vam->input, "%s", &s))
23285     {
23286       new_fp = fopen ((char *) s, "r");
23287       if (new_fp == 0)
23288         {
23289           errmsg ("Couldn't open script file %s", s);
23290           vec_free (s);
23291           return -99;
23292         }
23293     }
23294   else
23295     {
23296       errmsg ("Missing script name");
23297       return -99;
23298     }
23299
23300   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23301   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23302   save_ifp = vam->ifp;
23303   save_line_number = vam->input_line_number;
23304   save_current_file = (char *) vam->current_file;
23305
23306   vam->input_line_number = 0;
23307   vam->ifp = new_fp;
23308   vam->current_file = s;
23309   do_one_file (vam);
23310
23311   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23312   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23313   vam->ifp = save_ifp;
23314   vam->input_line_number = save_line_number;
23315   vam->current_file = (u8 *) save_current_file;
23316   vec_free (s);
23317
23318   return 0;
23319 #else
23320   clib_warning ("use the exec command...");
23321   return -99;
23322 #endif
23323 }
23324
23325 static int
23326 echo (vat_main_t * vam)
23327 {
23328   print (vam->ofp, "%v", vam->input->buffer);
23329   return 0;
23330 }
23331
23332 /* List of API message constructors, CLI names map to api_xxx */
23333 #define foreach_vpe_api_msg                                             \
23334 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23335 _(sw_interface_dump,"")                                                 \
23336 _(sw_interface_set_flags,                                               \
23337   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23338 _(sw_interface_add_del_address,                                         \
23339   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23340 _(sw_interface_set_rx_mode,                                             \
23341   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23342 _(sw_interface_set_table,                                               \
23343   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23344 _(sw_interface_set_mpls_enable,                                         \
23345   "<intfc> | sw_if_index [disable | dis]")                              \
23346 _(sw_interface_set_vpath,                                               \
23347   "<intfc> | sw_if_index <id> enable | disable")                        \
23348 _(sw_interface_set_vxlan_bypass,                                        \
23349   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23350 _(sw_interface_set_geneve_bypass,                                       \
23351   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23352 _(sw_interface_set_l2_xconnect,                                         \
23353   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23354   "enable | disable")                                                   \
23355 _(sw_interface_set_l2_bridge,                                           \
23356   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23357   "[shg <split-horizon-group>] [bvi]\n"                                 \
23358   "enable | disable")                                                   \
23359 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23360 _(bridge_domain_add_del,                                                \
23361   "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") \
23362 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23363 _(l2fib_add_del,                                                        \
23364   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23365 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23366 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23367 _(l2_flags,                                                             \
23368   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23369 _(bridge_flags,                                                         \
23370   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23371 _(tap_connect,                                                          \
23372   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23373 _(tap_modify,                                                           \
23374   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23375 _(tap_delete,                                                           \
23376   "<vpp-if-name> | sw_if_index <id>")                                   \
23377 _(sw_interface_tap_dump, "")                                            \
23378 _(tap_create_v2,                                                        \
23379   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23380 _(tap_delete_v2,                                                        \
23381   "<vpp-if-name> | sw_if_index <id>")                                   \
23382 _(sw_interface_tap_v2_dump, "")                                         \
23383 _(bond_create,                                                          \
23384   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23385   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23386 _(bond_delete,                                                          \
23387   "<vpp-if-name> | sw_if_index <id>")                                   \
23388 _(bond_enslave,                                                         \
23389   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23390 _(bond_detach_slave,                                                    \
23391   "sw_if_index <n>")                                                    \
23392 _(sw_interface_bond_dump, "")                                           \
23393 _(sw_interface_slave_dump,                                              \
23394   "<vpp-if-name> | sw_if_index <id>")                                   \
23395 _(ip_table_add_del,                                                     \
23396   "table-id <n> [ipv6]\n")                                              \
23397 _(ip_add_del_route,                                                     \
23398   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23399   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23400   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23401   "[multipath] [count <n>]")                                            \
23402 _(ip_mroute_add_del,                                                    \
23403   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23404   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23405 _(mpls_table_add_del,                                                   \
23406   "table-id <n>\n")                                                     \
23407 _(mpls_route_add_del,                                                   \
23408   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23409   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23410   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23411   "[multipath] [count <n>]")                                            \
23412 _(mpls_ip_bind_unbind,                                                  \
23413   "<label> <addr/len>")                                                 \
23414 _(mpls_tunnel_add_del,                                                  \
23415   " via <addr> [table-id <n>]\n"                                        \
23416   "sw_if_index <id>] [l2]  [del]")                                      \
23417 _(bier_table_add_del,                                                   \
23418   "<label> <sub-domain> <set> <bsl> [del]")                             \
23419 _(bier_route_add_del,                                                   \
23420   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23421   "[<intfc> | sw_if_index <id>]"                                        \
23422   "[weight <n>] [del] [multipath]")                                     \
23423 _(proxy_arp_add_del,                                                    \
23424   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23425 _(proxy_arp_intfc_enable_disable,                                       \
23426   "<intfc> | sw_if_index <id> enable | disable")                        \
23427 _(sw_interface_set_unnumbered,                                          \
23428   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23429 _(ip_neighbor_add_del,                                                  \
23430   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23431   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23432 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23433 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23434   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23435   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23436   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23437 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23438 _(reset_fib, "vrf <n> [ipv6]")                                          \
23439 _(dhcp_proxy_config,                                                    \
23440   "svr <v46-address> src <v46-address>\n"                               \
23441    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23442 _(dhcp_proxy_set_vss,                                                   \
23443   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23444 _(dhcp_proxy_dump, "ip6")                                               \
23445 _(dhcp_client_config,                                                   \
23446   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23447 _(set_ip_flow_hash,                                                     \
23448   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23449 _(sw_interface_ip6_enable_disable,                                      \
23450   "<intfc> | sw_if_index <id> enable | disable")                        \
23451 _(sw_interface_ip6_set_link_local_address,                              \
23452   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23453 _(ip6nd_proxy_add_del,                                                  \
23454   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23455 _(ip6nd_proxy_dump, "")                                                 \
23456 _(sw_interface_ip6nd_ra_prefix,                                         \
23457   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23458   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23459   "[nolink] [isno]")                                                    \
23460 _(sw_interface_ip6nd_ra_config,                                         \
23461   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23462   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23463   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23464 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23465 _(l2_patch_add_del,                                                     \
23466   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23467   "enable | disable")                                                   \
23468 _(sr_localsid_add_del,                                                  \
23469   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23470   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23471 _(classify_add_del_table,                                               \
23472   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23473   " [del] [del-chain] mask <mask-value>\n"                              \
23474   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23475   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23476 _(classify_add_del_session,                                             \
23477   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23478   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23479   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23480   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23481 _(classify_set_interface_ip_table,                                      \
23482   "<intfc> | sw_if_index <nn> table <nn>")                              \
23483 _(classify_set_interface_l2_tables,                                     \
23484   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23485   "  [other-table <nn>]")                                               \
23486 _(get_node_index, "node <node-name")                                    \
23487 _(add_node_next, "node <node-name> next <next-node-name>")              \
23488 _(l2tpv3_create_tunnel,                                                 \
23489   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23490   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23491   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23492 _(l2tpv3_set_tunnel_cookies,                                            \
23493   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23494   "[new_remote_cookie <nn>]\n")                                         \
23495 _(l2tpv3_interface_enable_disable,                                      \
23496   "<intfc> | sw_if_index <nn> enable | disable")                        \
23497 _(l2tpv3_set_lookup_key,                                                \
23498   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23499 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23500 _(vxlan_add_del_tunnel,                                                 \
23501   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23502   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23503   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23504 _(geneve_add_del_tunnel,                                                \
23505   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23506   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23507   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23508 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23509 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23510 _(gre_add_del_tunnel,                                                   \
23511   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23512   "[teb | erspan <session-id>] [del]")                                  \
23513 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23514 _(l2_fib_clear_table, "")                                               \
23515 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23516 _(l2_interface_vlan_tag_rewrite,                                        \
23517   "<intfc> | sw_if_index <nn> \n"                                       \
23518   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23519   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23520 _(create_vhost_user_if,                                                 \
23521         "socket <filename> [server] [renumber <dev_instance>] "         \
23522         "[mac <mac_address>]")                                          \
23523 _(modify_vhost_user_if,                                                 \
23524         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23525         "[server] [renumber <dev_instance>]")                           \
23526 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23527 _(sw_interface_vhost_user_dump, "")                                     \
23528 _(show_version, "")                                                     \
23529 _(vxlan_gpe_add_del_tunnel,                                             \
23530   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23531   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23532   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23533   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23534 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23535 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23536 _(interface_name_renumber,                                              \
23537   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23538 _(input_acl_set_interface,                                              \
23539   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23540   "  [l2-table <nn>] [del]")                                            \
23541 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23542 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23543 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23544 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23545 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23546 _(ip_dump, "ipv4 | ipv6")                                               \
23547 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23548 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23549   "  spid_id <n> ")                                                     \
23550 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23551   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23552   "  integ_alg <alg> integ_key <hex>")                                  \
23553 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23554   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23555   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23556   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23557 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23558 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23559   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23560   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23561   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23562   "  [instance <n>]")     \
23563 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23564 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23565   "  <alg> <hex>\n")                                                    \
23566 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23567 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23568 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23569   "(auth_data 0x<data> | auth_data <data>)")                            \
23570 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23571   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23572 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23573   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23574   "(local|remote)")                                                     \
23575 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23576 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23577 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23578 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23579 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23580 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23581 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23582 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23583 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23584 _(delete_loopback,"sw_if_index <nn>")                                   \
23585 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23586 _(map_add_domain,                                                       \
23587   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23588   "ip6-src <ip6addr> "                                                  \
23589   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23590 _(map_del_domain, "index <n>")                                          \
23591 _(map_add_del_rule,                                                     \
23592   "index <n> psid <n> dst <ip6addr> [del]")                             \
23593 _(map_domain_dump, "")                                                  \
23594 _(map_rule_dump, "index <map-domain>")                                  \
23595 _(want_interface_events,  "enable|disable")                             \
23596 _(want_stats,"enable|disable")                                          \
23597 _(get_first_msg_id, "client <name>")                                    \
23598 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23599 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23600   "fib-id <nn> [ip4][ip6][default]")                                    \
23601 _(get_node_graph, " ")                                                  \
23602 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23603 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23604 _(ioam_disable, "")                                                     \
23605 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23606                             " sw_if_index <sw_if_index> p <priority> "  \
23607                             "w <weight>] [del]")                        \
23608 _(one_add_del_locator, "locator-set <locator_name> "                    \
23609                         "iface <intf> | sw_if_index <sw_if_index> "     \
23610                         "p <priority> w <weight> [del]")                \
23611 _(one_add_del_local_eid,"vni <vni> eid "                                \
23612                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23613                          "locator-set <locator_name> [del]"             \
23614                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23615 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23616 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23617 _(one_enable_disable, "enable|disable")                                 \
23618 _(one_map_register_enable_disable, "enable|disable")                    \
23619 _(one_map_register_fallback_threshold, "<value>")                       \
23620 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23621 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23622                                "[seid <seid>] "                         \
23623                                "rloc <locator> p <prio> "               \
23624                                "w <weight> [rloc <loc> ... ] "          \
23625                                "action <action> [del-all]")             \
23626 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23627                           "<local-eid>")                                \
23628 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23629 _(one_use_petr, "ip-address> | disable")                                \
23630 _(one_map_request_mode, "src-dst|dst-only")                             \
23631 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23632 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23633 _(one_locator_set_dump, "[local | remote]")                             \
23634 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23635 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23636                        "[local] | [remote]")                            \
23637 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23638 _(one_ndp_bd_get, "")                                                   \
23639 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23640 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23641 _(one_l2_arp_bd_get, "")                                                \
23642 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23643 _(one_stats_enable_disable, "enable|disalbe")                           \
23644 _(show_one_stats_enable_disable, "")                                    \
23645 _(one_eid_table_vni_dump, "")                                           \
23646 _(one_eid_table_map_dump, "l2|l3")                                      \
23647 _(one_map_resolver_dump, "")                                            \
23648 _(one_map_server_dump, "")                                              \
23649 _(one_adjacencies_get, "vni <vni>")                                     \
23650 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23651 _(show_one_rloc_probe_state, "")                                        \
23652 _(show_one_map_register_state, "")                                      \
23653 _(show_one_status, "")                                                  \
23654 _(one_stats_dump, "")                                                   \
23655 _(one_stats_flush, "")                                                  \
23656 _(one_get_map_request_itr_rlocs, "")                                    \
23657 _(one_map_register_set_ttl, "<ttl>")                                    \
23658 _(one_set_transport_protocol, "udp|api")                                \
23659 _(one_get_transport_protocol, "")                                       \
23660 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23661 _(one_show_xtr_mode, "")                                                \
23662 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23663 _(one_show_pitr_mode, "")                                               \
23664 _(one_enable_disable_petr_mode, "enable|disable")                       \
23665 _(one_show_petr_mode, "")                                               \
23666 _(show_one_nsh_mapping, "")                                             \
23667 _(show_one_pitr, "")                                                    \
23668 _(show_one_use_petr, "")                                                \
23669 _(show_one_map_request_mode, "")                                        \
23670 _(show_one_map_register_ttl, "")                                        \
23671 _(show_one_map_register_fallback_threshold, "")                         \
23672 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23673                             " sw_if_index <sw_if_index> p <priority> "  \
23674                             "w <weight>] [del]")                        \
23675 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23676                         "iface <intf> | sw_if_index <sw_if_index> "     \
23677                         "p <priority> w <weight> [del]")                \
23678 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23679                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23680                          "locator-set <locator_name> [del]"             \
23681                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23682 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23683 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23684 _(lisp_enable_disable, "enable|disable")                                \
23685 _(lisp_map_register_enable_disable, "enable|disable")                   \
23686 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23687 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23688                                "[seid <seid>] "                         \
23689                                "rloc <locator> p <prio> "               \
23690                                "w <weight> [rloc <loc> ... ] "          \
23691                                "action <action> [del-all]")             \
23692 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23693                           "<local-eid>")                                \
23694 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23695 _(lisp_use_petr, "<ip-address> | disable")                              \
23696 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23697 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23698 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23699 _(lisp_locator_set_dump, "[local | remote]")                            \
23700 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23701 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23702                        "[local] | [remote]")                            \
23703 _(lisp_eid_table_vni_dump, "")                                          \
23704 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23705 _(lisp_map_resolver_dump, "")                                           \
23706 _(lisp_map_server_dump, "")                                             \
23707 _(lisp_adjacencies_get, "vni <vni>")                                    \
23708 _(gpe_fwd_entry_vnis_get, "")                                           \
23709 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23710 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23711                                 "[table <table-id>]")                   \
23712 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23713 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23714 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23715 _(gpe_get_encap_mode, "")                                               \
23716 _(lisp_gpe_add_del_iface, "up|down")                                    \
23717 _(lisp_gpe_enable_disable, "enable|disable")                            \
23718 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23719   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23720 _(show_lisp_rloc_probe_state, "")                                       \
23721 _(show_lisp_map_register_state, "")                                     \
23722 _(show_lisp_status, "")                                                 \
23723 _(lisp_get_map_request_itr_rlocs, "")                                   \
23724 _(show_lisp_pitr, "")                                                   \
23725 _(show_lisp_use_petr, "")                                               \
23726 _(show_lisp_map_request_mode, "")                                       \
23727 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23728 _(af_packet_delete, "name <host interface name>")                       \
23729 _(policer_add_del, "name <policer name> <params> [del]")                \
23730 _(policer_dump, "[name <policer name>]")                                \
23731 _(policer_classify_set_interface,                                       \
23732   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23733   "  [l2-table <nn>] [del]")                                            \
23734 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23735 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23736     "[master|slave]")                                                   \
23737 _(netmap_delete, "name <interface name>")                               \
23738 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23739 _(mpls_fib_dump, "")                                                    \
23740 _(classify_table_ids, "")                                               \
23741 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23742 _(classify_table_info, "table_id <nn>")                                 \
23743 _(classify_session_dump, "table_id <nn>")                               \
23744 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23745     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23746     "[template_interval <nn>] [udp_checksum]")                          \
23747 _(ipfix_exporter_dump, "")                                              \
23748 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23749 _(ipfix_classify_stream_dump, "")                                       \
23750 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23751 _(ipfix_classify_table_dump, "")                                        \
23752 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23753 _(sw_interface_span_dump, "[l2]")                                           \
23754 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23755 _(pg_create_interface, "if_id <nn>")                                    \
23756 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23757 _(pg_enable_disable, "[stream <id>] disable")                           \
23758 _(ip_source_and_port_range_check_add_del,                               \
23759   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23760 _(ip_source_and_port_range_check_interface_add_del,                     \
23761   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23762   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23763 _(ipsec_gre_add_del_tunnel,                                             \
23764   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23765 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23766 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23767 _(l2_interface_pbb_tag_rewrite,                                         \
23768   "<intfc> | sw_if_index <nn> \n"                                       \
23769   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23770   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23771 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23772 _(flow_classify_set_interface,                                          \
23773   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23774 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23775 _(ip_fib_dump, "")                                                      \
23776 _(ip_mfib_dump, "")                                                     \
23777 _(ip6_fib_dump, "")                                                     \
23778 _(ip6_mfib_dump, "")                                                    \
23779 _(feature_enable_disable, "arc_name <arc_name> "                        \
23780   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23781 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23782 "[disable]")                                                            \
23783 _(l2_xconnect_dump, "")                                                 \
23784 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23785 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23786 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23787 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23788 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23789 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23790 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23791   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23792 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23793 _(memfd_segment_create,"size <nnn>")                                    \
23794 _(sock_init_shm, "size <nnn>")                                          \
23795 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23796 _(dns_enable_disable, "[enable][disable]")                              \
23797 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23798 _(dns_resolve_name, "<hostname>")                                       \
23799 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23800 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23801 _(dns_resolve_name, "<hostname>")                                       \
23802 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23803   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23804 _(session_rules_dump, "")                                               \
23805 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23806 _(output_acl_set_interface,                                             \
23807   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23808   "  [l2-table <nn>] [del]")                                            \
23809 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23810
23811 /* List of command functions, CLI names map directly to functions */
23812 #define foreach_cli_function                                    \
23813 _(comment, "usage: comment <ignore-rest-of-line>")              \
23814 _(dump_interface_table, "usage: dump_interface_table")          \
23815 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23816 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23817 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23818 _(dump_stats_table, "usage: dump_stats_table")                  \
23819 _(dump_macro_table, "usage: dump_macro_table ")                 \
23820 _(dump_node_table, "usage: dump_node_table")                    \
23821 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23822 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23823 _(echo, "usage: echo <message>")                                \
23824 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23825 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23826 _(help, "usage: help")                                          \
23827 _(q, "usage: quit")                                             \
23828 _(quit, "usage: quit")                                          \
23829 _(search_node_table, "usage: search_node_table <name>...")      \
23830 _(set, "usage: set <variable-name> <value>")                    \
23831 _(script, "usage: script <file-name>")                          \
23832 _(unset, "usage: unset <variable-name>")
23833 #define _(N,n)                                  \
23834     static void vl_api_##n##_t_handler_uni      \
23835     (vl_api_##n##_t * mp)                       \
23836     {                                           \
23837         vat_main_t * vam = &vat_main;           \
23838         if (vam->json_output) {                 \
23839             vl_api_##n##_t_handler_json(mp);    \
23840         } else {                                \
23841             vl_api_##n##_t_handler(mp);         \
23842         }                                       \
23843     }
23844 foreach_vpe_api_reply_msg;
23845 #if VPP_API_TEST_BUILTIN == 0
23846 foreach_standalone_reply_msg;
23847 #endif
23848 #undef _
23849
23850 void
23851 vat_api_hookup (vat_main_t * vam)
23852 {
23853 #define _(N,n)                                                  \
23854     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23855                            vl_api_##n##_t_handler_uni,          \
23856                            vl_noop_handler,                     \
23857                            vl_api_##n##_t_endian,               \
23858                            vl_api_##n##_t_print,                \
23859                            sizeof(vl_api_##n##_t), 1);
23860   foreach_vpe_api_reply_msg;
23861 #if VPP_API_TEST_BUILTIN == 0
23862   foreach_standalone_reply_msg;
23863 #endif
23864 #undef _
23865
23866 #if (VPP_API_TEST_BUILTIN==0)
23867   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23868
23869   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23870
23871   vam->function_by_name = hash_create_string (0, sizeof (uword));
23872
23873   vam->help_by_name = hash_create_string (0, sizeof (uword));
23874 #endif
23875
23876   /* API messages we can send */
23877 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23878   foreach_vpe_api_msg;
23879 #undef _
23880
23881   /* Help strings */
23882 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23883   foreach_vpe_api_msg;
23884 #undef _
23885
23886   /* CLI functions */
23887 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23888   foreach_cli_function;
23889 #undef _
23890
23891   /* Help strings */
23892 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23893   foreach_cli_function;
23894 #undef _
23895 }
23896
23897 #if VPP_API_TEST_BUILTIN
23898 static clib_error_t *
23899 vat_api_hookup_shim (vlib_main_t * vm)
23900 {
23901   vat_api_hookup (&vat_main);
23902   return 0;
23903 }
23904
23905 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23906 #endif
23907
23908 /*
23909  * fd.io coding-style-patch-verification: ON
23910  *
23911  * Local Variables:
23912  * eval: (c-set-style "gnu")
23913  * End:
23914  */